From 42680d30aec3f2e9305f7a45d4ef3d7d9ce2eb10 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Thu, 18 Jul 2024 14:29:31 +0530 Subject: [PATCH] fix(esp_wifi): backport some dpp fixes --- .../src/crypto/crypto_mbedtls-ec.c | 87 +++++++++++-------- .../esp_supplicant/src/esp_dpp.c | 16 ++-- 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c index c5f38fa793..b69a68288c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,8 @@ #include "mbedtls/error.h" #include "mbedtls/oid.h" -#define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES +#define ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) +#define ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) #ifdef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT #define ACCESS_ECDH(S, var) S->MBEDTLS_PRIVATE(var) @@ -518,6 +519,7 @@ struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *gro struct crypto_key *pkey = NULL; int ret; mbedtls_pk_context *key = (mbedtls_pk_context *)crypto_alloc_key(); + mbedtls_ecp_group *ecp_grp = (mbedtls_ecp_group *)group; if (!key) { wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); @@ -538,7 +540,7 @@ struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *gro goto fail; } - if (mbedtls_ecp_check_pubkey((mbedtls_ecp_group *)group, point) < 0) { //typecast + if (mbedtls_ecp_check_pubkey(ecp_grp, point) < 0) { // ideally should have failed in upper condition, duplicate code?? wpa_printf(MSG_ERROR, "Invalid key"); goto fail; @@ -547,8 +549,9 @@ struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *gro if( ( ret = mbedtls_pk_setup( key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY) ) ) != 0 ) goto fail; + mbedtls_ecp_copy(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(Q), point); - mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1); + mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(grp), ecp_grp->id); pkey = (struct crypto_key *)key; crypto_ec_point_deinit((struct crypto_ec_point *)point, 0); @@ -581,19 +584,27 @@ struct crypto_ec_point *crypto_ec_get_public_key(struct crypto_key *key) int crypto_ec_get_priv_key_der(struct crypto_key *key, unsigned char **key_data, int *key_len) { mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - char der_data[ECP_PRV_DER_MAX_BYTES]; + char *der_data = os_malloc(ECP_PRV_DER_MAX_BYTES); - *key_len = mbedtls_pk_write_key_der(pkey, (unsigned char *)der_data, ECP_PRV_DER_MAX_BYTES); - if (*key_len <= 0) + if (!der_data) { + wpa_printf(MSG_ERROR, "memory allocation failed"); return -1; - + } + *key_len = mbedtls_pk_write_key_der(pkey, (unsigned char *)der_data, ECP_PRV_DER_MAX_BYTES); + if (*key_len <= 0) { + wpa_printf(MSG_ERROR, "Failed to write priv key"); + os_free(der_data); + return -1; + } *key_data = os_malloc(*key_len); if (!*key_data) { wpa_printf(MSG_ERROR, "memory allocation failed"); + os_free(der_data); return -1; } - os_memcpy(*key_data, der_data, *key_len); + os_memcpy(*key_data, der_data + ECP_PRV_DER_MAX_BYTES - *key_len, *key_len); + os_free(der_data); return 0; } @@ -643,16 +654,25 @@ int crypto_ec_get_publickey_buf(struct crypto_key *key, u8 *key_buf, int len) int crypto_write_pubkey_der(struct crypto_key *key, unsigned char **key_buf) { - unsigned char output_buf[1600] = {0}; - int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, output_buf, 1600); - if (len <= 0) - return 0; + unsigned char *buf = os_malloc(ECP_PUB_DER_MAX_BYTES); + + if(!buf) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + return -1; + } + int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, buf, ECP_PUB_DER_MAX_BYTES); + if (len <= 0) { + os_free(buf); + return -1; + } *key_buf = os_malloc(len); if (!*key_buf) { - return 0; + os_free(buf); + return -1; } - os_memcpy(*key_buf, output_buf + 1600 - len, len); + os_memcpy(*key_buf, buf + ECP_PUB_DER_MAX_BYTES - len, len); + os_free(buf); return len; } @@ -812,28 +832,21 @@ fail: int crypto_edcsa_sign_verify(const unsigned char *hash, const struct crypto_bignum *r, const struct crypto_bignum *s, struct crypto_key *csign, int hlen) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)csign; - int ret = 0; - - mbedtls_ecdsa_context *ctx = os_malloc(sizeof(*ctx)); - if (!ctx) { - wpa_printf(MSG_ERROR, "failed to allcate memory"); - return ret; + /* (mbedtls_ecdsa_context *) */ + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)csign); + if (!ecp_kp) { + return -1; } - mbedtls_ecdsa_init(ctx); - if (mbedtls_ecdsa_from_keypair(ctx, mbedtls_pk_ec(*pkey)) < 0) - return ret; - - if((ret = mbedtls_ecdsa_verify(&ctx->MBEDTLS_PRIVATE(grp), hash, hlen, - &ctx->MBEDTLS_PRIVATE(Q), (mbedtls_mpi *)r, (mbedtls_mpi *)s)) != 0){ + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); + mbedtls_ecp_point *ecp_kp_q = &ecp_kp->MBEDTLS_PRIVATE(Q); + int ret = mbedtls_ecdsa_verify(ecp_kp_grp, hash, hlen, + ecp_kp_q, (mbedtls_mpi *)r, (mbedtls_mpi *)s); + if (ret != 0) { wpa_printf(MSG_ERROR, "ecdsa verification failed"); return ret; } - mbedtls_ecdsa_free(ctx); - os_free(ctx); - return ret; } @@ -861,14 +874,18 @@ struct crypto_key *crypto_ec_parse_subpub_key(const unsigned char *p, size_t len { int ret; mbedtls_pk_context *pkey = (mbedtls_pk_context *)crypto_alloc_key(); - ret = mbedtls_pk_parse_subpubkey((unsigned char **)&p, p + len, pkey); - if (ret < 0) { - os_free(pkey); + if (!pkey) { return NULL; } + ret = mbedtls_pk_parse_subpubkey((unsigned char **)&p, p + len, pkey); + if (ret == 0) { + return (struct crypto_key *)pkey; + } - return (struct crypto_key *)pkey; + mbedtls_pk_free(pkey); + os_free(pkey); + return NULL; } int crypto_is_ec_key(struct crypto_key *key) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index 330d78a315..08e6934c5c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -102,12 +102,12 @@ static void esp_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx) esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_AUTH_TIMEOUT); } -void esp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len, - uint8_t channel, uint32_t wait_time_ms) +static esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len, + uint8_t channel, uint32_t wait_time_ms) { wifi_action_tx_req_t *req = os_zalloc(sizeof(*req) + len);; if (!req) { - return; + return ESP_FAIL;; } req->ifx = WIFI_IF_STA; @@ -122,13 +122,15 @@ void esp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len, if (ESP_OK != esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_REQ, channel, wait_time_ms, req)) { - wpa_printf(MSG_ERROR, "DPP: Failed to perfrm offchannel operation"); + wpa_printf(MSG_ERROR, "DPP: Failed to perform offchannel operation"); esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE); os_free(req); - return; + return ESP_FAIL;; } os_free(req); + + return ESP_OK; } static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_data) @@ -175,7 +177,7 @@ static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_d own_bi, rx_param->channel, (const u8 *)&rx_param->action_frm->u.public_action.v, dpp_data, len); os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN); - esp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), + esp_dpp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg), rx_param->channel, OFFCHAN_TX_WAIT_TIME); eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL,NULL); @@ -202,7 +204,7 @@ static void gas_query_req_tx(struct dpp_authentication *auth) wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (chan %u)", MAC2STR(auth->peer_mac_addr), auth->curr_chan); - esp_send_action_frame(auth->peer_mac_addr, wpabuf_head(buf), wpabuf_len(buf), + esp_dpp_send_action_frame(auth->peer_mac_addr, wpabuf_head(buf), wpabuf_len(buf), auth->curr_chan, OFFCHAN_TX_WAIT_TIME); }