SAE: Store PMK length and AKM in SAE data

These are needed to be able to support new AKM suites with variable
length PMK.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2022-07-24 22:15:52 +03:00 committed by Jouni Malinen
parent 9dc4e9d136
commit f8eed2e8b8
8 changed files with 27 additions and 14 deletions

View file

@ -1060,7 +1060,8 @@ void * hostapd_ctrl_iface_pmksa_create_entry(const u8 *aa, char *cmd)
if (sscanf(pos, "%d", &expiration) != 1) if (sscanf(pos, "%d", &expiration) != 1)
return NULL; 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 */ #endif /* CONFIG_MESH */

View file

@ -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_accepted = sta->sae->peer_commit_scalar;
sta->sae->peer_commit_scalar = NULL; sta->sae->peer_commit_scalar = NULL;
wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr, 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); 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. * restrict this only for PASN.
*/ */
wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr, 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; return 0;
} }

View file

@ -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, 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) if (wpa_auth->conf.disable_pmksa_caching)
return -1; return -1;
wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from SAE", pmk, PMK_LEN); 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, if (!akmp)
NULL, 0, akmp = WPA_KEY_MGMT_SAE;
wpa_auth->addr, addr, 0, NULL, if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, pmk_len, pmkid,
WPA_KEY_MGMT_SAE)) NULL, 0, wpa_auth->addr, addr, 0, NULL, akmp))
return 0; return 0;
return -1; 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 * struct rsn_pmksa_cache_entry *
wpa_auth_pmksa_create_entry(const u8 *aa, const u8 *spa, const u8 *pmk, 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) const u8 *pmkid, int expiration)
{ {
struct rsn_pmksa_cache_entry *entry; struct rsn_pmksa_cache_entry *entry;
struct os_reltime now; struct os_reltime now;
entry = pmksa_cache_auth_create_entry(pmk, PMK_LEN, pmkid, NULL, 0, aa, entry = pmksa_cache_auth_create_entry(pmk, pmk_len, pmkid, NULL, 0, aa,
spa, 0, NULL, WPA_KEY_MGMT_SAE); spa, 0, NULL, akmp);
if (!entry) if (!entry)
return NULL; return NULL;

View file

@ -425,7 +425,8 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
int session_timeout, int session_timeout,
struct eapol_state_machine *eapol); struct eapol_state_machine *eapol);
int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, 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); 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, int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr,
const u8 *pmk, size_t pmk_len, const u8 *pmkid, 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); char *buf, size_t len);
struct rsn_pmksa_cache_entry * struct rsn_pmksa_cache_entry *
wpa_auth_pmksa_create_entry(const u8 *aa, const u8 *spa, const u8 *pmk, 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); const u8 *pmkid, int expiration);
int wpa_auth_pmksa_add_entry(struct wpa_authenticator *wpa_auth, int wpa_auth_pmksa_add_entry(struct wpa_authenticator *wpa_auth,
struct rsn_pmksa_cache_entry *entry); struct rsn_pmksa_cache_entry *entry);

View file

@ -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 && sta->auth_alg == WLAN_AUTH_SAE) {
if (!sta->sae || prev_psk) if (!sta->sae || prev_psk)
return NULL; return NULL;
if (psk_len)
*psk_len = sta->sae->pmk_len;
return sta->sae->pmk; return sta->sae->pmk;
} }
if (sta && wpa_auth_uses_sae(sta->wpa_sm)) { if (sta && wpa_auth_uses_sae(sta->wpa_sm)) {

View file

@ -1621,6 +1621,7 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
os_memcpy(sae->tmp->kck, keys, hash_len); os_memcpy(sae->tmp->kck, keys, hash_len);
sae->tmp->kck_len = hash_len; sae->tmp->kck_len = hash_len;
os_memcpy(sae->pmk, keys + hash_len, SAE_PMK_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); os_memcpy(sae->pmkid, val, SAE_PMKID_LEN);
#ifdef CONFIG_SAE_PK #ifdef CONFIG_SAE_PK
if (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)); forced_memzero(keys, sizeof(keys));
wpa_hexdump_key(MSG_DEBUG, "SAE: KCK", wpa_hexdump_key(MSG_DEBUG, "SAE: KCK",
sae->tmp->kck, sae->tmp->kck_len); 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; ret = 0;
fail: fail:

View file

@ -105,6 +105,8 @@ struct sae_data {
enum sae_state state; enum sae_state state;
u16 send_confirm; u16 send_confirm;
u8 pmk[SAE_PMK_LEN]; u8 pmk[SAE_PMK_LEN];
size_t pmk_len;
int akmp; /* WPA_KEY_MGMT_* used in key derivation */
u8 pmkid[SAE_PMKID_LEN]; u8 pmkid[SAE_PMKID_LEN];
struct crypto_bignum *peer_commit_scalar; struct crypto_bignum *peer_commit_scalar;
struct crypto_bignum *peer_commit_scalar_accepted; struct crypto_bignum *peer_commit_scalar_accepted;

View file

@ -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) { if (sae_set_group(&wpa_s->sme.sae, group) == 0) {
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d", wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d",
wpa_s->sme.sae.group); wpa_s->sme.sae.group);
wpa_s->sme.sae.akmp = wpa_s->key_mgmt;
return 0; return 0;
} }
wpa_s->sme.sae_group_index++; 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, wpa_printf(MSG_DEBUG,
"SME: SAE completed - setting PMK for 4-way handshake"); "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); wpa_s->sme.sae.pmkid, bssid);
if (wpa_s->conf->sae_pmkid_in_assoc) { if (wpa_s->conf->sae_pmkid_in_assoc) {
/* Update the own RSNE contents now that we have set the PMK /* Update the own RSNE contents now that we have set the PMK