1/*	$OpenBSD: ieee80211_pae_output.c,v 1.33 2022/01/05 05:18:25 dlg Exp $	*/
2
3/*-
4 * Copyright (c) 2007,2008 Damien Bergamini <damien.bergamini@free.fr>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * This code implements the 4-Way Handshake and Group Key Handshake protocols
21 * (both Supplicant and Authenticator Key Transmit state machines) defined in
22 * IEEE Std 802.11-2007 section 8.5.
23 */
24
25#include <sys/param.h>
26#include <sys/systm.h>
27#include <sys/mbuf.h>
28#include <sys/kernel.h>
29#include <sys/socket.h>
30#include <sys/sockio.h>
31#include <sys/endian.h>
32#include <sys/errno.h>
33
34#include <net/if.h>
35#include <net/if_dl.h>
36#include <net/if_media.h>
37#include <net/if_llc.h>
38
39#include <netinet/in.h>
40#include <netinet/if_ether.h>
41#include <netinet/ip.h>
42
43#include <net80211/ieee80211_var.h>
44#include <net80211/ieee80211_priv.h>
45
46int		ieee80211_send_eapol_key(struct ieee80211com *, struct mbuf *,
47		    struct ieee80211_node *, const struct ieee80211_ptk *);
48#ifndef IEEE80211_STA_ONLY
49u_int8_t	*ieee80211_add_gtk_kde(u_int8_t *, struct ieee80211_node *,
50		    const struct ieee80211_key *);
51u_int8_t	*ieee80211_add_pmkid_kde(u_int8_t *, const u_int8_t *);
52u_int8_t	*ieee80211_add_igtk_kde(u_int8_t *,
53		    const struct ieee80211_key *);
54#endif
55struct mbuf 	*ieee80211_get_eapol_key(int, int, u_int);
56
57/*
58 * Send an EAPOL-Key frame to node `ni'.  If MIC or encryption is required,
59 * the PTK must be passed (otherwise it can be set to NULL.)
60 */
61int
62ieee80211_send_eapol_key(struct ieee80211com *ic, struct mbuf *m,
63    struct ieee80211_node *ni, const struct ieee80211_ptk *ptk)
64{
65	struct ifnet *ifp = &ic->ic_if;
66	struct ether_header *eh;
67	struct ieee80211_eapol_key *key;
68	u_int16_t info;
69	int len, error;
70
71	M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
72	if (m == NULL)
73		return ENOMEM;
74	/* no need to m_pullup here (ok by construction) */
75	eh = mtod(m, struct ether_header *);
76	eh->ether_type = htons(ETHERTYPE_EAPOL);
77	IEEE80211_ADDR_COPY(eh->ether_shost, ic->ic_myaddr);
78	IEEE80211_ADDR_COPY(eh->ether_dhost, ni->ni_macaddr);
79
80	key = (struct ieee80211_eapol_key *)&eh[1];
81	key->version = EAPOL_VERSION;
82	key->type = EAPOL_KEY;
83	key->desc = (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) ?
84	    EAPOL_KEY_DESC_IEEE80211 : EAPOL_KEY_DESC_WPA;
85
86	info = BE_READ_2(key->info);
87	/* use V3 descriptor if KDF is SHA256-based */
88	if (ieee80211_is_sha256_akm(ni->ni_rsnakms))
89		info |= EAPOL_KEY_DESC_V3;
90	/* use V2 descriptor if pairwise or group cipher is CCMP */
91	else if (ni->ni_rsncipher == IEEE80211_CIPHER_CCMP ||
92	    ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP)
93		info |= EAPOL_KEY_DESC_V2;
94	else
95		info |= EAPOL_KEY_DESC_V1;
96	BE_WRITE_2(key->info, info);
97
98	len = m->m_len - sizeof(struct ether_header);
99	BE_WRITE_2(key->paylen, len - sizeof(*key));
100	BE_WRITE_2(key->len, len - 4);
101
102#ifndef IEEE80211_STA_ONLY
103	if (info & EAPOL_KEY_ENCRYPTED) {
104		if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
105			/* clear "Encrypted" bit for WPA */
106			info &= ~EAPOL_KEY_ENCRYPTED;
107			BE_WRITE_2(key->info, info);
108		}
109		ieee80211_eapol_key_encrypt(ic, key, ptk->kek);
110
111		if ((info & EAPOL_KEY_VERSION_MASK) != EAPOL_KEY_DESC_V1) {
112			/* AES Key Wrap adds 8 bytes + padding */
113			m->m_pkthdr.len = m->m_len =
114			    sizeof(*eh) + 4 + BE_READ_2(key->len);
115		}
116	}
117#endif
118	if (info & EAPOL_KEY_KEYMIC)
119		ieee80211_eapol_key_mic(key, ptk->kck);
120
121#ifndef IEEE80211_STA_ONLY
122	/* start a 100ms timeout if an answer is expected from supplicant */
123	if (info & EAPOL_KEY_KEYACK)
124		timeout_add_msec(&ni->ni_eapol_to, 100);
125#endif
126
127	error = ifq_enqueue(&ifp->if_snd, m);
128	if (error)
129		return (error);
130	if_start(ifp);
131	return 0;
132}
133
134#ifndef IEEE80211_STA_ONLY
135/*
136 * Handle EAPOL-Key timeouts (no answer from supplicant).
137 */
138void
139ieee80211_eapol_timeout(void *arg)
140{
141	struct ieee80211_node *ni = arg;
142	struct ieee80211com *ic = ni->ni_ic;
143	int s;
144
145	DPRINTF(("no answer from station %s in state %d\n",
146	    ether_sprintf(ni->ni_macaddr), ni->ni_rsn_state));
147
148	s = splnet();
149
150	switch (ni->ni_rsn_state) {
151	case RSNA_PTKSTART:
152	case RSNA_PTKCALCNEGOTIATING:
153		(void)ieee80211_send_4way_msg1(ic, ni);
154		break;
155	case RSNA_PTKINITNEGOTIATING:
156		(void)ieee80211_send_4way_msg3(ic, ni);
157		break;
158	}
159
160	switch (ni->ni_rsn_gstate) {
161	case RSNA_REKEYNEGOTIATING:
162		(void)ieee80211_send_group_msg1(ic, ni);
163		break;
164	}
165
166	splx(s);
167}
168
169/*
170 * Add a GTK KDE to an EAPOL-Key frame (see Figure 144).
171 */
172u_int8_t *
173ieee80211_add_gtk_kde(u_int8_t *frm, struct ieee80211_node *ni,
174    const struct ieee80211_key *k)
175{
176	KASSERT(k->k_flags & IEEE80211_KEY_GROUP);
177
178	*frm++ = IEEE80211_ELEMID_VENDOR;
179	*frm++ = 6 + k->k_len;
180	memcpy(frm, IEEE80211_OUI, 3); frm += 3;
181	*frm++ = IEEE80211_KDE_GTK;
182	*frm = k->k_id & 3;
183	/*
184	 * The TxRx flag for sending a GTK is always the opposite of whether
185	 * the pairwise key is used for data encryption/integrity or not.
186	 */
187	if (ni->ni_rsncipher == IEEE80211_CIPHER_USEGROUP)
188		*frm |= 1 << 2;	/* set the Tx bit */
189	frm++;
190	*frm++ = 0;	/* reserved */
191	memcpy(frm, k->k_key, k->k_len);
192	return frm + k->k_len;
193}
194
195/*
196 * Add a PMKID KDE to an EAPOL-Key frame (see Figure 146).
197 */
198u_int8_t *
199ieee80211_add_pmkid_kde(u_int8_t *frm, const u_int8_t *pmkid)
200{
201	*frm++ = IEEE80211_ELEMID_VENDOR;
202	*frm++ = 20;
203	memcpy(frm, IEEE80211_OUI, 3); frm += 3;
204	*frm++ = IEEE80211_KDE_PMKID;
205	memcpy(frm, pmkid, IEEE80211_PMKID_LEN);
206	return frm + IEEE80211_PMKID_LEN;
207}
208
209/*
210 * Add an IGTK KDE to an EAPOL-Key frame (see Figure 8-32a).
211 */
212u_int8_t *
213ieee80211_add_igtk_kde(u_int8_t *frm, const struct ieee80211_key *k)
214{
215	KASSERT(k->k_flags & IEEE80211_KEY_IGTK);
216
217	*frm++ = IEEE80211_ELEMID_VENDOR;
218	*frm++ = 4 + 24;
219	memcpy(frm, IEEE80211_OUI, 3); frm += 3;
220	*frm++ = IEEE80211_KDE_IGTK;
221	LE_WRITE_2(frm, k->k_id); frm += 2;
222	LE_WRITE_6(frm, k->k_tsc); frm += 6;	/* IPN */
223	memcpy(frm, k->k_key, 16);
224	return frm + 16;
225}
226#endif	/* IEEE80211_STA_ONLY */
227
228struct mbuf *
229ieee80211_get_eapol_key(int flags, int type, u_int pktlen)
230{
231	struct mbuf *m;
232
233	/* reserve space for 802.11 encapsulation and EAPOL-Key header */
234	pktlen += sizeof(struct ieee80211_frame) + LLC_SNAPFRAMELEN +
235	    sizeof(struct ieee80211_eapol_key);
236
237	if (pktlen > MCLBYTES)
238		panic("EAPOL-Key frame too large: %u", pktlen);
239	MGETHDR(m, flags, type);
240	if (m == NULL)
241		return NULL;
242	if (pktlen > MHLEN) {
243		MCLGET(m, flags);
244		if (!(m->m_flags & M_EXT))
245			return m_free(m);
246	}
247	m->m_data += sizeof(struct ieee80211_frame) + LLC_SNAPFRAMELEN;
248	return m;
249}
250
251#ifndef IEEE80211_STA_ONLY
252/*
253 * Send 4-Way Handshake Message 1 to the supplicant.
254 */
255int
256ieee80211_send_4way_msg1(struct ieee80211com *ic, struct ieee80211_node *ni)
257{
258	struct ieee80211_eapol_key *key;
259	struct mbuf *m;
260	u_int16_t info, keylen;
261	u_int8_t *frm;
262
263	ni->ni_rsn_state = RSNA_PTKSTART;
264	if (++ni->ni_rsn_retries > 3) {
265		IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
266		    IEEE80211_REASON_4WAY_TIMEOUT);
267		ieee80211_node_leave(ic, ni);
268		return 0;
269	}
270	m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
271	    (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) ? 2 + 20 : 0);
272	if (m == NULL)
273		return ENOMEM;
274	key = mtod(m, struct ieee80211_eapol_key *);
275	memset(key, 0, sizeof(*key));
276
277	info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYACK;
278	BE_WRITE_2(key->info, info);
279
280	/* copy the authenticator's nonce (ANonce) */
281	memcpy(key->nonce, ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
282
283	keylen = ieee80211_cipher_keylen(ni->ni_rsncipher);
284	BE_WRITE_2(key->keylen, keylen);
285
286	frm = (u_int8_t *)&key[1];
287	/* NB: WPA does not have PMKID KDE */
288	if (ni->ni_rsnprotos == IEEE80211_PROTO_RSN &&
289	    ieee80211_is_8021x_akm(ni->ni_rsnakms))
290		frm = ieee80211_add_pmkid_kde(frm, ni->ni_pmkid);
291
292	m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
293
294	if (ic->ic_if.if_flags & IFF_DEBUG)
295		printf("%s: sending msg %d/%d of the %s handshake to %s\n",
296		    ic->ic_if.if_xname, 1, 4, "4-way",
297		    ether_sprintf(ni->ni_macaddr));
298
299	ni->ni_replaycnt++;
300	BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
301
302	return ieee80211_send_eapol_key(ic, m, ni, NULL);
303}
304#endif	/* IEEE80211_STA_ONLY */
305
306/*
307 * Send 4-Way Handshake Message 2 to the authenticator.
308 */
309int
310ieee80211_send_4way_msg2(struct ieee80211com *ic, struct ieee80211_node *ni,
311    const u_int8_t *replaycnt, const struct ieee80211_ptk *tptk)
312{
313	struct ieee80211_eapol_key *key;
314	struct mbuf *m;
315	u_int16_t info;
316	u_int8_t *frm;
317
318	ni->ni_rsn_supp_state = RSNA_SUPP_PTKNEGOTIATING;
319	m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
320	    (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) ?
321		2 + IEEE80211_WPAIE_MAXLEN :
322		2 + IEEE80211_RSNIE_MAXLEN);
323	if (m == NULL)
324		return ENOMEM;
325	key = mtod(m, struct ieee80211_eapol_key *);
326	memset(key, 0, sizeof(*key));
327
328	info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYMIC;
329	BE_WRITE_2(key->info, info);
330
331	/* copy key replay counter from Message 1/4 */
332	memcpy(key->replaycnt, replaycnt, 8);
333
334	/* copy the supplicant's nonce (SNonce) */
335	memcpy(key->nonce, ic->ic_nonce, EAPOL_KEY_NONCE_LEN);
336
337	frm = (u_int8_t *)&key[1];
338	/* add the WPA/RSN IE used in the (Re)Association Request */
339	if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
340		int keylen;
341		frm = ieee80211_add_wpa(frm, ic, ni);
342		/* WPA sets the key length field here */
343		keylen = ieee80211_cipher_keylen(ni->ni_rsncipher);
344		BE_WRITE_2(key->keylen, keylen);
345	} else	/* RSN */
346		frm = ieee80211_add_rsn(frm, ic, ni);
347
348	m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
349
350	if (ic->ic_if.if_flags & IFF_DEBUG)
351		printf("%s: sending msg %d/%d of the %s handshake to %s\n",
352		    ic->ic_if.if_xname, 2, 4, "4-way",
353		    ether_sprintf(ni->ni_macaddr));
354
355	return ieee80211_send_eapol_key(ic, m, ni, tptk);
356}
357
358#ifndef IEEE80211_STA_ONLY
359/*
360 * Send 4-Way Handshake Message 3 to the supplicant.
361 */
362int
363ieee80211_send_4way_msg3(struct ieee80211com *ic, struct ieee80211_node *ni)
364{
365	struct ieee80211_eapol_key *key;
366	struct ieee80211_key *k = NULL;
367	struct mbuf *m;
368	u_int16_t info, keylen;
369	u_int8_t *frm;
370
371	ni->ni_rsn_state = RSNA_PTKINITNEGOTIATING;
372	if (++ni->ni_rsn_retries > 3) {
373		IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
374		    IEEE80211_REASON_4WAY_TIMEOUT);
375		ieee80211_node_leave(ic, ni);
376		return 0;
377	}
378	if (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) {
379		k = &ic->ic_nw_keys[ic->ic_def_txkey];
380		m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
381		    2 + IEEE80211_RSNIE_MAXLEN + 2 + 6 + k->k_len + 15 +
382		    ((ni->ni_flags & IEEE80211_NODE_MFP) ? 2 + 28 : 0));
383	} else { /* WPA */
384		m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
385		    2 + IEEE80211_WPAIE_MAXLEN +
386		    ((ni->ni_flags & IEEE80211_NODE_MFP) ? 2 + 28 : 0));
387	}
388	if (m == NULL)
389		return ENOMEM;
390	key = mtod(m, struct ieee80211_eapol_key *);
391	memset(key, 0, sizeof(*key));
392
393	info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYACK | EAPOL_KEY_KEYMIC;
394	if (ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP)
395		info |= EAPOL_KEY_INSTALL;
396
397	/* use same nonce as in Message 1 */
398	memcpy(key->nonce, ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
399
400	ni->ni_replaycnt++;
401	BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
402
403	keylen = ieee80211_cipher_keylen(ni->ni_rsncipher);
404	BE_WRITE_2(key->keylen, keylen);
405
406	frm = (u_int8_t *)&key[1];
407	/* add the WPA/RSN IE included in Beacon/Probe Response */
408	if (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) {
409		frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
410		/* encapsulate the GTK */
411		frm = ieee80211_add_gtk_kde(frm, ni, k);
412		LE_WRITE_6(key->rsc, k->k_tsc);
413		/* encapsulate the IGTK if MFP was negotiated */
414		if (ni->ni_flags & IEEE80211_NODE_MFP) {
415			frm = ieee80211_add_igtk_kde(frm,
416			    &ic->ic_nw_keys[ic->ic_igtk_kid]);
417		}
418		/* ask that the EAPOL-Key frame be encrypted */
419		info |= EAPOL_KEY_ENCRYPTED | EAPOL_KEY_SECURE;
420	} else	/* WPA */
421		frm = ieee80211_add_wpa(frm, ic, ic->ic_bss);
422
423	/* write the key info field */
424	BE_WRITE_2(key->info, info);
425
426	m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
427
428	if (ic->ic_if.if_flags & IFF_DEBUG)
429		printf("%s: sending msg %d/%d of the %s handshake to %s\n",
430		    ic->ic_if.if_xname, 3, 4, "4-way",
431		    ether_sprintf(ni->ni_macaddr));
432
433	return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
434}
435#endif	/* IEEE80211_STA_ONLY */
436
437/*
438 * Send 4-Way Handshake Message 4 to the authenticator.
439 */
440int
441ieee80211_send_4way_msg4(struct ieee80211com *ic, struct ieee80211_node *ni)
442{
443	struct ieee80211_eapol_key *key;
444	struct mbuf *m;
445	u_int16_t info;
446
447	ni->ni_rsn_supp_state = RSNA_SUPP_PTKDONE;
448	m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
449	if (m == NULL)
450		return ENOMEM;
451	key = mtod(m, struct ieee80211_eapol_key *);
452	memset(key, 0, sizeof(*key));
453
454	info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYMIC;
455
456	/* copy key replay counter from authenticator */
457	BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
458
459	if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
460		int keylen;
461		/* WPA sets the key length field here */
462		keylen = ieee80211_cipher_keylen(ni->ni_rsncipher);
463		BE_WRITE_2(key->keylen, keylen);
464	} else
465		info |= EAPOL_KEY_SECURE;
466
467	/* write the key info field */
468	BE_WRITE_2(key->info, info);
469
470	/* empty key data field */
471	m->m_pkthdr.len = m->m_len = sizeof(*key);
472
473	if (ic->ic_if.if_flags & IFF_DEBUG)
474		printf("%s: sending msg %d/%d of the %s handshake to %s\n",
475		    ic->ic_if.if_xname, 4, 4, "4-way",
476		    ether_sprintf(ni->ni_macaddr));
477
478	return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
479}
480
481#ifndef IEEE80211_STA_ONLY
482/*
483 * Send Group Key Handshake Message 1 to the supplicant.
484 */
485int
486ieee80211_send_group_msg1(struct ieee80211com *ic, struct ieee80211_node *ni)
487{
488	struct ieee80211_eapol_key *key;
489	const struct ieee80211_key *k;
490	struct mbuf *m;
491	u_int16_t info;
492	u_int8_t *frm;
493	u_int8_t kid;
494
495	ni->ni_rsn_gstate = RSNA_REKEYNEGOTIATING;
496	if (++ni->ni_rsn_retries > 3) {
497		IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
498		    IEEE80211_REASON_GROUP_TIMEOUT);
499		ieee80211_node_leave(ic, ni);
500		return 0;
501	}
502	if (ni->ni_flags & IEEE80211_NODE_REKEY)
503		kid = (ic->ic_def_txkey == 1) ? 2 : 1;
504	else
505		kid = ic->ic_def_txkey;
506	k = &ic->ic_nw_keys[kid];
507
508	m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
509	    ((ni->ni_rsnprotos == IEEE80211_PROTO_WPA) ?
510		k->k_len : 2 + 6 + k->k_len) +
511	    ((ni->ni_flags & IEEE80211_NODE_MFP) ? 2 + 28 : 0) +
512	    15);
513	if (m == NULL)
514		return ENOMEM;
515	key = mtod(m, struct ieee80211_eapol_key *);
516	memset(key, 0, sizeof(*key));
517
518	info = EAPOL_KEY_KEYACK | EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE |
519	    EAPOL_KEY_ENCRYPTED;
520
521	ni->ni_replaycnt++;
522	BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
523
524	frm = (u_int8_t *)&key[1];
525	if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
526		/* WPA does not have GTK KDE */
527		BE_WRITE_2(key->keylen, k->k_len);
528		memcpy(frm, k->k_key, k->k_len);
529		frm += k->k_len;
530		info |= (k->k_id & 0x3) << EAPOL_KEY_WPA_KID_SHIFT;
531		if (ni->ni_rsncipher == IEEE80211_CIPHER_USEGROUP)
532			info |= EAPOL_KEY_WPA_TX;
533	} else {	/* RSN */
534		frm = ieee80211_add_gtk_kde(frm, ni, k);
535		if (ni->ni_flags & IEEE80211_NODE_MFP) {
536			if (ni->ni_flags & IEEE80211_NODE_REKEY)
537				kid = (ic->ic_igtk_kid == 4) ? 5 : 4;
538			else
539				kid = ic->ic_igtk_kid;
540			frm = ieee80211_add_igtk_kde(frm,
541			    &ic->ic_nw_keys[kid]);
542		}
543	}
544	/* RSC = last transmit sequence number for the GTK */
545	LE_WRITE_6(key->rsc, k->k_tsc);
546
547	/* write the key info field */
548	BE_WRITE_2(key->info, info);
549
550	m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
551
552	if (ic->ic_if.if_flags & IFF_DEBUG)
553		printf("%s: sending msg %d/%d of the %s handshake to %s\n",
554		    ic->ic_if.if_xname, 1, 2, "group key",
555		    ether_sprintf(ni->ni_macaddr));
556
557	return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
558}
559#endif	/* IEEE80211_STA_ONLY */
560
561/*
562 * Send Group Key Handshake Message 2 to the authenticator.
563 */
564int
565ieee80211_send_group_msg2(struct ieee80211com *ic, struct ieee80211_node *ni,
566    const struct ieee80211_key *k)
567{
568	struct ieee80211_eapol_key *key;
569	u_int16_t info;
570	struct mbuf *m;
571
572	m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
573	if (m == NULL)
574		return ENOMEM;
575	key = mtod(m, struct ieee80211_eapol_key *);
576	memset(key, 0, sizeof(*key));
577
578	info = EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE;
579
580	/* copy key replay counter from authenticator */
581	BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
582
583	if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
584		/* WPA sets the key length and key id fields here */
585		BE_WRITE_2(key->keylen, k->k_len);
586		info |= (k->k_id & 3) << EAPOL_KEY_WPA_KID_SHIFT;
587	}
588
589	/* write the key info field */
590	BE_WRITE_2(key->info, info);
591
592	/* empty key data field */
593	m->m_pkthdr.len = m->m_len = sizeof(*key);
594
595	if (ic->ic_if.if_flags & IFF_DEBUG)
596		printf("%s: sending msg %d/%d of the %s handshake to %s\n",
597		    ic->ic_if.if_xname, 2, 2, "group key",
598		    ether_sprintf(ni->ni_macaddr));
599
600	return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
601}
602
603/*
604 * EAPOL-Key Request frames are sent by the supplicant to request that the
605 * authenticator initiates either a 4-Way Handshake or Group Key Handshake,
606 * or to report a MIC failure in a TKIP MSDU.
607 */
608int
609ieee80211_send_eapol_key_req(struct ieee80211com *ic,
610    struct ieee80211_node *ni, u_int16_t info, u_int64_t tsc)
611{
612	struct ieee80211_eapol_key *key;
613	struct mbuf *m;
614
615	m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
616	if (m == NULL)
617		return ENOMEM;
618	key = mtod(m, struct ieee80211_eapol_key *);
619	memset(key, 0, sizeof(*key));
620
621	info |= EAPOL_KEY_REQUEST;
622	BE_WRITE_2(key->info, info);
623
624	/* in case of TKIP MIC failure, fill the RSC field */
625	if (info & EAPOL_KEY_ERROR)
626		LE_WRITE_6(key->rsc, tsc);
627
628	/* use our separate key replay counter for key requests */
629	BE_WRITE_8(key->replaycnt, ni->ni_reqreplaycnt);
630	ni->ni_reqreplaycnt++;
631
632	/* empty key data field */
633	m->m_pkthdr.len = m->m_len = sizeof(*key);
634
635	if (ic->ic_if.if_flags & IFF_DEBUG)
636		printf("%s: sending EAPOL-Key request to %s\n",
637		    ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr));
638
639	return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
640}
641