00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef INTERMEDIATE_VALUE_KAT
00028 #error "Must #define INTERMEDIATE_VALUE_KAT to generate the Intermediate Value Known Answer Test."
00029 #endif
00030
00031 #include <assert.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <time.h>
00036
00037 #include "rijndael-api-fst.h"
00038
00039 #define SUBMITTER "Joan Daemen"
00040
00041 static void blockPrint(FILE *fp, const BYTE *block, const char *tag) {
00042 int i;
00043 fprintf (fp, "%s=", tag);
00044 for (i = 0; i < 16; i++) {
00045 fprintf (fp, "%02X", block[i]);
00046 }
00047 fprintf (fp, "\n");
00048 fflush (fp);
00049 }
00050
00051 static void rijndaelVKKAT(FILE *fp, int keyLength) {
00052 int i, j, r;
00053 BYTE block[4*4];
00054 BYTE keyMaterial[320];
00055 BYTE byteVal = (BYTE)'8';
00056 keyInstance keyInst;
00057 cipherInstance cipherInst;
00058
00059 #ifdef TRACE_KAT_MCT
00060 printf("Executing Variable-Key KAT (key %d): ", keyLength);
00061 fflush(stdout);
00062 #endif
00063 fprintf(fp,
00064 "\n"
00065 "==========\n"
00066 "\n"
00067 "KEYSIZE=%d\n"
00068 "\n", keyLength);
00069 fflush(fp);
00070 memset(block, 0, 16);
00071 blockPrint(fp, block, "PT");
00072 memset(keyMaterial, 0, sizeof (keyMaterial));
00073 memset(keyMaterial, '0', keyLength/4);
00074 for (i = 0; i < keyLength; i++) {
00075 keyMaterial[i/4] = byteVal;
00076 r = makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00077 if (TRUE != r) {
00078 fprintf(stderr,"makeKey error %d\n",r);
00079 exit(-1);
00080 }
00081 fprintf(fp, "\nI=%d\n", i+1);
00082 fprintf(fp, "KEY=%s\n", keyMaterial);
00083 memset(block, 0, 16);
00084 r = cipherInit(&cipherInst, MODE_ECB, NULL);
00085 if (TRUE != r) {
00086 fprintf(stderr,"cipherInit error %d\n",r);
00087 exit(-1);
00088 }
00089 r = blockEncrypt(&cipherInst, &keyInst, block, 128, block);
00090 if (128 != r) {
00091 fprintf(stderr,"blockEncrypt error %d\n",r);
00092 exit(-1);
00093 }
00094 blockPrint(fp, block, "CT");
00095
00096 makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00097 blockDecrypt(&cipherInst, &keyInst, block, 128, block);
00098 for (j = 0; j < 16; j++) {
00099 assert(block[j] == 0);
00100 }
00101
00102 keyMaterial[i/4] = (BYTE)'0';
00103 byteVal =
00104 (byteVal == '8') ? '4' :
00105 (byteVal == '4') ? '2' :
00106 (byteVal == '2') ? '1' :
00107 '8';
00108 }
00109 assert(byteVal == (BYTE)'8');
00110
00111 #ifdef TRACE_KAT_MCT
00112 printf(" done.\n");
00113 #endif
00114 }
00115
00116
00117 static void rijndaelVTKAT(FILE *fp, int keyLength) {
00118 int i;
00119 BYTE block[4*4];
00120 BYTE keyMaterial[320];
00121 keyInstance keyInst;
00122 cipherInstance cipherInst;
00123
00124 #ifdef TRACE_KAT_MCT
00125 printf("Executing Variable-Text KAT (key %d): ", keyLength);
00126 fflush(stdout);
00127 #endif
00128 fprintf(fp,
00129 "\n"
00130 "==========\n"
00131 "\n"
00132 "KEYSIZE=%d\n"
00133 "\n", keyLength);
00134 fflush(fp);
00135 memset(keyMaterial, 0, sizeof (keyMaterial));
00136 memset(keyMaterial, '0', keyLength/4);
00137 makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00138 fprintf(fp, "KEY=%s\n", keyMaterial);
00139 for (i = 0; i < 128; i++) {
00140 memset(block, 0, 16);
00141 block[i/8] |= 1 << (7 - i%8);
00142 fprintf (fp, "\nI=%d\n", i+1);
00143 blockPrint(fp, block, "PT");
00144 cipherInit(&cipherInst, MODE_ECB, NULL);
00145 blockEncrypt(&cipherInst, &keyInst, block, 128, block);
00146 blockPrint(fp, block, "CT");
00147 }
00148 #ifdef TRACE_KAT_MCT
00149 printf(" done.\n");
00150 #endif
00151 }
00152
00153
00154 static void rijndaelTKAT(FILE *fp, int keyLength, FILE *in) {
00155 int i, j;
00156 unsigned int s;
00157 BYTE block[4*4], block2[4*4];
00158 BYTE keyMaterial[320];
00159 keyInstance keyInst;
00160 cipherInstance cipherInst;
00161
00162 #ifdef TRACE_KAT_MCT
00163 printf("Executing Tables KAT (key %d): ", keyLength);
00164 fflush(stdout);
00165 #endif
00166 fprintf(fp,
00167 "\n"
00168 "==========\n"
00169 "\n"
00170 "KEYSIZE=%d\n"
00171 "\n", keyLength);
00172 fflush(fp);
00173
00174 memset(keyMaterial, 0, sizeof (keyMaterial));
00175
00176 for (i = 0; i < 64; i++) {
00177 fprintf(fp, "\nI=%d\n", i+1);
00178 for(j = 0; j < keyLength/4; j++) {
00179 fscanf(in, "%c", &keyMaterial[j]);
00180 }
00181 makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00182
00183 fprintf(fp, "KEY=%s\n", keyMaterial);
00184
00185 for (j = 0; j < 16; j++) {
00186 fscanf(in, "%02x", &s);
00187 block[j] = s;
00188 }
00189 fscanf(in, "%c", (char *)&s);
00190 fscanf(in, "%c", (char *)&s);
00191 blockPrint(fp, block, "PT");
00192 cipherInit(&cipherInst, MODE_ECB, NULL);
00193 blockEncrypt(&cipherInst, &keyInst, block, 128, block2);
00194 blockPrint(fp, block2, "CT");
00195 }
00196 for (i = 64; i < 128; i++) {
00197 fprintf(fp, "\nI=%d\n", i+1);
00198 for(j = 0; j < keyLength/4; j++) {
00199 fscanf(in, "%c", &keyMaterial[j]);
00200 }
00201 makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00202
00203 fprintf(fp, "KEY=%s\n", keyMaterial);
00204
00205 for (j = 0; j < 16; j++) {
00206 fscanf(in, "%02x", &s);
00207 block[j] = s;
00208 }
00209 fscanf(in, "%c", (char *)&s);
00210 fscanf(in, "%c", (char *)&s);
00211 cipherInit(&cipherInst, MODE_ECB, NULL);
00212 blockDecrypt(&cipherInst, &keyInst, block, 128, block2);
00213 blockPrint(fp, block2, "PT");
00214 blockPrint(fp, block, "CT");
00215 }
00216
00217 #ifdef TRACE_KAT_MCT
00218 printf(" done.\n");
00219 #endif
00220 }
00221
00222 #ifdef INTERMEDIATE_VALUE_KAT
00223 static void rijndaelIVKAT (FILE *fp, int keyLength) {
00224 int i;
00225 BYTE pt[4*4], ct[4*4];
00226 BYTE keyMaterial[320];
00227 keyInstance keyInst;
00228 cipherInstance cipherInst;
00229 char format[10];
00230 #ifdef TRACE_KAT_MCT
00231 printf ("Executing Intermediate value KAT (key %d): ", keyLength);
00232 fflush (stdout);
00233 #endif
00234
00235 fprintf(fp,
00236 "\n"
00237 "==========\n"
00238 "\n"
00239 "KEYSIZE=%d\n",
00240 keyLength);
00241 fflush(fp);
00242 memset(keyMaterial, 0, sizeof (keyMaterial));
00243 for (i = 0; i < keyLength/8; i++) {
00244 sprintf(&keyMaterial[2*i], "%02X", i);
00245 }
00246 fprintf(fp, "KEY=%s\n", keyMaterial);
00247
00248 for (i = 0; i < 16; i++) {
00249 pt[i] = i;
00250 }
00251
00252 fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
00253 makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00254 blockPrint(fp, pt, "PT");
00255 cipherInit(&cipherInst, MODE_ECB, NULL);
00256 for(i = 1; i < keyInst.Nr; i++) {
00257 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i);
00258 sprintf(format, "CT%d", i);
00259 blockPrint(fp, ct, format);
00260 }
00261 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr);
00262 blockPrint(fp, ct, "CT");
00263
00264 fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
00265 makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00266 blockPrint(fp, ct, "CT");
00267 cipherInit(&cipherInst, MODE_ECB, NULL);
00268 for(i = 1; i < keyInst.Nr; i++) {
00269 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i);
00270 sprintf(format, "PT%d", i);
00271 blockPrint(fp, pt, format);
00272 }
00273 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr);
00274 blockPrint(fp, pt, "PT");
00275
00276 #ifdef TRACE_KAT_MCT
00277 printf(" done.\n");
00278 #endif
00279 }
00280 #endif
00281
00282 static void makeKATs(const char *vkFile, const char *vtFile, const char *tblFile, const char *ivFile) {
00283 FILE *fp, *fp2;
00284
00285
00286 fp = fopen(vkFile, "w");
00287 fprintf(fp,
00288 "\n"
00289 "=========================\n"
00290 "\n"
00291 "FILENAME: \"%s\"\n"
00292 "\n"
00293 "Electronic Codebook (ECB) Mode\n"
00294 "Variable Key Known Answer Tests\n"
00295 "\n"
00296 "Algorithm Name: Rijndael\n"
00297 "Principal Submitter: %s\n",
00298 vkFile, SUBMITTER);
00299 fflush(fp);
00300
00301 rijndaelVKKAT(fp, 128);
00302 rijndaelVKKAT(fp, 192);
00303 rijndaelVKKAT(fp, 256);
00304
00305 fprintf(fp,
00306 "\n"
00307 "==========");
00308 fclose(fp);
00309
00310
00311 fp = fopen(vtFile, "w");
00312 fprintf(fp,
00313 "\n"
00314 "=========================\n"
00315 "\n"
00316 "FILENAME: \"%s\"\n"
00317 "\n"
00318 "Electronic Codebook (ECB) Mode\n"
00319 "Variable Text Known Answer Tests\n"
00320 "\n"
00321 "Algorithm Name: Rijndael\n"
00322 "Principal Submitter: %s\n",
00323 vtFile, SUBMITTER);
00324 fflush(fp);
00325
00326 rijndaelVTKAT(fp, 128);
00327 rijndaelVTKAT(fp, 192);
00328 rijndaelVTKAT(fp, 256);
00329
00330 fprintf(fp,
00331 "\n"
00332 "==========");
00333 fclose(fp);
00334
00335
00336 fp = fopen(tblFile, "w");
00337 fprintf(fp,
00338 "/* Description of what tables are tested:\n"
00339 " The provided implementations each use a different set of tables\n"
00340 " - Java implementation: uses no tables\n"
00341 " - reference C implementation: uses Logtable, Alogtable, S, Si, rcon\n"
00342 " - fast C implementation: uses rcon and additionally\n"
00343 " Te0, Te1, Te2, Te3, Te4, Td0, Td1, Td2, Td3, Td4.\n"
00344 " All these tables are tested.\n"
00345 "\n"
00346 "=========================\n"
00347 "\n"
00348 "FILENAME: \"%s\"\n"
00349 "\n"
00350 "Electronic Codebook (ECB) Mode\n"
00351 "Tables Known Answer Tests\n"
00352 "\n"
00353 "Algorithm Name: Rijndael\n"
00354 "Principal Submitter: %s\n",
00355 tblFile, SUBMITTER);
00356 fflush(fp);
00357
00358 if (NULL != (fp2 = fopen("table.128", "r"))) {
00359 rijndaelTKAT(fp, 128, fp2);
00360 fclose(fp2);
00361 } else {
00362 printf("Table Known Answer test expects file table.128\n");
00363 fclose(fp);
00364 exit(EXIT_FAILURE);
00365 }
00366 if (NULL != (fp2 = fopen("table.192", "r"))) {
00367 rijndaelTKAT(fp, 192, fp2);
00368 fclose(fp2);
00369 } else {
00370 printf("Table Known Answer test expects file table.192\n");
00371 fclose(fp);
00372 exit(EXIT_FAILURE);
00373 }
00374 if (NULL != (fp2 = fopen("table.256", "r"))) {
00375 rijndaelTKAT(fp, 256, fp2);
00376 fclose(fp2);
00377 } else {
00378 printf("Table Known Answer test expects file table.192\n");
00379 fclose(fp);
00380 exit(EXIT_FAILURE);
00381 }
00382
00383 fprintf(fp,
00384 "\n"
00385 "==========");
00386 fclose(fp);
00387
00388 #ifdef INTERMEDIATE_VALUE_KAT
00389
00390 fp = fopen(ivFile, "w");
00391 fprintf(fp,
00392 "\n"
00393 "=========================\n"
00394 "\n"
00395 "FILENAME: \"%s\"\n"
00396 "\n"
00397 "Electronic Codebook (ECB) Mode\n"
00398 "Intermediate Value Known Answer Tests\n"
00399 "\n"
00400 "Algorithm Name: Rijndael\n"
00401 "Principal Submitter: %s\n",
00402 ivFile, SUBMITTER);
00403 fflush(fp);
00404
00405 rijndaelIVKAT(fp, 128);
00406 rijndaelIVKAT(fp, 192);
00407 rijndaelIVKAT(fp, 256);
00408
00409 fprintf(fp,
00410 "\n"
00411 "==========");
00412 fclose(fp);
00413 #endif
00414 }
00415
00416 static void rijndaelECB_MCT(FILE *fp, int keyLength, BYTE direction) {
00417 int i, j;
00418 BYTE inBlock[4*4], outBlock[4*4], binKey[4*MAXKC];
00419 BYTE keyMaterial[320];
00420 keyInstance keyInst;
00421 cipherInstance cipherInst;
00422
00423 #ifdef TRACE_KAT_MCT
00424 int width = 0;
00425 clock_t elapsed = -clock();
00426 printf("Executing ECB MCT (%s, key %d): ",
00427 direction == DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT", keyLength);
00428 fflush(stdout);
00429 #endif
00430 fprintf(fp,
00431 "\n"
00432 "=========================\n"
00433 "\n"
00434 "KEYSIZE=%d\n", keyLength);
00435 fflush(fp);
00436 memset(outBlock, 0, 16);
00437 memset(binKey, 0, keyLength/8);
00438 for (i = 0; i < 400; i++) {
00439 #ifdef TRACE_KAT_MCT
00440 while (width-- > 0) {
00441 putchar('\b');
00442 }
00443 width = printf("%d", i);
00444 fflush(stdout);
00445 #endif
00446 fprintf(fp, "\nI=%d\n", i);
00447
00448 for (j = 0; j < keyLength/8; j++) {
00449 sprintf(&keyMaterial[2*j], "%02X", binKey[j]);
00450 }
00451 keyMaterial[keyLength/4] = 0;
00452 fprintf(fp, "KEY=%s\n", keyMaterial);
00453 makeKey(&keyInst, direction, keyLength, keyMaterial);
00454
00455 blockPrint(fp, outBlock, direction == DIR_ENCRYPT ? "PT" : "CT");
00456 cipherInit(&cipherInst, MODE_ECB, NULL);
00457 if (direction == DIR_ENCRYPT) {
00458 for (j = 0; j < 10000; j++) {
00459 memcpy(inBlock, outBlock, 16);
00460 blockEncrypt(&cipherInst, &keyInst, inBlock, 128, outBlock);
00461 }
00462 } else {
00463 for (j = 0; j < 10000; j++) {
00464 memcpy(inBlock, outBlock, 16);
00465 blockDecrypt(&cipherInst, &keyInst, inBlock, 128, outBlock);
00466 }
00467 }
00468 blockPrint(fp, outBlock, direction == DIR_ENCRYPT ? "CT" : "PT");
00469
00470 switch (keyLength) {
00471 case 128:
00472 for (j = 0; j < 128/8; j++) {
00473 binKey[j] ^= outBlock[j];
00474 }
00475 break;
00476 case 192:
00477 for (j = 0; j < 64/8; j++) {
00478 binKey[j] ^= inBlock[j + 64/8];
00479 }
00480 for (j = 0; j < 128/8; j++) {
00481 binKey[j + 64/8] ^= outBlock[j];
00482 }
00483 break;
00484 case 256:
00485 for (j = 0; j < 128/8; j++) {
00486 binKey[j] ^= inBlock[j];
00487 }
00488 for (j = 0; j < 128/8; j++) {
00489 binKey[j + 128/8] ^= outBlock[j];
00490 }
00491 break;
00492 }
00493 }
00494 #ifdef TRACE_KAT_MCT
00495 elapsed += clock();
00496 while (width-- > 0) {
00497 putchar('\b');
00498 }
00499 printf("%d done (%.1f s).\n", i, (float)elapsed/CLOCKS_PER_SEC);
00500 #endif
00501 }
00502
00503
00504 static void rijndaelCBC_MCT(FILE *fp, int keyLength, BYTE direction) {
00505 int i, j, r, t;
00506 BYTE inBlock[256/8], outBlock[256/8], binKey[256/8], cv[256/8];
00507 BYTE keyMaterial[320];
00508 keyInstance keyInst;
00509 cipherInstance cipherInst;
00510
00511 #ifdef TRACE_KAT_MCT
00512 int width = 0;
00513 clock_t elapsed = -clock();
00514 printf("Executing CBC MCT (%s, key %d): ",
00515 direction == DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT", keyLength);
00516 fflush (stdout);
00517 #endif
00518 fprintf (fp,
00519 "\n"
00520 "==========\n"
00521 "\n"
00522 "KEYSIZE=%d\n", keyLength);
00523 fflush(fp);
00524 memset(cv, 0, 16);
00525 memset(inBlock, 0, 16);
00526 memset(binKey, 0, keyLength/8);
00527 for (i = 0; i < 400; i++) {
00528 #ifdef TRACE_KAT_MCT
00529 while (width-- > 0) {
00530 putchar('\b');
00531 }
00532 width = printf("%d", i);
00533 fflush(stdout);
00534 #endif
00535 fprintf (fp, "\nI=%d\n", i);
00536
00537 for (j = 0; j < keyLength/8; j++) {
00538 sprintf (&keyMaterial[2*j], "%02X", binKey[j]);
00539 }
00540 keyMaterial[keyLength/4] = 0;
00541 fprintf(fp, "KEY=%s\n", keyMaterial);
00542 r = makeKey(&keyInst, direction, keyLength, keyMaterial);
00543 if (TRUE != r) {
00544 fprintf(stderr,"makeKey error %d\n",r);
00545 exit(-1);
00546 }
00547 r = cipherInit(&cipherInst, MODE_ECB, NULL);
00548 if (TRUE != r) {
00549 fprintf(stderr,"cipherInit error %d\n",r);
00550 exit(-1);
00551 }
00552
00553 blockPrint(fp, cv, "IV");
00554 blockPrint(fp, inBlock, direction == DIR_ENCRYPT ? "PT" : "CT");
00555 if (direction == DIR_ENCRYPT) {
00556 for (j = 0; j < 10000; j++) {
00557 for (t = 0; t < 16; t++) {
00558 inBlock[t] ^= cv[t];
00559 }
00560 r = blockEncrypt(&cipherInst, &keyInst, inBlock, 128, outBlock);
00561 if (128 != r) {
00562 fprintf(stderr,"blockEncrypt error %d\n",r);
00563 exit(-1);
00564 }
00565 memcpy(inBlock, cv, 16);
00566 memcpy(cv, outBlock, 16);
00567 }
00568 } else {
00569 for (j = 0; j < 10000; j++) {
00570 blockDecrypt(&cipherInst, &keyInst, inBlock, 128, outBlock);
00571 for (t = 0; t < 16; t++) {
00572 outBlock[t] ^= cv[t];
00573 }
00574 memcpy(cv, inBlock, 16);
00575 memcpy(inBlock, outBlock, 16);
00576 }
00577 }
00578 blockPrint(fp, outBlock, direction == DIR_ENCRYPT ? "CT" : "PT");
00579
00580 switch (keyLength) {
00581 case 128:
00582 for (j = 0; j < 128/8; j++) {
00583 binKey[j] ^= outBlock[j];
00584 }
00585 break;
00586 case 192:
00587 for (j = 0; j < 64/8; j++) {
00588 if (direction == DIR_ENCRYPT) {
00589 binKey[j] ^= inBlock[j + 64/8];
00590 } else {
00591 binKey[j] ^= cv[j + 64/8];
00592 }
00593 }
00594 for (j = 0; j < 128/8; j++) {
00595 binKey[j + 64/8] ^= outBlock[j];
00596 }
00597 break;
00598 case 256:
00599 for (j = 0; j < 128/8; j++) {
00600 if (direction == DIR_ENCRYPT) {
00601 binKey[j] ^= inBlock[j];
00602 } else {
00603 binKey[j] ^= cv[j];
00604 }
00605 }
00606 for (j = 0; j < 128/8; j++) {
00607 binKey[j + 128/8] ^= outBlock[j];
00608 }
00609 break;
00610 }
00611 }
00612 #ifdef TRACE_KAT_MCT
00613 elapsed += clock();
00614 while (width-- > 0) {
00615 putchar('\b');
00616 }
00617 printf("%d done (%.1f s).\n", i, (float)elapsed/CLOCKS_PER_SEC);
00618 #endif
00619 }
00620
00621
00622 static void makeMCTs(const char *ecbEncryptionFile, const char *ecbDecryptionFile,
00623 const char *cbcEncryptionFile, const char *cbcDecryptionFile) {
00624 FILE *fp;
00625
00626
00627 fp = fopen(ecbEncryptionFile, "w");
00628 fprintf(fp,
00629 "\n"
00630 "=========================\n"
00631 "\n"
00632 "FILENAME: \"%s\"\n"
00633 "\n"
00634 "Electronic Codebook (ECB) Mode - ENCRYPTION\n"
00635 "Monte Carlo Test\n"
00636 "\n"
00637 "Algorithm Name: Rijndael\n"
00638 "Principal Submitter: %s\n",
00639 ecbEncryptionFile, SUBMITTER);
00640 fflush(fp);
00641
00642 rijndaelECB_MCT(fp, 128, DIR_ENCRYPT);
00643 rijndaelECB_MCT(fp, 192, DIR_ENCRYPT);
00644 rijndaelECB_MCT(fp, 256, DIR_ENCRYPT);
00645
00646 fprintf(fp,
00647 "\n"
00648 "===========");
00649 fclose(fp);
00650
00651
00652 fp = fopen(ecbDecryptionFile, "w");
00653 fprintf(fp,
00654 "\n"
00655 "=========================\n"
00656 "\n"
00657 "FILENAME: \"%s\"\n"
00658 "\n"
00659 "Electronic Codebook (ECB) Mode - DECRYPTION\n"
00660 "Monte Carlo Test\n"
00661 "\n"
00662 "Algorithm Name: Rijndael\n"
00663 "Principal Submitter: %s\n",
00664 ecbDecryptionFile, SUBMITTER);
00665 fflush(fp);
00666
00667 rijndaelECB_MCT(fp, 128, DIR_DECRYPT);
00668 rijndaelECB_MCT(fp, 192, DIR_DECRYPT);
00669 rijndaelECB_MCT(fp, 256, DIR_DECRYPT);
00670
00671 fprintf(fp,
00672 "\n"
00673 "===========");
00674 fclose(fp);
00675
00676
00677 fp = fopen (cbcEncryptionFile, "w");
00678 fprintf(fp,
00679 "\n"
00680 "=========================\n"
00681 "\n"
00682 "FILENAME: \"%s\"\n"
00683 "\n"
00684 "Cipher Block Chaining (CBC) Mode - ENCRYPTION\n"
00685 "Monte Carlo Test\n"
00686 "\n"
00687 "Algorithm Name: Rijndael\n"
00688 "Principal Submitter: %s\n",
00689 cbcEncryptionFile, SUBMITTER);
00690 fflush(fp);
00691
00692 rijndaelCBC_MCT(fp, 128, DIR_ENCRYPT);
00693 rijndaelCBC_MCT(fp, 192, DIR_ENCRYPT);
00694 rijndaelCBC_MCT(fp, 256, DIR_ENCRYPT);
00695
00696 fprintf(fp,
00697 "\n"
00698 "===========");
00699 fclose(fp);
00700
00701
00702 fp = fopen(cbcDecryptionFile, "w");
00703 fprintf(fp,
00704 "\n"
00705 "=========================\n"
00706 "\n"
00707 "FILENAME: \"%s\"\n"
00708 "\n"
00709 "Cipher Block Chaining (CBC) Mode - DECRYPTION\n"
00710 "Monte Carlo Test\n"
00711 "\n"
00712 "Algorithm Name: Rijndael\n"
00713 "Principal Submitter: %s\n",
00714 cbcDecryptionFile, SUBMITTER);
00715 fflush(fp);
00716
00717 rijndaelCBC_MCT(fp, 128, DIR_DECRYPT);
00718 rijndaelCBC_MCT(fp, 192, DIR_DECRYPT);
00719 rijndaelCBC_MCT(fp, 256, DIR_DECRYPT);
00720
00721 fprintf(fp,
00722 "\n"
00723 "===========");
00724 fclose(fp);
00725 }
00726
00727 static void makeFIPSTestVectors(const char *fipsFile) {
00728 int i, keyLength, r;
00729 keyInstance keyInst;
00730 cipherInstance cipherInst;
00731 BYTE keyMaterial[320];
00732 u8 pt[16], ct[16];
00733 char format[64];
00734 FILE *fp;
00735
00736 #ifdef TRACE_KAT_MCT
00737 printf("Generating FIPS test vectors...");
00738 #endif
00739
00740 fp = fopen(fipsFile, "w");
00741 fprintf(fp,
00742 "\n"
00743 "================================\n\n"
00744 "FILENAME: \"%s\"\n\n"
00745 "FIPS Test Vectors\n",
00746 fipsFile);
00747
00748
00749 keyLength = 128;
00750 memset(keyMaterial, 0, sizeof (keyMaterial));
00751 for (i = 0; i < keyLength/8; i++) {
00752 sprintf(&keyMaterial[2*i], "%02X", i);
00753 }
00754
00755 fprintf(fp, "\n================================\n\n");
00756 fprintf(fp, "KEYSIZE=128\n\n");
00757 fprintf(fp, "KEY=%s\n\n", keyMaterial);
00758
00759
00760 for (i = 0; i < 16; i++) {
00761 pt[i] = (i << 4) | i;
00762 }
00763
00764
00765 makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00766 cipherInit(&cipherInst, MODE_ECB, NULL);
00767 fprintf(fp, "Round Subkey Values (Encryption)\n\n");
00768 for (r = 0; r <= keyInst.Nr; r++) {
00769 fprintf(fp, "RK%d=", r);
00770 for (i = 0; i < 4; i++) {
00771 u32 w = keyInst.rk[4*r + i];
00772 fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00773 }
00774 fprintf(fp, "\n");
00775 }
00776 fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
00777 blockPrint(fp, pt, "PT");
00778 for (i = 1; i < keyInst.Nr; i++) {
00779 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i);
00780 sprintf(format, "CT%d", i);
00781 blockPrint(fp, ct, format);
00782 }
00783 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr);
00784 blockPrint(fp, ct, "CT");
00785
00786
00787 makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00788 cipherInit(&cipherInst, MODE_ECB, NULL);
00789 fprintf(fp, "\nRound Subkey Values (Decryption)\n\n");
00790 for (r = 0; r <= keyInst.Nr; r++) {
00791 fprintf(fp, "RK%d=", r);
00792 for (i = 0; i < 4; i++) {
00793 u32 w = keyInst.rk[4*r + i];
00794 fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00795 }
00796 fprintf(fp, "\n");
00797 }
00798 fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
00799 blockPrint(fp, ct, "CT");
00800 for (i = 1; i < keyInst.Nr; i++) {
00801 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i);
00802 sprintf(format, "PT%d", i);
00803 blockPrint(fp, pt, format);
00804 }
00805 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr);
00806 blockPrint(fp, pt, "PT");
00807
00808
00809 keyLength = 192;
00810 memset(keyMaterial, 0, sizeof (keyMaterial));
00811 for (i = 0; i < keyLength/8; i++) {
00812 sprintf(&keyMaterial[2*i], "%02X", i);
00813 }
00814
00815 fprintf(fp, "\n================================\n\n");
00816 fprintf(fp, "KEYSIZE=192\n\n");
00817 fprintf(fp, "KEY=%s\n\n", keyMaterial);
00818
00819
00820 for (i = 0; i < 16; i++) {
00821 pt[i] = (i << 4) | i;
00822 }
00823
00824
00825 makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00826 cipherInit(&cipherInst, MODE_ECB, NULL);
00827 fprintf(fp, "\nRound Subkey Values (Encryption)\n\n");
00828 for (r = 0; r <= keyInst.Nr; r++) {
00829 fprintf(fp, "RK%d=", r);
00830 for (i = 0; i < 4; i++) {
00831 u32 w = keyInst.rk[4*r + i];
00832 fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00833 }
00834 fprintf(fp, "\n");
00835 }
00836 fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
00837 blockPrint(fp, pt, "PT");
00838 for (i = 1; i < keyInst.Nr; i++) {
00839 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i);
00840 sprintf(format, "CT%d", i);
00841 blockPrint(fp, ct, format);
00842 }
00843 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr);
00844 blockPrint(fp, ct, "CT");
00845
00846
00847 makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00848 cipherInit(&cipherInst, MODE_ECB, NULL);
00849 fprintf(fp, "\nRound Subkey Values (Decryption)\n\n");
00850 for (r = 0; r <= keyInst.Nr; r++) {
00851 fprintf(fp, "RK%d=", r);
00852 for (i = 0; i < 4; i++) {
00853 u32 w = keyInst.rk[4*r + i];
00854 fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00855 }
00856 fprintf(fp, "\n");
00857 }
00858 fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
00859 blockPrint(fp, ct, "CT");
00860 for(i = 1; i < keyInst.Nr; i++) {
00861 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i);
00862 sprintf(format, "PT%d", i);
00863 blockPrint(fp, pt, format);
00864 }
00865 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr);
00866 blockPrint(fp, pt, "PT");
00867
00868
00869 keyLength = 256;
00870 memset(keyMaterial, 0, sizeof (keyMaterial));
00871 for (i = 0; i < keyLength/8; i++) {
00872 sprintf(&keyMaterial[2*i], "%02X", i);
00873 }
00874
00875 fprintf(fp, "\n================================\n\n");
00876 fprintf(fp, "KEYSIZE=256\n\n");
00877 fprintf(fp, "KEY=%s\n\n", keyMaterial);
00878
00879
00880 for (i = 0; i < 16; i++) {
00881 pt[i] = (i << 4) | i;
00882 }
00883
00884
00885 makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00886 cipherInit(&cipherInst, MODE_ECB, NULL);
00887 fprintf(fp, "\nRound Subkey Values (Encryption)\n\n");
00888 for (r = 0; r <= keyInst.Nr; r++) {
00889 fprintf(fp, "RK%d=", r);
00890 for (i = 0; i < 4; i++) {
00891 u32 w = keyInst.rk[4*r + i];
00892 fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00893 }
00894 fprintf(fp, "\n");
00895 }
00896 fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
00897 blockPrint(fp, pt, "PT");
00898 for(i = 1; i < keyInst.Nr; i++) {
00899 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i);
00900 sprintf(format, "CT%d", i);
00901 blockPrint(fp, ct, format);
00902 }
00903 cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr);
00904 blockPrint(fp, ct, "CT");
00905
00906
00907 makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00908 cipherInit(&cipherInst, MODE_ECB, NULL);
00909 fprintf(fp, "\nRound Subkey Values (Decryption)\n\n");
00910 for (r = 0; r <= keyInst.Nr; r++) {
00911 fprintf(fp, "RK%d=", r);
00912 for (i = 0; i < 4; i++) {
00913 u32 w = keyInst.rk[4*r + i];
00914 fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00915 }
00916 fprintf(fp, "\n");
00917 }
00918 fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
00919 blockPrint(fp, ct, "CT");
00920 for(i = 1; i < keyInst.Nr; i++) {
00921 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i);
00922 sprintf(format, "PT%d", i);
00923 blockPrint(fp, pt, format);
00924 }
00925 cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr);
00926 blockPrint(fp, pt, "PT");
00927
00928 fprintf(fp, "\n");
00929 fclose(fp);
00930 #ifdef TRACE_KAT_MCT
00931 printf(" done.\n");
00932 #endif
00933 }
00934
00935 #define ITERATIONS 10000000
00936
00937 void rijndaelSpeed(int keyBits) {
00938 int Nr, i;
00939 u32 rk[4*(MAXNR + 1)];
00940 u8 cipherKey[256/8], pt[16], ct[16];
00941 clock_t elapsed;
00942 float sec;
00943
00944 memset(cipherKey, 0, sizeof(cipherKey));
00945 printf("================================\n");
00946 printf("Speed measurement for %d-bit keys:\n", keyBits);
00947
00948
00949
00950
00951 elapsed = -clock();
00952 for (i = 0; i < ITERATIONS; i++) {
00953 Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
00954 }
00955 elapsed += clock();
00956 sec = (float)elapsed/CLOCKS_PER_SEC;
00957 printf("Encryption key schedule: %.1f s, %.0f Mbit/s\n",
00958 sec, (float)ITERATIONS*128/sec/1000000);
00959
00960
00961
00962
00963 elapsed = -clock();
00964 for (i = 0; i < ITERATIONS; i++) {
00965 rijndaelEncrypt(rk, Nr, pt, ct);
00966 }
00967 elapsed += clock();
00968 sec = (float)elapsed/CLOCKS_PER_SEC;
00969 printf("Encryption: %.1f s, %.0f Mbit/s\n",
00970 sec, (float)ITERATIONS*128/sec/1000000);
00971
00972
00973
00974
00975 elapsed = -clock();
00976 for (i = 0; i < ITERATIONS; i++) {
00977 Nr = rijndaelKeySetupDec(rk, cipherKey, keyBits);
00978 }
00979 elapsed += clock();
00980 sec = (float)elapsed/CLOCKS_PER_SEC;
00981 printf("Decryption key schedule: %.1f s, %.0f Mbit/s\n",
00982 sec, (float)ITERATIONS*128/sec/1000000);
00983
00984
00985
00986
00987 elapsed = -clock();
00988 for (i = 0; i < ITERATIONS; i++) {
00989 rijndaelDecrypt(rk, Nr, pt, ct);
00990 }
00991 elapsed += clock();
00992 sec = (float)elapsed/CLOCKS_PER_SEC;
00993 printf("Decryption: %.1f s, %.0f Mbit/s\n",
00994 sec, (float)ITERATIONS*128/sec/1000000);
00995
00996 }
00997
00998 int main(void) {
00999 makeFIPSTestVectors("fips-test-vectors.txt");
01000 makeKATs("ecb_vk.txt", "ecb_vt.txt", "ecb_tbl.txt", "ecb_iv.txt");
01001 makeMCTs("ecb_e_m.txt", "ecb_d_m.txt", "cbc_e_m.txt", "cbc_d_m.txt");
01002
01003
01004
01005
01006
01007 return 0;
01008 }