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