xref: /openbsd/sys/net80211/ieee80211_crypto.c (revision 3d8817e4)
1 /*	$OpenBSD: ieee80211_crypto.c,v 1.60 2011/01/11 15:42:05 deraadt Exp $	*/
2 
3 /*-
4  * Copyright (c) 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 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/mbuf.h>
22 #include <sys/malloc.h>
23 #include <sys/kernel.h>
24 #include <sys/socket.h>
25 #include <sys/sockio.h>
26 #include <sys/endian.h>
27 #include <sys/errno.h>
28 #include <sys/proc.h>
29 #include <sys/sysctl.h>
30 
31 #include <net/if.h>
32 #include <net/if_dl.h>
33 #include <net/if_media.h>
34 #include <net/if_arp.h>
35 #include <net/if_llc.h>
36 
37 #ifdef INET
38 #include <netinet/in.h>
39 #include <netinet/if_ether.h>
40 #endif
41 
42 #include <net80211/ieee80211_var.h>
43 #include <net80211/ieee80211_priv.h>
44 
45 #include <dev/rndvar.h>
46 #include <crypto/arc4.h>
47 #include <crypto/md5.h>
48 #include <crypto/sha1.h>
49 #include <crypto/sha2.h>
50 #include <crypto/hmac.h>
51 #include <crypto/rijndael.h>
52 #include <crypto/cmac.h>
53 #include <crypto/key_wrap.h>
54 
55 void	ieee80211_prf(const u_int8_t *, size_t, const u_int8_t *, size_t,
56 	    const u_int8_t *, size_t, u_int8_t *, size_t);
57 void	ieee80211_kdf(const u_int8_t *, size_t, const u_int8_t *, size_t,
58 	    const u_int8_t *, size_t, u_int8_t *, size_t);
59 void	ieee80211_derive_pmkid(enum ieee80211_akm, const u_int8_t *,
60 	    const u_int8_t *, const u_int8_t *, u_int8_t *);
61 
62 void
63 ieee80211_crypto_attach(struct ifnet *ifp)
64 {
65 	struct ieee80211com *ic = (void *)ifp;
66 
67 	TAILQ_INIT(&ic->ic_pmksa);
68 	if (ic->ic_caps & IEEE80211_C_RSN) {
69 		ic->ic_rsnprotos = IEEE80211_PROTO_WPA | IEEE80211_PROTO_RSN;
70 		ic->ic_rsnakms = IEEE80211_AKM_PSK;
71 		ic->ic_rsnciphers = IEEE80211_CIPHER_TKIP |
72 		    IEEE80211_CIPHER_CCMP;
73 		ic->ic_rsngroupcipher = IEEE80211_CIPHER_TKIP;
74 		ic->ic_rsngroupmgmtcipher = IEEE80211_CIPHER_BIP;
75 	}
76 	ic->ic_set_key = ieee80211_set_key;
77 	ic->ic_delete_key = ieee80211_delete_key;
78 }
79 
80 void
81 ieee80211_crypto_detach(struct ifnet *ifp)
82 {
83 	struct ieee80211com *ic = (void *)ifp;
84 	struct ieee80211_pmk *pmk;
85 	int i;
86 
87 	/* purge the PMKSA cache */
88 	while ((pmk = TAILQ_FIRST(&ic->ic_pmksa)) != NULL) {
89 		TAILQ_REMOVE(&ic->ic_pmksa, pmk, pmk_next);
90 		explicit_bzero(pmk, sizeof(*pmk));
91 		free(pmk, M_DEVBUF);
92 	}
93 
94 	/* clear all group keys from memory */
95 	for (i = 0; i < IEEE80211_GROUP_NKID; i++) {
96 		struct ieee80211_key *k = &ic->ic_nw_keys[i];
97 		if (k->k_cipher != IEEE80211_CIPHER_NONE)
98 			(*ic->ic_delete_key)(ic, NULL, k);
99 		explicit_bzero(k, sizeof(*k));
100 	}
101 
102 	/* clear pre-shared key from memory */
103 	explicit_bzero(ic->ic_psk, IEEE80211_PMK_LEN);
104 }
105 
106 /*
107  * Return the length in bytes of a cipher suite key (see Table 60).
108  */
109 int
110 ieee80211_cipher_keylen(enum ieee80211_cipher cipher)
111 {
112 	switch (cipher) {
113 	case IEEE80211_CIPHER_WEP40:
114 		return 5;
115 	case IEEE80211_CIPHER_TKIP:
116 		return 32;
117 	case IEEE80211_CIPHER_CCMP:
118 		return 16;
119 	case IEEE80211_CIPHER_WEP104:
120 		return 13;
121 	case IEEE80211_CIPHER_BIP:
122 		return 16;
123 	default:	/* unknown cipher */
124 		return 0;
125 	}
126 }
127 
128 int
129 ieee80211_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
130     struct ieee80211_key *k)
131 {
132 	int error;
133 
134 	switch (k->k_cipher) {
135 	case IEEE80211_CIPHER_WEP40:
136 	case IEEE80211_CIPHER_WEP104:
137 		error = ieee80211_wep_set_key(ic, k);
138 		break;
139 	case IEEE80211_CIPHER_TKIP:
140 		error = ieee80211_tkip_set_key(ic, k);
141 		break;
142 	case IEEE80211_CIPHER_CCMP:
143 		error = ieee80211_ccmp_set_key(ic, k);
144 		break;
145 	case IEEE80211_CIPHER_BIP:
146 		error = ieee80211_bip_set_key(ic, k);
147 		break;
148 	default:
149 		/* should not get there */
150 		error = EINVAL;
151 	}
152 	return error;
153 }
154 
155 void
156 ieee80211_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
157     struct ieee80211_key *k)
158 {
159 	switch (k->k_cipher) {
160 	case IEEE80211_CIPHER_WEP40:
161 	case IEEE80211_CIPHER_WEP104:
162 		ieee80211_wep_delete_key(ic, k);
163 		break;
164 	case IEEE80211_CIPHER_TKIP:
165 		ieee80211_tkip_delete_key(ic, k);
166 		break;
167 	case IEEE80211_CIPHER_CCMP:
168 		ieee80211_ccmp_delete_key(ic, k);
169 		break;
170 	case IEEE80211_CIPHER_BIP:
171 		ieee80211_bip_delete_key(ic, k);
172 		break;
173 	default:
174 		/* should not get there */
175 		break;
176 	}
177 	explicit_bzero(k, sizeof(*k));
178 }
179 
180 struct ieee80211_key *
181 ieee80211_get_txkey(struct ieee80211com *ic, const struct ieee80211_frame *wh,
182     struct ieee80211_node *ni)
183 {
184 	int kid;
185 
186 	if ((ic->ic_flags & IEEE80211_F_RSNON) &&
187 	    !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
188 	    ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP)
189 		return &ni->ni_pairwise_key;
190 
191 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) ||
192 	    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
193 	    IEEE80211_FC0_TYPE_MGT)
194 		kid = ic->ic_def_txkey;
195 	else
196 		kid = ic->ic_igtk_kid;
197 	return &ic->ic_nw_keys[kid];
198 }
199 
200 struct mbuf *
201 ieee80211_encrypt(struct ieee80211com *ic, struct mbuf *m0,
202     struct ieee80211_key *k)
203 {
204 	switch (k->k_cipher) {
205 	case IEEE80211_CIPHER_WEP40:
206 	case IEEE80211_CIPHER_WEP104:
207 		m0 = ieee80211_wep_encrypt(ic, m0, k);
208 		break;
209 	case IEEE80211_CIPHER_TKIP:
210 		m0 = ieee80211_tkip_encrypt(ic, m0, k);
211 		break;
212 	case IEEE80211_CIPHER_CCMP:
213 		m0 = ieee80211_ccmp_encrypt(ic, m0, k);
214 		break;
215 	case IEEE80211_CIPHER_BIP:
216 		m0 = ieee80211_bip_encap(ic, m0, k);
217 		break;
218 	default:
219 		/* should not get there */
220 		m_freem(m0);
221 		m0 = NULL;
222 	}
223 	return m0;
224 }
225 
226 struct mbuf *
227 ieee80211_decrypt(struct ieee80211com *ic, struct mbuf *m0,
228     struct ieee80211_node *ni)
229 {
230 	struct ieee80211_frame *wh;
231 	struct ieee80211_key *k;
232 	u_int8_t *ivp, *mmie;
233 	u_int16_t kid;
234 	int hdrlen;
235 
236 	/* find key for decryption */
237 	wh = mtod(m0, struct ieee80211_frame *);
238 	if ((ic->ic_flags & IEEE80211_F_RSNON) &&
239 	    !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
240 	    ni->ni_rsncipher != IEEE80211_CIPHER_USEGROUP) {
241 		k = &ni->ni_pairwise_key;
242 
243 	} else if (!IEEE80211_IS_MULTICAST(wh->i_addr1) ||
244 	    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
245 	    IEEE80211_FC0_TYPE_MGT) {
246 		/* retrieve group data key id from IV field */
247 		hdrlen = ieee80211_get_hdrlen(wh);
248 		/* check that IV field is present */
249 		if (m0->m_len < hdrlen + 4) {
250 			m_freem(m0);
251 			return NULL;
252 		}
253 		ivp = (u_int8_t *)wh + hdrlen;
254 		kid = ivp[3] >> 6;
255 		k = &ic->ic_nw_keys[kid];
256 	} else {
257 		/* retrieve integrity group key id from MMIE */
258 		if (m0->m_len < sizeof(*wh) + IEEE80211_MMIE_LEN) {
259 			m_freem(m0);
260 			return NULL;
261 		}
262 		/* it is assumed management frames are contiguous */
263 		mmie = (u_int8_t *)wh + m0->m_len - IEEE80211_MMIE_LEN;
264 		/* check that MMIE is valid */
265 		if (mmie[0] != IEEE80211_ELEMID_MMIE || mmie[1] != 16) {
266 			m_freem(m0);
267 			return NULL;
268 		}
269 		kid = LE_READ_2(&mmie[2]);
270 		if (kid != 4 && kid != 5) {
271 			m_freem(m0);
272 			return NULL;
273 		}
274 		k = &ic->ic_nw_keys[kid];
275 	}
276 	switch (k->k_cipher) {
277 	case IEEE80211_CIPHER_WEP40:
278 	case IEEE80211_CIPHER_WEP104:
279 		m0 = ieee80211_wep_decrypt(ic, m0, k);
280 		break;
281 	case IEEE80211_CIPHER_TKIP:
282 		m0 = ieee80211_tkip_decrypt(ic, m0, k);
283 		break;
284 	case IEEE80211_CIPHER_CCMP:
285 		m0 = ieee80211_ccmp_decrypt(ic, m0, k);
286 		break;
287 	case IEEE80211_CIPHER_BIP:
288 		m0 = ieee80211_bip_decap(ic, m0, k);
289 		break;
290 	default:
291 		/* key not defined */
292 		m_freem(m0);
293 		m0 = NULL;
294 	}
295 	return m0;
296 }
297 
298 /*
299  * SHA1-based Pseudo-Random Function (see 8.5.1.1).
300  */
301 void
302 ieee80211_prf(const u_int8_t *key, size_t key_len, const u_int8_t *label,
303     size_t label_len, const u_int8_t *context, size_t context_len,
304     u_int8_t *output, size_t len)
305 {
306 	HMAC_SHA1_CTX ctx;
307 	u_int8_t digest[SHA1_DIGEST_LENGTH];
308 	u_int8_t count;
309 
310 	for (count = 0; len != 0; count++) {
311 		HMAC_SHA1_Init(&ctx, key, key_len);
312 		HMAC_SHA1_Update(&ctx, label, label_len);
313 		HMAC_SHA1_Update(&ctx, context, context_len);
314 		HMAC_SHA1_Update(&ctx, &count, 1);
315 		if (len < SHA1_DIGEST_LENGTH) {
316 			HMAC_SHA1_Final(digest, &ctx);
317 			/* truncate HMAC-SHA1 to len bytes */
318 			memcpy(output, digest, len);
319 			break;
320 		}
321 		HMAC_SHA1_Final(output, &ctx);
322 		output += SHA1_DIGEST_LENGTH;
323 		len -= SHA1_DIGEST_LENGTH;
324 	}
325 }
326 
327 /*
328  * SHA256-based Key Derivation Function (see 8.5.1.5.2).
329  */
330 void
331 ieee80211_kdf(const u_int8_t *key, size_t key_len, const u_int8_t *label,
332     size_t label_len, const u_int8_t *context, size_t context_len,
333     u_int8_t *output, size_t len)
334 {
335 	HMAC_SHA256_CTX ctx;
336 	u_int8_t digest[SHA256_DIGEST_LENGTH];
337 	u_int16_t i, iter, length;
338 
339 	length = htole16(len * NBBY);
340 	for (i = 1; len != 0; i++) {
341 		HMAC_SHA256_Init(&ctx, key, key_len);
342 		iter = htole16(i);
343 		HMAC_SHA256_Update(&ctx, (u_int8_t *)&iter, sizeof iter);
344 		HMAC_SHA256_Update(&ctx, label, label_len);
345 		HMAC_SHA256_Update(&ctx, context, context_len);
346 		HMAC_SHA256_Update(&ctx, (u_int8_t *)&length, sizeof length);
347 		if (len < SHA256_DIGEST_LENGTH) {
348 			HMAC_SHA256_Final(digest, &ctx);
349 			/* truncate HMAC-SHA-256 to len bytes */
350 			memcpy(output, digest, len);
351 			break;
352 		}
353 		HMAC_SHA256_Final(output, &ctx);
354 		output += SHA256_DIGEST_LENGTH;
355 		len -= SHA256_DIGEST_LENGTH;
356 	}
357 }
358 
359 /*
360  * Derive Pairwise Transient Key (PTK) (see 8.5.1.2).
361  */
362 void
363 ieee80211_derive_ptk(enum ieee80211_akm akm, const u_int8_t *pmk,
364     const u_int8_t *aa, const u_int8_t *spa, const u_int8_t *anonce,
365     const u_int8_t *snonce, struct ieee80211_ptk *ptk)
366 {
367 	void (*kdf)(const u_int8_t *, size_t, const u_int8_t *, size_t,
368 	    const u_int8_t *, size_t, u_int8_t *, size_t);
369 	u_int8_t buf[2 * IEEE80211_ADDR_LEN + 2 * EAPOL_KEY_NONCE_LEN];
370 	int ret;
371 
372 	/* Min(AA,SPA) || Max(AA,SPA) */
373 	ret = memcmp(aa, spa, IEEE80211_ADDR_LEN) < 0;
374 	memcpy(&buf[ 0], ret ? aa : spa, IEEE80211_ADDR_LEN);
375 	memcpy(&buf[ 6], ret ? spa : aa, IEEE80211_ADDR_LEN);
376 
377 	/* Min(ANonce,SNonce) || Max(ANonce,SNonce) */
378 	ret = memcmp(anonce, snonce, EAPOL_KEY_NONCE_LEN) < 0;
379 	memcpy(&buf[12], ret ? anonce : snonce, EAPOL_KEY_NONCE_LEN);
380 	memcpy(&buf[44], ret ? snonce : anonce, EAPOL_KEY_NONCE_LEN);
381 
382 	kdf = ieee80211_is_sha256_akm(akm) ? ieee80211_kdf : ieee80211_prf;
383 	(*kdf)(pmk, IEEE80211_PMK_LEN, "Pairwise key expansion", 23,
384 	    buf, sizeof buf, (u_int8_t *)ptk, sizeof(*ptk));
385 }
386 
387 static void
388 ieee80211_pmkid_sha1(const u_int8_t *pmk, const u_int8_t *aa,
389     const u_int8_t *spa, u_int8_t *pmkid)
390 {
391 	HMAC_SHA1_CTX ctx;
392 	u_int8_t digest[SHA1_DIGEST_LENGTH];
393 
394 	HMAC_SHA1_Init(&ctx, pmk, IEEE80211_PMK_LEN);
395 	HMAC_SHA1_Update(&ctx, "PMK Name", 8);
396 	HMAC_SHA1_Update(&ctx, aa, IEEE80211_ADDR_LEN);
397 	HMAC_SHA1_Update(&ctx, spa, IEEE80211_ADDR_LEN);
398 	HMAC_SHA1_Final(digest, &ctx);
399 	/* use the first 128 bits of HMAC-SHA1 */
400 	memcpy(pmkid, digest, IEEE80211_PMKID_LEN);
401 }
402 
403 static void
404 ieee80211_pmkid_sha256(const u_int8_t *pmk, const u_int8_t *aa,
405     const u_int8_t *spa, u_int8_t *pmkid)
406 {
407 	HMAC_SHA256_CTX ctx;
408 	u_int8_t digest[SHA256_DIGEST_LENGTH];
409 
410 	HMAC_SHA256_Init(&ctx, pmk, IEEE80211_PMK_LEN);
411 	HMAC_SHA256_Update(&ctx, "PMK Name", 8);
412 	HMAC_SHA256_Update(&ctx, aa, IEEE80211_ADDR_LEN);
413 	HMAC_SHA256_Update(&ctx, spa, IEEE80211_ADDR_LEN);
414 	HMAC_SHA256_Final(digest, &ctx);
415 	/* use the first 128 bits of HMAC-SHA-256 */
416 	memcpy(pmkid, digest, IEEE80211_PMKID_LEN);
417 }
418 
419 /*
420  * Derive Pairwise Master Key Identifier (PMKID) (see 8.5.1.2).
421  */
422 void
423 ieee80211_derive_pmkid(enum ieee80211_akm akm, const u_int8_t *pmk,
424     const u_int8_t *aa, const u_int8_t *spa, u_int8_t *pmkid)
425 {
426 	if (ieee80211_is_sha256_akm(akm))
427 		ieee80211_pmkid_sha256(pmk, aa, spa, pmkid);
428 	else
429 		ieee80211_pmkid_sha1(pmk, aa, spa, pmkid);
430 }
431 
432 typedef union _ANY_CTX {
433 	HMAC_MD5_CTX	md5;
434 	HMAC_SHA1_CTX	sha1;
435 	AES_CMAC_CTX	cmac;
436 } ANY_CTX;
437 
438 /*
439  * Compute the Key MIC field of an EAPOL-Key frame using the specified Key
440  * Confirmation Key (KCK).  The hash function can be HMAC-MD5, HMAC-SHA1
441  * or AES-128-CMAC depending on the EAPOL-Key Key Descriptor Version.
442  */
443 void
444 ieee80211_eapol_key_mic(struct ieee80211_eapol_key *key, const u_int8_t *kck)
445 {
446 	u_int8_t digest[SHA1_DIGEST_LENGTH];
447 	ANY_CTX ctx;	/* XXX off stack? */
448 	u_int len;
449 
450 	len = BE_READ_2(key->len) + 4;
451 
452 	switch (BE_READ_2(key->info) & EAPOL_KEY_VERSION_MASK) {
453 	case EAPOL_KEY_DESC_V1:
454 		HMAC_MD5_Init(&ctx.md5, kck, 16);
455 		HMAC_MD5_Update(&ctx.md5, (u_int8_t *)key, len);
456 		HMAC_MD5_Final(key->mic, &ctx.md5);
457 		break;
458 	case EAPOL_KEY_DESC_V2:
459 		HMAC_SHA1_Init(&ctx.sha1, kck, 16);
460 		HMAC_SHA1_Update(&ctx.sha1, (u_int8_t *)key, len);
461 		HMAC_SHA1_Final(digest, &ctx.sha1);
462 		/* truncate HMAC-SHA1 to its 128 MSBs */
463 		memcpy(key->mic, digest, EAPOL_KEY_MIC_LEN);
464 		break;
465 	case EAPOL_KEY_DESC_V3:
466 		AES_CMAC_Init(&ctx.cmac);
467 		AES_CMAC_SetKey(&ctx.cmac, kck);
468 		AES_CMAC_Update(&ctx.cmac, (u_int8_t *)key, len);
469 		AES_CMAC_Final(key->mic, &ctx.cmac);
470 		break;
471 	}
472 }
473 
474 /*
475  * Check the MIC of a received EAPOL-Key frame using the specified Key
476  * Confirmation Key (KCK).
477  */
478 int
479 ieee80211_eapol_key_check_mic(struct ieee80211_eapol_key *key,
480     const u_int8_t *kck)
481 {
482 	u_int8_t mic[EAPOL_KEY_MIC_LEN];
483 
484 	memcpy(mic, key->mic, EAPOL_KEY_MIC_LEN);
485 	memset(key->mic, 0, EAPOL_KEY_MIC_LEN);
486 	ieee80211_eapol_key_mic(key, kck);
487 
488 	return timingsafe_bcmp(key->mic, mic, EAPOL_KEY_MIC_LEN) != 0;
489 }
490 
491 #ifndef IEEE80211_STA_ONLY
492 /*
493  * Encrypt the Key Data field of an EAPOL-Key frame using the specified Key
494  * Encryption Key (KEK).  The encryption algorithm can be either ARC4 or
495  * AES Key Wrap depending on the EAPOL-Key Key Descriptor Version.
496  */
497 void
498 ieee80211_eapol_key_encrypt(struct ieee80211com *ic,
499     struct ieee80211_eapol_key *key, const u_int8_t *kek)
500 {
501 	union {
502 		struct rc4_ctx rc4;
503 		aes_key_wrap_ctx aes;
504 	} ctx;	/* XXX off stack? */
505 	u_int8_t keybuf[EAPOL_KEY_IV_LEN + 16];
506 	u_int16_t len, info;
507 	u_int8_t *data;
508 	int n;
509 
510 	len  = BE_READ_2(key->paylen);
511 	info = BE_READ_2(key->info);
512 	data = (u_int8_t *)(key + 1);
513 
514 	switch (info & EAPOL_KEY_VERSION_MASK) {
515 	case EAPOL_KEY_DESC_V1:
516 		/* set IV to the lower 16 octets of our global key counter */
517 		memcpy(key->iv, ic->ic_globalcnt + 16, 16);
518 		/* increment our global key counter (256-bit, big-endian) */
519 		for (n = 31; n >= 0 && ++ic->ic_globalcnt[n] == 0; n--);
520 
521 		/* concatenate the EAPOL-Key IV field and the KEK */
522 		memcpy(keybuf, key->iv, EAPOL_KEY_IV_LEN);
523 		memcpy(keybuf + EAPOL_KEY_IV_LEN, kek, 16);
524 
525 		rc4_keysetup(&ctx.rc4, keybuf, sizeof keybuf);
526 		/* discard the first 256 octets of the ARC4 key stream */
527 		rc4_skip(&ctx.rc4, RC4STATE);
528 		rc4_crypt(&ctx.rc4, data, data, len);
529 		break;
530 	case EAPOL_KEY_DESC_V2:
531 	case EAPOL_KEY_DESC_V3:
532 		if (len < 16 || (len & 7) != 0) {
533 			/* insert padding */
534 			n = (len < 16) ? 16 - len : 8 - (len & 7);
535 			data[len++] = IEEE80211_ELEMID_VENDOR;
536 			memset(&data[len], 0, n - 1);
537 			len += n - 1;
538 		}
539 		aes_key_wrap_set_key_wrap_only(&ctx.aes, kek, 16);
540 		aes_key_wrap(&ctx.aes, data, len / 8, data);
541 		len += 8;	/* AES Key Wrap adds 8 bytes */
542 		/* update key data length */
543 		BE_WRITE_2(key->paylen, len);
544 		/* update packet body length */
545 		BE_WRITE_2(key->len, sizeof(*key) + len - 4);
546 		break;
547 	}
548 }
549 #endif	/* IEEE80211_STA_ONLY */
550 
551 /*
552  * Decrypt the Key Data field of an EAPOL-Key frame using the specified Key
553  * Encryption Key (KEK).  The encryption algorithm can be either ARC4 or
554  * AES Key Wrap depending on the EAPOL-Key Key Descriptor Version.
555  */
556 int
557 ieee80211_eapol_key_decrypt(struct ieee80211_eapol_key *key,
558     const u_int8_t *kek)
559 {
560 	union {
561 		struct rc4_ctx rc4;
562 		aes_key_wrap_ctx aes;
563 	} ctx;	/* XXX off stack? */
564 	u_int8_t keybuf[EAPOL_KEY_IV_LEN + 16];
565 	u_int16_t len, info;
566 	u_int8_t *data;
567 
568 	len  = BE_READ_2(key->paylen);
569 	info = BE_READ_2(key->info);
570 	data = (u_int8_t *)(key + 1);
571 
572 	switch (info & EAPOL_KEY_VERSION_MASK) {
573 	case EAPOL_KEY_DESC_V1:
574 		/* concatenate the EAPOL-Key IV field and the KEK */
575 		memcpy(keybuf, key->iv, EAPOL_KEY_IV_LEN);
576 		memcpy(keybuf + EAPOL_KEY_IV_LEN, kek, 16);
577 
578 		rc4_keysetup(&ctx.rc4, keybuf, sizeof keybuf);
579 		/* discard the first 256 octets of the ARC4 key stream */
580 		rc4_skip(&ctx.rc4, RC4STATE);
581 		rc4_crypt(&ctx.rc4, data, data, len);
582 		return 0;
583 	case EAPOL_KEY_DESC_V2:
584 	case EAPOL_KEY_DESC_V3:
585 		/* Key Data Length must be a multiple of 8 */
586 		if (len < 16 + 8 || (len & 7) != 0)
587 			return 1;
588 		len -= 8;	/* AES Key Wrap adds 8 bytes */
589 		aes_key_wrap_set_key(&ctx.aes, kek, 16);
590 		return aes_key_unwrap(&ctx.aes, data, data, len / 8);
591 	}
592 
593 	return 1;	/* unknown Key Descriptor Version */
594 }
595 
596 /*
597  * Add a PMK entry to the PMKSA cache.
598  */
599 struct ieee80211_pmk *
600 ieee80211_pmksa_add(struct ieee80211com *ic, enum ieee80211_akm akm,
601     const u_int8_t *macaddr, const u_int8_t *key, u_int32_t lifetime)
602 {
603 	struct ieee80211_pmk *pmk;
604 
605 	/* check if an entry already exists for this (STA,AKMP) */
606 	TAILQ_FOREACH(pmk, &ic->ic_pmksa, pmk_next) {
607 		if (pmk->pmk_akm == akm &&
608 		    IEEE80211_ADDR_EQ(pmk->pmk_macaddr, macaddr))
609 			break;
610 	}
611 	if (pmk == NULL) {
612 		/* allocate a new PMKSA entry */
613 		if ((pmk = malloc(sizeof(*pmk), M_DEVBUF, M_NOWAIT)) == NULL)
614 			return NULL;
615 		pmk->pmk_akm = akm;
616 		IEEE80211_ADDR_COPY(pmk->pmk_macaddr, macaddr);
617 		TAILQ_INSERT_TAIL(&ic->ic_pmksa, pmk, pmk_next);
618 	}
619 	memcpy(pmk->pmk_key, key, IEEE80211_PMK_LEN);
620 	pmk->pmk_lifetime = lifetime;	/* XXX not used yet */
621 #ifndef IEEE80211_STA_ONLY
622 	if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
623 		ieee80211_derive_pmkid(pmk->pmk_akm, pmk->pmk_key,
624 		    ic->ic_myaddr, macaddr, pmk->pmk_pmkid);
625 	} else
626 #endif
627 	{
628 		ieee80211_derive_pmkid(pmk->pmk_akm, pmk->pmk_key,
629 		    macaddr, ic->ic_myaddr, pmk->pmk_pmkid);
630 	}
631 	return pmk;
632 }
633 
634 /*
635  * Check if we have a cached PMK entry for the specified node and PMKID.
636  */
637 struct ieee80211_pmk *
638 ieee80211_pmksa_find(struct ieee80211com *ic, struct ieee80211_node *ni,
639     const u_int8_t *pmkid)
640 {
641 	struct ieee80211_pmk *pmk;
642 
643 	TAILQ_FOREACH(pmk, &ic->ic_pmksa, pmk_next) {
644 		if (pmk->pmk_akm == ni->ni_rsnakms &&
645 		    IEEE80211_ADDR_EQ(pmk->pmk_macaddr, ni->ni_macaddr) &&
646 		    (pmkid == NULL ||
647 		     memcmp(pmk->pmk_pmkid, pmkid, IEEE80211_PMKID_LEN) == 0))
648 			break;
649 	}
650 	return pmk;
651 }
652