xref: /wlan-driver/qca-wifi-host-cmn/qdf/linux/src/qdf_crypto.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  * DOC: qdf_crypto.c
22*5113495bSYour Name  *
23*5113495bSYour Name  * This source file contains linux specific definitions for QDF crypto APIs
24*5113495bSYour Name  */
25*5113495bSYour Name 
26*5113495bSYour Name /* Include Files */
27*5113495bSYour Name #include "qdf_crypto.h"
28*5113495bSYour Name #include <linux/export.h>
29*5113495bSYour Name #include <crypto/hash.h>
30*5113495bSYour Name #include <crypto/aes.h>
31*5113495bSYour Name #include <crypto/skcipher.h>
32*5113495bSYour Name #include <crypto/aead.h>
33*5113495bSYour Name #include <linux/ieee80211.h>
34*5113495bSYour Name #include <qdf_module.h>
35*5113495bSYour Name 
36*5113495bSYour Name /* Function Definitions and Documentation */
37*5113495bSYour Name #define MAX_HMAC_ELEMENT_CNT 10
38*5113495bSYour Name 
39*5113495bSYour Name /*
40*5113495bSYour Name  * xor: API to calculate xor
41*5113495bSYour Name  * @a: first variable
42*5113495bSYour Name  * @b: second variable
43*5113495bSYour Name  * @len: length of variables
44*5113495bSYour Name  */
xor(uint8_t * a,const uint8_t * b,size_t len)45*5113495bSYour Name static void xor(uint8_t *a, const uint8_t *b, size_t len)
46*5113495bSYour Name {
47*5113495bSYour Name 	unsigned int i;
48*5113495bSYour Name 
49*5113495bSYour Name 	for (i = 0; i < len; i++)
50*5113495bSYour Name 	a[i] ^= b[i];
51*5113495bSYour Name }
52*5113495bSYour Name 
qdf_get_hash(uint8_t * type,uint8_t element_cnt,uint8_t * addr[],uint32_t * addr_len,int8_t * hash)53*5113495bSYour Name int qdf_get_hash(uint8_t *type,
54*5113495bSYour Name 		uint8_t element_cnt, uint8_t *addr[], uint32_t *addr_len,
55*5113495bSYour Name 		int8_t *hash)
56*5113495bSYour Name {
57*5113495bSYour Name 	return qdf_get_hmac_hash(type, NULL, 0, element_cnt,
58*5113495bSYour Name 				 addr, addr_len, hash);
59*5113495bSYour Name }
60*5113495bSYour Name 
qdf_get_hmac_hash(uint8_t * type,uint8_t * key,uint32_t keylen,uint8_t element_cnt,uint8_t * addr[],uint32_t * addr_len,int8_t * hash)61*5113495bSYour Name int qdf_get_hmac_hash(uint8_t *type, uint8_t *key,
62*5113495bSYour Name 		uint32_t keylen,
63*5113495bSYour Name 		uint8_t element_cnt, uint8_t *addr[], uint32_t *addr_len,
64*5113495bSYour Name 		int8_t *hash)
65*5113495bSYour Name {
66*5113495bSYour Name 	int i;
67*5113495bSYour Name 	size_t src_len[MAX_HMAC_ELEMENT_CNT];
68*5113495bSYour Name 
69*5113495bSYour Name 	if (element_cnt > MAX_HMAC_ELEMENT_CNT) {
70*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
71*5113495bSYour Name 			  FL("Invalid element count %d"), element_cnt);
72*5113495bSYour Name 		return -EINVAL;
73*5113495bSYour Name 	}
74*5113495bSYour Name 
75*5113495bSYour Name 	for (i = 0; i < element_cnt; i++)
76*5113495bSYour Name 		src_len[i] = addr_len[i];
77*5113495bSYour Name 
78*5113495bSYour Name 	return qdf_get_keyed_hash(type, key, keylen, (const uint8_t **)addr,
79*5113495bSYour Name 				  src_len, element_cnt,  hash);
80*5113495bSYour Name }
81*5113495bSYour Name 
82*5113495bSYour Name QDF_STATUS
qdf_default_hmac_sha256_kdf(uint8_t * secret,uint32_t secret_len,uint8_t * label,uint8_t * optional_data,uint32_t optional_data_len,uint8_t * key,uint32_t keylen)83*5113495bSYour Name qdf_default_hmac_sha256_kdf(uint8_t *secret, uint32_t secret_len,
84*5113495bSYour Name 			    uint8_t *label, uint8_t *optional_data,
85*5113495bSYour Name 			    uint32_t optional_data_len, uint8_t *key,
86*5113495bSYour Name 			    uint32_t keylen)
87*5113495bSYour Name {
88*5113495bSYour Name 	uint8_t tmp_hash[SHA256_DIGEST_SIZE] = {0};
89*5113495bSYour Name 	uint8_t count = 1;
90*5113495bSYour Name 	uint8_t *addr[4];
91*5113495bSYour Name 	uint32_t len[4];
92*5113495bSYour Name 	uint32_t current_position = 0, remaining_data = SHA256_DIGEST_SIZE;
93*5113495bSYour Name 
94*5113495bSYour Name 	addr[0] = tmp_hash;
95*5113495bSYour Name 	len[0] = SHA256_DIGEST_SIZE;
96*5113495bSYour Name 	addr[1] = label;
97*5113495bSYour Name 	len[1] = strlen(label) + 1;
98*5113495bSYour Name 	addr[2] = optional_data;
99*5113495bSYour Name 	len[2] = optional_data_len;
100*5113495bSYour Name 	addr[3] = &count;
101*5113495bSYour Name 	len[3] = 1;
102*5113495bSYour Name 
103*5113495bSYour Name 	if (keylen == 0 ||
104*5113495bSYour Name 	    (keylen > (WLAN_MAX_PRF_INTERATIONS_COUNT * SHA256_DIGEST_SIZE))) {
105*5113495bSYour Name 		qdf_err("invalid key length %d", keylen);
106*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
107*5113495bSYour Name 	}
108*5113495bSYour Name 
109*5113495bSYour Name 	/* Create T1 */
110*5113495bSYour Name 	if (qdf_get_hmac_hash(HMAC_SHA256_CRYPTO_TYPE, secret, secret_len, 3,
111*5113495bSYour Name 			      &addr[1], &len[1], tmp_hash) < 0) {
112*5113495bSYour Name 		qdf_err("failed to get hmac hash");
113*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
114*5113495bSYour Name 	}
115*5113495bSYour Name 
116*5113495bSYour Name 	/* Update hash from tmp_hash */
117*5113495bSYour Name 	qdf_mem_copy(key + current_position, tmp_hash, remaining_data);
118*5113495bSYour Name 	current_position += remaining_data;
119*5113495bSYour Name 
120*5113495bSYour Name 	for (count = 2; current_position < keylen; count++) {
121*5113495bSYour Name 		remaining_data = keylen - current_position;
122*5113495bSYour Name 		if (remaining_data > SHA256_DIGEST_SIZE)
123*5113495bSYour Name 			remaining_data = SHA256_DIGEST_SIZE;
124*5113495bSYour Name 
125*5113495bSYour Name 		/* Create T-n */
126*5113495bSYour Name 		if (qdf_get_hmac_hash(HMAC_SHA256_CRYPTO_TYPE, secret,
127*5113495bSYour Name 				      secret_len, 4, addr, len, tmp_hash) < 0) {
128*5113495bSYour Name 			qdf_err("failed to get hmac hash");
129*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
130*5113495bSYour Name 		}
131*5113495bSYour Name 		/* Update hash from tmp_hash */
132*5113495bSYour Name 		qdf_mem_copy(key + current_position, tmp_hash, remaining_data);
133*5113495bSYour Name 		current_position += remaining_data;
134*5113495bSYour Name 	}
135*5113495bSYour Name 
136*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
137*5113495bSYour Name }
138*5113495bSYour Name 
139*5113495bSYour Name /* qdf_update_dbl from RFC 5297. Length of d is AES_BLOCK_SIZE (128 bits) */
qdf_update_dbl(uint8_t * d)140*5113495bSYour Name void qdf_update_dbl(uint8_t *d)
141*5113495bSYour Name {
142*5113495bSYour Name 	int i;
143*5113495bSYour Name 	uint8_t msb, msb_prev = 0;
144*5113495bSYour Name 
145*5113495bSYour Name 	/* left shift by 1 */
146*5113495bSYour Name 	for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
147*5113495bSYour Name 		msb = d[i] & 0x80;
148*5113495bSYour Name 		d[i] = d[i] << 1;
149*5113495bSYour Name 		d[i] += msb_prev ? 1 : 0;
150*5113495bSYour Name 		msb_prev = msb;
151*5113495bSYour Name 	}
152*5113495bSYour Name 
153*5113495bSYour Name 	if (msb)
154*5113495bSYour Name 		d[AES_BLOCK_SIZE - 1] ^= 0x87;
155*5113495bSYour Name }
156*5113495bSYour Name 
xor_128(const uint8_t * a,const uint8_t * b,uint8_t * out)157*5113495bSYour Name static inline void xor_128(const uint8_t *a, const uint8_t *b, uint8_t *out)
158*5113495bSYour Name {
159*5113495bSYour Name 	uint8_t i;
160*5113495bSYour Name 
161*5113495bSYour Name 	for (i = 0; i < AES_BLOCK_SIZE; i++)
162*5113495bSYour Name 		out[i] = a[i] ^ b[i];
163*5113495bSYour Name }
164*5113495bSYour Name 
leftshift_onebit(const uint8_t * input,uint8_t * output)165*5113495bSYour Name static inline void leftshift_onebit(const uint8_t *input, uint8_t *output)
166*5113495bSYour Name {
167*5113495bSYour Name 	int i, overflow = 0;
168*5113495bSYour Name 
169*5113495bSYour Name 	for (i = (AES_BLOCK_SIZE - 1); i >= 0; i--) {
170*5113495bSYour Name 		output[i] = input[i] << 1;
171*5113495bSYour Name 		output[i] |= overflow;
172*5113495bSYour Name 		overflow = (input[i] & 0x80) ? 1 : 0;
173*5113495bSYour Name 	}
174*5113495bSYour Name }
175*5113495bSYour Name 
176*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
177*5113495bSYour Name static void
generate_subkey(struct crypto_aes_ctx * aes_ctx,uint8_t * k1,uint8_t * k2)178*5113495bSYour Name generate_subkey(struct crypto_aes_ctx *aes_ctx, uint8_t *k1, uint8_t *k2)
179*5113495bSYour Name {
180*5113495bSYour Name 	uint8_t l[AES_BLOCK_SIZE] = {
181*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
183*5113495bSYour Name 	};
184*5113495bSYour Name 	uint8_t tmp[AES_BLOCK_SIZE];
185*5113495bSYour Name 	const uint8_t const_rb[AES_BLOCK_SIZE] = {
186*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
188*5113495bSYour Name 	};
189*5113495bSYour Name 	const uint8_t const_zero[AES_BLOCK_SIZE] = {
190*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
192*5113495bSYour Name 	};
193*5113495bSYour Name 
194*5113495bSYour Name 	aes_encrypt(aes_ctx, l, const_zero);
195*5113495bSYour Name 
196*5113495bSYour Name 	if ((l[0] & 0x80) == 0) {       /* If MSB(l) = 0, then k1 = l << 1 */
197*5113495bSYour Name 		leftshift_onebit(l, k1);
198*5113495bSYour Name 	} else {                /* Else k1 = ( l << 1 ) (+) Rb */
199*5113495bSYour Name 		leftshift_onebit(l, tmp);
200*5113495bSYour Name 		xor_128(tmp, const_rb, k1);
201*5113495bSYour Name 	}
202*5113495bSYour Name 
203*5113495bSYour Name 	if ((k1[0] & 0x80) == 0) {
204*5113495bSYour Name 		leftshift_onebit(k1, k2);
205*5113495bSYour Name 	} else {
206*5113495bSYour Name 		leftshift_onebit(k1, tmp);
207*5113495bSYour Name 		xor_128(tmp, const_rb, k2);
208*5113495bSYour Name 	}
209*5113495bSYour Name }
210*5113495bSYour Name #else
211*5113495bSYour Name static void
generate_subkey(struct crypto_cipher * tfm,uint8_t * k1,uint8_t * k2)212*5113495bSYour Name generate_subkey(struct crypto_cipher *tfm, uint8_t *k1, uint8_t *k2)
213*5113495bSYour Name {
214*5113495bSYour Name 	uint8_t l[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
215*5113495bSYour Name 	const uint8_t const_rb[AES_BLOCK_SIZE] = {
216*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
218*5113495bSYour Name 	};
219*5113495bSYour Name 	const uint8_t const_zero[AES_BLOCK_SIZE] = {
220*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221*5113495bSYour Name 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
222*5113495bSYour Name 	};
223*5113495bSYour Name 
224*5113495bSYour Name 	crypto_cipher_encrypt_one(tfm, l, const_zero);
225*5113495bSYour Name 
226*5113495bSYour Name 	if ((l[0] & 0x80) == 0) {       /* If MSB(l) = 0, then k1 = l << 1 */
227*5113495bSYour Name 		leftshift_onebit(l, k1);
228*5113495bSYour Name 	} else {                /* Else k1 = ( l << 1 ) (+) Rb */
229*5113495bSYour Name 		leftshift_onebit(l, tmp);
230*5113495bSYour Name 		xor_128(tmp, const_rb, k1);
231*5113495bSYour Name 	}
232*5113495bSYour Name 
233*5113495bSYour Name 	if ((k1[0] & 0x80) == 0) {
234*5113495bSYour Name 		leftshift_onebit(k1, k2);
235*5113495bSYour Name 	} else {
236*5113495bSYour Name 		leftshift_onebit(k1, tmp);
237*5113495bSYour Name 		xor_128(tmp, const_rb, k2);
238*5113495bSYour Name 	}
239*5113495bSYour Name }
240*5113495bSYour Name #endif
241*5113495bSYour Name 
padding(const uint8_t * lastb,uint8_t * pad,uint16_t length)242*5113495bSYour Name static inline void padding(const uint8_t *lastb, uint8_t *pad, uint16_t length)
243*5113495bSYour Name {
244*5113495bSYour Name 	uint8_t j;
245*5113495bSYour Name 
246*5113495bSYour Name 	/* original last block */
247*5113495bSYour Name 	for (j = 0; j < AES_BLOCK_SIZE; j++) {
248*5113495bSYour Name 		if (j < length)
249*5113495bSYour Name 			pad[j] = lastb[j];
250*5113495bSYour Name 		else if (j == length)
251*5113495bSYour Name 			pad[j] = 0x80;
252*5113495bSYour Name 		else
253*5113495bSYour Name 			pad[j] = 0x00;
254*5113495bSYour Name 	}
255*5113495bSYour Name }
256*5113495bSYour Name 
257*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
qdf_crypto_aes_128_cmac(const uint8_t * key,const uint8_t * data,uint16_t len,uint8_t * mic)258*5113495bSYour Name int qdf_crypto_aes_128_cmac(const uint8_t *key, const uint8_t *data,
259*5113495bSYour Name 			    uint16_t len, uint8_t *mic)
260*5113495bSYour Name {
261*5113495bSYour Name 	uint8_t x[AES_BLOCK_SIZE], y[AES_BLOCK_SIZE];
262*5113495bSYour Name 	uint8_t m_last[AES_BLOCK_SIZE], padded[AES_BLOCK_SIZE];
263*5113495bSYour Name 	uint8_t k1[AES_KEYSIZE_128], k2[AES_KEYSIZE_128];
264*5113495bSYour Name 	int cmp_blk;
265*5113495bSYour Name 	int i, num_block = (len + 15) / AES_BLOCK_SIZE;
266*5113495bSYour Name 	struct crypto_aes_ctx aes_ctx;
267*5113495bSYour Name 	int ret;
268*5113495bSYour Name 
269*5113495bSYour Name 	/*
270*5113495bSYour Name 	 * Calculate MIC and then copy
271*5113495bSYour Name 	 */
272*5113495bSYour Name 	ret = aes_expandkey(&aes_ctx, key, AES_KEYSIZE_128);
273*5113495bSYour Name 	if (ret) {
274*5113495bSYour Name 		qdf_err("aes_expandkey failed (%d)", ret);
275*5113495bSYour Name 		return ret;
276*5113495bSYour Name 	}
277*5113495bSYour Name 
278*5113495bSYour Name 	generate_subkey(&aes_ctx, k1, k2);
279*5113495bSYour Name 
280*5113495bSYour Name 	if (num_block == 0) {
281*5113495bSYour Name 		num_block = 1;
282*5113495bSYour Name 		cmp_blk = 0;
283*5113495bSYour Name 	} else {
284*5113495bSYour Name 		cmp_blk = ((len % AES_BLOCK_SIZE) == 0) ? 1 : 0;
285*5113495bSYour Name 	}
286*5113495bSYour Name 
287*5113495bSYour Name 	if (cmp_blk) {
288*5113495bSYour Name 		/* Last block is complete block */
289*5113495bSYour Name 		xor_128(&data[AES_BLOCK_SIZE * (num_block - 1)], k1, m_last);
290*5113495bSYour Name 	} else {
291*5113495bSYour Name 		/* Last block is not complete block */
292*5113495bSYour Name 		padding(&data[AES_BLOCK_SIZE * (num_block - 1)], padded,
293*5113495bSYour Name 			len % AES_BLOCK_SIZE);
294*5113495bSYour Name 		xor_128(padded, k2, m_last);
295*5113495bSYour Name 	}
296*5113495bSYour Name 
297*5113495bSYour Name 	for (i = 0; i < AES_BLOCK_SIZE; i++)
298*5113495bSYour Name 		x[i] = 0;
299*5113495bSYour Name 
300*5113495bSYour Name 	for (i = 0; i < (num_block - 1); i++) {
301*5113495bSYour Name 		/* y = Mi (+) x */
302*5113495bSYour Name 		xor_128(x, &data[AES_BLOCK_SIZE * i], y);
303*5113495bSYour Name 		/* x = AES-128(KEY, y) */
304*5113495bSYour Name 		aes_encrypt(&aes_ctx, x, y);
305*5113495bSYour Name 	}
306*5113495bSYour Name 
307*5113495bSYour Name 	xor_128(x, m_last, y);
308*5113495bSYour Name 	aes_encrypt(&aes_ctx, x, y);
309*5113495bSYour Name 	memzero_explicit(&aes_ctx, sizeof(aes_ctx));
310*5113495bSYour Name 
311*5113495bSYour Name 	memcpy(mic, x, CMAC_TLEN);
312*5113495bSYour Name 
313*5113495bSYour Name 	return 0;
314*5113495bSYour Name }
315*5113495bSYour Name #else
qdf_crypto_aes_128_cmac(const uint8_t * key,const uint8_t * data,uint16_t len,uint8_t * mic)316*5113495bSYour Name int qdf_crypto_aes_128_cmac(const uint8_t *key, const uint8_t *data,
317*5113495bSYour Name 			    uint16_t len, uint8_t *mic)
318*5113495bSYour Name {
319*5113495bSYour Name 	uint8_t x[AES_BLOCK_SIZE], y[AES_BLOCK_SIZE];
320*5113495bSYour Name 	uint8_t m_last[AES_BLOCK_SIZE], padded[AES_BLOCK_SIZE];
321*5113495bSYour Name 	uint8_t k1[AES_KEYSIZE_128], k2[AES_KEYSIZE_128];
322*5113495bSYour Name 	int cmp_blk;
323*5113495bSYour Name 	int i, num_block = (len + 15) / AES_BLOCK_SIZE;
324*5113495bSYour Name 	struct crypto_cipher *tfm;
325*5113495bSYour Name 	int ret;
326*5113495bSYour Name 
327*5113495bSYour Name 	/*
328*5113495bSYour Name 	 * Calculate MIC and then copy
329*5113495bSYour Name 	 */
330*5113495bSYour Name 	tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
331*5113495bSYour Name 	if (IS_ERR(tfm)) {
332*5113495bSYour Name 		ret = PTR_ERR(tfm);
333*5113495bSYour Name 		qdf_err("crypto_alloc_cipher failed (%d)", ret);
334*5113495bSYour Name 		return ret;
335*5113495bSYour Name 	}
336*5113495bSYour Name 
337*5113495bSYour Name 	ret = crypto_cipher_setkey(tfm, key, AES_KEYSIZE_128);
338*5113495bSYour Name 	if (ret) {
339*5113495bSYour Name 		qdf_err("crypto_cipher_setkey failed (%d)", ret);
340*5113495bSYour Name 		crypto_free_cipher(tfm);
341*5113495bSYour Name 		return ret;
342*5113495bSYour Name 	}
343*5113495bSYour Name 
344*5113495bSYour Name 	generate_subkey(tfm, k1, k2);
345*5113495bSYour Name 
346*5113495bSYour Name 	if (num_block == 0) {
347*5113495bSYour Name 		num_block = 1;
348*5113495bSYour Name 		cmp_blk = 0;
349*5113495bSYour Name 	} else {
350*5113495bSYour Name 		cmp_blk = ((len % AES_BLOCK_SIZE) == 0) ? 1 : 0;
351*5113495bSYour Name 	}
352*5113495bSYour Name 
353*5113495bSYour Name 	if (cmp_blk) {
354*5113495bSYour Name 		/* Last block is complete block */
355*5113495bSYour Name 		xor_128(&data[AES_BLOCK_SIZE * (num_block - 1)], k1, m_last);
356*5113495bSYour Name 	} else {
357*5113495bSYour Name 		/* Last block is not complete block */
358*5113495bSYour Name 		padding(&data[AES_BLOCK_SIZE * (num_block - 1)], padded,
359*5113495bSYour Name 			len % AES_BLOCK_SIZE);
360*5113495bSYour Name 		xor_128(padded, k2, m_last);
361*5113495bSYour Name 	}
362*5113495bSYour Name 
363*5113495bSYour Name 	for (i = 0; i < AES_BLOCK_SIZE; i++)
364*5113495bSYour Name 		x[i] = 0;
365*5113495bSYour Name 
366*5113495bSYour Name 	for (i = 0; i < (num_block - 1); i++) {
367*5113495bSYour Name 		/* y = Mi (+) x */
368*5113495bSYour Name 		xor_128(x, &data[AES_BLOCK_SIZE * i], y);
369*5113495bSYour Name 		/* x = AES-128(KEY, y) */
370*5113495bSYour Name 		crypto_cipher_encrypt_one(tfm, x, y);
371*5113495bSYour Name 	}
372*5113495bSYour Name 
373*5113495bSYour Name 	xor_128(x, m_last, y);
374*5113495bSYour Name 	crypto_cipher_encrypt_one(tfm, x, y);
375*5113495bSYour Name 
376*5113495bSYour Name 	crypto_free_cipher(tfm);
377*5113495bSYour Name 
378*5113495bSYour Name 	memcpy(mic, x, CMAC_TLEN);
379*5113495bSYour Name 
380*5113495bSYour Name 	return 0;
381*5113495bSYour Name }
382*5113495bSYour Name #endif
383*5113495bSYour Name 
384*5113495bSYour Name /**
385*5113495bSYour Name  * set_desc_flags() - set flags variable in the shash_desc struct
386*5113495bSYour Name  * @desc: pointer to shash_desc struct
387*5113495bSYour Name  * @tfm: pointer to crypto_shash struct
388*5113495bSYour Name  *
389*5113495bSYour Name  * Set the flags variable in the shash_desc struct by getting the flag
390*5113495bSYour Name  * from the crypto_hash struct. The flag is not actually used, prompting
391*5113495bSYour Name  * its removal from kernel code in versions 5.2 and above. Thus, for
392*5113495bSYour Name  * versions 5.2 and above, do not set the flag variable of shash_desc.
393*5113495bSYour Name  */
394*5113495bSYour Name #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0))
set_desc_flags(struct shash_desc * desc,struct crypto_shash * tfm)395*5113495bSYour Name static void set_desc_flags(struct shash_desc *desc, struct crypto_shash *tfm)
396*5113495bSYour Name {
397*5113495bSYour Name 	desc->flags = crypto_shash_get_flags(tfm);
398*5113495bSYour Name }
399*5113495bSYour Name #else
set_desc_flags(struct shash_desc * desc,struct crypto_shash * tfm)400*5113495bSYour Name static void set_desc_flags(struct shash_desc *desc, struct crypto_shash *tfm)
401*5113495bSYour Name {
402*5113495bSYour Name }
403*5113495bSYour Name #endif
404*5113495bSYour Name 
qdf_get_keyed_hash(const char * alg,const uint8_t * key,unsigned int key_len,const uint8_t * src[],size_t * src_len,size_t num_elements,uint8_t * out)405*5113495bSYour Name int qdf_get_keyed_hash(const char *alg, const uint8_t *key,
406*5113495bSYour Name 			unsigned int key_len, const uint8_t *src[],
407*5113495bSYour Name 			size_t *src_len, size_t num_elements, uint8_t *out)
408*5113495bSYour Name {
409*5113495bSYour Name 	struct crypto_shash *tfm;
410*5113495bSYour Name 	int ret;
411*5113495bSYour Name 	size_t i;
412*5113495bSYour Name 
413*5113495bSYour Name 	tfm = crypto_alloc_shash(alg, 0, CRYPTO_ALG_ASYNC);
414*5113495bSYour Name 	if (IS_ERR(tfm)) {
415*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
416*5113495bSYour Name 			  FL("Failed to allocate transformation for %s: %ld"),
417*5113495bSYour Name 			  alg, PTR_ERR(tfm));
418*5113495bSYour Name 		return -EINVAL;
419*5113495bSYour Name 	}
420*5113495bSYour Name 
421*5113495bSYour Name 	if (key && key_len) {
422*5113495bSYour Name 		ret = crypto_shash_setkey(tfm, key, key_len);
423*5113495bSYour Name 		if (ret) {
424*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
425*5113495bSYour Name 				  FL("Set key failed for %s, ret:%d"),
426*5113495bSYour Name 				  alg, -ret);
427*5113495bSYour Name 			goto error;
428*5113495bSYour Name 		}
429*5113495bSYour Name 	}
430*5113495bSYour Name 
431*5113495bSYour Name 	do {
432*5113495bSYour Name 		SHASH_DESC_ON_STACK(desc, tfm);
433*5113495bSYour Name 		desc->tfm = tfm;
434*5113495bSYour Name 		set_desc_flags(desc, tfm);
435*5113495bSYour Name 
436*5113495bSYour Name 		ret = crypto_shash_init(desc);
437*5113495bSYour Name 		if (ret) {
438*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
439*5113495bSYour Name 				  FL("Failed to init hash for %s, ret:%d"),
440*5113495bSYour Name 				  alg, -ret);
441*5113495bSYour Name 			goto error;
442*5113495bSYour Name 		}
443*5113495bSYour Name 
444*5113495bSYour Name 		for (i = 0; i < num_elements; i++) {
445*5113495bSYour Name 			ret = crypto_shash_update(desc, src[i], src_len[i]);
446*5113495bSYour Name 			if (ret) {
447*5113495bSYour Name 				QDF_TRACE(QDF_MODULE_ID_QDF,
448*5113495bSYour Name 					  QDF_TRACE_LEVEL_ERROR,
449*5113495bSYour Name 					  FL("Failed to update hash for %s, ret:%d"),
450*5113495bSYour Name 					  alg, -ret);
451*5113495bSYour Name 				goto error;
452*5113495bSYour Name 			}
453*5113495bSYour Name 		}
454*5113495bSYour Name 
455*5113495bSYour Name 		ret = crypto_shash_final(desc, out);
456*5113495bSYour Name 		if (ret)
457*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
458*5113495bSYour Name 				  FL("Failed to get digest for %s, ret:%d"),
459*5113495bSYour Name 				  alg, -ret);
460*5113495bSYour Name 	} while (0);
461*5113495bSYour Name 
462*5113495bSYour Name error:
463*5113495bSYour Name 	crypto_free_shash(tfm);
464*5113495bSYour Name 	return ret;
465*5113495bSYour Name }
466*5113495bSYour Name 
467*5113495bSYour Name qdf_export_symbol(qdf_get_keyed_hash);
468*5113495bSYour Name 
469*5113495bSYour Name /* AES String to Vector from RFC 5297, 'out' should be of length AES_BLOCK_SIZE
470*5113495bSYour Name  */
qdf_aes_s2v(const uint8_t * key,unsigned int key_len,const uint8_t * s[],size_t s_len[],size_t num_s,uint8_t * out)471*5113495bSYour Name int qdf_aes_s2v(const uint8_t *key, unsigned int key_len, const uint8_t *s[],
472*5113495bSYour Name 		   size_t s_len[], size_t num_s, uint8_t *out)
473*5113495bSYour Name {
474*5113495bSYour Name 	const char *alg = "cmac(aes)";
475*5113495bSYour Name 	uint8_t d[AES_BLOCK_SIZE];
476*5113495bSYour Name 	uint8_t buf[AES_BLOCK_SIZE] = { 0 };
477*5113495bSYour Name 	size_t buf_len = AES_BLOCK_SIZE;
478*5113495bSYour Name 	const uint8_t *a[1];
479*5113495bSYour Name 	unsigned int i;
480*5113495bSYour Name 	uint8_t *t = NULL;
481*5113495bSYour Name 	size_t t_len;
482*5113495bSYour Name 	int ret;
483*5113495bSYour Name 
484*5113495bSYour Name 	if (num_s == 0) {
485*5113495bSYour Name 		/* V = AES-CMAC(K, <one>) */
486*5113495bSYour Name 		buf[0] = 0x01;
487*5113495bSYour Name 		a[0] = buf;
488*5113495bSYour Name 		ret = qdf_get_keyed_hash(alg, key, key_len, a, &buf_len, 1,
489*5113495bSYour Name 					 out);
490*5113495bSYour Name 		return ret;
491*5113495bSYour Name 	}
492*5113495bSYour Name 
493*5113495bSYour Name 	/* D = AES-CMAC(K, <zero>) */
494*5113495bSYour Name 	a[0] = buf;
495*5113495bSYour Name 	ret = qdf_get_keyed_hash(alg, key, key_len, a, &buf_len, 1, d);
496*5113495bSYour Name 	if (ret)
497*5113495bSYour Name 		goto error;
498*5113495bSYour Name 
499*5113495bSYour Name 	for (i = 0; i < num_s - 1; i++) {
500*5113495bSYour Name 		/* D = qdf_update_dbl(D) xor AES-CMAC(K, Si) */
501*5113495bSYour Name 		qdf_update_dbl(d);
502*5113495bSYour Name 		ret = qdf_get_keyed_hash(alg, key, key_len, &s[i], &s_len[i], 1,
503*5113495bSYour Name 					 buf);
504*5113495bSYour Name 		if (ret)
505*5113495bSYour Name 			goto error;
506*5113495bSYour Name 		xor(d, buf, AES_BLOCK_SIZE);
507*5113495bSYour Name 	}
508*5113495bSYour Name 
509*5113495bSYour Name 	if (s_len[i] >= AES_BLOCK_SIZE) {
510*5113495bSYour Name 		/* len(Sn) >= 128 */
511*5113495bSYour Name 		/* T = Sn xorend D */
512*5113495bSYour Name 		t = qdf_mem_malloc(s_len[i]);
513*5113495bSYour Name 		if (!t)
514*5113495bSYour Name 			return -EINVAL;
515*5113495bSYour Name 		qdf_mem_copy(t, s[i], s_len[i]);
516*5113495bSYour Name 		xor(t + s_len[i] - AES_BLOCK_SIZE, d, AES_BLOCK_SIZE);
517*5113495bSYour Name 		t_len = s_len[i];
518*5113495bSYour Name 	} else {
519*5113495bSYour Name 		/* len(Sn) < 128 */
520*5113495bSYour Name 		/* T = qdf_update_dbl(D) xor pad(Sn) */
521*5113495bSYour Name 		qdf_update_dbl(d);
522*5113495bSYour Name 		qdf_mem_zero(buf, AES_BLOCK_SIZE);
523*5113495bSYour Name 		qdf_mem_copy(buf, s[i], s_len[i]);
524*5113495bSYour Name 		buf[s_len[i]] = 0x80;
525*5113495bSYour Name 		xor(d, s[i], AES_BLOCK_SIZE);
526*5113495bSYour Name 		t = d;
527*5113495bSYour Name 		t_len = AES_BLOCK_SIZE;
528*5113495bSYour Name 	}
529*5113495bSYour Name 
530*5113495bSYour Name 	/* V = AES-CMAC(K, T) */
531*5113495bSYour Name 	a[0] = t;
532*5113495bSYour Name 	ret = qdf_get_keyed_hash(alg, key, key_len, a, &t_len, 1, out);
533*5113495bSYour Name 
534*5113495bSYour Name error:
535*5113495bSYour Name 	if (t && t != d)
536*5113495bSYour Name 		qdf_mem_free(t);
537*5113495bSYour Name 	return ret;
538*5113495bSYour Name }
539*5113495bSYour Name 
540*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0))
qdf_aes_ctr(const uint8_t * key,unsigned int key_len,uint8_t * siv,const uint8_t * src,size_t src_len,uint8_t * dest,bool enc)541*5113495bSYour Name int qdf_aes_ctr(const uint8_t *key, unsigned int key_len, uint8_t *siv,
542*5113495bSYour Name 		const uint8_t *src, size_t src_len, uint8_t *dest, bool enc)
543*5113495bSYour Name {
544*5113495bSYour Name 	struct crypto_skcipher *tfm;
545*5113495bSYour Name 	struct skcipher_request *req = NULL;
546*5113495bSYour Name 	struct scatterlist sg_in, sg_out;
547*5113495bSYour Name 	int ret;
548*5113495bSYour Name 
549*5113495bSYour Name 	if (!IS_VALID_CTR_KEY_LEN(key_len)) {
550*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
551*5113495bSYour Name 			  FL("Invalid key length: %u"), key_len);
552*5113495bSYour Name 		return -EINVAL;
553*5113495bSYour Name 	}
554*5113495bSYour Name 
555*5113495bSYour Name 	tfm = crypto_alloc_skcipher("ctr(aes)", 0, CRYPTO_ALG_ASYNC);
556*5113495bSYour Name 	if (IS_ERR(tfm)) {
557*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
558*5113495bSYour Name 			  FL("Failed to alloc transformation for ctr(aes):%ld"),
559*5113495bSYour Name 			  PTR_ERR(tfm));
560*5113495bSYour Name 		return -EAGAIN;
561*5113495bSYour Name 	}
562*5113495bSYour Name 
563*5113495bSYour Name 	req = skcipher_request_alloc(tfm, GFP_KERNEL);
564*5113495bSYour Name 	if (!req) {
565*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
566*5113495bSYour Name 			  FL("Failed to allocate request for ctr(aes)"));
567*5113495bSYour Name 		crypto_free_skcipher(tfm);
568*5113495bSYour Name 		return -EAGAIN;
569*5113495bSYour Name 	}
570*5113495bSYour Name 
571*5113495bSYour Name 	ret = crypto_skcipher_setkey(tfm, key, key_len);
572*5113495bSYour Name 	if (ret) {
573*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
574*5113495bSYour Name 			  FL("Set key failed for ctr(aes), ret:%d"), -ret);
575*5113495bSYour Name 		skcipher_request_free(req);
576*5113495bSYour Name 		crypto_free_skcipher(tfm);
577*5113495bSYour Name 		return ret;
578*5113495bSYour Name 	}
579*5113495bSYour Name 
580*5113495bSYour Name 	sg_init_one(&sg_in, src, src_len);
581*5113495bSYour Name 	sg_init_one(&sg_out, dest, src_len);
582*5113495bSYour Name 	skcipher_request_set_crypt(req, &sg_in, &sg_out, src_len, siv);
583*5113495bSYour Name 
584*5113495bSYour Name 	if (enc)
585*5113495bSYour Name 		ret = crypto_skcipher_encrypt(req);
586*5113495bSYour Name 	else
587*5113495bSYour Name 		ret = crypto_skcipher_decrypt(req);
588*5113495bSYour Name 
589*5113495bSYour Name 	if (ret) {
590*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
591*5113495bSYour Name 			  FL("%s failed for ctr(aes), ret:%d"),
592*5113495bSYour Name 			  enc ? "Encryption" : "Decryption", -ret);
593*5113495bSYour Name 	}
594*5113495bSYour Name 
595*5113495bSYour Name 	skcipher_request_free(req);
596*5113495bSYour Name 	crypto_free_skcipher(tfm);
597*5113495bSYour Name 	return ret;
598*5113495bSYour Name }
599*5113495bSYour Name #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
qdf_aes_ctr(const uint8_t * key,unsigned int key_len,uint8_t * siv,const uint8_t * src,size_t src_len,uint8_t * dest,bool enc)600*5113495bSYour Name int qdf_aes_ctr(const uint8_t *key, unsigned int key_len, uint8_t *siv,
601*5113495bSYour Name 		const uint8_t *src, size_t src_len, uint8_t *dest, bool enc)
602*5113495bSYour Name {
603*5113495bSYour Name 	struct crypto_ablkcipher *tfm;
604*5113495bSYour Name 	struct ablkcipher_request *req = NULL;
605*5113495bSYour Name 	struct scatterlist sg_in, sg_out;
606*5113495bSYour Name 	int ret;
607*5113495bSYour Name 
608*5113495bSYour Name 	if (!IS_VALID_CTR_KEY_LEN(key_len)) {
609*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
610*5113495bSYour Name 			  FL("Invalid key length: %u"), key_len);
611*5113495bSYour Name 		return -EINVAL;
612*5113495bSYour Name 	}
613*5113495bSYour Name 
614*5113495bSYour Name 	tfm = crypto_alloc_ablkcipher("ctr(aes)", 0, CRYPTO_ALG_ASYNC);
615*5113495bSYour Name 	if (IS_ERR(tfm)) {
616*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
617*5113495bSYour Name 			  FL("Failed to alloc transformation for ctr(aes):%ld"),
618*5113495bSYour Name 			  PTR_ERR(tfm));
619*5113495bSYour Name 		return -EAGAIN;
620*5113495bSYour Name 	}
621*5113495bSYour Name 
622*5113495bSYour Name 	req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
623*5113495bSYour Name 	if (!req) {
624*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
625*5113495bSYour Name 			  FL("Failed to allocate request for ctr(aes)"));
626*5113495bSYour Name 		crypto_free_ablkcipher(tfm);
627*5113495bSYour Name 		return -EAGAIN;
628*5113495bSYour Name 	}
629*5113495bSYour Name 
630*5113495bSYour Name 	ret = crypto_ablkcipher_setkey(tfm, key, key_len);
631*5113495bSYour Name 	if (ret) {
632*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
633*5113495bSYour Name 			  FL("Set key failed for ctr(aes), ret:%d"), -ret);
634*5113495bSYour Name 		ablkcipher_request_free(req);
635*5113495bSYour Name 		crypto_free_ablkcipher(tfm);
636*5113495bSYour Name 		return ret;
637*5113495bSYour Name 	}
638*5113495bSYour Name 
639*5113495bSYour Name 	sg_init_one(&sg_in, src, src_len);
640*5113495bSYour Name 	sg_init_one(&sg_out, dest, src_len);
641*5113495bSYour Name 	ablkcipher_request_set_crypt(req, &sg_in, &sg_out, src_len, siv);
642*5113495bSYour Name 
643*5113495bSYour Name 	if (enc)
644*5113495bSYour Name 		ret = crypto_ablkcipher_encrypt(req);
645*5113495bSYour Name 	else
646*5113495bSYour Name 		ret = crypto_ablkcipher_decrypt(req);
647*5113495bSYour Name 
648*5113495bSYour Name 	if (ret) {
649*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
650*5113495bSYour Name 			  FL("%s failed for ctr(aes), ret:%d"),
651*5113495bSYour Name 			  enc ? "Encryption" : "Decryption", -ret);
652*5113495bSYour Name 	}
653*5113495bSYour Name 
654*5113495bSYour Name 	ablkcipher_request_free(req);
655*5113495bSYour Name 	crypto_free_ablkcipher(tfm);
656*5113495bSYour Name 
657*5113495bSYour Name 	return ret;
658*5113495bSYour Name }
659*5113495bSYour Name #else
qdf_aes_ctr(const uint8_t * key,unsigned int key_len,uint8_t * siv,const uint8_t * src,size_t src_len,uint8_t * dest,bool enc)660*5113495bSYour Name int qdf_aes_ctr(const uint8_t *key, unsigned int key_len, uint8_t *siv,
661*5113495bSYour Name 		const uint8_t *src, size_t src_len, uint8_t *dest, bool enc)
662*5113495bSYour Name {
663*5113495bSYour Name 	return -EINVAL;
664*5113495bSYour Name }
665*5113495bSYour Name #endif
666*5113495bSYour Name 
667*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
qdf_crypto_aes_gmac(const uint8_t * key,uint16_t key_length,uint8_t * iv,const uint8_t * aad,const uint8_t * data,uint16_t data_len,uint8_t * mic)668*5113495bSYour Name int qdf_crypto_aes_gmac(const uint8_t *key, uint16_t key_length,
669*5113495bSYour Name 			uint8_t *iv, const uint8_t *aad,
670*5113495bSYour Name 			const uint8_t *data, uint16_t data_len, uint8_t *mic)
671*5113495bSYour Name {
672*5113495bSYour Name 	struct crypto_aead *tfm;
673*5113495bSYour Name 	int ret = 0;
674*5113495bSYour Name 	struct scatterlist sg[4];
675*5113495bSYour Name 	uint16_t req_size;
676*5113495bSYour Name 	struct aead_request *req = NULL;
677*5113495bSYour Name 	uint8_t *aad_ptr, *input;
678*5113495bSYour Name 
679*5113495bSYour Name 	tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
680*5113495bSYour Name 	if (IS_ERR(tfm)) {
681*5113495bSYour Name 		ret = PTR_ERR(tfm);
682*5113495bSYour Name 		tfm = NULL;
683*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
684*5113495bSYour Name 			  "%s: crypto_alloc_aead failed (%d)", __func__, ret);
685*5113495bSYour Name 		goto err_tfm;
686*5113495bSYour Name 	}
687*5113495bSYour Name 
688*5113495bSYour Name 	ret = crypto_aead_setkey(tfm, key, key_length);
689*5113495bSYour Name 	if (ret) {
690*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
691*5113495bSYour Name 			  "crypto_aead_setkey failed (%d)", ret);
692*5113495bSYour Name 		goto err_tfm;
693*5113495bSYour Name 	}
694*5113495bSYour Name 
695*5113495bSYour Name 	ret = crypto_aead_setauthsize(tfm, IEEE80211_MMIE_GMAC_MICLEN);
696*5113495bSYour Name 	if (ret) {
697*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
698*5113495bSYour Name 			  "crypto_aead_setauthsize failed (%d)", ret);
699*5113495bSYour Name 		goto err_tfm;
700*5113495bSYour Name 	}
701*5113495bSYour Name 
702*5113495bSYour Name 	/* Prepare aead request */
703*5113495bSYour Name 	req_size = sizeof(*req) + crypto_aead_reqsize(tfm) +
704*5113495bSYour Name 			IEEE80211_MMIE_GMAC_MICLEN + AAD_LEN;
705*5113495bSYour Name 	req = qdf_mem_malloc(req_size);
706*5113495bSYour Name 	if (!req) {
707*5113495bSYour Name 		ret = -ENOMEM;
708*5113495bSYour Name 		goto err_tfm;
709*5113495bSYour Name 	}
710*5113495bSYour Name 
711*5113495bSYour Name 	input = (uint8_t *)req + sizeof(*req) + crypto_aead_reqsize(tfm);
712*5113495bSYour Name 	aad_ptr = input + IEEE80211_MMIE_GMAC_MICLEN;
713*5113495bSYour Name 	qdf_mem_copy(aad_ptr, aad, AAD_LEN);
714*5113495bSYour Name 
715*5113495bSYour Name 	/* Scatter list operations */
716*5113495bSYour Name 	sg_init_table(sg, 4);
717*5113495bSYour Name 	sg_set_buf(&sg[0], aad_ptr, AAD_LEN);
718*5113495bSYour Name 	sg_set_buf(&sg[1], data, data_len);
719*5113495bSYour Name 	sg_set_buf(&sg[2], input, IEEE80211_MMIE_GMAC_MICLEN);
720*5113495bSYour Name 	sg_set_buf(&sg[3], mic, IEEE80211_MMIE_GMAC_MICLEN);
721*5113495bSYour Name 
722*5113495bSYour Name 	aead_request_set_tfm(req, tfm);
723*5113495bSYour Name 	aead_request_set_crypt(req, sg, sg, 0, iv);
724*5113495bSYour Name 	aead_request_set_ad(req,
725*5113495bSYour Name 			    AAD_LEN + data_len + IEEE80211_MMIE_GMAC_MICLEN);
726*5113495bSYour Name 	crypto_aead_encrypt(req);
727*5113495bSYour Name 
728*5113495bSYour Name err_tfm:
729*5113495bSYour Name 	if (tfm)
730*5113495bSYour Name 		crypto_free_aead(tfm);
731*5113495bSYour Name 
732*5113495bSYour Name 	if (req)
733*5113495bSYour Name 		qdf_mem_free(req);
734*5113495bSYour Name 
735*5113495bSYour Name 	return ret;
736*5113495bSYour Name }
737*5113495bSYour Name #else
qdf_crypto_aes_gmac(uint8_t * key,uint16_t key_length,uint8_t * iv,uint8_t * aad,uint8_t * data,uint16_t data_len,uint8_t * mic)738*5113495bSYour Name int qdf_crypto_aes_gmac(uint8_t *key, uint16_t key_length,
739*5113495bSYour Name 			uint8_t *iv, uint8_t *aad, uint8_t *data,
740*5113495bSYour Name 			uint16_t data_len, uint8_t *mic)
741*5113495bSYour Name {
742*5113495bSYour Name 	return -EINVAL;
743*5113495bSYour Name }
744*5113495bSYour Name #endif
745