1 /* $OpenBSD: ieee80211_crypto.c,v 1.79 2024/04/14 03:26:25 jsg 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
49 void 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);
51 void 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);
53 void ieee80211_derive_pmkid(enum ieee80211_akm, const u_int8_t *,
54 const u_int8_t *, const u_int8_t *, u_int8_t *);
55
56 void
ieee80211_crypto_attach(struct ifnet * ifp)57 ieee80211_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
77 void
ieee80211_crypto_detach(struct ifnet * ifp)78 ieee80211_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
101 void
ieee80211_crypto_clear_groupkeys(struct ieee80211com * ic)102 ieee80211_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 */
117 int
ieee80211_cipher_keylen(enum ieee80211_cipher cipher)118 ieee80211_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
136 int
ieee80211_set_key(struct ieee80211com * ic,struct ieee80211_node * ni,struct ieee80211_key * k)137 ieee80211_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
167 void
ieee80211_delete_key(struct ieee80211com * ic,struct ieee80211_node * ni,struct ieee80211_key * k)168 ieee80211_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
192 struct ieee80211_key *
ieee80211_get_txkey(struct ieee80211com * ic,const struct ieee80211_frame * wh,struct ieee80211_node * ni)193 ieee80211_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
212 struct ieee80211_key *
ieee80211_get_rxkey(struct ieee80211com * ic,struct mbuf * m,struct ieee80211_node * ni)213 ieee80211_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
256 struct mbuf *
ieee80211_encrypt(struct ieee80211com * ic,struct mbuf * m0,struct ieee80211_key * k)257 ieee80211_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
285 struct mbuf *
ieee80211_decrypt(struct ieee80211com * ic,struct mbuf * m0,struct ieee80211_node * ni)286 ieee80211_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 */
323 void
ieee80211_prf(const u_int8_t * key,size_t key_len,const u_int8_t * label,size_t label_len,const u_int8_t * context,size_t context_len,u_int8_t * output,size_t len)324 ieee80211_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 */
352 void
ieee80211_kdf(const u_int8_t * key,size_t key_len,const u_int8_t * label,size_t label_len,const u_int8_t * context,size_t context_len,u_int8_t * output,size_t len)353 ieee80211_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 */
384 void
ieee80211_derive_ptk(enum ieee80211_akm akm,const u_int8_t * pmk,const u_int8_t * aa,const u_int8_t * spa,const u_int8_t * anonce,const u_int8_t * snonce,struct ieee80211_ptk * ptk)385 ieee80211_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
409 static void
ieee80211_pmkid_sha1(const u_int8_t * pmk,const u_int8_t * aa,const u_int8_t * spa,u_int8_t * pmkid)410 ieee80211_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
425 static void
ieee80211_pmkid_sha256(const u_int8_t * pmk,const u_int8_t * aa,const u_int8_t * spa,u_int8_t * pmkid)426 ieee80211_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 */
444 void
ieee80211_derive_pmkid(enum ieee80211_akm akm,const u_int8_t * pmk,const u_int8_t * aa,const u_int8_t * spa,u_int8_t * pmkid)445 ieee80211_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
454 typedef 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 */
465 void
ieee80211_eapol_key_mic(struct ieee80211_eapol_key * key,const u_int8_t * kck)466 ieee80211_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 */
500 int
ieee80211_eapol_key_check_mic(struct ieee80211_eapol_key * key,const u_int8_t * kck)501 ieee80211_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 */
519 void
ieee80211_eapol_key_encrypt(struct ieee80211com * ic,struct ieee80211_eapol_key * key,const u_int8_t * kek)520 ieee80211_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
544 /* concatenate the EAPOL-Key IV field and the KEK */
545 memcpy(keybuf, key->iv, EAPOL_KEY_IV_LEN);
546 memcpy(keybuf + EAPOL_KEY_IV_LEN, kek, 16);
547
548 rc4_keysetup(&ctx.rc4, keybuf, sizeof keybuf);
549 /* discard the first 256 octets of the ARC4 key stream */
550 rc4_skip(&ctx.rc4, RC4STATE);
551 rc4_crypt(&ctx.rc4, data, data, len);
552 break;
553 case EAPOL_KEY_DESC_V2:
554 case EAPOL_KEY_DESC_V3:
555 if (len < 16 || (len & 7) != 0) {
556 /* insert padding */
557 n = (len < 16) ? 16 - len : 8 - (len & 7);
558 data[len++] = IEEE80211_ELEMID_VENDOR;
559 memset(&data[len], 0, n - 1);
560 len += n - 1;
561 }
562 aes_key_wrap_set_key_wrap_only(&ctx.aes, kek, 16);
563 aes_key_wrap(&ctx.aes, data, len / 8, data);
564 len += 8; /* AES Key Wrap adds 8 bytes */
565 /* update key data length */
566 BE_WRITE_2(key->paylen, len);
567 /* update packet body length */
568 BE_WRITE_2(key->len, sizeof(*key) + len - 4);
569 break;
570 }
571 }
572 #endif /* IEEE80211_STA_ONLY */
573
574 /*
575 * Decrypt the Key Data field of an EAPOL-Key frame using the specified Key
576 * Encryption Key (KEK). The encryption algorithm can be either ARC4 or
577 * AES Key Wrap depending on the EAPOL-Key Key Descriptor Version.
578 */
579 int
ieee80211_eapol_key_decrypt(struct ieee80211_eapol_key * key,const u_int8_t * kek)580 ieee80211_eapol_key_decrypt(struct ieee80211_eapol_key *key,
581 const u_int8_t *kek)
582 {
583 union {
584 struct rc4_ctx rc4;
585 aes_key_wrap_ctx aes;
586 } ctx; /* XXX off stack? */
587 u_int8_t keybuf[EAPOL_KEY_IV_LEN + 16];
588 u_int16_t len, info;
589 u_int8_t *data;
590
591 len = BE_READ_2(key->paylen);
592 info = BE_READ_2(key->info);
593 data = (u_int8_t *)(key + 1);
594
595 switch (info & EAPOL_KEY_VERSION_MASK) {
596 case EAPOL_KEY_DESC_V1:
597 /* concatenate the EAPOL-Key IV field and the KEK */
598 memcpy(keybuf, key->iv, EAPOL_KEY_IV_LEN);
599 memcpy(keybuf + EAPOL_KEY_IV_LEN, kek, 16);
600
601 rc4_keysetup(&ctx.rc4, keybuf, sizeof keybuf);
602 /* discard the first 256 octets of the ARC4 key stream */
603 rc4_skip(&ctx.rc4, RC4STATE);
604 rc4_crypt(&ctx.rc4, data, data, len);
605 return 0;
606 case EAPOL_KEY_DESC_V2:
607 case EAPOL_KEY_DESC_V3:
608 /* Key Data Length must be a multiple of 8 */
609 if (len < 16 + 8 || (len & 7) != 0)
610 return 1;
611 len -= 8; /* AES Key Wrap adds 8 bytes */
612 aes_key_wrap_set_key(&ctx.aes, kek, 16);
613 return aes_key_unwrap(&ctx.aes, data, data, len / 8);
614 }
615
616 return 1; /* unknown Key Descriptor Version */
617 }
618
619 /*
620 * Add a PMK entry to the PMKSA cache.
621 */
622 struct ieee80211_pmk *
ieee80211_pmksa_add(struct ieee80211com * ic,enum ieee80211_akm akm,const u_int8_t * macaddr,const u_int8_t * key,u_int32_t lifetime)623 ieee80211_pmksa_add(struct ieee80211com *ic, enum ieee80211_akm akm,
624 const u_int8_t *macaddr, const u_int8_t *key, u_int32_t lifetime)
625 {
626 struct ieee80211_pmk *pmk;
627
628 /* check if an entry already exists for this (STA,AKMP) */
629 TAILQ_FOREACH(pmk, &ic->ic_pmksa, pmk_next) {
630 if (pmk->pmk_akm == akm &&
631 IEEE80211_ADDR_EQ(pmk->pmk_macaddr, macaddr))
632 break;
633 }
634 if (pmk == NULL) {
635 /* allocate a new PMKSA entry */
636 if ((pmk = malloc(sizeof(*pmk), M_DEVBUF, M_NOWAIT)) == NULL)
637 return NULL;
638 pmk->pmk_akm = akm;
639 IEEE80211_ADDR_COPY(pmk->pmk_macaddr, macaddr);
640 TAILQ_INSERT_TAIL(&ic->ic_pmksa, pmk, pmk_next);
641 }
642 memcpy(pmk->pmk_key, key, IEEE80211_PMK_LEN);
643 pmk->pmk_lifetime = lifetime; /* XXX not used yet */
644 #ifndef IEEE80211_STA_ONLY
645 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
646 ieee80211_derive_pmkid(pmk->pmk_akm, pmk->pmk_key,
647 ic->ic_myaddr, macaddr, pmk->pmk_pmkid);
648 } else
649 #endif
650 {
651 ieee80211_derive_pmkid(pmk->pmk_akm, pmk->pmk_key,
652 macaddr, ic->ic_myaddr, pmk->pmk_pmkid);
653 }
654 return pmk;
655 }
656
657 /*
658 * Check if we have a cached PMK entry for the specified node and PMKID.
659 */
660 struct ieee80211_pmk *
ieee80211_pmksa_find(struct ieee80211com * ic,struct ieee80211_node * ni,const u_int8_t * pmkid)661 ieee80211_pmksa_find(struct ieee80211com *ic, struct ieee80211_node *ni,
662 const u_int8_t *pmkid)
663 {
664 struct ieee80211_pmk *pmk;
665
666 TAILQ_FOREACH(pmk, &ic->ic_pmksa, pmk_next) {
667 if (pmk->pmk_akm == ni->ni_rsnakms &&
668 IEEE80211_ADDR_EQ(pmk->pmk_macaddr, ni->ni_macaddr) &&
669 (pmkid == NULL ||
670 memcmp(pmk->pmk_pmkid, pmkid, IEEE80211_PMKID_LEN) == 0))
671 break;
672 }
673 return pmk;
674 }
675