xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/mlan/esa/common/crypt_new_rom.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file crypt_new_rom.c
2  *
3  *  @brief This file defines AES based functions.
4  *
5  * Copyright (C) 2014-2017, Marvell International Ltd.
6  *
7  * This software file (the "File") is distributed by Marvell International
8  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
9  * (the "License").  You may use, redistribute and/or modify this File in
10  * accordance with the terms and conditions of the License, a copy of which
11  * is available by writing to the Free Software Foundation, Inc.,
12  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
13  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14  *
15  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
18  * this warranty disclaimer.
19  */
20 
21 /******************************************************
22 Change log:
23     03/07/2014: Initial version
24 ******************************************************/
25 /*
26  * AES based functions
27  *
28  * - AES Key Wrap algorithm (128-bit KEK) (RFC-3394)
29  * - AES primitive algorithm
30  * - AES CCM algorithm
31  *
32  * Date: 11/01/2005
33  */
34 #include "wltypes.h"
35 #include "crypt_new_rom.h"
36 #include "rc4_rom.h"
37 #include "rijndael.h"
38 
39 #include "hostsa_ext_def.h"
40 #include "authenticator.h"
41 
42 static const UINT8 MRVL_DEFAULT_IV[8] = { 0xA6, 0xA6, 0xA6, 0xA6,
43 	0xA6, 0xA6, 0xA6, 0xA6
44 };
45 
46 UINT8 aesResult[32];
47 
48 /* MRVL_AES_MEMCMP
49  *      : similiar to memcmp in std c lib
50  * @dst     : dst ptr to be compared to
51  * @src     : src ptr to be compared from
52  * @len     : size of the comparison
53  *
54  * ASSUMPTION   : dst/src has to be valid data ptrs
55  */
56 int
MRVL_AES_MEMCMP(UINT8 * dst,UINT8 * src,int len)57 MRVL_AES_MEMCMP(UINT8 *dst, UINT8 *src, int len)
58 {
59 	int cnt = len;
60 
61 	while (len--) {
62 		if (*dst++ == *src++) {
63 			cnt--;
64 		}
65 	}
66 
67 	if (0 == cnt) {
68 		return 0;	/* dst == src */
69 	}
70 
71 	return -1;		/* dst != src */
72 }
73 
74 /* MRVL_AES_MEMSET
75  *      : similiar to memset in std c lib
76  * @dst     : dst starting pointer
77  * @val     : val to be set
78  * @size    : size of dst buffer to be set
79  *
80  * ASSUMPTION   : dst buffer must always have larger than the value of size
81  */
82 void
MRVL_AES_MEMSET(UINT8 * dst,UINT8 val,int size)83 MRVL_AES_MEMSET(UINT8 *dst, UINT8 val, int size)
84 {
85 	while (size--) {
86 		*dst++ = val;
87 	}
88 }
89 
90 /* MRVL_AES_MEMCPY
91  *      : similar to memcpy in std c lib
92  * @dst     : dst buffer starting ptr
93  * @src     : src buffer starting ptr
94  * @size    : size of copy
95  *
96  * ASSUMPTION   :
97  *      1: dst buffer must be larger than src + size of copy
98  *      2: dst buffer isn't overlapping src buffer
99  */
100 void
MRVL_AES_MEMCPY(UINT8 * dst,UINT8 * src,int size)101 MRVL_AES_MEMCPY(UINT8 *dst, UINT8 *src, int size)
102 {
103 	if (dst < src) {
104 		while (size) {
105 			*dst++ = *src++;
106 			size--;
107 		}
108 	} else {
109 		while (size) {
110 			*(dst + size - 1) = *(src + size - 1);
111 			size--;
112 		}
113 	}
114 }
115 
116 int
MRVL_AesInterCheck(UINT8 * inter,UINT8 * d)117 MRVL_AesInterCheck(UINT8 *inter, UINT8 *d)
118 {
119 	if (0 == MRVL_AES_MEMCMP(inter, d, 16)) {
120 		return 0;
121 	}
122 
123 	return -1;
124 }
125 
126 #ifdef WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH
127 extern const u8 Te4[256];
128 extern const u32 rcon[];
129 extern const u32 Td0[256];
130 extern const u32 Td1[256];
131 extern const u32 Td2[256];
132 extern const u32 Td3[256];
133 #define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
134 
135 static int
rijndaelKeySetupEnc_2(u32 rk[],const u8 cipherKey[],int keyBits)136 rijndaelKeySetupEnc_2(u32 rk[ /*4*(Nr + 1) */ ], const u8 cipherKey[],
137 		      int keyBits)
138 {
139 	int i = 0;
140 	u32 temp;
141 
142 	rk[0] = GETU32(cipherKey);
143 	rk[1] = GETU32(cipherKey + 4);
144 	rk[2] = GETU32(cipherKey + 8);
145 	rk[3] = GETU32(cipherKey + 12);
146 	if (keyBits == 128) {
147 		for (;;) {
148 			temp = rk[3];
149 			rk[4] = rk[0] ^
150 				(Te4[(temp >> 16) & 0xff] << 24) ^
151 				(Te4[(temp >> 8) & 0xff] << 16) ^
152 				(Te4[(temp) & 0xff] << 8) ^
153 				(Te4[(temp >> 24)]) ^ rcon[i];
154 			rk[5] = rk[1] ^ rk[4];
155 			rk[6] = rk[2] ^ rk[5];
156 			rk[7] = rk[3] ^ rk[6];
157 			if (++i == 10) {
158 				return 10;
159 			}
160 			rk += 4;
161 		}
162 	}
163 
164     /** Handle 24 bytes key length */
165 	rk[4] = GETU32(cipherKey + 16);
166 	rk[5] = GETU32(cipherKey + 20);
167 	if (keyBits == 192) {
168 		for (;;) {
169 			temp = rk[5];
170 			rk[6] = rk[0] ^
171 				(Te4[(temp >> 16) & 0xff] << 24) ^
172 				(Te4[(temp >> 8) & 0xff] << 16) ^
173 				(Te4[(temp) & 0xff] << 8) ^
174 				(Te4[(temp >> 24)]) ^ rcon[i];
175 			rk[7] = rk[1] ^ rk[6];
176 			rk[8] = rk[2] ^ rk[7];
177 			rk[9] = rk[3] ^ rk[8];
178 			if (++i == 8) {
179 				return 12;
180 			}
181 			rk[10] = rk[4] ^ rk[9];
182 			rk[11] = rk[5] ^ rk[10];
183 			rk += 6;
184 		}
185 	}
186 
187     /** Handle 32 bytes key length */
188 	rk[6] = GETU32(cipherKey + 24);
189 	rk[7] = GETU32(cipherKey + 28);
190 	if (keyBits == 256) {
191 		for (;;) {
192 			temp = rk[7];
193 			rk[8] = rk[0] ^
194 				(Te4[(temp >> 16) & 0xff] << 24) ^
195 				(Te4[(temp >> 8) & 0xff] << 16) ^
196 				(Te4[(temp) & 0xff] << 8) ^
197 				(Te4[(temp >> 24)]) ^ rcon[i];
198 			rk[9] = rk[1] ^ rk[8];
199 			rk[10] = rk[2] ^ rk[9];
200 			rk[11] = rk[3] ^ rk[10];
201 			if (++i == 7) {
202 				return 14;
203 			}
204 			temp = rk[11];
205 			rk[12] = rk[4] ^
206 				(Te4[(temp >> 24)] << 24) ^
207 				(Te4[(temp >> 16) & 0xff] << 16) ^
208 				(Te4[(temp >> 8) & 0xff] << 8) ^
209 				(Te4[(temp) & 0xff]);
210 			rk[13] = rk[5] ^ rk[12];
211 			rk[14] = rk[6] ^ rk[13];
212 			rk[15] = rk[7] ^ rk[14];
213 			rk += 8;
214 		}
215 	}
216 	return 0;
217 }
218 
219 static int
rijndaelKeySetupDec_2(u32 rk[],const u8 cipherKey[],int keyBits,int have_encrypt)220 rijndaelKeySetupDec_2(u32 rk[ /*4*(Nr + 1) */ ], const u8 cipherKey[],
221 		      int keyBits, int have_encrypt)
222 {
223 	int Nr, i, j;
224 	u32 temp;
225 
226 	if (have_encrypt) {
227 		Nr = have_encrypt;
228 	} else {
229 		/* expand the cipher key: */
230 		Nr = rijndaelKeySetupEnc_2(rk, cipherKey, keyBits);
231 	}
232 	/* invert the order of the round keys: */
233 	for (i = 0, j = 4 * Nr; i < j; i += 4, j -= 4) {
234 		temp = rk[i];
235 		rk[i] = rk[j];
236 		rk[j] = temp;
237 		temp = rk[i + 1];
238 		rk[i + 1] = rk[j + 1];
239 		rk[j + 1] = temp;
240 		temp = rk[i + 2];
241 		rk[i + 2] = rk[j + 2];
242 		rk[j + 2] = temp;
243 		temp = rk[i + 3];
244 		rk[i + 3] = rk[j + 3];
245 		rk[j + 3] = temp;
246 	}
247 	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
248 	for (i = 1; i < Nr; i++) {
249 		rk += 4;
250 		rk[0] = Td0[Te4[(rk[0] >> 24)]] ^
251 			Td1[Te4[(rk[0] >> 16) & 0xff]] ^
252 			Td2[Te4[(rk[0] >> 8) & 0xff]] ^
253 			Td3[Te4[(rk[0]) & 0xff]];
254 		rk[1] = Td0[Te4[(rk[1] >> 24)]] ^
255 			Td1[Te4[(rk[1] >> 16) & 0xff]] ^
256 			Td2[Te4[(rk[1] >> 8) & 0xff]] ^
257 			Td3[Te4[(rk[1]) & 0xff]];
258 		rk[2] = Td0[Te4[(rk[2] >> 24)]] ^
259 			Td1[Te4[(rk[2] >> 16) & 0xff]] ^
260 			Td2[Te4[(rk[2] >> 8) & 0xff]] ^
261 			Td3[Te4[(rk[2]) & 0xff]];
262 		rk[3] = Td0[Te4[(rk[3] >> 24)]] ^
263 			Td1[Te4[(rk[3] >> 16) & 0xff]] ^
264 			Td2[Te4[(rk[3] >> 8) & 0xff]] ^
265 			Td3[Te4[(rk[3]) & 0xff]];
266 	}
267 	return Nr;
268 }
269 
270 static void
rijndael_set_key_2(rijndael_ctx * ctx,u8 * key,int bits,int encrypt)271 rijndael_set_key_2(rijndael_ctx *ctx, u8 *key, int bits, int encrypt)
272 {
273 	ctx->Nr = rijndaelKeySetupEnc_2(ctx->key, key, bits);
274 	if (encrypt) {
275 		ctx->decrypt = 0;
276 	} else {
277 		ctx->decrypt = 1;
278 		rijndaelKeySetupDec_2(ctx->key, key, bits, ctx->Nr);
279 							     /**bt_test :: TBD */
280 	}
281 }
282 #endif /** WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH */
283 
284 /*
285  * AesEncrypt   : aes primitive encryption
286  *
287  * @kek     : key encryption key
288  * @kekLen  : kek len
289  * @data    : data pointer
290  *
291  * ASSUMPTION   : both src and dst buffer has to be 16 bytes or 128-bit
292  */
293 int
MRVL_AesEncrypt(UINT8 * kek,UINT8 kekLen,UINT8 * data,UINT8 * ret)294 MRVL_AesEncrypt(UINT8 *kek, UINT8 kekLen, UINT8 *data, UINT8 *ret)
295 {
296 	//BufferDesc_t * pDesc = NULL;
297 	UINT8 buf[400] = { 0 };
298 	rijndael_ctx *ctx;
299 #if 0				//!defined(REMOVE_PATCH_HOOKS)
300 	int ptr_val;
301 
302 	if (MRVL_AesEncrypt_hook(kek, kekLen, data, ret, &ptr_val)) {
303 		return ptr_val;
304 	}
305 #endif
306 #if 0
307 	/* Wait forever ensures a buffer */
308 	pDesc = (BufferDesc_t *) bml_AllocBuffer(ramHook_encrPoolConfig,
309 						 400, BML_WAIT_FOREVER);
310 #endif
311 	//ctx = (rijndael_ctx *)BML_DATA_PTR(pDesc);
312 	ctx = (rijndael_ctx *)buf;
313 #ifdef WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH
314 	rijndael_set_key_2(ctx, (UINT8 *)kek, kekLen * 64, 1);
315 #else
316 	rijndael_set_key(ctx, (UINT8 *)kek, kekLen * 64, 1);
317 #endif	   /** WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH */
318 	rijndael_encrypt(ctx, data, ret);
319 //    bml_FreeBuffer((UINT32)pDesc);
320 
321 	return 0;
322 }
323 
324 /****************************************************************
325  * AES_WRAP : AES_WRAP is specified by RFC 3394 section 2.2.1
326  *
327  * Inputs   : plaintest, n 64-bit values {P1, P2, ..., Pn}, and
328  *        Key, K (the KEK)
329  * Outputs  : ciphertext, (n+1) 64-bit values {C0, ..., Cn}
330  *
331  * NOTE:  this function is ported over from WPA_SUPPLICANT
332  ****************************************************************
333  *
334  * @kek     : key encryption key
335  * @kekLen  : kek len, in unit of 64-bit, has to be 2, 3, or 4
336  * @n       : length of the wrapped key in 64-bit
337  *          unit; e.g.: 2 = 128-bit = 16 bytes
338  * @plain   : plaintext key to be wrapped, has to be n * (64-bit)
339  *          or n * 8 bytes
340  * @cipher  : wrapped key, (n + 1) * 64-bit or (n+1) * 8 bytes
341  */
342 
343 /* debugging */
344 
345 int
MRVL_AesWrap(UINT8 * kek,UINT8 kekLen,UINT32 n,UINT8 * plain,UINT8 * keyIv,UINT8 * cipher)346 MRVL_AesWrap(UINT8 *kek, UINT8 kekLen, UINT32 n,
347 	     UINT8 *plain, UINT8 *keyIv, UINT8 *cipher)
348 {
349 	UINT8 a[8];
350 	UINT8 b[16];
351 	int i = 0;
352 	int j = 0;
353 	UINT8 *r = NULL;
354 #if 0				//!defined(REMOVE_PATCH_HOOKS)
355 	int ptr_val;
356 
357 	if (MRVL_AesWrap_hook(kek, kekLen, n, plain, keyIv, cipher, &ptr_val)) {
358 		return ptr_val;
359 	}
360 #endif
361 
362 	/* 0: before everything, check n value
363 	 */
364 	if (1 > n) {
365 		return -1;
366 	}
367 
368 	r = cipher + 8;
369 
370 	/* 1: initialize variables */
371 	MRVL_AES_MEMSET(b, 0x0, 16);
372 	if (keyIv) {
373 		MRVL_AES_MEMCPY(a, keyIv, 8);
374 	} else {
375 		MRVL_AES_MEMCPY(a, (UINT8 *)MRVL_DEFAULT_IV, 8);
376 	}
377 	MRVL_AES_MEMCPY(r, plain, (8 * n));
378 
379 	/* 2: calculate intermediate values
380 	 * For j = 0 to 5
381 	 *  For i=1 to n
382 	 *      B = AES(K, A | R[i])
383 	 *      A = MSB(64, B) ^ t where t = (n*j)+i
384 	 *              R[i] = LSB(64, B)
385 	 */
386 	for (j = 0; j <= 5; j++) {
387 		r = cipher + 8;
388 		for (i = 1; i <= n; i++) {
389 			MRVL_AES_MEMCPY(b, a, 8);
390 			MRVL_AES_MEMCPY(b + 8, r, 8);
391 			MRVL_AesEncrypt(kek, kekLen, b, b);
392 			MRVL_AES_MEMCPY(a, b, 8);
393 			a[7] ^= n * j + i;
394 			MRVL_AES_MEMCPY(r, b + 8, 8);
395 			r += 8;
396 		}
397 	}
398 
399 	MRVL_AES_MEMCPY(cipher, a, 8);
400 
401 	/* 3: output the results
402 	 * these are already in @cipher
403 	 */
404 
405 	return 0;
406 }
407 
408 /****************************************************************
409  * AES_UNWRAP   : AES_UNWRAP is specified by RFC 3394 section 2.2.2
410  *
411  * Inputs   : ciphertext, (n+1) 64-bit values {C0, ..., Cn}, and
412  *        Key, K (the KEK)
413  *
414  * Outputs  : plaintest, n 64-bit values {P1, P2, ..., Pn} + first 8 bytes
415  *        for KEYIV
416  *
417  *
418  ****************************************************************
419  *
420  * @kek     : key encryption key
421  * @kekLen  : kek len, in unit of 64-bit, has to be 2, 3, or 4
422  * @n       : length of the wrapped key in 64-bit
423  *          unit; e.g.: 2 = 128-bit = 16 bytes
424  * @cipher  : wrapped data, (n + 1) * 64-bit or (n+1) * 8 bytes
425  * @plain   : plaintext being unwrapped, has to be n * (64-bit)
426  *          or n * 8 bytes + extra 8 bytes for KEYIV
427  */
428 int
MRVL_AesUnWrap(UINT8 * kek,UINT8 kekLen,UINT32 n,UINT8 * cipher,UINT8 * keyIv,UINT8 * plain)429 MRVL_AesUnWrap(UINT8 *kek, UINT8 kekLen, UINT32 n,
430 	       UINT8 *cipher, UINT8 *keyIv, UINT8 *plain)
431 {
432 	UINT8 b[16];
433 	int i = 0;
434 	int j = 0;
435 	UINT8 a[8];
436 	UINT8 *r = NULL;
437 	//BufferDesc_t * pDesc = NULL;
438 	UINT8 buf[400] = { 0 };
439 
440 	rijndael_ctx *ctx;
441 #if 0				//!defined(REMOVE_PATCH_HOOKS)
442 	int ptr_val;
443 
444 	if (MRVL_AesUnWrap_hook(kek, kekLen, n, cipher, keyIv, plain, &ptr_val)) {
445 		return ptr_val;
446 	}
447 #endif
448 
449 	/* 0: before everything, check n value
450 	 */
451 	if (1 > n) {
452 		return -1;
453 	}
454 
455 	/* 1: initialize variables */
456 	MRVL_AES_MEMSET(a, 0x0, 8);
457 	MRVL_AES_MEMSET(b, 0x0, 16);
458 	MRVL_AES_MEMCPY(a, cipher, 8);
459 	r = plain;
460 	MRVL_AES_MEMCPY(r, cipher + 8, 8 * n);
461 #if 0
462 	/* Wait forever ensures a buffer */
463 	pDesc = (BufferDesc_t *) bml_AllocBuffer(ramHook_encrPoolConfig,
464 						 400, BML_WAIT_FOREVER);
465 #endif
466 	//ctx = (rijndael_ctx *)BML_DATA_PTR(pDesc);
467 	ctx = (rijndael_ctx *)buf;
468 #ifdef WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH
469 	rijndael_set_key_2(ctx, (UINT8 *)kek, kekLen * 64, 0);
470 #else
471 	rijndael_set_key(ctx, (UINT8 *)kek, kekLen * 64, 0);
472 #endif	   /** WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH */
473 
474 	/* 2: compute intermediate values
475 	 * For j = 5 to 0
476 	 *     For i = n to 1
477 	 *         B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
478 	 *         A = MSB(64, B)
479 	 *         R[i] = LSB(64, B)
480 	 */
481 	for (j = 5; j >= 0; j--) {
482 		r = plain + (n - 1) * 8;
483 		for (i = n; i >= 1; i--) {
484 			MRVL_AES_MEMCPY(b, a, 8);
485 			b[7] ^= n * j + i;
486 			MRVL_AES_MEMCPY(b + 8, r, 8);
487 
488 			rijndael_decrypt(ctx, b, b);
489 
490 			MRVL_AES_MEMCPY(a, b, 8);
491 			MRVL_AES_MEMCPY(r, b + 8, 8);
492 			r -= 8;
493 		}
494 	}
495 
496 //    bml_FreeBuffer((UINT32)pDesc);
497 
498 	/* 3: copy decrypted KeyIV to keyIv array */
499 	if (keyIv) {
500 		if (MRVL_AES_MEMCMP(keyIv, a, 8)) {
501 			return -1;
502 		}
503 	} else {
504 		if (MRVL_AES_MEMCMP((UINT8 *)MRVL_DEFAULT_IV, a, 8)) {
505 			return -1;
506 		}
507 	}
508 
509 	return 0;
510 }
511 
512 #if 0
513 /*****
514  * AES CRYPTION HELPER FUNCTIONS
515  *
516  */
517 int
518 MRVL_AesValidateHostRequest(UINT32 *pBitMap, UINT8 *pCmdPtr,
519 			    UINT8 *pCryptData, SINT8 *AESwrapEnc)
520 {
521 	host_MRVL_AES_CRYPT_t *pLocal = NULL;
522 	MrvlIEParamSet_t *pLocalIEParam = NULL;
523 #if 0				//!defined(REMOVE_PATCH_HOOKS)
524 	int ptr_val;
525 
526 	if (MRVL_AesValidateHostRequest_hook(pBitMap,
527 					     pCmdPtr,
528 					     pCryptData,
529 					     AESwrapEnc, &ptr_val)) {
530 		return ptr_val;
531 	}
532 #endif
533 
534 	if (NULL == pBitMap || NULL == pCmdPtr) {
535 		return -1;
536 	}
537 
538 	pLocal = (host_MRVL_AES_CRYPT_t *) pCmdPtr;
539 	pLocalIEParam = (MrvlIEParamSet_t *)&(pLocal->aesTlv);
540 	if ((0 != pLocal->action) && (0x1 != pLocal->action)) {
541 		*pBitMap |= MRVL_AES_NOT_EN_AND_DECRYPT;
542 	}
543 
544 	if (0 == pLocal->action) {
545 		((MRVL_ENDECRYPT_t *)pCryptData)->enDeAction = CRYPT_DECRYPT;
546 	} else if (1 == pLocal->action) {
547 		((MRVL_ENDECRYPT_t *)pCryptData)->enDeAction = CRYPT_ENCRYPT;
548 	}
549 	switch (pLocal->algorithm) {
550 	case MRVL_CRYPTO_TEST_RC4:
551 		if ((1 > (pLocal->keyIVLen + pLocal->keyLen)) ||
552 		    (256 < (pLocal->keyIVLen + pLocal->keyLen))) {
553 			*pBitMap |= MRVL_AES_KEY_IV_INVALID_RC4;
554 		}
555 		break;
556 	case MRVL_CRYPTO_TEST_AES_ECB:
557 		if ((16 != pLocal->keyLen) &&
558 		    (24 != pLocal->keyLen) && (32 != pLocal->keyLen)) {
559 			*pBitMap |= MRVL_AES_KEY_SIZE_INVALID;
560 		}
561 
562 		if ((16 != pLocalIEParam->Length)) {
563 			*pBitMap |= MRVL_AES_DATA_SIZE_INVALID;
564 		}
565 		break;
566 	case MRVL_CRYPTO_TEST_AES_WRAP:
567 		if (8 != pLocal->keyIVLen) {
568 			*pBitMap |= MRVL_AES_KEY_IV_INVALID_AES_WRAP;
569 		}
570 
571 		if ((16 != pLocal->keyLen) &&
572 		    (24 != pLocal->keyLen) && (32 != pLocal->keyLen)) {
573 			*pBitMap |= MRVL_AES_KEY_SIZE_INVALID;
574 		}
575 
576 		if ((1016 < pLocalIEParam->Length) ||
577 		    (8 > pLocalIEParam->Length)) {
578 			*pBitMap |= MRVL_AES_DATA_SIZE_INVALID;
579 		}
580 
581 		if (1 == pLocal->action) {	/* Encryption */
582 			*AESwrapEnc = 8;
583 		} else if (0 == pLocal->action) {	/* Decryption */
584 			*AESwrapEnc = -8;
585 		}
586 		break;
587 #ifdef DIAG_AES_CCM
588 	case MRVL_CRYPTO_TEST_AEC_CCM:
589 		{
590 			host_MRVL_AES_CCM_CRYPT_t *pLocalCCM
591 				= (host_MRVL_AES_CCM_CRYPT_t *) pCmdPtr;
592 
593 			pLocalIEParam =
594 				(MrvlIEParamSet_t *)&(pLocalCCM->aesTlv);
595 
596 			/* key length should be 16 */
597 			if ((16 != pLocalCCM->keyLen) &&
598 			    (24 != pLocalCCM->keyLen) &&
599 			    (32 != pLocalCCM->keyLen)) {
600 				*pBitMap |= MRVL_AES_KEY_SIZE_INVALID;
601 			}
602 
603 			/* nonce length 7 ~ 13 bytes */
604 			if ((pLocalCCM->nonceLen < 7) ||
605 			    (pLocalCCM->nonceLen > 13)) {
606 				*pBitMap |= MRVL_AES_NONCE_INVALID;
607 			}
608 
609 			/* AAD length 0 ~ 30 bytes */
610 			if (pLocalCCM->aadLen > 30) {
611 				*pBitMap |= MRVL_AES_AAD_INVALID;
612 			}
613 
614 			/* payload length 0 ~ 32 bytes */
615 			if (40 < pLocalIEParam->Length) {
616 				*pBitMap |= MRVL_AES_DATA_SIZE_INVALID;
617 			}
618 		}
619 		break;
620 #endif
621 #ifdef WAPI_HW_SUPPORT
622 	case MRVL_CRYPTO_TEST_WAPI:
623 		{
624 			host_MRVL_WAPI_CRYPT_t *pLocalWAPI
625 				= (host_MRVL_WAPI_CRYPT_t *) pCmdPtr;
626 
627 			/* key length should be 16 */
628 			if (pLocalWAPI->keyLen != 32) {
629 				*pBitMap |= MRVL_AES_KEY_SIZE_INVALID;
630 			}
631 
632 			/* nonce length 16 bytes */
633 			if (pLocalWAPI->nonceLen != 16) {
634 				*pBitMap |= MRVL_AES_NONCE_INVALID;
635 			}
636 
637 			/* AAD length 32 or 48 bytes */
638 			if ((pLocalWAPI->aadLen != 32) &&
639 			    (pLocalWAPI->aadLen != 48)) {
640 				*pBitMap |= MRVL_AES_AAD_INVALID;
641 			}
642 		}
643 		break;
644 #endif
645 	default:
646 		*pBitMap |= MRVL_AES_ALGORITHM_INVALID;
647 		break;
648 	}
649 
650 	/* put the buffer ptr to cryptdata */
651 	((MRVL_ENDECRYPT_t *)pCryptData)->pData = pCmdPtr;
652 
653 	return 0;
654 }
655 
656 /**************
657  * WRAPPER to do AES primitive encryption
658  */
659 void
660 MRVL_AesPrimitiveEncrypt(MRVL_ENDECRYPT_t *crypt, int *pErr)
661 {
662 	UINT8 *kek = NULL;
663 	UINT8 *data = NULL;
664 	UINT8 kekLen = 0;
665 	host_MRVL_AES_CRYPT_t *pLocal = NULL;
666 	MrvlIEAesCrypt_t *pLocalIEParam = NULL;
667 
668 #if 0				//!defined(REMOVE_PATCH_HOOKS)
669 	if (MRVL_AesPrimitiveEncrypt_hook(crypt, pErr)) {
670 		return;
671 	}
672 #endif
673 
674 	if ((NULL == pErr) || (NULL == crypt)) {
675 		*pErr = -1;
676 		return;
677 	}
678 
679 	*pErr = 0;
680 
681 	if ((CRYPT_ENCRYPT != crypt->enDeAction)) {
682 		*pErr = -1;
683 		return;
684 	}
685 
686 	pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData);
687 	pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv);
688 
689 	kek = (UINT8 *)(pLocal->key);
690 	kekLen = pLocal->keyLen;
691 	data = (UINT8 *)(pLocalIEParam->payload);
692 
693 	if (-1 == MRVL_AesEncrypt(kek, kekLen / 8, data, data)) {
694 		*pErr = -1;
695 		return;
696 	}
697 }
698 
699 void
700 MRVL_AesPrimitiveDecrypt(MRVL_ENDECRYPT_t *crypt, int *pErr)
701 {
702 	UINT8 *kek = NULL;
703 	UINT8 *data = NULL;
704 	UINT8 kekLen = 0;
705 	host_MRVL_AES_CRYPT_t *pLocal = NULL;
706 	MrvlIEAesCrypt_t *pLocalIEParam = NULL;
707 	BufferDesc_t *pDesc;
708 	rijndael_ctx *ctx;
709 
710 #if 0				//!defined(REMOVE_PATCH_HOOKS)
711 	if (MRVL_AesPrimitiveDecrypt_hook(crypt, pErr)) {
712 		return;
713 	}
714 #endif
715 
716 	if ((NULL == pErr) || (NULL == crypt)) {
717 		*pErr = -1;
718 		return;
719 	}
720 
721 	if ((CRYPT_DECRYPT != crypt->enDeAction)) {
722 		*pErr = -1;
723 		return;
724 	}
725 
726 	pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData);
727 	pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv);
728 
729 	kek = (UINT8 *)(pLocal->key);
730 	kekLen = pLocal->keyLen;
731 	data = (UINT8 *)(pLocalIEParam->payload);
732 #if 0
733 	/* Wait forever ensures a buffer */
734 	pDesc = (BufferDesc_t *) bml_AllocBuffer(ramHook_encrPoolConfig,
735 						 400, BML_WAIT_FOREVER);
736 #endif
737 	ctx = (rijndael_ctx *)BML_DATA_PTR(pDesc);
738 
739 #ifdef WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH
740 	rijndael_set_key_2(ctx, (UINT8 *)kek, kekLen * 8, 0);
741 #else
742 	rijndael_set_key(ctx, (UINT8 *)kek, kekLen * 8, 0);
743 #endif	   /** WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH */
744 
745 	rijndael_decrypt(ctx, data, data);
746 	bml_FreeBuffer((UINT32)pDesc);
747 
748 	*pErr = 0;
749 
750 }
751 
752 void
753 MRVL_AesWrapEncrypt(MRVL_ENDECRYPT_t *crypt, int *pErr)
754 {
755 	UINT8 *kek = NULL;
756 	UINT8 *data = NULL;
757 	UINT8 *keyIV = NULL;
758 	UINT8 kekLen = 0;
759 	UINT32 dataLen = 0;
760 	host_MRVL_AES_CRYPT_t *pLocal = NULL;
761 	MrvlIEAesCrypt_t *pLocalIEParam = NULL;
762 
763 #if 0				//!defined(REMOVE_PATCH_HOOKS)
764 	if (MRVL_AesWrapEncrypt_hook(crypt, pErr)) {
765 		return;
766 	}
767 #endif
768 
769 	if ((NULL == pErr) || (NULL == crypt)) {
770 		*pErr = -1;
771 		return;
772 	}
773 
774 	*pErr = 0;
775 
776 	if ((CRYPT_ENCRYPT != crypt->enDeAction)) {
777 		*pErr = -1;
778 		return;
779 	}
780 
781 	pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData);
782 	pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv);
783 
784 	kek = (UINT8 *)(pLocal->key);
785 	keyIV = (UINT8 *)(pLocal->keyIV);
786 	kekLen = pLocal->keyLen;
787 	data = (UINT8 *)(pLocalIEParam->payload);
788 	dataLen = pLocalIEParam->hdr.Length;
789 	/* need to add one more 8-bytes for return length */
790 	pLocalIEParam->hdr.Length = dataLen + 8;
791 
792 	if (-1 ==
793 	    MRVL_AesWrap(kek, kekLen / 8, dataLen / 8, data, keyIV,
794 			 aesResult)) {
795 		*pErr = -2;
796 		return;
797 	}
798 
799 	MRVL_AES_MEMCPY(data, aesResult, pLocalIEParam->hdr.Length);
800 }
801 
802 void
803 MRVL_AesWrapDecrypt(MRVL_ENDECRYPT_t *crypt, int *pErr)
804 {
805 	UINT8 *kek = NULL;
806 	UINT8 *keyIV = NULL;
807 	UINT8 *data = NULL;
808 	UINT8 kekLen = 0;
809 	UINT32 dataLen = 0;
810 	host_MRVL_AES_CRYPT_t *pLocal = NULL;
811 	MrvlIEAesCrypt_t *pLocalIEParam = NULL;
812 
813 #if 0				//!defined(REMOVE_PATCH_HOOKS)
814 	if (MRVL_AesWrapDecrypt_hook(crypt, pErr)) {
815 		return;
816 	}
817 #endif
818 
819 	if ((NULL == pErr) || (NULL == crypt)) {
820 		*pErr = -1;
821 		return;
822 	}
823 
824 	*pErr = 0;
825 
826 	if ((CRYPT_DECRYPT != crypt->enDeAction)) {
827 		*pErr = -1;
828 		return;
829 	}
830 
831 	pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData);
832 	pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv);
833 
834 	kek = (UINT8 *)(pLocal->key);
835 	keyIV = (UINT8 *)(pLocal->keyIV);
836 	kekLen = pLocal->keyLen;
837 	data = (UINT8 *)(pLocalIEParam->payload);
838 	dataLen = pLocalIEParam->hdr.Length;
839 
840 	if (-1 == MRVL_AesUnWrap(kek, kekLen / 8, dataLen / 8 - 1,
841 				 data, keyIV, aesResult)) {
842 		*pErr = -2;
843 		return;
844 	}
845 
846 	dataLen -= 8;
847 	pLocalIEParam->hdr.Length = dataLen;
848 	MRVL_AES_MEMCPY(data, aesResult, dataLen);
849 
850 }
851 #endif
852 #ifdef RC4
853 
854 void
MRVL_Rc4Cryption(void * priv,MRVL_ENDECRYPT_t * crypt,int * pErr)855 MRVL_Rc4Cryption(void *priv, MRVL_ENDECRYPT_t *crypt, int *pErr)
856 {
857 	host_MRVL_AES_CRYPT_t *pLocal = NULL;
858 	MrvlIEAesCrypt_t *pLocalIEParam = NULL;
859 	UINT8 *key = NULL;
860 	UINT8 *keyIV = NULL;
861 	UINT8 *data = NULL;
862 	UINT32 dataLen = 0;
863 
864 	if ((NULL == pErr) || (NULL == crypt)) {
865 		*pErr = -1;
866 		return;
867 	}
868 
869 	*pErr = 0;
870 
871 	/* since RC4 encrypt/decrypt are the same */
872 	if ((CRYPT_DECRYPT != crypt->enDeAction) &&
873 	    (CRYPT_ENCRYPT != crypt->enDeAction)) {
874 		*pErr = -2;
875 		return;
876 	}
877 
878 	pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData);
879 	pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv);
880 
881 	key = (UINT8 *)(pLocal->key);
882 	data = (UINT8 *)(pLocalIEParam->payload);
883 	keyIV = (UINT8 *)(pLocal->keyIV);
884 	dataLen = pLocalIEParam->hdr.Length;
885 
886 	RC4_Encrypt(priv, key, keyIV, pLocal->keyIVLen, data, dataLen, 0);
887 
888 	return;
889 }
890 #endif /* RC4 */
891