Merge branch 'bugfix/static_analysis_issue_supplicant_v6.0' into 'release/v6.0'

fix(esp_wifi): Backport some fixes to v6.0

See merge request espressif/esp-idf!47651
This commit is contained in:
Jiang Jiang Jian
2026-04-30 16:30:23 +08:00
2 changed files with 98 additions and 69 deletions
@@ -1610,6 +1610,23 @@ static psa_ecc_family_t group_id_to_psa(mbedtls_ecp_group_id grp_id, size_t *bit
}
}
static size_t crypto_ecdh_output_size(const crypto_ec_key_wrapper_t *wrapper)
{
size_t key_bits = 0;
psa_ecc_family_t ecc_family;
if (!wrapper) {
return 0;
}
ecc_family = group_id_to_psa(wrapper->curve_id, &key_bits);
if (ecc_family == 0 || key_bits == 0) {
return 0;
}
return PSA_BITS_TO_BYTES(key_bits);
}
struct crypto_ec_key * crypto_ec_key_set_pub(const struct crypto_ec_group *group,
const u8 *buf, size_t len)
{
@@ -1960,46 +1977,6 @@ struct crypto_bignum *crypto_ec_key_get_private_key(struct crypto_ec_key *key)
return (struct crypto_bignum *)wrapper->cached_private_key;
}
{
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status;
size_t raw_len = 0;
size_t raw_size;
u8 *raw_key = NULL;
mbedtls_mpi *d = NULL;
status = psa_get_key_attributes(wrapper->key_id, &key_attributes);
if (status == PSA_SUCCESS) {
raw_size = PSA_EXPORT_KEY_OUTPUT_SIZE(psa_get_key_type(&key_attributes),
psa_get_key_bits(&key_attributes));
psa_reset_key_attributes(&key_attributes);
raw_key = os_malloc(raw_size);
d = os_calloc(1, sizeof(*d));
if (raw_key && d) {
status = psa_export_key(wrapper->key_id, raw_key, raw_size, &raw_len);
if (status == PSA_SUCCESS) {
mbedtls_mpi_init(d);
if (mbedtls_mpi_read_binary(d, raw_key, raw_len) == 0) {
wrapper->cached_private_key = d;
forced_memzero(raw_key, raw_size);
os_free(raw_key);
return (struct crypto_bignum *) wrapper->cached_private_key;
}
mbedtls_mpi_free(d);
}
}
if (d) {
os_free(d);
}
if (raw_key) {
forced_memzero(raw_key, raw_size);
}
os_free(raw_key);
}
}
mbedtls_pk_context *pkey_ctx = os_calloc(1, sizeof(mbedtls_pk_context));
if (!pkey_ctx) {
return NULL;
@@ -2385,10 +2362,17 @@ int crypto_ecdh(struct crypto_ec_key *key_own, struct crypto_ec_key *key_peer,
{
crypto_ec_key_wrapper_t *peer_wrapper = (crypto_ec_key_wrapper_t *)key_peer;
crypto_ec_key_wrapper_t *own_wrapper = (crypto_ec_key_wrapper_t *)key_own;
size_t secret_buf_size;
if (!peer_wrapper || !own_wrapper) {
return -1;
}
secret_buf_size = crypto_ecdh_output_size(own_wrapper);
if (secret_buf_size == 0) {
return -1;
}
#if CONFIG_MBEDTLS_HARDWARE_MPI && !CONFIG_MBEDTLS_HARDWARE_ECC
*secret_len = 0;
@@ -2405,7 +2389,8 @@ int crypto_ecdh(struct crypto_ec_key *key_own, struct crypto_ec_key *key_peer,
own_wrapper->key_id,
peer_wrapper->cached_public_key_buf,
peer_wrapper->cached_public_key_len,
secret, 66, &secret_length);
secret, secret_buf_size,
&secret_length);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "psa_raw_key_agreement failed with %d", status);
return -1;
@@ -2434,7 +2419,8 @@ int crypto_ecdh(struct crypto_ec_key *key_own, struct crypto_ec_key *key_peer,
*secret_len = 0;
size_t secret_length = 0;
status = psa_raw_key_agreement(PSA_ALG_ECDH, own_wrapper->key_id,
peer_key_buf, peer_key_len, secret, 66,
peer_key_buf, peer_key_len, secret,
secret_buf_size,
&secret_length);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "psa_raw_key_agreement failed with %d", status);
@@ -3233,6 +3219,10 @@ void crypto_ec_key_deinit(struct crypto_ec_key *key)
}
#if CONFIG_MBEDTLS_HARDWARE_MPI && !CONFIG_MBEDTLS_HARDWARE_ECC
if (wrapper->cached_public_key_buf) {
if (wrapper->cached_public_key_len) {
forced_memzero(wrapper->cached_public_key_buf,
wrapper->cached_public_key_len);
}
os_free(wrapper->cached_public_key_buf);
}
#endif
@@ -18,6 +18,8 @@
#include "common/dpp.h"
#include "sdkconfig.h"
#include "test_wpa_supplicant_common.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#ifdef CONFIG_ESP_WIFI_TESTING_OPTIONS
struct dpp_global {
@@ -42,15 +44,18 @@ static void dpp_test_clear_overrides(void)
static u32 dpp_test_prod_limit_us(void)
{
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
return 300000;
#elif SOC_ECC_SUPPORTED
#if CONFIG_MBEDTLS_HARDWARE_ECC
return 100000;
#else
return 100000;
return 325000;
#endif
}
static int dpp_test_leak_threshold(void)
{
return 800;
}
static void dpp_test_log_auth_timing(const char *label,
const struct dpp_authentication *auth)
{
@@ -66,7 +71,7 @@ static void dpp_test_log_auth_timing(const char *label,
TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]")
{
set_leak_threshold(300);
set_leak_threshold(dpp_test_leak_threshold());
/* Global variables */
char command[1200] = {0};
const u8 *frame;
@@ -165,7 +170,6 @@ TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]")
len -= 26;
auth_instance = dpp_auth_req_rx(NULL, 1, 0, NULL,
dpp_bootstrap_get_id(dpp, id), 2412, frame, frame + 6, len - 6);
TEST_ASSERT_NOT_NULL(auth_instance);
TEST_ASSERT_NOT_NULL(auth_instance->resp_msg);
dpp_test_log_auth_timing("Vector responder", auth_instance);
@@ -231,27 +235,41 @@ TEST_CASE("Test DPP responder p256 production timing", "[wpa_dpp][performance]")
int responder_id;
int initiator_id;
u32 limit_us = dpp_test_prod_limit_us();
u64 total_us = 0;
const char *failure = NULL;
set_leak_threshold(300);
set_leak_threshold(dpp_test_leak_threshold());
os_memset(&dpp_conf, 0, sizeof(dpp_conf));
dpp = dpp_global_init(&dpp_conf);
TEST_ASSERT_NOT_NULL(dpp);
if (!dpp) {
TEST_FAIL_MESSAGE("Failed to initialize DPP global context");
}
responder_id = dpp_bootstrap_gen(dpp, "type=qrcode curve=P-256");
TEST_ASSERT(responder_id > 0);
if (responder_id <= 0) {
failure = "Failed to generate responder bootstrap";
goto cleanup;
}
initiator_id = dpp_bootstrap_gen(dpp, "type=qrcode curve=P-256");
TEST_ASSERT(initiator_id > 0);
if (initiator_id <= 0) {
failure = "Failed to generate initiator bootstrap";
goto cleanup;
}
responder_bi = dpp_bootstrap_get_id(dpp, responder_id);
initiator_bi = dpp_bootstrap_get_id(dpp, initiator_id);
TEST_ASSERT_NOT_NULL(responder_bi);
TEST_ASSERT_NOT_NULL(initiator_bi);
if (!responder_bi || !initiator_bi) {
failure = "Failed to resolve bootstrap info";
goto cleanup;
}
dpp_test_clear_overrides();
initiator_auth = dpp_auth_init(NULL, responder_bi, initiator_bi,
DPP_CAPAB_CONFIGURATOR, 2412, NULL, 0);
TEST_ASSERT_NOT_NULL(initiator_auth);
TEST_ASSERT_NOT_NULL(initiator_auth->req_msg);
if (!initiator_auth || !initiator_auth->req_msg) {
failure = "Failed to initialize DPP initiator authentication";
goto cleanup;
}
frame = wpabuf_head_u8(initiator_auth->req_msg) + 2;
len = wpabuf_len(initiator_auth->req_msg) - 2;
@@ -259,36 +277,57 @@ TEST_CASE("Test DPP responder p256 production timing", "[wpa_dpp][performance]")
NULL, responder_bi, 2412,
frame, frame + DPP_HDR_LEN,
len - DPP_HDR_LEN);
TEST_ASSERT_NOT_NULL(responder_auth);
TEST_ASSERT_NOT_NULL(responder_auth->resp_msg);
if (!responder_auth || !responder_auth->resp_msg) {
failure = "Failed to process DPP authentication request";
goto cleanup;
}
dpp_test_log_auth_timing("Production responder", responder_auth);
total_us = responder_auth->auth_req_total_us;
if (limit_us) {
ESP_LOGI("DPP Test",
"Production responder timing gate(us): total=%llu limit=%u",
(unsigned long long) responder_auth->auth_req_total_us,
limit_us);
TEST_ASSERT_MESSAGE(responder_auth->auth_req_total_us <= limit_us,
"DPP responder production timing regression");
"Production responder timing gate(us): total=%llu limit=%lu",
(unsigned long long) total_us,
(unsigned long) limit_us);
}
frame = wpabuf_head_u8(responder_auth->resp_msg) + 2;
len = wpabuf_len(responder_auth->resp_msg) - 2;
conf = dpp_auth_resp_rx(initiator_auth, frame, frame + DPP_HDR_LEN,
len - DPP_HDR_LEN);
TEST_ASSERT_NOT_NULL(conf);
TEST_ASSERT_EQUAL_INT(1, initiator_auth->auth_success);
if (!conf) {
failure = "Failed to process DPP authentication response";
goto cleanup;
}
if (initiator_auth->auth_success != 1) {
failure = "Initiator authentication did not complete successfully";
goto cleanup;
}
frame = wpabuf_head_u8(conf) + 2;
len = wpabuf_len(conf) - 2;
TEST_ASSERT_EQUAL_INT(0, dpp_auth_conf_rx(responder_auth, frame,
frame + DPP_HDR_LEN,
len - DPP_HDR_LEN));
TEST_ASSERT_EQUAL_INT(1, responder_auth->auth_success);
if (dpp_auth_conf_rx(responder_auth, frame, frame + DPP_HDR_LEN,
len - DPP_HDR_LEN) != 0) {
failure = "Failed to process DPP authentication confirmation";
goto cleanup;
}
if (responder_auth->auth_success != 1) {
failure = "Responder authentication did not complete successfully";
goto cleanup;
}
cleanup:
wpabuf_free(conf);
dpp_auth_deinit(responder_auth);
dpp_auth_deinit(initiator_auth);
dpp_global_deinit(dpp);
dpp_test_clear_overrides();
if (failure) {
TEST_FAIL_MESSAGE(failure);
}
if (limit_us) {
TEST_ASSERT_MESSAGE(total_us <= limit_us,
"DPP responder production timing regression");
}
}
#endif