Skip to content

Commit

Permalink
Merge branch 'bugfix/wifi_backport_v5.1' into 'release/v5.1'
Browse files Browse the repository at this point in the history
esp_wifi: backport some wifi fixes to v5.1

See merge request espressif/esp-idf!23847
  • Loading branch information
jack0c committed May 19, 2023
2 parents 829fdd1 + 3ef8c77 commit 057cf2b
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 263 deletions.
5 changes: 2 additions & 3 deletions components/esp_wifi/include/esp_wifi_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ typedef struct {
uint32_t transition_disable:1; /**< Whether to enable transition disable feature */
uint32_t reserved:26; /**< Reserved for future feature set */
wifi_sae_pwe_method_t sae_pwe_h2e; /**< Configuration for SAE PWE derivation method */
wifi_sae_pk_mode_t sae_pk_mode; /**< SAE-PK mode */
wifi_sae_pk_mode_t sae_pk_mode; /**< Configuration for SAE-PK (Public Key) Authentication method */
uint8_t failure_retry_cnt; /**< Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config.
Note: Enabling this may cause connection time to increase incase best AP doesn't behave properly. */
uint32_t he_dcm_set:1; /**< Whether DCM max.constellation for transmission and reception is set. */
Expand Down Expand Up @@ -702,8 +702,7 @@ typedef struct {
char svc_info[ESP_WIFI_MAX_SVC_INFO_LEN]; /**< Service info shared in Publish frame */
uint8_t single_replied_event:1; /**< Give single Replied event or every time */
uint8_t datapath_reqd:1; /**< NAN Datapath required for the service */
uint8_t fsd_reqd:1; /**< Further Service Discovery required */
uint8_t reserved:5; /**< Reserved */
uint8_t reserved:6; /**< Reserved */
} wifi_nan_publish_cfg_t;

/**
Expand Down
15 changes: 13 additions & 2 deletions components/esp_wifi/wifi_apps/src/nan_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -989,8 +989,19 @@ esp_err_t esp_wifi_nan_get_peer_records(int *num_peer_records, uint8_t own_svc_i
MACADDR_COPY(peer_record[peer_num].peer_nmi, temp->peer_nmi);
p_ndl = nan_find_ndl(0, temp->peer_nmi);
if (p_ndl) {
peer_record[peer_num].ndp_id = p_ndl->ndp_id;
MACADDR_COPY(peer_record[peer_num].peer_ndi, p_ndl->peer_ndi);
if (p_ndl->own_role == ESP_NAN_PUBLISH) {
if (p_ndl->publisher_id == own_svc_id) {
peer_record[peer_num].ndp_id = p_ndl->ndp_id;
MACADDR_COPY(peer_record[peer_num].peer_ndi, p_ndl->peer_ndi);
}
} else if (p_ndl->own_role == ESP_NAN_SUBSCRIBE) {
struct peer_svc_info *peer_info = NULL;
peer_info = nan_find_peer_svc(own_svc_id, temp->svc_id, temp->peer_nmi);
if (peer_info && peer_info->svc_id == p_ndl->publisher_id) {
peer_record[peer_num].ndp_id = p_ndl->ndp_id;
MACADDR_COPY(peer_record[peer_num].peer_ndi, p_ndl->peer_ndi);
}
}
} else {
peer_record[peer_num].ndp_id = 0;
MACADDR_COPY(peer_record[peer_num].peer_ndi, null_mac);
Expand Down
2 changes: 1 addition & 1 deletion components/lwip/lwip
Submodule lwip updated 1 files
+1 −0 src/api/netdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1222,275 +1222,24 @@ struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
return sh_secret;
}

static int crypto_ec_key_load_group_from_der_params(mbedtls_asn1_buf *params, mbedtls_ecp_group *group)
{
if (params == NULL) {
return -1;
}

mbedtls_ecp_group_id grp_id;
if (params->tag == MBEDTLS_ASN1_OID) {
if (mbedtls_oid_get_ec_grp(params, &grp_id) != 0) {
return -1;
}
} else {
return -1;
}

if (group->id != MBEDTLS_ECP_DP_NONE && group->id != grp_id) {
return -1;
}
if (mbedtls_ecp_group_load(group, grp_id) != 0) {
return -1;
}
return 0;
}

static bool crypto_ec_key_is_compressed(const u8 *der, size_t der_len)
{
size_t len;
size_t prime_len;
const unsigned char *end = der + der_len;
const unsigned char *p;
*(const unsigned char **)&p = der;


if (mbedtls_asn1_get_tag((unsigned char **)&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return false;
}

end = p + len;
mbedtls_asn1_buf alg_oid;
mbedtls_asn1_buf params;
memset(&params, 0, sizeof(mbedtls_asn1_buf));
if (mbedtls_asn1_get_alg((unsigned char **)&p, end, &alg_oid, &params) != 0) {
return false;
}


if (mbedtls_asn1_get_bitstring_null((unsigned char **)&p, end, &len) != 0) {
return false;
}

mbedtls_ecp_group *group = os_malloc(sizeof(mbedtls_ecp_group));
if (!group) {
return false;
}
mbedtls_ecp_group_init(group);
if (crypto_ec_key_load_group_from_der_params(&params, group) != 0) {
goto _err;
}

prime_len = mbedtls_mpi_size(&group->P);

if (mbedtls_ecp_get_type(group) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS
&& (end - p) == 1+prime_len
&& (*p == 0x02 || *p == 0x03)) {
mbedtls_ecp_group_free(group);
os_free(group);
return true;
}

_err:
mbedtls_ecp_group_free(group);
os_free(group);
return false;
}

/* See https://github.com/Mbed-TLS/mbedtls/pull/6282 and https://github.com/mwarning/mbedtls_ecp_compression for more details*/
static struct crypto_ec_key* crypto_ec_key_parse_compressed_pub(const u8 *der, size_t der_len)
struct crypto_ec_key *crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
{

mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
const mbedtls_pk_info_t *pk_info;
mbedtls_pk_context *pkey = NULL;
int ret;
size_t len;
size_t prime_len;
const unsigned char *end = der + der_len;
const unsigned char *p;
*(const unsigned char **)&p = der;
int parity_bit;


if ((ret = mbedtls_asn1_get_tag((unsigned char **)&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return NULL;
}

end = p + len;
mbedtls_asn1_buf alg_oid;
mbedtls_asn1_buf params;
memset(&params, 0, sizeof(mbedtls_asn1_buf));
if ((ret = mbedtls_asn1_get_alg((unsigned char **)&p, end, &alg_oid, &params)) != 0) {
return NULL;
}

if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0) {
return NULL;
}

if ((ret = mbedtls_asn1_get_bitstring_null((unsigned char **)&p, end, &len)) != 0) {
return NULL;
}

if (p + len != end) {
return NULL;
}

if ((pk_info = mbedtls_pk_info_from_type(pk_alg)) == NULL) {
return NULL;
}

if (!(pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH)) {
return NULL;
}

mbedtls_ecp_group *group = os_malloc(sizeof(mbedtls_ecp_group));
if (!group) {
return NULL;
}
mbedtls_ecp_group_init(group);

if ((ret = crypto_ec_key_load_group_from_der_params(&params, group)) != 0) {
mbedtls_ecp_group_free(group);
os_free(group);
return NULL;
}

/* Check prerequisite p = 3 mod 4 */
if (mbedtls_mpi_get_bit(&group->P, 0) != 1 ||
mbedtls_mpi_get_bit(&group->P, 1) != 1) {
mbedtls_ecp_group_free(group);
os_free(group);
return NULL;
}

prime_len = mbedtls_mpi_size(&group->P);
mbedtls_pk_context *pkey = os_zalloc(sizeof(*pkey));

unsigned char *new_der = os_malloc(sizeof(unsigned char)*(der_len+prime_len));
if (!new_der) {
mbedtls_ecp_group_free(group);
os_free(group);
if (!pkey) {
return NULL;
}
os_memcpy(new_der, der, der_len);
int offset = p - (unsigned char *)der ;
unsigned char *key_start = (unsigned char *)new_der + offset;
unsigned int new_der_len = der_len + prime_len;

mbedtls_mpi y;
mbedtls_mpi x;
mbedtls_mpi n;


mbedtls_mpi_init(&y);
mbedtls_mpi_init(&x);
mbedtls_mpi_init(&n);

MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&x, key_start + 1, prime_len));
parity_bit = key_start[0] & 1;

/* w = y^2 = x^3 + ax + b
* y = sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4)
* use y to store intermediate results*/

/* y = x^2 */
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&y, &x, &x));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&y, &y, &group->P));

/* y = x^2 + a */
if (group->A.MBEDTLS_PRIVATE(p) == NULL) {
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&n, -3));
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&y, &y, &n));
} else {
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&y, &y, &group->A));
}
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&y, &y, &group->P));

/* y = x^3 + ax */
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&y, &y, &x));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&y, &y, &group->P));

/* y = x^3 + ax + b */
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&y, &y, &group->B));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&y, &y, &group->P));

/* n = P + 1 */
MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&n, &group->P, 1));

/* n = (P + 1) / 4 */
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&n, 2));

/* y ^ ((P + 1) / 4) (mod p) */
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&y, &y, &n, &group->P, NULL));

/* check parity bit match or else invert Y */
/* This quick inversion implementation is valid because Y != 0 for all
* Short Weierstrass curves supported by mbedtls, as each supported curve
* has an order that is a large prime, so each supported curve does not
* have any point of order 2, and a point with Y == 0 would be of order 2 */

if (mbedtls_mpi_get_bit(&y, 0) != parity_bit) {
/* y = p - y */
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&y, &group->P, &y));
}

/* y => output */
ret = mbedtls_mpi_write_binary(&y, key_start + 1 + prime_len, prime_len);

key_start[0] = 0x04;

pkey = os_zalloc(sizeof(*pkey));
if (!pkey) {
goto cleanup;
}
mbedtls_pk_init(pkey);
mbedtls_pk_setup(pkey, pk_info);

mbedtls_ecp_group_copy(&mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp), (const mbedtls_ecp_group *)group);

if ((ret = mbedtls_ecp_point_read_binary(group, &mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(Q),
(const unsigned char *)key_start, (new_der + new_der_len - key_start))) == 0) {
ret = mbedtls_ecp_check_pubkey(&mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp), &mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(Q));
}
ret = mbedtls_pk_parse_public_key(pkey, der, der_len);

if (ret < 0) {
wpa_printf(MSG_ERROR, "failed to parse ec public key");
mbedtls_ecp_group_free(group);
os_free(group);
os_free(new_der);
mbedtls_pk_free(pkey);
os_free(pkey);
return NULL;
}

cleanup:
mbedtls_mpi_free(&y);
mbedtls_mpi_free(&x);
mbedtls_mpi_free(&n);
mbedtls_ecp_group_free(group);
os_free(group);
os_free(new_der);

return (struct crypto_ec_key *)pkey;
}

struct crypto_ec_key *crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
{
mbedtls_pk_context *pkey = NULL;

if (crypto_ec_key_is_compressed(der, der_len)) {
pkey = (mbedtls_pk_context *)crypto_ec_key_parse_compressed_pub(der, der_len);
if (!pkey) {
wpa_printf(MSG_ERROR, "failed to parse ec public key");
return NULL;
}
} else {
wpa_printf(MSG_ERROR, "failed to parse ec public key. expected compressed format");
return NULL;
}
return (struct crypto_ec_key *)pkey;
}

Expand Down
1 change: 1 addition & 0 deletions components/wpa_supplicant/esp_supplicant/src/esp_dpp.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ esp_err_t esp_supp_dpp_start_listen(void)
return ESP_ERR_INVALID_STATE;
}

s_dpp_stop_listening = false;
return esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ int wpa_sta_connect(uint8_t *bssid)

void wpa_config_done(void)
{
/* used in future for setting scan and assoc IEs */
esp_set_scan_ie();
}

int wpa_parse_wpa_ie_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data)
Expand Down
6 changes: 6 additions & 0 deletions components/wpa_supplicant/src/rsn_supp/wpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ wifi_cipher_type_t cipher_type_map_supp_to_public(unsigned wpa_cipher)
case WPA_CIPHER_SMS4:
return WIFI_CIPHER_TYPE_SMS4;

case WPA_CIPHER_GCMP:
return WIFI_CIPHER_TYPE_GCMP;

case WPA_CIPHER_GCMP_256:
return WIFI_CIPHER_TYPE_GCMP256;

default:
return WIFI_CIPHER_TYPE_UNKNOWN;
}
Expand Down
21 changes: 21 additions & 0 deletions examples/wifi/scan/main/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ static void print_cipher_type(int pairwise_cipher, int group_cipher)
case WIFI_CIPHER_TYPE_TKIP_CCMP:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
break;
case WIFI_CIPHER_TYPE_AES_CMAC128:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_AES_CMAC128");
break;
case WIFI_CIPHER_TYPE_SMS4:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_SMS4");
break;
case WIFI_CIPHER_TYPE_GCMP:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_GCMP");
break;
case WIFI_CIPHER_TYPE_GCMP256:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_GCMP256");
break;
default:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
break;
Expand All @@ -103,6 +115,15 @@ static void print_cipher_type(int pairwise_cipher, int group_cipher)
case WIFI_CIPHER_TYPE_TKIP_CCMP:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
break;
case WIFI_CIPHER_TYPE_SMS4:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_SMS4");
break;
case WIFI_CIPHER_TYPE_GCMP:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_GCMP");
break;
case WIFI_CIPHER_TYPE_GCMP256:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_GCMP256");
break;
default:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
break;
Expand Down

0 comments on commit 057cf2b

Please sign in to comment.