aboutsummaryrefslogtreecommitdiffstats
path: root/src/rsn_supp
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2008-08-31 19:57:28 (GMT)
committerJouni Malinen <j@w1.fi>2008-08-31 19:57:28 (GMT)
commit565861976dc4288e70eea26c9f47c6b24e25beea (patch)
treedbdbfdfd769b171d4658224191f7faa197673260 /src/rsn_supp
parent9b71728bba36effcff5c2f7fd915f5bde3753bcb (diff)
downloadhostap-06-565861976dc4288e70eea26c9f47c6b24e25beea.zip
hostap-06-565861976dc4288e70eea26c9f47c6b24e25beea.tar.gz
hostap-06-565861976dc4288e70eea26c9f47c6b24e25beea.tar.bz2
Added support for using SHA256-based stronger key derivation for WPA2
IEEE 802.11w/D6.0 defines new AKMPs to indicate SHA256-based algorithms for key derivation (and AES-CMAC for EAPOL-Key MIC). Add support for using new AKMPs and clean up AKMP processing with helper functions in defs.h.
Diffstat (limited to 'src/rsn_supp')
-rw-r--r--src/rsn_supp/peerkey.c43
-rw-r--r--src/rsn_supp/peerkey.h3
-rw-r--r--src/rsn_supp/pmksa_cache.c27
-rw-r--r--src/rsn_supp/pmksa_cache.h6
-rw-r--r--src/rsn_supp/preauth.c8
-rw-r--r--src/rsn_supp/wpa.c57
-rw-r--r--src/rsn_supp/wpa_ie.c8
7 files changed, 101 insertions, 51 deletions
diff --git a/src/rsn_supp/peerkey.c b/src/rsn_supp/peerkey.c
index 92ced5b..45c256a 100644
--- a/src/rsn_supp/peerkey.c
+++ b/src/rsn_supp/peerkey.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - PeerKey for Direct Link Setup (DLS)
- * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -18,6 +18,7 @@
#include "common.h"
#include "sha1.h"
+#include "sha256.h"
#include "eloop.h"
#include "wpa.h"
#include "wpa_i.h"
@@ -239,15 +240,19 @@ static int wpa_supplicant_process_smk_m2(
/* TODO: find existing entry and if found, use that instead of adding
* a new one; how to handle the case where both ends initiate at the
* same time? */
- peerkey = os_malloc(sizeof(*peerkey));
+ peerkey = os_zalloc(sizeof(*peerkey));
if (peerkey == NULL)
return -1;
- os_memset(peerkey, 0, sizeof(*peerkey));
os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN);
os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
peerkey->rsnie_i_len = kde.rsn_ie_len;
peerkey->cipher = cipher;
+#ifdef CONFIG_IEEE80211W
+ if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 |
+ WPA_KEY_MGMT_PSK_SHA256))
+ peerkey->use_sha256 = 1;
+#endif /* CONFIG_IEEE80211W */
if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) {
wpa_msg(sm->ctx->ctx, MSG_WARNING,
@@ -294,18 +299,20 @@ static int wpa_supplicant_process_smk_m2(
* @mac_p: Peer MAC address
* @inonce: Initiator Nonce
* @mac_i: Initiator MAC address
+ * @use_sha256: Whether to use SHA256-based KDF
*
* 8.5.1.4 Station to station (STK) key hierarchy
* SMKID = HMAC-SHA1-128(SMK, "SMK Name" || PNonce || MAC_P || INonce || MAC_I)
*/
static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p,
- const u8 *inonce, const u8 *mac_i, u8 *smkid)
+ const u8 *inonce, const u8 *mac_i, u8 *smkid,
+ int use_sha256)
{
char *title = "SMK Name";
const u8 *addr[5];
const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN,
ETH_ALEN };
- unsigned char hash[SHA1_MAC_LEN];
+ unsigned char hash[SHA256_MAC_LEN];
addr[0] = (u8 *) title;
addr[1] = pnonce;
@@ -313,7 +320,12 @@ static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p,
addr[3] = inonce;
addr[4] = mac_i;
- hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash);
+#ifdef CONFIG_IEEE80211W
+ if (use_sha256)
+ hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash);
+ else
+#endif /* CONFIG_IEEE80211W */
+ hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash);
os_memcpy(smkid, hash, PMKID_LEN);
}
@@ -578,11 +590,13 @@ static int wpa_supplicant_process_smk_m45(
if (peerkey->initiator) {
rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr,
- peerkey->inonce, sm->own_addr, peerkey->smkid);
+ peerkey->inonce, sm->own_addr, peerkey->smkid,
+ peerkey->use_sha256);
wpa_supplicant_send_stk_1_of_4(sm, peerkey);
} else {
rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr,
- peerkey->inonce, peerkey->addr, peerkey->smkid);
+ peerkey->inonce, peerkey->addr, peerkey->smkid,
+ peerkey->use_sha256);
}
wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN);
@@ -695,7 +709,8 @@ static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,
wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
sm->own_addr, peerkey->addr,
peerkey->pnonce, key->key_nonce,
- (u8 *) stk, sizeof(*stk));
+ (u8 *) stk, sizeof(*stk),
+ peerkey->use_sha256);
/* Supplicant: swap tx/rx Mic keys */
os_memcpy(buf, stk->u.auth.tx_mic_key, 8);
os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8);
@@ -927,7 +942,8 @@ int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
sm->own_addr, peerkey->addr,
peerkey->inonce, key->key_nonce,
- (u8 *) &peerkey->stk, sizeof(peerkey->stk));
+ (u8 *) &peerkey->stk, sizeof(peerkey->stk),
+ peerkey->use_sha256);
peerkey->stk_set = 1;
}
@@ -1016,12 +1032,15 @@ int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
/* TODO: find existing entry and if found, use that instead of adding
* a new one */
- peerkey = os_malloc(sizeof(*peerkey));
+ peerkey = os_zalloc(sizeof(*peerkey));
if (peerkey == NULL)
return -1;
- os_memset(peerkey, 0, sizeof(*peerkey));
peerkey->initiator = 1;
os_memcpy(peerkey->addr, peer, ETH_ALEN);
+#ifdef CONFIG_IEEE80211W
+ if (wpa_key_mgmt_sha256(sm->key_mgmt))
+ peerkey->use_sha256 = 1;
+#endif /* CONFIG_IEEE80211W */
/* SMK M1:
* EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
diff --git a/src/rsn_supp/peerkey.h b/src/rsn_supp/peerkey.h
index f69c68f..2613127 100644
--- a/src/rsn_supp/peerkey.h
+++ b/src/rsn_supp/peerkey.h
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - PeerKey for Direct Link Setup (DLS)
- * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,6 +34,7 @@ struct wpa_peerkey {
int cipher; /* Selected cipher (WPA_CIPHER_*) */
u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
int replay_counter_set;
+ int use_sha256; /* whether AKMP indicate SHA256-based derivations */
struct wpa_ptk stk, tstk;
int stk_set, tstk_set;
diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c
index 2a5bb5a..f8373de 100644
--- a/src/rsn_supp/pmksa_cache.c
+++ b/src/rsn_supp/pmksa_cache.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - RSN PMKSA cache
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -18,6 +18,7 @@
#include "wpa.h"
#include "eloop.h"
#include "sha1.h"
+#include "sha256.h"
#include "wpa_i.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "pmksa_cache.h"
@@ -43,23 +44,29 @@ struct rsn_pmksa_cache {
* @pmk_len: Length of pmk in bytes
* @aa: Authenticator address
* @spa: Supplicant address
+ * @use_sha256: Whether to use SHA256-based KDF
*
* IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
* PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
*/
-void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
- u8 *pmkid)
+static void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa,
+ const u8 *spa, u8 *pmkid, int use_sha256)
{
char *title = "PMK Name";
const u8 *addr[3];
const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
- unsigned char hash[SHA1_MAC_LEN];
+ unsigned char hash[SHA256_MAC_LEN];
addr[0] = (u8 *) title;
addr[1] = aa;
addr[2] = spa;
- hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
+#ifdef CONFIG_IEEE80211W
+ if (use_sha256)
+ hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
+ else
+#endif /* CONFIG_IEEE80211W */
+ hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
os_memcpy(pmkid, hash, PMKID_LEN);
}
@@ -145,6 +152,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
* @aa: Authenticator address
* @spa: Supplicant address
* @network_ctx: Network configuration context for this PMK
+ * @akmp: WPA_KEY_MGMT_* used in key derivation
* Returns: Pointer to the added PMKSA cache entry or %NULL on error
*
* This function create a PMKSA entry for a new PMK and adds it to the PMKSA
@@ -154,7 +162,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 *aa, const u8 *spa, void *network_ctx)
+ const u8 *aa, const u8 *spa, void *network_ctx, int akmp)
{
struct rsn_pmksa_cache_entry *entry, *pos, *prev;
struct os_time now;
@@ -167,12 +175,13 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
return NULL;
os_memcpy(entry->pmk, pmk, pmk_len);
entry->pmk_len = pmk_len;
- rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid);
+ rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
+ wpa_key_mgmt_sha256(akmp));
os_get_time(&now);
entry->expiration = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime;
entry->reauth_time = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime *
pmksa->sm->dot11RSNAConfigPMKReauthThreshold / 100;
- entry->akmp = WPA_KEY_MGMT_IEEE8021X;
+ entry->akmp = akmp;
os_memcpy(entry->aa, aa, ETH_ALEN);
entry->network_ctx = network_ctx;
@@ -324,7 +333,7 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa,
new_entry = pmksa_cache_add(pmksa, old_entry->pmk, old_entry->pmk_len,
aa, pmksa->sm->own_addr,
- old_entry->network_ctx);
+ old_entry->network_ctx, old_entry->akmp);
if (new_entry == NULL)
return NULL;
diff --git a/src/rsn_supp/pmksa_cache.h b/src/rsn_supp/pmksa_cache.h
index bf3b4d2..a329b25 100644
--- a/src/rsn_supp/pmksa_cache.h
+++ b/src/rsn_supp/pmksa_cache.h
@@ -1,6 +1,6 @@
/*
* wpa_supplicant - WPA2/RSN PMKSA cache functions
- * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -56,7 +56,7 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
int pmksa_cache_list(struct wpa_sm *sm, 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 *aa, const u8 *spa, void *network_ctx);
+ const u8 *aa, const u8 *spa, void *network_ctx, int akmp);
void pmksa_cache_notify_reconfig(struct rsn_pmksa_cache *pmksa);
struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm);
void pmksa_cache_clear_current(struct wpa_sm *sm);
@@ -100,7 +100,7 @@ static inline int pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
static inline struct rsn_pmksa_cache_entry *
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
- const u8 *aa, const u8 *spa, void *network_ctx)
+ 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 7bc3c04..b00c004 100644
--- a/src/rsn_supp/preauth.c
+++ b/src/rsn_supp/preauth.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - RSN pre-authentication
- * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -104,7 +104,8 @@ static void rsn_preauth_eapol_cb(struct eapol_sm *eapol, int success,
sm->pmk_len = pmk_len;
pmksa_cache_add(sm->pmksa, pmk, pmk_len,
sm->preauth_bssid, sm->own_addr,
- sm->network_ctx);
+ sm->network_ctx,
+ WPA_KEY_MGMT_IEEE8021X);
} else {
wpa_msg(sm->ctx->ctx, MSG_INFO, "RSN: failed to get "
"master session key from pre-auth EAPOL state "
@@ -304,7 +305,8 @@ void rsn_preauth_candidate_process(struct wpa_sm *sm)
if (sm->preauth_eapol ||
sm->proto != WPA_PROTO_RSN ||
wpa_sm_get_state(sm) != WPA_COMPLETED ||
- sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X) {
+ (sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
+ sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SHA256)) {
wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: not in suitable state "
"for new pre-authentication");
return; /* invalid state for new pre-auth */
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 89ca473..5ec1dab 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -77,6 +77,12 @@ static const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
case WPA_KEY_MGMT_FT_PSK:
return "FT-PSK";
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ case WPA_KEY_MGMT_IEEE8021X_SHA256:
+ return "WPA2-EAP-SHA256";
+ case WPA_KEY_MGMT_PSK_SHA256:
+ return "WPA2-PSK-SHA256";
+#endif /* CONFIG_IEEE80211W */
default:
return "UNKNOWN";
}
@@ -140,8 +146,7 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
int key_info, ver;
u8 bssid[ETH_ALEN], *rbuf;
- if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_PSK)
+ if (wpa_key_mgmt_ft(sm->key_mgmt) || wpa_key_mgmt_sha256(sm->key_mgmt))
ver = WPA_KEY_INFO_TYPE_AES_128_CMAC;
else if (sm->pairwise_cipher == WPA_CIPHER_CCMP)
ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
@@ -216,8 +221,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
#ifdef CONFIG_IEEE80211R
sm->xxkey_len = 0;
#endif /* CONFIG_IEEE80211R */
- } else if ((sm->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) && sm->eapol) {
+ } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
int res, pmk_len;
pmk_len = PMK_LEN;
res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN);
@@ -244,7 +248,8 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
"machines", sm->pmk, pmk_len);
sm->pmk_len = pmk_len;
pmksa_cache_add(sm->pmksa, sm->pmk, pmk_len, src_addr,
- sm->own_addr, sm->network_ctx);
+ sm->own_addr, sm->network_ctx,
+ sm->key_mgmt);
if (!sm->cur_pmksa && pmkid &&
pmksa_cache_get(sm->pmksa, src_addr, pmkid)) {
wpa_printf(MSG_DEBUG, "RSN: the new PMK "
@@ -268,8 +273,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
}
}
- if (abort_cached && (sm->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X)) {
+ if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) {
/* Send EAPOL-Start to trigger full EAP authentication. */
u8 *buf;
size_t buflen;
@@ -356,14 +360,14 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
struct wpa_ptk *ptk)
{
#ifdef CONFIG_IEEE80211R
- if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_PSK)
+ if (wpa_key_mgmt_ft(sm->key_mgmt))
return wpa_derive_ptk_ft(sm, src_addr, key, ptk);
#endif /* CONFIG_IEEE80211R */
wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
sm->own_addr, sm->bssid, sm->snonce, key->key_nonce,
- (u8 *) ptk, sizeof(*ptk));
+ (u8 *) ptk, sizeof(*ptk),
+ wpa_key_mgmt_sha256(sm->key_mgmt));
return 0;
}
@@ -458,8 +462,7 @@ 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 (sm->key_mgmt == WPA_KEY_MGMT_PSK ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_PSK)
+ if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
eapol_sm_notify_eap_success(sm->eapol, TRUE);
/*
* Start preauthentication after a short wait to avoid a
@@ -478,8 +481,7 @@ static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
}
#ifdef CONFIG_IEEE80211R
- if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_PSK) {
+ if (wpa_key_mgmt_ft(sm->key_mgmt)) {
/* Prepare for the next transition */
wpa_ft_prepare_auth_request(sm);
}
@@ -834,8 +836,7 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
}
#ifdef CONFIG_IEEE80211R
- if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_PSK) {
+ if (wpa_key_mgmt_ft(sm->key_mgmt)) {
struct rsn_mdie *mdie;
/* TODO: verify that full MDIE matches with the one from scan
* results, not only mobility domain */
@@ -1463,8 +1464,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
}
#ifdef CONFIG_IEEE80211R
- if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_PSK) {
+ if (wpa_key_mgmt_ft(sm->key_mgmt)) {
/* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
wpa_printf(MSG_INFO, "FT: AP did not use "
@@ -1473,6 +1473,15 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
}
} else
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
+ if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
+ wpa_printf(MSG_INFO, "WPA: AP did not use the "
+ "negotiated AES-128-CMAC.");
+ goto out;
+ }
+ } else
+#endif /* CONFIG_IEEE80211W */
if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
wpa_printf(MSG_INFO, "WPA: CCMP is used, but EAPOL-Key "
@@ -1651,6 +1660,12 @@ static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
case WPA_KEY_MGMT_FT_PSK:
return RSN_AUTH_KEY_MGMT_FT_PSK;
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ case WPA_KEY_MGMT_IEEE8021X_SHA256:
+ return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
+ case WPA_KEY_MGMT_PSK_SHA256:
+ return RSN_AUTH_KEY_MGMT_PSK_SHA256;
+#endif /* CONFIG_IEEE80211W */
case WPA_KEY_MGMT_WPA_NONE:
return WPA_AUTH_KEY_MGMT_NONE;
default:
@@ -1708,10 +1723,8 @@ int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
} else
pmkid_txt[0] = '\0';
- if ((sm->key_mgmt == WPA_KEY_MGMT_PSK ||
- sm->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_PSK ||
- sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) &&
+ if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
+ wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&
sm->proto == WPA_PROTO_RSN)
rsna = 1;
else
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index 94a542d..84f2811 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -1,6 +1,6 @@
/*
* wpa_supplicant - WPA/RSN IE and KDE processing
- * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -316,6 +316,12 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
} else if (key_mgmt == WPA_KEY_MGMT_FT_PSK) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ } else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SHA256) {
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
+ } else if (key_mgmt == WPA_KEY_MGMT_PSK_SHA256) {
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
+#endif /* CONFIG_IEEE80211W */
} else {
wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
key_mgmt);