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 * 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 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 152 gcmp_get_trailer_len(struct ieee80211_key *k) 153 { 154 return (k->wk_cipher->ic_trailer); 155 } 156 157 static int 158 gcmp_get_header_len(struct ieee80211_key *k) 159 { 160 return (k->wk_cipher->ic_header); 161 } 162 163 static int 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 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 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 269 gcmp_enmic(struct ieee80211_key *k, struct mbuf *m, int force) 270 { 271 return (1); 272 } 273 274 static __inline uint64_t 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 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 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 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 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 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