/*
* WPA Supplicant - PeerKey for Direct Link Setup (DLS)
- * Copyright (c) 2006-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2015, 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
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#include "includes.h"
#include "eloop.h"
#include "crypto/sha1.h"
#include "crypto/sha256.h"
+#include "crypto/random.h"
#include "common/ieee802_11_defs.h"
#include "wpa.h"
#include "wpa_i.h"
{
size_t rlen;
struct wpa_eapol_key *err;
+ struct wpa_eapol_key_192 *err192;
struct rsn_error_kde error;
u8 *rbuf, *pos;
size_t kde_len;
(void *) &err);
if (rbuf == NULL)
return -1;
+ err192 = (struct wpa_eapol_key_192 *) err;
err->type = EAPOL_KEY_TYPE_RSN;
key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
"(mui %d error_type %d)", mui, error_type);
}
- wpa_eapol_key_send(sm, sm->ptk.kck, ver, dst, ETH_P_EAPOL,
- rbuf, rlen, err->key_mic);
+ wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, dst,
+ ETH_P_EAPOL, rbuf, rlen, err192->key_mic);
return 0;
}
{
size_t rlen;
struct wpa_eapol_key *reply;
+ struct wpa_eapol_key_192 *reply192;
u8 *rbuf, *pos;
size_t kde_len;
u16 key_info;
(void *) &reply);
if (rbuf == NULL)
return -1;
+ reply192 = (struct wpa_eapol_key_192 *) reply;
reply->type = EAPOL_KEY_TYPE_RSN;
key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
wpa_add_kde(pos, RSN_KEY_DATA_NONCE, peerkey->inonce, WPA_NONCE_LEN);
wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3");
- wpa_eapol_key_send(sm, sm->ptk.kck, ver, src_addr, ETH_P_EAPOL,
- rbuf, rlen, reply->key_mic);
+ wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, src_addr,
+ ETH_P_EAPOL, rbuf, rlen, reply192->key_mic);
return 0;
}
return -1;
}
- cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
- if (cipher & WPA_CIPHER_CCMP) {
- wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
- cipher = WPA_CIPHER_CCMP;
- } else if (cipher & WPA_CIPHER_TKIP) {
- wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
- cipher = WPA_CIPHER_TKIP;
- } else {
+ cipher = wpa_pick_pairwise_cipher(ie.pairwise_cipher &
+ sm->allowed_pairwise_cipher, 0);
+ if (cipher < 0) {
wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2");
wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr,
STK_MUI_SMK, STK_ERR_CPHR_NS,
ver);
return -1;
}
+ wpa_printf(MSG_DEBUG, "RSN: Using %s for PeerKey",
+ wpa_cipher_txt(cipher));
/* 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
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 */
+ peerkey->akmp = ie.key_mgmt;
- if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) {
+ if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Failed to get random data for PNonce");
wpa_supplicant_peerkey_free(sm, peerkey);
/* Include only the selected cipher in pairwise cipher suite */
WPA_PUT_LE16(pos, 1);
pos += 2;
- if (cipher == WPA_CIPHER_CCMP)
- RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
- else if (cipher == WPA_CIPHER_TKIP)
- RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
+ RSN_SELECTOR_PUT(pos, wpa_cipher_to_suite(WPA_PROTO_RSN, cipher));
pos += RSN_SELECTOR_LEN;
hdr->len = (pos - peerkey->rsnie_p) - 2;
* @mac_p: Peer MAC address
* @inonce: Initiator Nonce
* @mac_i: Initiator MAC address
- * @use_sha256: Whether to use SHA256-based KDF
+ * @akmp: Negotiated AKM
*
* 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,
- int use_sha256)
+ int akmp)
{
char *title = "SMK Name";
const u8 *addr[5];
addr[4] = mac_i;
#ifdef CONFIG_IEEE80211W
- if (use_sha256)
+ if (wpa_key_mgmt_sha256(akmp))
hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash);
else
#endif /* CONFIG_IEEE80211W */
msg->type = EAPOL_KEY_TYPE_RSN;
- if (peerkey->cipher == WPA_CIPHER_CCMP)
+ if (peerkey->cipher != WPA_CIPHER_TKIP)
ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
else
ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK;
WPA_PUT_BE16(msg->key_info, key_info);
- if (peerkey->cipher == WPA_CIPHER_CCMP)
+ if (peerkey->cipher != WPA_CIPHER_TKIP)
WPA_PUT_BE16(msg->key_length, 16);
else
WPA_PUT_BE16(msg->key_length, 32);
wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID,
peerkey->smkid, PMKID_LEN);
- if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) {
+ if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"RSN: Failed to get random data for INonce (STK)");
os_free(mbuf);
wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR,
MAC2STR(peerkey->addr));
- wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL,
+ wpa_eapol_key_send(sm, NULL, 0, ver, peerkey->addr, ETH_P_EAPOL,
mbuf, mlen, NULL);
}
msg->type = EAPOL_KEY_TYPE_RSN;
- if (peerkey->cipher == WPA_CIPHER_CCMP)
+ if (peerkey->cipher != WPA_CIPHER_TKIP)
ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
else
ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
WPA_PUT_BE16(msg->key_info, key_info);
- if (peerkey->cipher == WPA_CIPHER_CCMP)
+ if (peerkey->cipher != WPA_CIPHER_TKIP)
WPA_PUT_BE16(msg->key_length, 16);
else
WPA_PUT_BE16(msg->key_length, 32);
wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR,
MAC2STR(peerkey->addr));
- wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr,
- ETH_P_EAPOL, mbuf, mlen, msg->key_mic);
+ wpa_eapol_key_send(sm, peerkey->stk.kck, peerkey->stk.kck_len, ver,
+ peerkey->addr, ETH_P_EAPOL, mbuf, mlen,
+ msg->key_mic);
}
peerkey->rsnie_p_len = kde->rsn_ie_len;
os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN);
- cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
- if (cipher & WPA_CIPHER_CCMP) {
- wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
- peerkey->cipher = WPA_CIPHER_CCMP;
- } else if (cipher & WPA_CIPHER_TKIP) {
- wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
- peerkey->cipher = WPA_CIPHER_TKIP;
- } else {
+ cipher = wpa_pick_pairwise_cipher(ie.pairwise_cipher &
+ sm->allowed_pairwise_cipher, 0);
+ if (cipher < 0) {
wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected "
"unacceptable cipher", MAC2STR(kde->mac_addr));
wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr,
/* TODO: abort negotiation */
return -1;
}
+ wpa_printf(MSG_DEBUG, "RSN: Using %s for PeerKey",
+ wpa_cipher_txt(cipher));
+ peerkey->cipher = cipher;
return 0;
}
struct wpa_peerkey *peerkey;
struct wpa_eapol_ie_parse kde;
u32 lifetime;
- struct os_time now;
if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
lifetime = WPA_GET_BE32(kde.lifetime);
wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime);
if (lifetime > 1000000000)
- lifetime = 1000000000; /* avoid overflowing expiration time */
+ lifetime = 1000000000; /* avoid overflowing eloop time */
peerkey->lifetime = lifetime;
- os_get_time(&now);
- peerkey->expiration = now.sec + lifetime;
eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
sm, peerkey);
if (peerkey->initiator) {
rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr,
peerkey->inonce, sm->own_addr, peerkey->smkid,
- peerkey->use_sha256);
+ peerkey->akmp);
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->use_sha256);
+ peerkey->akmp);
}
wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN);
static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,
struct wpa_peerkey *peerkey,
const struct wpa_eapol_key *key,
- u16 ver)
+ u16 ver, const u8 *key_data,
+ size_t key_data_len)
{
struct wpa_eapol_ie_parse ie;
- const u8 *kde;
- size_t len, kde_buf_len;
+ size_t kde_buf_len;
struct wpa_ptk *stk;
u8 buf[8], *kde_buf, *pos;
be32 lifetime;
os_memset(&ie, 0, sizeof(ie));
/* RSN: msg 1/4 should contain SMKID for the selected SMK */
- kde = (const u8 *) (key + 1);
- len = WPA_GET_BE16(key->key_data_length);
- wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len);
- if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) {
+ wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", key_data, key_data_len);
+ if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0 ||
+ ie.pmkid == NULL) {
wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4");
return;
}
- if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
+ if (os_memcmp_const(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4",
ie.pmkid, PMKID_LEN);
return;
}
- if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) {
+ if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"RSN: Failed to get random data for PNonce");
return;
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),
- peerkey->use_sha256);
+ stk, peerkey->akmp, peerkey->cipher);
/* 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);
- os_memcpy(stk->u.auth.rx_mic_key, buf, 8);
+ os_memcpy(buf, &stk->tk[16], 8);
+ os_memcpy(&stk->tk[16], &stk->tk[24], 8);
+ os_memcpy(&stk->tk[24], buf, 8);
peerkey->tstk_set = 1;
kde_buf_len = peerkey->rsnie_p_len +
struct wpa_eapol_ie_parse *kde)
{
u32 lifetime;
- struct os_time now;
if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime))
return;
lifetime, peerkey->lifetime);
peerkey->lifetime = lifetime;
- os_get_time(&now);
- peerkey->expiration = now.sec + lifetime;
eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
sm, peerkey);
static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,
struct wpa_peerkey *peerkey,
const struct wpa_eapol_key *key,
- u16 ver)
+ u16 ver, const u8 *key_data,
+ size_t key_data_len)
{
struct wpa_eapol_ie_parse kde;
- const u8 *keydata;
- size_t len;
wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from "
MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
/* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE
* from the peer. It may also include Lifetime KDE. */
- keydata = (const u8 *) (key + 1);
- len = WPA_GET_BE16(key->key_data_length);
- wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len);
- if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 ||
+ wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", key_data, key_data_len);
+ if (wpa_supplicant_parse_ies(key_data, key_data_len, &kde) < 0 ||
kde.pmkid == NULL || kde.rsn_ie == NULL) {
wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4");
return;
}
- if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
+ if (os_memcmp_const(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4",
kde.pmkid, PMKID_LEN);
return;
static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm,
struct wpa_peerkey *peerkey,
const struct wpa_eapol_key *key,
- u16 ver)
+ u16 ver, const u8 *key_data,
+ size_t key_data_len)
{
struct wpa_eapol_ie_parse kde;
- const u8 *keydata;
- size_t len, key_len;
+ size_t key_len;
const u8 *_key;
u8 key_buf[32], rsc[6];
/* RSN: msg 3/4 should contain Initiator RSN IE. It may also include
* Lifetime KDE. */
- keydata = (const u8 *) (key + 1);
- len = WPA_GET_BE16(key->key_data_length);
- wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len);
- if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) {
+ wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", key_data, key_data_len);
+ if (wpa_supplicant_parse_ies(key_data, key_data_len, &kde) < 0) {
wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in "
"STK 3/4");
return;
if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver,
WPA_GET_BE16(key->key_info),
- NULL, 0, &peerkey->stk))
+ &peerkey->stk))
return;
- _key = (u8 *) peerkey->stk.tk1;
+ _key = peerkey->stk.tk;
if (peerkey->cipher == WPA_CIPHER_TKIP) {
/* Swap Tx/Rx keys for Michael MIC */
os_memcpy(key_buf, _key, 16);
- os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8);
- os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8);
+ os_memcpy(key_buf + 16, _key + 24, 8);
+ os_memcpy(key_buf + 24, _key + 16, 8);
_key = key_buf;
key_len = 32;
} else
os_memset(rsc, 0, 6);
if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
rsc, sizeof(rsc), _key, key_len) < 0) {
+ os_memset(key_buf, 0, sizeof(key_buf));
wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
"driver.");
return;
}
+ os_memset(key_buf, 0, sizeof(key_buf));
}
os_memset(rsc, 0, 6);
if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
- rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1,
+ rsc, sizeof(rsc), peerkey->stk.tk,
peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) {
wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
"driver.");
*/
int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
struct wpa_peerkey *peerkey,
- struct wpa_eapol_key *key, u16 ver,
+ struct wpa_eapol_key_192 *key, u16 ver,
const u8 *buf, size_t len)
{
- u8 mic[16];
+ u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
+ size_t mic_len = 16;
int ok = 0;
if (peerkey->initiator && !peerkey->stk_set) {
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),
- peerkey->use_sha256);
+ &peerkey->stk, peerkey->akmp, peerkey->cipher);
peerkey->stk_set = 1;
}
- os_memcpy(mic, key->key_mic, 16);
+ os_memcpy(mic, key->key_mic, mic_len);
if (peerkey->tstk_set) {
- os_memset(key->key_mic, 0, 16);
- wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
- key->key_mic);
- if (os_memcmp(mic, key->key_mic, 16) != 0) {
+ os_memset(key->key_mic, 0, mic_len);
+ wpa_eapol_key_mic(peerkey->tstk.kck, peerkey->tstk.kck_len,
+ sm->key_mgmt, ver, buf, len, key->key_mic);
+ if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) {
wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
"when using TSTK - ignoring TSTK");
} else {
peerkey->stk_set = 1;
os_memcpy(&peerkey->stk, &peerkey->tstk,
sizeof(peerkey->stk));
+ os_memset(&peerkey->tstk, 0, sizeof(peerkey->tstk));
}
}
if (!ok && peerkey->stk_set) {
- os_memset(key->key_mic, 0, 16);
- wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
- key->key_mic);
- if (os_memcmp(mic, key->key_mic, 16) != 0) {
+ os_memset(key->key_mic, 0, mic_len);
+ wpa_eapol_key_mic(peerkey->stk.kck, peerkey->stk.kck_len,
+ sm->key_mgmt, ver, buf, len, key->key_mic);
+ if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) {
wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
"- dropping packet");
return -1;
return -1;
}
- if (sm->pairwise_cipher == WPA_CIPHER_CCMP)
+ if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
else
ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
return -1;
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 */
+ peerkey->akmp = sm->key_mgmt;
/* SMK M1:
* EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
count_pos = pos;
pos += 2;
- count = 0;
- if (sm->allowed_pairwise_cipher & WPA_CIPHER_CCMP) {
- RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
- pos += RSN_SELECTOR_LEN;
- count++;
- }
- if (sm->allowed_pairwise_cipher & WPA_CIPHER_TKIP) {
- RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
- pos += RSN_SELECTOR_LEN;
- count++;
- }
+ count = rsn_cipher_put_suites(pos, sm->allowed_pairwise_cipher);
+ pos += count * RSN_SELECTOR_LEN;
WPA_PUT_LE16(count_pos, count);
hdr->len = (pos - peerkey->rsnie_i) - 2;
WPA_REPLAY_COUNTER_LEN);
inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
- if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) {
+ if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Failed to get random data for INonce");
os_free(rbuf);
wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer "
MACSTR ")", MAC2STR(peer));
- wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
- rbuf, rlen, req->key_mic);
+ wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, bssid,
+ ETH_P_EAPOL, rbuf, rlen, req->key_mic);
peerkey->next = sm->peerkey;
sm->peerkey = peerkey;
while (peerkey) {
prev = peerkey;
peerkey = peerkey->next;
- os_free(prev);
+ wpa_supplicant_peerkey_free(sm, prev);
}
+ sm->peerkey = NULL;
}
void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
- struct wpa_eapol_key *key, u16 key_info, u16 ver)
+ struct wpa_eapol_key *key, u16 key_info, u16 ver,
+ const u8 *key_data, size_t key_data_len)
{
if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) ==
(WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) {
/* 3/4 STK 4-Way Handshake */
- wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver);
+ wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver,
+ key_data, key_data_len);
} else if (key_info & WPA_KEY_INFO_ACK) {
/* 1/4 STK 4-Way Handshake */
- wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver);
+ wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver,
+ key_data, key_data_len);
} else if (key_info & WPA_KEY_INFO_SECURE) {
/* 4/4 STK 4-Way Handshake */
wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
} else {
/* 2/4 STK 4-Way Handshake */
- wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver);
+ wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver,
+ key_data, key_data_len);
}
}