wpa_supplicant: Add SAE handshake support for WPA3-PSK
Under WPA3-Personal, SAE authentication is used to derive PMK which is more secure and immune to offline dictionary attacks. 1. Add modules to generate SAE commit/confirm for the handshake 2. Add modules that build and parse SAE data in Auth frames 3. Add WPA3 association and key mgmt definitions 4. Invert y-bit while solving for ECC co-ordinate - Once an X co-ordinate is obtained, solving for Y co-ordinate using an elliptical curve equation results in 2 possible values, Y and (P - Y), where p is the prime number. The co-ordinates are used for deriving keys in SAE handshake. As par the 802.11 spec if LSB of X is same as LSB of Y then Y is chosen, (P - Y) otherwise. This is not what is implemented, so fix this behavior to obtain the correct Y co-ordinate.
This commit is contained in:
parent
8f5f828ad6
commit
6b76228fcb
14 changed files with 464 additions and 72 deletions
|
@ -56,6 +56,7 @@ typedef enum {
|
|||
WIFI_AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */
|
||||
WIFI_AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */
|
||||
WIFI_AUTH_WPA2_ENTERPRISE, /**< authenticate mode : WPA2_ENTERPRISE */
|
||||
WIFI_AUTH_WPA3_PSK, /**< authenticate mode : WPA3_PSK */
|
||||
WIFI_AUTH_MAX
|
||||
} wifi_auth_mode_t;
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ set(srcs "port/os_xtensa.c"
|
|||
"src/esp_supplicant/esp_wpa_main.c"
|
||||
"src/esp_supplicant/esp_wpas_glue.c"
|
||||
"src/esp_supplicant/esp_wps.c"
|
||||
"src/esp_supplicant/esp_wpa3.c"
|
||||
"src/rsn_supp/pmksa_cache.c"
|
||||
"src/rsn_supp/wpa.c"
|
||||
"src/rsn_supp/wpa_ie.c"
|
||||
|
|
|
@ -159,6 +159,7 @@
|
|||
#define WLAN_STATUS_QUERY_RESP_OUTSTANDING 95
|
||||
#define WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL 99
|
||||
#define WLAN_STATUS_ASSOC_DENIED_NO_VHT 104
|
||||
#define WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER 123
|
||||
|
||||
/* Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) */
|
||||
#define WLAN_REASON_UNSPECIFIED 1
|
||||
|
@ -225,6 +226,32 @@
|
|||
#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74
|
||||
#define WLAN_EID_MMIE 76
|
||||
#define WLAN_EID_VENDOR_SPECIFIC 221
|
||||
#define WLAN_EID_CAG_NUMBER 237
|
||||
#define WLAN_EID_AP_CSN 239
|
||||
#define WLAN_EID_FILS_INDICATION 240
|
||||
#define WLAN_EID_DILS 241
|
||||
#define WLAN_EID_FRAGMENT 242
|
||||
#define WLAN_EID_EXTENSION 255
|
||||
|
||||
/* Element ID Extension (EID 255) values */
|
||||
#define WLAN_EID_EXT_ASSOC_DELAY_INFO 1
|
||||
#define WLAN_EID_EXT_FILS_REQ_PARAMS 2
|
||||
#define WLAN_EID_EXT_FILS_KEY_CONFIRM 3
|
||||
#define WLAN_EID_EXT_FILS_SESSION 4
|
||||
#define WLAN_EID_EXT_FILS_HLP_CONTAINER 5
|
||||
#define WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN 6
|
||||
#define WLAN_EID_EXT_KEY_DELIVERY 7
|
||||
#define WLAN_EID_EXT_FILS_WRAPPED_DATA 8
|
||||
#define WLAN_EID_EXT_FTM_SYNC_INFO 9
|
||||
#define WLAN_EID_EXT_EXTENDED_REQUEST 10
|
||||
#define WLAN_EID_EXT_ESTIMATED_SERVICE_PARAMS 11
|
||||
#define WLAN_EID_EXT_FILS_PUBLIC_KEY 12
|
||||
#define WLAN_EID_EXT_FILS_NONCE 13
|
||||
#define WLAN_EID_EXT_FUTURE_CHANNEL_GUIDANCE 14
|
||||
#define WLAN_EID_EXT_OWE_DH_PARAM 32
|
||||
#define WLAN_EID_EXT_PASSWORD_IDENTIFIER 33
|
||||
#define WLAN_EID_EXT_HE_CAPABILITIES 35
|
||||
#define WLAN_EID_EXT_HE_OPERATION 36
|
||||
|
||||
|
||||
/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */
|
||||
|
|
|
@ -35,7 +35,7 @@ void bin_clear_free(void *bin, size_t len)
|
|||
}
|
||||
}
|
||||
|
||||
int sae_set_group(struct sae_data *sae, u16 group)
|
||||
int sae_set_group(struct sae_data *sae, int group)
|
||||
{
|
||||
struct sae_temporary_data *tmp;
|
||||
|
||||
|
@ -47,6 +47,8 @@ int sae_set_group(struct sae_data *sae, u16 group)
|
|||
/* First, check if this is an ECC group */
|
||||
tmp->ec = crypto_ec_init(group);
|
||||
if (tmp->ec) {
|
||||
wpa_printf(MSG_DEBUG, "SAE: Selecting supported ECC group %d",
|
||||
group);
|
||||
sae->group = group;
|
||||
tmp->prime_len = crypto_ec_prime_len(tmp->ec);
|
||||
tmp->prime = crypto_ec_get_prime(tmp->ec);
|
||||
|
@ -57,6 +59,8 @@ int sae_set_group(struct sae_data *sae, u16 group)
|
|||
/* Not an ECC group, check FFC */
|
||||
tmp->dh = dh_groups_get(group);
|
||||
if (tmp->dh) {
|
||||
wpa_printf(MSG_DEBUG, "SAE: Selecting supported FFC group %d",
|
||||
group);
|
||||
sae->group = group;
|
||||
tmp->prime_len = tmp->dh->prime_len;
|
||||
if (tmp->prime_len > SAE_MAX_PRIME_LEN) {
|
||||
|
@ -84,6 +88,8 @@ int sae_set_group(struct sae_data *sae, u16 group)
|
|||
}
|
||||
|
||||
/* Unsupported group */
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"SAE: Group %d not supported by the crypto library", group);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -105,6 +111,7 @@ void sae_clear_temp_data(struct sae_data *sae)
|
|||
crypto_ec_point_deinit(tmp->own_commit_element_ecc, 0);
|
||||
crypto_ec_point_deinit(tmp->peer_commit_element_ecc, 0);
|
||||
wpabuf_free(tmp->anti_clogging_token);
|
||||
os_free(tmp->pw_id);
|
||||
bin_clear_free(tmp, sizeof(*tmp));
|
||||
sae->tmp = NULL;
|
||||
}
|
||||
|
@ -423,12 +430,13 @@ static int get_random_qr_qnr(const u8 *prime, size_t prime_len,
|
|||
|
||||
static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
|
||||
const u8 *addr2, const u8 *password,
|
||||
size_t password_len)
|
||||
size_t password_len, const char *identifier)
|
||||
{
|
||||
u8 counter, k = 40;
|
||||
u8 addrs[2 * ETH_ALEN];
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
const u8 *addr[3];
|
||||
size_t len[3];
|
||||
size_t num_elem;
|
||||
u8 dummy_password[32];
|
||||
size_t dummy_password_len;
|
||||
int pwd_seed_odd = 0;
|
||||
|
@ -460,10 +468,13 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
|
|||
|
||||
wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
|
||||
password, password_len);
|
||||
if (identifier)
|
||||
wpa_printf(MSG_DEBUG, "SAE: password identifier: %s",
|
||||
identifier);
|
||||
|
||||
/*
|
||||
* H(salt, ikm) = HMAC-SHA256(salt, ikm)
|
||||
* base = password
|
||||
* base = password [|| identifier]
|
||||
* pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
|
||||
* base || counter)
|
||||
*/
|
||||
|
@ -471,8 +482,15 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
|
|||
|
||||
addr[0] = password;
|
||||
len[0] = password_len;
|
||||
addr[1] = &counter;
|
||||
len[1] = sizeof(counter);
|
||||
num_elem = 1;
|
||||
if (identifier) {
|
||||
addr[num_elem] = (const u8 *) identifier;
|
||||
len[num_elem] = os_strlen(identifier);
|
||||
num_elem++;
|
||||
}
|
||||
addr[num_elem] = &counter;
|
||||
len[num_elem] = sizeof(counter);
|
||||
num_elem++;
|
||||
|
||||
/*
|
||||
* Continue for at least k iterations to protect against side-channel
|
||||
|
@ -490,8 +508,8 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
|
|||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
|
||||
if (hmac_sha256_vector(addrs, sizeof(addrs), 2, addr, len,
|
||||
pwd_seed) < 0)
|
||||
if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
|
||||
addr, len, pwd_seed) < 0)
|
||||
break;
|
||||
|
||||
res = sae_test_pwd_seed_ecc(sae, pwd_seed,
|
||||
|
@ -549,12 +567,13 @@ fail:
|
|||
|
||||
static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
|
||||
const u8 *addr2, const u8 *password,
|
||||
size_t password_len)
|
||||
size_t password_len, const char *identifier)
|
||||
{
|
||||
u8 counter;
|
||||
u8 addrs[2 * ETH_ALEN];
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
const u8 *addr[3];
|
||||
size_t len[3];
|
||||
size_t num_elem;
|
||||
int found = 0;
|
||||
|
||||
if (sae->tmp->pwe_ffc == NULL) {
|
||||
|
@ -569,14 +588,21 @@ static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
|
|||
/*
|
||||
* H(salt, ikm) = HMAC-SHA256(salt, ikm)
|
||||
* pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
|
||||
* password || counter)
|
||||
* password [|| identifier] || counter)
|
||||
*/
|
||||
sae_pwd_seed_key(addr1, addr2, addrs);
|
||||
|
||||
addr[0] = password;
|
||||
len[0] = password_len;
|
||||
addr[1] = &counter;
|
||||
len[1] = sizeof(counter);
|
||||
num_elem = 1;
|
||||
if (identifier) {
|
||||
addr[num_elem] = (const u8 *) identifier;
|
||||
len[num_elem] = os_strlen(identifier);
|
||||
num_elem++;
|
||||
}
|
||||
addr[num_elem] = &counter;
|
||||
len[num_elem] = sizeof(counter);
|
||||
num_elem++;
|
||||
|
||||
for (counter = 1; !found; counter++) {
|
||||
u8 pwd_seed[SHA256_MAC_LEN];
|
||||
|
@ -589,8 +615,8 @@ static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
|
|||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
|
||||
if (hmac_sha256_vector(addrs, sizeof(addrs), 2, addr, len,
|
||||
pwd_seed) < 0)
|
||||
if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
|
||||
addr, len, pwd_seed) < 0)
|
||||
break;
|
||||
res = sae_test_pwd_seed_ffc(sae, pwd_seed, sae->tmp->pwe_ffc);
|
||||
if (res < 0)
|
||||
|
@ -697,13 +723,15 @@ fail:
|
|||
|
||||
int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
|
||||
const u8 *password, size_t password_len,
|
||||
struct sae_data *sae)
|
||||
const char *identifier, struct sae_data *sae)
|
||||
{
|
||||
if (sae->tmp == NULL ||
|
||||
(sae->tmp->ec && sae_derive_pwe_ecc(sae, addr1, addr2, password,
|
||||
password_len) < 0) ||
|
||||
password_len,
|
||||
identifier) < 0) ||
|
||||
(sae->tmp->dh && sae_derive_pwe_ffc(sae, addr1, addr2, password,
|
||||
password_len) < 0) ||
|
||||
password_len,
|
||||
identifier) < 0) ||
|
||||
sae_derive_commit(sae) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
@ -838,7 +866,7 @@ int sae_process_commit(struct sae_data *sae)
|
|||
}
|
||||
|
||||
void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
|
||||
const struct wpabuf *token)
|
||||
const struct wpabuf *token, const char *identifier)
|
||||
{
|
||||
u8 *pos;
|
||||
|
||||
|
@ -872,6 +900,16 @@ void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
|
|||
wpa_hexdump(MSG_DEBUG, "SAE: own commit-element",
|
||||
pos, sae->tmp->prime_len);
|
||||
}
|
||||
|
||||
if (identifier) {
|
||||
/* Password Identifier element */
|
||||
wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
|
||||
wpabuf_put_u8(buf, 1 + os_strlen(identifier));
|
||||
wpabuf_put_u8(buf, WLAN_EID_EXT_PASSWORD_IDENTIFIER);
|
||||
wpabuf_put_str(buf, identifier);
|
||||
wpa_printf(MSG_DEBUG, "SAE: own Password Identifier: %s",
|
||||
identifier);
|
||||
}
|
||||
}
|
||||
|
||||
u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group)
|
||||
|
@ -915,25 +953,71 @@ u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group)
|
|||
return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int sae_is_password_id_elem(const u8 *pos, const u8 *end)
|
||||
{
|
||||
int ret = end - pos >= 3 &&
|
||||
pos[0] == WLAN_EID_EXTENSION &&
|
||||
pos[1] >= 1 &&
|
||||
end - pos - 2 >= pos[1] &&
|
||||
pos[2] == WLAN_EID_EXT_PASSWORD_IDENTIFIER;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sae_parse_commit_token(struct sae_data *sae, const u8 **pos,
|
||||
const u8 *end, const u8 **token,
|
||||
size_t *token_len)
|
||||
{
|
||||
if ((sae->tmp->ec ? 3 : 2) * sae->tmp->prime_len < end - *pos) {
|
||||
size_t tlen = end - (*pos + (sae->tmp->ec ? 3 : 2) *
|
||||
sae->tmp->prime_len);
|
||||
size_t scalar_elem_len, tlen;
|
||||
const u8 *elem;
|
||||
|
||||
if (token)
|
||||
*token = NULL;
|
||||
if (token_len)
|
||||
*token_len = 0;
|
||||
|
||||
scalar_elem_len = (sae->tmp->ec ? 3 : 2) * sae->tmp->prime_len;
|
||||
if (scalar_elem_len >= (size_t) (end - *pos))
|
||||
return; /* No extra data beyond peer scalar and element */
|
||||
|
||||
/* It is a bit difficult to parse this now that there is an
|
||||
* optional variable length Anti-Clogging Token field and
|
||||
* optional variable length Password Identifier element in the
|
||||
* frame. We are sending out fixed length Anti-Clogging Token
|
||||
* fields, so use that length as a requirement for the received
|
||||
* token and check for the presence of possible Password
|
||||
* Identifier element based on the element header information.
|
||||
*/
|
||||
tlen = end - (*pos + scalar_elem_len);
|
||||
|
||||
if (tlen < SHA256_MAC_LEN) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"SAE: Too short optional data (%u octets) to include our Anti-Clogging Token",
|
||||
(unsigned int) tlen);
|
||||
return;
|
||||
}
|
||||
|
||||
elem = *pos + scalar_elem_len;
|
||||
if (sae_is_password_id_elem(elem, end)) {
|
||||
/* Password Identifier element takes out all available
|
||||
* extra octets, so there can be no Anti-Clogging token in
|
||||
* this frame. */
|
||||
return;
|
||||
}
|
||||
|
||||
elem += SHA256_MAC_LEN;
|
||||
if (sae_is_password_id_elem(elem, end)) {
|
||||
/* Password Identifier element is included in the end, so
|
||||
* remove its length from the Anti-Clogging token field. */
|
||||
tlen -= 2 + elem[1];
|
||||
}
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "SAE: Anti-Clogging Token", *pos, tlen);
|
||||
if (token)
|
||||
*token = *pos;
|
||||
if (token_len)
|
||||
*token_len = tlen;
|
||||
*pos += tlen;
|
||||
} else {
|
||||
if (token)
|
||||
*token = NULL;
|
||||
if (token_len)
|
||||
*token_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static u16 sae_parse_commit_scalar(struct sae_data *sae, const u8 **pos,
|
||||
|
@ -973,7 +1057,6 @@ static u16 sae_parse_commit_scalar(struct sae_data *sae, const u8 **pos,
|
|||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
crypto_bignum_deinit(sae->peer_commit_scalar, 0);
|
||||
sae->peer_commit_scalar = peer_scalar;
|
||||
wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-scalar",
|
||||
|
@ -983,12 +1066,12 @@ static u16 sae_parse_commit_scalar(struct sae_data *sae, const u8 **pos,
|
|||
return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static u16 sae_parse_commit_element_ecc(struct sae_data *sae, const u8 *pos,
|
||||
static u16 sae_parse_commit_element_ecc(struct sae_data *sae, const u8 **pos,
|
||||
const u8 *end)
|
||||
{
|
||||
u8 prime[SAE_MAX_ECC_PRIME_LEN];
|
||||
|
||||
if (2 * sae->tmp->prime_len > end - pos) {
|
||||
if (2 * sae->tmp->prime_len > end - *pos) {
|
||||
wpa_printf(MSG_DEBUG, "SAE: Not enough data for "
|
||||
"commit-element");
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
|
@ -999,8 +1082,8 @@ static u16 sae_parse_commit_element_ecc(struct sae_data *sae, const u8 *pos,
|
|||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
|
||||
/* element x and y coordinates < p */
|
||||
if (os_memcmp(pos, prime, sae->tmp->prime_len) >= 0 ||
|
||||
os_memcmp(pos + sae->tmp->prime_len, prime,
|
||||
if (os_memcmp(*pos, prime, sae->tmp->prime_len) >= 0 ||
|
||||
os_memcmp(*pos + sae->tmp->prime_len, prime,
|
||||
sae->tmp->prime_len) >= 0) {
|
||||
wpa_printf(MSG_DEBUG, "SAE: Invalid coordinates in peer "
|
||||
"element");
|
||||
|
@ -1008,13 +1091,13 @@ static u16 sae_parse_commit_element_ecc(struct sae_data *sae, const u8 *pos,
|
|||
}
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(x)",
|
||||
pos, sae->tmp->prime_len);
|
||||
*pos, sae->tmp->prime_len);
|
||||
wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(y)",
|
||||
pos + sae->tmp->prime_len, sae->tmp->prime_len);
|
||||
*pos + sae->tmp->prime_len, sae->tmp->prime_len);
|
||||
|
||||
crypto_ec_point_deinit(sae->tmp->peer_commit_element_ecc, 0);
|
||||
sae->tmp->peer_commit_element_ecc =
|
||||
crypto_ec_point_from_bin(sae->tmp->ec, pos);
|
||||
crypto_ec_point_from_bin(sae->tmp->ec, *pos);
|
||||
if (sae->tmp->peer_commit_element_ecc == NULL)
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
|
||||
|
@ -1024,26 +1107,28 @@ static u16 sae_parse_commit_element_ecc(struct sae_data *sae, const u8 *pos,
|
|||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
|
||||
*pos += 2 * sae->tmp->prime_len;
|
||||
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static u16 sae_parse_commit_element_ffc(struct sae_data *sae, const u8 *pos,
|
||||
static u16 sae_parse_commit_element_ffc(struct sae_data *sae, const u8 **pos,
|
||||
const u8 *end)
|
||||
{
|
||||
struct crypto_bignum *res, *one;
|
||||
const u8 one_bin[1] = { 0x01 };
|
||||
|
||||
if (sae->tmp->prime_len > end - pos) {
|
||||
if (sae->tmp->prime_len > end - *pos) {
|
||||
wpa_printf(MSG_DEBUG, "SAE: Not enough data for "
|
||||
"commit-element");
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element", pos,
|
||||
wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element", *pos,
|
||||
sae->tmp->prime_len);
|
||||
|
||||
crypto_bignum_deinit(sae->tmp->peer_commit_element_ffc, 0);
|
||||
sae->tmp->peer_commit_element_ffc =
|
||||
crypto_bignum_init_set(pos, sae->tmp->prime_len);
|
||||
crypto_bignum_init_set(*pos, sae->tmp->prime_len);
|
||||
if (sae->tmp->peer_commit_element_ffc == NULL)
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
/* 1 < element < p - 1 */
|
||||
|
@ -1071,10 +1156,12 @@ static u16 sae_parse_commit_element_ffc(struct sae_data *sae, const u8 *pos,
|
|||
}
|
||||
crypto_bignum_deinit(res, 0);
|
||||
|
||||
*pos += sae->tmp->prime_len;
|
||||
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static u16 sae_parse_commit_element(struct sae_data *sae, const u8 *pos,
|
||||
static u16 sae_parse_commit_element(struct sae_data *sae, const u8 **pos,
|
||||
const u8 *end)
|
||||
{
|
||||
if (sae->tmp->dh)
|
||||
|
@ -1082,6 +1169,41 @@ static u16 sae_parse_commit_element(struct sae_data *sae, const u8 *pos,
|
|||
return sae_parse_commit_element_ecc(sae, pos, end);
|
||||
}
|
||||
|
||||
static int sae_parse_password_identifier(struct sae_data *sae,
|
||||
const u8 *pos, const u8 *end)
|
||||
{
|
||||
wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
|
||||
pos, end - pos);
|
||||
if (!sae_is_password_id_elem(pos, end)) {
|
||||
if (sae->tmp->pw_id) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"SAE: No Password Identifier included, but expected one (%s)",
|
||||
sae->tmp->pw_id);
|
||||
return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
|
||||
}
|
||||
os_free(sae->tmp->pw_id);
|
||||
sae->tmp->pw_id = NULL;
|
||||
return WLAN_STATUS_SUCCESS; /* No Password Identifier */
|
||||
}
|
||||
|
||||
if (sae->tmp->pw_id &&
|
||||
(pos[1] - 1 != (int) os_strlen(sae->tmp->pw_id) ||
|
||||
os_memcmp(sae->tmp->pw_id, pos + 3, pos[1] - 1) != 0)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"SAE: The included Password Identifier does not match the expected one (%s)",
|
||||
sae->tmp->pw_id);
|
||||
return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
|
||||
}
|
||||
|
||||
os_free(sae->tmp->pw_id);
|
||||
sae->tmp->pw_id = os_malloc(pos[1]);
|
||||
if (!sae->tmp->pw_id)
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
os_memcpy(sae->tmp->pw_id, pos + 3, pos[1] - 1);
|
||||
sae->tmp->pw_id[pos[1] - 1] = '\0';
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
|
||||
const u8 **token, size_t *token_len, int *allowed_groups)
|
||||
{
|
||||
|
@ -1105,7 +1227,12 @@ u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
|
|||
return res;
|
||||
|
||||
/* commit-element */
|
||||
res = sae_parse_commit_element(sae, pos, end);
|
||||
res = sae_parse_commit_element(sae, &pos, end);
|
||||
if (res != WLAN_STATUS_SUCCESS)
|
||||
return res;
|
||||
|
||||
/* Optional Password Identifier element */
|
||||
res = sae_parse_password_identifier(sae, pos, end);
|
||||
if (res != WLAN_STATUS_SUCCESS)
|
||||
return res;
|
||||
|
||||
|
@ -1220,6 +1347,7 @@ void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf)
|
|||
/* Send-Confirm */
|
||||
sc = wpabuf_put(buf, 0);
|
||||
wpabuf_put_le16(buf, sae->send_confirm);
|
||||
if (sae->send_confirm < 0xffff)
|
||||
sae->send_confirm++;
|
||||
|
||||
if (sae->tmp->ec)
|
||||
|
@ -1277,4 +1405,19 @@ int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const char * sae_state_txt(enum sae_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case SAE_NOTHING:
|
||||
return "Nothing";
|
||||
case SAE_COMMITTED:
|
||||
return "Committed";
|
||||
case SAE_CONFIRMED:
|
||||
return "Confirmed";
|
||||
case SAE_ACCEPTED:
|
||||
return "Accepted";
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
|
|
|
@ -5,14 +5,12 @@
|
|||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
|
||||
#ifndef SAE_H
|
||||
#define SAE_H
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/wpa_debug.h"
|
||||
|
@ -47,6 +45,7 @@ struct sae_temporary_data {
|
|||
struct crypto_bignum *prime_buf;
|
||||
struct crypto_bignum *order_buf;
|
||||
struct wpabuf *anti_clogging_token;
|
||||
char *pw_id;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -54,32 +53,38 @@ enum {
|
|||
SAE_MSG_CONFIRM = 2,
|
||||
};
|
||||
|
||||
enum sae_state {
|
||||
SAE_NOTHING, SAE_COMMITTED, SAE_CONFIRMED, SAE_ACCEPTED
|
||||
};
|
||||
|
||||
struct sae_data {
|
||||
enum { SAE_NOTHING, SAE_COMMITTED, SAE_CONFIRMED, SAE_ACCEPTED } state;
|
||||
enum sae_state state;
|
||||
u16 send_confirm;
|
||||
u8 pmk[SAE_PMK_LEN];
|
||||
u8 pmkid[SAE_PMKID_LEN];
|
||||
struct crypto_bignum *peer_commit_scalar;
|
||||
u16 group;
|
||||
int sync;
|
||||
int group;
|
||||
unsigned int sync; /* protocol instance variable: Sync */
|
||||
u16 rc; /* protocol instance variable: Rc (received send-confirm) */
|
||||
struct sae_temporary_data *tmp;
|
||||
};
|
||||
|
||||
int sae_set_group(struct sae_data *sae, u16 group);
|
||||
int sae_set_group(struct sae_data *sae, int group);
|
||||
void sae_clear_temp_data(struct sae_data *sae);
|
||||
void sae_clear_data(struct sae_data *sae);
|
||||
|
||||
int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
|
||||
const u8 *password, size_t password_len,
|
||||
struct sae_data *sae);
|
||||
const char *identifier, struct sae_data *sae);
|
||||
int sae_process_commit(struct sae_data *sae);
|
||||
void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
|
||||
const struct wpabuf *token);
|
||||
const struct wpabuf *token, const char *identifier);
|
||||
u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
|
||||
const u8 **token, size_t *token_len, int *allowed_groups);
|
||||
void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf);
|
||||
int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len);
|
||||
u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group);
|
||||
const char * sae_state_txt(enum sae_state state);
|
||||
|
||||
#endif /* SAE_H */
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
|
|
|
@ -58,6 +58,10 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
|
|||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
|
||||
return WPA_KEY_MGMT_FT_PSK;
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
|
||||
return WPA_KEY_MGMT_SAE;
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
|
||||
return WPA_KEY_MGMT_IEEE8021X_SHA256;
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#endif /* CONFIG_IEEE80211R */
|
||||
#define RSN_AUTH_KEY_MGMT_802_1X_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
|
||||
#define RSN_AUTH_KEY_MGMT_PSK_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
|
||||
#define RSN_AUTH_KEY_MGMT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
|
||||
|
||||
#define RSN_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x0f, 0xac, 0)
|
||||
#define RSN_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
|
||||
|
|
|
@ -478,9 +478,11 @@ int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
|
|||
* such that p ≡ 3 (mod 4)
|
||||
* y_ = (y2 ^ ((p+1)/4)) mod p
|
||||
*
|
||||
* if y_bit: y = p-y_
|
||||
* else y = y_`
|
||||
* if LSB of both x and y are same: y = y_
|
||||
* else y = p - y_
|
||||
* y_bit is LSB of x
|
||||
*/
|
||||
y_bit = (y_bit != 0);
|
||||
|
||||
y_sqr = (mbedtls_mpi *) crypto_ec_point_compute_y_sqr(e, x);
|
||||
|
||||
|
@ -490,9 +492,9 @@ int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
|
|||
MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(&temp, NULL, &temp, 4));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(y, y_sqr, &temp, &e->group.P, NULL));
|
||||
|
||||
if (y_bit) {
|
||||
if (y_bit != mbedtls_mpi_get_bit(y, 0))
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(y, &e->group.P, y));
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&((mbedtls_ecp_point* )p)->X, (const mbedtls_mpi*) x));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&((mbedtls_ecp_point *)p)->Z, 1));
|
||||
} else {
|
||||
|
|
|
@ -64,7 +64,8 @@ enum {
|
|||
WPA_AUTH_CCKM = 0x06,
|
||||
WPA2_AUTH_CCKM = 0x07,
|
||||
WPA2_AUTH_PSK_SHA256= 0x08,
|
||||
WPA2_AUTH_INVALID = 0x09,
|
||||
WPA3_AUTH_PSK = 0x09,
|
||||
WPA2_AUTH_INVALID = 0x0a,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
@ -121,6 +122,10 @@ struct wpa_funcs {
|
|||
int (*wpa_parse_wpa_ie)(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data);
|
||||
int (*wpa_config_bss)(u8 *bssid);
|
||||
int (*wpa_michael_mic_failure)(u16 is_unicast);
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
u8 *(*wpa3_build_sae_msg)(u8 *bssid, u32 type, u32 *len);
|
||||
int (*wpa3_parse_sae_msg)(u8 *buf, u32 len, u32 type);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct wpa2_funcs {
|
||||
|
@ -209,6 +214,7 @@ int esp_wifi_ipc_internal(wifi_ipc_config_t *cfg, bool sync);
|
|||
int esp_wifi_register_wpa2_cb_internal(struct wpa2_funcs *cb);
|
||||
int esp_wifi_unregister_wpa2_cb_internal(void);
|
||||
bool esp_wifi_sta_prof_is_wpa2_internal(void);
|
||||
bool esp_wifi_sta_prof_is_wpa3_internal(void);
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_disable_internal(wifi_wpa2_param_t *param);
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_enable_internal(wifi_wpa2_param_t *param);
|
||||
esp_err_t esp_wifi_set_wpa2_ent_state_internal(wpa2_ent_eap_state_t state);
|
||||
|
|
165
components/wpa_supplicant/src/esp_supplicant/esp_wpa3.c
Normal file
165
components/wpa_supplicant/src/esp_supplicant/esp_wpa3.c
Normal file
|
@ -0,0 +1,165 @@
|
|||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
|
||||
#include "../common/sae.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "rsn_supp/wpa.h"
|
||||
|
||||
static struct sae_data g_sae_data;
|
||||
|
||||
int g_allowed_groups[] = { IANA_SECP256R1, 0 };
|
||||
|
||||
static struct wpabuf *wpa3_build_sae_commit(u8 *bssid)
|
||||
{
|
||||
int default_group = IANA_SECP256R1;
|
||||
struct wpabuf *buf;
|
||||
u8 own_addr[ETH_ALEN];
|
||||
const u8 *pw;
|
||||
memset(&g_sae_data, 0, sizeof(g_sae_data));
|
||||
|
||||
if (sae_set_group(&g_sae_data, default_group)) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: could not set SAE group %d", default_group);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_wifi_get_macaddr_internal(WIFI_IF_STA, own_addr);
|
||||
if (!bssid) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: cannot prepare SAE commit with no BSSID!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pw = (const u8 *)esp_wifi_sta_get_prof_password_internal();
|
||||
if (sae_prepare_commit(own_addr, bssid, pw, strlen((const char *)pw), NULL, &g_sae_data) < 0) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to prepare SAE commit!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// For reuse PWE after retry case
|
||||
// memcpy(g_sae_data.tmp->bssid, bssid, ETH_ALEN);
|
||||
|
||||
buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN);
|
||||
sae_write_commit(&g_sae_data, buf, NULL, NULL); //no token
|
||||
g_sae_data.state = SAE_COMMITTED;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static struct wpabuf *wpa3_build_sae_confirm(void)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
|
||||
if (g_sae_data.state != SAE_COMMITTED)
|
||||
return NULL;
|
||||
|
||||
buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN);
|
||||
sae_write_confirm(&g_sae_data, buf);
|
||||
g_sae_data.state = SAE_CONFIRMED;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static u8 *wpa3_build_sae_msg(u8 *bssid, u32 sae_msg_type, u32 *sae_msg_len)
|
||||
{
|
||||
struct wpabuf *buf = NULL;
|
||||
|
||||
switch (sae_msg_type) {
|
||||
case SAE_MSG_COMMIT:
|
||||
buf = wpa3_build_sae_commit(bssid);
|
||||
break;
|
||||
case SAE_MSG_CONFIRM:
|
||||
buf = wpa3_build_sae_confirm();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
*sae_msg_len = (u32)wpabuf_len(buf);
|
||||
return wpabuf_mhead_u8(buf);
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int wpa3_parse_sae_commit(u8 *buf, u32 len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (g_sae_data.state != SAE_COMMITTED) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to parse SAE commit in state(%d)!",
|
||||
g_sae_data.state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = sae_parse_commit(&g_sae_data, buf, len, NULL, 0, g_allowed_groups);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: could not parse commit(%d)", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = sae_process_commit(&g_sae_data);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: could not process commit(%d)", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wpa3_parse_sae_confirm(u8 *buf, u32 len)
|
||||
{
|
||||
if (g_sae_data.state != SAE_CONFIRMED) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to parse SAE commit in state(%d)!",
|
||||
g_sae_data.state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sae_check_confirm(&g_sae_data, buf, len);
|
||||
g_sae_data.state = SAE_ACCEPTED;
|
||||
|
||||
wpa_set_pmk(g_sae_data.pmk);
|
||||
memcpy(esp_wifi_sta_get_ap_info_prof_pmk_internal(), g_sae_data.pmk, PMK_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wpa3_parse_sae_msg(u8 *buf, u32 len, u32 sae_msg_type)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (sae_msg_type) {
|
||||
case SAE_MSG_COMMIT:
|
||||
ret = wpa3_parse_sae_commit(buf, len);
|
||||
break;
|
||||
case SAE_MSG_CONFIRM:
|
||||
ret = wpa3_parse_sae_confirm(buf, len);
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_ERROR, "wpa3: Invalid SAE msg type(%d)!",
|
||||
sae_msg_type);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb)
|
||||
{
|
||||
wpa_cb->wpa3_build_sae_msg = wpa3_build_sae_msg;
|
||||
wpa_cb->wpa3_parse_sae_msg = wpa3_parse_sae_msg;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WPA3_SAE */
|
23
components/wpa_supplicant/src/esp_supplicant/esp_wpa3_i.h
Normal file
23
components/wpa_supplicant/src/esp_supplicant/esp_wpa3_i.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ESP_WPA3_H
|
||||
#define ESP_WPA3_H
|
||||
|
||||
#include "esp_wifi_driver.h"
|
||||
|
||||
void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb);
|
||||
|
||||
#endif /* ESP_WPA3_H */
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#include "esp_wpa3_i.h"
|
||||
|
||||
void wpa_install_key(enum wpa_alg alg, u8 *addr, int key_idx, int set_tx,
|
||||
u8 *seq, size_t seq_len, u8 *key, size_t key_len, int key_entry_valid)
|
||||
|
@ -74,7 +75,7 @@ void wpa_config_profile()
|
|||
{
|
||||
if (esp_wifi_sta_prof_is_wpa_internal()) {
|
||||
wpa_set_profile(WPA_PROTO_WPA, esp_wifi_sta_get_prof_authmode_internal());
|
||||
} else if (esp_wifi_sta_prof_is_wpa2_internal()) {
|
||||
} else if (esp_wifi_sta_prof_is_wpa2_internal() || esp_wifi_sta_prof_is_wpa3_internal()) {
|
||||
wpa_set_profile(WPA_PROTO_RSN, esp_wifi_sta_get_prof_authmode_internal());
|
||||
} else {
|
||||
WPA_ASSERT(0);
|
||||
|
@ -201,6 +202,9 @@ int esp_supplicant_init(void)
|
|||
wpa_cb->wpa_parse_wpa_ie = wpa_parse_wpa_ie_wrapper;
|
||||
wpa_cb->wpa_config_bss = NULL;//wpa_config_bss;
|
||||
wpa_cb->wpa_michael_mic_failure = wpa_michael_mic_failure;
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
esp_wifi_register_wpa3_cb(wpa_cb);
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
|
||||
esp_wifi_register_wpa_cb_internal(wpa_cb);
|
||||
|
||||
|
|
|
@ -2077,6 +2077,10 @@ void wpa_set_profile(u32 wpa_proto, u8 auth_mode)
|
|||
sm->key_mgmt = WPA_KEY_MGMT_PSK; /* fixed to PSK for now */
|
||||
} else if (auth_mode == WPA2_AUTH_PSK_SHA256) {
|
||||
sm->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
|
||||
} else if (auth_mode == WPA3_AUTH_PSK) {
|
||||
sm->key_mgmt = WPA_KEY_MGMT_SAE; /* for WPA3 PSK */
|
||||
} else {
|
||||
sm->key_mgmt = WPA_KEY_MGMT_PSK; /* fixed to PSK for now */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2143,6 +2147,8 @@ wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len)
|
|||
* Here only handle passphrase string. Need extra step to handle 32B, 64Hex raw
|
||||
* PMK.
|
||||
*/
|
||||
if (sm->key_mgmt == WPA_KEY_MGMT_SAE)
|
||||
return;
|
||||
|
||||
/* This is really SLOW, so just re cacl while reset param */
|
||||
if (esp_wifi_sta_get_reset_param_internal() != 0) {
|
||||
|
|
|
@ -204,6 +204,10 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
|
|||
} else if (key_mgmt == WPA_KEY_MGMT_PSK_SHA256) {
|
||||
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
} else if (key_mgmt == WPA_KEY_MGMT_SAE) {
|
||||
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
|
||||
key_mgmt);
|
||||
|
|
Loading…
Reference in a new issue