Browse Source

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.
Jouni Malinen 15 years ago
parent
commit
39eb4d0877
2 changed files with 17 additions and 16 deletions
  1. 8 7
      src/ap/wpa_auth_ft.c
  2. 9 9
      src/rsn_supp/wpa_ft.c

+ 8 - 7
src/ap/wpa_auth_ft.c

@@ -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;
 	}

+ 9 - 9
src/rsn_supp/wpa_ft.c

@@ -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.");