SAE: Indicate AKM suite selector in commit for new AKM suites

SAE authentication needs to known which AKM suite is being used to be
able to determine the correct PMK length for the new AKM suite selectors
that use variable length keys.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2022-07-24 22:24:56 +03:00 committed by Jouni Malinen
parent e81ec0962d
commit 91010e6f67
3 changed files with 78 additions and 0 deletions

View file

@ -495,6 +495,7 @@
#define WLAN_EID_EXT_EHT_CAPABILITIES 108
#define WLAN_EID_EXT_TID_TO_LINK_MAPPING 109
#define WLAN_EID_EXT_MULTI_LINK_TRAFFIC_INDICATION 110
#define WLAN_EID_EXT_AKM_SUITE_SELECTOR 114
/* Extended Capabilities field */
#define WLAN_EXT_CAPAB_20_40_COEX 0

View file

@ -1727,6 +1727,17 @@ int sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
token);
}
if (wpa_key_mgmt_sae_ext_key(sae->akmp)) {
u32 suite = wpa_akm_to_suite(sae->akmp);
wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
wpabuf_put_u8(buf, 1 + RSN_SELECTOR_LEN);
wpabuf_put_u8(buf, WLAN_EID_EXT_AKM_SUITE_SELECTOR);
RSN_SELECTOR_PUT(wpabuf_put(buf, RSN_SELECTOR_LEN), suite);
wpa_printf(MSG_DEBUG, "SAE: AKM Suite Selector: %08x", suite);
sae->own_akm_suite_selector = suite;
}
return 0;
}
@ -1803,6 +1814,16 @@ static int sae_is_token_container_elem(const u8 *pos, const u8 *end)
}
static int sae_is_akm_suite_selector_elem(const u8 *pos, const u8 *end)
{
return end - pos >= 2 + 1 + RSN_SELECTOR_LEN &&
pos[0] == WLAN_EID_EXTENSION &&
pos[1] >= 1 + RSN_SELECTOR_LEN &&
end - pos - 2 >= pos[1] &&
pos[2] == WLAN_EID_EXT_AKM_SUITE_SELECTOR;
}
static void sae_parse_commit_token(struct sae_data *sae, const u8 **pos,
const u8 *end, const u8 **token,
size_t *token_len, int h2e)
@ -2090,6 +2111,35 @@ static int sae_parse_rejected_groups(struct sae_data *sae,
}
static int sae_parse_akm_suite_selector(struct sae_data *sae,
const u8 **pos, const u8 *end)
{
const u8 *epos;
u8 len;
wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
*pos, end - *pos);
if (!sae_is_akm_suite_selector_elem(*pos, end))
return WLAN_STATUS_SUCCESS;
epos = *pos;
epos++; /* skip IE type */
len = *epos++; /* IE length */
if (len > end - epos || len < 1)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
epos++; /* skip ext ID */
len--;
if (len < RSN_SELECTOR_LEN)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
sae->peer_akm_suite_selector = RSN_SELECTOR_GET(epos);
wpa_printf(MSG_DEBUG, "SAE: Received AKM Suite Selector: %08x",
sae->peer_akm_suite_selector);
*pos = epos + len;
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,
int h2e)
@ -2134,6 +2184,31 @@ u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
if (h2e)
sae_parse_token_container(sae, pos, end, token, token_len);
/* Conditional AKM Suite Selector element */
if (h2e) {
res = sae_parse_akm_suite_selector(sae, &pos, end);
if (res != WLAN_STATUS_SUCCESS)
return res;
}
if (sae->own_akm_suite_selector &&
sae->own_akm_suite_selector != sae->peer_akm_suite_selector) {
wpa_printf(MSG_DEBUG,
"SAE: AKM suite selector mismatch: own=%08x peer=%08x",
sae->own_akm_suite_selector,
sae->peer_akm_suite_selector);
return WLAN_STATUS_UNSPECIFIED_FAILURE;
}
if (!sae->akmp) {
if (sae->peer_akm_suite_selector ==
RSN_AUTH_KEY_MGMT_SAE_EXT_KEY)
sae->akmp = WPA_KEY_MGMT_SAE_EXT_KEY;
else if (sae->peer_akm_suite_selector ==
RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY)
sae->akmp = WPA_KEY_MGMT_FT_SAE_EXT_KEY;
}
/*
* Check whether peer-commit-scalar and PEER-COMMIT-ELEMENT are same as
* the values we sent which would be evidence of a reflection attack.

View file

@ -107,6 +107,8 @@ struct sae_data {
u8 pmk[SAE_PMK_LEN];
size_t pmk_len;
int akmp; /* WPA_KEY_MGMT_* used in key derivation */
u32 own_akm_suite_selector;
u32 peer_akm_suite_selector;
u8 pmkid[SAE_PMKID_LEN];
struct crypto_bignum *peer_commit_scalar;
struct crypto_bignum *peer_commit_scalar_accepted;