UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
test_aes.c
Go to the documentation of this file.
1/*
2 * FILE: test_aes.c
3 * AUTHORS: Colin Perkins
4 *
5 * Test vector for AES
6 *
7 * Copyright (c) 2004 University of Glasgow
8 * Copyright (c) 2003-2004 University of Southern California
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, is permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * Derived from "rijndaeltest-ref.c v2.0 August '99" by Paulo Barreto
35 * and Vincent Rijmen (public domain reference implementation of Rijndael).
36 *
37 */
38
39#define __USE_MINGW_ANSI_STDIO 1
40
41#include "config.h"
42#include "config_unix.h"
43#include "config_win32.h"
44#include "debug.h"
45#include "memory.h"
46
47#include "crypto/crypt_aes.h"
48#include "test_aes.h"
49
50#define SUBMITTER "Joan Daemen"
51
52static void blockPrint(FILE * fp, const BYTE * block, const char *tag)
53{
54 int i;
55 fprintf(fp, "%s=", tag);
56 for (i = 0; i < 16; i++) {
57 fprintf(fp, "%02X", block[i]);
58 }
59 fprintf(fp, "\n");
60 fflush(fp);
61} /* blockPrint */
62
63static void rijndaelVKKAT(FILE * fp, int keyLength)
64{
65 int i, j, r;
66 BYTE block[4 * 4];
67 BYTE keyMaterial[320];
68 BYTE byteVal = (BYTE) '8';
69 keyInstance keyInst;
70 cipherInstance cipherInst;
71
72#ifdef TRACE_KAT_MCT
73 printf("Executing Variable-Key KAT (key %d): ", keyLength);
74 fflush(stdout);
75#endif /* ?TRACE_KAT_MCT */
76 fprintf(fp, "\n" "==========\n" "\n" "KEYSIZE=%d\n" "\n", keyLength);
77 fflush(fp);
78 memset(block, 0, 16);
79 blockPrint(fp, block, "PT");
80 memset(keyMaterial, 0, sizeof(keyMaterial));
81 memset(keyMaterial, '0', keyLength / 4);
82 for (i = 0; i < keyLength; i++) {
83 keyMaterial[i / 4] = byteVal; /* set only the i-th bit of the i-th test key */
84 r = makeKey(&keyInst, DIR_ENCRYPT, keyLength, (char *) keyMaterial);
85 if (TRUE != r) {
86 fprintf(stderr, "makeKey error %d\n", r);
87 exit(-1);
88 }
89 fprintf(fp, "\nI=%d\n", i + 1);
90 fprintf(fp, "KEY=%s\n", keyMaterial);
91 memset(block, 0, 16);
92 r = cipherInit(&cipherInst, MODE_ECB, NULL);
93 if (TRUE != r) {
94 fprintf(stderr, "cipherInit error %d\n", r);
95 exit(-1);
96 }
97 r = blockEncrypt(&cipherInst, &keyInst, block, 128, block);
98 if (128 != r) {
99 fprintf(stderr, "blockEncrypt error %d\n", r);
100 exit(-1);
101 }
102 blockPrint(fp, block, "CT");
103 /* now check decryption: */
104 makeKey(&keyInst, DIR_DECRYPT, keyLength, (char *) keyMaterial);
105 blockDecrypt(&cipherInst, &keyInst, block, 128, block);
106 for (j = 0; j < 16; j++) {
107 assert(block[j] == 0);
108 }
109 /* undo changes for the next iteration: */
110 keyMaterial[i / 4] = (BYTE) '0';
111 byteVal =
112 (byteVal == '8') ? '4' :
113 (byteVal == '4') ? '2' : (byteVal == '2') ? '1' :
114 /* (byteVal == '1') */ '8';
115 }
116 assert(byteVal == (BYTE) '8');
117
118#ifdef TRACE_KAT_MCT
119 printf(" done.\n");
120#endif /* ?TRACE_KAT_MCT */
121} /* rijndaelVKKAT */
122
123static void rijndaelVTKAT(FILE * fp, int keyLength)
124{
125 int i;
126 BYTE block[4 * 4];
127 BYTE keyMaterial[320];
128 keyInstance keyInst;
129 cipherInstance cipherInst;
130
131#ifdef TRACE_KAT_MCT
132 printf("Executing Variable-Text KAT (key %d): ", keyLength);
133 fflush(stdout);
134#endif /* ?TRACE_KAT_MCT */
135 fprintf(fp, "\n" "==========\n" "\n" "KEYSIZE=%d\n" "\n", keyLength);
136 fflush(fp);
137 memset(keyMaterial, 0, sizeof(keyMaterial));
138 memset(keyMaterial, '0', keyLength / 4);
139 makeKey(&keyInst, DIR_ENCRYPT, keyLength, (char *) keyMaterial);
140 fprintf(fp, "KEY=%s\n", keyMaterial);
141 for (i = 0; i < 128; i++) {
142 memset(block, 0, 16);
143 block[i / 8] |= 1 << (7 - i % 8); /* set only the i-th bit of the i-th test block */
144 fprintf(fp, "\nI=%d\n", i + 1);
145 blockPrint(fp, block, "PT");
146 cipherInit(&cipherInst, MODE_ECB, NULL);
147 blockEncrypt(&cipherInst, &keyInst, block, 128, block);
148 blockPrint(fp, block, "CT");
149 }
150#ifdef TRACE_KAT_MCT
151 printf(" done.\n");
152#endif /* ?TRACE_KAT_MCT */
153}
154
155#ifdef __GNUC__
156#pragma GCC diagnostic ignored "-Wunused-result"
157#endif
158static void rijndaelTKAT(FILE * fp, int keyLength, FILE * in)
159{
160 int i, j;
161 unsigned int s;
162 BYTE block[4 * 4], block2[4 * 4];
163 BYTE keyMaterial[320];
164 keyInstance keyInst;
165 cipherInstance cipherInst;
166
167#ifdef TRACE_KAT_MCT
168 printf("Executing Tables KAT (key %d): ", keyLength);
169 fflush(stdout);
170#endif /* ?TRACE_KAT_MCT */
171 fprintf(fp, "\n" "==========\n" "\n" "KEYSIZE=%d\n" "\n", keyLength);
172 fflush(fp);
173
174 memset(keyMaterial, 0, sizeof(keyMaterial));
175
176 for (i = 0; i < 64; i++) {
177 fprintf(fp, "\nI=%d\n", i + 1);
178 for (j = 0; j < keyLength / 4; j++) {
179 fscanf(in, "%c", &keyMaterial[j]);
180 }
181 makeKey(&keyInst, DIR_ENCRYPT, keyLength, (char *) keyMaterial);
182
183 fprintf(fp, "KEY=%s\n", keyMaterial);
184
185 for (j = 0; j < 16; j++) {
186 fscanf(in, "%02x", &s);
187 block[j] = s;
188 }
189 fscanf(in, "%c", (char *)&s);
190 fscanf(in, "%c", (char *)&s);
191 blockPrint(fp, block, "PT");
192 cipherInit(&cipherInst, MODE_ECB, NULL);
193 blockEncrypt(&cipherInst, &keyInst, block, 128, block2);
194 blockPrint(fp, block2, "CT");
195 }
196 for (i = 64; i < 128; i++) {
197 fprintf(fp, "\nI=%d\n", i + 1);
198 for (j = 0; j < keyLength / 4; j++) {
199 fscanf(in, "%c", &keyMaterial[j]);
200 }
201 makeKey(&keyInst, DIR_DECRYPT, keyLength, (char *) keyMaterial);
202
203 fprintf(fp, "KEY=%s\n", keyMaterial);
204
205 for (j = 0; j < 16; j++) {
206 fscanf(in, "%02x", &s);
207 block[j] = s;
208 }
209 fscanf(in, "%c", (char *)&s);
210 fscanf(in, "%c", (char *)&s);
211 cipherInit(&cipherInst, MODE_ECB, NULL);
212 blockDecrypt(&cipherInst, &keyInst, block, 128, block2);
213 blockPrint(fp, block2, "PT");
214 blockPrint(fp, block, "CT");
215 }
216
217#ifdef TRACE_KAT_MCT
218 printf(" done.\n");
219#endif /* ?TRACE_KAT_MCT */
220}
221
222static void rijndaelIVKAT(FILE * fp, int keyLength)
223{
224 int i;
225 BYTE pt[4 * 4], ct[4 * 4];
226 BYTE keyMaterial[320];
227 keyInstance keyInst;
228 cipherInstance cipherInst;
229 char format[10];
230#ifdef TRACE_KAT_MCT
231 printf("Executing Intermediate value KAT (key %d): ", keyLength);
232 fflush(stdout);
233#endif /* ?TRACE_KAT_MCT */
234
235 fprintf(fp, "\n" "==========\n" "\n" "KEYSIZE=%d\n", keyLength);
236 fflush(fp);
237 memset(keyMaterial, 0, sizeof(keyMaterial));
238 for (i = 0; i < keyLength / 8; i++) {
239 sprintf((char *) &keyMaterial[2 * i], "%02X", i);
240 }
241 fprintf(fp, "KEY=%s\n", keyMaterial);
242
243 for (i = 0; i < 16; i++) {
244 pt[i] = i;
245 }
246
247 fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
248 makeKey(&keyInst, DIR_ENCRYPT, keyLength, (char *) keyMaterial);
249 blockPrint(fp, pt, "PT");
250 cipherInit(&cipherInst, MODE_ECB, NULL);
251 for (i = 1; i < keyInst.Nr; i++) {
252 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i);
253 assert(i <= 99999);
254 sprintf(format, "CT%d", i);
255 blockPrint(fp, ct, format);
256 }
257 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr);
258 blockPrint(fp, ct, "CT");
259
260 fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
261 makeKey(&keyInst, DIR_DECRYPT, keyLength, (char *) keyMaterial);
262 blockPrint(fp, ct, "CT");
263 cipherInit(&cipherInst, MODE_ECB, NULL);
264 for (i = 1; i < keyInst.Nr; i++) {
265 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i);
266 assert(i <= 99999);
267 sprintf(format, "PT%d", i);
268 blockPrint(fp, pt, format);
269 }
270 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr);
271 blockPrint(fp, pt, "PT");
272
273#ifdef TRACE_KAT_MCT
274 printf(" done.\n");
275#endif
276}
277
278static void makeKATs(const char *vkFile, const char *vtFile,
279 const char *tblFile, const char *ivFile)
280{
281 FILE *fp, *fp2;
282
283 /* prepare Variable Key Known Answer Tests: */
284 fp = fopen(vkFile, "w");
285 fprintf(fp,
286 "\n"
287 "=========================\n"
288 "\n"
289 "FILENAME: \"%s\"\n"
290 "\n"
291 "Electronic Codebook (ECB) Mode\n"
292 "Variable Key Known Answer Tests\n"
293 "\n"
294 "Algorithm Name: Rijndael\n"
295 "Principal Submitter: %s\n", vkFile, SUBMITTER);
296 fflush(fp);
297
298 rijndaelVKKAT(fp, 128);
299 rijndaelVKKAT(fp, 192);
300 rijndaelVKKAT(fp, 256);
301
302 fprintf(fp, "\n" "==========");
303 fclose(fp);
304
305 /* prepare Variable Text Known Answer Tests: */
306 fp = fopen(vtFile, "w");
307 fprintf(fp,
308 "\n"
309 "=========================\n"
310 "\n"
311 "FILENAME: \"%s\"\n"
312 "\n"
313 "Electronic Codebook (ECB) Mode\n"
314 "Variable Text Known Answer Tests\n"
315 "\n"
316 "Algorithm Name: Rijndael\n"
317 "Principal Submitter: %s\n", vtFile, SUBMITTER);
318 fflush(fp);
319
320 rijndaelVTKAT(fp, 128);
321 rijndaelVTKAT(fp, 192);
322 rijndaelVTKAT(fp, 256);
323
324 fprintf(fp, "\n" "==========");
325 fclose(fp);
326
327 /* prepare Tables Known Answer Tests: */
328 fp = fopen(tblFile, "w");
329 fprintf(fp,
330 "/* Description of what tables are tested:\n"
331 " The provided implementations each use a different set of tables\n"
332 " - Java implementation: uses no tables\n"
333 " - reference C implementation: uses Logtable, Alogtable, S, Si, rcon\n"
334 " - fast C implementation: uses Logtable, Alogtable, rcon\n"
335 " and additionally, T1, T2, T3, T4, T5, T6, T7, T8\n"
336 " and (for the inverse key schedule only) U1, U2, U3, U4.\n"
337 " All these tables are tested.\n"
338 "\n"
339 "=========================\n"
340 "\n"
341 "FILENAME: \"%s\"\n"
342 "\n"
343 "Electronic Codebook (ECB) Mode\n"
344 "Tables Known Answer Tests\n"
345 "\n"
346 "Algorithm Name: Rijndael\n"
347 "Principal Submitter: %s\n", tblFile, SUBMITTER);
348 fflush(fp);
349
350 if (NULL != (fp2 = fopen("test/test_aes.table.128", "r"))) {
351 rijndaelTKAT(fp, 128, fp2);
352 fclose(fp2);
353 } else {
354 printf
355 ("Table Known Answer test expects file test/test_aes.table.128\n");
356 fclose(fp);
357 exit(EXIT_FAILURE);
358 }
359 if (NULL != (fp2 = fopen("test/test_aes.table.192", "r"))) {
360 rijndaelTKAT(fp, 192, fp2);
361 fclose(fp2);
362 } else {
363 printf
364 ("Table Known Answer test expects file test/test_aes.table.192\n");
365 fclose(fp);
366 exit(EXIT_FAILURE);
367 }
368 if (NULL != (fp2 = fopen("test/test_aes.table.256", "r"))) {
369 rijndaelTKAT(fp, 256, fp2);
370 fclose(fp2);
371 } else {
372 printf
373 ("Table Known Answer test expects file test/test_aes.table.192\n");
374 fclose(fp);
375 exit(EXIT_FAILURE);
376 }
377
378 fprintf(fp, "\n" "==========");
379 fclose(fp);
380
381 /* prepare Intermediate Values Known Answer Tests: */
382 fp = fopen(ivFile, "w");
383 fprintf(fp,
384 "\n"
385 "=========================\n"
386 "\n"
387 "FILENAME: \"%s\"\n"
388 "\n"
389 "Electronic Codebook (ECB) Mode\n"
390 "Intermediate Value Known Answer Tests\n"
391 "\n"
392 "Algorithm Name: Rijndael\n"
393 "Principal Submitter: %s\n", ivFile, SUBMITTER);
394 fflush(fp);
395
396 rijndaelIVKAT(fp, 128);
397 rijndaelIVKAT(fp, 192);
398 rijndaelIVKAT(fp, 256);
399
400 fprintf(fp, "\n" "==========");
401 fclose(fp);
402}
403
404static void rijndaelECB_MCT(FILE * fp, int keyLength, BYTE direction)
405{
406 int i, j;
407 BYTE inBlock[4 * 4], outBlock[4 * 4], binKey[4 * MAXKC];
408 BYTE keyMaterial[320];
409 keyInstance keyInst;
410 cipherInstance cipherInst;
411
412 printf(".");
413 fflush(stdout);
414#ifdef TRACE_KAT_MCT
415 int width = 0;
416 clock_t elapsed = -clock();
417 printf("Executing ECB MCT (%s, key %d): ",
418 direction == DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT", keyLength);
419 fflush(stdout);
420#endif /* ?TRACE_KAT_MCT */
421 fprintf(fp,
422 "\n"
423 "=========================\n" "\n" "KEYSIZE=%d\n", keyLength);
424 fflush(fp);
425 memset(outBlock, 0, 16);
426 memset(binKey, 0, keyLength / 8);
427 for (i = 0; i < 400; i++) {
428#ifdef TRACE_KAT_MCT
429 while (width-- > 0) {
430 putchar('\b');
431 }
432 width = printf("%d", i);
433 fflush(stdout);
434#endif /* ?TRACE_KAT_MCT */
435 fprintf(fp, "\nI=%d\n", i);
436 /* prepare key: */
437 for (j = 0; j < keyLength / 8; j++) {
438 sprintf((char *) &keyMaterial[2 * j], "%02X", binKey[j]);
439 }
440 keyMaterial[keyLength / 4] = 0;
441 fprintf(fp, "KEY=%s\n", keyMaterial);
442 makeKey(&keyInst, direction, keyLength, (char *) keyMaterial);
443 /* do encryption/decryption: */
444 blockPrint(fp, outBlock,
445 direction == DIR_ENCRYPT ? "PT" : "CT");
446 cipherInit(&cipherInst, MODE_ECB, NULL);
447 if (direction == DIR_ENCRYPT) {
448 for (j = 0; j < 10000; j++) {
449 memcpy(inBlock, outBlock, 16);
450 blockEncrypt(&cipherInst, &keyInst, inBlock,
451 128, outBlock);
452 }
453 } else {
454 for (j = 0; j < 10000; j++) {
455 memcpy(inBlock, outBlock, 16);
456 blockDecrypt(&cipherInst, &keyInst, inBlock,
457 128, outBlock);
458 }
459 }
460 blockPrint(fp, outBlock,
461 direction == DIR_ENCRYPT ? "CT" : "PT");
462 /* prepare new key: */
463 switch (keyLength) {
464 case 128:
465 for (j = 0; j < 128 / 8; j++) {
466 binKey[j] ^= outBlock[j];
467 }
468 break;
469 case 192:
470 for (j = 0; j < 64 / 8; j++) {
471 binKey[j] ^= inBlock[j + 64 / 8];
472 }
473 for (j = 0; j < 128 / 8; j++) {
474 binKey[j + 64 / 8] ^= outBlock[j];
475 }
476 break;
477 case 256:
478 for (j = 0; j < 128 / 8; j++) {
479 binKey[j] ^= inBlock[j];
480 }
481 for (j = 0; j < 128 / 8; j++) {
482 binKey[j + 128 / 8] ^= outBlock[j];
483 }
484 break;
485 }
486 }
487#ifdef TRACE_KAT_MCT
488 elapsed += clock();
489 while (width-- > 0) {
490 putchar('\b');
491 }
492 printf("%d done (%.1f s).\n", i, (float)elapsed / CLOCKS_PER_SEC);
493#endif /* ?TRACE_KAT_MCT */
494} /* rijndaelECB_MCT */
495
496static void rijndaelCBC_MCT(FILE * fp, int keyLength, BYTE direction)
497{
498 int i, j, r, t;
499 BYTE inBlock[256 / 8], outBlock[256 / 8], binKey[256 / 8], cv[256 / 8];
500 BYTE keyMaterial[320];
501 keyInstance keyInst;
502 cipherInstance cipherInst;
503
504 printf(".");
505 fflush(stdout);
506#ifdef TRACE_KAT_MCT
507 int width = 0;
508 clock_t elapsed = -clock();
509 printf("Executing CBC MCT (%s, key %d): ",
510 direction == DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT", keyLength);
511 fflush(stdout);
512#endif /* ?TRACE_KAT_MCT */
513 fprintf(fp, "\n" "==========\n" "\n" "KEYSIZE=%d\n", keyLength);
514 fflush(fp);
515 memset(cv, 0, 16);
516 memset(inBlock, 0, 16);
517 memset(binKey, 0, keyLength / 8);
518 for (i = 0; i < 400; i++) {
519#ifdef TRACE_KAT_MCT
520 while (width-- > 0) {
521 putchar('\b');
522 }
523 width = printf("%d", i);
524 fflush(stdout);
525#endif /* ?TRACE_KAT_MCT */
526 fprintf(fp, "\nI=%d\n", i);
527 /* prepare key: */
528 for (j = 0; j < keyLength / 8; j++) {
529 sprintf((char *) &keyMaterial[2 * j], "%02X", binKey[j]);
530 }
531 keyMaterial[keyLength / 4] = 0;
532 fprintf(fp, "KEY=%s\n", keyMaterial);
533 r = makeKey(&keyInst, direction, keyLength, (char *) keyMaterial);
534 if (TRUE != r) {
535 fprintf(stderr, "makeKey error %d\n", r);
536 exit(-1);
537 }
538 r = cipherInit(&cipherInst, MODE_ECB, NULL);
539 if (TRUE != r) {
540 fprintf(stderr, "cipherInit error %d\n", r);
541 exit(-1);
542 }
543 /* do encryption/decryption: */
544 blockPrint(fp, cv, "IV");
545 blockPrint(fp, inBlock, direction == DIR_ENCRYPT ? "PT" : "CT");
546 if (direction == DIR_ENCRYPT) {
547 for (j = 0; j < 10000; j++) {
548 for (t = 0; t < 16; t++) {
549 inBlock[t] ^= cv[t];
550 }
551 r = blockEncrypt(&cipherInst, &keyInst, inBlock,
552 128, outBlock);
553 if (128 != r) {
554 fprintf(stderr,
555 "blockEncrypt error %d\n", r);
556 exit(-1);
557 }
558 memcpy(inBlock, cv, 16);
559 memcpy(cv, outBlock, 16);
560 }
561 } else {
562 for (j = 0; j < 10000; j++) {
563 blockDecrypt(&cipherInst, &keyInst, inBlock,
564 128, outBlock);
565 for (t = 0; t < 16; t++) {
566 outBlock[t] ^= cv[t];
567 }
568 memcpy(cv, inBlock, 16);
569 memcpy(inBlock, outBlock, 16);
570 }
571 }
572 blockPrint(fp, outBlock,
573 direction == DIR_ENCRYPT ? "CT" : "PT");
574 /* prepare new key: */
575 switch (keyLength) {
576 case 128:
577 for (j = 0; j < 128 / 8; j++) {
578 binKey[j] ^= outBlock[j];
579 }
580 break;
581 case 192:
582 for (j = 0; j < 64 / 8; j++) {
583 if (direction == DIR_ENCRYPT) {
584 binKey[j] ^= inBlock[j + 64 / 8];
585 } else {
586 binKey[j] ^= cv[j + 64 / 8];
587 }
588 }
589 for (j = 0; j < 128 / 8; j++) {
590 binKey[j + 64 / 8] ^= outBlock[j];
591 }
592 break;
593 case 256:
594 for (j = 0; j < 128 / 8; j++) {
595 if (direction == DIR_ENCRYPT) {
596 binKey[j] ^= inBlock[j];
597 } else {
598 binKey[j] ^= cv[j];
599 }
600 }
601 for (j = 0; j < 128 / 8; j++) {
602 binKey[j + 128 / 8] ^= outBlock[j];
603 }
604 break;
605 }
606 }
607#ifdef TRACE_KAT_MCT
608 elapsed += clock();
609 while (width-- > 0) {
610 putchar('\b');
611 }
612 printf("%d done (%.1f s).\n", i, (float)elapsed / CLOCKS_PER_SEC);
613#endif /* ?TRACE_KAT_MCT */
614} /* rijndaelCBC_MCT */
615
616static void makeMCTs(const char *ecbEncryptionFile,
617 const char *ecbDecryptionFile,
618 const char *cbcEncryptionFile,
619 const char *cbcDecryptionFile)
620{
621 FILE *fp;
622
623 /* prepare ECB Encryption Monte Carlo Tests: */
624 fp = fopen(ecbEncryptionFile, "w");
625 fprintf(fp,
626 "\n"
627 "=========================\n"
628 "\n"
629 "FILENAME: \"%s\"\n"
630 "\n"
631 "Electronic Codebook (ECB) Mode - ENCRYPTION\n"
632 "Monte Carlo Test\n"
633 "\n"
634 "Algorithm Name: Rijndael\n"
635 "Principal Submitter: %s\n", ecbEncryptionFile, SUBMITTER);
636 fflush(fp);
637
641
642 fprintf(fp, "\n" "===========");
643 fclose(fp);
644
645 /* prepare ECB Decryption Monte Carlo Tests: */
646 fp = fopen(ecbDecryptionFile, "w");
647 fprintf(fp,
648 "\n"
649 "=========================\n"
650 "\n"
651 "FILENAME: \"%s\"\n"
652 "\n"
653 "Electronic Codebook (ECB) Mode - DECRYPTION\n"
654 "Monte Carlo Test\n"
655 "\n"
656 "Algorithm Name: Rijndael\n"
657 "Principal Submitter: %s\n", ecbDecryptionFile, SUBMITTER);
658 fflush(fp);
659
663
664 fprintf(fp, "\n" "===========");
665 fclose(fp);
666
667 /* prepare CBC Encryption Monte Carlo Tests: */
668 fp = fopen(cbcEncryptionFile, "w");
669 fprintf(fp,
670 "\n"
671 "=========================\n"
672 "\n"
673 "FILENAME: \"%s\"\n"
674 "\n"
675 "Cipher Block Chaining (CBC) Mode - ENCRYPTION\n"
676 "Monte Carlo Test\n"
677 "\n"
678 "Algorithm Name: Rijndael\n"
679 "Principal Submitter: %s\n", cbcEncryptionFile, SUBMITTER);
680 fflush(fp);
681
685
686 fprintf(fp, "\n" "===========");
687 fclose(fp);
688
689 /* prepare CBC Decryption Monte Carlo Tests: */
690 fp = fopen(cbcDecryptionFile, "w");
691 fprintf(fp,
692 "\n"
693 "=========================\n"
694 "\n"
695 "FILENAME: \"%s\"\n"
696 "\n"
697 "Cipher Block Chaining (CBC) Mode - DECRYPTION\n"
698 "Monte Carlo Test\n"
699 "\n"
700 "Algorithm Name: Rijndael\n"
701 "Principal Submitter: %s\n", cbcDecryptionFile, SUBMITTER);
702 fflush(fp);
703
707
708 fprintf(fp, "\n" "===========");
709 fclose(fp);
710} /* makeMCTs */
711
712static void compare_files(char *nfile_n, char *ofile_n)
713{
714 int cn, co;
715 FILE *nfile = fopen(nfile_n, "r");
716 FILE *ofile = fopen(ofile_n, "r");
717
718 if ((nfile == NULL) || (ofile == NULL)) {
719 printf("FAIL\n");
720 printf(" Unable to open test file for reading!\n");
721 exit(1);
722 }
723
724 while (1) {
725 cn = fgetc(nfile);
726 co = fgetc(ofile);
727 if (feof(nfile)) {
728 if (!feof(ofile)) {
729 printf("FAIL\n");
730 printf(" Short result file!\n");
731 exit(1);
732 }
733 break;
734 }
735 if (cn != co) {
736 printf("FAIL\n");
737 printf(" Test results %s and %s differ!\n", nfile_n,
738 ofile_n);
739 exit(1);
740 }
741 }
742 fclose(nfile);
743 fclose(ofile);
744 if (unlink(nfile_n) != 0) {
745 printf("Ok\n");
746 printf(" Unable to remove %s: ", nfile_n);
747 perror("");
748 exit(1);
749 }
750}
751
752int test_aes(void)
753{
754 printf
755 ("Testing AES (Known answer tests) ......................................... ");
756 fflush(stdout);
757 makeKATs("ecb_vk.txt", "ecb_vt.txt", "ecb_tbl.txt", "ecb_iv.txt");
758 compare_files("ecb_vk.txt", "test/test_aes.results.ecb_vk.txt");
759 compare_files("ecb_vt.txt", "test/test_aes.results.ecb_vt.txt");
760 compare_files("ecb_tbl.txt", "test/test_aes.results.ecb_tbl.txt");
761 compare_files("ecb_iv.txt", "test/test_aes.results.ecb_iv.txt");
762 printf("Ok\n");
763
764 printf
765 ("Testing AES (Monte Carlo tests) ..............................");
766 fflush(stdout);
767 makeMCTs("ecb_e_m.txt", "ecb_d_m.txt", "cbc_e_m.txt", "cbc_d_m.txt");
768 compare_files("ecb_e_m.txt", "test/test_aes.results.ecb_e_m.txt");
769 compare_files("ecb_d_m.txt", "test/test_aes.results.ecb_d_m.txt");
770 compare_files("cbc_e_m.txt", "test/test_aes.results.cbc_e_m.txt");
771 compare_files("cbc_d_m.txt", "test/test_aes.results.cbc_d_m.txt");
772 printf(" Ok\n");
773 return 0;
774}
#define TRUE
int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
Definition crypt_aes.c:145
int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int rounds)
Definition crypt_aes.c:444
int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
Definition crypt_aes.c:287
int makeKey(keyInstance *key, BYTE direction, int keyLen, const char *keyMaterial)
Definition crypt_aes.c:45
int cipherInit(cipherInstance *cipher, BYTE mode, char *IV)
Definition crypt_aes.c:105
#define DIR_DECRYPT
Definition crypt_aes.h:46
#define MODE_ECB
Definition crypt_aes.h:47
unsigned char BYTE
Definition crypt_aes.h:71
#define DIR_ENCRYPT
Definition crypt_aes.h:45
#define MAXKC
static void blockPrint(FILE *fp, const BYTE *block, const char *tag)
Definition test_aes.c:52
static void rijndaelTKAT(FILE *fp, int keyLength, FILE *in)
Definition test_aes.c:158
static void rijndaelVKKAT(FILE *fp, int keyLength)
Definition test_aes.c:63
static void rijndaelCBC_MCT(FILE *fp, int keyLength, BYTE direction)
Definition test_aes.c:496
static void compare_files(char *nfile_n, char *ofile_n)
Definition test_aes.c:712
static void makeKATs(const char *vkFile, const char *vtFile, const char *tblFile, const char *ivFile)
Definition test_aes.c:278
#define SUBMITTER
Definition test_aes.c:50
static void rijndaelECB_MCT(FILE *fp, int keyLength, BYTE direction)
Definition test_aes.c:404
static void rijndaelVTKAT(FILE *fp, int keyLength)
Definition test_aes.c:123
int test_aes(void)
Definition test_aes.c:752
static void rijndaelIVKAT(FILE *fp, int keyLength)
Definition test_aes.c:222
static void makeMCTs(const char *ecbEncryptionFile, const char *ecbDecryptionFile, const char *cbcEncryptionFile, const char *cbcDecryptionFile)
Definition test_aes.c:616