]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Add new AKM
authorJouni Malinen <jouni@qca.qualcomm.com>
Sat, 17 Jun 2017 20:48:52 +0000 (23:48 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 19 Jun 2017 18:13:17 +0000 (21:13 +0300)
This new AKM is used with DPP when using the signed Connector to derive
a PMK. Since the KCK, KEK, and MIC lengths are variable within a single
AKM, this needs number of additional changes to get the PMK length
delivered to places that need to figure out the lengths of the PTK
components.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
23 files changed:
hostapd/config_file.c
hostapd/ctrl_iface.c
src/ap/ieee802_11.c
src/ap/ieee802_1x.c
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_i.h
src/ap/wpa_auth_ie.c
src/common/defs.h
src/common/wpa_common.c
src/common/wpa_common.h
src/drivers/driver.h
src/drivers/driver_nl80211_capa.c
src/rsn_supp/peerkey.c
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_ie.c
wlantest/rx_eapol.c
wpa_supplicant/config.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/events.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpas_glue.c

index 3946589853d6ebfb0883b4b8d143f5ea134fe5fc..0924d41cc1cbe1af23c7cd1453d6ba6993fa87a8 100644 (file)
@@ -715,6 +715,10 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
                else if (os_strcmp(start, "OWE") == 0)
                        val |= WPA_KEY_MGMT_OWE;
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+               else if (os_strcmp(start, "DPP") == 0)
+                       val |= WPA_KEY_MGMT_DPP;
+#endif /* CONFIG_DPP */
                else {
                        wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
                                   line, start);
index 1a7764ab3bc55ec325a28507cefb4521b757ef88..4f49b5c4f2b219ce85a5d55dcfc8b0399ef3d8d8 100644 (file)
@@ -1110,6 +1110,15 @@ static int hostapd_ctrl_iface_get_key_mgmt(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_OWE */
 
+#ifdef CONFIG_DPP
+       if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) {
+               ret = os_snprintf(pos, end - pos, "DPP ");
+               if (os_snprintf_error(end - pos, ret))
+                       return pos - buf;
+               pos += ret;
+       }
+#endif /* CONFIG_DPP */
+
        if (pos > buf && *(pos - 1) == ' ') {
                *(pos - 1) = '\0';
                pos--;
index b9f819c741c07920cac3006619ef0f6190c5523b..3e0a2dd55be7844714df0236c2166d28fafc9f52 100644 (file)
@@ -1012,6 +1012,8 @@ static u16 wpa_res_to_status_code(int res)
 #endif /* CONFIG_IEEE80211W */
        if (res == WPA_INVALID_MDIE)
                return WLAN_STATUS_INVALID_MDIE;
+       if (res == WPA_INVALID_PMKID)
+               return WLAN_STATUS_INVALID_PMKID;
        if (res != WPA_IE_OK)
                return WLAN_STATUS_INVALID_IE;
        return WLAN_STATUS_SUCCESS;
index ae38f6c7de5ae757bbcbfa531b288ce4b030f0e7..6ea1ebe544da20f9ef88a9204ff902ca872ea836 100644 (file)
@@ -974,7 +974,8 @@ void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
 
        key_mgmt = wpa_auth_sta_key_mgmt(sta->wpa_sm);
        if (key_mgmt != -1 &&
-           (wpa_key_mgmt_wpa_psk(key_mgmt) || key_mgmt == WPA_KEY_MGMT_OWE)) {
+           (wpa_key_mgmt_wpa_psk(key_mgmt) || key_mgmt == WPA_KEY_MGMT_OWE ||
+            key_mgmt == WPA_KEY_MGMT_DPP)) {
                wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore EAPOL message - "
                           "STA is using PSK");
                return;
@@ -1118,7 +1119,8 @@ void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
 
        key_mgmt = wpa_auth_sta_key_mgmt(sta->wpa_sm);
        if (key_mgmt != -1 &&
-           (wpa_key_mgmt_wpa_psk(key_mgmt) || key_mgmt == WPA_KEY_MGMT_OWE)) {
+           (wpa_key_mgmt_wpa_psk(key_mgmt) || key_mgmt == WPA_KEY_MGMT_OWE ||
+            key_mgmt == WPA_KEY_MGMT_DPP)) {
                wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore STA - using PSK");
                /*
                 * Clear any possible EAPOL authenticator state to support
index 459b56e58963d7e47c5e0773cc5049a32ca679bb..07da33ffc2287583350f5959ce81d98afcb3d8b4 100644 (file)
@@ -35,8 +35,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(int akmp, struct wpa_ptk *PTK, u8 *data,
-                             size_t data_len);
+static int wpa_verify_key_mic(int akmp, size_t pmk_len, struct wpa_ptk *PTK,
+                             u8 *data, size_t data_len);
 #ifdef CONFIG_FILS
 static int wpa_aead_decrypt(struct wpa_state_machine *sm, struct wpa_ptk *ptk,
                            u8 *buf, size_t buf_len, u16 *_key_data_len);
@@ -226,13 +226,13 @@ void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr,
 
 
 static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth,
-                              const u8 *addr)
+                              const u8 *addr, u16 reason)
 {
        if (wpa_auth->cb->disconnect == NULL)
                return;
-       wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr));
-       wpa_auth->cb->disconnect(wpa_auth->cb_ctx, addr,
-                                WLAN_REASON_PREV_AUTH_NOT_VALID);
+       wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR " (reason %u)",
+                  MAC2STR(addr), reason);
+       wpa_auth->cb->disconnect(wpa_auth->cb_ctx, addr, reason);
 }
 
 
@@ -866,8 +866,8 @@ static int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data,
                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) {
+               if (wpa_verify_key_mic(sm->wpa_key_mgmt, pmk_len, &PTK,
+                                      data, data_len) == 0) {
                        ok = 1;
                        break;
                }
@@ -912,7 +912,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
                return;
        wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL data", data, data_len);
 
-       mic_len = wpa_mic_len(sm->wpa_key_mgmt);
+       mic_len = wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len);
        keyhdrlen = sizeof(*key) + mic_len + 2;
 
        if (data_len < sizeof(*hdr) + keyhdrlen) {
@@ -1025,6 +1025,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
                        if (!wpa_use_aes_cmac(sm) &&
                            !wpa_key_mgmt_fils(sm->wpa_key_mgmt) &&
                            sm->wpa_key_mgmt != WPA_KEY_MGMT_OWE &&
+                           sm->wpa_key_mgmt != WPA_KEY_MGMT_DPP &&
                            ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
                                wpa_auth_logger(wpa_auth, sm->addr,
                                                LOGGER_WARNING,
@@ -1036,6 +1037,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
 
                if ((wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) ||
                     wpa_key_mgmt_fils(sm->wpa_key_mgmt) ||
+                    sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP ||
                     sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE) &&
                    ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
                        wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING,
@@ -1160,7 +1162,8 @@ continue_processing:
                                   "collect more entropy for random number "
                                   "generation");
                        random_mark_pool_ready();
-                       wpa_sta_disconnect(wpa_auth, sm->addr);
+                       wpa_sta_disconnect(wpa_auth, sm->addr,
+                                          WLAN_REASON_PREV_AUTH_NOT_VALID);
                        return;
                }
                break;
@@ -1238,8 +1241,8 @@ continue_processing:
        sm->MICVerified = FALSE;
        if (sm->PTK_valid && !sm->update_snonce) {
                if (mic_len &&
-                   wpa_verify_key_mic(sm->wpa_key_mgmt, &sm->PTK, data,
-                                      data_len) &&
+                   wpa_verify_key_mic(sm->wpa_key_mgmt, sm->pmk_len, &sm->PTK,
+                                      data, data_len) &&
                    (msg != PAIRWISE_4 || !sm->alt_snonce_valid ||
                     wpa_try_alt_snonce(sm, data, data_len))) {
                        wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
@@ -1419,7 +1422,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
        int i;
        u8 *key_mic, *key_data;
 
-       mic_len = wpa_mic_len(sm->wpa_key_mgmt);
+       mic_len = wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len);
        keyhdrlen = sizeof(*key) + mic_len + 2;
 
        len = sizeof(struct ieee802_1x_hdr) + keyhdrlen;
@@ -1428,6 +1431,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
                version = force_version;
        else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN ||
                 sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE ||
+                sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP ||
                 wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) ||
                 wpa_key_mgmt_fils(sm->wpa_key_mgmt))
                version = WPA_KEY_INFO_TYPE_AKM_DEFINED;
@@ -1454,6 +1458,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_OWE ||
+            sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP ||
             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) {
@@ -1557,6 +1562,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_OWE ||
+                   sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP ||
                    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) {
@@ -1656,15 +1662,15 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
 }
 
 
-static int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data,
-                             size_t data_len)
+static int wpa_verify_key_mic(int akmp, size_t pmk_len, struct wpa_ptk *PTK,
+                             u8 *data, size_t data_len)
 {
        struct ieee802_1x_hdr *hdr;
        struct wpa_eapol_key *key;
        u16 key_info;
        int ret = 0;
        u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN], *mic_pos;
-       size_t mic_len = wpa_mic_len(akmp);
+       size_t mic_len = wpa_mic_len(akmp, pmk_len);
 
        if (data_len < sizeof(*hdr) + sizeof(*key))
                return -1;
@@ -1837,6 +1843,7 @@ SM_STATE(WPA_PTK, INITIALIZE)
        wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0);
        sm->TimeoutCtr = 0;
        if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
+           sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP ||
            sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE) {
                wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
                                   WPA_EAPOL_authorized, 0);
@@ -1846,9 +1853,14 @@ SM_STATE(WPA_PTK, INITIALIZE)
 
 SM_STATE(WPA_PTK, DISCONNECT)
 {
+       u16 reason = sm->disconnect_reason;
+
        SM_ENTRY_MA(WPA_PTK, DISCONNECT, wpa_ptk);
        sm->Disconnect = FALSE;
-       wpa_sta_disconnect(sm->wpa_auth, sm->addr);
+       sm->disconnect_reason = 0;
+       if (!reason)
+               reason = WLAN_REASON_PREV_AUTH_NOT_VALID;
+       wpa_sta_disconnect(sm->wpa_auth, sm->addr, reason);
 }
 
 
@@ -1949,6 +1961,14 @@ SM_STATE(WPA_PTK, INITPMK)
                wpa_printf(MSG_DEBUG, "WPA: PMK from PMKSA cache");
                os_memcpy(sm->PMK, sm->pmksa->pmk, sm->pmksa->pmk_len);
                sm->pmk_len = sm->pmksa->pmk_len;
+#ifdef CONFIG_DPP
+       } else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: No PMKSA cache entry for STA - reject connection");
+               sm->Disconnect = TRUE;
+               sm->disconnect_reason = WLAN_REASON_INVALID_PMKID;
+               return;
+#endif /* CONFIG_DPP */
        } else if (wpa_auth_get_msk(sm->wpa_auth, sm->addr, msk, &len) == 0) {
                unsigned int pmk_len;
 
@@ -2596,7 +2616,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
        sm->update_snonce = FALSE;
        os_memset(&PTK, 0, sizeof(PTK));
 
-       mic_len = wpa_mic_len(sm->wpa_key_mgmt);
+       mic_len = wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len);
 
        /* WPA with IEEE 802.1X: use the derived PMK from EAP
         * WPA-PSK: iterate through possible PSKs and select the one matching
@@ -2618,7 +2638,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
                        break;
 
                if (mic_len &&
-                   wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK,
+                   wpa_verify_key_mic(sm->wpa_key_mgmt, pmk_len, &PTK,
                                       sm->last_rx_eapol_key,
                                       sm->last_rx_eapol_key_len) == 0) {
                        ok = 1;
@@ -2687,12 +2707,14 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
                wpa_hexdump(MSG_DEBUG, "WPA IE in msg 2/4",
                            eapol_key_ie, eapol_key_ie_len);
                /* MLME-DEAUTHENTICATE.request */
-               wpa_sta_disconnect(wpa_auth, sm->addr);
+               wpa_sta_disconnect(wpa_auth, sm->addr,
+                                  WLAN_REASON_PREV_AUTH_NOT_VALID);
                return;
        }
 #ifdef CONFIG_IEEE80211R_AP
        if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) {
-               wpa_sta_disconnect(wpa_auth, sm->addr);
+               wpa_sta_disconnect(wpa_auth, sm->addr,
+                                  WLAN_REASON_PREV_AUTH_NOT_VALID);
                return;
        }
 #endif /* CONFIG_IEEE80211R_AP */
@@ -3002,7 +3024,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
 
        wpa_send_eapol(sm->wpa_auth, sm,
                       (secure ? WPA_KEY_INFO_SECURE : 0) |
-                      (wpa_mic_len(sm->wpa_key_mgmt) ? WPA_KEY_INFO_MIC : 0) |
+                      (wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ?
+                       WPA_KEY_INFO_MIC : 0) |
                       WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL |
                       WPA_KEY_INFO_KEY_TYPE,
                       _rsc, sm->ANonce, kde, pos - kde, keyidx, encr);
@@ -3019,7 +3042,8 @@ SM_STATE(WPA_PTK, PTKINITDONE)
                int klen = wpa_cipher_key_len(sm->pairwise);
                if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
                                     sm->PTK.tk, klen)) {
-                       wpa_sta_disconnect(sm->wpa_auth, sm->addr);
+                       wpa_sta_disconnect(sm->wpa_auth, sm->addr,
+                                          WLAN_REASON_PREV_AUTH_NOT_VALID);
                        return;
                }
                /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
@@ -3033,6 +3057,7 @@ SM_STATE(WPA_PTK, PTKINITDONE)
                }
 
                if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
+                   sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP ||
                    sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE) {
                        wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
                                           WPA_EAPOL_authorized, 1);
@@ -3106,12 +3131,18 @@ SM_STEP(WPA_PTK)
                         sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE
                         /* FIX: && 802.1X::keyRun */)
                        SM_ENTER(WPA_PTK, INITPSK);
+               else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP)
+                       SM_ENTER(WPA_PTK, INITPMK);
                break;
        case WPA_PTK_INITPMK:
                if (wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
-                                      WPA_EAPOL_keyAvailable) > 0)
+                                      WPA_EAPOL_keyAvailable) > 0) {
                        SM_ENTER(WPA_PTK, PTKSTART);
-               else {
+#ifdef CONFIG_DPP
+               } else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP && sm->pmksa) {
+                       SM_ENTER(WPA_PTK, PTKSTART);
+#endif /* CONFIG_DPP */
+               } else {
                        wpa_auth->dot11RSNA4WayHandshakeFailures++;
                        wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO,
                                        "INITPMK - keyAvailable = false");
@@ -3250,7 +3281,8 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
 
        wpa_send_eapol(sm->wpa_auth, sm,
                       WPA_KEY_INFO_SECURE |
-                      (wpa_mic_len(sm->wpa_key_mgmt) ? WPA_KEY_INFO_MIC : 0) |
+                      (wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ?
+                       WPA_KEY_INFO_MIC : 0) |
                       WPA_KEY_INFO_ACK |
                       (!sm->Pair ? WPA_KEY_INFO_INSTALL : 0),
                       rsc, NULL, kde, kde_len, gsm->GN, 1);
index c1aeb87bfb645bcbba0e6a35c5e69ff3e0bed6e7..7d6e015942d2cdec1d4d20cd9bcfb73e730b0d05 100644 (file)
@@ -276,7 +276,7 @@ enum {
        WPA_IE_OK, WPA_INVALID_IE, WPA_INVALID_GROUP, WPA_INVALID_PAIRWISE,
        WPA_INVALID_AKMP, WPA_NOT_ENABLED, WPA_ALLOC_FAIL,
        WPA_MGMT_FRAME_PROTECTION_VIOLATION, WPA_INVALID_MGMT_GROUP_CIPHER,
-       WPA_INVALID_MDIE, WPA_INVALID_PROTO
+       WPA_INVALID_MDIE, WPA_INVALID_PROTO, WPA_INVALID_PMKID
 };
 
 int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
index e7d699ee565a3ae9f2ca265e702a2473bb050589..23d2af307887c5b4048dc6d9a084a4a812b473cf 100644 (file)
@@ -43,6 +43,7 @@ struct wpa_state_machine {
        Boolean AuthenticationRequest;
        Boolean ReAuthenticationRequest;
        Boolean Disconnect;
+       u16 disconnect_reason; /* specific reason code to use with Disconnect */
        u32 TimeoutCtr;
        u32 GTimeoutCtr;
        Boolean TimeoutEvt;
index b1444d922817e91d7141fa4f9973a1fb3bb73f70..ff7b97ae1a4a9e557b2de2430e82a63c8a63db4a 100644 (file)
@@ -241,6 +241,13 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
                num_suites++;
        }
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+       if (conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) {
+               RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_DPP);
+               pos += RSN_SELECTOR_LEN;
+               num_suites++;
+       }
+#endif /* CONFIG_DPP */
 
 #ifdef CONFIG_RSN_TESTING
        if (rsn_testing) {
@@ -579,6 +586,10 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
                else if (data.key_mgmt & WPA_KEY_MGMT_OWE)
                        selector = RSN_AUTH_KEY_MGMT_OWE;
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+               else if (data.key_mgmt & WPA_KEY_MGMT_DPP)
+                       selector = RSN_AUTH_KEY_MGMT_DPP;
+#endif /* CONFIG_DPP */
                wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
 
                selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
@@ -675,6 +686,10 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
        else if (key_mgmt & WPA_KEY_MGMT_OWE)
                sm->wpa_key_mgmt = WPA_KEY_MGMT_OWE;
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+       else if (key_mgmt & WPA_KEY_MGMT_DPP)
+               sm->wpa_key_mgmt = WPA_KEY_MGMT_DPP;
+#endif /* CONFIG_DPP */
        else
                sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
 
@@ -804,6 +819,14 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
                os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN);
        }
 
+#ifdef CONFIG_DPP
+       if (sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP && !sm->pmksa) {
+               wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
+                                "No PMKSA cache entry found for DPP");
+               return WPA_INVALID_PMKID;
+       }
+#endif /* CONFIG_DPP */
+
        if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) {
                os_free(sm->wpa_ie);
                sm->wpa_ie = os_malloc(wpa_ie_len);
index 023fe200a94ee1183bda626127b161436721ef58..ffe4fecf75095c7ffd32974f29d4b7b340a61c83 100644 (file)
@@ -56,6 +56,7 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean;
 #define WPA_KEY_MGMT_FT_FILS_SHA256 BIT(20)
 #define WPA_KEY_MGMT_FT_FILS_SHA384 BIT(21)
 #define WPA_KEY_MGMT_OWE BIT(22)
+#define WPA_KEY_MGMT_DPP BIT(23)
 
 static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
 {
@@ -138,7 +139,8 @@ static inline int wpa_key_mgmt_wpa(int akm)
                wpa_key_mgmt_wpa_psk(akm) ||
                wpa_key_mgmt_fils(akm) ||
                wpa_key_mgmt_sae(akm) ||
-               akm == WPA_KEY_MGMT_OWE;
+               akm == WPA_KEY_MGMT_OWE ||
+               akm == WPA_KEY_MGMT_DPP;
 }
 
 static inline int wpa_key_mgmt_wpa_any(int akm)
index 8eabf5435fb4101fd62ba0a00c6708377e8f1276..47b0d425bf22553da6d3eac12eeaefc3c5329027 100644 (file)
@@ -13,6 +13,7 @@
 #include "crypto/sha1.h"
 #include "crypto/sha256.h"
 #include "crypto/sha384.h"
+#include "crypto/sha512.h"
 #include "crypto/aes_wrap.h"
 #include "crypto/crypto.h"
 #include "ieee802_11_defs.h"
@@ -20,7 +21,7 @@
 #include "wpa_common.h"
 
 
-static unsigned int wpa_kck_len(int akmp)
+static unsigned int wpa_kck_len(int akmp, size_t pmk_len)
 {
        switch (akmp) {
        case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
@@ -30,13 +31,15 @@ static unsigned int wpa_kck_len(int akmp)
        case WPA_KEY_MGMT_FILS_SHA384:
        case WPA_KEY_MGMT_FT_FILS_SHA384:
                return 0;
+       case WPA_KEY_MGMT_DPP:
+               return pmk_len / 2;
        default:
                return 16;
        }
 }
 
 
-static unsigned int wpa_kek_len(int akmp)
+static unsigned int wpa_kek_len(int akmp, size_t pmk_len)
 {
        switch (akmp) {
        case WPA_KEY_MGMT_FILS_SHA384:
@@ -46,13 +49,15 @@ static unsigned int wpa_kek_len(int akmp)
        case WPA_KEY_MGMT_FILS_SHA256:
        case WPA_KEY_MGMT_FT_FILS_SHA256:
                return 32;
+       case WPA_KEY_MGMT_DPP:
+               return pmk_len <= 32 ? 16 : 32;
        default:
                return 16;
        }
 }
 
 
-unsigned int wpa_mic_len(int akmp)
+unsigned int wpa_mic_len(int akmp, size_t pmk_len)
 {
        switch (akmp) {
        case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
@@ -62,6 +67,8 @@ unsigned int wpa_mic_len(int akmp)
        case WPA_KEY_MGMT_FT_FILS_SHA256:
        case WPA_KEY_MGMT_FT_FILS_SHA384:
                return 0;
+       case WPA_KEY_MGMT_DPP:
+               return pmk_len / 2;
        default:
                return 16;
        }
@@ -91,7 +98,7 @@ unsigned int wpa_mic_len(int akmp)
 int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
                      const u8 *buf, size_t len, u8 *mic)
 {
-       u8 hash[SHA384_MAC_LEN];
+       u8 hash[SHA512_MAC_LEN];
 
        switch (ver) {
 #ifndef CONFIG_FIPS
@@ -145,6 +152,29 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
                        os_memcpy(mic, hash, MD5_MAC_LEN);
                        break;
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+               case WPA_KEY_MGMT_DPP:
+                       wpa_printf(MSG_DEBUG,
+                                  "WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - DPP)",
+                                  (unsigned int) key_len * 8 * 2);
+                       if (key_len == 128 / 8) {
+                               if (hmac_sha256(key, key_len, buf, len, hash))
+                                       return -1;
+                       } else if (key_len == 192 / 8) {
+                               if (hmac_sha384(key, key_len, buf, len, hash))
+                                       return -1;
+                       } else if (key_len == 256 / 8) {
+                               if (hmac_sha256(key, key_len, buf, len, hash))
+                                       return -1;
+                       } else {
+                               wpa_printf(MSG_INFO,
+                                          "DPP: Unsupported KCK length: %u",
+                                          (unsigned int) key_len);
+                               return -1;
+                       }
+                       os_memcpy(mic, hash, key_len / 8);
+                       break;
+#endif /* CONFIG_DPP */
                default:
                        wpa_printf(MSG_DEBUG,
                                   "WPA: EAPOL-Key MIC algorithm not known (AKM-defined - akmp=0x%x)",
@@ -213,8 +243,8 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
                          WPA_NONCE_LEN);
        }
 
-       ptk->kck_len = wpa_kck_len(akmp);
-       ptk->kek_len = wpa_kek_len(akmp);
+       ptk->kck_len = wpa_kck_len(akmp, pmk_len);
+       ptk->kek_len = wpa_kek_len(akmp, pmk_len);
        ptk->tk_len = wpa_cipher_key_len(cipher);
        ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
 
@@ -236,6 +266,27 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
 #else /* CONFIG_IEEE80211W */
                return -1;
 #endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_DPP
+       } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 32) {
+               wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
+               if (sha256_prf(pmk, pmk_len, label, data, sizeof(data),
+                              tmp, ptk_len) < 0)
+                       return -1;
+       } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 48) {
+               wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
+               if (sha384_prf(pmk, pmk_len, label, data, sizeof(data),
+                              tmp, ptk_len) < 0)
+                       return -1;
+       } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 64) {
+               wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)");
+               if (sha512_prf(pmk, pmk_len, label, data, sizeof(data),
+                              tmp, ptk_len) < 0)
+                       return -1;
+       } else if (akmp == WPA_KEY_MGMT_DPP) {
+               wpa_printf(MSG_INFO, "DPP: Unknown PMK length %u",
+                          (unsigned int) pmk_len);
+               return -1;
+#endif /* CONFIG_DPP */
        } else {
                wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA1)");
                if (sha1_prf(pmk, pmk_len, label, data, sizeof(data), tmp,
@@ -364,7 +415,7 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
        os_memcpy(data + 2 * ETH_ALEN + FILS_NONCE_LEN, anonce, FILS_NONCE_LEN);
 
        ptk->kck_len = 0;
-       ptk->kek_len = wpa_kek_len(akmp);
+       ptk->kek_len = wpa_kek_len(akmp, pmk_len);
        ptk->tk_len = wpa_cipher_key_len(cipher);
        if (wpa_key_mgmt_sha384(akmp))
                *ick_len = 48;
@@ -836,6 +887,10 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
        if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OWE)
                return WPA_KEY_MGMT_OWE;
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+       if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_DPP)
+               return WPA_KEY_MGMT_DPP;
+#endif /* CONFIG_DPP */
        if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OSEN)
                return WPA_KEY_MGMT_OSEN;
        return 0;
@@ -1319,8 +1374,8 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
        os_memcpy(pos, sta_addr, ETH_ALEN);
        pos += ETH_ALEN;
 
-       ptk->kck_len = wpa_kck_len(akmp);
-       ptk->kek_len = wpa_kek_len(akmp);
+       ptk->kck_len = wpa_kck_len(akmp, PMK_LEN);
+       ptk->kek_len = wpa_kek_len(akmp, PMK_LEN);
        ptk->tk_len = wpa_cipher_key_len(cipher);
        ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
 
index c0773e8b23e68ac33aae597ff2b0fc959cd419b4..f96eaa8beb044bf6705264fa5353d974b73cdbfc 100644 (file)
@@ -13,7 +13,7 @@
 #define PMKID_LEN 16
 #define PMK_LEN 32
 #define PMK_LEN_SUITE_B_192 48
-#define PMK_LEN_MAX 48
+#define PMK_LEN_MAX 64
 #define WPA_REPLAY_COUNTER_LEN 8
 #define WPA_NONCE_LEN 32
 #define WPA_KEY_RSC_LEN 8
@@ -68,6 +68,7 @@ RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
 #define RSN_AUTH_KEY_MGMT_OWE RSN_SELECTOR(0x00, 0x0f, 0xac, 18)
 #define RSN_AUTH_KEY_MGMT_CCKM RSN_SELECTOR(0x00, 0x40, 0x96, 0x00)
 #define RSN_AUTH_KEY_MGMT_OSEN RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x01)
+#define RSN_AUTH_KEY_MGMT_DPP RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x02)
 
 #define RSN_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x0f, 0xac, 0)
 #define RSN_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
@@ -197,8 +198,8 @@ struct wpa_eapol_key {
        /* followed by Key Data Length bytes of Key Data */
 } STRUCT_PACKED;
 
-#define WPA_EAPOL_KEY_MIC_MAX_LEN 24
-#define WPA_KCK_MAX_LEN 24
+#define WPA_EAPOL_KEY_MIC_MAX_LEN 32
+#define WPA_KCK_MAX_LEN 32
 #define WPA_KEK_MAX_LEN 64
 #define WPA_TK_MAX_LEN 32
 #define FILS_ICK_MAX_LEN 48
@@ -465,7 +466,7 @@ int wpa_pick_group_cipher(int ciphers);
 int wpa_parse_cipher(const char *value);
 int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim);
 int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise);
-unsigned int wpa_mic_len(int akmp);
+unsigned int wpa_mic_len(int akmp, size_t pmk_len);
 int fils_domain_name_hash(const char *domain, u8 *hash);
 
 #endif /* WPA_COMMON_H */
index 9587d063e79b640f33d8a98febf37e9ee30efa36..aee0cf60d5fd8bde22318e560fb1bc2101ba77e2 100644 (file)
@@ -1437,6 +1437,7 @@ struct wpa_driver_capa {
 #define WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B       0x00000100
 #define WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192   0x00000200
 #define WPA_DRIVER_CAPA_KEY_MGMT_OWE           0x00000400
+#define WPA_DRIVER_CAPA_KEY_MGMT_DPP           0x00000800
        /** Bitfield of supported key management suites */
        unsigned int key_mgmt;
 
index 9aa4e14e6aaea3867a235cfaac44043ab8e2702b..3d747ce0fc1030c1da8a36f49cf116ae9e1b5908 100644 (file)
@@ -1133,7 +1133,8 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
                WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
                WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B |
                WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192 |
-               WPA_DRIVER_CAPA_KEY_MGMT_OWE;
+               WPA_DRIVER_CAPA_KEY_MGMT_OWE |
+               WPA_DRIVER_CAPA_KEY_MGMT_DPP;
        drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
                WPA_DRIVER_AUTH_SHARED |
                WPA_DRIVER_AUTH_LEAP;
index ce338f8fd9214179e37c7cee6035dbbe2ff1709f..415afc90b4f76d2de3635d8a97b1603e69a55c1f 100644 (file)
@@ -1005,7 +1005,7 @@ int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
                return -1;
        }
 
-       mic_len = wpa_mic_len(sm->key_mgmt);
+       mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
        if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
                ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
        else
index 4e5b0a4f749f48d2bcf0eddee36ccdb8938333ef..183823ff47a90722819aaf54ba61794ba9d24078 100644 (file)
@@ -49,7 +49,7 @@ int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk,
                       u8 *msg, size_t msg_len, u8 *key_mic)
 {
        int ret = -1;
-       size_t mic_len = wpa_mic_len(sm->key_mgmt);
+       size_t mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
 
        wpa_printf(MSG_DEBUG, "WPA: Send EAPOL-Key frame to " MACSTR
                   " ver=%d mic_len=%d key_mgmt=0x%x",
@@ -197,7 +197,7 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
                return;
        }
 
-       mic_len = wpa_mic_len(sm->key_mgmt);
+       mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
        hdrlen = sizeof(*reply) + mic_len + 2;
        rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
                                  hdrlen, &rlen, (void *) &reply);
@@ -469,7 +469,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
 
        wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
 
-       mic_len = wpa_mic_len(sm->key_mgmt);
+       mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
        hdrlen = sizeof(*reply) + mic_len + 2;
        rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
                                  NULL, hdrlen + wpa_ie_len,
@@ -657,6 +657,7 @@ static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
                        MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
                eapol_sm_notify_portValid(sm->eapol, TRUE);
                if (wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
+                   sm->key_mgmt == WPA_KEY_MGMT_DPP ||
                    sm->key_mgmt == WPA_KEY_MGMT_OWE)
                        eapol_sm_notify_eap_success(sm->eapol, TRUE);
                /*
@@ -1234,7 +1235,7 @@ int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
        struct wpa_eapol_key *reply;
        u8 *rbuf, *key_mic;
 
-       mic_len = wpa_mic_len(sm->key_mgmt);
+       mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
        hdrlen = sizeof(*reply) + mic_len + 2;
        rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
                                  hdrlen, &rlen, (void *) &reply);
@@ -1543,7 +1544,7 @@ static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
        struct wpa_eapol_key *reply;
        u8 *rbuf, *key_mic;
 
-       mic_len = wpa_mic_len(sm->key_mgmt);
+       mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
        hdrlen = sizeof(*reply) + mic_len + 2;
        rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
                                  hdrlen, &rlen, (void *) &reply);
@@ -1654,7 +1655,7 @@ static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
 {
        u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
        int ok = 0;
-       size_t mic_len = wpa_mic_len(sm->key_mgmt);
+       size_t mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
 
        os_memcpy(mic, key + 1, mic_len);
        if (sm->tptk_set) {
@@ -1740,6 +1741,7 @@ static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
        } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
                   ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
                   sm->key_mgmt == WPA_KEY_MGMT_OWE ||
+                  sm->key_mgmt == WPA_KEY_MGMT_DPP ||
                   sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
                   wpa_key_mgmt_suite_b(sm->key_mgmt)) {
                u8 *buf;
@@ -1936,7 +1938,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
        sm->ft_completed = 0;
 #endif /* CONFIG_IEEE80211R */
 
-       mic_len = wpa_mic_len(sm->key_mgmt);
+       mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
        keyhdrlen = sizeof(*key) + mic_len + 2;
 
        if (len < sizeof(*hdr) + keyhdrlen) {
@@ -2022,6 +2024,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
            !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
            !wpa_key_mgmt_fils(sm->key_mgmt) &&
            sm->key_mgmt != WPA_KEY_MGMT_OWE &&
+           sm->key_mgmt != WPA_KEY_MGMT_DPP &&
            sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
                wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
                        "WPA: Unsupported EAPOL-Key descriptor version %d",
@@ -2039,6 +2042,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
 
        if ((wpa_key_mgmt_suite_b(sm->key_mgmt) ||
             wpa_key_mgmt_fils(sm->key_mgmt) ||
+            sm->key_mgmt == WPA_KEY_MGMT_DPP ||
             sm->key_mgmt == WPA_KEY_MGMT_OWE) &&
            ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
                wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
@@ -2074,6 +2078,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
            !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
            !wpa_key_mgmt_fils(sm->key_mgmt) &&
            sm->key_mgmt != WPA_KEY_MGMT_OWE &&
+           sm->key_mgmt != WPA_KEY_MGMT_DPP &&
            ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
                wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
                        "WPA: CCMP is used, but EAPOL-Key "
@@ -3094,6 +3099,13 @@ void wpa_sm_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
 }
 
 
+int wpa_sm_pmksa_exists(struct wpa_sm *sm, const u8 *bssid,
+                       const void *network_ctx)
+{
+       return pmksa_cache_get(sm->pmksa, bssid, NULL, network_ctx) != NULL;
+}
+
+
 void wpa_sm_drop_sa(struct wpa_sm *sm)
 {
        wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
index bee1c9221274159c56316b65220a8e5e2c01db39..37c5d62f1c1d053e6123f215b98119bc5961e019 100644 (file)
@@ -160,6 +160,8 @@ wpa_sm_pmksa_cache_add_entry(struct wpa_sm *sm,
 void wpa_sm_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
                            const u8 *pmkid, const u8 *bssid,
                            const u8 *fils_cache_id);
+int wpa_sm_pmksa_exists(struct wpa_sm *sm, const u8 *bssid,
+                       const void *network_ctx);
 void wpa_sm_drop_sa(struct wpa_sm *sm);
 int wpa_sm_has_ptk(struct wpa_sm *sm);
 
index cd7f14e211d47b303673624aca87d378295064a5..627bfeb4213f2b0b7122f055dad2956abada95fe 100644 (file)
@@ -196,6 +196,10 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
        } else if (key_mgmt & WPA_KEY_MGMT_OWE) {
                RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OWE);
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+       } else if (key_mgmt & WPA_KEY_MGMT_DPP) {
+               RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_DPP);
+#endif /* CONFIG_DPP */
        } else {
                wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
                           key_mgmt);
index c4f5e8da50a9484efdd456d6d960ec8ba18624dd..a0c6845b69c3a372e958b2216fde8cbea92d1733 100644 (file)
@@ -39,7 +39,7 @@ static int check_mic(const u8 *kck, size_t kck_len, int akmp, int ver,
        struct ieee802_1x_hdr *hdr;
        struct wpa_eapol_key *key;
        u8 rx_mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
-       size_t mic_len = wpa_mic_len(akmp);
+       size_t mic_len = wpa_mic_len(akmp, PMK_LEN);
 
        buf = os_memdup(data, len);
        if (buf == NULL)
@@ -244,7 +244,7 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
 
        eapol = (const struct ieee802_1x_hdr *) data;
        hdr = (const struct wpa_eapol_key *) (eapol + 1);
-       mic_len = wpa_mic_len(sta->key_mgmt);
+       mic_len = wpa_mic_len(sta->key_mgmt, PMK_LEN);
        mic = (const u8 *) (hdr + 1);
        if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
                add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
@@ -413,7 +413,7 @@ static u8 * decrypt_eapol_key_data(struct wlantest *wt, int akmp, const u8 *kek,
                return NULL;
 
        mic = (const u8 *) (hdr + 1);
-       mic_len = wpa_mic_len(akmp);
+       mic_len = wpa_mic_len(akmp, PMK_LEN);
        keydata = mic + mic_len + 2;
        keydatalen = WPA_GET_BE16(mic + mic_len);
 
@@ -574,7 +574,7 @@ static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
        sta = sta_get(bss, dst);
        if (sta == NULL)
                return;
-       mic_len = wpa_mic_len(sta->key_mgmt);
+       mic_len = wpa_mic_len(sta->key_mgmt, PMK_LEN);
 
        eapol = (const struct ieee802_1x_hdr *) data;
        hdr = (const struct wpa_eapol_key *) (eapol + 1);
@@ -805,7 +805,7 @@ static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
        sta = sta_get(bss, dst);
        if (sta == NULL)
                return;
-       mic_len = wpa_mic_len(sta->key_mgmt);
+       mic_len = wpa_mic_len(sta->key_mgmt, PMK_LEN);
 
        eapol = (const struct ieee802_1x_hdr *) data;
        hdr = (const struct wpa_eapol_key *) (eapol + 1);
@@ -974,7 +974,7 @@ static void rx_data_eapol_key(struct wlantest *wt, const u8 *bssid,
        if (bss) {
                sta = sta_get(bss, sta_addr);
                if (sta)
-                       mic_len = wpa_mic_len(sta->key_mgmt);
+                       mic_len = wpa_mic_len(sta->key_mgmt, PMK_LEN);
        }
 
        eapol = (const struct ieee802_1x_hdr *) data;
index 0248d7981731794a81ab3a2816c7dfcac91bd4e7..0be77ff225606fc58efe079c379e7e33f439b101 100644 (file)
@@ -780,6 +780,10 @@ static int wpa_config_parse_key_mgmt(const struct parse_data *data,
                else if (os_strcmp(start, "OWE") == 0)
                        val |= WPA_KEY_MGMT_OWE;
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+               else if (os_strcmp(start, "DPP") == 0)
+                       val |= WPA_KEY_MGMT_DPP;
+#endif /* CONFIG_DPP */
                else {
                        wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
                                   line, start);
index d8363a48c6a3b25139144c3eb59beb969abe1aeb..61ea6392eb90603edf0110aa4dcba08e923c6829 100644 (file)
@@ -2610,6 +2610,16 @@ static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
        }
 #endif /* CONFIG_OWE */
 
+#ifdef CONFIG_DPP
+       if (data.key_mgmt & WPA_KEY_MGMT_DPP) {
+               ret = os_snprintf(pos, end - pos, "%sDPP",
+                                 pos == start ? "" : "+");
+               if (os_snprintf_error(end - pos, ret))
+                       return pos;
+               pos += ret;
+       }
+#endif /* CONFIG_DPP */
+
        if (data.key_mgmt & WPA_KEY_MGMT_OSEN) {
                ret = os_snprintf(pos, end - pos, "%sOSEN",
                                  pos == start ? "" : "+");
@@ -3836,6 +3846,14 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
                pos += ret;
        }
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
+               ret = os_snprintf(pos, end - pos, " DPP");
+               if (os_snprintf_error(end - pos, ret))
+                       return pos - buf;
+               pos += ret;
+       }
+#endif /* CONFIG_DPP */
 
        return pos - buf;
 }
index 648ffdc86e0091bd78e0edd1e10c614a52976b7e..d16108faac933bd2f55755e4dd12f62dd2be77dc 100644 (file)
@@ -305,7 +305,8 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
        eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
        eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
        if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
-           wpa_s->key_mgmt == WPA_KEY_MGMT_OWE)
+           wpa_s->key_mgmt == WPA_KEY_MGMT_OWE ||
+           wpa_s->key_mgmt == WPA_KEY_MGMT_DPP)
                eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
        wpa_s->ap_ies_from_associnfo = 0;
        wpa_s->current_ssid = NULL;
@@ -1212,6 +1213,18 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_MBO */
 
+#ifdef CONFIG_DPP
+               if ((ssid->key_mgmt & WPA_KEY_MGMT_DPP) &&
+                   !wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, ssid)) {
+                       /* TODO: Go through DPP network introduction to generate
+                        * PMKSA entry. */
+                       if (debug_print)
+                               wpa_dbg(wpa_s, MSG_DEBUG,
+                                       "   skip - no PMKSA entry for DPP");
+                       continue;
+               }
+#endif /* CONFIG_DPP */
+
                /* Matching configuration found */
                return ssid;
        }
@@ -2541,6 +2554,7 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
                eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
        }
        if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
+           wpa_s->key_mgmt == WPA_KEY_MGMT_DPP ||
            wpa_s->key_mgmt == WPA_KEY_MGMT_OWE || ft_completed ||
            already_authorized)
                eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
index 0a107b08566ca39505819d81803a7ad8996ee2ff..ca6f179a1849263ccbb49857ab64ef7e7accc4bb 100644 (file)
@@ -1018,7 +1018,8 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
         * pkcs11_engine_path, pkcs11_module_path, openssl_ciphers.
         */
        if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
-           wpa_s->key_mgmt == WPA_KEY_MGMT_OWE) {
+           wpa_s->key_mgmt == WPA_KEY_MGMT_OWE ||
+           wpa_s->key_mgmt == WPA_KEY_MGMT_DPP) {
                /*
                 * Clear forced success to clear EAP state for next
                 * authentication.
@@ -1359,6 +1360,11 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
                wpa_s->key_mgmt = WPA_KEY_MGMT_OWE;
                wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT OWE");
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+       } else if (sel & WPA_KEY_MGMT_DPP) {
+               wpa_s->key_mgmt = WPA_KEY_MGMT_DPP;
+               wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT DPP");
+#endif /* CONFIG_DPP */
        } else {
                wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
                        "authenticated key management type");
@@ -3751,6 +3757,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
        os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
        if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
            wpa_s->key_mgmt != WPA_KEY_MGMT_OWE &&
+           wpa_s->key_mgmt != WPA_KEY_MGMT_DPP &&
            eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
                return;
        wpa_drv_poll(wpa_s);
index ae246f99cd9b7f86b2023dc7d31eb41bf5348263..8b4a883e45fecbc75e032dec187473a57b46b82e 100644 (file)
@@ -147,6 +147,7 @@ static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
 
        if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
            wpa_s->key_mgmt == WPA_KEY_MGMT_OWE ||
+           wpa_s->key_mgmt == WPA_KEY_MGMT_DPP ||
            wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
                /* Current SSID is not using IEEE 802.1X/EAP, so drop possible
                 * EAPOL frames (mainly, EAPOL-Start) from EAPOL state