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