1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
5 * All rights reserved.
6 * Copyright (c) 2025 Adrian Chadd <adrian@FreeBSD.org>.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * IEEE 802.11 AES-GCMP crypto support.
31 *
32 * The AES-GCM crypto routines in sys/net80211/ieee80211_crypto_gcm.[ch]
33 * are derived from similar code in hostapd 2.11 (src/crypto/aes-gcm.c).
34 * The code is used with the consent of the author and its licence is
35 * included in the above source files.
36 */
37 #include "opt_wlan.h"
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/mbuf.h>
42 #include <sys/malloc.h>
43 #include <sys/kernel.h>
44 #include <sys/module.h>
45
46 #include <sys/socket.h>
47
48 #include <net/if.h>
49 #include <net/if_media.h>
50 #include <net/ethernet.h>
51
52 #include <net80211/ieee80211_var.h>
53 #include <net80211/ieee80211_crypto_gcm.h>
54
55 #include <crypto/rijndael/rijndael.h>
56
57 #define AES_BLOCK_LEN 16
58
59 /*
60 * Note: GCMP_MIC_LEN defined in ieee80211_crypto_gcm.h, as it is also
61 * used by the AES-GCM routines for sizing the S and T hashes which are
62 * used by GCMP as the MIC.
63 */
64 #define GCMP_PN_LEN 6
65 #define GCMP_IV_LEN 12
66
67 struct gcmp_ctx {
68 struct ieee80211vap *cc_vap; /* for diagnostics+statistics */
69 struct ieee80211com *cc_ic;
70 rijndael_ctx cc_aes;
71 };
72
73 static void *gcmp_attach(struct ieee80211vap *, struct ieee80211_key *);
74 static void gcmp_detach(struct ieee80211_key *);
75 static int gcmp_setkey(struct ieee80211_key *);
76 static void gcmp_setiv(struct ieee80211_key *, uint8_t *);
77 static int gcmp_encap(struct ieee80211_key *, struct mbuf *);
78 static int gcmp_decap(struct ieee80211_key *, struct mbuf *, int);
79 static int gcmp_enmic(struct ieee80211_key *, struct mbuf *, int);
80 static int gcmp_demic(struct ieee80211_key *, struct mbuf *, int);
81
82 static const struct ieee80211_cipher gcmp = {
83 .ic_name = "AES-GCMP",
84 .ic_cipher = IEEE80211_CIPHER_AES_GCM_128,
85 .ic_header = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
86 IEEE80211_WEP_EXTIVLEN,
87 .ic_trailer = GCMP_MIC_LEN,
88 .ic_miclen = 0,
89 .ic_attach = gcmp_attach,
90 .ic_detach = gcmp_detach,
91 .ic_setkey = gcmp_setkey,
92 .ic_setiv = gcmp_setiv,
93 .ic_encap = gcmp_encap,
94 .ic_decap = gcmp_decap,
95 .ic_enmic = gcmp_enmic,
96 .ic_demic = gcmp_demic,
97 };
98
99 static const struct ieee80211_cipher gcmp_256 = {
100 .ic_name = "AES-GCMP-256",
101 .ic_cipher = IEEE80211_CIPHER_AES_GCM_256,
102 .ic_header = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
103 IEEE80211_WEP_EXTIVLEN,
104 .ic_trailer = GCMP_MIC_LEN,
105 .ic_miclen = 0,
106 .ic_attach = gcmp_attach,
107 .ic_detach = gcmp_detach,
108 .ic_setkey = gcmp_setkey,
109 .ic_setiv = gcmp_setiv,
110 .ic_encap = gcmp_encap,
111 .ic_decap = gcmp_decap,
112 .ic_enmic = gcmp_enmic,
113 .ic_demic = gcmp_demic,
114 };
115
116
117 static int gcmp_encrypt(struct ieee80211_key *, struct mbuf *, int hdrlen);
118 static int gcmp_decrypt(struct ieee80211_key *, u_int64_t pn,
119 struct mbuf *, int hdrlen);
120
121 /* number of references from net80211 layer */
122 static int nrefs = 0;
123
124 static void *
gcmp_attach(struct ieee80211vap * vap,struct ieee80211_key * k)125 gcmp_attach(struct ieee80211vap *vap, struct ieee80211_key *k)
126 {
127 struct gcmp_ctx *ctx;
128
129 ctx = (struct gcmp_ctx *) IEEE80211_MALLOC(sizeof(struct gcmp_ctx),
130 M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
131 if (ctx == NULL) {
132 vap->iv_stats.is_crypto_nomem++;
133 return (NULL);
134 }
135 ctx->cc_vap = vap;
136 ctx->cc_ic = vap->iv_ic;
137 nrefs++; /* NB: we assume caller locking */
138 return (ctx);
139 }
140
141 static void
gcmp_detach(struct ieee80211_key * k)142 gcmp_detach(struct ieee80211_key *k)
143 {
144 struct gcmp_ctx *ctx = k->wk_private;
145
146 IEEE80211_FREE(ctx, M_80211_CRYPTO);
147 KASSERT(nrefs > 0, ("imbalanced attach/detach"));
148 nrefs--; /* NB: we assume caller locking */
149 }
150
151 static int
gcmp_get_trailer_len(struct ieee80211_key * k)152 gcmp_get_trailer_len(struct ieee80211_key *k)
153 {
154 return (k->wk_cipher->ic_trailer);
155 }
156
157 static int
gcmp_get_header_len(struct ieee80211_key * k)158 gcmp_get_header_len(struct ieee80211_key *k)
159 {
160 return (k->wk_cipher->ic_header);
161 }
162
163 static int
gcmp_setkey(struct ieee80211_key * k)164 gcmp_setkey(struct ieee80211_key *k)
165 {
166 uint32_t keylen;
167
168 struct gcmp_ctx *ctx = k->wk_private;
169
170 switch (k->wk_cipher->ic_cipher) {
171 case IEEE80211_CIPHER_AES_GCM_128:
172 keylen = 128;
173 break;
174 case IEEE80211_CIPHER_AES_GCM_256:
175 keylen = 256;
176 break;
177 default:
178 IEEE80211_DPRINTF(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
179 "%s: Unexpected cipher (%u)",
180 __func__, k->wk_cipher->ic_cipher);
181 return (0);
182 }
183
184 if (k->wk_keylen != (keylen/NBBY)) {
185 IEEE80211_DPRINTF(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
186 "%s: Invalid key length %u, expecting %u\n",
187 __func__, k->wk_keylen, keylen/NBBY);
188 return (0);
189 }
190 if (k->wk_flags & IEEE80211_KEY_SWENCRYPT)
191 rijndael_set_key(&ctx->cc_aes, k->wk_key, k->wk_keylen*NBBY);
192 return (1);
193 }
194
195 static void
gcmp_setiv(struct ieee80211_key * k,uint8_t * ivp)196 gcmp_setiv(struct ieee80211_key *k, uint8_t *ivp)
197 {
198 struct gcmp_ctx *ctx = k->wk_private;
199 struct ieee80211vap *vap = ctx->cc_vap;
200 uint8_t keyid;
201
202 keyid = ieee80211_crypto_get_keyid(vap, k) << 6;
203
204 k->wk_keytsc++;
205 ivp[0] = k->wk_keytsc >> 0; /* PN0 */
206 ivp[1] = k->wk_keytsc >> 8; /* PN1 */
207 ivp[2] = 0; /* Reserved */
208 ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */
209 ivp[4] = k->wk_keytsc >> 16; /* PN2 */
210 ivp[5] = k->wk_keytsc >> 24; /* PN3 */
211 ivp[6] = k->wk_keytsc >> 32; /* PN4 */
212 ivp[7] = k->wk_keytsc >> 40; /* PN5 */
213 }
214
215 /*
216 * Add privacy headers appropriate for the specified key.
217 */
218 static int
gcmp_encap(struct ieee80211_key * k,struct mbuf * m)219 gcmp_encap(struct ieee80211_key *k, struct mbuf *m)
220 {
221 const struct ieee80211_frame *wh;
222 struct gcmp_ctx *ctx = k->wk_private;
223 struct ieee80211com *ic = ctx->cc_ic;
224 uint8_t *ivp;
225 int hdrlen;
226 int is_mgmt;
227
228 hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
229 wh = mtod(m, const struct ieee80211_frame *);
230 is_mgmt = IEEE80211_IS_MGMT(wh);
231
232 /*
233 * Check to see if we need to insert IV/MIC.
234 *
235 * Some offload devices don't require the IV to be inserted
236 * as part of the hardware encryption.
237 */
238 if (is_mgmt && (k->wk_flags & IEEE80211_KEY_NOIVMGT))
239 return (1);
240 if (!is_mgmt && (k->wk_flags & IEEE80211_KEY_NOIV))
241 return (1);
242
243 /*
244 * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
245 */
246 M_PREPEND(m, gcmp_get_header_len(k), IEEE80211_M_NOWAIT);
247 if (m == NULL)
248 return (0);
249 ivp = mtod(m, uint8_t *);
250 ovbcopy(ivp + gcmp_get_header_len(k), ivp, hdrlen);
251 ivp += hdrlen;
252
253 gcmp_setiv(k, ivp);
254
255 /*
256 * Finally, do software encrypt if needed.
257 */
258 if ((k->wk_flags & IEEE80211_KEY_SWENCRYPT) &&
259 !gcmp_encrypt(k, m, hdrlen))
260 return (0);
261
262 return (1);
263 }
264
265 /*
266 * Add MIC to the frame as needed.
267 */
268 static int
gcmp_enmic(struct ieee80211_key * k,struct mbuf * m,int force)269 gcmp_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
270 {
271 return (1);
272 }
273
274 static __inline uint64_t
READ_6(uint8_t b0,uint8_t b1,uint8_t b2,uint8_t b3,uint8_t b4,uint8_t b5)275 READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5)
276 {
277 uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
278 uint16_t iv16 = (b4 << 0) | (b5 << 8);
279 return ((((uint64_t)iv16) << 32) | iv32);
280 }
281
282 /*
283 * Validate and strip privacy headers (and trailer) for a
284 * received frame. The specified key should be correct but
285 * is also verified.
286 */
287 static int
gcmp_decap(struct ieee80211_key * k,struct mbuf * m,int hdrlen)288 gcmp_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
289 {
290 const struct ieee80211_rx_stats *rxs;
291 struct gcmp_ctx *ctx = k->wk_private;
292 struct ieee80211vap *vap = ctx->cc_vap;
293 struct ieee80211_frame *wh;
294 uint8_t *ivp, tid;
295 uint64_t pn;
296 bool noreplaycheck;
297
298 rxs = ieee80211_get_rx_params_ptr(m);
299
300 if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP) != 0)
301 goto finish;
302
303 /*
304 * Header should have extended IV and sequence number;
305 * verify the former and validate the latter.
306 */
307 wh = mtod(m, struct ieee80211_frame *);
308 ivp = mtod(m, uint8_t *) + hdrlen;
309 if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
310 /*
311 * No extended IV; discard frame.
312 */
313 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
314 "%s", "missing ExtIV for AES-GCM cipher");
315 vap->iv_stats.is_rx_gcmpformat++;
316 return (0);
317 }
318 tid = ieee80211_gettid(wh);
319 pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);
320
321 noreplaycheck = (k->wk_flags & IEEE80211_KEY_NOREPLAY) != 0;
322 noreplaycheck |= (rxs != NULL) &&
323 (rxs->c_pktflags & IEEE80211_RX_F_PN_VALIDATED) != 0;
324 if (pn <= k->wk_keyrsc[tid] && !noreplaycheck) {
325 /*
326 * Replay violation.
327 */
328 ieee80211_notify_replay_failure(vap, wh, k, pn, tid);
329 vap->iv_stats.is_rx_gcmpreplay++;
330 return (0);
331 }
332
333 /*
334 * Check if the device handled the decrypt in hardware.
335 * If so we just strip the header; otherwise we need to
336 * handle the decrypt in software. Note that for the
337 * latter we leave the header in place for use in the
338 * decryption work.
339 */
340 if ((k->wk_flags & IEEE80211_KEY_SWDECRYPT) &&
341 !gcmp_decrypt(k, pn, m, hdrlen))
342 return (0);
343
344 finish:
345 /*
346 * Copy up 802.11 header and strip crypto bits.
347 */
348 if ((rxs == NULL) || (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP) == 0) {
349 ovbcopy(mtod(m, void *), mtod(m, uint8_t *) +
350 gcmp_get_header_len(k), hdrlen);
351 m_adj(m, gcmp_get_header_len(k));
352 }
353
354 if ((rxs == NULL) || (rxs->c_pktflags & IEEE80211_RX_F_MIC_STRIP) == 0)
355 m_adj(m, -gcmp_get_trailer_len(k));
356
357 /*
358 * Ok to update rsc now.
359 */
360 if ((rxs == NULL) || (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP) == 0) {
361 /*
362 * Do not go backwards in the IEEE80211_KEY_NOREPLAY cases
363 * or in case hardware has checked but frames are arriving
364 * reordered (e.g., LinuxKPI drivers doing RSS which we are
365 * not prepared for at all).
366 */
367 if (pn > k->wk_keyrsc[tid])
368 k->wk_keyrsc[tid] = pn;
369 }
370
371 return (1);
372 }
373
374 /*
375 * Verify and strip MIC from the frame.
376 */
377 static int
gcmp_demic(struct ieee80211_key * k,struct mbuf * m,int force)378 gcmp_demic(struct ieee80211_key *k, struct mbuf *m, int force)
379 {
380 return (1);
381 }
382
383 /*
384 * Populate the 12 byte / 96 bit IV buffer.
385 */
386 static int
gcmp_init_iv(uint8_t * iv,const struct ieee80211_frame * wh,u_int64_t pn)387 gcmp_init_iv(uint8_t *iv, const struct ieee80211_frame *wh, u_int64_t pn)
388 {
389 uint8_t j_pn[GCMP_PN_LEN];
390
391 /* Construct the pn buffer */
392 j_pn[0] = pn >> 40;
393 j_pn[1] = pn >> 32;
394 j_pn[2] = pn >> 24;
395 j_pn[3] = pn >> 16;
396 j_pn[4] = pn >> 8;
397 j_pn[5] = pn >> 0;
398
399 memcpy(iv, wh->i_addr2, IEEE80211_ADDR_LEN);
400 memcpy(iv + IEEE80211_ADDR_LEN, j_pn, GCMP_PN_LEN);
401
402 return (GCMP_IV_LEN); /* 96 bits */
403 }
404
405 /*
406 * @brief Encrypt an mbuf.
407 *
408 * This uses a temporary memory buffer to encrypt; the
409 * current AES-GCM code expects things in a contiguous buffer
410 * and this avoids the need of breaking out the GCTR and
411 * GHASH routines into using mbuf iterators.
412 *
413 * @param key ieee80211_key to use
414 * @param mbuf 802.11 frame to encrypt
415 * @param hdrlen the length of the 802.11 header, including any padding
416 * @returns 0 if error, > 0 if OK.
417 */
418 static int
gcmp_encrypt(struct ieee80211_key * key,struct mbuf * m0,int hdrlen)419 gcmp_encrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen)
420 {
421 struct gcmp_ctx *ctx = key->wk_private;
422 struct ieee80211_frame *wh;
423 struct mbuf *m = m0;
424 int data_len, aad_len, iv_len, ret;
425 uint8_t aad[GCM_AAD_LEN];
426 uint8_t T[GCMP_MIC_LEN];
427 uint8_t iv[GCMP_IV_LEN];
428 uint8_t *p_pktbuf = NULL;
429 uint8_t *c_pktbuf = NULL;
430
431 wh = mtod(m, struct ieee80211_frame *);
432 data_len = m->m_pkthdr.len - (hdrlen + gcmp_get_header_len(key));
433
434 ctx->cc_vap->iv_stats.is_crypto_gcmp++;
435
436 p_pktbuf = IEEE80211_MALLOC(data_len, M_TEMP,
437 IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
438 if (p_pktbuf == NULL) {
439 IEEE80211_NOTE_MAC(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
440 wh->i_addr2, "%s",
441 "AES-GCM encrypt failed; couldn't allocate buffer");
442 ctx->cc_vap->iv_stats.is_crypto_gcmp_nomem++;
443 return (0);
444 }
445 c_pktbuf = IEEE80211_MALLOC(data_len, M_TEMP,
446 IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
447 if (c_pktbuf == NULL) {
448 IEEE80211_NOTE_MAC(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
449 wh->i_addr2, "%s",
450 "AES-GCM encrypt failed; couldn't allocate buffer");
451 ctx->cc_vap->iv_stats.is_crypto_gcmp_nomem++;
452 IEEE80211_FREE(p_pktbuf, M_TEMP);
453 return (0);
454 }
455
456 /* Initialise AAD */
457 aad_len = ieee80211_crypto_init_aad(wh, aad, GCM_AAD_LEN);
458
459 /* Initialise local Nonce to work on */
460 /* TODO: rename iv stuff here to nonce */
461 iv_len = gcmp_init_iv(iv, wh, key->wk_keytsc);
462
463 /* Copy mbuf data part into plaintext pktbuf */
464 m_copydata(m0, hdrlen + gcmp_get_header_len(key), data_len,
465 p_pktbuf);
466
467 /* Run encrypt */
468 /*
469 * Note: aad + 2 to skip over the 2 byte length populated
470 * at the beginning, since it's based on the AAD code in CCMP.
471 */
472 ieee80211_crypto_aes_gcm_ae(&ctx->cc_aes, iv, iv_len,
473 p_pktbuf, data_len, aad + 2, aad_len, c_pktbuf, T);
474
475 /* Copy data back over mbuf */
476 m_copyback(m0, hdrlen + gcmp_get_header_len(key), data_len,
477 c_pktbuf);
478
479 /* Append MIC */
480 ret = m_append(m0, gcmp_get_trailer_len(key), T);
481 if (ret == 0) {
482 IEEE80211_NOTE_MAC(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
483 wh->i_addr2, "%s",
484 "AES-GCM encrypt failed; couldn't append T");
485 ctx->cc_vap->iv_stats.is_crypto_gcmp_nospc++;
486 }
487
488 IEEE80211_FREE(p_pktbuf, M_TEMP);
489 IEEE80211_FREE(c_pktbuf, M_TEMP);
490
491 return (ret);
492 }
493
494 /*
495 * @brief Decrypt an mbuf.
496 *
497 * This uses a temporary memory buffer to decrypt; the
498 * current AES-GCM code expects things in a contiguous buffer
499 * and this avoids the need of breaking out the GCTR and
500 * GHASH routines into using mbuf iterators.
501 *
502 * @param key ieee80211_key to use
503 * @param mbuf 802.11 frame to decrypt
504 * @param hdrlen the length of the 802.11 header, including any padding
505 * @returns 0 if error, > 0 if OK.
506 */
507 static int
gcmp_decrypt(struct ieee80211_key * key,u_int64_t pn,struct mbuf * m,int hdrlen)508 gcmp_decrypt(struct ieee80211_key *key, u_int64_t pn, struct mbuf *m,
509 int hdrlen)
510 {
511 const struct ieee80211_rx_stats *rxs;
512 struct gcmp_ctx *ctx = key->wk_private;
513 struct ieee80211_frame *wh;
514 int data_len, aad_len, iv_len, ret;
515 uint8_t aad[GCM_AAD_LEN];
516 uint8_t T[GCMP_MIC_LEN];
517 uint8_t iv[GCMP_IV_LEN];
518 uint8_t *p_pktbuf = NULL;
519 uint8_t *c_pktbuf = NULL;
520
521 rxs = ieee80211_get_rx_params_ptr(m);
522 if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_DECRYPTED) != 0)
523 return (1);
524
525 wh = mtod(m, struct ieee80211_frame *);
526
527 /* Data length doesn't include the MIC at the end */
528 data_len = m->m_pkthdr.len -
529 (hdrlen + gcmp_get_header_len(key) + GCMP_MIC_LEN);
530
531 ctx->cc_vap->iv_stats.is_crypto_gcmp++;
532
533 p_pktbuf = IEEE80211_MALLOC(data_len, M_TEMP,
534 IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
535 if (p_pktbuf == NULL) {
536 ctx->cc_vap->iv_stats.is_crypto_gcmp_nomem++;
537 return (0);
538 }
539 c_pktbuf = IEEE80211_MALLOC(data_len, M_TEMP,
540 IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
541 if (c_pktbuf == NULL) {
542 ctx->cc_vap->iv_stats.is_crypto_gcmp_nomem++;
543 IEEE80211_FREE(p_pktbuf, M_TEMP);
544 return (0);
545 }
546
547 /* Initialise AAD */
548 aad_len = ieee80211_crypto_init_aad(wh, aad, GCM_AAD_LEN);
549
550 /* Initialise local IV copy to work on */
551 iv_len = gcmp_init_iv(iv, wh, pn);
552
553 /* Copy mbuf into ciphertext pktbuf */
554 m_copydata(m, hdrlen + gcmp_get_header_len(key), data_len,
555 c_pktbuf);
556
557 /* Copy the MIC into the tag buffer */
558 m_copydata(m, hdrlen + gcmp_get_header_len(key) + data_len,
559 GCMP_MIC_LEN, T);
560
561 /* Run decrypt */
562 /*
563 * Note: aad + 2 to skip over the 2 byte length populated
564 * at the beginning, since it's based on the AAD code in CCMP.
565 */
566 ret = ieee80211_crypto_aes_gcm_ad(&ctx->cc_aes, iv, iv_len,
567 c_pktbuf, data_len, aad + 2, aad_len, T, p_pktbuf);
568
569 /* If the MIC was stripped by HW/driver we are done. */
570 if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_MIC_STRIP) != 0)
571 goto skip_ok;
572
573 if (ret != 0) {
574 /* Decrypt failure */
575 ctx->cc_vap->iv_stats.is_rx_gcmpmic++;
576 IEEE80211_NOTE_MAC(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
577 wh->i_addr2, "%s", "AES-GCM decrypt failed; MIC mismatch");
578 IEEE80211_FREE(p_pktbuf, M_TEMP);
579 IEEE80211_FREE(c_pktbuf, M_TEMP);
580 return (0);
581 }
582
583 skip_ok:
584 /* Copy data back over mbuf */
585 m_copyback(m, hdrlen + gcmp_get_header_len(key), data_len,
586 p_pktbuf);
587
588 IEEE80211_FREE(p_pktbuf, M_TEMP);
589 IEEE80211_FREE(c_pktbuf, M_TEMP);
590
591 return (1);
592 }
593
594 /*
595 * Module glue.
596 */
597 IEEE80211_CRYPTO_MODULE(gcmp, 1);
598 IEEE80211_CRYPTO_MODULE_ADD(gcmp_256);
599