]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Suite B: Select EAPOL-Key integrity and key-wrap algorithms based on AKM
authorJouni Malinen <j@w1.fi>
Sun, 16 Nov 2014 13:40:02 +0000 (15:40 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 16 Nov 2014 15:09:11 +0000 (17:09 +0200)
This adds support for AKM 00-0F-AC:11 to specify the integrity and
key-wrap algorithms for EAPOL-Key frames using the new design where
descriptor version is set to 0 and algorithms are determined based on
AKM.

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/peerkey.c
src/rsn_supp/wpa.c
wlantest/rx_eapol.c

index 562801a5927afdbf6dab757f5ea52f1443adcf1b..0d2a311c5e3a4fe2a2c061954f3aec8a665b134e 100644 (file)
@@ -33,7 +33,8 @@
 
 static void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx);
 static int wpa_sm_step(struct wpa_state_machine *sm);
-static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len);
+static int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data,
+                             size_t data_len);
 static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx);
 static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
                              struct wpa_group *group);
@@ -884,6 +885,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
                    sm->pairwise == WPA_CIPHER_GCMP) {
                        if (wpa_use_aes_cmac(sm) &&
                            sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN &&
+                           !wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) &&
                            ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
                                wpa_auth_logger(wpa_auth, sm->addr,
                                                LOGGER_WARNING,
@@ -902,6 +904,13 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
                                return;
                        }
                }
+
+               if (wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) &&
+                   ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
+                       wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING,
+                                       "did not use EAPOL-Key descriptor version 0 as required for AKM-defined cases");
+                       return;
+               }
        }
 
        if (key_info & WPA_KEY_INFO_REQUEST) {
@@ -1123,7 +1132,8 @@ continue_processing:
 
        sm->MICVerified = FALSE;
        if (sm->PTK_valid && !sm->update_snonce) {
-               if (wpa_verify_key_mic(&sm->PTK, data, data_len)) {
+               if (wpa_verify_key_mic(sm->wpa_key_mgmt, &sm->PTK, data,
+                                      data_len)) {
                        wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
                                        "received EAPOL-Key with invalid MIC");
                        return;
@@ -1295,7 +1305,8 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
 
        if (force_version)
                version = force_version;
-       else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN)
+       else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN ||
+                wpa_key_mgmt_suite_b(sm->wpa_key_mgmt))
                version = WPA_KEY_INFO_TYPE_AKM_DEFINED;
        else if (wpa_use_aes_cmac(sm))
                version = WPA_KEY_INFO_TYPE_AES_128_CMAC;
@@ -1320,6 +1331,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
 
        if ((version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
             sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN ||
+            wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) ||
             version == WPA_KEY_INFO_TYPE_AES_128_CMAC) && encr) {
                pad_len = key_data_len % 8;
                if (pad_len)
@@ -1389,6 +1401,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
                                buf, key_data_len);
                if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
                    sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN ||
+                   wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) ||
                    version == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
                        if (aes_wrap(sm->PTK.kek, 16,
                                     (key_data_len - 8) / 8, buf,
@@ -1420,8 +1433,8 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
                        os_free(hdr);
                        return;
                }
-               wpa_eapol_key_mic(sm->PTK.kck, version, (u8 *) hdr, len,
-                                 key->key_mic);
+               wpa_eapol_key_mic(sm->PTK.kck, sm->wpa_key_mgmt, version,
+                                 (u8 *) hdr, len, key->key_mic);
 #ifdef CONFIG_TESTING_OPTIONS
                if (!pairwise &&
                    wpa_auth->conf.corrupt_gtk_rekey_mic_probability > 0.0 &&
@@ -1473,7 +1486,8 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
 }
 
 
-static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len)
+static int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data,
+                             size_t data_len)
 {
        struct ieee802_1x_hdr *hdr;
        struct wpa_eapol_key *key;
@@ -1489,7 +1503,7 @@ static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len)
        key_info = WPA_GET_BE16(key->key_info);
        os_memcpy(mic, key->key_mic, 16);
        os_memset(key->key_mic, 0, 16);
-       if (wpa_eapol_key_mic(PTK->kck, key_info & WPA_KEY_INFO_TYPE_MASK,
+       if (wpa_eapol_key_mic(PTK->kck, akmp, key_info & WPA_KEY_INFO_TYPE_MASK,
                              data, data_len, key->key_mic) ||
            os_memcmp_const(mic, key->key_mic, 16) != 0)
                ret = -1;
@@ -1795,10 +1809,13 @@ SM_STATE(WPA_PTK, PTKSTART)
                pmkid[0] = WLAN_EID_VENDOR_SPECIFIC;
                pmkid[1] = RSN_SELECTOR_LEN + PMKID_LEN;
                RSN_SELECTOR_PUT(&pmkid[2], RSN_KEY_DATA_PMKID);
-               if (sm->pmksa)
+               if (sm->pmksa) {
                        os_memcpy(&pmkid[2 + RSN_SELECTOR_LEN],
                                  sm->pmksa->pmkid, PMKID_LEN);
-               else {
+               } else if (wpa_key_mgmt_suite_b(sm->wpa_key_mgmt)) {
+                       /* No KCK available to derive PMKID */
+                       pmkid = NULL;
+               } else {
                        /*
                         * Calculate PMKID since no PMKSA cache entry was
                         * available with pre-calculated PMKID.
@@ -1856,7 +1873,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 
                wpa_derive_ptk(sm, pmk, &PTK);
 
-               if (wpa_verify_key_mic(&PTK, sm->last_rx_eapol_key,
+               if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK,
+                                      sm->last_rx_eapol_key,
                                       sm->last_rx_eapol_key_len) == 0) {
                        ok = 1;
                        break;
index f87e7910efa7e8053a4240bfc476c4bb5f475b6a..2970d0f0f78f64cda3ec891b2b3c077492aa9d38 100644 (file)
@@ -22,6 +22,7 @@
 /**
  * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
  * @key: EAPOL-Key Key Confirmation Key (KCK)
+ * @akmp: WPA_KEY_MGMT_* used in key derivation
  * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
  * @buf: Pointer to the beginning of the EAPOL header (version field)
  * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
  * happened during final editing of the standard and the correct behavior is
  * defined in the last draft (IEEE 802.11i/D10).
  */
-int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
-                     u8 *mic)
+int wpa_eapol_key_mic(const u8 *key, int akmp, int ver, const u8 *buf,
+                     size_t len, u8 *mic)
 {
-       u8 hash[SHA1_MAC_LEN];
+       u8 hash[SHA256_MAC_LEN];
 
        switch (ver) {
 #ifndef CONFIG_FIPS
@@ -56,11 +57,23 @@ int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
        case WPA_KEY_INFO_TYPE_AES_128_CMAC:
                return omac1_aes_128(key, buf, len, mic);
 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
-#ifdef CONFIG_HS20
        case WPA_KEY_INFO_TYPE_AKM_DEFINED:
-               /* FIX: This should be based on negotiated AKM */
-               return omac1_aes_128(key, buf, len, mic);
+               switch (akmp) {
+#ifdef CONFIG_HS20
+               case WPA_KEY_MGMT_OSEN:
+                       return omac1_aes_128(key, buf, len, mic);
 #endif /* CONFIG_HS20 */
+#ifdef CONFIG_SUITEB
+               case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
+                       if (hmac_sha256(key, 16, buf, len, hash))
+                               return -1;
+                       os_memcpy(mic, hash, MD5_MAC_LEN);
+                       break;
+#endif /* CONFIG_SUITEB */
+               default:
+                       return -1;
+               }
+               break;
        default:
                return -1;
        }
index 3bacbdceaaae097510d3fda4ca3c1e843cbcc4a9..17bed34a5342935cbd139f136f39add2001001a9 100644 (file)
@@ -327,8 +327,8 @@ struct rsn_rdie {
 #endif /* _MSC_VER */
 
 
-int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
-                     u8 *mic);
+int wpa_eapol_key_mic(const u8 *key, int akmp, int ver, const u8 *buf,
+                     size_t len, u8 *mic);
 void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
                    const u8 *addr1, const u8 *addr2,
                    const u8 *nonce1, const u8 *nonce2,
index 48b6f13bd4be30ea2c9a6a6861425cf483b55fdf..aca8f540cfdd39a3e02238620a0504936277fafa 100644 (file)
@@ -928,8 +928,8 @@ int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
        os_memcpy(mic, key->key_mic, 16);
        if (peerkey->tstk_set) {
                os_memset(key->key_mic, 0, 16);
-               wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
-                                 key->key_mic);
+               wpa_eapol_key_mic(peerkey->tstk.kck, sm->key_mgmt, ver, buf,
+                                 len, key->key_mic);
                if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
                        wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
                                   "when using TSTK - ignoring TSTK");
@@ -944,7 +944,7 @@ int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
 
        if (!ok && peerkey->stk_set) {
                os_memset(key->key_mic, 0, 16);
-               wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
+               wpa_eapol_key_mic(peerkey->stk.kck, sm->key_mgmt, ver, buf, len,
                                  key->key_mic);
                if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
                        wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
index 9c840c69890a646d0e1450be88de5d788bd4eb79..1d38ba5082ae62a6a0e53c8599ca09e7efe4f324 100644 (file)
@@ -56,10 +56,10 @@ void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck,
                }
        }
        if (key_mic &&
-           wpa_eapol_key_mic(kck, ver, msg, msg_len, key_mic)) {
+           wpa_eapol_key_mic(kck, sm->key_mgmt, ver, msg, msg_len, key_mic)) {
                wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
-                       "WPA: Failed to generate EAPOL-Key "
-                       "version %d MIC", ver);
+                       "WPA: Failed to generate EAPOL-Key version %d key_mgmt 0x%x MIC",
+                       ver, sm->key_mgmt);
                goto out;
        }
        wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", kck, 16);
@@ -89,7 +89,8 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
        int key_info, ver;
        u8 bssid[ETH_ALEN], *rbuf;
 
-       if (sm->key_mgmt == WPA_KEY_MGMT_OSEN)
+       if (sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
+           wpa_key_mgmt_suite_b(sm->key_mgmt))
                ver = WPA_KEY_INFO_TYPE_AKM_DEFINED;
        else if (wpa_key_mgmt_ft(sm->key_mgmt) ||
                 wpa_key_mgmt_sha256(sm->key_mgmt))
@@ -1451,7 +1452,7 @@ static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
        os_memcpy(mic, key->key_mic, 16);
        if (sm->tptk_set) {
                os_memset(key->key_mic, 0, 16);
-               wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len,
+               wpa_eapol_key_mic(sm->tptk.kck, sm->key_mgmt, ver, buf, len,
                                  key->key_mic);
                if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
                        wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
@@ -1468,7 +1469,7 @@ static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
 
        if (!ok && sm->ptk_set) {
                os_memset(key->key_mic, 0, 16);
-               wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len,
+               wpa_eapol_key_mic(sm->ptk.kck, sm->key_mgmt, ver, buf, len,
                                  key->key_mic);
                if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
                        wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
@@ -1522,7 +1523,8 @@ static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
                os_memset(ek, 0, sizeof(ek));
        } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
                   ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
-                  sm->key_mgmt == WPA_KEY_MGMT_OSEN) {
+                  sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
+                  wpa_key_mgmt_suite_b(sm->key_mgmt)) {
                u8 *buf;
                if (*key_data_len < 8 || *key_data_len % 8) {
                        wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
@@ -1720,6 +1722,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
            ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
            ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
+           !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
            sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
                wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
                        "WPA: Unsupported EAPOL-Key descriptor version %d",
@@ -1735,6 +1738,14 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
                goto out;
        }
 
+       if (wpa_key_mgmt_suite_b(sm->key_mgmt) &&
+           ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
+               wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+                       "RSN: Unsupported EAPOL-Key descriptor version %d (expected AKM defined = 0)",
+                       ver);
+               goto out;
+       }
+
 #ifdef CONFIG_IEEE80211R
        if (wpa_key_mgmt_ft(sm->key_mgmt)) {
                /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
@@ -1748,7 +1759,8 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
 #ifdef CONFIG_IEEE80211W
        if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
                if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
-                   sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
+                   sm->key_mgmt != WPA_KEY_MGMT_OSEN &&
+                   !wpa_key_mgmt_suite_b(sm->key_mgmt)) {
                        wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
                                "WPA: AP did not use the "
                                "negotiated AES-128-CMAC");
@@ -1757,6 +1769,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
        } else
 #endif /* CONFIG_IEEE80211W */
        if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
+           !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
            ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
                wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
                        "WPA: CCMP is used, but EAPOL-Key "
@@ -1776,6 +1789,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
                } else
                        goto out;
        } else if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
+                  !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
                   ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
                wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
                        "WPA: GCMP is used, but EAPOL-Key "
index a1a9b057bc6e55731d82acceaafa29bcc3b847ed..13510ef7a8cb03d2372cafccf25ccfd14d3306ba 100644 (file)
@@ -31,7 +31,8 @@ static int is_zero(const u8 *buf, size_t len)
 }
 
 
-static int check_mic(const u8 *kck, int ver, const u8 *data, size_t len)
+static int check_mic(const u8 *kck, int akmp, int ver, const u8 *data,
+                    size_t len)
 {
        u8 *buf;
        int ret = -1;
@@ -49,7 +50,7 @@ static int check_mic(const u8 *kck, int ver, const u8 *data, size_t len)
        os_memcpy(rx_mic, key->key_mic, 16);
        os_memset(key->key_mic, 0, 16);
 
-       if (wpa_eapol_key_mic(kck, ver, buf, len, key->key_mic) == 0 &&
+       if (wpa_eapol_key_mic(kck, akmp, ver, buf, len, key->key_mic) == 0 &&
            os_memcmp(rx_mic, key->key_mic, 16) == 0)
                ret = 0;
 
@@ -105,7 +106,7 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
                       bss->bssid, sta->addr, sta->anonce, sta->snonce,
                       (u8 *) &ptk, ptk_len,
                       wpa_key_mgmt_sha256(sta->key_mgmt));
-       if (check_mic(ptk.kck, ver, data, len) < 0)
+       if (check_mic(ptk.kck, sta->key_mgmt, ver, data, len) < 0)
                return -1;
 
        sta->tk_len = wpa_cipher_key_len(sta->pairwise_cipher);
@@ -168,7 +169,8 @@ static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
 
                wpa_debug_level = MSG_WARNING;
                dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
-                       if (check_mic(ptk->ptk.kck, ver, data, len) < 0)
+                       if (check_mic(ptk->ptk.kck, sta->key_mgmt, ver, data,
+                                     len) < 0)
                                continue;
                        wpa_printf(MSG_INFO, "Pre-set PTK matches for STA "
                                   MACSTR " BSSID " MACSTR,
@@ -241,7 +243,8 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
                         "Use TPTK for validation EAPOL-Key MIC");
                kck = sta->tptk.kck;
        }
-       if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
+       if (check_mic(kck, sta->key_mgmt, key_info & WPA_KEY_INFO_TYPE_MASK,
+                     data, len) < 0) {
                add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
                return;
        }
@@ -532,7 +535,8 @@ static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
                kck = sta->tptk.kck;
                kek = sta->tptk.kek;
        }
-       if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
+       if (check_mic(kck, sta->key_mgmt, key_info & WPA_KEY_INFO_TYPE_MASK,
+                     data, len) < 0) {
                add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
                return;
        }
@@ -677,7 +681,8 @@ static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
                         "Use TPTK for validation EAPOL-Key MIC");
                kck = sta->tptk.kck;
        }
-       if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
+       if (check_mic(kck, sta->key_mgmt, key_info & WPA_KEY_INFO_TYPE_MASK,
+                     data, len) < 0) {
                add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
                return;
        }
@@ -724,7 +729,8 @@ static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
        }
 
        if (sta->ptk_set &&
-           check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
+           check_mic(sta->ptk.kck, sta->key_mgmt,
+                     key_info & WPA_KEY_INFO_TYPE_MASK,
                      data, len) < 0) {
                add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
                return;
@@ -848,7 +854,8 @@ static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
        }
 
        if (sta->ptk_set &&
-           check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
+           check_mic(sta->ptk.kck, sta->key_mgmt,
+                     key_info & WPA_KEY_INFO_TYPE_MASK,
                      data, len) < 0) {
                add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
                return;