From 8aa16b460f72b70a0e59dd302914cf3bdc281d52 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Tue, 24 Oct 2023 03:07:48 +0200 Subject: [PATCH] hostapd: fix OWE association with mbedtls The code for hostapd-mbedtls did not work when used for OWE association. When handling association requests, the buffer offsets and length assumptions were incorrect, leading to never calculating the y point, thus denying association. Also when crafting the association response, the buffer contained the trailing key-type. Fix up both issues to adhere to the specification and make hostapd-mbedtls work with the OWE security type. Signed-off-by: David Bauer --- .../hostapd/patches/998-key-expansion.patch | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 package/network/services/hostapd/patches/998-key-expansion.patch diff --git a/package/network/services/hostapd/patches/998-key-expansion.patch b/package/network/services/hostapd/patches/998-key-expansion.patch new file mode 100644 index 0000000000..69734e2f5d --- /dev/null +++ b/package/network/services/hostapd/patches/998-key-expansion.patch @@ -0,0 +1,86 @@ +--- a/src/crypto/crypto_mbedtls.c ++++ b/src/crypto/crypto_mbedtls.c +@@ -2299,25 +2299,33 @@ struct crypto_ecdh * crypto_ecdh_init2(i + struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) + { + mbedtls_ecp_group *grp = &ecdh->grp; +- size_t len = CRYPTO_EC_plen(grp); ++ size_t prime_len = CRYPTO_EC_plen(grp); ++ size_t output_len = prime_len; ++ u8 output_offset = 0; ++ u8 buf[256]; ++ + #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED + /* len */ + #endif + #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED +- if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) +- len = inc_y ? len*2+1 : len+1; ++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { ++ prime_len = inc_y ? prime_len * 2 : prime_len; ++ output_len = prime_len + 1; ++ output_offset = 1; ++ } + #endif +- struct wpabuf *buf = wpabuf_alloc(len); +- if (buf == NULL) ++ ++ if (output_len > sizeof(buf)) + return NULL; ++ + inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED; +- if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &len, +- wpabuf_mhead_u8(buf), len) == 0) { +- wpabuf_put(buf, len); +- return buf; ++ if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &output_len, ++ buf, output_len) == 0) { ++ if (output_len - output_offset < prime_len) ++ return NULL; ++ return wpabuf_alloc_copy(buf + output_offset, prime_len); + } + +- wpabuf_free(buf); + return NULL; + } + +@@ -2379,10 +2387,7 @@ struct wpabuf * crypto_ecdh_set_peerkey( + os_memcpy(buf+2, key, len); + } + len >>= 1; /*(repurpose len to prime_len)*/ +- } +- else if (key[0] == 0x02 || key[0] == 0x03) { /* (inc_y == 0) */ +- --len; /*(repurpose len to prime_len)*/ +- ++ } else { /* (inc_y == 0) */ + /* mbedtls_ecp_point_read_binary() does not currently support + * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03) + * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */ +@@ -2390,22 +2395,21 @@ struct wpabuf * crypto_ecdh_set_peerkey( + /* derive y, amend buf[] with y for UNCOMPRESSED format */ + if (sizeof(buf)-2 < len*2 || len == 0) + return NULL; ++ + buf[0] = (u8)(1+len*2); + buf[1] = 0x04; ++ os_memcpy(buf+2, key, len); ++ + mbedtls_mpi bn; + mbedtls_mpi_init(&bn); +- int ret = mbedtls_mpi_read_binary(&bn, key+1, len) +- || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, +- key[0] & 1) ++ int ret = mbedtls_mpi_read_binary(&bn, key, len) ++ || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, 0) + || mbedtls_mpi_write_binary(&bn, buf+2+len, len); + mbedtls_mpi_free(&bn); + if (ret != 0) + return NULL; + } + +- if (key[0] == 0) /*(repurpose len to prime_len)*/ +- len = CRYPTO_EC_plen(grp); +- + if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0]+1)) + return NULL; + } -- 2.30.2