]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FT: AP mode FTE writing to support FT-SAE-KEY-EXT
authorJouni Malinen <quic_jouni@quicinc.com>
Sun, 16 Oct 2022 13:51:12 +0000 (16:51 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 16 Oct 2022 13:51:12 +0000 (16:51 +0300)
Provide enough information to allow the FTE to be built using the
correct MIC field length based on the used AKM and key length.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
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
src/common/wpa_common.h

index a65a2964b1a7ef408fa51c820e9516fba7e2f45b..761abd7ce1cc2267d2abc656874aad88d0efef80 100644 (file)
@@ -2110,10 +2110,8 @@ 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, use_sha384,
+               res = wpa_auth_write_fte(hapd->wpa_auth, sta->wpa_sm,
                                         wpabuf_put(data, 0),
                                         wpabuf_tailroom(data));
                if (res < 0) {
index 73feac4291b1c511d051967bdaed10efa45bf86a..060beaec65d89920d810b6205801e4d1aa38b7ac 100644 (file)
@@ -3685,9 +3685,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
                                  2 + sm->assoc_resp_ftie[1]);
                        res = 2 + sm->assoc_resp_ftie[1];
                } else {
-                       int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
-
-                       res = wpa_write_ftie(conf, use_sha384,
+                       res = wpa_write_ftie(conf, sm->wpa_key_mgmt,
+                                            sm->xxkey_len,
                                             conf->r0_key_holder,
                                             conf->r0_key_holder_len,
                                             NULL, NULL, pos,
@@ -5453,13 +5452,14 @@ 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, int use_sha384,
+int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth,
+                      struct wpa_state_machine *sm,
                       u8 *buf, size_t len)
 {
        struct wpa_auth_config *conf = &wpa_auth->conf;
 
-       return wpa_write_ftie(conf, use_sha384, conf->r0_key_holder,
-                             conf->r0_key_holder_len,
+       return wpa_write_ftie(conf, sm->wpa_key_mgmt, sm->xxkey_len,
+                             conf->r0_key_holder, conf->r0_key_holder_len,
                              NULL, NULL, buf, len, NULL, 0, 0);
 }
 #endif /* CONFIG_IEEE80211R_AP */
@@ -5673,9 +5673,8 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
                                  2 + sm->assoc_resp_ftie[1]);
                        res = 2 + sm->assoc_resp_ftie[1];
                } else {
-                       int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
-
-                       res = wpa_write_ftie(conf, use_sha384,
+                       res = wpa_write_ftie(conf, sm->wpa_key_mgmt,
+                                            sm->xxkey_len,
                                             conf->r0_key_holder,
                                             conf->r0_key_holder_len,
                                             NULL, NULL, pos,
index e8e6a8a6b77c54ce08d9c10d9fe09a6ad211e7ae..64e661640a322bf9164a0a68a54d7e6fbea6bb99 100644 (file)
@@ -535,7 +535,8 @@ int wpa_fils_validate_key_confirm(struct wpa_state_machine *sm, const u8 *ies,
 int get_sta_tx_parameters(struct wpa_state_machine *sm, int ap_max_chanwidth,
                          int ap_seg1_idx, int *bandwidth, int *seg1_idx);
 
-int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
+int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth,
+                      struct wpa_state_machine *sm,
                       u8 *buf, size_t len);
 void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm,
                                   u8 *fils_anonce, u8 *fils_snonce,
index b9f451d52a8c165e94bcab69ed1f70164792c9ba..0e522180d5f4be31435244cd30dbb8e511015db2 100644 (file)
@@ -20,6 +20,7 @@
 #include "crypto/aes_siv.h"
 #include "crypto/aes_wrap.h"
 #include "crypto/sha384.h"
+#include "crypto/sha512.h"
 #include "crypto/random.h"
 #include "ap_config.h"
 #include "ieee802_11.h"
@@ -805,15 +806,28 @@ int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len)
 }
 
 
-int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
+int wpa_write_ftie(struct wpa_auth_config *conf, int key_mgmt, size_t key_len,
                   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, int rsnxe_used)
 {
        u8 *pos = buf, *ielen;
-       size_t hdrlen = use_sha384 ? sizeof(struct rsn_ftie_sha384) :
-               sizeof(struct rsn_ftie);
+       size_t hdrlen;
+
+       if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+           key_len == SHA256_MAC_LEN)
+               hdrlen = sizeof(struct rsn_ftie);
+       else if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+                key_len == SHA384_MAC_LEN)
+               hdrlen = sizeof(struct rsn_ftie_sha384);
+       else if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+                key_len == SHA512_MAC_LEN)
+               hdrlen = sizeof(struct rsn_ftie_sha512);
+       else if (wpa_key_mgmt_sha384(key_mgmt))
+               hdrlen = sizeof(struct rsn_ftie_sha384);
+       else
+               hdrlen = sizeof(struct rsn_ftie);
 
        if (len < 2 + hdrlen + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len +
            subelem_len)
@@ -822,7 +836,20 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
        *pos++ = WLAN_EID_FAST_BSS_TRANSITION;
        ielen = pos++;
 
-       if (use_sha384) {
+       if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+           key_len == SHA512_MAC_LEN) {
+               struct rsn_ftie_sha512 *hdr = (struct rsn_ftie_sha512 *) pos;
+
+               os_memset(hdr, 0, sizeof(*hdr));
+               pos += sizeof(*hdr);
+               WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
+               if (anonce)
+                       os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
+               if (snonce)
+                       os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
+       } else if ((key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+                   key_len == SHA384_MAC_LEN) ||
+                  wpa_key_mgmt_sha384(key_mgmt)) {
                struct rsn_ftie_sha384 *hdr = (struct rsn_ftie_sha384 *) pos;
 
                os_memset(hdr, 0, sizeof(*hdr));
@@ -2522,6 +2549,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
        const u8 *kck;
        size_t kck_len;
        int use_sha384;
+       size_t key_len;
 
        if (sm == NULL)
                return pos;
@@ -2705,7 +2733,20 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
                           rsnxe_used);
        }
 #endif /* CONFIG_TESTING_OPTIONS */
-       res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len,
+       key_len = sm->xxkey_len;
+       if (!key_len)
+               key_len = sm->pmk_r1_len;
+       if (!key_len && sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+           sm->wpa_auth->cb->get_psk) {
+               size_t psk_len;
+
+               if (sm->wpa_auth->cb->get_psk(sm->wpa_auth->cb_ctx,
+                                             sm->addr, sm->p2p_dev_addr,
+                                             NULL, &psk_len, NULL))
+                       key_len = psk_len;
+       }
+       res = wpa_write_ftie(conf, sm->wpa_key_mgmt, key_len,
+                            r0kh_id, r0kh_id_len,
                             anonce, snonce, pos, end - pos,
                             subelem, subelem_len, rsnxe_used);
        os_free(subelem);
@@ -3282,7 +3323,8 @@ pmk_r1_derived:
                goto fail;
        pos += ret;
 
-       ret = wpa_write_ftie(conf, use_sha384, parse.r0kh_id, parse.r0kh_id_len,
+       ret = wpa_write_ftie(conf, parse.key_mgmt, pmk_r1_len,
+                            parse.r0kh_id, parse.r0kh_id_len,
                             sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0,
                             0);
        if (ret < 0)
index 5bd699c25d9c077d29799af080a4a31435254cd1..99a95abfdec556be2f8879d0177ab4fb4e9d7e57 100644 (file)
@@ -298,7 +298,7 @@ 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, int use_sha384,
+int wpa_write_ftie(struct wpa_auth_config *conf, int key_mgmt, size_t key_len,
                   const u8 *r0kh_id, size_t r0kh_id_len,
                   const u8 *anonce, const u8 *snonce,
                   u8 *buf, size_t len, const u8 *subelem,
index 71b423cbf39881a59d6c91f0bf601f9a02de44e6..11faa976007af71baabfe80b6b2863da9011529b 100644 (file)
@@ -401,6 +401,14 @@ struct rsn_ftie_sha384 {
        /* followed by optional parameters */
 } STRUCT_PACKED;
 
+struct rsn_ftie_sha512 {
+       u8 mic_control[2];
+       u8 mic[32];
+       u8 anonce[WPA_NONCE_LEN];
+       u8 snonce[WPA_NONCE_LEN];
+       /* followed by optional parameters */
+} STRUCT_PACKED;
+
 #define FTIE_SUBELEM_R1KH_ID 1
 #define FTIE_SUBELEM_GTK 2
 #define FTIE_SUBELEM_R0KH_ID 3