]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FT: Check key derivation results explicitly in AP operations
authorJouni Malinen <jouni@qca.qualcomm.com>
Tue, 14 Feb 2017 09:09:30 +0000 (11:09 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 14 Feb 2017 14:33:01 +0000 (16:33 +0200)
Previously, any potential (even if very unlikely) local operation error
was ignored. Now these will result in aborting the negotiation.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/ap/wpa_auth.c
src/ap/wpa_auth_ft.c
src/common/wpa_common.c
src/common/wpa_common.h

index be734d1c39945ec0bb79d5b94d42dbff95c8bfb9..5dcf1e3d2d053d5d48fa295e0894fddd69afe1ee 100644 (file)
@@ -857,7 +857,8 @@ static int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data,
                        pmk_len = sm->pmk_len;
                }
 
-               wpa_derive_ptk(sm, sm->alt_SNonce, pmk, pmk_len, &PTK);
+               if (wpa_derive_ptk(sm, sm->alt_SNonce, pmk, pmk_len, &PTK) < 0)
+                       break;
 
                if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK, data, data_len)
                    == 0) {
@@ -2464,7 +2465,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
                        pmk_len = sm->pmk_len;
                }
 
-               wpa_derive_ptk(sm, sm->SNonce, pmk, pmk_len, &PTK);
+               if (wpa_derive_ptk(sm, sm->SNonce, pmk, pmk_len, &PTK) < 0)
+                       break;
 
                if (mic_len &&
                    wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK,
index 1fe3c2b4c49a70e4105a84a88ea43f05538b721d..917dafd8c179213c6b2db69fbbfd712fd639ac23 100644 (file)
@@ -392,16 +392,19 @@ int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
                return -1;
        }
 
-       wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, ssid, ssid_len, mdid,
-                         r0kh, r0kh_len, sm->addr, pmk_r0, pmk_r0_name);
+       if (wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, ssid, ssid_len, mdid,
+                             r0kh, r0kh_len, sm->addr,
+                             pmk_r0, pmk_r0_name) < 0)
+               return -1;
        wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, PMK_LEN);
        wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN);
        if (!psk_local || !wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt))
                wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_name,
                                    sm->pairwise);
 
-       wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr,
-                         pmk_r1, sm->pmk_r1_name);
+       if (wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr,
+                             pmk_r1, sm->pmk_r1_name) < 0)
+               return -1;
        wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN);
        wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", sm->pmk_r1_name,
                    WPA_PMK_NAME_LEN);
@@ -834,12 +837,12 @@ static int wpa_ft_psk_pmk_r1(struct wpa_state_machine *sm,
                if (pmk == NULL)
                        break;
 
-               wpa_derive_pmk_r0(pmk, PMK_LEN, ssid, ssid_len, mdid, r0kh,
-                                 r0kh_len, sm->addr, pmk_r0, pmk_r0_name);
-               wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr,
-                                 pmk_r1, pmk_r1_name);
-
-               if (os_memcmp_const(pmk_r1_name, req_pmk_r1_name,
+               if (wpa_derive_pmk_r0(pmk, PMK_LEN, ssid, ssid_len, mdid, r0kh,
+                                     r0kh_len, sm->addr,
+                                     pmk_r0, pmk_r0_name) < 0 ||
+                   wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr,
+                                     pmk_r1, pmk_r1_name) < 0 ||
+                   os_memcmp_const(pmk_r1_name, req_pmk_r1_name,
                                    WPA_PMK_NAME_LEN) != 0)
                        continue;
 
@@ -958,9 +961,10 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
 
        wpa_hexdump(MSG_DEBUG, "FT: Requested PMKR0Name",
                    parse.rsn_pmkid, WPA_PMK_NAME_LEN);
-       wpa_derive_pmk_r1_name(parse.rsn_pmkid,
-                              sm->wpa_auth->conf.r1_key_holder, sm->addr,
-                              pmk_r1_name);
+       if (wpa_derive_pmk_r1_name(parse.rsn_pmkid,
+                                  sm->wpa_auth->conf.r1_key_holder, sm->addr,
+                                  pmk_r1_name) < 0)
+               return WLAN_STATUS_UNSPECIFIED_FAILURE;
        wpa_hexdump(MSG_DEBUG, "FT: Derived requested PMKR1Name",
                    pmk_r1_name, WPA_PMK_NAME_LEN);
 
@@ -1483,8 +1487,11 @@ static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
                return -1;
        }
 
-       wpa_derive_pmk_r1(pmk_r0, f.pmk_r0_name, f.r1kh_id, f.s1kh_id,
-                         r.pmk_r1, r.pmk_r1_name);
+       if (wpa_derive_pmk_r1(pmk_r0, f.pmk_r0_name, f.r1kh_id, f.s1kh_id,
+                             r.pmk_r1, r.pmk_r1_name) < 0) {
+               os_memset(pmk_r0, 0, PMK_LEN);
+               return -1;
+       }
        wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", r.pmk_r1, PMK_LEN);
        wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", r.pmk_r1_name,
                    WPA_PMK_NAME_LEN);
@@ -1825,10 +1832,10 @@ int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
 }
 
 
-static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
-                                  struct wpa_ft_pmk_r0_sa *pmk_r0,
-                                  struct ft_remote_r1kh *r1kh,
-                                  const u8 *s1kh_id, int pairwise)
+static int wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
+                                 struct wpa_ft_pmk_r0_sa *pmk_r0,
+                                 struct ft_remote_r1kh *r1kh,
+                                 const u8 *s1kh_id, int pairwise)
 {
        struct ft_r0kh_r1kh_push_frame frame, f;
        struct os_time now;
@@ -1846,8 +1853,9 @@ static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
        os_memcpy(f.r1kh_id, r1kh->id, FT_R1KH_ID_LEN);
        os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN);
        os_memcpy(f.pmk_r0_name, pmk_r0->pmk_r0_name, WPA_PMK_NAME_LEN);
-       wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_name, r1kh->id,
-                         s1kh_id, f.pmk_r1, f.pmk_r1_name);
+       if (wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_name, r1kh->id,
+                             s1kh_id, f.pmk_r1, f.pmk_r1_name) < 0)
+               return -1;
        wpa_printf(MSG_DEBUG, "FT: R1KH-ID " MACSTR, MAC2STR(r1kh->id));
        wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", f.pmk_r1, PMK_LEN);
        wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", f.pmk_r1_name,
@@ -1863,9 +1871,10 @@ static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
        if (aes_wrap(r1kh->key, sizeof(r1kh->key),
                     (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
                     plain, crypt) < 0)
-               return;
+               return -1;
 
        wpa_ft_rrb_send(wpa_auth, r1kh->addr, (u8 *) &frame, sizeof(frame));
+       return 0;
 }
 
 
index 79f001bd140740946f9268d084d769aa6dba66c7..3280baee52fc2f0d4a63481af32c02a82afdd443 100644 (file)
@@ -1104,10 +1104,10 @@ int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
  *
  * IEEE Std 802.11r-2008 - 8.5.1.5.3
  */
-void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
-                      const u8 *ssid, size_t ssid_len,
-                      const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
-                      const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name)
+int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
+                     const u8 *ssid, size_t ssid_len,
+                     const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
+                     const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name)
 {
        u8 buf[1 + SSID_MAX_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
               FT_R0KH_ID_MAX_LEN + ETH_ALEN];
@@ -1124,7 +1124,7 @@ void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
         * PMK-R0Name-Salt = L(R0-Key-Data, 256, 128)
         */
        if (ssid_len > SSID_MAX_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
-               return;
+               return -1;
        pos = buf;
        *pos++ = ssid_len;
        os_memcpy(pos, ssid, ssid_len);
@@ -1137,8 +1137,9 @@ void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
        os_memcpy(pos, s0kh_id, ETH_ALEN);
        pos += ETH_ALEN;
 
-       sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
-                  r0_key_data, sizeof(r0_key_data));
+       if (sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
+                      r0_key_data, sizeof(r0_key_data)) < 0)
+               return -1;
        os_memcpy(pmk_r0, r0_key_data, PMK_LEN);
 
        /*
@@ -1149,8 +1150,10 @@ void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
        addr[1] = r0_key_data + PMK_LEN;
        len[1] = 16;
 
-       sha256_vector(2, addr, len, hash);
+       if (sha256_vector(2, addr, len, hash) < 0)
+               return -1;
        os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
+       return 0;
 }
 
 
@@ -1159,8 +1162,8 @@ void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
  *
  * IEEE Std 802.11r-2008 - 8.5.1.5.4
  */
-void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
-                           const u8 *s1kh_id, u8 *pmk_r1_name)
+int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
+                          const u8 *s1kh_id, u8 *pmk_r1_name)
 {
        u8 hash[32];
        const u8 *addr[4];
@@ -1179,8 +1182,10 @@ void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
        addr[3] = s1kh_id;
        len[3] = ETH_ALEN;
 
-       sha256_vector(4, addr, len, hash);
+       if (sha256_vector(4, addr, len, hash) < 0)
+               return -1;
        os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
+       return 0;
 }
 
 
@@ -1189,9 +1194,9 @@ void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
  *
  * IEEE Std 802.11r-2008 - 8.5.1.5.4
  */
-void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
-                      const u8 *r1kh_id, const u8 *s1kh_id,
-                      u8 *pmk_r1, u8 *pmk_r1_name)
+int wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
+                     const u8 *r1kh_id, const u8 *s1kh_id,
+                     u8 *pmk_r1, u8 *pmk_r1_name)
 {
        u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
        u8 *pos;
@@ -1203,9 +1208,12 @@ void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
        os_memcpy(pos, s1kh_id, ETH_ALEN);
        pos += ETH_ALEN;
 
-       sha256_prf(pmk_r0, PMK_LEN, "FT-R1", buf, pos - buf, pmk_r1, PMK_LEN);
+       if (sha256_prf(pmk_r0, PMK_LEN, "FT-R1", buf, pos - buf,
+                      pmk_r1, PMK_LEN) < 0)
+               return -1;
 
-       wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, pmk_r1_name);
+       return wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id,
+                                     pmk_r1_name);
 }
 
 
@@ -1245,7 +1253,9 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
        ptk->tk_len = wpa_cipher_key_len(cipher);
        ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
 
-       sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf, tmp, ptk_len);
+       if (sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf,
+                      tmp, ptk_len) < 0)
+               return -1;
 
        /*
         * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
@@ -1264,7 +1274,8 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
        addr[5] = sta_addr;
        len[5] = ETH_ALEN;
 
-       sha256_vector(6, addr, len, hash);
+       if (sha256_vector(6, addr, len, hash) < 0)
+               return -1;
        os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
 
        os_memcpy(ptk->kck, tmp, ptk->kck_len);
index 4e465f5bd85d367323a50477a1ced3dfb78fe8ff..a84cc9b2d1aa9a04a224ac4a4279bbe9987d38c8 100644 (file)
@@ -358,15 +358,15 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
               const u8 *ftie, size_t ftie_len,
               const u8 *rsnie, size_t rsnie_len,
               const u8 *ric, size_t ric_len, u8 *mic);
-void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
-                      const u8 *ssid, size_t ssid_len,
-                      const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
-                      const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name);
-void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
-                           const u8 *s1kh_id, u8 *pmk_r1_name);
-void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
-                      const u8 *r1kh_id, const u8 *s1kh_id,
-                      u8 *pmk_r1, u8 *pmk_r1_name);
+int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
+                     const u8 *ssid, size_t ssid_len,
+                     const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
+                     const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name);
+int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
+                          const u8 *s1kh_id, u8 *pmk_r1_name);
+int wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
+                     const u8 *r1kh_id, const u8 *s1kh_id,
+                     u8 *pmk_r1, u8 *pmk_r1_name);
 int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
                      const u8 *sta_addr, const u8 *bssid,
                      const u8 *pmk_r1_name,