FT: Support BIP-CMAC-256, BIP-GMAC-128, BIP-GMAC-256 in STA case

wpa_supplicant was hardcoded to use BIP-CMAC-128 in FT protocol if PMF
was enabled. Extend that to allow the other BIP algorithms to be used as
well.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2018-06-05 21:38:01 +03:00
parent ff168f8c23
commit ef13b33afc

View file

@ -236,7 +236,10 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
/* RSN Capabilities */
capab = 0;
#ifdef CONFIG_IEEE80211W
if (sm->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC)
if (sm->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC ||
sm->mgmt_group_cipher == WPA_CIPHER_BIP_GMAC_128 ||
sm->mgmt_group_cipher == WPA_CIPHER_BIP_GMAC_256 ||
sm->mgmt_group_cipher == WPA_CIPHER_BIP_CMAC_256)
capab |= WPA_CAPABILITY_MFPC;
#endif /* CONFIG_IEEE80211W */
WPA_PUT_LE16(pos, capab);
@ -251,10 +254,24 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
pos += WPA_PMK_NAME_LEN;
#ifdef CONFIG_IEEE80211W
if (sm->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
/* Management Group Cipher Suite */
/* Management Group Cipher Suite */
switch (sm->mgmt_group_cipher) {
case WPA_CIPHER_AES_128_CMAC:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
pos += RSN_SELECTOR_LEN;
break;
case WPA_CIPHER_BIP_GMAC_128:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128);
pos += RSN_SELECTOR_LEN;
break;
case WPA_CIPHER_BIP_GMAC_256:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256);
pos += RSN_SELECTOR_LEN;
break;
case WPA_CIPHER_BIP_CMAC_256:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_CMAC_256);
pos += RSN_SELECTOR_LEN;
break;
}
#endif /* CONFIG_IEEE80211W */
@ -721,7 +738,8 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem,
static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
size_t igtk_elem_len)
{
u8 igtk[WPA_IGTK_LEN];
u8 igtk[WPA_IGTK_MAX_LEN];
size_t igtk_len;
u16 keyidx;
const u8 *kek;
size_t kek_len;
@ -734,7 +752,10 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
kek_len = sm->ptk.kek_len;
}
if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC)
if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC &&
sm->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_128 &&
sm->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_256 &&
sm->mgmt_group_cipher != WPA_CIPHER_BIP_CMAC_256)
return 0;
if (igtk_elem == NULL) {
@ -745,18 +766,19 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
wpa_hexdump_key(MSG_DEBUG, "FT: Received IGTK in Reassoc Resp",
igtk_elem, igtk_elem_len);
if (igtk_elem_len != 2 + 6 + 1 + WPA_IGTK_LEN + 8) {
igtk_len = wpa_cipher_key_len(sm->mgmt_group_cipher);
if (igtk_elem_len != 2 + 6 + 1 + igtk_len + 8) {
wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem "
"length %lu", (unsigned long) igtk_elem_len);
return -1;
}
if (igtk_elem[8] != WPA_IGTK_LEN) {
if (igtk_elem[8] != igtk_len) {
wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem Key Length "
"%d", igtk_elem[8]);
return -1;
}
if (aes_unwrap(kek, kek_len, WPA_IGTK_LEN / 8, igtk_elem + 9, igtk)) {
if (aes_unwrap(kek, kek_len, igtk_len / 8, igtk_elem + 9, igtk)) {
wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
"decrypt IGTK");
return -1;
@ -767,13 +789,16 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
keyidx = WPA_GET_LE16(igtk_elem);
wpa_hexdump_key(MSG_DEBUG, "FT: IGTK from Reassoc Resp", igtk,
WPA_IGTK_LEN);
if (wpa_sm_set_key(sm, WPA_ALG_IGTK, broadcast_ether_addr, keyidx, 0,
igtk_elem + 2, 6, igtk, WPA_IGTK_LEN) < 0) {
igtk_len);
if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
broadcast_ether_addr, keyidx, 0,
igtk_elem + 2, 6, igtk, igtk_len) < 0) {
wpa_printf(MSG_WARNING, "WPA: Failed to set IGTK to the "
"driver.");
os_memset(igtk, 0, sizeof(igtk));
return -1;
}
os_memset(igtk, 0, sizeof(igtk));
return 0;
}