]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FT: FTE generation for SHA384-based AKM on AP
authorJouni Malinen <j@w1.fi>
Mon, 4 Jun 2018 22:31:43 +0000 (01:31 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 5 Jun 2018 17:16:37 +0000 (20:16 +0300)
The MIC field is now a variable length field, so make FTE generation in
hostapd aware of the two different field lengths.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/ieee802_11.c
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_ft.c
src/ap/wpa_auth_i.h

index 9f6d24420560398d6b953cfcedf3f1b8c3984440..2c65a1d85577a76afceb933426367f2ea539535d 100644 (file)
@@ -1446,8 +1446,11 @@ prepare_auth_resp_fils(struct hostapd_data *hapd,
        if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm))) {
                /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
                int res;
+               int use_sha384 = wpa_key_mgmt_sha384(
+                       wpa_auth_sta_key_mgmt(sta->wpa_sm));
 
-               res = wpa_auth_write_fte(hapd->wpa_auth, wpabuf_put(data, 0),
+               res = wpa_auth_write_fte(hapd->wpa_auth, use_sha384,
+                                        wpabuf_put(data, 0),
                                         wpabuf_tailroom(data));
                if (res < 0) {
                        *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
index c7e8ec7a38a6c569d413885078edea994b909c16..126d98c9f4af7202522402947306caf254677df0 100644 (file)
@@ -3014,7 +3014,10 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
                                  2 + sm->assoc_resp_ftie[1]);
                        res = 2 + sm->assoc_resp_ftie[1];
                } else {
-                       res = wpa_write_ftie(conf, conf->r0_key_holder,
+                       int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
+
+                       res = wpa_write_ftie(conf, use_sha384,
+                                            conf->r0_key_holder,
                                             conf->r0_key_holder_len,
                                             NULL, NULL, pos,
                                             kde + kde_len - pos,
@@ -4540,11 +4543,12 @@ wpa_auth_pmksa_get_fils_cache_id(struct wpa_authenticator *wpa_auth,
 
 
 #ifdef CONFIG_IEEE80211R_AP
-int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, u8 *buf, size_t len)
+int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
+                      u8 *buf, size_t len)
 {
        struct wpa_auth_config *conf = &wpa_auth->conf;
 
-       return wpa_write_ftie(conf, conf->r0_key_holder,
+       return wpa_write_ftie(conf, use_sha384, conf->r0_key_holder,
                              conf->r0_key_holder_len,
                              NULL, NULL, buf, len, NULL, 0);
 }
@@ -4714,7 +4718,10 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
                                  2 + sm->assoc_resp_ftie[1]);
                        res = 2 + sm->assoc_resp_ftie[1];
                } else {
-                       res = wpa_write_ftie(conf, conf->r0_key_holder,
+                       int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
+
+                       res = wpa_write_ftie(conf, use_sha384,
+                                            conf->r0_key_holder,
                                             conf->r0_key_holder_len,
                                             NULL, NULL, pos,
                                             kde + kde_len - pos,
index 128b6570bd62ab3cb97d3c11ce7c4c9b6e706da5..fad5536f740e93ef369d3488e52e45c2ce547902 100644 (file)
@@ -449,7 +449,8 @@ const u8 *  wpa_fils_validate_fils_session(struct wpa_state_machine *sm,
 int wpa_fils_validate_key_confirm(struct wpa_state_machine *sm, const u8 *ies,
                                  size_t ies_len);
 
-int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, u8 *buf, size_t len);
+int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
+                      u8 *buf, size_t len);
 void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm,
                                   u8 *fils_anonce, u8 *fils_snonce,
                                   u8 *fils_kek, size_t *fils_kek_len);
index 93ed12662effe09fa2549ce56da7cc963509de24..586d0a6b8dd16bcbcc1f2906a715fb3a970139b6 100644 (file)
@@ -746,30 +746,44 @@ int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len)
 }
 
 
-int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
-                  size_t r0kh_id_len,
+int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
+                  const u8 *r0kh_id, size_t r0kh_id_len,
                   const u8 *anonce, const u8 *snonce,
                   u8 *buf, size_t len, const u8 *subelem,
                   size_t subelem_len)
 {
        u8 *pos = buf, *ielen;
-       struct rsn_ftie *hdr;
+       size_t hdrlen = use_sha384 ? sizeof(struct rsn_ftie_sha384) :
+               sizeof(struct rsn_ftie);
 
-       if (len < 2 + sizeof(*hdr) + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len +
+       if (len < 2 + hdrlen + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len +
            subelem_len)
                return -1;
 
        *pos++ = WLAN_EID_FAST_BSS_TRANSITION;
        ielen = pos++;
 
-       hdr = (struct rsn_ftie *) pos;
-       os_memset(hdr, 0, sizeof(*hdr));
-       pos += sizeof(*hdr);
-       WPA_PUT_LE16(hdr->mic_control, 0);
-       if (anonce)
-               os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
-       if (snonce)
-               os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
+       if (use_sha384) {
+               struct rsn_ftie_sha384 *hdr = (struct rsn_ftie_sha384 *) pos;
+
+               os_memset(hdr, 0, sizeof(*hdr));
+               pos += sizeof(*hdr);
+               WPA_PUT_LE16(hdr->mic_control, 0);
+               if (anonce)
+                       os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
+               if (snonce)
+                       os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
+       } else {
+               struct rsn_ftie *hdr = (struct rsn_ftie *) pos;
+
+               os_memset(hdr, 0, sizeof(*hdr));
+               pos += sizeof(*hdr);
+               WPA_PUT_LE16(hdr->mic_control, 0);
+               if (anonce)
+                       os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
+               if (snonce)
+                       os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
+       }
 
        /* Optional Parameters */
        *pos++ = FTIE_SUBELEM_R1KH_ID;
@@ -2308,10 +2322,10 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
                                 const u8 *req_ies, size_t req_ies_len)
 {
        u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL;
+       u8 *fte_mic, *elem_count;
        size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0;
        int res;
        struct wpa_auth_config *conf;
-       struct rsn_ftie *_ftie;
        struct wpa_ft_ies parse;
        u8 *ric_start;
        u8 *anonce, *snonce;
@@ -2386,8 +2400,9 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
                anonce = NULL;
                snonce = NULL;
        }
-       res = wpa_write_ftie(conf, r0kh_id, r0kh_id_len, anonce, snonce, pos,
-                            end - pos, subelem, subelem_len);
+       res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len,
+                            anonce, snonce, pos, end - pos,
+                            subelem, subelem_len);
        os_free(subelem);
        if (res < 0)
                return pos;
@@ -2395,9 +2410,20 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
        ftie_len = res;
        pos += res;
 
-       _ftie = (struct rsn_ftie *) (ftie + 2);
+       if (use_sha384) {
+               struct rsn_ftie_sha384 *_ftie =
+                       (struct rsn_ftie_sha384 *) (ftie + 2);
+
+               fte_mic = _ftie->mic;
+               elem_count = &_ftie->mic_control[1];
+       } else {
+               struct rsn_ftie *_ftie = (struct rsn_ftie *) (ftie + 2);
+
+               fte_mic = _ftie->mic;
+               elem_count = &_ftie->mic_control[1];
+       }
        if (auth_alg == WLAN_AUTH_FT)
-               _ftie->mic_control[1] = 3; /* Information element count */
+               *elem_count = 3; /* Information element count */
 
        ric_start = pos;
        if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse, use_sha384) == 0
@@ -2405,7 +2431,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
                pos = wpa_ft_process_ric(sm, pos, end, parse.ric,
                                         parse.ric_len);
                if (auth_alg == WLAN_AUTH_FT)
-                       _ftie->mic_control[1] +=
+                       *elem_count +=
                                ieee802_11_ie_count(ric_start,
                                                    pos - ric_start);
        }
@@ -2424,7 +2450,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
                       mdie, mdie_len, ftie, ftie_len,
                       rsnie, rsnie_len,
                       ric_start, ric_start ? pos - ric_start : 0,
-                      _ftie->mic) < 0)
+                      fte_mic) < 0)
                wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
 
        os_free(sm->assoc_resp_ftie);
@@ -2871,7 +2897,7 @@ pmk_r1_derived:
                goto fail;
        pos += ret;
 
-       ret = wpa_write_ftie(conf, parse.r0kh_id, parse.r0kh_id_len,
+       ret = wpa_write_ftie(conf, use_sha384, parse.r0kh_id, parse.r0kh_id_len,
                             sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0);
        if (ret < 0)
                goto fail;
index 676e4bf153f3ed97067f1b287248eb823a713947..b1cea1b49b14cbde18b3db804c0de769ece171cd 100644 (file)
@@ -277,8 +277,8 @@ int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth,
 
 #ifdef CONFIG_IEEE80211R_AP
 int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len);
-int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
-                  size_t r0kh_id_len,
+int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
+                  const u8 *r0kh_id, size_t r0kh_id_len,
                   const u8 *anonce, const u8 *snonce,
                   u8 *buf, size_t len, const u8 *subelem,
                   size_t subelem_len);