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: