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