From nobody Tue Nov 15 20:04:20 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4NBcZs0Zl3z4hdWG; Tue, 15 Nov 2022 20:04:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4NBcZs07z2z4N6m; Tue, 15 Nov 2022 20:04:21 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1668542661; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+4hhOOdQPX5iOP2Kt68g+PznPwEfcBRglYjyBitvmx4=; b=NzF5/Wf96jibNbKUmXb3bQDstlDslI0/OaBBdEF4ymnNm/4fzGF25z6mqhSnGlzz21H9Jn wBcAIea9u9J8yuWaufiV/RDOTkFv6lrxx+JdOltgh6JM+8iOA0P9IkRQGLOncaFQRMNPsz SJMm6jrN2VCt1ixXjQxUgUgrMuHaQ0tuz1wjiVKLfCLShECbKI5vux/ryRmmK6QiIpd/GS vJIKUq1ix0FAAdZuwlA1XLGy57O0PMwJ/TYCWJeBkGvondXznx4FzgHIS5iDno8IqpArPE 1I4YuVIIFYsNfhy5HpBgOln+8Sh3YlbDlB5cWk+b5vHsHrBdd9pxoqrDCBEP0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1668542661; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+4hhOOdQPX5iOP2Kt68g+PznPwEfcBRglYjyBitvmx4=; b=Ki2yoAtg4mJBZNeLDGD3xdsOGBoyODkLHwKipY1Os7jGl9nKQ5US9Px8YgRpodcI0DTymX ECvd9RbNlMzkw0zG9WhGPS33Iwnba4PvUobRpZy1JSRPQ7FJfmfbwcW0QJmztT86rz0GQh G/dwJH80ItFsBhQl7tkINZORgvEstn7HrlFVufsufoOz6mJbaD+4cevFHUhrgjJ2AqFO46 6Y46JaOlWr2iYC5GfxvwtXSfnn2Be8p1f91Qd4cUX9HgMv5OVYlD9qyjk2TLwkeuNcH3Qa mqmsQfh3xRhgzQdrFZM5c2+IUMF/pr66QuTr5Xq/yo+7UVpYqGa4OwvY5APyaQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1668542661; a=rsa-sha256; cv=none; b=iszNkRAc+j9UahG9wg61KDTJtmoxl5PAU2s9AXKmUSyOiwdJCrAtDUkMUUQEaxq+3pue6g CVImvx3dMuTxb9EDz8RSZnwUvdND3/PQWI8YnXASuN+H3fY18jvYww9FHKhRe3MkzbXM1j CDZFZNCKRc4a1p4D34ZslfPnIX04JDj6LDOzwex7qPf2bvgJKhIIVQl0JnVCyg0Z2GqSh9 WMYpLCwYDQPPK+SdZqF0pMpLHXITV/48MaSW0NxSl9s52Q7Q/xyO+CzDpXX/a1/9KOzrsv dVvAXpL7Ehp8RCUsZCK3sghuYv3YO5spjPkIgLVKhRJjSye3fMOobknRyTYlRw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4NBcZr66KyzZZ7; Tue, 15 Nov 2022 20:04:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 2AFK4KbF029373; Tue, 15 Nov 2022 20:04:20 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2AFK4Kl8029372; Tue, 15 Nov 2022 20:04:20 GMT (envelope-from git) Date: Tue, 15 Nov 2022 20:04:20 GMT Message-Id: <202211152004.2AFK4Kl8029372@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: 65bd3adbed15 - main - ktls: Add tests for receiving corrupted or invalid records. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 65bd3adbed1526cfedc4474c1a390e058303128f Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=65bd3adbed1526cfedc4474c1a390e058303128f commit 65bd3adbed1526cfedc4474c1a390e058303128f Author: John Baldwin AuthorDate: 2022-11-15 20:03:19 +0000 Commit: John Baldwin CommitDate: 2022-11-15 20:03:19 +0000 ktls: Add tests for receiving corrupted or invalid records. These should all trigger errors when reading from the socket. Tests include truncated records (socket closed early on the other side), corrupted records (bits flipped in explicit IVs, ciphertext, or MAC), invalid header fields, and various invalid record lengths. Reviewed by: markj Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D37373 --- tests/sys/kern/ktls_test.c | 651 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 635 insertions(+), 16 deletions(-) diff --git a/tests/sys/kern/ktls_test.c b/tests/sys/kern/ktls_test.c index 3ad733e73f75..09fb96ed11e8 100644 --- a/tests/sys/kern/ktls_test.c +++ b/tests/sys/kern/ktls_test.c @@ -26,7 +26,7 @@ * SUCH DAMAGE. */ -#include +#include #include #include #include @@ -677,6 +677,22 @@ tls_trailer_len(struct tls_enable *en) return (len); } +/* Minimum valid record payload size for a given cipher suite. */ +static size_t +tls_minimum_record_payload(struct tls_enable *en) +{ + size_t len; + + len = tls_header_len(en); + if (en->cipher_algorithm == CRYPTO_AES_CBC) + len += roundup2(tls_mac_len(en) + 1, AES_BLOCK_LEN); + else + len += tls_mac_len(en); + if (en->tls_vminor == TLS_MINOR_VER_THREE) + len++; + return (len - sizeof(struct tls_record_layer)); +} + /* 'len' is the length of the payload application data. */ static void tls_mte_aad(struct tls_enable *en, size_t len, @@ -1471,6 +1487,329 @@ test_ktls_receive_app_data(const atf_tc_t *tc, struct tls_enable *en, ATF_REQUIRE(close(kq) == 0); } +static void +ktls_receive_tls_error(int fd, int expected_error) +{ + struct msghdr msg; + struct tls_get_record *tgr; + char cbuf[CMSG_SPACE(sizeof(*tgr))]; + char buf[64]; + struct iovec iov; + + memset(&msg, 0, sizeof(msg)); + + msg.msg_control = cbuf; + msg.msg_controllen = sizeof(cbuf); + + iov.iov_base = buf; + iov.iov_len = sizeof(buf); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + ATF_REQUIRE(recvmsg(fd, &msg, 0) == -1); + if (expected_error != 0) + ATF_REQUIRE(errno == expected_error); +} + +static void +test_ktls_receive_corrupted_record(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len, ssize_t offset) +{ + char *plaintext, *outbuf; + size_t outbuf_cap, outbuf_len; + ssize_t rv; + int sockets[2]; + + ATF_REQUIRE(len <= TLS_MAX_MSG_SIZE_V10_2); + + plaintext = alloc_buffer(len); + outbuf_cap = tls_header_len(en) + len + tls_trailer_len(en); + outbuf = malloc(outbuf_cap); + + ATF_REQUIRE_MSG(open_sockets(tc, sockets), "failed to create sockets"); + + ATF_REQUIRE(setsockopt(sockets[0], IPPROTO_TCP, TCP_RXTLS_ENABLE, en, + sizeof(*en)) == 0); + check_tls_mode(tc, sockets[0], TCP_RXTLS_MODE); + + fd_set_blocking(sockets[0]); + fd_set_blocking(sockets[1]); + + outbuf_len = encrypt_tls_record(en, TLS_RLTYPE_APP, seqno, + plaintext, len, outbuf, outbuf_cap, 0); + + /* A negative offset is an offset from the end. */ + if (offset < 0) + offset += outbuf_len; + outbuf[offset] ^= 0x01; + + rv = write(sockets[1], outbuf, outbuf_len); + ATF_REQUIRE(rv == (ssize_t)outbuf_len); + + ktls_receive_tls_error(sockets[0], EBADMSG); + + free(outbuf); + free(plaintext); + + close_sockets(sockets); +} + +static void +test_ktls_receive_corrupted_iv(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len) +{ + ATF_REQUIRE(tls_header_len(en) > sizeof(struct tls_record_layer)); + + /* Corrupt the first byte of the explicit IV after the header. */ + test_ktls_receive_corrupted_record(tc, en, seqno, len, + sizeof(struct tls_record_layer)); +} + +static void +test_ktls_receive_corrupted_data(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len) +{ + ATF_REQUIRE(len > 0); + + /* Corrupt the first ciphertext byte after the header. */ + test_ktls_receive_corrupted_record(tc, en, seqno, len, + tls_header_len(en)); +} + +static void +test_ktls_receive_corrupted_mac(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len) +{ + size_t offset; + + /* Corrupt the first byte of the MAC. */ + if (en->cipher_algorithm == CRYPTO_AES_CBC) + offset = tls_header_len(en) + len; + else + offset = -tls_mac_len(en); + test_ktls_receive_corrupted_record(tc, en, seqno, len, offset); +} + +static void +test_ktls_receive_corrupted_padding(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len) +{ + ATF_REQUIRE(en->cipher_algorithm == CRYPTO_AES_CBC); + + /* Corrupt the last byte of the padding. */ + test_ktls_receive_corrupted_record(tc, en, seqno, len, -1); +} + +static void +test_ktls_receive_truncated_record(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len) +{ + char *plaintext, *outbuf; + size_t outbuf_cap, outbuf_len; + ssize_t rv; + int sockets[2]; + + ATF_REQUIRE(len <= TLS_MAX_MSG_SIZE_V10_2); + + plaintext = alloc_buffer(len); + outbuf_cap = tls_header_len(en) + len + tls_trailer_len(en); + outbuf = malloc(outbuf_cap); + + ATF_REQUIRE_MSG(open_sockets(tc, sockets), "failed to create sockets"); + + ATF_REQUIRE(setsockopt(sockets[0], IPPROTO_TCP, TCP_RXTLS_ENABLE, en, + sizeof(*en)) == 0); + check_tls_mode(tc, sockets[0], TCP_RXTLS_MODE); + + fd_set_blocking(sockets[0]); + fd_set_blocking(sockets[1]); + + outbuf_len = encrypt_tls_record(en, TLS_RLTYPE_APP, seqno, + plaintext, len, outbuf, outbuf_cap, 0); + + rv = write(sockets[1], outbuf, outbuf_len / 2); + ATF_REQUIRE(rv == (ssize_t)(outbuf_len / 2)); + + ATF_REQUIRE(shutdown(sockets[1], SHUT_WR) == 0); + + ktls_receive_tls_error(sockets[0], EMSGSIZE); + + free(outbuf); + free(plaintext); + + close_sockets(sockets); +} + +static void +test_ktls_receive_bad_major(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len) +{ + struct tls_record_layer *hdr; + char *plaintext, *outbuf; + size_t outbuf_cap, outbuf_len; + ssize_t rv; + int sockets[2]; + + ATF_REQUIRE(len <= TLS_MAX_MSG_SIZE_V10_2); + + plaintext = alloc_buffer(len); + outbuf_cap = tls_header_len(en) + len + tls_trailer_len(en); + outbuf = malloc(outbuf_cap); + + ATF_REQUIRE_MSG(open_sockets(tc, sockets), "failed to create sockets"); + + ATF_REQUIRE(setsockopt(sockets[0], IPPROTO_TCP, TCP_RXTLS_ENABLE, en, + sizeof(*en)) == 0); + check_tls_mode(tc, sockets[0], TCP_RXTLS_MODE); + + fd_set_blocking(sockets[0]); + fd_set_blocking(sockets[1]); + + outbuf_len = encrypt_tls_record(en, TLS_RLTYPE_APP, seqno, + plaintext, len, outbuf, outbuf_cap, 0); + + hdr = (void *)outbuf; + hdr->tls_vmajor++; + + rv = write(sockets[1], outbuf, outbuf_len); + ATF_REQUIRE(rv == (ssize_t)outbuf_len); + + ktls_receive_tls_error(sockets[0], EINVAL); + + free(outbuf); + free(plaintext); + + close_sockets(sockets); +} + +static void +test_ktls_receive_bad_minor(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len) +{ + struct tls_record_layer *hdr; + char *plaintext, *outbuf; + size_t outbuf_cap, outbuf_len; + ssize_t rv; + int sockets[2]; + + ATF_REQUIRE(len <= TLS_MAX_MSG_SIZE_V10_2); + + plaintext = alloc_buffer(len); + outbuf_cap = tls_header_len(en) + len + tls_trailer_len(en); + outbuf = malloc(outbuf_cap); + + ATF_REQUIRE_MSG(open_sockets(tc, sockets), "failed to create sockets"); + + ATF_REQUIRE(setsockopt(sockets[0], IPPROTO_TCP, TCP_RXTLS_ENABLE, en, + sizeof(*en)) == 0); + check_tls_mode(tc, sockets[0], TCP_RXTLS_MODE); + + fd_set_blocking(sockets[0]); + fd_set_blocking(sockets[1]); + + outbuf_len = encrypt_tls_record(en, TLS_RLTYPE_APP, seqno, + plaintext, len, outbuf, outbuf_cap, 0); + + hdr = (void *)outbuf; + hdr->tls_vminor++; + + rv = write(sockets[1], outbuf, outbuf_len); + ATF_REQUIRE(rv == (ssize_t)outbuf_len); + + ktls_receive_tls_error(sockets[0], EINVAL); + + free(outbuf); + free(plaintext); + + close_sockets(sockets); +} + +static void +test_ktls_receive_bad_type(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len) +{ + struct tls_record_layer *hdr; + char *plaintext, *outbuf; + size_t outbuf_cap, outbuf_len; + ssize_t rv; + int sockets[2]; + + ATF_REQUIRE(len <= TLS_MAX_MSG_SIZE_V10_2); + ATF_REQUIRE(en->tls_vminor == TLS_MINOR_VER_THREE); + + plaintext = alloc_buffer(len); + outbuf_cap = tls_header_len(en) + len + tls_trailer_len(en); + outbuf = malloc(outbuf_cap); + + ATF_REQUIRE_MSG(open_sockets(tc, sockets), "failed to create sockets"); + + ATF_REQUIRE(setsockopt(sockets[0], IPPROTO_TCP, TCP_RXTLS_ENABLE, en, + sizeof(*en)) == 0); + check_tls_mode(tc, sockets[0], TCP_RXTLS_MODE); + + fd_set_blocking(sockets[0]); + fd_set_blocking(sockets[1]); + + outbuf_len = encrypt_tls_record(en, 0x21 /* Alert */, seqno, + plaintext, len, outbuf, outbuf_cap, 0); + + hdr = (void *)outbuf; + hdr->tls_type = TLS_RLTYPE_APP + 1; + + rv = write(sockets[1], outbuf, outbuf_len); + ATF_REQUIRE(rv == (ssize_t)outbuf_len); + + ktls_receive_tls_error(sockets[0], EINVAL); + + free(outbuf); + free(plaintext); + + close_sockets(sockets); +} + +static void +test_ktls_receive_bad_size(const atf_tc_t *tc, struct tls_enable *en, + uint64_t seqno, size_t len) +{ + struct tls_record_layer *hdr; + char *outbuf; + size_t outbuf_len; + ssize_t rv; + int sockets[2]; + + outbuf_len = sizeof(*hdr) + len; + outbuf = calloc(1, outbuf_len); + + ATF_REQUIRE_MSG(open_sockets(tc, sockets), "failed to create sockets"); + + ATF_REQUIRE(setsockopt(sockets[0], IPPROTO_TCP, TCP_RXTLS_ENABLE, en, + sizeof(*en)) == 0); + check_tls_mode(tc, sockets[0], TCP_RXTLS_MODE); + + fd_set_blocking(sockets[0]); + fd_set_blocking(sockets[1]); + + hdr = (void *)outbuf; + hdr->tls_vmajor = en->tls_vmajor; + if (en->tls_vminor == TLS_MINOR_VER_THREE) + hdr->tls_vminor = TLS_MINOR_VER_TWO; + else + hdr->tls_vminor = en->tls_vminor; + hdr->tls_type = TLS_RLTYPE_APP; + hdr->tls_length = htons(len); + + rv = write(sockets[1], outbuf, outbuf_len); + ATF_REQUIRE(rv == (ssize_t)outbuf_len); + + ATF_REQUIRE(shutdown(sockets[1], SHUT_WR) == 0); + + ktls_receive_tls_error(sockets[0], EMSGSIZE); + + free(outbuf); + + close_sockets(sockets); +} + #define TLS_10_TESTS(M) \ M(aes128_cbc_1_0_sha1, CRYPTO_AES_CBC, 128 / 8, \ CRYPTO_SHA1_HMAC, TLS_MINOR_VER_ZERO) \ @@ -1507,11 +1846,14 @@ test_ktls_receive_app_data(const atf_tc_t *tc, struct tls_enable *en, TLS_10_TESTS(M) \ AES_CBC_NONZERO_TESTS(M) -#define AES_GCM_TESTS(M) \ +#define AES_GCM_12_TESTS(M) \ M(aes128_gcm_1_2, CRYPTO_AES_NIST_GCM_16, 128 / 8, 0, \ TLS_MINOR_VER_TWO) \ M(aes256_gcm_1_2, CRYPTO_AES_NIST_GCM_16, 256 / 8, 0, \ - TLS_MINOR_VER_TWO) \ + TLS_MINOR_VER_TWO) + +#define AES_GCM_TESTS(M) \ + AES_GCM_12_TESTS(M) \ M(aes128_gcm_1_3, CRYPTO_AES_NIST_GCM_16, 128 / 8, 0, \ TLS_MINOR_VER_THREE) \ M(aes256_gcm_1_3, CRYPTO_AES_NIST_GCM_16, 256 / 8, 0, \ @@ -1789,28 +2131,191 @@ ATF_TC_BODY(ktls_receive_##cipher_name##_##name, tc) \ auth_alg, minor, name) \ ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_##name); +#define GEN_RECEIVE_BAD_DATA_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, len) \ +ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_bad_data); \ +ATF_TC_BODY(ktls_receive_##cipher_name##_bad_data, tc) \ +{ \ + struct tls_enable en; \ + uint64_t seqno; \ + \ + ATF_REQUIRE_KTLS(); \ + seqno = random(); \ + build_tls_enable(cipher_alg, key_size, auth_alg, minor, seqno, \ + &en); \ + test_ktls_receive_corrupted_data(tc, &en, seqno, len); \ + free_tls_enable(&en); \ +} + +#define ADD_RECEIVE_BAD_DATA_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_bad_data); + +#define GEN_RECEIVE_BAD_MAC_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, len) \ +ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_bad_mac); \ +ATF_TC_BODY(ktls_receive_##cipher_name##_bad_mac, tc) \ +{ \ + struct tls_enable en; \ + uint64_t seqno; \ + \ + ATF_REQUIRE_KTLS(); \ + seqno = random(); \ + build_tls_enable(cipher_alg, key_size, auth_alg, minor, seqno, \ + &en); \ + test_ktls_receive_corrupted_mac(tc, &en, seqno, len); \ + free_tls_enable(&en); \ +} + +#define ADD_RECEIVE_BAD_MAC_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_bad_mac); + +#define GEN_RECEIVE_TRUNCATED_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, len) \ +ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_truncated_record); \ +ATF_TC_BODY(ktls_receive_##cipher_name##_truncated_record, tc) \ +{ \ + struct tls_enable en; \ + uint64_t seqno; \ + \ + ATF_REQUIRE_KTLS(); \ + seqno = random(); \ + build_tls_enable(cipher_alg, key_size, auth_alg, minor, seqno, \ + &en); \ + test_ktls_receive_truncated_record(tc, &en, seqno, len); \ + free_tls_enable(&en); \ +} + +#define ADD_RECEIVE_TRUNCATED_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_truncated_record); + +#define GEN_RECEIVE_BAD_MAJOR_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, len) \ +ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_bad_major); \ +ATF_TC_BODY(ktls_receive_##cipher_name##_bad_major, tc) \ +{ \ + struct tls_enable en; \ + uint64_t seqno; \ + \ + ATF_REQUIRE_KTLS(); \ + seqno = random(); \ + build_tls_enable(cipher_alg, key_size, auth_alg, minor, seqno, \ + &en); \ + test_ktls_receive_bad_major(tc, &en, seqno, len); \ + free_tls_enable(&en); \ +} + +#define ADD_RECEIVE_BAD_MAJOR_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_bad_major); + +#define GEN_RECEIVE_BAD_MINOR_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, len) \ +ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_bad_minor); \ +ATF_TC_BODY(ktls_receive_##cipher_name##_bad_minor, tc) \ +{ \ + struct tls_enable en; \ + uint64_t seqno; \ + \ + ATF_REQUIRE_KTLS(); \ + seqno = random(); \ + build_tls_enable(cipher_alg, key_size, auth_alg, minor, seqno, \ + &en); \ + test_ktls_receive_bad_minor(tc, &en, seqno, len); \ + free_tls_enable(&en); \ +} + +#define ADD_RECEIVE_BAD_MINOR_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_bad_minor); + +#define GEN_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, name, len) \ +ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_##name); \ +ATF_TC_BODY(ktls_receive_##cipher_name##_##name, tc) \ +{ \ + struct tls_enable en; \ + uint64_t seqno; \ + \ + ATF_REQUIRE_KTLS(); \ + seqno = random(); \ + build_tls_enable(cipher_alg, key_size, auth_alg, minor, seqno, \ + &en); \ + test_ktls_receive_bad_size(tc, &en, seqno, (len)); \ + free_tls_enable(&en); \ +} + +#define ADD_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, name) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_##name); + #define GEN_RECEIVE_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, 64, 0) \ GEN_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \ - auth_alg, minor, long, 64 * 1024, 0) + auth_alg, minor, long, 64 * 1024, 0) \ + GEN_RECEIVE_BAD_DATA_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, 64) \ + GEN_RECEIVE_BAD_MAC_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, 64) \ + GEN_RECEIVE_TRUNCATED_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, 64) \ + GEN_RECEIVE_BAD_MAJOR_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, 64) \ + GEN_RECEIVE_BAD_MINOR_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, 64) \ + GEN_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, small_record, \ + tls_minimum_record_payload(&en) - 1) \ + GEN_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, oversized_record, \ + TLS_MAX_MSG_SIZE_V10_2 * 2) #define ADD_RECEIVE_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) \ ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \ - auth_alg, minor, long) + auth_alg, minor, long) \ + ADD_RECEIVE_BAD_DATA_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ADD_RECEIVE_BAD_MAC_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ADD_RECEIVE_TRUNCATED_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ADD_RECEIVE_BAD_MAJOR_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ADD_RECEIVE_BAD_MINOR_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ADD_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, small_record) \ + ADD_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, oversized_record) /* - * For each supported cipher suite, run two receive tests: + * For each supported cipher suite, run several receive tests: * * - a short test which sends 64 bytes of application data (likely as * a single TLS record) * * - a long test which sends 64KB of application data (split across * multiple TLS records) + * + * - a test with corrupted payload data in a single TLS record + * + * - a test with a corrupted MAC in a single TLS record + * + * - a test with a truncated TLS record + * + * - tests with invalid TLS major and minor versions + * + * - a tests with a record whose is one less than the smallest valid + * size + * + * - a test with an oversized TLS record */ AES_CBC_NONZERO_TESTS(GEN_RECEIVE_TESTS); AES_GCM_TESTS(GEN_RECEIVE_TESTS); @@ -1894,6 +2399,45 @@ CHACHA20_TESTS(GEN_RECEIVE_TESTS); ADD_RECEIVE_APP_DATA_TEST(cipher_name, cipher_alg, key_size, \ auth_alg, minor, padding_32_extra) +#define GEN_RECEIVE_BAD_PADDING_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, len) \ +ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_bad_padding); \ +ATF_TC_BODY(ktls_receive_##cipher_name##_bad_padding, tc) \ +{ \ + struct tls_enable en; \ + uint64_t seqno; \ + \ + ATF_REQUIRE_KTLS(); \ + seqno = random(); \ + build_tls_enable(cipher_alg, key_size, auth_alg, minor, seqno, \ + &en); \ + test_ktls_receive_corrupted_padding(tc, &en, seqno, len); \ + free_tls_enable(&en); \ +} + +#define ADD_RECEIVE_BAD_PADDING_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_bad_padding); + +#define GEN_RECEIVE_MTE_TESTS(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + GEN_RECEIVE_MTE_PADDING_TESTS(cipher_name, cipher_alg, \ + key_size, auth_alg, minor) \ + GEN_RECEIVE_BAD_PADDING_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, 64) \ + GEN_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, non_block_size, \ + tls_minimum_record_payload(&en) + 1) + +#define ADD_RECEIVE_MTE_TESTS(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ADD_RECEIVE_MTE_PADDING_TESTS(cipher_name, cipher_alg, \ + key_size, auth_alg, minor) \ + ADD_RECEIVE_BAD_PADDING_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ADD_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, non_block_size) + /* * For AES-CBC MTE cipher suites using padding, add tests of messages * with each possible padding size. Note that the padding_ tests @@ -1904,28 +2448,101 @@ CHACHA20_TESTS(GEN_RECEIVE_TESTS); * * Two additional tests check for additional padding with an extra * 16 or 32 bytes beyond the normal padding. + * + * Another test checks for corrupted padding. + * + * Another test checks for a record whose payload is not a multiple of + * the AES block size. */ -AES_CBC_NONZERO_TESTS(GEN_RECEIVE_MTE_PADDING_TESTS); +AES_CBC_NONZERO_TESTS(GEN_RECEIVE_MTE_TESTS); + +#define GEN_RECEIVE_BAD_IV_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ +ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_bad_iv); \ +ATF_TC_BODY(ktls_receive_##cipher_name##_bad_iv, tc) \ +{ \ + struct tls_enable en; \ + uint64_t seqno; \ + \ + ATF_REQUIRE_KTLS(); \ + seqno = random(); \ + build_tls_enable(cipher_alg, key_size, auth_alg, minor, seqno, \ + &en); \ + test_ktls_receive_corrupted_iv(tc, &en, seqno, 64); \ + free_tls_enable(&en); \ +} + +#define ADD_RECEIVE_BAD_IV_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_bad_iv); -#define GEN_RECEIVE_TLS13_PADDING_TESTS(cipher_name, cipher_alg, \ +#define GEN_RECEIVE_EXPLICIT_IV_TESTS(cipher_name, cipher_alg, \ key_size, auth_alg, minor) \ + GEN_RECEIVE_BAD_IV_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + GEN_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, short_header, \ + sizeof(struct tls_record_layer) + 1) + +#define ADD_RECEIVE_EXPLICIT_IV_TESTS(cipher_name, cipher_alg, \ + key_size, auth_alg, minor) \ + ADD_RECEIVE_BAD_IV_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ADD_RECEIVE_BAD_SIZE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, short_header) + +/* + * For cipher suites with an explicit IV, run a receive test where the + * explicit IV has been corrupted. Also run a receive test that sends + * a short record without a complete IV. + */ +AES_CBC_NONZERO_TESTS(GEN_RECEIVE_EXPLICIT_IV_TESTS); +AES_GCM_12_TESTS(GEN_RECEIVE_EXPLICIT_IV_TESTS); + +#define GEN_RECEIVE_BAD_TYPE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, len) \ +ATF_TC_WITHOUT_HEAD(ktls_receive_##cipher_name##_bad_type); \ +ATF_TC_BODY(ktls_receive_##cipher_name##_bad_type, tc) \ +{ \ + struct tls_enable en; \ + uint64_t seqno; \ + \ + ATF_REQUIRE_KTLS(); \ + seqno = random(); \ + build_tls_enable(cipher_alg, key_size, auth_alg, minor, seqno, \ + &en); \ + test_ktls_receive_bad_type(tc, &en, seqno, len); \ + free_tls_enable(&en); \ +} + +#define ADD_RECEIVE_BAD_TYPE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) \ + ATF_TP_ADD_TC(tp, ktls_receive_##cipher_name##_bad_type); + +#define GEN_RECEIVE_TLS13_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) + auth_alg, minor, long_padded, 64 * 1024, 15) \ + GEN_RECEIVE_BAD_TYPE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor, 64) -#define ADD_RECEIVE_TLS13_PADDING_TESTS(cipher_name, cipher_alg, \ - key_size, auth_alg, minor) \ +#define ADD_RECEIVE_TLS13_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, \ - auth_alg, minor, long_padded) + auth_alg, minor, long_padded) \ + ADD_RECEIVE_BAD_TYPE_TEST(cipher_name, cipher_alg, key_size, \ + auth_alg, minor) /* * For TLS 1.3 cipher suites, run two additional receive tests which - * use add padding to each record. + * use add padding to each record. Also run a test that uses an + * invalid "outer" record type. */ -TLS_13_TESTS(GEN_RECEIVE_TLS13_PADDING_TESTS); +TLS_13_TESTS(GEN_RECEIVE_TLS13_TESTS); static void test_ktls_invalid_receive_cipher_suite(const atf_tc_t *tc, @@ -2064,8 +2681,10 @@ ATF_TP_ADD_TCS(tp) AES_CBC_NONZERO_TESTS(ADD_RECEIVE_TESTS); AES_GCM_TESTS(ADD_RECEIVE_TESTS); CHACHA20_TESTS(ADD_RECEIVE_TESTS); - AES_CBC_NONZERO_TESTS(ADD_RECEIVE_MTE_PADDING_TESTS); - TLS_13_TESTS(ADD_RECEIVE_TLS13_PADDING_TESTS); + AES_CBC_NONZERO_TESTS(ADD_RECEIVE_MTE_TESTS); + AES_CBC_NONZERO_TESTS(ADD_RECEIVE_EXPLICIT_IV_TESTS); + AES_GCM_12_TESTS(ADD_RECEIVE_EXPLICIT_IV_TESTS); + TLS_13_TESTS(ADD_RECEIVE_TLS13_TESTS); INVALID_CIPHER_SUITES(ADD_INVALID_RECEIVE_TEST); /* Miscellaneous */