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