xref: /haiku/src/libs/compat/openbsd_wlan/net80211/ieee80211_pae_output.c (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
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 
46 int		ieee80211_send_eapol_key(struct ieee80211com *, struct mbuf *,
47 		    struct ieee80211_node *, const struct ieee80211_ptk *);
48 #ifndef IEEE80211_STA_ONLY
49 u_int8_t	*ieee80211_add_gtk_kde(u_int8_t *, struct ieee80211_node *,
50 		    const struct ieee80211_key *);
51 u_int8_t	*ieee80211_add_pmkid_kde(u_int8_t *, const u_int8_t *);
52 u_int8_t	*ieee80211_add_igtk_kde(u_int8_t *,
53 		    const struct ieee80211_key *);
54 #endif
55 struct 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  */
61 int
62 ieee80211_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  */
138 void
139 ieee80211_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  */
172 u_int8_t *
173 ieee80211_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  */
198 u_int8_t *
199 ieee80211_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  */
212 u_int8_t *
213 ieee80211_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 
228 struct mbuf *
229 ieee80211_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  */
255 int
256 ieee80211_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  */
309 int
310 ieee80211_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  */
362 int
363 ieee80211_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  */
440 int
441 ieee80211_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  */
485 int
486 ieee80211_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  */
564 int
565 ieee80211_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  */
608 int
609 ieee80211_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