Line data Source code
1 : /* $OpenBSD: ieee80211_pae_output.c,v 1.30 2017/12/21 12:09:38 mpi 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 0 : ieee80211_send_eapol_key(struct ieee80211com *ic, struct mbuf *m,
63 : struct ieee80211_node *ni, const struct ieee80211_ptk *ptk)
64 : {
65 0 : 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 0 : M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
72 0 : if (m == NULL)
73 0 : return ENOMEM;
74 : /* no need to m_pullup here (ok by construction) */
75 0 : eh = mtod(m, struct ether_header *);
76 0 : eh->ether_type = htons(ETHERTYPE_PAE);
77 0 : IEEE80211_ADDR_COPY(eh->ether_shost, ic->ic_myaddr);
78 0 : IEEE80211_ADDR_COPY(eh->ether_dhost, ni->ni_macaddr);
79 :
80 0 : key = (struct ieee80211_eapol_key *)&eh[1];
81 0 : key->version = EAPOL_VERSION;
82 0 : key->type = EAPOL_KEY;
83 0 : key->desc = (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) ?
84 : EAPOL_KEY_DESC_IEEE80211 : EAPOL_KEY_DESC_WPA;
85 :
86 0 : info = BE_READ_2(key->info);
87 : /* use V3 descriptor if KDF is SHA256-based */
88 0 : if (ieee80211_is_sha256_akm(ni->ni_rsnakms))
89 0 : info |= EAPOL_KEY_DESC_V3;
90 : /* use V2 descriptor if pairwise or group cipher is CCMP */
91 0 : else if (ni->ni_rsncipher == IEEE80211_CIPHER_CCMP ||
92 0 : ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP)
93 0 : info |= EAPOL_KEY_DESC_V2;
94 : else
95 0 : info |= EAPOL_KEY_DESC_V1;
96 0 : BE_WRITE_2(key->info, info);
97 :
98 0 : len = m->m_len - sizeof(struct ether_header);
99 0 : BE_WRITE_2(key->paylen, len - sizeof(*key));
100 0 : BE_WRITE_2(key->len, len - 4);
101 :
102 : #ifndef IEEE80211_STA_ONLY
103 0 : if (info & EAPOL_KEY_ENCRYPTED) {
104 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
105 : /* clear "Encrypted" bit for WPA */
106 0 : info &= ~EAPOL_KEY_ENCRYPTED;
107 0 : BE_WRITE_2(key->info, info);
108 0 : }
109 0 : ieee80211_eapol_key_encrypt(ic, key, ptk->kek);
110 :
111 0 : if ((info & EAPOL_KEY_VERSION_MASK) != EAPOL_KEY_DESC_V1) {
112 : /* AES Key Wrap adds 8 bytes + padding */
113 0 : m->m_pkthdr.len = m->m_len =
114 0 : sizeof(*eh) + 4 + BE_READ_2(key->len);
115 0 : }
116 : }
117 : #endif
118 0 : if (info & EAPOL_KEY_KEYMIC)
119 0 : 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 0 : if (info & EAPOL_KEY_KEYACK)
124 0 : timeout_add_msec(&ni->ni_eapol_to, 100);
125 : #endif
126 :
127 0 : IFQ_ENQUEUE(&ifp->if_snd, m, error);
128 0 : if (error)
129 0 : return (error);
130 0 : if_start(ifp);
131 0 : return 0;
132 0 : }
133 :
134 : #ifndef IEEE80211_STA_ONLY
135 : /*
136 : * Handle EAPOL-Key timeouts (no answer from supplicant).
137 : */
138 : void
139 0 : ieee80211_eapol_timeout(void *arg)
140 : {
141 0 : struct ieee80211_node *ni = arg;
142 0 : 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 0 : s = splnet();
149 :
150 0 : switch (ni->ni_rsn_state) {
151 : case RSNA_PTKSTART:
152 : case RSNA_PTKCALCNEGOTIATING:
153 0 : (void)ieee80211_send_4way_msg1(ic, ni);
154 0 : break;
155 : case RSNA_PTKINITNEGOTIATING:
156 0 : (void)ieee80211_send_4way_msg3(ic, ni);
157 0 : break;
158 : }
159 :
160 0 : switch (ni->ni_rsn_gstate) {
161 : case RSNA_REKEYNEGOTIATING:
162 0 : (void)ieee80211_send_group_msg1(ic, ni);
163 0 : break;
164 : }
165 :
166 0 : splx(s);
167 0 : }
168 :
169 : /*
170 : * Add a GTK KDE to an EAPOL-Key frame (see Figure 144).
171 : */
172 : u_int8_t *
173 0 : ieee80211_add_gtk_kde(u_int8_t *frm, struct ieee80211_node *ni,
174 : const struct ieee80211_key *k)
175 : {
176 0 : KASSERT(k->k_flags & IEEE80211_KEY_GROUP);
177 :
178 0 : *frm++ = IEEE80211_ELEMID_VENDOR;
179 0 : *frm++ = 6 + k->k_len;
180 0 : memcpy(frm, IEEE80211_OUI, 3); frm += 3;
181 0 : *frm++ = IEEE80211_KDE_GTK;
182 0 : *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 0 : if (ni->ni_rsncipher == IEEE80211_CIPHER_USEGROUP)
188 0 : *frm |= 1 << 2; /* set the Tx bit */
189 0 : frm++;
190 0 : *frm++ = 0; /* reserved */
191 0 : memcpy(frm, k->k_key, k->k_len);
192 0 : 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 0 : ieee80211_add_pmkid_kde(u_int8_t *frm, const u_int8_t *pmkid)
200 : {
201 0 : *frm++ = IEEE80211_ELEMID_VENDOR;
202 0 : *frm++ = 20;
203 0 : memcpy(frm, IEEE80211_OUI, 3); frm += 3;
204 0 : *frm++ = IEEE80211_KDE_PMKID;
205 0 : memcpy(frm, pmkid, IEEE80211_PMKID_LEN);
206 0 : 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 0 : ieee80211_add_igtk_kde(u_int8_t *frm, const struct ieee80211_key *k)
214 : {
215 0 : KASSERT(k->k_flags & IEEE80211_KEY_IGTK);
216 :
217 0 : *frm++ = IEEE80211_ELEMID_VENDOR;
218 0 : *frm++ = 4 + 24;
219 0 : memcpy(frm, IEEE80211_OUI, 3); frm += 3;
220 0 : *frm++ = IEEE80211_KDE_IGTK;
221 0 : LE_WRITE_2(frm, k->k_id); frm += 2;
222 0 : LE_WRITE_6(frm, k->k_tsc); frm += 6; /* IPN */
223 0 : memcpy(frm, k->k_key, 16);
224 0 : return frm + 16;
225 : }
226 : #endif /* IEEE80211_STA_ONLY */
227 :
228 : struct mbuf *
229 0 : 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 0 : pktlen += sizeof(struct ieee80211_frame) + LLC_SNAPFRAMELEN +
235 : sizeof(struct ieee80211_eapol_key);
236 :
237 0 : if (pktlen > MCLBYTES)
238 0 : panic("EAPOL-Key frame too large: %u", pktlen);
239 0 : MGETHDR(m, flags, type);
240 0 : if (m == NULL)
241 0 : return NULL;
242 0 : if (pktlen > MHLEN) {
243 0 : MCLGET(m, flags);
244 0 : if (!(m->m_flags & M_EXT))
245 0 : return m_free(m);
246 : }
247 0 : m->m_data += sizeof(struct ieee80211_frame) + LLC_SNAPFRAMELEN;
248 0 : return m;
249 0 : }
250 :
251 : #ifndef IEEE80211_STA_ONLY
252 : /*
253 : * Send 4-Way Handshake Message 1 to the supplicant.
254 : */
255 : int
256 0 : 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 0 : ni->ni_rsn_state = RSNA_PTKSTART;
264 0 : if (++ni->ni_rsn_retries > 3) {
265 0 : IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
266 : IEEE80211_REASON_4WAY_TIMEOUT);
267 0 : ieee80211_node_leave(ic, ni);
268 0 : return 0;
269 : }
270 0 : m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
271 0 : (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) ? 2 + 20 : 0);
272 0 : if (m == NULL)
273 0 : return ENOMEM;
274 0 : key = mtod(m, struct ieee80211_eapol_key *);
275 0 : memset(key, 0, sizeof(*key));
276 :
277 : info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYACK;
278 0 : BE_WRITE_2(key->info, info);
279 :
280 : /* copy the authenticator's nonce (ANonce) */
281 0 : memcpy(key->nonce, ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
282 :
283 0 : keylen = ieee80211_cipher_keylen(ni->ni_rsncipher);
284 0 : BE_WRITE_2(key->keylen, keylen);
285 :
286 0 : frm = (u_int8_t *)&key[1];
287 : /* NB: WPA does not have PMKID KDE */
288 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_RSN &&
289 0 : ieee80211_is_8021x_akm(ni->ni_rsnakms))
290 0 : frm = ieee80211_add_pmkid_kde(frm, ni->ni_pmkid);
291 :
292 0 : m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
293 :
294 0 : if (ic->ic_if.if_flags & IFF_DEBUG)
295 0 : printf("%s: sending msg %d/%d of the %s handshake to %s\n",
296 0 : ic->ic_if.if_xname, 1, 4, "4-way",
297 0 : ether_sprintf(ni->ni_macaddr));
298 :
299 0 : ni->ni_replaycnt++;
300 0 : BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
301 :
302 0 : return ieee80211_send_eapol_key(ic, m, ni, NULL);
303 0 : }
304 : #endif /* IEEE80211_STA_ONLY */
305 :
306 : /*
307 : * Send 4-Way Handshake Message 2 to the authenticator.
308 : */
309 : int
310 0 : 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 0 : ni->ni_rsn_supp_state = RSNA_SUPP_PTKNEGOTIATING;
319 0 : m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
320 0 : (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) ?
321 : 2 + IEEE80211_WPAIE_MAXLEN :
322 : 2 + IEEE80211_RSNIE_MAXLEN);
323 0 : if (m == NULL)
324 0 : return ENOMEM;
325 0 : key = mtod(m, struct ieee80211_eapol_key *);
326 0 : memset(key, 0, sizeof(*key));
327 :
328 : info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYMIC;
329 0 : BE_WRITE_2(key->info, info);
330 :
331 : /* copy key replay counter from Message 1/4 */
332 0 : memcpy(key->replaycnt, replaycnt, 8);
333 :
334 : /* copy the supplicant's nonce (SNonce) */
335 0 : memcpy(key->nonce, ic->ic_nonce, EAPOL_KEY_NONCE_LEN);
336 :
337 0 : frm = (u_int8_t *)&key[1];
338 : /* add the WPA/RSN IE used in the (Re)Association Request */
339 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
340 : int keylen;
341 0 : frm = ieee80211_add_wpa(frm, ic, ni);
342 : /* WPA sets the key length field here */
343 0 : keylen = ieee80211_cipher_keylen(ni->ni_rsncipher);
344 0 : BE_WRITE_2(key->keylen, keylen);
345 0 : } else /* RSN */
346 0 : frm = ieee80211_add_rsn(frm, ic, ni);
347 :
348 0 : m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
349 :
350 0 : if (ic->ic_if.if_flags & IFF_DEBUG)
351 0 : printf("%s: sending msg %d/%d of the %s handshake to %s\n",
352 0 : ic->ic_if.if_xname, 2, 4, "4-way",
353 0 : ether_sprintf(ni->ni_macaddr));
354 :
355 0 : return ieee80211_send_eapol_key(ic, m, ni, tptk);
356 0 : }
357 :
358 : #ifndef IEEE80211_STA_ONLY
359 : /*
360 : * Send 4-Way Handshake Message 3 to the supplicant.
361 : */
362 : int
363 0 : 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 0 : ni->ni_rsn_state = RSNA_PTKINITNEGOTIATING;
372 0 : if (++ni->ni_rsn_retries > 3) {
373 0 : IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
374 : IEEE80211_REASON_4WAY_TIMEOUT);
375 0 : ieee80211_node_leave(ic, ni);
376 0 : return 0;
377 : }
378 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) {
379 0 : k = &ic->ic_nw_keys[ic->ic_def_txkey];
380 0 : m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
381 0 : 2 + IEEE80211_RSNIE_MAXLEN + 2 + 6 + k->k_len + 15 +
382 0 : ((ni->ni_flags & IEEE80211_NODE_MFP) ? 2 + 28 : 0));
383 0 : } else { /* WPA */
384 0 : m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
385 0 : 2 + IEEE80211_WPAIE_MAXLEN +
386 0 : ((ni->ni_flags & IEEE80211_NODE_MFP) ? 2 + 28 : 0));
387 : }
388 0 : if (m == NULL)
389 0 : return ENOMEM;
390 0 : key = mtod(m, struct ieee80211_eapol_key *);
391 0 : memset(key, 0, sizeof(*key));
392 :
393 : info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYACK | EAPOL_KEY_KEYMIC;
394 0 : if (ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP)
395 0 : info |= EAPOL_KEY_INSTALL;
396 :
397 : /* use same nonce as in Message 1 */
398 0 : memcpy(key->nonce, ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
399 :
400 0 : ni->ni_replaycnt++;
401 0 : BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
402 :
403 0 : keylen = ieee80211_cipher_keylen(ni->ni_rsncipher);
404 0 : BE_WRITE_2(key->keylen, keylen);
405 :
406 0 : frm = (u_int8_t *)&key[1];
407 : /* add the WPA/RSN IE included in Beacon/Probe Response */
408 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) {
409 0 : frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
410 : /* encapsulate the GTK */
411 0 : frm = ieee80211_add_gtk_kde(frm, ni, k);
412 0 : LE_WRITE_6(key->rsc, k->k_tsc);
413 : /* encapsulate the IGTK if MFP was negotiated */
414 0 : if (ni->ni_flags & IEEE80211_NODE_MFP) {
415 0 : frm = ieee80211_add_igtk_kde(frm,
416 0 : &ic->ic_nw_keys[ic->ic_igtk_kid]);
417 0 : }
418 : /* ask that the EAPOL-Key frame be encrypted */
419 0 : info |= EAPOL_KEY_ENCRYPTED | EAPOL_KEY_SECURE;
420 0 : } else /* WPA */
421 0 : frm = ieee80211_add_wpa(frm, ic, ic->ic_bss);
422 :
423 : /* write the key info field */
424 0 : BE_WRITE_2(key->info, info);
425 :
426 0 : m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
427 :
428 0 : if (ic->ic_if.if_flags & IFF_DEBUG)
429 0 : printf("%s: sending msg %d/%d of the %s handshake to %s\n",
430 0 : ic->ic_if.if_xname, 3, 4, "4-way",
431 0 : ether_sprintf(ni->ni_macaddr));
432 :
433 0 : return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
434 0 : }
435 : #endif /* IEEE80211_STA_ONLY */
436 :
437 : /*
438 : * Send 4-Way Handshake Message 4 to the authenticator.
439 : */
440 : int
441 0 : 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 0 : ni->ni_rsn_supp_state = RNSA_SUPP_PTKDONE;
448 0 : m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
449 0 : if (m == NULL)
450 0 : return ENOMEM;
451 0 : key = mtod(m, struct ieee80211_eapol_key *);
452 0 : memset(key, 0, sizeof(*key));
453 :
454 : info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYMIC;
455 :
456 : /* copy key replay counter from authenticator */
457 0 : BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
458 :
459 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
460 : int keylen;
461 : /* WPA sets the key length field here */
462 0 : keylen = ieee80211_cipher_keylen(ni->ni_rsncipher);
463 0 : BE_WRITE_2(key->keylen, keylen);
464 0 : } else
465 : info |= EAPOL_KEY_SECURE;
466 :
467 : /* write the key info field */
468 0 : BE_WRITE_2(key->info, info);
469 :
470 : /* empty key data field */
471 0 : m->m_pkthdr.len = m->m_len = sizeof(*key);
472 :
473 0 : if (ic->ic_if.if_flags & IFF_DEBUG)
474 0 : printf("%s: sending msg %d/%d of the %s handshake to %s\n",
475 0 : ic->ic_if.if_xname, 4, 4, "4-way",
476 0 : ether_sprintf(ni->ni_macaddr));
477 :
478 0 : return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
479 0 : }
480 :
481 : #ifndef IEEE80211_STA_ONLY
482 : /*
483 : * Send Group Key Handshake Message 1 to the supplicant.
484 : */
485 : int
486 0 : 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 0 : ni->ni_rsn_gstate = RSNA_REKEYNEGOTIATING;
496 0 : if (++ni->ni_rsn_retries > 3) {
497 0 : IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
498 : IEEE80211_REASON_GROUP_TIMEOUT);
499 0 : ieee80211_node_leave(ic, ni);
500 0 : return 0;
501 : }
502 0 : if (ni->ni_flags & IEEE80211_NODE_REKEY)
503 0 : kid = (ic->ic_def_txkey == 1) ? 2 : 1;
504 : else
505 0 : kid = ic->ic_def_txkey;
506 0 : k = &ic->ic_nw_keys[kid];
507 :
508 0 : m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
509 0 : ((ni->ni_rsnprotos == IEEE80211_PROTO_WPA) ?
510 0 : k->k_len : 2 + 6 + k->k_len) +
511 0 : ((ni->ni_flags & IEEE80211_NODE_MFP) ? 2 + 28 : 0) +
512 : 15);
513 0 : if (m == NULL)
514 0 : return ENOMEM;
515 0 : key = mtod(m, struct ieee80211_eapol_key *);
516 0 : memset(key, 0, sizeof(*key));
517 :
518 : info = EAPOL_KEY_KEYACK | EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE |
519 : EAPOL_KEY_ENCRYPTED;
520 :
521 0 : ni->ni_replaycnt++;
522 0 : BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
523 :
524 0 : frm = (u_int8_t *)&key[1];
525 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
526 : /* WPA does not have GTK KDE */
527 0 : BE_WRITE_2(key->keylen, k->k_len);
528 0 : memcpy(frm, k->k_key, k->k_len);
529 0 : frm += k->k_len;
530 0 : info |= (k->k_id & 0x3) << EAPOL_KEY_WPA_KID_SHIFT;
531 0 : if (ni->ni_rsncipher == IEEE80211_CIPHER_USEGROUP)
532 0 : info |= EAPOL_KEY_WPA_TX;
533 : } else { /* RSN */
534 0 : frm = ieee80211_add_gtk_kde(frm, ni, k);
535 0 : if (ni->ni_flags & IEEE80211_NODE_MFP) {
536 0 : if (ni->ni_flags & IEEE80211_NODE_REKEY)
537 0 : kid = (ic->ic_igtk_kid == 4) ? 5 : 4;
538 : else
539 0 : kid = ic->ic_igtk_kid;
540 0 : frm = ieee80211_add_igtk_kde(frm,
541 0 : &ic->ic_nw_keys[kid]);
542 0 : }
543 : }
544 : /* RSC = last transmit sequence number for the GTK */
545 0 : LE_WRITE_6(key->rsc, k->k_tsc);
546 :
547 : /* write the key info field */
548 0 : BE_WRITE_2(key->info, info);
549 :
550 0 : m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
551 :
552 0 : if (ic->ic_if.if_flags & IFF_DEBUG)
553 0 : printf("%s: sending msg %d/%d of the %s handshake to %s\n",
554 0 : ic->ic_if.if_xname, 1, 2, "group key",
555 0 : ether_sprintf(ni->ni_macaddr));
556 :
557 0 : return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
558 0 : }
559 : #endif /* IEEE80211_STA_ONLY */
560 :
561 : /*
562 : * Send Group Key Handshake Message 2 to the authenticator.
563 : */
564 : int
565 0 : 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 0 : m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
573 0 : if (m == NULL)
574 0 : return ENOMEM;
575 0 : key = mtod(m, struct ieee80211_eapol_key *);
576 0 : memset(key, 0, sizeof(*key));
577 :
578 : info = EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE;
579 :
580 : /* copy key replay counter from authenticator */
581 0 : BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
582 :
583 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
584 : /* WPA sets the key length and key id fields here */
585 0 : BE_WRITE_2(key->keylen, k->k_len);
586 0 : info |= (k->k_id & 3) << EAPOL_KEY_WPA_KID_SHIFT;
587 0 : }
588 :
589 : /* write the key info field */
590 0 : BE_WRITE_2(key->info, info);
591 :
592 : /* empty key data field */
593 0 : m->m_pkthdr.len = m->m_len = sizeof(*key);
594 :
595 0 : if (ic->ic_if.if_flags & IFF_DEBUG)
596 0 : printf("%s: sending msg %d/%d of the %s handshake to %s\n",
597 0 : ic->ic_if.if_xname, 2, 2, "group key",
598 0 : ether_sprintf(ni->ni_macaddr));
599 :
600 0 : return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
601 0 : }
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 0 : 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 0 : m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
616 0 : if (m == NULL)
617 0 : return ENOMEM;
618 0 : key = mtod(m, struct ieee80211_eapol_key *);
619 0 : memset(key, 0, sizeof(*key));
620 :
621 0 : info |= EAPOL_KEY_REQUEST;
622 0 : BE_WRITE_2(key->info, info);
623 :
624 : /* in case of TKIP MIC failure, fill the RSC field */
625 0 : if (info & EAPOL_KEY_ERROR)
626 0 : LE_WRITE_6(key->rsc, tsc);
627 :
628 : /* use our separate key replay counter for key requests */
629 0 : BE_WRITE_8(key->replaycnt, ni->ni_reqreplaycnt);
630 0 : ni->ni_reqreplaycnt++;
631 :
632 : /* empty key data field */
633 0 : m->m_pkthdr.len = m->m_len = sizeof(*key);
634 :
635 0 : if (ic->ic_if.if_flags & IFF_DEBUG)
636 0 : printf("%s: sending EAPOL-Key request to %s\n",
637 0 : ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr));
638 :
639 0 : return ieee80211_send_eapol_key(ic, m, ni, &ni->ni_ptk);
640 0 : }
|