From 31ed2a2bbb5cd9e2654a7683c3872243471a8556 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Wed, 12 Apr 2023 12:14:51 +0000 Subject: [PATCH 1/2] dtls13: support Authentication and Integrity-Only Cipher Suites See RFC 9150. To enable the feature use HAVE_NULL_CIPHER compilation flag. --- src/dtls13.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/dtls13.c b/src/dtls13.c index 6149031f5..2e0f68ad6 100644 --- a/src/dtls13.c +++ b/src/dtls13.c @@ -301,6 +301,12 @@ static int Dtls13EncryptDecryptRecordNumber(WOLFSSL* ssl, byte* seq, byte mask[DTLS13_RN_MASK_SIZE]; int ret; +#ifdef HAVE_NULL_CIPHER + /* Do not encrypt record numbers with null cipher. See RFC 9150 Sec 9 */ + if (ssl->specs.bulk_cipher_algorithm == wolfssl_cipher_null) + return 0; +#endif /*HAVE_NULL_CIPHER */ + ret = Dtls13GetRnMask(ssl, ciphertext, mask, dir); if (ret != 0) return ret; @@ -2266,6 +2272,15 @@ int Dtls13SetRecordNumberKeys(WOLFSSL* ssl, enum encrypt_side side) } #endif /* HAVE_CHACHA */ +#ifdef HAVE_NULL_CIPHER + if (ssl->specs.bulk_cipher_algorithm == wolfssl_cipher_null) { +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Skipping Record Number key provisioning with null cipher"); +#endif /* WOLFSSL_DEBUG_TLS */ + return 0; + } +#endif /* HAVE_NULL_CIPHER */ + return NOT_COMPILED_IN; } From 35185e1a594e97c517c6872131a7cf3d345898e1 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Thu, 13 Apr 2023 10:00:09 +0000 Subject: [PATCH 2/2] tests: add dtls13 null cipher test --- tests/api.c | 69 ++++++++++++++++++++++++++++++++++++++++++ tests/test-dtls13.conf | 20 ++++++++++++ 2 files changed, 89 insertions(+) diff --git a/tests/api.c b/tests/api.c index d9958a5a3..450951912 100644 --- a/tests/api.c +++ b/tests/api.c @@ -65849,6 +65849,74 @@ static int test_dtls13_bad_epoch_ch(void) #endif +#if defined(HAVE_NULL_CIPHER) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \ + defined(WOLFSSL_DTLS13) +static byte* test_find_string(const char *string, + byte *buf, int buf_size) +{ + int string_size, i; + + string_size = XSTRLEN(string); + for (i = 0; i < buf_size - string_size - 1; i++) { + if (XSTRCMP((char*)&buf[i], string) == 0) + return &buf[i]; + } + return NULL; +} + +static int test_wolfSSL_dtls13_null_cipher(void) +{ + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + struct test_memio_ctx test_ctx; + const char *test_str = "test"; + int ret, test_str_size; + byte buf[255], *ptr; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + test_ctx.c_ciphers = test_ctx.s_ciphers = "TLS13-SHA256-SHA256"; + ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method); + if (ret != 0) + return TEST_FAIL; + ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL); + if (ret != 0) + return TEST_FAIL; + test_str_size = XSTRLEN("test") + 1; + ret = wolfSSL_write(ssl_c, test_str, test_str_size); + if (ret != test_str_size) + return TEST_FAIL; + ret = wolfSSL_read(ssl_s, buf, sizeof(buf)); + if (ret != test_str_size || XSTRCMP((char*)buf, test_str) != 0) + return TEST_FAIL; + + ret = wolfSSL_write(ssl_c, test_str, test_str_size); + if (ret != test_str_size) + return TEST_FAIL; + + /* check that the packet was sent cleartext */ + ptr = test_find_string(test_str, test_ctx.s_buff, test_ctx.s_len); + if (ptr == NULL) + return TEST_FAIL; + /* modify the message */ + *ptr = 'H'; + /* bad messages should be ignored in DTLS */ + ret = wolfSSL_read(ssl_s, buf, sizeof(buf)); + if (ret != -1 || ssl_s->error != WANT_READ) + return TEST_FAIL; + + wolfSSL_free(ssl_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_c); + wolfSSL_CTX_free(ctx_s); + return TEST_SUCCESS; +} +#else +static int test_wolfSSL_dtls13_null_cipher(void) +{ + return TEST_SKIPPED; +} +#endif /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -66886,6 +66954,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_harden_no_secure_renegotiation), TEST_DECL(test_override_alt_cert_chain), TEST_DECL(test_dtls13_bad_epoch_ch), + TEST_DECL(test_wolfSSL_dtls13_null_cipher), /* If at some point a stub get implemented this test should fail indicating * a need to implement a new test case */ diff --git a/tests/test-dtls13.conf b/tests/test-dtls13.conf index 0186b9a7f..57724e68c 100644 --- a/tests/test-dtls13.conf +++ b/tests/test-dtls13.conf @@ -270,3 +270,23 @@ -u -v 4 -l TLS_AES_128_GCM_SHA256 + +# server DTLSv1.3 Integrity-only SHA256 +-u +-v 4 +-l TLS13-SHA256-SHA256 + +# client DTLSv1.3 Integrity-only SHA256 +-u +-v 4 +-l TLS13-SHA256-SHA256 + +# server DTSv1.3 Integrity-only SHA384 +-u +-v 4 +-l TLS13-SHA384-SHA384 + +# client DTLSv1.3 Integrity-only SHA384 +-u +-v 4 +-l TLS13-SHA384-SHA384