peerkey.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
1/*
2 * WPA Supplicant - PeerKey for Direct Link Setup (DLS)
3 * Copyright (c) 2006-2008, Jouni Malinen <j@w1.fi>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "includes.h"
16
17#ifdef CONFIG_PEERKEY
18
19#include "common.h"
20#include "eloop.h"
21#include "crypto/sha1.h"
22#include "crypto/sha256.h"
23#include "crypto/random.h"
24#include "common/ieee802_11_defs.h"
25#include "wpa.h"
26#include "wpa_i.h"
27#include "wpa_ie.h"
28#include "peerkey.h"
29
30
31static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
32{
33	os_memcpy(pos, ie, ie_len);
34	return pos + ie_len;
35}
36
37
38static u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len)
39{
40	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
41	*pos++ = RSN_SELECTOR_LEN + data_len;
42	RSN_SELECTOR_PUT(pos, kde);
43	pos += RSN_SELECTOR_LEN;
44	os_memcpy(pos, data, data_len);
45	pos += data_len;
46	return pos;
47}
48
49
50static void wpa_supplicant_smk_timeout(void *eloop_ctx, void *timeout_ctx)
51{
52#if 0
53	struct wpa_sm *sm = eloop_ctx;
54	struct wpa_peerkey *peerkey = timeout_ctx;
55#endif
56	/* TODO: time out SMK and any STK that was generated using this SMK */
57}
58
59
60static void wpa_supplicant_peerkey_free(struct wpa_sm *sm,
61					struct wpa_peerkey *peerkey)
62{
63	eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
64	os_free(peerkey);
65}
66
67
68static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst,
69					 const u8 *peer,
70					 u16 mui, u16 error_type, int ver)
71{
72	size_t rlen;
73	struct wpa_eapol_key *err;
74	struct rsn_error_kde error;
75	u8 *rbuf, *pos;
76	size_t kde_len;
77	u16 key_info;
78
79	kde_len = 2 + RSN_SELECTOR_LEN + sizeof(error);
80	if (peer)
81		kde_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN;
82
83	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
84				  NULL, sizeof(*err) + kde_len, &rlen,
85				  (void *) &err);
86	if (rbuf == NULL)
87		return -1;
88
89	err->type = EAPOL_KEY_TYPE_RSN;
90	key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
91		WPA_KEY_INFO_SECURE | WPA_KEY_INFO_ERROR |
92		WPA_KEY_INFO_REQUEST;
93	WPA_PUT_BE16(err->key_info, key_info);
94	WPA_PUT_BE16(err->key_length, 0);
95	os_memcpy(err->replay_counter, sm->request_counter,
96		  WPA_REPLAY_COUNTER_LEN);
97	inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
98
99	WPA_PUT_BE16(err->key_data_length, (u16) kde_len);
100	pos = (u8 *) (err + 1);
101
102	if (peer) {
103		/* Peer MAC Address KDE */
104		pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
105	}
106
107	/* Error KDE */
108	error.mui = host_to_be16(mui);
109	error.error_type = host_to_be16(error_type);
110	wpa_add_kde(pos, RSN_KEY_DATA_ERROR, (u8 *) &error, sizeof(error));
111
112	if (peer) {
113		wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error (peer "
114			   MACSTR " mui %d error_type %d)",
115			   MAC2STR(peer), mui, error_type);
116	} else {
117		wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error "
118			   "(mui %d error_type %d)", mui, error_type);
119	}
120
121	wpa_eapol_key_send(sm, sm->ptk.kck, ver, dst, ETH_P_EAPOL,
122			   rbuf, rlen, err->key_mic);
123
124	return 0;
125}
126
127
128static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm,
129				      const unsigned char *src_addr,
130				      const struct wpa_eapol_key *key,
131				      int ver, struct wpa_peerkey *peerkey)
132{
133	size_t rlen;
134	struct wpa_eapol_key *reply;
135	u8 *rbuf, *pos;
136	size_t kde_len;
137	u16 key_info;
138
139	/* KDEs: Peer RSN IE, Initiator MAC Address, Initiator Nonce */
140	kde_len = peerkey->rsnie_p_len +
141		2 + RSN_SELECTOR_LEN + ETH_ALEN +
142		2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN;
143
144	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
145				  NULL, sizeof(*reply) + kde_len, &rlen,
146				  (void *) &reply);
147	if (rbuf == NULL)
148		return -1;
149
150	reply->type = EAPOL_KEY_TYPE_RSN;
151	key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
152		WPA_KEY_INFO_SECURE;
153	WPA_PUT_BE16(reply->key_info, key_info);
154	WPA_PUT_BE16(reply->key_length, 0);
155	os_memcpy(reply->replay_counter, key->replay_counter,
156		  WPA_REPLAY_COUNTER_LEN);
157
158	os_memcpy(reply->key_nonce, peerkey->pnonce, WPA_NONCE_LEN);
159
160	WPA_PUT_BE16(reply->key_data_length, (u16) kde_len);
161	pos = (u8 *) (reply + 1);
162
163	/* Peer RSN IE */
164	pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
165
166	/* Initiator MAC Address KDE */
167	pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peerkey->addr, ETH_ALEN);
168
169	/* Initiator Nonce */
170	wpa_add_kde(pos, RSN_KEY_DATA_NONCE, peerkey->inonce, WPA_NONCE_LEN);
171
172	wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3");
173	wpa_eapol_key_send(sm, sm->ptk.kck, ver, src_addr, ETH_P_EAPOL,
174			   rbuf, rlen, reply->key_mic);
175
176	return 0;
177}
178
179
180static int wpa_supplicant_process_smk_m2(
181	struct wpa_sm *sm, const unsigned char *src_addr,
182	const struct wpa_eapol_key *key, size_t extra_len, int ver)
183{
184	struct wpa_peerkey *peerkey;
185	struct wpa_eapol_ie_parse kde;
186	struct wpa_ie_data ie;
187	int cipher;
188	struct rsn_ie_hdr *hdr;
189	u8 *pos;
190
191	wpa_printf(MSG_DEBUG, "RSN: Received SMK M2");
192
193	if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
194		wpa_printf(MSG_INFO, "RSN: SMK handshake not allowed for "
195			   "the current network");
196		return -1;
197	}
198
199	if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
200	    0) {
201		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M2");
202		return -1;
203	}
204
205	if (kde.rsn_ie == NULL || kde.mac_addr == NULL ||
206	    kde.mac_addr_len < ETH_ALEN) {
207		wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in "
208			   "SMK M2");
209		return -1;
210	}
211
212	wpa_printf(MSG_DEBUG, "RSN: SMK M2 - SMK initiator " MACSTR,
213		   MAC2STR(kde.mac_addr));
214
215	if (kde.rsn_ie_len > PEERKEY_MAX_IE_LEN) {
216		wpa_printf(MSG_INFO, "RSN: Too long Initiator RSN IE in SMK "
217			   "M2");
218		return -1;
219	}
220
221	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
222		wpa_printf(MSG_INFO, "RSN: Failed to parse RSN IE in SMK M2");
223		return -1;
224	}
225
226	cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
227	if (cipher & WPA_CIPHER_CCMP) {
228		wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
229		cipher = WPA_CIPHER_CCMP;
230	} else if (cipher & WPA_CIPHER_TKIP) {
231		wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
232		cipher = WPA_CIPHER_TKIP;
233	} else {
234		wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2");
235		wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr,
236					      STK_MUI_SMK, STK_ERR_CPHR_NS,
237					      ver);
238		return -1;
239	}
240
241	/* TODO: find existing entry and if found, use that instead of adding
242	 * a new one; how to handle the case where both ends initiate at the
243	 * same time? */
244	peerkey = os_zalloc(sizeof(*peerkey));
245	if (peerkey == NULL)
246		return -1;
247	os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN);
248	os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
249	os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
250	peerkey->rsnie_i_len = kde.rsn_ie_len;
251	peerkey->cipher = cipher;
252#ifdef CONFIG_IEEE80211W
253	if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 |
254			   WPA_KEY_MGMT_PSK_SHA256))
255		peerkey->use_sha256 = 1;
256#endif /* CONFIG_IEEE80211W */
257
258	if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
259		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
260			"WPA: Failed to get random data for PNonce");
261		wpa_supplicant_peerkey_free(sm, peerkey);
262		return -1;
263	}
264
265	hdr = (struct rsn_ie_hdr *) peerkey->rsnie_p;
266	hdr->elem_id = WLAN_EID_RSN;
267	WPA_PUT_LE16(hdr->version, RSN_VERSION);
268	pos = (u8 *) (hdr + 1);
269	/* Group Suite can be anything for SMK RSN IE; receiver will just
270	 * ignore it. */
271	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
272	pos += RSN_SELECTOR_LEN;
273	/* Include only the selected cipher in pairwise cipher suite */
274	WPA_PUT_LE16(pos, 1);
275	pos += 2;
276	if (cipher == WPA_CIPHER_CCMP)
277		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
278	else if (cipher == WPA_CIPHER_TKIP)
279		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
280	pos += RSN_SELECTOR_LEN;
281
282	hdr->len = (pos - peerkey->rsnie_p) - 2;
283	peerkey->rsnie_p_len = pos - peerkey->rsnie_p;
284	wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
285		    peerkey->rsnie_p, peerkey->rsnie_p_len);
286
287	wpa_supplicant_send_smk_m3(sm, src_addr, key, ver, peerkey);
288
289	peerkey->next = sm->peerkey;
290	sm->peerkey = peerkey;
291
292	return 0;
293}
294
295
296/**
297 * rsn_smkid - Derive SMK identifier
298 * @smk: Station master key (32 bytes)
299 * @pnonce: Peer Nonce
300 * @mac_p: Peer MAC address
301 * @inonce: Initiator Nonce
302 * @mac_i: Initiator MAC address
303 * @use_sha256: Whether to use SHA256-based KDF
304 *
305 * 8.5.1.4 Station to station (STK) key hierarchy
306 * SMKID = HMAC-SHA1-128(SMK, "SMK Name" || PNonce || MAC_P || INonce || MAC_I)
307 */
308static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p,
309		      const u8 *inonce, const u8 *mac_i, u8 *smkid,
310		      int use_sha256)
311{
312	char *title = "SMK Name";
313	const u8 *addr[5];
314	const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN,
315				ETH_ALEN };
316	unsigned char hash[SHA256_MAC_LEN];
317
318	addr[0] = (u8 *) title;
319	addr[1] = pnonce;
320	addr[2] = mac_p;
321	addr[3] = inonce;
322	addr[4] = mac_i;
323
324#ifdef CONFIG_IEEE80211W
325	if (use_sha256)
326		hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash);
327	else
328#endif /* CONFIG_IEEE80211W */
329		hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash);
330	os_memcpy(smkid, hash, PMKID_LEN);
331}
332
333
334static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm,
335					   struct wpa_peerkey *peerkey)
336{
337	size_t mlen;
338	struct wpa_eapol_key *msg;
339	u8 *mbuf;
340	size_t kde_len;
341	u16 key_info, ver;
342
343	kde_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
344
345	mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
346				  sizeof(*msg) + kde_len, &mlen,
347				  (void *) &msg);
348	if (mbuf == NULL)
349		return;
350
351	msg->type = EAPOL_KEY_TYPE_RSN;
352
353	if (peerkey->cipher == WPA_CIPHER_CCMP)
354		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
355	else
356		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
357
358	key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK;
359	WPA_PUT_BE16(msg->key_info, key_info);
360
361	if (peerkey->cipher == WPA_CIPHER_CCMP)
362		WPA_PUT_BE16(msg->key_length, 16);
363	else
364		WPA_PUT_BE16(msg->key_length, 32);
365
366	os_memcpy(msg->replay_counter, peerkey->replay_counter,
367		  WPA_REPLAY_COUNTER_LEN);
368	inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
369
370	WPA_PUT_BE16(msg->key_data_length, kde_len);
371	wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID,
372		    peerkey->smkid, PMKID_LEN);
373
374	if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
375		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
376			"RSN: Failed to get random data for INonce (STK)");
377		os_free(mbuf);
378		return;
379	}
380	wpa_hexdump(MSG_DEBUG, "RSN: INonce for STK 4-Way Handshake",
381		    peerkey->inonce, WPA_NONCE_LEN);
382	os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
383
384	wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR,
385		   MAC2STR(peerkey->addr));
386	wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL,
387			   mbuf, mlen, NULL);
388}
389
390
391static void wpa_supplicant_send_stk_3_of_4(struct wpa_sm *sm,
392					   struct wpa_peerkey *peerkey)
393{
394	size_t mlen;
395	struct wpa_eapol_key *msg;
396	u8 *mbuf, *pos;
397	size_t kde_len;
398	u16 key_info, ver;
399	be32 lifetime;
400
401	kde_len = peerkey->rsnie_i_len +
402		2 + RSN_SELECTOR_LEN + sizeof(lifetime);
403
404	mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
405				  sizeof(*msg) + kde_len, &mlen,
406				  (void *) &msg);
407	if (mbuf == NULL)
408		return;
409
410	msg->type = EAPOL_KEY_TYPE_RSN;
411
412	if (peerkey->cipher == WPA_CIPHER_CCMP)
413		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
414	else
415		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
416
417	key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK |
418		WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
419	WPA_PUT_BE16(msg->key_info, key_info);
420
421	if (peerkey->cipher == WPA_CIPHER_CCMP)
422		WPA_PUT_BE16(msg->key_length, 16);
423	else
424		WPA_PUT_BE16(msg->key_length, 32);
425
426	os_memcpy(msg->replay_counter, peerkey->replay_counter,
427		  WPA_REPLAY_COUNTER_LEN);
428	inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
429
430	WPA_PUT_BE16(msg->key_data_length, kde_len);
431	pos = (u8 *) (msg + 1);
432	pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
433	lifetime = host_to_be32(peerkey->lifetime);
434	wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
435		    (u8 *) &lifetime, sizeof(lifetime));
436
437	os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
438
439	wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR,
440		   MAC2STR(peerkey->addr));
441	wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr,
442			   ETH_P_EAPOL, mbuf, mlen, msg->key_mic);
443}
444
445
446static int wpa_supplicant_process_smk_m4(struct wpa_peerkey *peerkey,
447					 struct wpa_eapol_ie_parse *kde)
448{
449	wpa_printf(MSG_DEBUG, "RSN: Received SMK M4 (Initiator " MACSTR ")",
450		   MAC2STR(kde->mac_addr));
451
452	if (os_memcmp(kde->smk + PMK_LEN, peerkey->pnonce, WPA_NONCE_LEN) != 0)
453	{
454		wpa_printf(MSG_INFO, "RSN: PNonce in SMK KDE does not "
455			   "match with the one used in SMK M3");
456		return -1;
457	}
458
459	if (os_memcmp(kde->nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
460		wpa_printf(MSG_INFO, "RSN: INonce in SMK M4 did not "
461			   "match with the one received in SMK M2");
462		return -1;
463	}
464
465	return 0;
466}
467
468
469static int wpa_supplicant_process_smk_m5(struct wpa_sm *sm,
470					 const unsigned char *src_addr,
471					 const struct wpa_eapol_key *key,
472					 int ver,
473					 struct wpa_peerkey *peerkey,
474					 struct wpa_eapol_ie_parse *kde)
475{
476	int cipher;
477	struct wpa_ie_data ie;
478
479	wpa_printf(MSG_DEBUG, "RSN: Received SMK M5 (Peer " MACSTR ")",
480		   MAC2STR(kde->mac_addr));
481	if (kde->rsn_ie == NULL || kde->rsn_ie_len > PEERKEY_MAX_IE_LEN ||
482	    wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0) {
483		wpa_printf(MSG_INFO, "RSN: No RSN IE in SMK M5");
484		/* TODO: abort negotiation */
485		return -1;
486	}
487
488	if (os_memcmp(key->key_nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
489		wpa_printf(MSG_INFO, "RSN: Key Nonce in SMK M5 does "
490			   "not match with INonce used in SMK M1");
491		return -1;
492	}
493
494	if (os_memcmp(kde->smk + PMK_LEN, peerkey->inonce, WPA_NONCE_LEN) != 0)
495	{
496		wpa_printf(MSG_INFO, "RSN: INonce in SMK KDE does not "
497			   "match with the one used in SMK M1");
498		return -1;
499	}
500
501	os_memcpy(peerkey->rsnie_p, kde->rsn_ie, kde->rsn_ie_len);
502	peerkey->rsnie_p_len = kde->rsn_ie_len;
503	os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN);
504
505	cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
506	if (cipher & WPA_CIPHER_CCMP) {
507		wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
508		peerkey->cipher = WPA_CIPHER_CCMP;
509	} else if (cipher & WPA_CIPHER_TKIP) {
510		wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
511		peerkey->cipher = WPA_CIPHER_TKIP;
512	} else {
513		wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected "
514			   "unacceptable cipher", MAC2STR(kde->mac_addr));
515		wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr,
516					      STK_MUI_SMK, STK_ERR_CPHR_NS,
517					      ver);
518		/* TODO: abort negotiation */
519		return -1;
520	}
521
522	return 0;
523}
524
525
526static int wpa_supplicant_process_smk_m45(
527	struct wpa_sm *sm, const unsigned char *src_addr,
528	const struct wpa_eapol_key *key, size_t extra_len, int ver)
529{
530	struct wpa_peerkey *peerkey;
531	struct wpa_eapol_ie_parse kde;
532	u32 lifetime;
533	struct os_time now;
534
535	if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
536		wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
537			   "the current network");
538		return -1;
539	}
540
541	if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
542	    0) {
543		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M4/M5");
544		return -1;
545	}
546
547	if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
548	    kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN ||
549	    kde.smk == NULL || kde.smk_len < PMK_LEN + WPA_NONCE_LEN ||
550	    kde.lifetime == NULL || kde.lifetime_len < 4) {
551		wpa_printf(MSG_INFO, "RSN: No MAC Address, Nonce, SMK, or "
552			   "Lifetime KDE in SMK M4/M5");
553		return -1;
554	}
555
556	for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
557		if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 0 &&
558		    os_memcmp(peerkey->initiator ? peerkey->inonce :
559			   peerkey->pnonce,
560			   key->key_nonce, WPA_NONCE_LEN) == 0)
561			break;
562	}
563	if (peerkey == NULL) {
564		wpa_printf(MSG_INFO, "RSN: No matching SMK handshake found "
565			   "for SMK M4/M5: peer " MACSTR,
566			   MAC2STR(kde.mac_addr));
567		return -1;
568	}
569
570	if (peerkey->initiator) {
571		if (wpa_supplicant_process_smk_m5(sm, src_addr, key, ver,
572						  peerkey, &kde) < 0)
573			return -1;
574	} else {
575		if (wpa_supplicant_process_smk_m4(peerkey, &kde) < 0)
576			return -1;
577	}
578
579	os_memcpy(peerkey->smk, kde.smk, PMK_LEN);
580	peerkey->smk_complete = 1;
581	wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", peerkey->smk, PMK_LEN);
582	lifetime = WPA_GET_BE32(kde.lifetime);
583	wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime);
584	if (lifetime > 1000000000)
585		lifetime = 1000000000; /* avoid overflowing expiration time */
586	peerkey->lifetime = lifetime;
587	os_get_time(&now);
588	peerkey->expiration = now.sec + lifetime;
589	eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
590			       sm, peerkey);
591
592	if (peerkey->initiator) {
593		rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr,
594			  peerkey->inonce, sm->own_addr, peerkey->smkid,
595			  peerkey->use_sha256);
596		wpa_supplicant_send_stk_1_of_4(sm, peerkey);
597	} else {
598		rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr,
599			  peerkey->inonce, peerkey->addr, peerkey->smkid,
600			  peerkey->use_sha256);
601	}
602	wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN);
603
604	return 0;
605}
606
607
608static int wpa_supplicant_process_smk_error(
609	struct wpa_sm *sm, const unsigned char *src_addr,
610	const struct wpa_eapol_key *key, size_t extra_len)
611{
612	struct wpa_eapol_ie_parse kde;
613	struct rsn_error_kde error;
614	u8 peer[ETH_ALEN];
615	u16 error_type;
616
617	wpa_printf(MSG_DEBUG, "RSN: Received SMK Error");
618
619	if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
620		wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
621			   "the current network");
622		return -1;
623	}
624
625	if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
626	    0) {
627		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");
628		return -1;
629	}
630
631	if (kde.error == NULL || kde.error_len < sizeof(error)) {
632		wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error");
633		return -1;
634	}
635
636	if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN)
637		os_memcpy(peer, kde.mac_addr, ETH_ALEN);
638	else
639		os_memset(peer, 0, ETH_ALEN);
640	os_memcpy(&error, kde.error, sizeof(error));
641	error_type = be_to_host16(error.error_type);
642	wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
643		"RSN: SMK Error KDE received: MUI %d error_type %d peer "
644		MACSTR,
645		be_to_host16(error.mui), error_type,
646		MAC2STR(peer));
647
648	if (kde.mac_addr &&
649	    (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN ||
650	     error_type == STK_ERR_CPHR_NS)) {
651		struct wpa_peerkey *peerkey;
652
653		for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
654			if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) ==
655			    0)
656				break;
657		}
658		if (peerkey == NULL) {
659			wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake "
660				   "found for SMK Error");
661			return -1;
662		}
663		/* TODO: abort SMK/STK handshake and remove all related keys */
664	}
665
666	return 0;
667}
668
669
670static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,
671					      struct wpa_peerkey *peerkey,
672					      const struct wpa_eapol_key *key,
673					      u16 ver)
674{
675	struct wpa_eapol_ie_parse ie;
676	const u8 *kde;
677	size_t len, kde_buf_len;
678	struct wpa_ptk *stk;
679	u8 buf[8], *kde_buf, *pos;
680	be32 lifetime;
681
682	wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from "
683		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
684
685	os_memset(&ie, 0, sizeof(ie));
686
687	/* RSN: msg 1/4 should contain SMKID for the selected SMK */
688	kde = (const u8 *) (key + 1);
689	len = WPA_GET_BE16(key->key_data_length);
690	wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len);
691	if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) {
692		wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4");
693		return;
694	}
695	if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
696		wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4",
697			    ie.pmkid, PMKID_LEN);
698		return;
699	}
700
701	if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
702		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
703			"RSN: Failed to get random data for PNonce");
704		return;
705	}
706	wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce",
707		    peerkey->pnonce, WPA_NONCE_LEN);
708
709	/* Calculate STK which will be stored as a temporary STK until it has
710	 * been verified when processing message 3/4. */
711	stk = &peerkey->tstk;
712	wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
713		       sm->own_addr, peerkey->addr,
714		       peerkey->pnonce, key->key_nonce,
715		       (u8 *) stk, sizeof(*stk),
716		       peerkey->use_sha256);
717	/* Supplicant: swap tx/rx Mic keys */
718	os_memcpy(buf, stk->u.auth.tx_mic_key, 8);
719	os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8);
720	os_memcpy(stk->u.auth.rx_mic_key, buf, 8);
721	peerkey->tstk_set = 1;
722
723	kde_buf_len = peerkey->rsnie_p_len +
724		2 + RSN_SELECTOR_LEN + sizeof(lifetime) +
725		2 + RSN_SELECTOR_LEN + PMKID_LEN;
726	kde_buf = os_malloc(kde_buf_len);
727	if (kde_buf == NULL)
728		return;
729	pos = kde_buf;
730	pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
731	lifetime = host_to_be32(peerkey->lifetime);
732	pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
733			  (u8 *) &lifetime, sizeof(lifetime));
734	wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN);
735
736	if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver,
737				       peerkey->pnonce, kde_buf, kde_buf_len,
738				       stk)) {
739		os_free(kde_buf);
740		return;
741	}
742	os_free(kde_buf);
743
744	os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
745}
746
747
748static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm,
749					       struct wpa_peerkey *peerkey,
750					       struct wpa_eapol_ie_parse *kde)
751{
752	u32 lifetime;
753	struct os_time now;
754
755	if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime))
756		return;
757
758	lifetime = WPA_GET_BE32(kde->lifetime);
759
760	if (lifetime >= peerkey->lifetime) {
761		wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds "
762			   "which is larger than or equal to own value %u "
763			   "seconds - ignored", lifetime, peerkey->lifetime);
764		return;
765	}
766
767	wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds "
768		   "(own was %u seconds) - updated",
769		   lifetime, peerkey->lifetime);
770	peerkey->lifetime = lifetime;
771
772	os_get_time(&now);
773	peerkey->expiration = now.sec + lifetime;
774	eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
775	eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
776			       sm, peerkey);
777}
778
779
780static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,
781					      struct wpa_peerkey *peerkey,
782					      const struct wpa_eapol_key *key,
783					      u16 ver)
784{
785	struct wpa_eapol_ie_parse kde;
786	const u8 *keydata;
787	size_t len;
788
789	wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from "
790		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
791
792	os_memset(&kde, 0, sizeof(kde));
793
794	/* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE
795	 * from the peer. It may also include Lifetime KDE. */
796	keydata = (const u8 *) (key + 1);
797	len = WPA_GET_BE16(key->key_data_length);
798	wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len);
799	if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 ||
800	    kde.pmkid == NULL || kde.rsn_ie == NULL) {
801		wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4");
802		return;
803	}
804
805	if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
806		wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4",
807			    kde.pmkid, PMKID_LEN);
808		return;
809	}
810
811	if (kde.rsn_ie_len != peerkey->rsnie_p_len ||
812	    os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) {
813		wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK "
814			   "handshakes did not match");
815		wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake",
816			    peerkey->rsnie_p, peerkey->rsnie_p_len);
817		wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake",
818			    kde.rsn_ie, kde.rsn_ie_len);
819		return;
820	}
821
822	wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
823
824	wpa_supplicant_send_stk_3_of_4(sm, peerkey);
825	os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN);
826}
827
828
829static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm,
830					      struct wpa_peerkey *peerkey,
831					      const struct wpa_eapol_key *key,
832					      u16 ver)
833{
834	struct wpa_eapol_ie_parse kde;
835	const u8 *keydata;
836	size_t len, key_len;
837	const u8 *_key;
838	u8 key_buf[32], rsc[6];
839
840	wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from "
841		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
842
843	os_memset(&kde, 0, sizeof(kde));
844
845	/* RSN: msg 3/4 should contain Initiator RSN IE. It may also include
846	 * Lifetime KDE. */
847	keydata = (const u8 *) (key + 1);
848	len = WPA_GET_BE16(key->key_data_length);
849	wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len);
850	if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) {
851		wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in "
852			   "STK 3/4");
853		return;
854	}
855
856	if (kde.rsn_ie_len != peerkey->rsnie_i_len ||
857	    os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) {
858		wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK "
859			   "handshakes did not match");
860		wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK "
861			    "handshake",
862			    peerkey->rsnie_i, peerkey->rsnie_i_len);
863		wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK "
864			    "handshake",
865			    kde.rsn_ie, kde.rsn_ie_len);
866		return;
867	}
868
869	if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
870		wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK "
871			   "4-Way Handshake differs from 3 of STK 4-Way "
872			   "Handshake - drop packet (src=" MACSTR ")",
873			   MAC2STR(peerkey->addr));
874		return;
875	}
876
877	wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
878
879	if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver,
880				       WPA_GET_BE16(key->key_info),
881				       NULL, 0, &peerkey->stk))
882		return;
883
884	_key = (u8 *) peerkey->stk.tk1;
885	if (peerkey->cipher == WPA_CIPHER_TKIP) {
886		/* Swap Tx/Rx keys for Michael MIC */
887		os_memcpy(key_buf, _key, 16);
888		os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8);
889		os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8);
890		_key = key_buf;
891		key_len = 32;
892	} else
893		key_len = 16;
894
895	os_memset(rsc, 0, 6);
896	if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
897			   rsc, sizeof(rsc), _key, key_len) < 0) {
898		wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
899			   "driver.");
900		return;
901	}
902}
903
904
905static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm,
906					      struct wpa_peerkey *peerkey,
907					      const struct wpa_eapol_key *key,
908					      u16 ver)
909{
910	u8 rsc[6];
911
912	wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from "
913		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
914
915	os_memset(rsc, 0, 6);
916	if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
917			   rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1,
918			   peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) {
919		wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
920			   "driver.");
921		return;
922	}
923}
924
925
926/**
927 * peerkey_verify_eapol_key_mic - Verify PeerKey MIC
928 * @sm: Pointer to WPA state machine data from wpa_sm_init()
929 * @peerkey: Pointer to the PeerKey data for the peer
930 * @key: Pointer to the EAPOL-Key frame header
931 * @ver: Version bits from EAPOL-Key Key Info
932 * @buf: Pointer to the beginning of EAPOL-Key frame
933 * @len: Length of the EAPOL-Key frame
934 * Returns: 0 on success, -1 on failure
935 */
936int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
937				 struct wpa_peerkey *peerkey,
938				 struct wpa_eapol_key *key, u16 ver,
939				 const u8 *buf, size_t len)
940{
941	u8 mic[16];
942	int ok = 0;
943
944	if (peerkey->initiator && !peerkey->stk_set) {
945		wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
946			       sm->own_addr, peerkey->addr,
947			       peerkey->inonce, key->key_nonce,
948			       (u8 *) &peerkey->stk, sizeof(peerkey->stk),
949			       peerkey->use_sha256);
950		peerkey->stk_set = 1;
951	}
952
953	os_memcpy(mic, key->key_mic, 16);
954	if (peerkey->tstk_set) {
955		os_memset(key->key_mic, 0, 16);
956		wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
957				  key->key_mic);
958		if (os_memcmp(mic, key->key_mic, 16) != 0) {
959			wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
960				   "when using TSTK - ignoring TSTK");
961		} else {
962			ok = 1;
963			peerkey->tstk_set = 0;
964			peerkey->stk_set = 1;
965			os_memcpy(&peerkey->stk, &peerkey->tstk,
966				  sizeof(peerkey->stk));
967		}
968	}
969
970	if (!ok && peerkey->stk_set) {
971		os_memset(key->key_mic, 0, 16);
972		wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
973				  key->key_mic);
974		if (os_memcmp(mic, key->key_mic, 16) != 0) {
975			wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
976				   "- dropping packet");
977			return -1;
978		}
979		ok = 1;
980	}
981
982	if (!ok) {
983		wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC "
984			   "- dropping packet");
985		return -1;
986	}
987
988	os_memcpy(peerkey->replay_counter, key->replay_counter,
989		  WPA_REPLAY_COUNTER_LEN);
990	peerkey->replay_counter_set = 1;
991	return 0;
992}
993
994
995/**
996 * wpa_sm_stkstart - Send EAPOL-Key Request for STK handshake (STK M1)
997 * @sm: Pointer to WPA state machine data from wpa_sm_init()
998 * @peer: MAC address of the peer STA
999 * Returns: 0 on success, or -1 on failure
1000 *
1001 * Send an EAPOL-Key Request to the current authenticator to start STK
1002 * handshake with the peer.
1003 */
1004int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
1005{
1006	size_t rlen, kde_len;
1007	struct wpa_eapol_key *req;
1008	int key_info, ver;
1009	u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos;
1010	u16 count;
1011	struct rsn_ie_hdr *hdr;
1012	struct wpa_peerkey *peerkey;
1013	struct wpa_ie_data ie;
1014
1015	if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled)
1016		return -1;
1017
1018	if (sm->ap_rsn_ie &&
1019	    wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 &&
1020	    !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) {
1021		wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK");
1022		return -1;
1023	}
1024
1025	if (sm->pairwise_cipher == WPA_CIPHER_CCMP)
1026		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
1027	else
1028		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
1029
1030	if (wpa_sm_get_bssid(sm, bssid) < 0) {
1031		wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
1032			   "SMK M1");
1033		return -1;
1034	}
1035
1036	/* TODO: find existing entry and if found, use that instead of adding
1037	 * a new one */
1038	peerkey = os_zalloc(sizeof(*peerkey));
1039	if (peerkey == NULL)
1040		return -1;
1041	peerkey->initiator = 1;
1042	os_memcpy(peerkey->addr, peer, ETH_ALEN);
1043#ifdef CONFIG_IEEE80211W
1044	if (wpa_key_mgmt_sha256(sm->key_mgmt))
1045		peerkey->use_sha256 = 1;
1046#endif /* CONFIG_IEEE80211W */
1047
1048	/* SMK M1:
1049	 * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
1050	 *           MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE))
1051	 */
1052
1053	hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i;
1054	hdr->elem_id = WLAN_EID_RSN;
1055	WPA_PUT_LE16(hdr->version, RSN_VERSION);
1056	pos = (u8 *) (hdr + 1);
1057	/* Group Suite can be anything for SMK RSN IE; receiver will just
1058	 * ignore it. */
1059	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1060	pos += RSN_SELECTOR_LEN;
1061	count_pos = pos;
1062	pos += 2;
1063
1064	count = 0;
1065	if (sm->allowed_pairwise_cipher & WPA_CIPHER_CCMP) {
1066		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1067		pos += RSN_SELECTOR_LEN;
1068		count++;
1069	}
1070	if (sm->allowed_pairwise_cipher & WPA_CIPHER_TKIP) {
1071		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
1072		pos += RSN_SELECTOR_LEN;
1073		count++;
1074	}
1075	WPA_PUT_LE16(count_pos, count);
1076
1077	hdr->len = (pos - peerkey->rsnie_i) - 2;
1078	peerkey->rsnie_i_len = pos - peerkey->rsnie_i;
1079	wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
1080		    peerkey->rsnie_i, peerkey->rsnie_i_len);
1081
1082	kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;
1083
1084	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
1085				  sizeof(*req) + kde_len, &rlen,
1086				  (void *) &req);
1087	if (rbuf == NULL) {
1088		wpa_supplicant_peerkey_free(sm, peerkey);
1089		return -1;
1090	}
1091
1092	req->type = EAPOL_KEY_TYPE_RSN;
1093	key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
1094		WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver;
1095	WPA_PUT_BE16(req->key_info, key_info);
1096	WPA_PUT_BE16(req->key_length, 0);
1097	os_memcpy(req->replay_counter, sm->request_counter,
1098		  WPA_REPLAY_COUNTER_LEN);
1099	inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
1100
1101	if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
1102		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1103			"WPA: Failed to get random data for INonce");
1104		os_free(rbuf);
1105		wpa_supplicant_peerkey_free(sm, peerkey);
1106		return -1;
1107	}
1108	os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
1109	wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake",
1110		    req->key_nonce, WPA_NONCE_LEN);
1111
1112	WPA_PUT_BE16(req->key_data_length, (u16) kde_len);
1113	pos = (u8 *) (req + 1);
1114
1115	/* Initiator RSN IE */
1116	pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
1117	/* Peer MAC address KDE */
1118	wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
1119
1120	wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer "
1121		   MACSTR ")", MAC2STR(peer));
1122	wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
1123			   rbuf, rlen, req->key_mic);
1124
1125	peerkey->next = sm->peerkey;
1126	sm->peerkey = peerkey;
1127
1128	return 0;
1129}
1130
1131
1132/**
1133 * peerkey_deinit - Free PeerKey values
1134 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1135 */
1136void peerkey_deinit(struct wpa_sm *sm)
1137{
1138	struct wpa_peerkey *prev, *peerkey = sm->peerkey;
1139	while (peerkey) {
1140		prev = peerkey;
1141		peerkey = peerkey->next;
1142		os_free(prev);
1143	}
1144	sm->peerkey = NULL;
1145}
1146
1147
1148void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
1149			   struct wpa_eapol_key *key, u16 key_info, u16 ver)
1150{
1151	if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) ==
1152	    (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) {
1153		/* 3/4 STK 4-Way Handshake */
1154		wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver);
1155	} else if (key_info & WPA_KEY_INFO_ACK) {
1156		/* 1/4 STK 4-Way Handshake */
1157		wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver);
1158	} else if (key_info & WPA_KEY_INFO_SECURE) {
1159		/* 4/4 STK 4-Way Handshake */
1160		wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
1161	} else {
1162		/* 2/4 STK 4-Way Handshake */
1163		wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver);
1164	}
1165}
1166
1167
1168void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
1169			  struct wpa_eapol_key *key, size_t extra_len,
1170			  u16 key_info, u16 ver)
1171{
1172	if (key_info & WPA_KEY_INFO_ERROR) {
1173		/* SMK Error */
1174		wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len);
1175	} else if (key_info & WPA_KEY_INFO_ACK) {
1176		/* SMK M2 */
1177		wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len,
1178					      ver);
1179	} else {
1180		/* SMK M4 or M5 */
1181		wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len,
1182					       ver);
1183	}
1184}
1185
1186#endif /* CONFIG_PEERKEY */
1187