Preparations for variable length KCK and KEK
This modifies struct wpa_ptk to allow the length of KCK and KEK to be stored. This is needed to allow longer keys to be used, e.g., with Suite B 192-bit level. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
287eb3f9d7
commit
98cd3d1c3b
21 changed files with 401 additions and 317 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* IEEE 802.11 RSN / WPA Authenticator
|
||||
* Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -1487,7 +1487,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
|||
sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN ||
|
||||
wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) ||
|
||||
version == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
|
||||
if (aes_wrap(sm->PTK.kek, 16,
|
||||
if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len,
|
||||
(key_data_len - 8) / 8, buf,
|
||||
(u8 *) (key + 1))) {
|
||||
os_free(hdr);
|
||||
|
@ -1495,16 +1495,20 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
|||
return;
|
||||
}
|
||||
WPA_PUT_BE16(key->key_data_length, key_data_len);
|
||||
} else {
|
||||
} else if (sm->PTK.kek_len == 16) {
|
||||
u8 ek[32];
|
||||
os_memcpy(key->key_iv,
|
||||
sm->group->Counter + WPA_NONCE_LEN - 16, 16);
|
||||
inc_byte_array(sm->group->Counter, WPA_NONCE_LEN);
|
||||
os_memcpy(ek, key->key_iv, 16);
|
||||
os_memcpy(ek + 16, sm->PTK.kek, 16);
|
||||
os_memcpy(ek + 16, sm->PTK.kek, sm->PTK.kek_len);
|
||||
os_memcpy(key + 1, buf, key_data_len);
|
||||
rc4_skip(ek, 32, 256, (u8 *) (key + 1), key_data_len);
|
||||
WPA_PUT_BE16(key->key_data_length, key_data_len);
|
||||
} else {
|
||||
os_free(hdr);
|
||||
os_free(buf);
|
||||
return;
|
||||
}
|
||||
os_free(buf);
|
||||
}
|
||||
|
@ -1517,7 +1521,8 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
|||
os_free(hdr);
|
||||
return;
|
||||
}
|
||||
wpa_eapol_key_mic(sm->PTK.kck, sm->wpa_key_mgmt, version,
|
||||
wpa_eapol_key_mic(sm->PTK.kck, sm->PTK.kck_len,
|
||||
sm->wpa_key_mgmt, version,
|
||||
(u8 *) hdr, len, key->key_mic);
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
if (!pairwise &&
|
||||
|
@ -1577,7 +1582,8 @@ static int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data,
|
|||
struct wpa_eapol_key *key;
|
||||
u16 key_info;
|
||||
int ret = 0;
|
||||
u8 mic[16];
|
||||
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
|
||||
size_t mic_len = 16;
|
||||
|
||||
if (data_len < sizeof(*hdr) + sizeof(*key))
|
||||
return -1;
|
||||
|
@ -1585,13 +1591,14 @@ static int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data,
|
|||
hdr = (struct ieee802_1x_hdr *) data;
|
||||
key = (struct wpa_eapol_key *) (hdr + 1);
|
||||
key_info = WPA_GET_BE16(key->key_info);
|
||||
os_memcpy(mic, key->key_mic, 16);
|
||||
os_memset(key->key_mic, 0, 16);
|
||||
if (wpa_eapol_key_mic(PTK->kck, akmp, key_info & WPA_KEY_INFO_TYPE_MASK,
|
||||
os_memcpy(mic, key->key_mic, mic_len);
|
||||
os_memset(key->key_mic, 0, mic_len);
|
||||
if (wpa_eapol_key_mic(PTK->kck, PTK->kck_len, akmp,
|
||||
key_info & WPA_KEY_INFO_TYPE_MASK,
|
||||
data, data_len, key->key_mic) ||
|
||||
os_memcmp_const(mic, key->key_mic, 16) != 0)
|
||||
os_memcmp_const(mic, key->key_mic, mic_len) != 0)
|
||||
ret = -1;
|
||||
os_memcpy(key->key_mic, mic, 16);
|
||||
os_memcpy(key->key_mic, mic, mic_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1928,18 +1935,14 @@ SM_STATE(WPA_PTK, PTKSTART)
|
|||
static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
|
||||
const u8 *pmk, struct wpa_ptk *ptk)
|
||||
{
|
||||
size_t ptk_len = wpa_cipher_key_len(sm->pairwise) + 32;
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))
|
||||
return wpa_auth_derive_ptk_ft(sm, pmk, ptk, ptk_len);
|
||||
return wpa_auth_derive_ptk_ft(sm, pmk, ptk);
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
||||
wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
|
||||
sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce,
|
||||
(u8 *) ptk, ptk_len,
|
||||
wpa_key_mgmt_sha256(sm->wpa_key_mgmt));
|
||||
|
||||
return 0;
|
||||
return wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
|
||||
sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce,
|
||||
ptk, sm->wpa_key_mgmt, sm->pairwise);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2271,7 +2274,7 @@ SM_STATE(WPA_PTK, PTKINITDONE)
|
|||
enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise);
|
||||
int klen = wpa_cipher_key_len(sm->pairwise);
|
||||
if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
|
||||
sm->PTK.tk1, klen)) {
|
||||
sm->PTK.tk, klen)) {
|
||||
wpa_sta_disconnect(sm->wpa_auth, sm->addr);
|
||||
return;
|
||||
}
|
||||
|
@ -3171,7 +3174,7 @@ int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk,
|
|||
return -1;
|
||||
|
||||
if (pmksa_cache_auth_add(sm->wpa_auth->pmksa, pmk, PMK_LEN,
|
||||
sm->PTK.kck, sizeof(sm->PTK.kck),
|
||||
sm->PTK.kck, sm->PTK.kck_len,
|
||||
sm->wpa_auth->addr, sm->addr, session_timeout,
|
||||
eapol, sm->wpa_key_mgmt))
|
||||
return 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* hostapd - IEEE 802.11r - Fast BSS Transition
|
||||
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -362,7 +362,7 @@ static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm,
|
|||
|
||||
|
||||
int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
|
||||
struct wpa_ptk *ptk, size_t ptk_len)
|
||||
struct wpa_ptk *ptk)
|
||||
{
|
||||
u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN];
|
||||
u8 pmk_r1[PMK_LEN];
|
||||
|
@ -374,7 +374,6 @@ int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
|
|||
const u8 *ssid = sm->wpa_auth->conf.ssid;
|
||||
size_t ssid_len = sm->wpa_auth->conf.ssid_len;
|
||||
|
||||
|
||||
if (sm->xxkey_len == 0) {
|
||||
wpa_printf(MSG_DEBUG, "FT: XXKey not available for key "
|
||||
"derivation");
|
||||
|
@ -396,13 +395,9 @@ int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
|
|||
wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, sm->pmk_r1_name,
|
||||
sm->pairwise);
|
||||
|
||||
wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
|
||||
sm->wpa_auth->addr, sm->pmk_r1_name,
|
||||
(u8 *) ptk, ptk_len, ptk_name);
|
||||
wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, ptk_len);
|
||||
wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
|
||||
|
||||
return 0;
|
||||
return wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
|
||||
sm->wpa_auth->addr, sm->pmk_r1_name,
|
||||
ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise);
|
||||
}
|
||||
|
||||
|
||||
|
@ -461,7 +456,8 @@ static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len)
|
|||
WPA_PUT_LE16(&subelem[2], gsm->GN & 0x03);
|
||||
subelem[4] = gsm->GTK_len;
|
||||
wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 5);
|
||||
if (aes_wrap(sm->PTK.kek, 16, key_len / 8, key, subelem + 13)) {
|
||||
if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len, key_len / 8, key,
|
||||
subelem + 13)) {
|
||||
os_free(subelem);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -493,7 +489,7 @@ static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len)
|
|||
wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos);
|
||||
pos += 6;
|
||||
*pos++ = WPA_IGTK_LEN;
|
||||
if (aes_wrap(sm->PTK.kek, 16, WPA_IGTK_LEN / 8,
|
||||
if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len, WPA_IGTK_LEN / 8,
|
||||
gsm->IGTK[gsm->GN_igtk - 4], pos)) {
|
||||
os_free(subelem);
|
||||
return NULL;
|
||||
|
@ -745,7 +741,8 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
|
|||
ric_start = NULL;
|
||||
|
||||
if (auth_alg == WLAN_AUTH_FT &&
|
||||
wpa_ft_mic(sm->PTK.kck, sm->addr, sm->wpa_auth->addr, 6,
|
||||
wpa_ft_mic(sm->PTK.kck, sm->PTK.kck_len, sm->addr,
|
||||
sm->wpa_auth->addr, 6,
|
||||
mdie, mdie_len, ftie, ftie_len,
|
||||
rsnie, rsnie_len,
|
||||
ric_start, ric_start ? pos - ric_start : 0,
|
||||
|
@ -789,7 +786,7 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm)
|
|||
* optimized by adding the STA entry earlier.
|
||||
*/
|
||||
if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
|
||||
sm->PTK.tk1, klen))
|
||||
sm->PTK.tk, klen))
|
||||
return;
|
||||
|
||||
/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
|
||||
|
@ -807,7 +804,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
|
|||
u8 ptk_name[WPA_PMK_NAME_LEN];
|
||||
struct wpa_auth_config *conf;
|
||||
struct wpa_ft_ies parse;
|
||||
size_t buflen, ptk_len;
|
||||
size_t buflen;
|
||||
int ret;
|
||||
u8 *pos, *end;
|
||||
int pairwise;
|
||||
|
@ -892,13 +889,11 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
|
|||
wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
|
||||
sm->ANonce, WPA_NONCE_LEN);
|
||||
|
||||
ptk_len = pairwise == WPA_CIPHER_TKIP ? 64 : 48;
|
||||
wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
|
||||
sm->wpa_auth->addr, pmk_r1_name,
|
||||
(u8 *) &sm->PTK, ptk_len, ptk_name);
|
||||
wpa_hexdump_key(MSG_DEBUG, "FT: PTK",
|
||||
(u8 *) &sm->PTK, ptk_len);
|
||||
wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
|
||||
if (wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
|
||||
sm->wpa_auth->addr, pmk_r1_name,
|
||||
&sm->PTK, ptk_name, sm->wpa_key_mgmt,
|
||||
pairwise) < 0)
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
|
||||
sm->pairwise = pairwise;
|
||||
sm->PTK_valid = TRUE;
|
||||
|
@ -993,7 +988,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
|
|||
struct wpa_ft_ies parse;
|
||||
struct rsn_mdie *mdie;
|
||||
struct rsn_ftie *ftie;
|
||||
u8 mic[16];
|
||||
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
|
||||
size_t mic_len = 16;
|
||||
unsigned int count;
|
||||
|
||||
if (sm == NULL)
|
||||
|
@ -1108,7 +1104,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (wpa_ft_mic(sm->PTK.kck, sm->addr, sm->wpa_auth->addr, 5,
|
||||
if (wpa_ft_mic(sm->PTK.kck, sm->PTK.kck_len, sm->addr,
|
||||
sm->wpa_auth->addr, 5,
|
||||
parse.mdie - 2, parse.mdie_len + 2,
|
||||
parse.ftie - 2, parse.ftie_len + 2,
|
||||
parse.rsn - 2, parse.rsn_len + 2,
|
||||
|
@ -1118,12 +1115,13 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
|
|||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
}
|
||||
|
||||
if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
|
||||
if (os_memcmp_const(mic, ftie->mic, mic_len) != 0) {
|
||||
wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
|
||||
wpa_printf(MSG_DEBUG, "FT: addr=" MACSTR " auth_addr=" MACSTR,
|
||||
MAC2STR(sm->addr), MAC2STR(sm->wpa_auth->addr));
|
||||
wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", ftie->mic, 16);
|
||||
wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16);
|
||||
wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC",
|
||||
ftie->mic, mic_len);
|
||||
wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, mic_len);
|
||||
wpa_hexdump(MSG_MSGDUMP, "FT: MDIE",
|
||||
parse.mdie - 2, parse.mdie_len + 2);
|
||||
wpa_hexdump(MSG_MSGDUMP, "FT: FTIE",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* hostapd - IEEE 802.11i-2004 / WPA Authenticator: Internal definitions
|
||||
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -248,7 +248,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
|
|||
u8 *buf, size_t len, const u8 *subelem,
|
||||
size_t subelem_len);
|
||||
int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
|
||||
struct wpa_ptk *ptk, size_t ptk_len);
|
||||
struct wpa_ptk *ptk);
|
||||
struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void);
|
||||
void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache);
|
||||
void wpa_ft_install_ptk(struct wpa_state_machine *sm);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue