diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c index 29b41f5bc..ac8f6fae8 100644 --- a/src/ap/ctrl_iface_ap.c +++ b/src/ap/ctrl_iface_ap.c @@ -1060,7 +1060,8 @@ void * hostapd_ctrl_iface_pmksa_create_entry(const u8 *aa, char *cmd) if (sscanf(pos, "%d", &expiration) != 1) return NULL; - return wpa_auth_pmksa_create_entry(aa, spa, pmk, pmkid, expiration); + return wpa_auth_pmksa_create_entry(aa, spa, pmk, PMK_LEN, + WPA_KEY_MGMT_SAE, pmkid, expiration); } #endif /* CONFIG_MESH */ diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 1d4e5c5be..639d21d12 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -982,7 +982,8 @@ void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta) sta->sae->peer_commit_scalar_accepted = sta->sae->peer_commit_scalar; sta->sae->peer_commit_scalar = NULL; wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr, - sta->sae->pmk, sta->sae->pmkid); + sta->sae->pmk, sta->sae->pmk_len, + sta->sae->pmkid, sta->sae->akmp); sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS); } @@ -2514,7 +2515,8 @@ static int pasn_wd_handle_sae_confirm(struct hostapd_data *hapd, * restrict this only for PASN. */ wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr, - pasn->sae.pmk, pasn->sae.pmkid); + pasn->sae.pmk, pasn->sae.pmk_len, + pasn->sae.pmkid, pasn->sae.akmp); return 0; } diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 0776fae1a..53211f625 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -4860,16 +4860,17 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, - const u8 *pmk, const u8 *pmkid) + const u8 *pmk, size_t pmk_len, const u8 *pmkid, + int akmp) { if (wpa_auth->conf.disable_pmksa_caching) return -1; - wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from SAE", pmk, PMK_LEN); - if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, PMK_LEN, pmkid, - NULL, 0, - wpa_auth->addr, addr, 0, NULL, - WPA_KEY_MGMT_SAE)) + wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from SAE", pmk, pmk_len); + if (!akmp) + akmp = WPA_KEY_MGMT_SAE; + if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, pmk_len, pmkid, + NULL, 0, wpa_auth->addr, addr, 0, NULL, akmp)) return 0; return -1; @@ -4947,13 +4948,14 @@ int wpa_auth_pmksa_list_mesh(struct wpa_authenticator *wpa_auth, const u8 *addr, struct rsn_pmksa_cache_entry * wpa_auth_pmksa_create_entry(const u8 *aa, const u8 *spa, const u8 *pmk, + size_t pmk_len, int akmp, const u8 *pmkid, int expiration) { struct rsn_pmksa_cache_entry *entry; struct os_reltime now; - entry = pmksa_cache_auth_create_entry(pmk, PMK_LEN, pmkid, NULL, 0, aa, - spa, 0, NULL, WPA_KEY_MGMT_SAE); + entry = pmksa_cache_auth_create_entry(pmk, pmk_len, pmkid, NULL, 0, aa, + spa, 0, NULL, akmp); if (!entry) return NULL; diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index d2a36006a..c6ba422f7 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -425,7 +425,8 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, int session_timeout, struct eapol_state_machine *eapol); int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, - const u8 *pmk, const u8 *pmkid); + const u8 *pmk, size_t pmk_len, const u8 *pmkid, + int akmp); void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid); int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr, const u8 *pmk, size_t pmk_len, const u8 *pmkid, @@ -439,6 +440,7 @@ int wpa_auth_pmksa_list_mesh(struct wpa_authenticator *wpa_auth, const u8 *addr, char *buf, size_t len); struct rsn_pmksa_cache_entry * wpa_auth_pmksa_create_entry(const u8 *aa, const u8 *spa, const u8 *pmk, + size_t pmk_len, int akmp, const u8 *pmkid, int expiration); int wpa_auth_pmksa_add_entry(struct wpa_authenticator *wpa_auth, struct rsn_pmksa_cache_entry *entry); diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 50efc2c28..9d776db2d 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -348,6 +348,8 @@ static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr, if (sta && sta->auth_alg == WLAN_AUTH_SAE) { if (!sta->sae || prev_psk) return NULL; + if (psk_len) + *psk_len = sta->sae->pmk_len; return sta->sae->pmk; } if (sta && wpa_auth_uses_sae(sta->wpa_sm)) { diff --git a/src/common/sae.c b/src/common/sae.c index c0f154e91..48e4fb4af 100644 --- a/src/common/sae.c +++ b/src/common/sae.c @@ -1621,6 +1621,7 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k) os_memcpy(sae->tmp->kck, keys, hash_len); sae->tmp->kck_len = hash_len; os_memcpy(sae->pmk, keys + hash_len, SAE_PMK_LEN); + sae->pmk_len = SAE_PMK_LEN; os_memcpy(sae->pmkid, val, SAE_PMKID_LEN); #ifdef CONFIG_SAE_PK if (sae->pk) { @@ -1634,7 +1635,7 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k) forced_memzero(keys, sizeof(keys)); wpa_hexdump_key(MSG_DEBUG, "SAE: KCK", sae->tmp->kck, sae->tmp->kck_len); - wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, SAE_PMK_LEN); + wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, sae->pmk_len); ret = 0; fail: diff --git a/src/common/sae.h b/src/common/sae.h index 93fc5fb39..6eb2b6f4f 100644 --- a/src/common/sae.h +++ b/src/common/sae.h @@ -105,6 +105,8 @@ struct sae_data { enum sae_state state; u16 send_confirm; u8 pmk[SAE_PMK_LEN]; + size_t pmk_len; + int akmp; /* WPA_KEY_MGMT_* used in key derivation */ u8 pmkid[SAE_PMKID_LEN]; struct crypto_bignum *peer_commit_scalar; struct crypto_bignum *peer_commit_scalar_accepted; diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 4903cd364..f8de1628b 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -72,6 +72,7 @@ static int sme_set_sae_group(struct wpa_supplicant *wpa_s) if (sae_set_group(&wpa_s->sme.sae, group) == 0) { wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d", wpa_s->sme.sae.group); + wpa_s->sme.sae.akmp = wpa_s->key_mgmt; return 0; } wpa_s->sme.sae_group_index++; @@ -1462,7 +1463,7 @@ static int sme_sae_set_pmk(struct wpa_supplicant *wpa_s, const u8 *bssid) { wpa_printf(MSG_DEBUG, "SME: SAE completed - setting PMK for 4-way handshake"); - wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN, + wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, wpa_s->sme.sae.pmk_len, wpa_s->sme.sae.pmkid, bssid); if (wpa_s->conf->sae_pmkid_in_assoc) { /* Update the own RSNE contents now that we have set the PMK