Resync with broadcom drivers 5.100.138.20 and utilities.
[tomato.git] / release / src-rt / bcmcrypto / aes.c
blob1d721706d5dbed114c20f522d1e986b76bf7c5a6
1 /*
2 * aes.c
3 * AES encrypt/decrypt wrapper functions used around Rijndael reference
4 * implementation
6 * Copyright (C) 2010, Broadcom Corporation
7 * All Rights Reserved.
8 *
9 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
10 * the contents of this file may not be disclosed to third parties, copied
11 * or duplicated in any form, in whole or in part, without the prior
12 * written permission of Broadcom Corporation.
14 * $Id: aes.c,v 1.34.10.1 2010-05-28 15:25:49 Exp $
17 #include <typedefs.h>
18 #ifdef BCMDRIVER
19 #include <osl.h>
20 #else
21 #include <stddef.h> /* for size_t */
22 #if defined(__GNUC__)
23 extern void bcopy(const void *src, void *dst, size_t len);
24 extern int bcmp(const void *b1, const void *b2, size_t len);
25 extern void bzero(void *b, size_t len);
26 #else
27 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
28 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
29 #define bzero(b, len) memset((b), 0, (len))
30 #endif
31 #endif /* BCMDRIVER */
32 #include <bcmendian.h>
33 #include <bcmutils.h>
34 #include <proto/802.11.h>
35 #include <bcmcrypto/aes.h>
36 #include <bcmcrypto/rijndael-alg-fst.h>
38 #ifdef BCMAES_TEST
39 #include <stdio.h>
41 #define dbg(args) printf args
43 void
44 pinter(const char *label, const uint8 *A, const size_t il, const uint8 *R)
46 int k;
47 printf("%s", label);
48 for (k = 0; k < AES_BLOCK_SZ; k++)
49 printf("%02X", A[k]);
50 printf(" ");
51 for (k = 0; k < il; k++) {
52 printf("%02X", R[k]);
53 if (!((k + 1) % AES_BLOCK_SZ))
54 printf(" ");
56 printf("\n");
59 void
60 pres(const char *label, const size_t len, const uint8 *data)
62 int k;
63 printf("%s\n", label);
64 for (k = 0; k < len; k++) {
65 printf("%02x ", data[k]);
66 if (!((k + 1) % AES_BLOCK_SZ))
67 printf("\n");
69 printf("\n");
72 #ifdef BCMAES_GENTABLE
73 void
74 ptable(const char *tablename, const uint32 *table)
76 int k;
77 printf("static const uint32 %s[256] = {\n ", tablename);
78 for (k = 0; k < 256; k++) {
79 printf("0x%08xU", table[k]);
80 if ((k+1) % 4)
81 printf(", ");
82 else
83 if (k != 255)
84 printf(",\n ");
85 else
86 printf("\n");
88 printf("};\n");
90 #endif /* BCMAES_GENTABLE */
92 #else
93 #define dbg(args)
94 #define pinter(label, A, il, R)
95 #define pres(label, len, data)
96 #endif /* BCMAES_TEST */
99 * ptxt - plain text
100 * ctxt - cipher text
103 /* Perform AES block encryption, including key schedule setup */
104 void
105 BCMROMFN(aes_encrypt)(const size_t kl, const uint8 *K, const uint8 *ptxt, uint8 *ctxt)
107 uint32 rk[4 * (AES_MAXROUNDS + 1)];
108 rijndaelKeySetupEnc(rk, K, (int)AES_KEY_BITLEN(kl));
109 rijndaelEncrypt(rk, (int)AES_ROUNDS(kl), ptxt, ctxt);
112 /* Perform AES block decryption, including key schedule setup */
113 void
114 BCMROMFN(aes_decrypt)(const size_t kl, const uint8 *K, const uint8 *ctxt, uint8 *ptxt)
116 uint32 rk[4 * (AES_MAXROUNDS + 1)];
117 rijndaelKeySetupDec(rk, K, (int)AES_KEY_BITLEN(kl));
118 rijndaelDecrypt(rk, (int)AES_ROUNDS(kl), ctxt, ptxt);
121 /* AES-CBC mode encryption algorithm
122 * - handle partial blocks with padding of type as above
123 * - assumes nonce is ready to use as-is (i.e. any
124 * encryption/randomization of nonce/IV is handled by the caller)
125 * - ptxt and ctxt can point to the same location
126 * - returns -1 on error or final length of output
131 BCMROMFN(aes_cbc_encrypt_pad)(uint32 *rk,
132 const size_t key_len,
133 const uint8 *nonce,
134 const size_t data_len,
135 const uint8 *ptxt,
136 uint8 *ctxt,
137 uint8 padd_type)
140 uint8 tmp[AES_BLOCK_SZ];
141 uint32 encrypt_len = 0;
142 uint32 j;
144 /* First block get XORed with nonce/IV */
145 const unsigned char *iv = nonce;
146 unsigned char *crypt_data = ctxt;
147 const unsigned char *plain_data = ptxt;
148 uint32 remaining = (uint32)data_len;
150 while (remaining >= AES_BLOCK_SZ)
152 xor_128bit_block(iv, plain_data, tmp);
153 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, crypt_data);
154 remaining -= AES_BLOCK_SZ;
155 iv = crypt_data;
156 crypt_data += AES_BLOCK_SZ;
157 plain_data += AES_BLOCK_SZ;
158 encrypt_len += AES_BLOCK_SZ;
161 if (padd_type == NO_PADDING)
162 return encrypt_len;
164 if (remaining) {
165 for (j = 0; j < remaining; j++)
167 tmp[j] = plain_data[j] ^ iv[j];
170 switch (padd_type)
172 case PAD_LEN_PADDING:
173 for (j = remaining; j < AES_BLOCK_SZ; j++) {
174 tmp[j] = (AES_BLOCK_SZ - remaining) ^ iv[j];
176 break;
177 default:
178 return -1;
181 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, crypt_data);
182 encrypt_len += AES_BLOCK_SZ;
184 return (encrypt_len);
187 /* AES-CBC mode encryption algorithm
188 * - does not handle partial blocks
189 * - assumes nonce is ready to use as-is (i.e. any
190 * encryption/randomization of nonce/IV is handled by the caller)
191 * - ptxt and ctxt can point to the same location
192 * - returns -1 on error
196 BCMROMFN(aes_cbc_encrypt)(uint32 *rk,
197 const size_t key_len,
198 const uint8 *nonce,
199 const size_t data_len,
200 const uint8 *ptxt,
201 uint8 *ctxt)
203 if (data_len % AES_BLOCK_SZ) return (-1);
204 if (data_len < AES_BLOCK_SZ) return (-1);
206 return aes_cbc_encrypt_pad(rk, key_len, nonce, data_len, ptxt, ctxt, NO_PADDING);
210 /* AES-CBC mode decryption algorithm
211 * - handle partial plaintext blocks with padding
212 * - ptxt and ctxt can point to the same location
213 * - returns -1 on error
216 BCMROMFN(aes_cbc_decrypt_pad)(uint32 *rk,
217 const size_t key_len,
218 const uint8 *nonce,
219 const size_t data_len,
220 const uint8 *ctxt,
221 uint8 *ptxt,
222 uint8 padd_type)
224 uint8 tmp[AES_BLOCK_SZ];
225 uint32 remaining = (uint32)data_len;
226 /* First block get XORed with nonce/IV */
227 const unsigned char *iv = nonce;
228 const unsigned char *crypt_data = ctxt;
229 uint32 plaintext_len = 0;
230 unsigned char *plain_data = ptxt;
232 if (data_len % AES_BLOCK_SZ) return (-1);
233 if (data_len < AES_BLOCK_SZ) return (-1);
235 while (remaining >= AES_BLOCK_SZ)
237 aes_block_decrypt((int)AES_ROUNDS(key_len), rk, crypt_data, tmp);
238 xor_128bit_block(tmp, iv, plain_data);
239 remaining -= AES_BLOCK_SZ;
240 iv = crypt_data;
241 crypt_data += AES_BLOCK_SZ;
242 plain_data += AES_BLOCK_SZ;
243 plaintext_len += AES_BLOCK_SZ;
245 if (padd_type == PAD_LEN_PADDING)
246 plaintext_len -= ptxt[plaintext_len -1];
247 return (plaintext_len);
251 BCMROMFN(aes_cbc_decrypt)(uint32 *rk,
252 const size_t key_len,
253 const uint8 *nonce,
254 const size_t data_len,
255 const uint8 *ctxt,
256 uint8 *ptxt)
259 return aes_cbc_decrypt_pad(rk, key_len, nonce, data_len, ctxt, ptxt, NO_PADDING);
264 /* AES-CTR mode encryption/decryption algorithm
265 * - max data_len is (AES_BLOCK_SZ * 2^16)
266 * - nonce must be AES_BLOCK_SZ bytes
267 * - assumes nonce is ready to use as-is (i.e. any
268 * encryption/randomization of nonce/IV is handled by the caller)
269 * - ptxt and ctxt can point to the same location
270 * - returns -1 on error
273 BCMROMFN(aes_ctr_crypt)(unsigned int *rk,
274 const size_t key_len,
275 const uint8 *nonce,
276 const size_t data_len,
277 const uint8 *ptxt,
278 uint8 *ctxt)
280 size_t k;
281 uint8 tmp[AES_BLOCK_SZ], ctr[AES_BLOCK_SZ];
283 if (data_len > (AES_BLOCK_SZ * AES_CTR_MAXBLOCKS)) return (-1);
285 bcopy(nonce, ctr, AES_BLOCK_SZ);
287 for (k = 0; k < (data_len / AES_BLOCK_SZ); k++) {
288 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, ctr, tmp);
289 xor_128bit_block(ptxt, tmp, ctxt);
290 ctr[AES_BLOCK_SZ-1]++;
291 if (!ctr[AES_BLOCK_SZ - 1]) ctr[AES_BLOCK_SZ - 2]++;
292 ptxt += AES_BLOCK_SZ;
293 ctxt += AES_BLOCK_SZ;
295 /* handle partial block */
296 if (data_len%AES_BLOCK_SZ) {
297 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, ctr, tmp);
298 for (k = 0; k < (data_len % AES_BLOCK_SZ); k++)
299 ctxt[k] = ptxt[k] ^ tmp[k];
302 return (0);
306 /* AES-CCM mode MAC calculation
307 * - computes AES_CCM_AUTH_LEN MAC
308 * - nonce must be AES_CCM_NONCE_LEN bytes
309 * - returns -1 on error
313 BCMROMFN(aes_ccm_mac)(unsigned int *rk,
314 const size_t key_len,
315 const uint8 *nonce,
316 const size_t aad_len,
317 const uint8 *aad,
318 const size_t data_len,
319 const uint8 *ptxt,
320 uint8 *mac)
322 uint8 B_0[AES_BLOCK_SZ], X[AES_BLOCK_SZ];
323 size_t j, k;
325 if (aad_len > AES_CCM_AAD_MAX_LEN) return (-1);
327 pres("aes_ccm_mac: nonce:", AES_CCM_NONCE_LEN, nonce);
328 pres("aes_ccm_mac: aad:", aad_len, aad);
329 pres("aes_ccm_mac: input:", data_len, ptxt);
331 /* B_0 = Flags || Nonce || l(m) */
332 B_0[0] = AES_CCM_AUTH_FLAGS;
333 if (aad_len)
334 B_0[0] |= AES_CCM_AUTH_AAD_FLAG;
335 bcopy(nonce, &B_0[1], AES_CCM_NONCE_LEN);
336 B_0[AES_BLOCK_SZ - 2] = (uint8)(data_len >> 8) & 0xff;
337 B_0[AES_BLOCK_SZ - 1] = (uint8)(data_len & 0xff);
339 /* X_1 := E( K, B_0 ) */
340 pres("aes_ccm_mac: CBC IV in:", AES_BLOCK_SZ, B_0);
341 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, B_0, X);
342 pres("aes_ccm_mac: CBC IV out:", AES_BLOCK_SZ, X);
344 /* X_i + 1 := E( K, X_i XOR B_i ) for i = 1, ..., n */
346 /* first the AAD */
347 if (aad_len) {
348 pres("aes_ccm_mac: aad:", aad_len, aad);
349 X[0] ^= (aad_len >> 8) & 0xff;
350 X[1] ^= aad_len & 0xff;
351 k = 2;
352 j = aad_len;
353 while (j--) {
354 X[k] ^= *aad++;
355 k++;
356 if (k == AES_BLOCK_SZ) {
357 pres("aes_ccm_mac: After xor (full block aad):", AES_BLOCK_SZ, X);
358 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
359 pres("aes_ccm_mac: After AES (full block aad):", AES_BLOCK_SZ, X);
360 k = 0;
363 /* handle partial last block */
364 if (k % AES_BLOCK_SZ) {
365 pres("aes_ccm_mac: After xor (partial block aad):", AES_BLOCK_SZ, X);
366 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
367 pres("aes_ccm_mac: After AES (partial block aad):", AES_BLOCK_SZ, X);
371 /* then the message data */
372 for (k = 0; k < (data_len / AES_BLOCK_SZ); k++) {
373 xor_128bit_block(X, ptxt, X);
374 pres("aes_ccm_mac: After xor (full block data):", AES_BLOCK_SZ, X);
375 ptxt += AES_BLOCK_SZ;
376 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
377 pres("aes_ccm_mac: After AES (full block data):", AES_BLOCK_SZ, X);
379 /* last block may be partial, padding is implicit in this xor */
380 for (k = 0; k < (data_len % AES_BLOCK_SZ); k++)
381 X[k] ^= *ptxt++;
382 if (data_len % AES_BLOCK_SZ) {
383 pres("aes_ccm_mac: After xor (final block data):", AES_BLOCK_SZ, X);
384 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
385 pres("aes_ccm_mac: After AES (final block data):", AES_BLOCK_SZ, X);
388 /* T := first-M-bytes( X_n+1 ) */
389 bcopy(X, mac, AES_CCM_AUTH_LEN);
390 pres("aes_ccm_mac: MAC:", AES_CCM_AUTH_LEN, mac);
392 return (0);
395 /* AES-CCM mode encryption
396 * - computes AES_CCM_AUTH_LEN MAC and then encrypts ptxt and MAC
397 * - nonce must be AES_CCM_NONCE_LEN bytes
398 * - ctxt must have sufficient tailroom for CCM MAC
399 * - ptxt and ctxt can point to the same location
400 * - returns -1 on error
404 BCMROMFN(aes_ccm_encrypt)(unsigned int *rk,
405 const size_t key_len,
406 const uint8 *nonce,
407 const size_t aad_len,
408 const uint8 *aad,
409 const size_t data_len,
410 const uint8 *ptxt,
411 uint8 *ctxt,
412 uint8 *mac)
414 uint8 A[AES_BLOCK_SZ], X[AES_BLOCK_SZ];
416 /* initialize counter */
417 A[0] = AES_CCM_CRYPT_FLAGS;
418 bcopy(nonce, &A[1], AES_CCM_NONCE_LEN);
419 A[AES_BLOCK_SZ-2] = 0;
420 A[AES_BLOCK_SZ-1] = 0;
421 pres("aes_ccm_encrypt: initial counter:", AES_BLOCK_SZ, A);
423 /* calculate and encrypt MAC */
424 if (aes_ccm_mac(rk, key_len, nonce, aad_len, aad, data_len, ptxt, X))
425 return (-1);
426 pres("aes_ccm_encrypt: MAC:", AES_CCM_AUTH_LEN, X);
427 if (aes_ctr_crypt(rk, key_len, A, AES_CCM_AUTH_LEN, X, X))
428 return (-1);
429 pres("aes_ccm_encrypt: encrypted MAC:", AES_CCM_AUTH_LEN, X);
430 bcopy(X, mac, AES_CCM_AUTH_LEN);
432 /* encrypt data */
433 A[AES_BLOCK_SZ - 1] = 1;
434 if (aes_ctr_crypt(rk, key_len, A, data_len, ptxt, ctxt))
435 return (-1);
436 pres("aes_ccm_encrypt: encrypted data:", data_len, ctxt);
438 return (0);
441 /* AES-CCM mode decryption
442 * - decrypts ctxt, then computes AES_CCM_AUTH_LEN MAC and checks it against
443 * then decrypted MAC
444 * - the decrypted MAC is included in ptxt
445 * - nonce must be AES_CCM_NONCE_LEN bytes
446 * - ptxt and ctxt can point to the same location
447 * - returns -1 on error
451 BCMROMFN(aes_ccm_decrypt)(unsigned int *rk,
452 const size_t key_len,
453 const uint8 *nonce,
454 const size_t aad_len,
455 const uint8 *aad,
456 const size_t data_len,
457 const uint8 *ctxt,
458 uint8 *ptxt)
460 uint8 A[AES_BLOCK_SZ], X[AES_BLOCK_SZ];
462 /* initialize counter */
463 A[0] = AES_CCM_CRYPT_FLAGS;
464 bcopy(nonce, &A[1], AES_CCM_NONCE_LEN);
465 A[AES_BLOCK_SZ - 2] = 0;
466 A[AES_BLOCK_SZ - 1] = 1;
467 pres("aes_ccm_decrypt: initial counter:", AES_BLOCK_SZ, A);
469 /* decrypt data */
470 if (aes_ctr_crypt(rk, key_len, A, data_len-AES_CCM_AUTH_LEN, ctxt, ptxt))
471 return (-1);
472 pres("aes_ccm_decrypt: decrypted data:", data_len-AES_CCM_AUTH_LEN, ptxt);
474 /* decrypt MAC */
475 A[AES_BLOCK_SZ - 2] = 0;
476 A[AES_BLOCK_SZ - 1] = 0;
477 if (aes_ctr_crypt(rk, key_len, A, AES_CCM_AUTH_LEN,
478 ctxt+data_len-AES_CCM_AUTH_LEN, ptxt + data_len - AES_CCM_AUTH_LEN))
479 return (-1);
480 pres("aes_ccm_decrypt: decrypted MAC:", AES_CCM_AUTH_LEN,
481 ptxt + data_len - AES_CCM_AUTH_LEN);
483 /* calculate MAC */
484 if (aes_ccm_mac(rk, key_len, nonce, aad_len, aad,
485 data_len - AES_CCM_AUTH_LEN, ptxt, X))
486 return (-1);
487 pres("aes_ccm_decrypt: MAC:", AES_CCM_AUTH_LEN, X);
488 if (bcmp(X, ptxt + data_len - AES_CCM_AUTH_LEN, AES_CCM_AUTH_LEN) != 0)
489 return (-1);
491 return (0);
494 /* AES-CCMP mode encryption algorithm
495 * - packet buffer should be an 802.11 MPDU, starting with Frame Control,
496 * and including the CCMP extended IV
497 * - encrypts in-place
498 * - packet buffer must have sufficient tailroom for CCMP MAC
499 * - returns -1 on error
504 BCMROMFN(aes_ccmp_encrypt)(unsigned int *rk,
505 const size_t key_len,
506 const size_t data_len,
507 uint8 *p,
508 bool legacy,
509 uint8 nonce_1st_byte)
511 uint8 nonce[AES_CCMP_NONCE_LEN], aad[AES_CCMP_AAD_MAX_LEN];
512 struct dot11_header *h = (struct dot11_header*) p;
513 uint la, lh;
514 int status = 0;
516 aes_ccmp_cal_params(h, legacy, nonce_1st_byte, nonce, aad, &la, &lh);
518 pres("aes_ccmp_encrypt: aad:", la, aad);
521 * MData:
522 * B3..Bn, n = floor((l(m)+(AES_BLOCK_SZ-1))/AES_BLOCK_SZ) + 2
523 * m || pad(m)
526 status = aes_ccm_encrypt(rk, key_len, nonce, la, aad,
527 data_len - lh, p + lh, p + lh, p + data_len);
529 pres("aes_ccmp_encrypt: Encrypted packet with MAC:",
530 data_len+AES_CCMP_AUTH_LEN, p);
532 if (status) return (AES_CCMP_ENCRYPT_ERROR);
533 else return (AES_CCMP_ENCRYPT_SUCCESS);
537 BCMROMFN(aes_ccmp_decrypt)(unsigned int *rk,
538 const size_t key_len,
539 const size_t data_len,
540 uint8 *p,
541 bool legacy,
542 uint8 nonce_1st_byte)
544 uint8 nonce[AES_CCMP_NONCE_LEN], aad[AES_CCMP_AAD_MAX_LEN];
545 struct dot11_header *h = (struct dot11_header *)p;
546 uint la, lh;
547 int status = 0;
549 aes_ccmp_cal_params(h, legacy, nonce_1st_byte, nonce, aad, &la, &lh);
551 pres("aes_ccmp_decrypt: aad:", la, aad);
554 * MData:
555 * B3..Bn, n = floor((l(m)+(AES_BLOCK_SZ-1))/AES_BLOCK_SZ) + 2
556 * m || pad(m)
559 status = aes_ccm_decrypt(rk, key_len, nonce, la, aad,
560 data_len - lh, p + lh, p + lh);
562 pres("aes_ccmp_decrypt: Decrypted packet with MAC:", data_len, p);
564 if (status) return (AES_CCMP_DECRYPT_MIC_FAIL);
565 else return (AES_CCMP_DECRYPT_SUCCESS);
568 void
569 BCMROMFN(aes_ccmp_cal_params)(struct dot11_header *h, bool legacy,
570 uint8 nonce_1st_byte, uint8 *nonce, uint8 *aad, uint *la, uint *lh)
572 uint8 *iv_data;
573 uint16 fc, subtype;
574 uint16 seq, qc = 0;
575 uint addlen = 0;
576 bool wds, qos;
578 bzero(nonce, AES_CCMP_NONCE_LEN);
579 bzero(aad, AES_CCMP_AAD_MAX_LEN);
581 fc = ltoh16(h->fc);
582 subtype = (fc & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT;
583 wds = ((fc & (FC_TODS | FC_FROMDS)) == (FC_TODS | FC_FROMDS));
584 /* all QoS subtypes have the FC_SUBTYPE_QOS_DATA bit set */
585 qos = (FC_TYPE(fc) == FC_TYPE_DATA) && (subtype & FC_SUBTYPE_QOS_DATA);
587 if (qos) {
588 qc = ltoh16(*((uint16 *)((uchar *)h +
589 (wds ? DOT11_A4_HDR_LEN : DOT11_A3_HDR_LEN))));
592 if (wds) {
593 dbg(("aes_ccmp_cal_params: A4 present\n"));
594 addlen += ETHER_ADDR_LEN;
596 if (qos) {
597 dbg(("aes_ccmp_cal_params: QC present\n"));
598 addlen += DOT11_QOS_LEN;
601 /* length of MPDU header, including IV */
602 *lh = DOT11_A3_HDR_LEN + DOT11_IV_AES_CCM_LEN + addlen;
603 /* length of AAD */
604 *la = AES_CCMP_AAD_MIN_LEN + addlen;
605 /* pointer to IV */
606 iv_data = (uint8 *)h + DOT11_A3_HDR_LEN + addlen;
608 *nonce++ = nonce_1st_byte;
610 bcopy((uchar *)&h->a2, nonce, ETHER_ADDR_LEN);
611 nonce += ETHER_ADDR_LEN;
613 /* PN[5] */
614 *nonce++ = iv_data[7];
615 /* PN[4] */
616 *nonce++ = iv_data[6];
617 /* PN[3] */
618 *nonce++ = iv_data[5];
619 /* PN[2] */
620 *nonce++ = iv_data[4];
621 /* PN[1] */
622 *nonce++ = iv_data[1];
623 /* PN[0] */
624 *nonce++ = iv_data[0];
626 pres("aes_ccmp_cal_params: nonce:", AES_CCM_NONCE_LEN, nonce - AES_CCM_NONCE_LEN);
628 /* B1..B2 = l(aad) || aad || pad(aad) */
629 /* aad: maskedFC || A1 || A2 || A3 || maskedSC || A4 || maskedQC */
631 if (!legacy) {
632 #ifdef MFP
633 /* For a management frame, don't mask the the subtype bits */
634 if (nonce_1st_byte & AES_CCMP_NF_MANAGEMENT)
635 fc &= (FC_SUBTYPE_MASK | AES_CCMP_FC_MASK);
636 else
637 #endif /* MFP */
638 fc &= AES_CCMP_FC_MASK;
639 } else {
640 /* 802.11i Draft 3 inconsistencies:
641 * Clause 8.3.4.4.3: "FC ­ MPDU Frame Control field, with Retry bit masked
642 * to zero." (8.3.4.4.3).
643 * Figure 29: "FC ­ MPDU Frame Control field, with Retry, MoreData, CF-ACK,
644 * CF-POLL bits masked to zero."
645 * F.10.4.1: "FC ­ MPDU Frame Control field, with Retry, MoreData,
646 * PwrMgmt bits masked to zero."
649 /* Our implementation: match 8.3.4.4.3 */
650 fc &= AES_CCMP_LEGACY_FC_MASK;
652 *aad++ = (uint8)(fc & 0xff);
653 *aad++ = (uint8)((fc >> 8) & 0xff);
655 bcopy((uchar *)&h->a1, aad, 3*ETHER_ADDR_LEN);
656 aad += 3*ETHER_ADDR_LEN;
658 seq = ltoh16(h->seq);
659 if (!legacy) {
660 seq &= AES_CCMP_SEQ_MASK;
661 } else {
662 seq &= AES_CCMP_LEGACY_SEQ_MASK;
665 *aad++ = (uint8)(seq & 0xff);
666 *aad++ = (uint8)((seq >> 8) & 0xff);
668 if (wds) {
669 bcopy((uchar *)&h->a4, aad, ETHER_ADDR_LEN);
670 aad += ETHER_ADDR_LEN;
672 if (qos) {
673 if (!legacy) {
674 /* 802.11i Draft 7.0 inconsistencies:
675 * Clause 8.3.3.3.2: "QC ­ The Quality of Service Control, a
676 * two-octet field that includes the MSDU priority, reserved
677 * for future use."
678 * I.7.4: TID portion of QoS
681 /* Our implementation: match the test vectors */
682 qc &= AES_CCMP_QOS_MASK;
683 *aad++ = (uint8)(qc & 0xff);
684 *aad++ = (uint8)((qc >> 8) & 0xff);
685 } else {
686 /* 802.11i Draft 3.0 inconsistencies: */
687 /* Clause 8.3.4.4.3: "QC ­ The QoS Control, if present." */
688 /* Figure 30: "QC ­ The QoS TC from QoS Control, if present." */
689 /* F.10.4.1: "QC ­ The QoS TC from QoS Control, if present." */
691 /* Our implementation: Match clause 8.3.4.4.3 */
692 qc &= AES_CCMP_LEGACY_QOS_MASK;
693 *aad++ = (uint8)(qc & 0xff);
694 *aad++ = (uint8)((qc >> 8) & 0xff);
699 #if defined(WLFBT)
700 /* 128-bit long string of zeros */
701 static uint8 Z128[] = {
702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
706 /* CMAC Subkey generation polynomial for 128-bit blocks */
707 static uint8 R128[] = {
708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
712 /* AES-CMAC subkey generation
713 * - computes subkeys K1 and K2 of length AES_BLOCK_SZ
715 void
716 aes_cmac_gen_subkeys(const size_t kl, const uint8 *K, uint8 *K1, uint8 *K2)
718 uint8 L[AES_BLOCK_SZ];
719 uint8 high, low;
720 int i;
722 /* L = CIPHK(0b) */
723 aes_encrypt(kl, K, Z128, L);
724 pres("Key", kl, K);
725 pres("CIPHK", AES_BLOCK_SZ, L);
727 /* If MSB1(L) = 0, then K1 = L << 1 */
728 /* Else K1 = (L << 1) ⊕ Rb */
729 high = 0;
730 for (i = AES_BLOCK_SZ-1; i >= 0; i--) {
731 low = L[i] << 1;
732 K1[i] = low | high;
733 high = (L[i] & 0x80) >> 7;
735 if ((L[0] & 0x80) != 0) xor_128bit_block(K1, R128, K1);
736 pres("K1", AES_BLOCK_SZ, K1);
738 /* If MSB1(K1) = 0, then K2 = K1 << 1 */
739 /* Else K2 = (K1 << 1) ⊕ Rb */
740 high = 0;
741 for (i = AES_BLOCK_SZ-1; i >= 0; i--) {
742 low = K1[i] << 1;
743 K2[i] = low | high;
744 high = (K1[i] & 0x80) >> 7;
746 if ((K1[0] & 0x80) != 0) xor_128bit_block(K2, R128, K2);
747 pres("K2", AES_BLOCK_SZ, K2);
749 return;
752 /* AES-CMAC mode calculation
753 * - computes AES_CMAC_AUTH_LEN MAC
754 * - operates on complete bytes only (i.e. data_len is in bytes)
757 void
758 aes_cmac(const size_t key_len, const uint8* K,
759 const uint8 *K1, const uint8 *K2,
760 const size_t data_len,
761 const uint8 *ptxt,
762 uint8 *mac)
764 uint n, pblen, i;
765 uint8 Mn[AES_BLOCK_SZ], tmp[AES_BLOCK_SZ], C[AES_BLOCK_SZ];
766 uint32 rk[4 * (AES_MAXROUNDS + 1)];
768 /* If Mlen = 0, let n = 1; else, let n = ⎡Mlen/b⎤ */
769 if (data_len == 0)
770 n = 1;
771 else
772 n = (data_len + AES_BLOCK_SZ - 1)/AES_BLOCK_SZ;
774 /* Let M1, M2, ... , Mn-1, Mn* denote the unique sequence of bit
775 strings such that M = M1 || M2 || ... || Mn-1 || Mn*, where M1,
776 M2,..., Mn-1 are complete blocks. If Mn* is a complete block, let
777 Mn = K1 ⊕ Mn*; else, let Mn = K2 ⊕ (Mn*||10j), where j = nb-Mlen-1
780 if (data_len == (n * AES_BLOCK_SZ)) {
781 /* Mn* is a complete block */
782 xor_128bit_block(K1, &(ptxt[(n-1)*AES_BLOCK_SZ]), Mn);
783 } else {
784 /* Mn* is a partial block, pad with 0s and use K2 */
785 pblen = data_len - ((n-1)*AES_BLOCK_SZ);
786 for (i = 0; i < pblen; i++) Mn[i] = ptxt[((n-1)*AES_BLOCK_SZ) + i];
787 Mn[pblen] = 0x80;
788 for (i = pblen+1; i < AES_BLOCK_SZ; i++) Mn[i] = 0;
789 xor_128bit_block(K2, Mn, Mn);
792 /* Let C0 = 0b */
793 bzero(C, AES_BLOCK_SZ);
795 /* For i = 1 to n, let Ci = CIPHK(Ci-1 ⊕ Mi) */
796 rijndaelKeySetupEnc(rk, K, (int)AES_KEY_BITLEN(key_len));
797 for (i = 1; i < n; i++) {
798 xor_128bit_block(C, &(ptxt[(i-1)*AES_BLOCK_SZ]), tmp);
799 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, C);
801 xor_128bit_block(C, Mn, tmp);
802 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, C);
804 /* Let T = MSBTlen(Cn) */
805 bcopy(C, mac, AES_CMAC_AUTH_LEN);
807 return;
811 void
812 aes_cmac_calc(const uint8 *data, const size_t data_length, const uint8 *mic_key,
813 const size_t key_len, uint8 *mic)
815 uint8 K1[AES_BLOCK_SZ], K2[AES_BLOCK_SZ];
817 aes_cmac_gen_subkeys(key_len, mic_key, K1, K2);
818 aes_cmac(key_len, mic_key, K1, K2, data_length, data, mic);
820 #endif
822 #ifdef BCMAES_GENTABLE
823 /* AES table expansion for rijndael-alg-fst.c
824 * - can compute all 10 tables needed by rijndael-alg-fst.c
825 * - only stores table entries for non-NULL entries in "at" structure, so
826 * can be used to generate a subset of the tables if only some are needed
828 void
829 aes_gen_tables(const uint8 *S, const uint8 *Si, aes_tables_t at)
831 int k;
832 uint8 s2, s3;
833 uint8 si2, si4, si8, si9, sib, sid, sie;
834 uint32 Te0tmp, Td0tmp;
836 for (k = 0; k < AES_SBOX_ENTRIES; k++) {
837 /* 2 X S[k] */
838 XTIME(S[k], s2);
840 /* 3 X S[k] */
841 s3 = s2 ^ S[k];
843 /* 2 X Si[k] */
844 XTIME(Si[k], si2);
846 /* 4 X Si[k] */
847 XTIME(si2, si4);
849 /* 8 X Si[k] */
850 XTIME(si4, si8);
852 /* 9 X S[k] */
853 si9 = si8 ^ Si[k];
855 /* 11 X S[k] */
856 sib = si9 ^ si2;
858 /* 13 X S[k] */
859 sid = si8 ^ si4 ^ Si[k];
861 /* 14 X S[k] */
862 sie = si8 ^ si4 ^ si2;
864 Te0tmp = (s2 << 24) | (S[k] << 16) | (S[k] << 8) | s3;
865 if (at.Te0 != NULL)
866 at.Te0[k] = Te0tmp;
867 if (at.Te1 != NULL)
868 at.Te1[k] = ROTATE(Te0tmp, 24);
869 if (at.Te2 != NULL)
870 at.Te2[k] = ROTATE(Te0tmp, 16);
871 if (at.Te3 != NULL)
872 at.Te3[k] = ROTATE(Te0tmp, 8);
873 if (at.Te4 != NULL)
874 at.Te4[k] = (S[k] << 24) | (S[k] << 16) | (S[k] << 8) | S[k];
876 Td0tmp = (sie << 24) | (si9 << 16) | (sid << 8) | sib;
877 if (at.Td0 != NULL)
878 at.Td0[k] = Td0tmp;
879 if (at.Td1 != NULL)
880 at.Td1[k] = ROTATE(Td0tmp, 24);
881 if (at.Td2 != NULL)
882 at.Td2[k] = ROTATE(Td0tmp, 16);
883 if (at.Td3 != NULL)
884 at.Td3[k] = ROTATE(Td0tmp, 8);
885 if (at.Td4 != NULL)
886 at.Td4[k] = (Si[k] << 24) | (Si[k] << 16) | (Si[k] << 8) | Si[k];
889 #endif /* BCMAES_GENTABLE */
891 #ifdef BCMAES_TEST
892 #include "aes_vectors.h"
894 static uint8
895 get_nonce_1st_byte(struct dot11_header *h)
897 uint16 fc, subtype;
898 uint16 qc;
899 bool wds, qos;
901 qc = 0;
902 fc = ltoh16(h->fc);
903 subtype = (fc & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT;
904 wds = ((fc & (FC_TODS | FC_FROMDS)) == (FC_TODS | FC_FROMDS));
905 /* all QoS subtypes have the FC_SUBTYPE_QOS_DATA bit set */
906 qos = (FC_TYPE(fc) == FC_TYPE_DATA) && (subtype & FC_SUBTYPE_QOS_DATA);
908 if (qos) {
909 qc = ltoh16(*((uint16 *)((uchar *)h +
910 (wds ? DOT11_A4_HDR_LEN : DOT11_A3_HDR_LEN))));
913 /* nonce = priority octet || A2 || PN, !legacy */
914 return (uint8)(QOS_TID(qc) & 0x0f);
917 int main(int argc, char **argv)
919 uint8 output[BUFSIZ], input2[BUFSIZ];
920 int retv, k, fail = 0;
921 uint32 rk[4 * (AES_MAXROUNDS + 1)];
923 #ifdef BCMAES_GENTABLE
924 uint32 Te0test[256], Te1test[256], Te2test[256], Te3test[256], Te4test[256];
925 uint32 Td0test[256], Td1test[256], Td2test[256], Td3test[256], Td4test[256];
927 aes_tables_t at = {
928 Te0test, Te1test, Te2test, Te3test, Te4test,
929 Td0test, Td1test, Td2test, Td3test, Td4test
931 #endif /* BCMAES_GENTABLE */
933 /* AES-CBC */
934 dbg(("%s: AES-CBC\n", *argv));
935 for (k = 0; k < NUM_CBC_VECTORS; k++) {
936 rijndaelKeySetupEnc(rk, aes_cbc_vec[k].key,
937 AES_KEY_BITLEN(aes_cbc_vec[k].kl));
938 retv = aes_cbc_encrypt(rk, aes_cbc_vec[k].kl,
939 aes_cbc_vec[k].nonce, aes_cbc_vec[k].il,
940 aes_cbc_vec[k].input, output);
941 pres("AES CBC Encrypt: ", aes_cbc_vec[k].il, output);
943 if (retv == -1) {
944 dbg(("%s: aes_cbc_encrypt failed\n", *argv));
945 fail++;
947 if (bcmp(output, aes_cbc_vec[k].ref, aes_cbc_vec[k].il) != 0) {
948 dbg(("%s: aes_cbc_encrypt failed\n", *argv));
949 fail++;
952 rijndaelKeySetupDec(rk, aes_cbc_vec[k].key,
953 AES_KEY_BITLEN(aes_cbc_vec[k].kl));
954 retv = aes_cbc_decrypt(rk, aes_cbc_vec[k].kl,
955 aes_cbc_vec[k].nonce, aes_cbc_vec[k].il,
956 aes_cbc_vec[k].ref, input2);
957 pres("AES CBC Decrypt: ", aes_cbc_vec[k].il, input2);
959 if (retv == -1) {
960 dbg(("%s: aes_cbc_decrypt failed\n", *argv));
961 fail++;
963 if (bcmp(aes_cbc_vec[k].input, input2, aes_cbc_vec[k].il) != 0) {
964 dbg(("%s: aes_cbc_decrypt failed\n", *argv));
965 fail++;
969 /* AES-CTR, full blocks */
970 dbg(("%s: AES-CTR, full blocks\n", *argv));
971 for (k = 0; k < NUM_CTR_VECTORS; k++) {
972 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
973 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
974 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
975 aes_ctr_vec[k].nonce, aes_ctr_vec[k].il,
976 aes_ctr_vec[k].input, output);
977 pres("AES CTR Encrypt: ", aes_ctr_vec[k].il, output);
979 if (retv) {
980 dbg(("%s: aes_ctr_crypt failed\n", *argv));
981 fail++;
983 if (bcmp(output, aes_ctr_vec[k].ref, aes_ctr_vec[k].il) != 0) {
984 dbg(("%s: aes_ctr_crypt encrypt failed\n", *argv));
985 fail++;
988 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
989 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
990 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
991 aes_ctr_vec[k].nonce, aes_ctr_vec[k].il,
992 aes_ctr_vec[k].ref, input2);
993 pres("AES CTR Decrypt: ", aes_ctr_vec[k].il, input2);
995 if (retv) {
996 dbg(("%s: aes_ctr_crypt failed\n", *argv));
997 fail++;
999 if (bcmp(aes_ctr_vec[k].input, input2, aes_ctr_vec[k].il) != 0) {
1000 dbg(("%s: aes_ctr_crypt decrypt failed\n", *argv));
1001 fail++;
1005 /* AES-CTR, one partial block */
1006 dbg(("%s: AES-CTR, one partial block\n", *argv));
1007 for (k = 0; k < NUM_CTR_VECTORS; k++) {
1008 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
1009 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
1010 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
1011 aes_ctr_vec[k].nonce, k+1,
1012 aes_ctr_vec[k].input, output);
1013 pres("AES CTR Partial Block Encrypt: ", k+1, output);
1015 if (retv) {
1016 dbg(("%s: aes_ctr_crypt failed\n", *argv));
1017 fail++;
1019 if (bcmp(output, aes_ctr_vec[k].ref, k + 1) != 0) {
1020 dbg(("%s: aes_ctr_crypt encrypt failed\n", *argv));
1021 fail++;
1024 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
1025 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
1026 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
1027 aes_ctr_vec[k].nonce, k + 1,
1028 aes_ctr_vec[k].ref, input2);
1029 pres("AES CTR Partial Block Decrypt: ", k + 1, input2);
1031 if (retv) {
1032 dbg(("%s: aes_ctr_crypt failed\n", *argv));
1033 fail++;
1035 if (bcmp(aes_ctr_vec[k].input, input2, k + 1) != 0) {
1036 dbg(("%s: aes_ctr_crypt decrypt failed\n", *argv));
1037 fail++;
1041 /* AES-CTR, multi-block partial */
1042 dbg(("%s: AES-CTR, multi-block partial\n", *argv));
1043 for (k = 0; k < NUM_CTR_VECTORS; k++) {
1044 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
1045 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
1046 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
1047 aes_ctr_vec[k].nonce, AES_BLOCK_SZ + NUM_CTR_VECTORS+k+1,
1048 aes_ctr_vec[k].input, output);
1049 pres("AES CTR Partial Multi-Block Encrypt: ",
1050 AES_BLOCK_SZ + NUM_CTR_VECTORS + k + 1, output);
1052 if (retv) {
1053 dbg(("%s: aes_ctr_crypt failed\n", *argv));
1054 fail++;
1056 if (bcmp(output, aes_ctr_vec[k].ref, AES_BLOCK_SZ+NUM_CTR_VECTORS + k + 1) != 0) {
1057 dbg(("%s: aes_ctr_crypt encrypt failed\n", *argv));
1058 fail++;
1061 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
1062 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
1063 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
1064 aes_ctr_vec[k].nonce, AES_BLOCK_SZ + NUM_CTR_VECTORS + k + 1,
1065 aes_ctr_vec[k].ref, input2);
1066 pres("AES CTR Partial Multi-Block Decrypt: ",
1067 AES_BLOCK_SZ + NUM_CTR_VECTORS + k + 1, input2);
1069 if (retv) {
1070 dbg(("%s: aes_ctr_crypt failed\n", *argv));
1071 fail++;
1073 if (bcmp(aes_ctr_vec[k].input, input2,
1074 AES_BLOCK_SZ + NUM_CTR_VECTORS + k + 1) != 0) {
1075 dbg(("%s: aes_ctr_crypt decrypt failed\n", *argv));
1076 fail++;
1080 /* AES-CCM */
1081 dbg(("%s: AES-CCM\n", *argv));
1082 for (k = 0; k < NUM_CCM_VECTORS; k++) {
1083 rijndaelKeySetupEnc(rk, aes_ccm_vec[k].key,
1084 AES_KEY_BITLEN(aes_ccm_vec[k].kl));
1085 retv = aes_ccm_mac(rk, aes_ccm_vec[k].kl,
1086 aes_ccm_vec[k].nonce, aes_ccm_vec[k].al,
1087 aes_ccm_vec[k].aad, aes_ccm_vec[k].il,
1088 aes_ccm_vec[k].input, output);
1090 if (retv) {
1091 dbg(("%s: aes_ccm_mac failed\n", *argv));
1092 fail++;
1094 if (bcmp(output, aes_ccm_vec[k].mac, AES_CCM_AUTH_LEN) != 0) {
1095 dbg(("%s: aes_ccm_mac failed\n", *argv));
1096 fail++;
1099 rijndaelKeySetupEnc(rk, aes_ccm_vec[k].key,
1100 AES_KEY_BITLEN(aes_ccm_vec[k].kl));
1101 retv = aes_ccm_encrypt(rk, aes_ccm_vec[k].kl,
1102 aes_ccm_vec[k].nonce, aes_ccm_vec[k].al,
1103 aes_ccm_vec[k].aad, aes_ccm_vec[k].il,
1104 aes_ccm_vec[k].input, output, &output[aes_ccm_vec[k].il]);
1105 pres("AES CCM Encrypt: ", aes_ccm_vec[k].il + AES_CCM_AUTH_LEN, output);
1107 if (retv) {
1108 dbg(("%s: aes_ccm_encrypt failed\n", *argv));
1109 fail++;
1111 if (bcmp(output, aes_ccm_vec[k].ref, aes_ccm_vec[k].il + AES_CCM_AUTH_LEN) != 0) {
1112 dbg(("%s: aes_ccm_encrypt failed\n", *argv));
1113 fail++;
1116 rijndaelKeySetupEnc(rk, aes_ccm_vec[k].key,
1117 AES_KEY_BITLEN(aes_ccm_vec[k].kl));
1118 retv = aes_ccm_decrypt(rk, aes_ccm_vec[k].kl,
1119 aes_ccm_vec[k].nonce, aes_ccm_vec[k].al,
1120 aes_ccm_vec[k].aad, aes_ccm_vec[k].il + AES_CCM_AUTH_LEN,
1121 aes_ccm_vec[k].ref, input2);
1122 pres("AES CCM Decrypt: ", aes_ccm_vec[k].il + AES_CCM_AUTH_LEN, input2);
1124 if (retv) {
1125 dbg(("%s: aes_ccm_decrypt failed\n", *argv));
1126 fail++;
1128 if (bcmp(aes_ccm_vec[k].input, input2, aes_ccm_vec[k].il) != 0) {
1129 dbg(("%s: aes_ccm_decrypt failed\n", *argv));
1130 fail++;
1134 /* AES-CCMP */
1135 dbg(("%s: AES-CCMP\n", *argv));
1136 for (k = 0; k < NUM_CCMP_VECTORS; k++) {
1137 uint8 nonce_1st_byte;
1138 dbg(("%s: AES-CCMP vector %d\n", *argv, k));
1139 rijndaelKeySetupEnc(rk, aes_ccmp_vec[k].key,
1140 AES_KEY_BITLEN(aes_ccmp_vec[k].kl));
1141 bcopy(aes_ccmp_vec[k].input, output, aes_ccmp_vec[k].il);
1142 nonce_1st_byte = get_nonce_1st_byte((struct dot11_header *)output);
1143 retv = aes_ccmp_encrypt(rk, aes_ccmp_vec[k].kl,
1144 aes_ccmp_vec[k].il, output,
1145 aes_ccmp_vec[k].flags[2],
1146 nonce_1st_byte);
1148 if (retv) {
1149 dbg(("%s: aes_ccmp_encrypt of vector %d returned error\n", *argv, k));
1150 fail++;
1152 if (bcmp(output, aes_ccmp_vec[k].ref,
1153 aes_ccmp_vec[k].il+AES_CCM_AUTH_LEN) != 0) {
1154 dbg(("%s: aes_ccmp_encrypt of vector %d reference mismatch\n", *argv, k));
1155 fail++;
1158 rijndaelKeySetupEnc(rk, aes_ccmp_vec[k].key,
1159 AES_KEY_BITLEN(aes_ccmp_vec[k].kl));
1160 bcopy(aes_ccmp_vec[k].ref, output, aes_ccmp_vec[k].il+AES_CCM_AUTH_LEN);
1161 nonce_1st_byte = get_nonce_1st_byte((struct dot11_header *)output);
1162 retv = aes_ccmp_decrypt(rk, aes_ccmp_vec[k].kl,
1163 aes_ccmp_vec[k].il+AES_CCM_AUTH_LEN, output,
1164 aes_ccmp_vec[k].flags[2],
1165 nonce_1st_byte);
1167 if (retv) {
1168 dbg(("%s: aes_ccmp_decrypt of vector %d returned error %d\n",
1169 *argv, k, retv));
1170 fail++;
1172 if (bcmp(output, aes_ccmp_vec[k].input, aes_ccmp_vec[k].il) != 0) {
1173 dbg(("%s: aes_ccmp_decrypt of vector %d reference mismatch\n", *argv, k));
1174 fail++;
1179 #ifdef BCMAES_GENTABLE
1180 aes_gen_tables(AES_Sbox, AES_Inverse_Sbox, at);
1181 ptable("Te0", Te0test);
1182 ptable("Te1", Te1test);
1183 ptable("Te2", Te2test);
1184 ptable("Te3", Te3test);
1185 ptable("Te4", Te4test);
1187 ptable("Td0", Td0test);
1188 ptable("Td1", Td1test);
1189 ptable("Td2", Td2test);
1190 ptable("Td3", Td3test);
1191 ptable("Td4", Td4test);
1192 #endif /* BCMAES_GENTABLE */
1194 fprintf(stderr, "%s: %s\n", *argv, fail ? "FAILED" : "PASSED");
1195 return (fail);
1198 #endif /* BCMAES_TEST */