Migrate UI cleanup phase 4 from MIPS into ARM
[tomato.git] / release / src-rt-6.x.4708 / bcmcrypto / aes.c
blob37d0a40215c56c30e2e168e01520234eb76d28ac
1 /*
2 * aes.c
3 * AES encrypt/decrypt wrapper functions used around Rijndael reference
4 * implementation
6 * Copyright (C) 2012, 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 241182 2011-02-17 21:50:03Z $
17 #include <typedefs.h>
19 #ifdef BCMDRIVER
20 #include <osl.h>
21 #else
22 #include <string.h>
23 #endif /* BCMDRIVER */
25 #include <bcmendian.h>
26 #include <bcmutils.h>
27 #include <proto/802.11.h>
28 #include <bcmcrypto/aes.h>
29 #include <bcmcrypto/rijndael-alg-fst.h>
31 #ifdef BCMAES_TEST
32 #include <stdio.h>
34 #define dbg(args) printf args
36 void
37 pinter(const char *label, const uint8 *A, const size_t il, const uint8 *R)
39 int k;
40 printf("%s", label);
41 for (k = 0; k < AES_BLOCK_SZ; k++)
42 printf("%02X", A[k]);
43 printf(" ");
44 for (k = 0; k < il; k++) {
45 printf("%02X", R[k]);
46 if (!((k + 1) % AES_BLOCK_SZ))
47 printf(" ");
49 printf("\n");
52 void
53 pres(const char *label, const size_t len, const uint8 *data)
55 int k;
56 printf("%s\n", label);
57 for (k = 0; k < len; k++) {
58 printf("%02x ", data[k]);
59 if (!((k + 1) % AES_BLOCK_SZ))
60 printf("\n");
62 printf("\n");
65 #ifdef BCMAES_GENTABLE
66 void
67 ptable(const char *tablename, const uint32 *table)
69 int k;
70 printf("static const uint32 %s[256] = {\n ", tablename);
71 for (k = 0; k < 256; k++) {
72 printf("0x%08xU", table[k]);
73 if ((k+1) % 4)
74 printf(", ");
75 else
76 if (k != 255)
77 printf(",\n ");
78 else
79 printf("\n");
81 printf("};\n");
83 #endif /* BCMAES_GENTABLE */
85 #else
86 #define dbg(args)
87 #define pinter(label, A, il, R)
88 #define pres(label, len, data)
89 #endif /* BCMAES_TEST */
92 * ptxt - plain text
93 * ctxt - cipher text
96 /* Perform AES block encryption, including key schedule setup */
97 void
98 BCMROMFN(aes_encrypt)(const size_t kl, const uint8 *K, const uint8 *ptxt, uint8 *ctxt)
100 uint32 rk[4 * (AES_MAXROUNDS + 1)];
101 rijndaelKeySetupEnc(rk, K, (int)AES_KEY_BITLEN(kl));
102 rijndaelEncrypt(rk, (int)AES_ROUNDS(kl), ptxt, ctxt);
105 /* Perform AES block decryption, including key schedule setup */
106 void
107 BCMROMFN(aes_decrypt)(const size_t kl, const uint8 *K, const uint8 *ctxt, uint8 *ptxt)
109 uint32 rk[4 * (AES_MAXROUNDS + 1)];
110 rijndaelKeySetupDec(rk, K, (int)AES_KEY_BITLEN(kl));
111 rijndaelDecrypt(rk, (int)AES_ROUNDS(kl), ctxt, ptxt);
114 /* AES-CBC mode encryption algorithm
115 * - handle partial blocks with padding of type as above
116 * - assumes nonce is ready to use as-is (i.e. any
117 * encryption/randomization of nonce/IV is handled by the caller)
118 * - ptxt and ctxt can point to the same location
119 * - returns -1 on error or final length of output
124 BCMROMFN(aes_cbc_encrypt_pad)(uint32 *rk,
125 const size_t key_len,
126 const uint8 *nonce,
127 const size_t data_len,
128 const uint8 *ptxt,
129 uint8 *ctxt,
130 uint8 padd_type)
133 uint8 tmp[AES_BLOCK_SZ];
134 uint32 encrypt_len = 0;
135 uint32 j;
137 /* First block get XORed with nonce/IV */
138 const unsigned char *iv = nonce;
139 unsigned char *crypt_data = ctxt;
140 const unsigned char *plain_data = ptxt;
141 uint32 remaining = (uint32)data_len;
143 while (remaining >= AES_BLOCK_SZ) {
144 xor_128bit_block(iv, plain_data, tmp);
145 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, crypt_data);
146 remaining -= AES_BLOCK_SZ;
147 iv = crypt_data;
148 crypt_data += AES_BLOCK_SZ;
149 plain_data += AES_BLOCK_SZ;
150 encrypt_len += AES_BLOCK_SZ;
153 if (padd_type == NO_PADDING)
154 return encrypt_len;
156 if (remaining) {
157 for (j = 0; j < remaining; j++) {
158 tmp[j] = plain_data[j] ^ iv[j];
161 switch (padd_type) {
162 case PAD_LEN_PADDING:
163 for (j = remaining; j < AES_BLOCK_SZ; j++) {
164 tmp[j] = (AES_BLOCK_SZ - remaining) ^ iv[j];
166 break;
167 default:
168 return -1;
171 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, crypt_data);
172 encrypt_len += AES_BLOCK_SZ;
174 return (encrypt_len);
177 /* AES-CBC mode encryption algorithm
178 * - does not handle partial blocks
179 * - assumes nonce is ready to use as-is (i.e. any
180 * encryption/randomization of nonce/IV is handled by the caller)
181 * - ptxt and ctxt can point to the same location
182 * - returns -1 on error
186 BCMROMFN(aes_cbc_encrypt)(uint32 *rk,
187 const size_t key_len,
188 const uint8 *nonce,
189 const size_t data_len,
190 const uint8 *ptxt,
191 uint8 *ctxt)
193 if (data_len % AES_BLOCK_SZ)
194 return (-1);
195 if (data_len < AES_BLOCK_SZ)
196 return (-1);
198 return aes_cbc_encrypt_pad(rk, key_len, nonce, data_len, ptxt, ctxt, NO_PADDING);
202 /* AES-CBC mode decryption algorithm
203 * - handle partial plaintext blocks with padding
204 * - ptxt and ctxt can point to the same location
205 * - returns -1 on error
208 BCMROMFN(aes_cbc_decrypt_pad)(uint32 *rk,
209 const size_t key_len,
210 const uint8 *nonce,
211 const size_t data_len,
212 const uint8 *ctxt,
213 uint8 *ptxt,
214 uint8 padd_type)
216 uint8 tmp[AES_BLOCK_SZ];
217 uint32 remaining = (uint32)data_len;
218 /* First block get XORed with nonce/IV */
219 const unsigned char *iv = nonce;
220 const unsigned char *crypt_data = ctxt;
221 uint32 plaintext_len = 0;
222 unsigned char *plain_data = ptxt;
224 if (data_len % AES_BLOCK_SZ)
225 return (-1);
226 if (data_len < AES_BLOCK_SZ)
227 return (-1);
229 while (remaining >= AES_BLOCK_SZ) {
230 aes_block_decrypt((int)AES_ROUNDS(key_len), rk, crypt_data, tmp);
231 xor_128bit_block(tmp, iv, plain_data);
232 remaining -= AES_BLOCK_SZ;
233 iv = crypt_data;
234 crypt_data += AES_BLOCK_SZ;
235 plain_data += AES_BLOCK_SZ;
236 plaintext_len += AES_BLOCK_SZ;
238 if (padd_type == PAD_LEN_PADDING)
239 plaintext_len -= ptxt[plaintext_len -1];
240 return (plaintext_len);
244 BCMROMFN(aes_cbc_decrypt)(uint32 *rk,
245 const size_t key_len,
246 const uint8 *nonce,
247 const size_t data_len,
248 const uint8 *ctxt,
249 uint8 *ptxt)
251 return aes_cbc_decrypt_pad(rk, key_len, nonce, data_len, ctxt, ptxt, NO_PADDING);
254 /* AES-CTR mode encryption/decryption algorithm
255 * - max data_len is (AES_BLOCK_SZ * 2^16)
256 * - nonce must be AES_BLOCK_SZ bytes
257 * - assumes nonce is ready to use as-is (i.e. any
258 * encryption/randomization of nonce/IV is handled by the caller)
259 * - ptxt and ctxt can point to the same location
260 * - returns -1 on error
263 BCMROMFN(aes_ctr_crypt)(unsigned int *rk,
264 const size_t key_len,
265 const uint8 *nonce,
266 const size_t data_len,
267 const uint8 *ptxt,
268 uint8 *ctxt)
270 size_t k;
271 uint8 tmp[AES_BLOCK_SZ], ctr[AES_BLOCK_SZ];
273 if (data_len > (AES_BLOCK_SZ * AES_CTR_MAXBLOCKS)) return (-1);
275 memcpy(ctr, nonce, AES_BLOCK_SZ);
277 for (k = 0; k < (data_len / AES_BLOCK_SZ); k++) {
278 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, ctr, tmp);
279 xor_128bit_block(ptxt, tmp, ctxt);
280 ctr[AES_BLOCK_SZ-1]++;
281 if (!ctr[AES_BLOCK_SZ - 1]) ctr[AES_BLOCK_SZ - 2]++;
282 ptxt += AES_BLOCK_SZ;
283 ctxt += AES_BLOCK_SZ;
285 /* handle partial block */
286 if (data_len % AES_BLOCK_SZ) {
287 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, ctr, tmp);
288 for (k = 0; k < (data_len % AES_BLOCK_SZ); k++)
289 ctxt[k] = ptxt[k] ^ tmp[k];
292 return (0);
296 /* AES-CCM mode MAC calculation
297 * - computes AES_CCM_AUTH_LEN MAC
298 * - nonce must be AES_CCM_NONCE_LEN bytes
299 * - returns -1 on error
303 BCMROMFN(aes_ccm_mac)(unsigned int *rk,
304 const size_t key_len,
305 const uint8 *nonce,
306 const size_t aad_len,
307 const uint8 *aad,
308 const size_t data_len,
309 const uint8 *ptxt,
310 uint8 *mac)
312 uint8 B_0[AES_BLOCK_SZ], X[AES_BLOCK_SZ];
313 size_t j, k;
315 if (aad_len > AES_CCM_AAD_MAX_LEN) return (-1);
317 pres("aes_ccm_mac: nonce:", AES_CCM_NONCE_LEN, nonce);
318 pres("aes_ccm_mac: aad:", aad_len, aad);
319 pres("aes_ccm_mac: input:", data_len, ptxt);
321 /* B_0 = Flags || Nonce || l(m) */
322 B_0[0] = AES_CCM_AUTH_FLAGS;
323 if (aad_len)
324 B_0[0] |= AES_CCM_AUTH_AAD_FLAG;
325 memcpy(&B_0[1], nonce, AES_CCM_NONCE_LEN);
326 B_0[AES_BLOCK_SZ - 2] = (uint8)(data_len >> 8) & 0xff;
327 B_0[AES_BLOCK_SZ - 1] = (uint8)(data_len & 0xff);
329 /* X_1 := E( K, B_0 ) */
330 pres("aes_ccm_mac: CBC IV in:", AES_BLOCK_SZ, B_0);
331 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, B_0, X);
332 pres("aes_ccm_mac: CBC IV out:", AES_BLOCK_SZ, X);
334 /* X_i + 1 := E( K, X_i XOR B_i ) for i = 1, ..., n */
336 /* first the AAD */
337 if (aad_len) {
338 pres("aes_ccm_mac: aad:", aad_len, aad);
339 X[0] ^= (aad_len >> 8) & 0xff;
340 X[1] ^= aad_len & 0xff;
341 k = 2;
342 j = aad_len;
343 while (j--) {
344 X[k] ^= *aad++;
345 k++;
346 if (k == AES_BLOCK_SZ) {
347 pres("aes_ccm_mac: After xor (full block aad):", AES_BLOCK_SZ, X);
348 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
349 pres("aes_ccm_mac: After AES (full block aad):", AES_BLOCK_SZ, X);
350 k = 0;
353 /* handle partial last block */
354 if (k % AES_BLOCK_SZ) {
355 pres("aes_ccm_mac: After xor (partial block aad):", AES_BLOCK_SZ, X);
356 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
357 pres("aes_ccm_mac: After AES (partial block aad):", AES_BLOCK_SZ, X);
361 /* then the message data */
362 for (k = 0; k < (data_len / AES_BLOCK_SZ); k++) {
363 xor_128bit_block(X, ptxt, X);
364 pres("aes_ccm_mac: After xor (full block data):", AES_BLOCK_SZ, X);
365 ptxt += AES_BLOCK_SZ;
366 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
367 pres("aes_ccm_mac: After AES (full block data):", AES_BLOCK_SZ, X);
369 /* last block may be partial, padding is implicit in this xor */
370 for (k = 0; k < (data_len % AES_BLOCK_SZ); k++)
371 X[k] ^= *ptxt++;
372 if (data_len % AES_BLOCK_SZ) {
373 pres("aes_ccm_mac: After xor (final block data):", AES_BLOCK_SZ, X);
374 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
375 pres("aes_ccm_mac: After AES (final block data):", AES_BLOCK_SZ, X);
378 /* T := first-M-bytes( X_n+1 ) */
379 memcpy(mac, X, AES_CCM_AUTH_LEN);
380 pres("aes_ccm_mac: MAC:", AES_CCM_AUTH_LEN, mac);
382 return (0);
385 /* AES-CCM mode encryption
386 * - computes AES_CCM_AUTH_LEN MAC and then encrypts ptxt and MAC
387 * - nonce must be AES_CCM_NONCE_LEN bytes
388 * - ctxt must have sufficient tailroom for CCM MAC
389 * - ptxt and ctxt can point to the same location
390 * - returns -1 on error
394 BCMROMFN(aes_ccm_encrypt)(unsigned int *rk,
395 const size_t key_len,
396 const uint8 *nonce,
397 const size_t aad_len,
398 const uint8 *aad,
399 const size_t data_len,
400 const uint8 *ptxt,
401 uint8 *ctxt,
402 uint8 *mac)
404 uint8 A[AES_BLOCK_SZ], X[AES_BLOCK_SZ];
406 /* initialize counter */
407 A[0] = AES_CCM_CRYPT_FLAGS;
408 memcpy(&A[1], nonce, AES_CCM_NONCE_LEN);
409 A[AES_BLOCK_SZ-2] = 0;
410 A[AES_BLOCK_SZ-1] = 0;
411 pres("aes_ccm_encrypt: initial counter:", AES_BLOCK_SZ, A);
413 /* calculate and encrypt MAC */
414 if (aes_ccm_mac(rk, key_len, nonce, aad_len, aad, data_len, ptxt, X))
415 return (-1);
416 pres("aes_ccm_encrypt: MAC:", AES_CCM_AUTH_LEN, X);
417 if (aes_ctr_crypt(rk, key_len, A, AES_CCM_AUTH_LEN, X, X))
418 return (-1);
419 pres("aes_ccm_encrypt: encrypted MAC:", AES_CCM_AUTH_LEN, X);
420 memcpy(mac, X, AES_CCM_AUTH_LEN);
422 /* encrypt data */
423 A[AES_BLOCK_SZ - 1] = 1;
424 if (aes_ctr_crypt(rk, key_len, A, data_len, ptxt, ctxt))
425 return (-1);
426 pres("aes_ccm_encrypt: encrypted data:", data_len, ctxt);
428 return (0);
431 /* AES-CCM mode decryption
432 * - decrypts ctxt, then computes AES_CCM_AUTH_LEN MAC and checks it against
433 * then decrypted MAC
434 * - the decrypted MAC is included in ptxt
435 * - nonce must be AES_CCM_NONCE_LEN bytes
436 * - ptxt and ctxt can point to the same location
437 * - returns -1 on error
441 BCMROMFN(aes_ccm_decrypt)(unsigned int *rk,
442 const size_t key_len,
443 const uint8 *nonce,
444 const size_t aad_len,
445 const uint8 *aad,
446 const size_t data_len,
447 const uint8 *ctxt,
448 uint8 *ptxt)
450 uint8 A[AES_BLOCK_SZ], X[AES_BLOCK_SZ];
452 /* initialize counter */
453 A[0] = AES_CCM_CRYPT_FLAGS;
454 memcpy(&A[1], nonce, AES_CCM_NONCE_LEN);
455 A[AES_BLOCK_SZ - 2] = 0;
456 A[AES_BLOCK_SZ - 1] = 1;
457 pres("aes_ccm_decrypt: initial counter:", AES_BLOCK_SZ, A);
459 /* decrypt data */
460 if (aes_ctr_crypt(rk, key_len, A, data_len-AES_CCM_AUTH_LEN, ctxt, ptxt))
461 return (-1);
462 pres("aes_ccm_decrypt: decrypted data:", data_len-AES_CCM_AUTH_LEN, ptxt);
464 /* decrypt MAC */
465 A[AES_BLOCK_SZ - 2] = 0;
466 A[AES_BLOCK_SZ - 1] = 0;
467 if (aes_ctr_crypt(rk, key_len, A, AES_CCM_AUTH_LEN,
468 ctxt+data_len-AES_CCM_AUTH_LEN, ptxt + data_len - AES_CCM_AUTH_LEN))
469 return (-1);
470 pres("aes_ccm_decrypt: decrypted MAC:", AES_CCM_AUTH_LEN,
471 ptxt + data_len - AES_CCM_AUTH_LEN);
473 /* calculate MAC */
474 if (aes_ccm_mac(rk, key_len, nonce, aad_len, aad,
475 data_len - AES_CCM_AUTH_LEN, ptxt, X))
476 return (-1);
477 pres("aes_ccm_decrypt: MAC:", AES_CCM_AUTH_LEN, X);
478 if (memcmp(X, ptxt + data_len - AES_CCM_AUTH_LEN, AES_CCM_AUTH_LEN) != 0)
479 return (-1);
481 return (0);
484 /* AES-CCMP mode encryption algorithm
485 * - packet buffer should be an 802.11 MPDU, starting with Frame Control,
486 * and including the CCMP extended IV
487 * - encrypts in-place
488 * - packet buffer must have sufficient tailroom for CCMP MAC
489 * - returns -1 on error
494 BCMROMFN(aes_ccmp_encrypt)(unsigned int *rk,
495 const size_t key_len,
496 const size_t data_len,
497 uint8 *p,
498 bool legacy,
499 uint8 nonce_1st_byte)
501 uint8 nonce[AES_CCMP_NONCE_LEN], aad[AES_CCMP_AAD_MAX_LEN];
502 struct dot11_header *h = (struct dot11_header*) p;
503 uint la, lh;
504 int status = 0;
506 aes_ccmp_cal_params(h, legacy, nonce_1st_byte, nonce, aad, &la, &lh);
508 pres("aes_ccmp_encrypt: aad:", la, aad);
511 * MData:
512 * B3..Bn, n = floor((l(m)+(AES_BLOCK_SZ-1))/AES_BLOCK_SZ) + 2
513 * m || pad(m)
516 status = aes_ccm_encrypt(rk, key_len, nonce, la, aad,
517 data_len - lh, p + lh, p + lh, p + data_len);
519 pres("aes_ccmp_encrypt: Encrypted packet with MAC:",
520 data_len+AES_CCMP_AUTH_LEN, p);
522 if (status)
523 return (AES_CCMP_ENCRYPT_ERROR);
524 else
525 return (AES_CCMP_ENCRYPT_SUCCESS);
529 BCMROMFN(aes_ccmp_decrypt)(unsigned int *rk,
530 const size_t key_len,
531 const size_t data_len,
532 uint8 *p,
533 bool legacy,
534 uint8 nonce_1st_byte)
536 uint8 nonce[AES_CCMP_NONCE_LEN], aad[AES_CCMP_AAD_MAX_LEN];
537 struct dot11_header *h = (struct dot11_header *)p;
538 uint la, lh;
539 int status = 0;
541 aes_ccmp_cal_params(h, legacy, nonce_1st_byte, nonce, aad, &la, &lh);
543 pres("aes_ccmp_decrypt: aad:", la, aad);
546 * MData:
547 * B3..Bn, n = floor((l(m)+(AES_BLOCK_SZ-1))/AES_BLOCK_SZ) + 2
548 * m || pad(m)
551 status = aes_ccm_decrypt(rk, key_len, nonce, la, aad,
552 data_len - lh, p + lh, p + lh);
554 pres("aes_ccmp_decrypt: Decrypted packet with MAC:", data_len, p);
556 if (status)
557 return (AES_CCMP_DECRYPT_MIC_FAIL);
558 else
559 return (AES_CCMP_DECRYPT_SUCCESS);
562 void
563 BCMROMFN(aes_ccmp_cal_params)(struct dot11_header *h, bool legacy,
564 uint8 nonce_1st_byte, uint8 *nonce, uint8 *aad, uint *la, uint *lh)
566 uint8 *iv_data;
567 uint16 fc, subtype;
568 uint16 seq, qc = 0;
569 uint addlen = 0;
570 bool wds, qos;
572 memset(nonce, 0, AES_CCMP_NONCE_LEN);
573 memset(aad, 0, AES_CCMP_AAD_MAX_LEN);
575 fc = ltoh16(h->fc);
576 subtype = (fc & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT;
577 wds = ((fc & (FC_TODS | FC_FROMDS)) == (FC_TODS | FC_FROMDS));
578 /* all QoS subtypes have the FC_SUBTYPE_QOS_DATA bit set */
579 qos = (FC_TYPE(fc) == FC_TYPE_DATA) && (subtype & FC_SUBTYPE_QOS_DATA);
581 if (qos) {
582 qc = ltoh16(*((uint16 *)((uchar *)h +
583 (wds ? DOT11_A4_HDR_LEN : DOT11_A3_HDR_LEN))));
586 if (wds) {
587 dbg(("aes_ccmp_cal_params: A4 present\n"));
588 addlen += ETHER_ADDR_LEN;
590 if (qos) {
591 dbg(("aes_ccmp_cal_params: QC present\n"));
592 addlen += DOT11_QOS_LEN;
595 /* length of MPDU header, including IV */
596 *lh = DOT11_A3_HDR_LEN + DOT11_IV_AES_CCM_LEN + addlen;
597 /* length of AAD */
598 *la = AES_CCMP_AAD_MIN_LEN + addlen;
599 /* pointer to IV */
600 iv_data = (uint8 *)h + DOT11_A3_HDR_LEN + addlen;
602 *nonce++ = nonce_1st_byte;
604 memcpy(nonce, (uchar *)&h->a2, ETHER_ADDR_LEN);
605 nonce += ETHER_ADDR_LEN;
607 /* PN[5] */
608 *nonce++ = iv_data[7];
609 /* PN[4] */
610 *nonce++ = iv_data[6];
611 /* PN[3] */
612 *nonce++ = iv_data[5];
613 /* PN[2] */
614 *nonce++ = iv_data[4];
615 /* PN[1] */
616 *nonce++ = iv_data[1];
617 /* PN[0] */
618 *nonce++ = iv_data[0];
620 pres("aes_ccmp_cal_params: nonce:", AES_CCM_NONCE_LEN, nonce - AES_CCM_NONCE_LEN);
622 /* B1..B2 = l(aad) || aad || pad(aad) */
623 /* aad: maskedFC || A1 || A2 || A3 || maskedSC || A4 || maskedQC */
625 if (!legacy) {
626 #ifdef MFP
627 /* For a management frame, don't mask the the subtype bits */
628 if (nonce_1st_byte & AES_CCMP_NF_MANAGEMENT)
629 fc &= (FC_SUBTYPE_MASK | AES_CCMP_FC_MASK);
630 else
631 #endif /* MFP */
632 fc &= AES_CCMP_FC_MASK;
633 } else {
634 /* 802.11i Draft 3 inconsistencies:
635 * Clause 8.3.4.4.3: "FC - MPDU Frame Control field, with Retry bit masked
636 * to zero." (8.3.4.4.3).
637 * Figure 29: "FC - MPDU Frame Control field, with Retry, MoreData, CF-ACK,
638 * CF-POLL bits masked to zero."
639 * F.10.4.1: "FC - MPDU Frame Control field, with Retry, MoreData,
640 * PwrMgmt bits masked to zero."
643 /* Our implementation: match 8.3.4.4.3 */
644 fc &= AES_CCMP_LEGACY_FC_MASK;
646 *aad++ = (uint8)(fc & 0xff);
647 *aad++ = (uint8)((fc >> 8) & 0xff);
649 memcpy(aad, (uchar *)&h->a1, 3*ETHER_ADDR_LEN);
650 aad += 3*ETHER_ADDR_LEN;
652 seq = ltoh16(h->seq);
653 if (!legacy) {
654 seq &= AES_CCMP_SEQ_MASK;
655 } else {
656 seq &= AES_CCMP_LEGACY_SEQ_MASK;
659 *aad++ = (uint8)(seq & 0xff);
660 *aad++ = (uint8)((seq >> 8) & 0xff);
662 if (wds) {
663 memcpy(aad, (uchar *)&h->a4, ETHER_ADDR_LEN);
664 aad += ETHER_ADDR_LEN;
666 if (qos) {
667 if (!legacy) {
668 /* 802.11i Draft 7.0 inconsistencies:
669 * Clause 8.3.3.3.2: "QC - The Quality of Service Control, a
670 * two-octet field that includes the MSDU priority, reserved
671 * for future use."
672 * I.7.4: TID portion of QoS
675 /* Our implementation: match the test vectors */
676 qc &= AES_CCMP_QOS_MASK;
677 *aad++ = (uint8)(qc & 0xff);
678 *aad++ = (uint8)((qc >> 8) & 0xff);
679 } else {
680 /* 802.11i Draft 3.0 inconsistencies: */
681 /* Clause 8.3.4.4.3: "QC - The QoS Control, if present." */
682 /* Figure 30: "QC - The QoS TC from QoS Control, if present." */
683 /* F.10.4.1: "QC - The QoS TC from QoS Control, if present." */
685 /* Our implementation: Match clause 8.3.4.4.3 */
686 qc &= AES_CCMP_LEGACY_QOS_MASK;
687 *aad++ = (uint8)(qc & 0xff);
688 *aad++ = (uint8)((qc >> 8) & 0xff);
693 /* 128-bit long string of zeros */
694 static const uint8 Z128[] = {
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
699 /* CMAC Subkey generation polynomial for 128-bit blocks */
700 static const uint8 R128[] = {
701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
705 /* AES-CMAC subkey generation
706 * - computes subkeys K1 and K2 of length AES_BLOCK_SZ
708 void
709 aes_cmac_gen_subkeys(const size_t kl, const uint8 *K, uint8 *K1, uint8 *K2)
711 uint8 L[AES_BLOCK_SZ];
712 uint8 high, low;
713 int i;
715 /* L = CIPHK(0b) */
716 aes_encrypt(kl, K, Z128, L);
717 pres("Key", kl, K);
718 pres("CIPHK", AES_BLOCK_SZ, L);
720 /* If MSB1(L) = 0, then K1 = L << 1 */
721 /* Else K1 = (L << 1) ^ Rb */
722 high = 0;
723 for (i = AES_BLOCK_SZ-1; i >= 0; i--) {
724 low = L[i] << 1;
725 K1[i] = low | high;
726 high = (L[i] & 0x80) >> 7;
728 if ((L[0] & 0x80) != 0)
729 xor_128bit_block(K1, R128, K1);
730 pres("K1", AES_BLOCK_SZ, K1);
732 /* If MSB1(K1) = 0, then K2 = K1 << 1 */
733 /* Else K2 = (K1 << 1) ^ Rb */
734 high = 0;
735 for (i = AES_BLOCK_SZ-1; i >= 0; i--) {
736 low = K1[i] << 1;
737 K2[i] = low | high;
738 high = (K1[i] & 0x80) >> 7;
740 if ((K1[0] & 0x80) != 0)
741 xor_128bit_block(K2, R128, K2);
742 pres("K2", AES_BLOCK_SZ, K2);
744 return;
747 /* AES-CMAC mode calculation
748 * - computes AES_CMAC_AUTH_LEN MAC
749 * - operates on complete bytes only (i.e. data_len is in bytes)
752 void
753 aes_cmac(const size_t key_len, const uint8* K,
754 const uint8 *K1, const uint8 *K2,
755 const size_t data_len,
756 const uint8 *ptxt,
757 uint8 *mac)
759 uint n, pblen, i;
760 uint8 Mn[AES_BLOCK_SZ], tmp[AES_BLOCK_SZ], C[AES_BLOCK_SZ];
761 uint32 rk[4 * (AES_MAXROUNDS + 1)];
763 /* If Mlen = 0, let n = 1; else, let n = Mlen/b */
764 if (data_len == 0)
765 n = 1;
766 else
767 n = ((uint)data_len + AES_BLOCK_SZ - 1)/AES_BLOCK_SZ;
769 /* Let M1, M2, ... , Mn-1, Mn* denote the unique sequence of bit
770 strings such that M = M1 || M2 || ... || Mn-1 || Mn*, where M1,
771 M2,..., Mn-1 are complete blocks. If Mn* is a complete block, let
772 Mn = K1 ^ Mn*; else, let Mn = K2 ^ (Mn*||10j), where j = nb-Mlen-1
775 if (data_len == (n * AES_BLOCK_SZ)) {
776 /* Mn* is a complete block */
777 xor_128bit_block(K1, &(ptxt[(n-1)*AES_BLOCK_SZ]), Mn);
778 } else {
779 /* Mn* is a partial block, pad with 0s and use K2 */
780 pblen = (uint)data_len - ((n-1)*AES_BLOCK_SZ);
781 for (i = 0; i < pblen; i++)
782 Mn[i] = ptxt[((n-1)*AES_BLOCK_SZ) + i];
783 Mn[pblen] = 0x80;
784 for (i = pblen + 1; i < AES_BLOCK_SZ; i++)
785 Mn[i] = 0;
786 xor_128bit_block(K2, Mn, Mn);
789 /* Let C0 = 0b */
790 memset(C, 0, AES_BLOCK_SZ);
792 /* For i = 1 to n, let Ci = CIPHK(Ci-1 ^ Mi) */
793 rijndaelKeySetupEnc(rk, K, (int)AES_KEY_BITLEN(key_len));
794 for (i = 1; i < n; i++) {
795 xor_128bit_block(C, &(ptxt[(i-1)*AES_BLOCK_SZ]), tmp);
796 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, C);
798 xor_128bit_block(C, Mn, tmp);
799 aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, C);
801 /* Let T = MSBTlen(Cn) */
802 memcpy(mac, C, AES_CMAC_AUTH_LEN);
804 return;
807 void
808 aes_cmac_calc(const uint8 *data, const size_t data_length, const uint8 *mic_key,
809 const size_t key_len, uint8 *mic)
811 uint8 K1[AES_BLOCK_SZ], K2[AES_BLOCK_SZ];
813 aes_cmac_gen_subkeys(key_len, mic_key, K1, K2);
814 aes_cmac(key_len, mic_key, K1, K2, data_length, data, mic);
817 #ifdef BCMAES_GENTABLE
818 /* AES table expansion for rijndael-alg-fst.c
819 * - can compute all 10 tables needed by rijndael-alg-fst.c
820 * - only stores table entries for non-NULL entries in "at" structure, so
821 * can be used to generate a subset of the tables if only some are needed
823 void
824 aes_gen_tables(const uint8 *S, const uint8 *Si, aes_tables_t at)
826 int k;
827 uint8 s2, s3;
828 uint8 si2, si4, si8, si9, sib, sid, sie;
829 uint32 Te0tmp, Td0tmp;
831 for (k = 0; k < AES_SBOX_ENTRIES; k++) {
832 /* 2 X S[k] */
833 XTIME(S[k], s2);
835 /* 3 X S[k] */
836 s3 = s2 ^ S[k];
838 /* 2 X Si[k] */
839 XTIME(Si[k], si2);
841 /* 4 X Si[k] */
842 XTIME(si2, si4);
844 /* 8 X Si[k] */
845 XTIME(si4, si8);
847 /* 9 X S[k] */
848 si9 = si8 ^ Si[k];
850 /* 11 X S[k] */
851 sib = si9 ^ si2;
853 /* 13 X S[k] */
854 sid = si8 ^ si4 ^ Si[k];
856 /* 14 X S[k] */
857 sie = si8 ^ si4 ^ si2;
859 Te0tmp = (s2 << 24) | (S[k] << 16) | (S[k] << 8) | s3;
860 if (at.Te0 != NULL)
861 at.Te0[k] = Te0tmp;
862 if (at.Te1 != NULL)
863 at.Te1[k] = ROTATE(Te0tmp, 24);
864 if (at.Te2 != NULL)
865 at.Te2[k] = ROTATE(Te0tmp, 16);
866 if (at.Te3 != NULL)
867 at.Te3[k] = ROTATE(Te0tmp, 8);
868 if (at.Te4 != NULL)
869 at.Te4[k] = (S[k] << 24) | (S[k] << 16) | (S[k] << 8) | S[k];
871 Td0tmp = (sie << 24) | (si9 << 16) | (sid << 8) | sib;
872 if (at.Td0 != NULL)
873 at.Td0[k] = Td0tmp;
874 if (at.Td1 != NULL)
875 at.Td1[k] = ROTATE(Td0tmp, 24);
876 if (at.Td2 != NULL)
877 at.Td2[k] = ROTATE(Td0tmp, 16);
878 if (at.Td3 != NULL)
879 at.Td3[k] = ROTATE(Td0tmp, 8);
880 if (at.Td4 != NULL)
881 at.Td4[k] = (Si[k] << 24) | (Si[k] << 16) | (Si[k] << 8) | Si[k];
884 #endif /* BCMAES_GENTABLE */
886 #ifdef BCMAES_TEST
887 #include "aes_vectors.h"
889 static uint8
890 get_nonce_1st_byte(struct dot11_header *h)
892 uint16 fc, subtype;
893 uint16 qc;
894 bool wds, qos;
896 qc = 0;
897 fc = ltoh16(h->fc);
898 subtype = (fc & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT;
899 wds = ((fc & (FC_TODS | FC_FROMDS)) == (FC_TODS | FC_FROMDS));
900 /* all QoS subtypes have the FC_SUBTYPE_QOS_DATA bit set */
901 qos = (FC_TYPE(fc) == FC_TYPE_DATA) && (subtype & FC_SUBTYPE_QOS_DATA);
903 if (qos) {
904 qc = ltoh16(*((uint16 *)((uchar *)h +
905 (wds ? DOT11_A4_HDR_LEN : DOT11_A3_HDR_LEN))));
908 /* nonce = priority octet || A2 || PN, !legacy */
909 return (uint8)(QOS_TID(qc) & 0x0f);
913 main(int argc, char **argv)
915 uint8 output[BUFSIZ], input2[BUFSIZ];
916 int retv, k, fail = 0;
917 uint32 rk[4 * (AES_MAXROUNDS + 1)];
919 #ifdef BCMAES_GENTABLE
920 uint32 Te0test[256], Te1test[256], Te2test[256], Te3test[256], Te4test[256];
921 uint32 Td0test[256], Td1test[256], Td2test[256], Td3test[256], Td4test[256];
923 aes_tables_t at = {
924 Te0test, Te1test, Te2test, Te3test, Te4test,
925 Td0test, Td1test, Td2test, Td3test, Td4test
927 #endif /* BCMAES_GENTABLE */
929 /* AES-CBC */
930 dbg(("%s: AES-CBC\n", *argv));
931 for (k = 0; k < NUM_CBC_VECTORS; k++) {
932 rijndaelKeySetupEnc(rk, aes_cbc_vec[k].key,
933 AES_KEY_BITLEN(aes_cbc_vec[k].kl));
934 retv = aes_cbc_encrypt(rk, aes_cbc_vec[k].kl,
935 aes_cbc_vec[k].nonce, aes_cbc_vec[k].il,
936 aes_cbc_vec[k].input, output);
937 pres("AES CBC Encrypt: ", aes_cbc_vec[k].il, output);
939 if (retv == -1) {
940 dbg(("%s: aes_cbc_encrypt failed\n", *argv));
941 fail++;
943 if (memcmp(output, aes_cbc_vec[k].ref, aes_cbc_vec[k].il) != 0) {
944 dbg(("%s: aes_cbc_encrypt failed\n", *argv));
945 fail++;
948 rijndaelKeySetupDec(rk, aes_cbc_vec[k].key,
949 AES_KEY_BITLEN(aes_cbc_vec[k].kl));
950 retv = aes_cbc_decrypt(rk, aes_cbc_vec[k].kl,
951 aes_cbc_vec[k].nonce, aes_cbc_vec[k].il,
952 aes_cbc_vec[k].ref, input2);
953 pres("AES CBC Decrypt: ", aes_cbc_vec[k].il, input2);
955 if (retv == -1) {
956 dbg(("%s: aes_cbc_decrypt failed\n", *argv));
957 fail++;
959 if (memcmp(aes_cbc_vec[k].input, input2, aes_cbc_vec[k].il) != 0) {
960 dbg(("%s: aes_cbc_decrypt failed\n", *argv));
961 fail++;
965 /* AES-CTR, full blocks */
966 dbg(("%s: AES-CTR, full blocks\n", *argv));
967 for (k = 0; k < NUM_CTR_VECTORS; k++) {
968 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
969 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
970 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
971 aes_ctr_vec[k].nonce, aes_ctr_vec[k].il,
972 aes_ctr_vec[k].input, output);
973 pres("AES CTR Encrypt: ", aes_ctr_vec[k].il, output);
975 if (retv) {
976 dbg(("%s: aes_ctr_crypt failed\n", *argv));
977 fail++;
979 if (memcmp(output, aes_ctr_vec[k].ref, aes_ctr_vec[k].il) != 0) {
980 dbg(("%s: aes_ctr_crypt encrypt failed\n", *argv));
981 fail++;
984 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
985 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
986 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
987 aes_ctr_vec[k].nonce, aes_ctr_vec[k].il,
988 aes_ctr_vec[k].ref, input2);
989 pres("AES CTR Decrypt: ", aes_ctr_vec[k].il, input2);
991 if (retv) {
992 dbg(("%s: aes_ctr_crypt failed\n", *argv));
993 fail++;
995 if (memcmp(aes_ctr_vec[k].input, input2, aes_ctr_vec[k].il) != 0) {
996 dbg(("%s: aes_ctr_crypt decrypt failed\n", *argv));
997 fail++;
1001 /* AES-CTR, one partial block */
1002 dbg(("%s: AES-CTR, one partial block\n", *argv));
1003 for (k = 0; k < NUM_CTR_VECTORS; k++) {
1004 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
1005 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
1006 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
1007 aes_ctr_vec[k].nonce, k+1,
1008 aes_ctr_vec[k].input, output);
1009 pres("AES CTR Partial Block Encrypt: ", k+1, output);
1011 if (retv) {
1012 dbg(("%s: aes_ctr_crypt failed\n", *argv));
1013 fail++;
1015 if (memcmp(output, aes_ctr_vec[k].ref, k + 1) != 0) {
1016 dbg(("%s: aes_ctr_crypt encrypt failed\n", *argv));
1017 fail++;
1020 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
1021 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
1022 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
1023 aes_ctr_vec[k].nonce, k + 1,
1024 aes_ctr_vec[k].ref, input2);
1025 pres("AES CTR Partial Block Decrypt: ", k + 1, input2);
1027 if (retv) {
1028 dbg(("%s: aes_ctr_crypt failed\n", *argv));
1029 fail++;
1031 if (memcmp(aes_ctr_vec[k].input, input2, k + 1) != 0) {
1032 dbg(("%s: aes_ctr_crypt decrypt failed\n", *argv));
1033 fail++;
1037 /* AES-CTR, multi-block partial */
1038 dbg(("%s: AES-CTR, multi-block partial\n", *argv));
1039 for (k = 0; k < NUM_CTR_VECTORS; k++) {
1040 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
1041 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
1042 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
1043 aes_ctr_vec[k].nonce, AES_BLOCK_SZ + NUM_CTR_VECTORS+k+1,
1044 aes_ctr_vec[k].input, output);
1045 pres("AES CTR Partial Multi-Block Encrypt: ",
1046 AES_BLOCK_SZ + NUM_CTR_VECTORS + k + 1, output);
1048 if (retv) {
1049 dbg(("%s: aes_ctr_crypt failed\n", *argv));
1050 fail++;
1052 if (memcmp(output, aes_ctr_vec[k].ref, AES_BLOCK_SZ+NUM_CTR_VECTORS + k + 1) != 0) {
1053 dbg(("%s: aes_ctr_crypt encrypt failed\n", *argv));
1054 fail++;
1057 rijndaelKeySetupEnc(rk, aes_ctr_vec[k].key,
1058 AES_KEY_BITLEN(aes_ctr_vec[k].kl));
1059 retv = aes_ctr_crypt(rk, aes_ctr_vec[k].kl,
1060 aes_ctr_vec[k].nonce, AES_BLOCK_SZ + NUM_CTR_VECTORS + k + 1,
1061 aes_ctr_vec[k].ref, input2);
1062 pres("AES CTR Partial Multi-Block Decrypt: ",
1063 AES_BLOCK_SZ + NUM_CTR_VECTORS + k + 1, input2);
1065 if (retv) {
1066 dbg(("%s: aes_ctr_crypt failed\n", *argv));
1067 fail++;
1069 if (memcmp(aes_ctr_vec[k].input, input2,
1070 AES_BLOCK_SZ + NUM_CTR_VECTORS + k + 1) != 0) {
1071 dbg(("%s: aes_ctr_crypt decrypt failed\n", *argv));
1072 fail++;
1076 /* AES-CCM */
1077 dbg(("%s: AES-CCM\n", *argv));
1078 for (k = 0; k < NUM_CCM_VECTORS; k++) {
1079 rijndaelKeySetupEnc(rk, aes_ccm_vec[k].key,
1080 AES_KEY_BITLEN(aes_ccm_vec[k].kl));
1081 retv = aes_ccm_mac(rk, aes_ccm_vec[k].kl,
1082 aes_ccm_vec[k].nonce, aes_ccm_vec[k].al,
1083 aes_ccm_vec[k].aad, aes_ccm_vec[k].il,
1084 aes_ccm_vec[k].input, output);
1086 if (retv) {
1087 dbg(("%s: aes_ccm_mac failed\n", *argv));
1088 fail++;
1090 if (memcmp(output, aes_ccm_vec[k].mac, AES_CCM_AUTH_LEN) != 0) {
1091 dbg(("%s: aes_ccm_mac failed\n", *argv));
1092 fail++;
1095 rijndaelKeySetupEnc(rk, aes_ccm_vec[k].key,
1096 AES_KEY_BITLEN(aes_ccm_vec[k].kl));
1097 retv = aes_ccm_encrypt(rk, aes_ccm_vec[k].kl,
1098 aes_ccm_vec[k].nonce, aes_ccm_vec[k].al,
1099 aes_ccm_vec[k].aad, aes_ccm_vec[k].il,
1100 aes_ccm_vec[k].input, output, &output[aes_ccm_vec[k].il]);
1101 pres("AES CCM Encrypt: ", aes_ccm_vec[k].il + AES_CCM_AUTH_LEN, output);
1103 if (retv) {
1104 dbg(("%s: aes_ccm_encrypt failed\n", *argv));
1105 fail++;
1107 if (memcmp(output, aes_ccm_vec[k].ref, aes_ccm_vec[k].il + AES_CCM_AUTH_LEN) != 0) {
1108 dbg(("%s: aes_ccm_encrypt failed\n", *argv));
1109 fail++;
1112 rijndaelKeySetupEnc(rk, aes_ccm_vec[k].key,
1113 AES_KEY_BITLEN(aes_ccm_vec[k].kl));
1114 retv = aes_ccm_decrypt(rk, aes_ccm_vec[k].kl,
1115 aes_ccm_vec[k].nonce, aes_ccm_vec[k].al,
1116 aes_ccm_vec[k].aad, aes_ccm_vec[k].il + AES_CCM_AUTH_LEN,
1117 aes_ccm_vec[k].ref, input2);
1118 pres("AES CCM Decrypt: ", aes_ccm_vec[k].il + AES_CCM_AUTH_LEN, input2);
1120 if (retv) {
1121 dbg(("%s: aes_ccm_decrypt failed\n", *argv));
1122 fail++;
1124 if (memcmp(aes_ccm_vec[k].input, input2, aes_ccm_vec[k].il) != 0) {
1125 dbg(("%s: aes_ccm_decrypt failed\n", *argv));
1126 fail++;
1130 /* AES-CCMP */
1131 dbg(("%s: AES-CCMP\n", *argv));
1132 for (k = 0; k < NUM_CCMP_VECTORS; k++) {
1133 uint8 nonce_1st_byte;
1134 dbg(("%s: AES-CCMP vector %d\n", *argv, k));
1135 rijndaelKeySetupEnc(rk, aes_ccmp_vec[k].key,
1136 AES_KEY_BITLEN(aes_ccmp_vec[k].kl));
1137 memcpy(output, aes_ccmp_vec[k].input, aes_ccmp_vec[k].il);
1138 nonce_1st_byte = get_nonce_1st_byte((struct dot11_header *)output);
1139 retv = aes_ccmp_encrypt(rk, aes_ccmp_vec[k].kl,
1140 aes_ccmp_vec[k].il, output,
1141 aes_ccmp_vec[k].flags[2],
1142 nonce_1st_byte);
1144 if (retv) {
1145 dbg(("%s: aes_ccmp_encrypt of vector %d returned error\n", *argv, k));
1146 fail++;
1148 if (memcmp(output, aes_ccmp_vec[k].ref,
1149 aes_ccmp_vec[k].il+AES_CCM_AUTH_LEN) != 0) {
1150 dbg(("%s: aes_ccmp_encrypt of vector %d reference mismatch\n", *argv, k));
1151 fail++;
1154 rijndaelKeySetupEnc(rk, aes_ccmp_vec[k].key,
1155 AES_KEY_BITLEN(aes_ccmp_vec[k].kl));
1156 memcpy(output, aes_ccmp_vec[k].ref, aes_ccmp_vec[k].il+AES_CCM_AUTH_LEN);
1157 nonce_1st_byte = get_nonce_1st_byte((struct dot11_header *)output);
1158 retv = aes_ccmp_decrypt(rk, aes_ccmp_vec[k].kl,
1159 aes_ccmp_vec[k].il+AES_CCM_AUTH_LEN, output,
1160 aes_ccmp_vec[k].flags[2],
1161 nonce_1st_byte);
1163 if (retv) {
1164 dbg(("%s: aes_ccmp_decrypt of vector %d returned error %d\n",
1165 *argv, k, retv));
1166 fail++;
1168 if (memcmp(output, aes_ccmp_vec[k].input, aes_ccmp_vec[k].il) != 0) {
1169 dbg(("%s: aes_ccmp_decrypt of vector %d reference mismatch\n", *argv, k));
1170 fail++;
1175 #ifdef BCMAES_GENTABLE
1176 aes_gen_tables(AES_Sbox, AES_Inverse_Sbox, at);
1177 ptable("Te0", Te0test);
1178 ptable("Te1", Te1test);
1179 ptable("Te2", Te2test);
1180 ptable("Te3", Te3test);
1181 ptable("Te4", Te4test);
1183 ptable("Td0", Td0test);
1184 ptable("Td1", Td1test);
1185 ptable("Td2", Td2test);
1186 ptable("Td3", Td3test);
1187 ptable("Td4", Td4test);
1188 #endif /* BCMAES_GENTABLE */
1190 fprintf(stderr, "%s: %s\n", *argv, fail ? "FAILED" : "PASSED");
1191 return (fail);
1194 #endif /* BCMAES_TEST */