]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OWE: Define and parse OWE AKM selector
authorJouni Malinen <j@w1.fi>
Sat, 11 Mar 2017 22:32:23 +0000 (00:32 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 12 Mar 2017 17:24:11 +0000 (19:24 +0200)
This adds a new RSN AKM "OWE".

Signed-off-by: Jouni Malinen <j@w1.fi>
15 files changed:
hostapd/config_file.c
hostapd/ctrl_iface.c
src/ap/ieee802_1x.c
src/ap/wpa_auth.c
src/ap/wpa_auth_ie.c
src/common/defs.h
src/common/wpa_common.c
src/common/wpa_common.h
src/rsn_supp/wpa.c
src/rsn_supp/wpa_ie.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 4ff4691942b95fb45c3d6f20242bb14b7f581ae5..2e4433d0792574ef3cf379acca77ed7b54cd809e 100644 (file)
@@ -710,6 +710,10 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
                        val |= WPA_KEY_MGMT_FT_FILS_SHA384;
 #endif /* CONFIG_IEEE80211R_AP */
 #endif /* CONFIG_FILS */
+#ifdef CONFIG_OWE
+               else if (os_strcmp(start, "OWE") == 0)
+                       val |= WPA_KEY_MGMT_OWE;
+#endif /* CONFIG_OWE */
                else {
                        wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
                                   line, start);
index 0d649cdccef865a370344024920aa45d16760d5d..9bfead0e8365010107d68a892f61020a2a67a3f3 100644 (file)
@@ -1100,6 +1100,15 @@ static int hostapd_ctrl_iface_get_key_mgmt(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_FILS */
 
+#ifdef CONFIG_OWE
+       if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) {
+               ret = os_snprintf(pos, end - pos, "OWE ");
+               if (os_snprintf_error(end - pos, ret))
+                       return pos - buf;
+               pos += ret;
+       }
+#endif /* CONFIG_OWE */
+
        if (pos > buf && *(pos - 1) == ' ') {
                *(pos - 1) = '\0';
                pos--;
index 7591df6bee368a29fe86896b4867d942c88ecb6d..ae38f6c7de5ae757bbcbfa531b288ce4b030f0e7 100644 (file)
@@ -973,7 +973,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)) {
+       if (key_mgmt != -1 &&
+           (wpa_key_mgmt_wpa_psk(key_mgmt) || key_mgmt == WPA_KEY_MGMT_OWE)) {
                wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore EAPOL message - "
                           "STA is using PSK");
                return;
@@ -1116,7 +1117,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)) {
+       if (key_mgmt != -1 &&
+           (wpa_key_mgmt_wpa_psk(key_mgmt) || key_mgmt == WPA_KEY_MGMT_OWE)) {
                wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore STA - using PSK");
                /*
                 * Clear any possible EAPOL authenticator state to support
index df4db280df32d5a197c9b238ddccace4d2437e21..4d3b5c057a571accd8e309d3b4a29e7b4ffa5373 100644 (file)
@@ -1809,7 +1809,8 @@ SM_STATE(WPA_PTK, INITIALIZE)
        wpa_remove_ptk(sm);
        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)) {
+       if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
+           sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE) {
                wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
                                   WPA_EAPOL_authorized, 0);
        }
@@ -2882,7 +2883,8 @@ SM_STATE(WPA_PTK, PTKINITDONE)
                                               sm->wpa_auth, sm);
                }
 
-               if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
+               if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
+                   sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE) {
                        wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
                                           WPA_EAPOL_authorized, 1);
                }
@@ -2951,7 +2953,8 @@ SM_STEP(WPA_PTK)
                    wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
                                       WPA_EAPOL_keyRun) > 0)
                        SM_ENTER(WPA_PTK, INITPMK);
-               else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)
+               else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
+                        sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE
                         /* FIX: && 802.1X::keyRun */)
                        SM_ENTER(WPA_PTK, INITPSK);
                break;
index c770d62a0b121aa3e52350c2d6476ee66e40daa5..5a7691fd227a14e9e2b3f639d92bd6b1838df0dc 100644 (file)
@@ -234,6 +234,13 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
        }
 #endif /* CONFIG_IEEE80211R_AP */
 #endif /* CONFIG_FILS */
+#ifdef CONFIG_OWE
+       if (conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) {
+               RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OWE);
+               pos += RSN_SELECTOR_LEN;
+               num_suites++;
+       }
+#endif /* CONFIG_OWE */
 
 #ifdef CONFIG_RSN_TESTING
        if (rsn_testing) {
@@ -567,6 +574,10 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
                        selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
                else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
                        selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
+#ifdef CONFIG_OWE
+               else if (data.key_mgmt & WPA_KEY_MGMT_OWE)
+                       selector = RSN_AUTH_KEY_MGMT_OWE;
+#endif /* CONFIG_OWE */
                wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
 
                selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
@@ -659,6 +670,10 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
 #endif /* CONFIG_SAE */
        else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
                sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
+#ifdef CONFIG_OWE
+       else if (key_mgmt & WPA_KEY_MGMT_OWE)
+               sm->wpa_key_mgmt = WPA_KEY_MGMT_OWE;
+#endif /* CONFIG_OWE */
        else
                sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
 
index eaccced22a762522240b006f7a5bbe740c34f362..4f2b64041e7ff67f3318b90fe5d418ad9c4d2f34 100644 (file)
@@ -55,6 +55,7 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean;
 #define WPA_KEY_MGMT_FILS_SHA384 BIT(19)
 #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)
 
 static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
 {
@@ -136,7 +137,8 @@ static inline int wpa_key_mgmt_wpa(int akm)
        return wpa_key_mgmt_wpa_ieee8021x(akm) ||
                wpa_key_mgmt_wpa_psk(akm) ||
                wpa_key_mgmt_fils(akm) ||
-               wpa_key_mgmt_sae(akm);
+               wpa_key_mgmt_sae(akm) ||
+               akm == WPA_KEY_MGMT_OWE;
 }
 
 static inline int wpa_key_mgmt_wpa_any(int akm)
index fd167d6f54308fa27ee28758642bb3f6f1902181..5df192e57a33fe83bca37472bdd0eedfd813e79f 100644 (file)
@@ -765,6 +765,10 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
                return WPA_KEY_MGMT_FT_FILS_SHA256;
        if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_FILS_SHA384)
                return WPA_KEY_MGMT_FT_FILS_SHA384;
+#ifdef CONFIG_OWE
+       if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OWE)
+               return WPA_KEY_MGMT_OWE;
+#endif /* CONFIG_OWE */
        if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OSEN)
                return WPA_KEY_MGMT_OSEN;
        return 0;
index a84cc9b2d1aa9a04a224ac4a4279bbe9987d38c8..c37f8175f086b807eb592a0e6915ea000d2a41ac 100644 (file)
@@ -63,6 +63,7 @@ RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
 #define RSN_AUTH_KEY_MGMT_FILS_SHA384 RSN_SELECTOR(0x00, 0x0f, 0xac, 15)
 #define RSN_AUTH_KEY_MGMT_FT_FILS_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 16)
 #define RSN_AUTH_KEY_MGMT_FT_FILS_SHA384 RSN_SELECTOR(0x00, 0x0f, 0xac, 17)
+#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)
 
index b1218212cea8550646c71352e47176fc492e4ed3..a1b647e5a04a4be99e65c78ebcd057dae2384506 100644 (file)
@@ -652,7 +652,8 @@ static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
                        sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,
                        MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
                eapol_sm_notify_portValid(sm->eapol, TRUE);
-               if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
+               if (wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
+                   sm->key_mgmt == WPA_KEY_MGMT_OWE)
                        eapol_sm_notify_eap_success(sm->eapol, TRUE);
                /*
                 * Start preauthentication after a short wait to avoid a
index 3be3087dad898bb420cfcac8cf2c33ac47516bbe..cd7f14e211d47b303673624aca87d378295064a5 100644 (file)
@@ -192,6 +192,10 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
                RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384);
 #endif /* CONFIG_IEEE80211R */
 #endif /* CONFIG_FILS */
+#ifdef CONFIG_OWE
+       } else if (key_mgmt & WPA_KEY_MGMT_OWE) {
+               RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OWE);
+#endif /* CONFIG_OWE */
        } else {
                wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
                           key_mgmt);
index 676b618b2ab120925f03982e66643f8a0e39fc30..f56b49bb8ad4f2edaa0bc7c2751fab3ae4bc3047 100644 (file)
@@ -732,6 +732,10 @@ static int wpa_config_parse_key_mgmt(const struct parse_data *data,
                        val |= WPA_KEY_MGMT_FT_FILS_SHA384;
 #endif /* CONFIG_IEEE80211R */
 #endif /* CONFIG_FILS */
+#ifdef CONFIG_OWE
+               else if (os_strcmp(start, "OWE") == 0)
+                       val |= WPA_KEY_MGMT_OWE;
+#endif /* CONFIG_OWE */
                else {
                        wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
                                   line, start);
index 95cae13ccfec08ea8d2a2297ff57dfa05c702256..a9839649991ffe7ae046bbfe1e7dee3b84fa35d0 100644 (file)
@@ -2578,6 +2578,16 @@ static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
 #endif /* CONFIG_IEEE80211R */
 #endif /* CONFIG_FILS */
 
+#ifdef CONFIG_OWE
+       if (data.key_mgmt & WPA_KEY_MGMT_OWE) {
+               ret = os_snprintf(pos, end - pos, "%sOWE",
+                                 pos == start ? "" : "+");
+               if (os_snprintf_error(end - pos, ret))
+                       return pos;
+               pos += ret;
+       }
+#endif /* CONFIG_OWE */
+
        if (data.key_mgmt & WPA_KEY_MGMT_OSEN) {
                ret = os_snprintf(pos, end - pos, "%sOSEN",
                                  pos == start ? "" : "+");
index 11cab658bf17aad103ab7c44d7caa9d61dc707b4..053fe15233fda6dbe2f9347e41f68b2235168f33 100644 (file)
@@ -302,7 +302,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))
+       if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
+           wpa_s->key_mgmt == WPA_KEY_MGMT_OWE)
                eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
        wpa_s->ap_ies_from_associnfo = 0;
        wpa_s->current_ssid = NULL;
@@ -2521,7 +2522,8 @@ static void wpa_supplicant_event_assoc(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) || ft_completed ||
+       if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
+           wpa_s->key_mgmt == WPA_KEY_MGMT_OWE || ft_completed ||
            already_authorized)
                eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
        /* 802.1X::portControl = Auto */
index 774d2c737db24998487964c3fbb889cedcd8e930..e65441d8b33e27431446e869771c348717567ba0 100644 (file)
@@ -997,7 +997,8 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
         * TODO: should notify EAPOL SM about changes in opensc_engine_path,
         * pkcs11_engine_path, pkcs11_module_path, openssl_ciphers.
         */
-       if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
+       if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
+           wpa_s->key_mgmt == WPA_KEY_MGMT_OWE) {
                /*
                 * Clear forced success to clear EAP state for next
                 * authentication.
@@ -1333,6 +1334,11 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
                wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
                wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
 #endif /* CONFIG_HS20 */
+#ifdef CONFIG_OWE
+       } else if (sel & WPA_KEY_MGMT_OWE) {
+               wpa_s->key_mgmt = WPA_KEY_MGMT_OWE;
+               wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT OWE");
+#endif /* CONFIG_OWE */
        } else {
                wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
                        "authenticated key management type");
@@ -3575,6 +3581,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 &&
            eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
                return;
        wpa_drv_poll(wpa_s);
index 768911fee79bce5ebe850d93e1855aed8a31e14f..52904d3d9c38a6ce61bedaa377947cc8e7a9151a 100644 (file)
@@ -146,6 +146,7 @@ static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
         * extra copy here */
 
        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_NONE) {
                /* Current SSID is not using IEEE 802.1X/EAP, so drop possible
                 * EAPOL frames (mainly, EAPOL-Start) from EAPOL state