From 89feead40a33c6a4c3bb3c5352a73e2938f672a1 Mon Sep 17 00:00:00 2001 From: Hui Bai Date: Mon, 11 Aug 2025 10:41:03 +0800 Subject: [PATCH] [noup] zephyr: Update crypto mbedtls wrapper to support TLSv1.3 Update tls_mbedtls_alt.c to support TLSv1.3 1. The TLS 1.3 key exporter mechanism is fundamentally different from TLS 1.2.The TLS 1.3 uses the HKDF for key derivation, instead of PRF used in TLS1.2. In tls_connection_export_key function, use HKDF-Expand_Label function if current tls version is TLS1.3. 2. Excluded all tls_prf_type check if TLSv1.3 flag is enabled. This type will not be used in TLSv1.3 handshake process. 3. Add protected result indication handling on EAP-peer side in tls_connection_handshake. Signed-off-by: Hui Bai --- src/crypto/tls_mbedtls_alt.c | 95 +++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 13 deletions(-) diff --git a/src/crypto/tls_mbedtls_alt.c b/src/crypto/tls_mbedtls_alt.c index 32055ec6f..186f5c897 100644 --- a/src/crypto/tls_mbedtls_alt.c +++ b/src/crypto/tls_mbedtls_alt.c @@ -58,6 +58,10 @@ #include #include #include +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) +#include <../library/ssl_misc.h> +#include <../library/ssl_tls13_keys.h> +#endif extern int (*hostap_rng_fn)(void*, unsigned char*, size_t); extern void* hostap_rng_ctx(void); @@ -469,7 +473,9 @@ void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) if (conn == NULL) return; +#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) if (conn->tls_prf_type) +#endif tls_connection_deinit_expkey(conn); #ifdef TLS_MBEDTLS_SESSION_TICKETS @@ -573,7 +579,9 @@ int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) conn->push_buf = NULL; conn->established = 0; conn->resumed = 0; +#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) if (conn->tls_prf_type) +#endif tls_connection_deinit_expkey(conn); /* RFE: prepare for session resumption? (see doc in crypto/tls.h) */ @@ -2012,8 +2020,10 @@ static void tls_connection_export_keys_cb(void *p_expkey, { struct tls_connection *conn = p_expkey; conn->tls_prf_type = tls_prf_type; +#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) if (!tls_prf_type) return; +#endif if (secret_len > sizeof(conn->expkey_secret)) { emsg(MSG_ERROR, "tls_connection_export_keys_cb secret too long"); @@ -2051,7 +2061,11 @@ static int tls_connection_export_keys_cb(void *p_expkey, int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, struct tls_random *data) { - if (!conn || !conn->tls_prf_type) + if (!conn +#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) + || !conn->tls_prf_type +#endif + ) return -1; data->client_random = conn->expkey_randbytes; data->client_random_len = MBEDTLS_EXPKEY_RAND_LEN; @@ -2070,10 +2084,29 @@ int tls_connection_export_key(void *tls_ctx, { /* (EAP-PEAP EAP-TLS EAP-TTLS) */ #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ - return (conn && conn->established && conn->tls_prf_type) ? - mbedtls_ssl_tls_prf(conn->tls_prf_type, conn->expkey_secret, conn->expkey_secret_len, label, - conn->expkey_randbytes, sizeof(conn->expkey_randbytes), out, out_len) : - -1; + if (!conn || !conn->established) + return -1; + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) +#if (MBEDTLS_VERSION_NUMBER >= 0x03040000) + if (conn->ssl.tls_version == MBEDTLS_SSL_VERSION_TLS1_3) + { + psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type( + (mbedtls_md_type_t)conn->ssl.handshake->ciphersuite_info->mac); + return mbedtls_ssl_tls13_hkdf_expand_label(hash_alg, conn->expkey_secret, + conn->expkey_secret_len, (const unsigned char *)label, + os_strlen(label), context, + context_len, out, out_len); + } + else +#endif +#endif + { + return (conn->tls_prf_type) ? + mbedtls_ssl_tls_prf(conn->tls_prf_type, conn->expkey_secret, conn->expkey_secret_len, label, + conn->expkey_randbytes, sizeof(conn->expkey_randbytes), out, out_len) : + -1; + } #else /* not implemented here for mbedtls < 2.18.0 */ return -1; @@ -2091,7 +2124,7 @@ static size_t tls_mbedtls_ssl_keyblock_size(mbedtls_ssl_context *ssl) { #if !defined(MBEDTLS_USE_PSA_CRYPTO) /* XXX: (not extracted for PSA crypto) */ #if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) + if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) return 0; /* (calculation not extracted) */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ @@ -2135,8 +2168,14 @@ static size_t tls_mbedtls_ssl_keyblock_size(mbedtls_ssl_context *ssl) int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, u8 *out, size_t out_len) { + int ret; + /* XXX: has export keys callback been run? */ - if (!conn || !conn->tls_prf_type) + if (!conn +#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) + || !conn->tls_prf_type +#endif + ) return -1; #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ @@ -2155,12 +2194,28 @@ int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, os_memcpy(seed + MBEDTLS_EXPKEY_RAND_LEN, conn->expkey_randbytes, MBEDTLS_EXPKEY_RAND_LEN); #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ - int ret = mbedtls_ssl_tls_prf(conn->tls_prf_type, conn->expkey_secret, conn->expkey_secret_len, "key expansion", + #if (MBEDTLS_VERSION_NUMBER >= 0x03040000) + if (conn->ssl.tls_version == MBEDTLS_SSL_VERSION_TLS1_3) + { + psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type( + (mbedtls_md_type_t)conn->ssl.handshake->ciphersuite_info->mac); + ret = mbedtls_ssl_tls13_hkdf_expand_label(hash_alg, conn->expkey_secret, + conn->expkey_secret_len, + (const unsigned char *)"key expansion", + os_strlen("key expansion"), seed, + sizeof(seed), tmp_out, skip + out_len); + } + else +#endif + { + ret = mbedtls_ssl_tls_prf(conn->tls_prf_type, conn->expkey_secret, + conn->expkey_secret_len, "key expansion", seed, sizeof(seed), tmp_out, skip + out_len); + } if (ret == 0) os_memcpy(out, tmp_out + skip, out_len); #else - int ret = -1; /*(not reached if not impl; return -1 at top of func)*/ + ret = -1; /*(not reached if not impl; return -1 at top of func)*/ #endif bin_clear_free(tmp_out, skip + out_len); @@ -2246,7 +2301,24 @@ struct wpabuf *tls_connection_handshake(void *tls_ctx, #endif #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ - int ret = mbedtls_ssl_handshake(&conn->ssl); + int ret = 0; + if (conn->ssl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_HANDSHAKE_OVER && + conn->ssl.MBEDTLS_PRIVATE(tls_version) == MBEDTLS_SSL_VERSION_TLS1_3) + { + int res = 0; + *appl_data = wpabuf_alloc(wpabuf_len(in_data)); + res = mbedtls_ssl_read(&conn->ssl, wpabuf_mhead(*appl_data), wpabuf_size(*appl_data)); + if (res < 0) + { + wpa_printf(MSG_DEBUG, "%s failed: 0x%x", __func__, res); + wpabuf_free(*appl_data); + ret = -1; + } + else + wpabuf_put(*appl_data, res); + } + else + ret = mbedtls_ssl_handshake(&conn->ssl); #else int ret = 0; while (conn->ssl.MBEDTLS_PRIVATE(state) != MBEDTLS_SSL_HANDSHAKE_OVER) @@ -2269,9 +2341,6 @@ struct wpabuf *tls_connection_handshake(void *tls_ctx, if (conn->push_buf == NULL) /* Need to return something to get final TLS ACK. */ conn->push_buf = wpabuf_alloc(0); - - if (appl_data /*&& conn->pull_buf && wpabuf_len(conn->pull_buf)*/) - *appl_data = NULL; /* RFE: check for application data */ break; case MBEDTLS_ERR_SSL_WANT_WRITE: case MBEDTLS_ERR_SSL_WANT_READ: