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