FT: Fix GTK subelement format in FTIE
The Key Info field was changed from 1-octet field to 2-octet field in 802.11r/D7.0, but that had not been updated in the implementation.
This commit is contained in:
parent
26e23750b9
commit
39eb4d0877
2 changed files with 17 additions and 16 deletions
|
@ -438,20 +438,21 @@ static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len)
|
|||
key = gsm->GTK[gsm->GN - 1];
|
||||
|
||||
/*
|
||||
* Sub-elem ID[1] | Length[1] | Key Info[1] | Key Length[1] | RSC[8] |
|
||||
* Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
|
||||
* Key[5..32].
|
||||
*/
|
||||
subelem_len = 12 + key_len + 8;
|
||||
subelem_len = 13 + key_len + 8;
|
||||
subelem = os_zalloc(subelem_len);
|
||||
if (subelem == NULL)
|
||||
return NULL;
|
||||
|
||||
subelem[0] = FTIE_SUBELEM_GTK;
|
||||
subelem[1] = 10 + key_len + 8;
|
||||
subelem[2] = gsm->GN & 0x03; /* Key ID in B0-B1 of Key Info */
|
||||
subelem[3] = gsm->GTK_len;
|
||||
wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 4);
|
||||
if (aes_wrap(sm->PTK.kek, key_len / 8, key, subelem + 12)) {
|
||||
subelem[1] = 11 + key_len + 8;
|
||||
/* Key ID in B0-B1 of Key Info */
|
||||
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, key_len / 8, key, subelem + 13)) {
|
||||
os_free(subelem);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -685,14 +685,14 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem,
|
|||
wpa_hexdump_key(MSG_DEBUG, "FT: Received GTK in Reassoc Resp",
|
||||
gtk_elem, gtk_elem_len);
|
||||
|
||||
if (gtk_elem_len < 10 + 24 || (gtk_elem_len - 10) % 8 ||
|
||||
gtk_elem_len - 18 > sizeof(gtk)) {
|
||||
if (gtk_elem_len < 11 + 24 || (gtk_elem_len - 11) % 8 ||
|
||||
gtk_elem_len - 19 > sizeof(gtk)) {
|
||||
wpa_printf(MSG_DEBUG, "FT: Invalid GTK sub-elem "
|
||||
"length %lu", (unsigned long) gtk_elem_len);
|
||||
return -1;
|
||||
}
|
||||
gtk_len = gtk_elem_len - 18;
|
||||
if (aes_unwrap(sm->ptk.kek, gtk_len / 8, gtk_elem + 10, gtk)) {
|
||||
gtk_len = gtk_elem_len - 19;
|
||||
if (aes_unwrap(sm->ptk.kek, gtk_len / 8, gtk_elem + 11, gtk)) {
|
||||
wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
|
||||
"decrypt GTK");
|
||||
return -1;
|
||||
|
@ -730,20 +730,20 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Key Info[1] | Key Length[1] | RSC[8] | Key[5..32]. */
|
||||
/* Key Info[2] | Key Length[1] | RSC[8] | Key[5..32]. */
|
||||
|
||||
keyidx = gtk_elem[0] & 0x03;
|
||||
keyidx = WPA_GET_LE16(gtk_elem) & 0x03;
|
||||
|
||||
if (gtk_elem[1] != keylen) {
|
||||
if (gtk_elem[2] != keylen) {
|
||||
wpa_printf(MSG_DEBUG, "FT: GTK length mismatch: received %d "
|
||||
"negotiated %lu",
|
||||
gtk_elem[1], (unsigned long) keylen);
|
||||
gtk_elem[2], (unsigned long) keylen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_hexdump_key(MSG_DEBUG, "FT: GTK from Reassoc Resp", gtk, keylen);
|
||||
if (wpa_sm_set_key(sm, alg, (u8 *) "\xff\xff\xff\xff\xff\xff",
|
||||
keyidx, 0, gtk_elem + 2, rsc_len, gtk, keylen) <
|
||||
keyidx, 0, gtk_elem + 3, rsc_len, gtk, keylen) <
|
||||
0) {
|
||||
wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the "
|
||||
"driver.");
|
||||
|
|
Loading…
Reference in a new issue