Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F98735529
D37371.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D37371.diff
View Options
diff --git a/tests/sys/kern/ktls_test.c b/tests/sys/kern/ktls_test.c
--- a/tests/sys/kern/ktls_test.c
+++ b/tests/sys/kern/ktls_test.c
@@ -270,8 +270,8 @@
}
static bool
-cbc_decrypt(const EVP_CIPHER *cipher, const char *key, const char *iv,
- const char *input, char *output, size_t size)
+cbc_crypt(const EVP_CIPHER *cipher, const char *key, const char *iv,
+ const char *input, char *output, size_t size, int enc)
{
EVP_CIPHER_CTX *ctx;
int outl, total;
@@ -283,7 +283,7 @@
return (false);
}
if (EVP_CipherInit_ex(ctx, cipher, NULL, (const u_char *)key,
- (const u_char *)iv, 0) != 1) {
+ (const u_char *)iv, enc) != 1) {
warnx("EVP_CipherInit_ex failed: %s",
ERR_error_string(ERR_get_error(), NULL));
EVP_CIPHER_CTX_free(ctx);
@@ -315,12 +315,25 @@
}
static bool
-verify_hash(const EVP_MD *md, const void *key, size_t key_len, const void *aad,
- size_t aad_len, const void *buffer, size_t len, const void *digest)
+cbc_encrypt(const EVP_CIPHER *cipher, const char *key, const char *iv,
+ const char *input, char *output, size_t size)
+{
+ return (cbc_crypt(cipher, key, iv, input, output, size, 1));
+}
+
+static bool
+cbc_decrypt(const EVP_CIPHER *cipher, const char *key, const char *iv,
+ const char *input, char *output, size_t size)
+{
+ return (cbc_crypt(cipher, key, iv, input, output, size, 0));
+}
+
+static bool
+compute_hash(const EVP_MD *md, const void *key, size_t key_len, const void *aad,
+ size_t aad_len, const void *buffer, size_t len, void *digest,
+ u_int *digest_len)
{
HMAC_CTX *ctx;
- unsigned char digest2[EVP_MAX_MD_SIZE];
- u_int digest_len;
ctx = HMAC_CTX_new();
if (ctx == NULL) {
@@ -346,13 +359,26 @@
HMAC_CTX_free(ctx);
return (false);
}
- if (HMAC_Final(ctx, digest2, &digest_len) != 1) {
+ if (HMAC_Final(ctx, digest, digest_len) != 1) {
warnx("HMAC_Final failed: %s",
ERR_error_string(ERR_get_error(), NULL));
HMAC_CTX_free(ctx);
return (false);
}
HMAC_CTX_free(ctx);
+ return (true);
+}
+
+static bool
+verify_hash(const EVP_MD *md, const void *key, size_t key_len, const void *aad,
+ size_t aad_len, const void *buffer, size_t len, const void *digest)
+{
+ unsigned char digest2[EVP_MAX_MD_SIZE];
+ u_int digest_len;
+
+ if (!compute_hash(md, key, key_len, aad, aad_len, buffer, len, digest2,
+ &digest_len))
+ return (false);
if (memcmp(digest, digest2, digest_len) != 0) {
warnx("HMAC mismatch");
return (false);
@@ -877,8 +903,62 @@
/*
* Encrypt a TLS record of type 'record_type' with payload 'len' bytes
* long at 'src' and store the result at 'dst'. If 'dst' doesn't have
- * sufficient room ('avail'), fail the test.
+ * sufficient room ('avail'), fail the test. 'padding' is the amount
+ * of additional padding to include beyond any amount mandated by the
+ * cipher suite.
*/
+static size_t
+encrypt_tls_aes_cbc_mte(struct tls_enable *en, uint8_t record_type,
+ uint64_t seqno, const void *src, size_t len, void *dst, size_t avail,
+ size_t padding)
+{
+ struct tls_record_layer *hdr;
+ struct tls_mac_data aad;
+ char *buf, *iv;
+ size_t hdr_len, mac_len, record_len;
+ u_int digest_len, i;
+
+ ATF_REQUIRE(padding % 16 == 0);
+
+ hdr = dst;
+ buf = dst;
+
+ hdr_len = tls_header_len(en);
+ mac_len = tls_mac_len(en);
+ padding += (AES_BLOCK_LEN - (len + mac_len) % AES_BLOCK_LEN);
+ ATF_REQUIRE(padding > 0 && padding <= 255);
+
+ record_len = hdr_len + len + mac_len + padding;
+ ATF_REQUIRE(record_len <= avail);
+
+ hdr->tls_type = record_type;
+ hdr->tls_vmajor = TLS_MAJOR_VER_ONE;
+ hdr->tls_vminor = en->tls_vminor;
+ hdr->tls_length = htons(record_len - sizeof(*hdr));
+ iv = (char *)(hdr + 1);
+ for (i = 0; i < AES_BLOCK_LEN; i++)
+ iv[i] = rdigit();
+
+ /* Copy plaintext to ciphertext region. */
+ memcpy(buf + hdr_len, src, len);
+
+ /* Compute HMAC. */
+ tls_mte_aad(en, len, hdr, seqno, &aad);
+ ATF_REQUIRE(compute_hash(tls_EVP_MD(en), en->auth_key, en->auth_key_len,
+ &aad, sizeof(aad), src, len, buf + hdr_len + len, &digest_len));
+ ATF_REQUIRE(digest_len == mac_len);
+
+ /* Store padding. */
+ for (i = 0; i < padding; i++)
+ buf[hdr_len + len + mac_len + i] = padding - 1;
+
+ /* Encrypt the record. */
+ ATF_REQUIRE(cbc_encrypt(tls_EVP_CIPHER(en), en->cipher_key, iv,
+ buf + hdr_len, buf + hdr_len, len + mac_len + padding));
+
+ return (record_len);
+}
+
static size_t
encrypt_tls_12_aead(struct tls_enable *en, uint8_t record_type, uint64_t seqno,
const void *src, size_t len, void *dst)
@@ -980,8 +1060,12 @@
encrypt_tls_record(struct tls_enable *en, uint8_t record_type, uint64_t seqno,
const void *src, size_t len, void *dst, size_t avail, size_t padding)
{
- return (encrypt_tls_aead(en, record_type, seqno, src, len, dst, avail,
- padding));
+ if (en->cipher_algorithm == CRYPTO_AES_CBC)
+ return (encrypt_tls_aes_cbc_mte(en, record_type, seqno, src,
+ len, dst, avail, padding));
+ else
+ return (encrypt_tls_aead(en, record_type, seqno, src, len,
+ dst, avail, padding));
}
static void
@@ -1389,9 +1473,9 @@
#define TLS_10_TESTS(M) \
M(aes128_cbc_1_0_sha1, CRYPTO_AES_CBC, 128 / 8, \
- CRYPTO_SHA1_HMAC) \
+ CRYPTO_SHA1_HMAC, TLS_MINOR_VER_ZERO) \
M(aes256_cbc_1_0_sha1, CRYPTO_AES_CBC, 256 / 8, \
- CRYPTO_SHA1_HMAC)
+ CRYPTO_SHA1_HMAC, TLS_MINOR_VER_ZERO)
#define TLS_13_TESTS(M) \
M(aes128_gcm_1_3, CRYPTO_AES_NIST_GCM_16, 128 / 8, 0, \
@@ -1401,11 +1485,7 @@
M(chacha20_poly1305_1_3, CRYPTO_CHACHA20_POLY1305, 256 / 8, 0, \
TLS_MINOR_VER_THREE)
-#define AES_CBC_TESTS(M) \
- M(aes128_cbc_1_0_sha1, CRYPTO_AES_CBC, 128 / 8, \
- CRYPTO_SHA1_HMAC, TLS_MINOR_VER_ZERO) \
- M(aes256_cbc_1_0_sha1, CRYPTO_AES_CBC, 256 / 8, \
- CRYPTO_SHA1_HMAC, TLS_MINOR_VER_ZERO) \
+#define AES_CBC_NONZERO_TESTS(M) \
M(aes128_cbc_1_1_sha1, CRYPTO_AES_CBC, 128 / 8, \
CRYPTO_SHA1_HMAC, TLS_MINOR_VER_ONE) \
M(aes256_cbc_1_1_sha1, CRYPTO_AES_CBC, 256 / 8, \
@@ -1423,6 +1503,10 @@
M(aes256_cbc_1_2_sha384, CRYPTO_AES_CBC, 256 / 8, \
CRYPTO_SHA2_384_HMAC, TLS_MINOR_VER_TWO) \
+#define AES_CBC_TESTS(M) \
+ TLS_10_TESTS(M) \
+ AES_CBC_NONZERO_TESTS(M)
+
#define AES_GCM_TESTS(M) \
M(aes128_gcm_1_2, CRYPTO_AES_NIST_GCM_16, 128 / 8, 0, \
TLS_MINOR_VER_TWO) \
@@ -1727,22 +1811,111 @@
*
* - a long test which sends 64KB of application data (split across
* multiple TLS records)
- *
- * Note that receive is currently only supported for TLS 1.2 AEAD
- * cipher suites.
*/
+AES_CBC_NONZERO_TESTS(GEN_RECEIVE_TESTS);
AES_GCM_TESTS(GEN_RECEIVE_TESTS);
CHACHA20_TESTS(GEN_RECEIVE_TESTS);
-#define GEN_PADDING_RECEIVE_TESTS(cipher_name, cipher_alg, key_size, \
- auth_alg, minor) \
+#define GEN_RECEIVE_MTE_PADDING_TESTS(cipher_name, cipher_alg, \
+ key_size, auth_alg, minor) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_1, 1, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_2, 2, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_3, 3, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_4, 4, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_5, 5, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_6, 6, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_7, 7, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_8, 8, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_9, 9, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_10, 10, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_11, 11, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_12, 12, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_13, 13, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_14, 14, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_15, 15, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_16, 16, 0) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_16_extra, 16, 16) \
+ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_32_extra, 16, 32)
+
+#define ADD_RECEIVE_MTE_PADDING_TESTS(cipher_name, cipher_alg, \
+ key_size, auth_alg, minor) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_1) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_2) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_3) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_4) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_5) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_6) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_7) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_8) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_9) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_10) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_11) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_12) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_13) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_14) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_15) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_16) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_16_extra) \
+ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
+ auth_alg, minor, padding_32_extra)
+
+/*
+ * For AES-CBC MTE cipher suites using padding, add tests of messages
+ * with each possible padding size. Note that the padding_<N> tests
+ * do not necessarily test <N> bytes of padding as the padding is a
+ * function of the cipher suite's MAC length. However, cycling
+ * through all of the payload sizes from 1 to 16 should exercise all
+ * of the possible padding lengths for each suite.
+ *
+ * Two additional tests check for additional padding with an extra
+ * 16 or 32 bytes beyond the normal padding.
+ */
+AES_CBC_NONZERO_TESTS(GEN_RECEIVE_MTE_PADDING_TESTS);
+
+#define GEN_RECEIVE_TLS13_PADDING_TESTS(cipher_name, cipher_alg, \
+ key_size, auth_alg, minor) \
GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
auth_alg, minor, short_padded, 64, 16) \
GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
auth_alg, minor, long_padded, 64 * 1024, 15)
-#define ADD_PADDING_RECEIVE_TESTS(cipher_name, cipher_alg, key_size, \
- auth_alg, minor) \
+#define ADD_RECEIVE_TLS13_PADDING_TESTS(cipher_name, cipher_alg, \
+ key_size, auth_alg, minor) \
ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
auth_alg, minor, short_padded) \
ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \
@@ -1752,7 +1925,7 @@
* For TLS 1.3 cipher suites, run two additional receive tests which
* use add padding to each record.
*/
-TLS_13_TESTS(GEN_PADDING_RECEIVE_TESTS);
+TLS_13_TESTS(GEN_RECEIVE_TLS13_PADDING_TESTS);
static void
test_ktls_invalid_receive_cipher_suite(const atf_tc_t *tc,
@@ -1833,7 +2006,7 @@
* Ensure that valid cipher suites not supported for receive are
* rejected.
*/
-AES_CBC_TESTS(GEN_UNSUPPORTED_RECEIVE_TEST);
+TLS_10_TESTS(GEN_UNSUPPORTED_RECEIVE_TEST);
/*
* Try to perform an invalid sendto(2) on a TXTLS-enabled socket, to exercise
@@ -1887,10 +2060,12 @@
INVALID_CIPHER_SUITES(ADD_INVALID_TRANSMIT_TEST);
/* Receive tests */
- AES_CBC_TESTS(ADD_UNSUPPORTED_RECEIVE_TEST);
+ TLS_10_TESTS(ADD_UNSUPPORTED_RECEIVE_TEST);
+ AES_CBC_NONZERO_TESTS(ADD_RECEIVE_TESTS);
AES_GCM_TESTS(ADD_RECEIVE_TESTS);
CHACHA20_TESTS(ADD_RECEIVE_TESTS);
- TLS_13_TESTS(ADD_PADDING_RECEIVE_TESTS);
+ AES_CBC_NONZERO_TESTS(ADD_RECEIVE_MTE_PADDING_TESTS);
+ TLS_13_TESTS(ADD_RECEIVE_TLS13_PADDING_TESTS);
INVALID_CIPHER_SUITES(ADD_INVALID_RECEIVE_TEST);
/* Miscellaneous */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 5, 1:25 PM (21 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13644536
Default Alt Text
D37371.diff (13 KB)
Attached To
Mode
D37371: ktls: Add tests for software AES-CBC decryption for TLS 1.1+.
Attached
Detach File
Event Timeline
Log In to Comment