]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Implement FILS-FT derivation
authorJouni Malinen <j@w1.fi>
Sun, 7 May 2017 08:47:44 +0000 (11:47 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 7 May 2017 14:04:29 +0000 (17:04 +0300)
This extends fils_pmk_to_ptk() to allow FILS-FT to be derived. The
callers do not yet use that capability; i.e., actual use will be added
in separate commits.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/wpa_auth.c
src/common/wpa_common.c
src/common/wpa_common.h
src/rsn_supp/wpa.c

index 74c5527561563d9bcb310747185c05f1dc16d574..7e3f9c83e29cdccc2982da6f70de5a32f6e63838 100644 (file)
@@ -2092,7 +2092,7 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
 
        res = fils_pmk_to_ptk(pmk, pmk_len, sm->addr, sm->wpa_auth->addr,
                              snonce, anonce, &sm->PTK, ick, &ick_len,
-                             sm->wpa_key_mgmt, sm->pairwise);
+                             sm->wpa_key_mgmt, sm->pairwise, NULL, NULL);
        if (res < 0)
                return res;
        sm->PTK_valid = TRUE;
index c82f3486bcd17a304b8d18e025b4b949b0c3bb3e..8eabf5435fb4101fd62ba0a00c6708377e8f1276 100644 (file)
@@ -339,10 +339,12 @@ int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len,
 
 int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
                    const u8 *snonce, const u8 *anonce, struct wpa_ptk *ptk,
-                   u8 *ick, size_t *ick_len, int akmp, int cipher)
+                   u8 *ick, size_t *ick_len, int akmp, int cipher,
+                   u8 *fils_ft, size_t *fils_ft_len)
 {
        u8 data[2 * ETH_ALEN + 2 * FILS_NONCE_LEN];
-       u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
+       u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
+              FILS_FT_MAX_LEN];
        size_t key_data_len;
        const char *label = "FILS PTK Derivation";
 
@@ -372,6 +374,18 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
                return -1;
        key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
 
+       if (fils_ft && fils_ft_len) {
+               if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
+                       *fils_ft_len = 32;
+               } else if (akmp == WPA_KEY_MGMT_FT_FILS_SHA384) {
+                       *fils_ft_len = 48;
+               } else {
+                       *fils_ft_len = 0;
+                       fils_ft = NULL;
+               }
+               key_data_len += *fils_ft_len;
+       }
+
        if (wpa_key_mgmt_sha384(akmp)) {
                wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA384)");
                if (sha384_prf(pmk, pmk_len, label, data, sizeof(data),
@@ -400,7 +414,12 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
        os_memcpy(ptk->tk, tmp + *ick_len + ptk->kek_len, ptk->tk_len);
        wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len);
 
-       /* TODO: FILS-FT */
+       if (fils_ft && fils_ft_len) {
+               os_memcpy(fils_ft, tmp + *ick_len + ptk->kek_len + ptk->tk_len,
+                         *fils_ft_len);
+               wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
+                               fils_ft, *fils_ft_len);
+       }
 
        os_memset(tmp, 0, sizeof(tmp));
        return 0;
index 6303510fefc4b78eebc438c07c89a16ec58d39e1..c0773e8b23e68ac33aae597ff2b0fc959cd419b4 100644 (file)
@@ -202,6 +202,7 @@ struct wpa_eapol_key {
 #define WPA_KEK_MAX_LEN 64
 #define WPA_TK_MAX_LEN 32
 #define FILS_ICK_MAX_LEN 48
+#define FILS_FT_MAX_LEN 48
 
 /**
  * struct wpa_ptk - WPA Pairwise Transient Key
@@ -346,7 +347,8 @@ int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len,
                   u8 *pmkid);
 int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
                    const u8 *snonce, const u8 *anonce, struct wpa_ptk *ptk,
-                   u8 *ick, size_t *ick_len, int akmp, int cipher);
+                   u8 *ick, size_t *ick_len, int akmp, int cipher,
+                   u8 *fils_ft, size_t *fils_ft_len);
 int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce,
                     const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
                     const u8 *g_sta, size_t g_sta_len,
index 316d692549ee55dc1088de413f78aa7c608ab840..79504de7ab58df6febaa5035f85fd34024ba44e3 100644 (file)
@@ -3603,8 +3603,8 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
 
        if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,
                            sm->fils_nonce, sm->fils_anonce, &sm->ptk,
-                           ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher) <
-           0) {
+                           ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher,
+                           NULL, NULL) < 0) {
                wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
                goto fail;
        }