fix(esp_wifi): backport some dpp fixes

This commit is contained in:
Kapil Gupta 2024-07-18 14:29:31 +05:30
parent ce8dd3997d
commit a3ef4cb054
2 changed files with 64 additions and 46 deletions

View File

@ -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
*/
@ -28,7 +28,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->var
@ -520,6 +521,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__);
@ -540,7 +542,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;
@ -549,8 +551,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);
@ -583,19 +586,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\n");
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;
}
@ -637,16 +648,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;
}
@ -806,27 +826,19 @@ 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\n");
return ret;
}
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){
wpa_printf(MSG_ERROR, "ecdsa verification failed\n");
return ret;
/* (mbedtls_ecdsa_context *) */
mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)csign);
if (!ecp_kp) {
return -1;
}
mbedtls_ecdsa_free(ctx);
os_free(ctx);
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;
}
@ -855,14 +867,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)

View File

@ -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);
}