aboutsummaryrefslogtreecommitdiffstats
path: root/src/rsn_supp
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2014-11-16 11:22:46 (GMT)
committerJouni Malinen <j@w1.fi>2014-11-16 15:09:11 (GMT)
commit087a1f4efde58ddab493a46437d13e9a4985f62d (patch)
treec317aa42cf03d9b9fb89c2ddf7f2f6d9c58efbee /src/rsn_supp
parent666497c8e65c3e6981d0c142a442dd7202c5d0b4 (diff)
downloadhostap-087a1f4efde58ddab493a46437d13e9a4985f62d.zip
hostap-087a1f4efde58ddab493a46437d13e9a4985f62d.tar.gz
hostap-087a1f4efde58ddab493a46437d13e9a4985f62d.tar.bz2
Suite B: PMKID derivation for AKM 00-0F-AC:11
The new AKM uses a different mechanism of deriving the PMKID based on KCK instead of PMK. hostapd was already doing this after the KCK had been derived, but wpa_supplicant functionality needs to be moved from processing of EAPOL-Key frame 1/4 to 3/4 to have the KCK available. Signed-off-by: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'src/rsn_supp')
-rw-r--r--src/rsn_supp/pmksa_cache.c14
-rw-r--r--src/rsn_supp/pmksa_cache.h2
-rw-r--r--src/rsn_supp/preauth.c1
-rw-r--r--src/rsn_supp/wpa.c17
4 files changed, 31 insertions, 3 deletions
diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c
index 885291a..5f29627 100644
--- a/src/rsn_supp/pmksa_cache.c
+++ b/src/rsn_supp/pmksa_cache.c
@@ -109,6 +109,8 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
* @pmk: The new pairwise master key
* @pmk_len: PMK length in bytes, usually PMK_LEN (32)
+ * @kck: Key confirmation key or %NULL if not yet derived
+ * @kck_len: KCK length in bytes
* @aa: Authenticator address
* @spa: Supplicant address
* @network_ctx: Network configuration context for this PMK
@@ -122,6 +124,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
*/
struct rsn_pmksa_cache_entry *
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
+ const u8 *kck, size_t kck_len,
const u8 *aa, const u8 *spa, void *network_ctx, int akmp)
{
struct rsn_pmksa_cache_entry *entry, *pos, *prev;
@@ -130,13 +133,19 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
if (pmk_len > PMK_LEN)
return NULL;
+ if (wpa_key_mgmt_suite_b(akmp) && !kck)
+ return NULL;
+
entry = os_zalloc(sizeof(*entry));
if (entry == NULL)
return NULL;
os_memcpy(entry->pmk, pmk, pmk_len);
entry->pmk_len = pmk_len;
- rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
- wpa_key_mgmt_sha256(akmp));
+ if (wpa_key_mgmt_suite_b(akmp))
+ rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
+ else
+ rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
+ wpa_key_mgmt_sha256(akmp));
os_get_reltime(&now);
entry->expiration = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime;
entry->reauth_time = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime *
@@ -333,6 +342,7 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa,
struct rsn_pmksa_cache_entry *new_entry;
new_entry = pmksa_cache_add(pmksa, old_entry->pmk, old_entry->pmk_len,
+ NULL, 0,
aa, pmksa->sm->own_addr,
old_entry->network_ctx, old_entry->akmp);
if (new_entry == NULL)
diff --git a/src/rsn_supp/pmksa_cache.h b/src/rsn_supp/pmksa_cache.h
index 6cbf89a..f8e040e 100644
--- a/src/rsn_supp/pmksa_cache.h
+++ b/src/rsn_supp/pmksa_cache.h
@@ -57,6 +57,7 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len);
struct rsn_pmksa_cache_entry *
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
+ const u8 *kck, size_t kck_len,
const u8 *aa, const u8 *spa, void *network_ctx, int akmp);
struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm);
void pmksa_cache_clear_current(struct wpa_sm *sm);
@@ -104,6 +105,7 @@ static inline int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf,
static inline struct rsn_pmksa_cache_entry *
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
+ const u8 *kck, size_t kck_len,
const u8 *aa, const u8 *spa, void *network_ctx, int akmp)
{
return NULL;
diff --git a/src/rsn_supp/preauth.c b/src/rsn_supp/preauth.c
index e392125..13a6cad 100644
--- a/src/rsn_supp/preauth.c
+++ b/src/rsn_supp/preauth.c
@@ -94,6 +94,7 @@ static void rsn_preauth_eapol_cb(struct eapol_sm *eapol,
pmk, pmk_len);
sm->pmk_len = pmk_len;
pmksa_cache_add(sm->pmksa, pmk, pmk_len,
+ NULL, 0,
sm->preauth_bssid, sm->own_addr,
sm->network_ctx,
WPA_KEY_MGMT_IEEE8021X);
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 47e3607..9c840c6 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -218,9 +218,11 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
sm->pmk_len = pmk_len;
wpa_supplicant_key_mgmt_set_pmk(sm);
if (sm->proto == WPA_PROTO_RSN &&
+ !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
!wpa_key_mgmt_ft(sm->key_mgmt)) {
sa = pmksa_cache_add(sm->pmksa,
sm->pmk, pmk_len,
+ NULL, 0,
src_addr, sm->own_addr,
sm->network_ctx,
sm->key_mgmt);
@@ -254,6 +256,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
}
if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) &&
+ !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
!wpa_key_mgmt_ft(sm->key_mgmt) && sm->key_mgmt != WPA_KEY_MGMT_OSEN)
{
/* Send EAPOL-Start to trigger full EAP authentication. */
@@ -1197,6 +1200,17 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
if (ie.gtk)
wpa_sm_set_rekey_offload(sm);
+ if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt)) {
+ struct rsn_pmksa_cache_entry *sa;
+
+ sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len,
+ sm->ptk.kck, sizeof(sm->ptk.kck),
+ sm->bssid, sm->own_addr,
+ sm->network_ctx, sm->key_mgmt);
+ if (!sm->cur_pmksa)
+ sm->cur_pmksa = sa;
+ }
+
return;
failed:
@@ -2225,7 +2239,8 @@ void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
#endif /* CONFIG_IEEE80211R */
if (bssid) {
- pmksa_cache_add(sm->pmksa, pmk, pmk_len, bssid, sm->own_addr,
+ pmksa_cache_add(sm->pmksa, pmk, pmk_len, NULL, 0,
+ bssid, sm->own_addr,
sm->network_ctx, sm->key_mgmt);
}
}