xref: /freebsd/sys/net80211/ieee80211_crypto_gcmp.c (revision a54a240c1b579e2c30af125f3b1fdfd87f280078)
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  * @brief Calculate the AAD required for this frame for AES-GCM.
385  *
386  * Note: This code was first copied over from ieee80211_crypto_ccmp.c, so
387  * it has some CCMP-isms.
388  *
389  * NOTE: the first two bytes are a 16 bit big-endian length, which are used
390  * by AES-CCM.  AES-GCM doesn't require the length at the beginning.
391  *
392  * @param wh	802.11 frame to calculate the AAD over
393  * @param aad	AAD buffer, GCM_AAD_LEN bytes
394  * @param The AAD length in bytes.
395  */
396 static int
gcmp_init_aad(const struct ieee80211_frame * wh,uint8_t * aad)397 gcmp_init_aad(const struct ieee80211_frame *wh, uint8_t *aad)
398 {
399 	int aad_len;
400 
401 	memset(aad, 0, GCM_AAD_LEN);
402 
403 #define	IS_QOS_DATA(wh)	IEEE80211_QOS_HAS_SEQ(wh)
404 	/* AAD:
405 	 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
406 	 * A1 | A2 | A3
407 	 * SC with bits 4..15 (seq#) masked to zero
408 	 * A4 (if present)
409 	 * QC (if present)
410 	 */
411 	aad[0] = 0;	/* AAD length >> 8 */
412 	/* NB: aad[1] set below */
413 
414 	/*
415 	 * TODO: go back over this in 802.11-2020 and triple check
416 	 * the AAD assembly with regards to packet flags.
417 	 */
418 
419 	aad[2] = wh->i_fc[0] & 0x8f;	/* XXX magic #s */
420 	/*
421 	 * TODO: 12.5.3.3.3 - bit 14 should always be set; bit 15 masked to 0
422 	 * if QoS control field, unmasked otherwise
423 	 */
424 	aad[3] = wh->i_fc[1] & 0xc7;	/* XXX magic #s */
425 	/* NB: we know 3 addresses are contiguous */
426 	memcpy(aad + 4, wh->i_addr1, 3 * IEEE80211_ADDR_LEN);
427 	aad[22] = wh->i_seq[0] & IEEE80211_SEQ_FRAG_MASK;
428 	aad[23] = 0; /* all bits masked */
429 	/*
430 	 * Construct variable-length portion of AAD based
431 	 * on whether this is a 4-address frame/QOS frame.
432 	 * We always zero-pad to 32 bytes before running it
433 	 * through the cipher.
434 	 */
435 	if (IEEE80211_IS_DSTODS(wh)) {
436 		IEEE80211_ADDR_COPY(aad + 24,
437 			((const struct ieee80211_frame_addr4 *)wh)->i_addr4);
438 		if (IS_QOS_DATA(wh)) {
439 			const struct ieee80211_qosframe_addr4 *qwh4 =
440 				(const struct ieee80211_qosframe_addr4 *) wh;
441 			aad[30] = qwh4->i_qos[0] & 0x0f;/* just priority bits */
442 			aad[31] = 0;
443 			aad_len = aad[1] = 22 + IEEE80211_ADDR_LEN + 2;
444 		} else {
445 			*(uint16_t *)&aad[30] = 0;
446 			aad_len = aad[1] = 22 + IEEE80211_ADDR_LEN;
447 		}
448 	} else {
449 		if (IS_QOS_DATA(wh)) {
450 			const struct ieee80211_qosframe *qwh =
451 				(const struct ieee80211_qosframe*) wh;
452 			aad[24] = qwh->i_qos[0] & 0x0f;	/* just priority bits */
453 			aad[25] = 0;
454 			aad_len = aad[1] = 22 + 2;
455 		} else {
456 			*(uint16_t *)&aad[24] = 0;
457 			aad_len = aad[1] = 22;
458 		}
459 		*(uint16_t *)&aad[26] = 0;
460 		*(uint32_t *)&aad[28] = 0;
461 	}
462 #undef	IS_QOS_DATA
463 
464 	return (aad_len);
465 }
466 
467 /*
468  * Populate the 12 byte / 96 bit IV buffer.
469  */
470 static int
gcmp_init_iv(uint8_t * iv,const struct ieee80211_frame * wh,u_int64_t pn)471 gcmp_init_iv(uint8_t *iv, const struct ieee80211_frame *wh, u_int64_t pn)
472 {
473 	uint8_t j_pn[GCMP_PN_LEN];
474 
475 	/* Construct the pn buffer */
476 	j_pn[0] = pn >> 40;
477 	j_pn[1] = pn >> 32;
478 	j_pn[2] = pn >> 24;
479 	j_pn[3] = pn >> 16;
480 	j_pn[4] = pn >> 8;
481 	j_pn[5] = pn >> 0;
482 
483 	memcpy(iv, wh->i_addr2, IEEE80211_ADDR_LEN);
484 	memcpy(iv + IEEE80211_ADDR_LEN, j_pn, GCMP_PN_LEN);
485 
486 	return (GCMP_IV_LEN); /* 96 bits */
487 }
488 
489 /*
490  * @brief Encrypt an mbuf.
491  *
492  * This uses a temporary memory buffer to encrypt; the
493  * current AES-GCM code expects things in a contiguous buffer
494  * and this avoids the need of breaking out the GCTR and
495  * GHASH routines into using mbuf iterators.
496  *
497  * @param key	ieee80211_key to use
498  * @param mbuf	802.11 frame to encrypt
499  * @param hdrlen	the length of the 802.11 header, including any padding
500  * @returns 0 if error, > 0 if OK.
501  */
502 static int
gcmp_encrypt(struct ieee80211_key * key,struct mbuf * m0,int hdrlen)503 gcmp_encrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen)
504 {
505 	struct gcmp_ctx *ctx = key->wk_private;
506 	struct ieee80211_frame *wh;
507 	struct mbuf *m = m0;
508 	int data_len, aad_len, iv_len, ret;
509 	uint8_t aad[GCM_AAD_LEN];
510 	uint8_t T[GCMP_MIC_LEN];
511 	uint8_t iv[GCMP_IV_LEN];
512 	uint8_t *p_pktbuf = NULL;
513 	uint8_t *c_pktbuf = NULL;
514 
515 	wh = mtod(m, struct ieee80211_frame *);
516 	data_len = m->m_pkthdr.len - (hdrlen + gcmp_get_header_len(key));
517 
518 	ctx->cc_vap->iv_stats.is_crypto_gcmp++;
519 
520 	p_pktbuf = IEEE80211_MALLOC(data_len, M_TEMP,
521 	    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
522 	if (p_pktbuf == NULL) {
523 		IEEE80211_NOTE_MAC(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
524 		    wh->i_addr2, "%s",
525 		    "AES-GCM encrypt failed; couldn't allocate buffer");
526 		ctx->cc_vap->iv_stats.is_crypto_gcmp_nomem++;
527 		return (0);
528 	}
529 	c_pktbuf = IEEE80211_MALLOC(data_len, M_TEMP,
530 	    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
531 	if (c_pktbuf == NULL) {
532 		IEEE80211_NOTE_MAC(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
533 		    wh->i_addr2, "%s",
534 		    "AES-GCM encrypt failed; couldn't allocate buffer");
535 		ctx->cc_vap->iv_stats.is_crypto_gcmp_nomem++;
536 		IEEE80211_FREE(p_pktbuf, M_TEMP);
537 		return (0);
538 	}
539 
540 	/* Initialise AAD */
541 	aad_len = gcmp_init_aad(wh, aad);
542 
543 	/* Initialise local Nonce to work on */
544 	/* TODO: rename iv stuff here to nonce */
545 	iv_len = gcmp_init_iv(iv, wh, key->wk_keytsc);
546 
547 	/* Copy mbuf data part into plaintext pktbuf */
548 	m_copydata(m0, hdrlen + gcmp_get_header_len(key), data_len,
549 	    p_pktbuf);
550 
551 	/* Run encrypt */
552 	/*
553 	 * Note: aad + 2 to skip over the 2 byte length populated
554 	 * at the beginning, since it's based on the AAD code in CCMP.
555 	 */
556 	ieee80211_crypto_aes_gcm_ae(&ctx->cc_aes, iv, iv_len,
557 	    p_pktbuf, data_len, aad + 2, aad_len, c_pktbuf, T);
558 
559 	/* Copy data back over mbuf */
560 	m_copyback(m0, hdrlen + gcmp_get_header_len(key), data_len,
561 	    c_pktbuf);
562 
563 	/* Append MIC */
564 	ret = m_append(m0, gcmp_get_trailer_len(key), T);
565 	if (ret == 0) {
566 		IEEE80211_NOTE_MAC(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
567 		    wh->i_addr2, "%s",
568 		    "AES-GCM encrypt failed; couldn't append T");
569 		ctx->cc_vap->iv_stats.is_crypto_gcmp_nospc++;
570 	}
571 
572 	IEEE80211_FREE(p_pktbuf, M_TEMP);
573 	IEEE80211_FREE(c_pktbuf, M_TEMP);
574 
575 	return (ret);
576 }
577 
578 /*
579  * @brief Decrypt an mbuf.
580  *
581  * This uses a temporary memory buffer to decrypt; the
582  * current AES-GCM code expects things in a contiguous buffer
583  * and this avoids the need of breaking out the GCTR and
584  * GHASH routines into using mbuf iterators.
585  *
586  * @param key	ieee80211_key to use
587  * @param mbuf	802.11 frame to decrypt
588  * @param hdrlen	the length of the 802.11 header, including any padding
589  * @returns 0 if error, > 0 if OK.
590  */
591 static int
gcmp_decrypt(struct ieee80211_key * key,u_int64_t pn,struct mbuf * m,int hdrlen)592 gcmp_decrypt(struct ieee80211_key *key, u_int64_t pn, struct mbuf *m,
593     int hdrlen)
594 {
595 	const struct ieee80211_rx_stats *rxs;
596 	struct gcmp_ctx *ctx = key->wk_private;
597 	struct ieee80211_frame *wh;
598 	int data_len, aad_len, iv_len, ret;
599 	uint8_t aad[GCM_AAD_LEN];
600 	uint8_t T[GCMP_MIC_LEN];
601 	uint8_t iv[GCMP_IV_LEN];
602 	uint8_t *p_pktbuf = NULL;
603 	uint8_t *c_pktbuf = NULL;
604 
605 	rxs = ieee80211_get_rx_params_ptr(m);
606 	if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_DECRYPTED) != 0)
607 		return (1);
608 
609 	wh = mtod(m, struct ieee80211_frame *);
610 
611 	/* Data length doesn't include the MIC at the end */
612 	data_len = m->m_pkthdr.len -
613 	    (hdrlen + gcmp_get_header_len(key) + GCMP_MIC_LEN);
614 
615 	ctx->cc_vap->iv_stats.is_crypto_gcmp++;
616 
617 	p_pktbuf = IEEE80211_MALLOC(data_len, M_TEMP,
618 	    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
619 	if (p_pktbuf == NULL) {
620 		ctx->cc_vap->iv_stats.is_crypto_gcmp_nomem++;
621 		return (0);
622 	}
623 	c_pktbuf = IEEE80211_MALLOC(data_len, M_TEMP,
624 	    IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
625 	if (c_pktbuf == NULL) {
626 		ctx->cc_vap->iv_stats.is_crypto_gcmp_nomem++;
627 		IEEE80211_FREE(p_pktbuf, M_TEMP);
628 		return (0);
629 	}
630 
631 	/* Initialise AAD */
632 	aad_len = gcmp_init_aad(wh, aad);
633 
634 	/* Initialise local IV copy to work on */
635 	iv_len = gcmp_init_iv(iv, wh, pn);
636 
637 	/* Copy mbuf into ciphertext pktbuf */
638 	m_copydata(m, hdrlen + gcmp_get_header_len(key), data_len,
639 	    c_pktbuf);
640 
641 	/* Copy the MIC into the tag buffer */
642 	m_copydata(m, hdrlen + gcmp_get_header_len(key) + data_len,
643 	    GCMP_MIC_LEN, T);
644 
645 	/* Run decrypt */
646 	/*
647 	 * Note: aad + 2 to skip over the 2 byte length populated
648 	 * at the beginning, since it's based on the AAD code in CCMP.
649 	 */
650 	ret = ieee80211_crypto_aes_gcm_ad(&ctx->cc_aes, iv, iv_len,
651 	    c_pktbuf, data_len, aad + 2, aad_len, T, p_pktbuf);
652 
653 	/* If the MIC was stripped by HW/driver we are done. */
654 	if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_MIC_STRIP) != 0)
655 		goto skip_ok;
656 
657 	if (ret != 0) {
658 		/* Decrypt failure */
659 		ctx->cc_vap->iv_stats.is_rx_gcmpmic++;
660 		IEEE80211_NOTE_MAC(ctx->cc_vap, IEEE80211_MSG_CRYPTO,
661 		    wh->i_addr2, "%s", "AES-GCM decrypt failed; MIC mismatch");
662 		IEEE80211_FREE(p_pktbuf, M_TEMP);
663 		IEEE80211_FREE(c_pktbuf, M_TEMP);
664 		return (0);
665 	}
666 
667 skip_ok:
668 	/* Copy data back over mbuf */
669 	m_copyback(m, hdrlen + gcmp_get_header_len(key), data_len,
670 	    p_pktbuf);
671 
672 	IEEE80211_FREE(p_pktbuf, M_TEMP);
673 	IEEE80211_FREE(c_pktbuf, M_TEMP);
674 
675 	return (1);
676 }
677 
678 /*
679  * Module glue.
680  */
681 IEEE80211_CRYPTO_MODULE(gcmp, 1);
682 IEEE80211_CRYPTO_MODULE_ADD(gcmp_256);
683