1/* ==================================================================== 2 * Copyright (c) 2004 The OpenSSL Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * 3. All advertising materials mentioning features or use of this 17 * software must display the following acknowledgment: 18 * "This product includes software developed by the OpenSSL Project 19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20 * 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22 * endorse or promote products derived from this software without 23 * prior written permission. For written permission, please contact 24 * openssl-core@openssl.org. 25 * 26 * 5. Products derived from this software may not be called "OpenSSL" 27 * nor may "OpenSSL" appear in their names without prior written 28 * permission of the OpenSSL Project. 29 * 30 * 6. Redistributions of any form whatsoever must retain the following 31 * acknowledgment: 32 * "This product includes software developed by the OpenSSL Project 33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46 * OF THE POSSIBILITY OF SUCH DAMAGE. 47 * 48 */ 49/*--------------------------------------------- 50 NIST AES Algorithm Validation Suite 51 Test Program 52 53 Donated to OpenSSL by: 54 V-ONE Corporation 55 20250 Century Blvd, Suite 300 56 Germantown, MD 20874 57 U.S.A. 58 ----------------------------------------------*/ 59 60#include <stdio.h> 61#include <stdlib.h> 62#include <string.h> 63#include <errno.h> 64#include <assert.h> 65 66#include <openssl/aes.h> 67#include <openssl/evp.h> 68#include <openssl/fips.h> 69#include <openssl/err.h> 70#include "e_os.h" 71 72#define AES_BLOCK_SIZE 16 73 74#define VERBOSE 1 75 76/*-----------------------------------------------*/ 77 78int AESTest(EVP_CIPHER_CTX *ctx, 79 char *amode, int akeysz, unsigned char *aKey, 80 unsigned char *iVec, 81 int dir, /* 0 = decrypt, 1 = encrypt */ 82 unsigned char *plaintext, unsigned char *ciphertext, int len) 83 { 84 const EVP_CIPHER *cipher = NULL; 85 int ret = 1; 86 int kt = 0; 87 88 if (ctx) 89 memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); 90 91 if (strcasecmp(amode, "CBC") == 0) 92 kt = 1000; 93 else if (strcasecmp(amode, "ECB") == 0) 94 kt = 2000; 95 else if (strcasecmp(amode, "CFB128") == 0) 96 kt = 3000; 97 else if (strncasecmp(amode, "OFB", 3) == 0) 98 kt = 4000; 99 else if(!strcasecmp(amode,"CFB1")) 100 kt=5000; 101 else if(!strcasecmp(amode,"CFB8")) 102 kt=6000; 103 else 104 { 105 printf("Unknown mode: %s\n", amode); 106 EXIT(1); 107 } 108 if (ret) 109 { 110 if ((akeysz != 128) && (akeysz != 192) && (akeysz != 256)) 111 { 112 printf("Invalid key size: %d\n", akeysz); 113 ret = 0; 114 } 115 else 116 { 117 kt += akeysz; 118 switch (kt) 119 { 120 case 1128: /* CBC 128 */ 121 cipher = EVP_aes_128_cbc(); 122 break; 123 case 1192: /* CBC 192 */ 124 cipher = EVP_aes_192_cbc(); 125 break; 126 case 1256: /* CBC 256 */ 127 cipher = EVP_aes_256_cbc(); 128 break; 129 case 2128: /* ECB 128 */ 130 cipher = EVP_aes_128_ecb(); 131 break; 132 case 2192: /* ECB 192 */ 133 cipher = EVP_aes_192_ecb(); 134 break; 135 case 2256: /* ECB 256 */ 136 cipher = EVP_aes_256_ecb(); 137 break; 138 case 3128: /* CFB 128 */ 139 cipher = EVP_aes_128_cfb(); 140 break; 141 case 3192: /* CFB 192 */ 142 cipher = EVP_aes_192_cfb(); 143 break; 144 case 3256: /* CFB 256 */ 145 cipher = EVP_aes_256_cfb(); 146 break; 147 case 4128: /* OFB 128 */ 148 cipher = EVP_aes_128_ofb(); 149 break; 150 case 4192: /* OFB 192 */ 151 cipher = EVP_aes_192_ofb(); 152 break; 153 case 4256: /* OFB 256 */ 154 cipher = EVP_aes_256_ofb(); 155 break; 156 case 5128: 157 cipher=EVP_aes_128_cfb1(); 158 break; 159 case 5192: 160 cipher=EVP_aes_192_cfb1(); 161 break; 162 case 5256: 163 cipher=EVP_aes_256_cfb1(); 164 break; 165 case 6128: 166 cipher=EVP_aes_128_cfb8(); 167 break; 168 case 6192: 169 cipher=EVP_aes_192_cfb8(); 170 break; 171 case 6256: 172 cipher=EVP_aes_256_cfb8(); 173 break; 174 default: 175 printf("Didn't handle mode %d\n",kt); 176 EXIT(1); 177 } 178 if (dir) 179 { /* encrypt */ 180 if(!EVP_CipherInit(ctx, cipher, aKey, iVec, AES_ENCRYPT)) 181 { 182 ERR_print_errors_fp(stderr); 183 EXIT(1); 184 } 185 186 EVP_Cipher(ctx, ciphertext, (unsigned char*)plaintext, len); 187 } 188 else 189 { /* decrypt */ 190 if(!EVP_CipherInit(ctx, cipher, aKey, iVec, AES_DECRYPT)) 191 { 192 ERR_print_errors_fp(stderr); 193 EXIT(1); 194 } 195 EVP_Cipher(ctx, (unsigned char*)plaintext, ciphertext, len); 196 } 197 } 198 } 199 return ret; 200 } 201 202/*-----------------------------------------------*/ 203 204int hex2bin(char *in, int len, unsigned char *out) 205{ 206 int n1, n2; 207 unsigned char ch; 208 209 for (n1 = 0, n2 = 0; n1 < len; ) 210 { /* first byte */ 211 if ((in[n1] >= '0') && (in[n1] <= '9')) 212 ch = in[n1++] - '0'; 213 else if ((in[n1] >= 'A') && (in[n1] <= 'F')) 214 ch = in[n1++] - 'A' + 10; 215 else if ((in[n1] >= 'a') && (in[n1] <= 'f')) 216 ch = in[n1++] - 'a' + 10; 217 else 218 return -1; 219 if(len == 1) 220 { 221 out[n2++]=ch; 222 break; 223 } 224 out[n2] = ch << 4; 225 /* second byte */ 226 if ((in[n1] >= '0') && (in[n1] <= '9')) 227 ch = in[n1++] - '0'; 228 else if ((in[n1] >= 'A') && (in[n1] <= 'F')) 229 ch = in[n1++] - 'A' + 10; 230 else if ((in[n1] >= 'a') && (in[n1] <= 'f')) 231 ch = in[n1++] - 'a' + 10; 232 else 233 return -1; 234 out[n2++] |= ch; 235 } 236 return n2; 237} 238 239/*-----------------------------------------------*/ 240 241int bin2hex(unsigned char *in, int len, char *out) 242{ 243 int n1, n2; 244 unsigned char ch; 245 246 for (n1 = 0, n2 = 0; n1 < len; ++n1) 247 { 248 /* first nibble */ 249 ch = in[n1] >> 4; 250 if (ch <= 0x09) 251 out[n2++] = ch + '0'; 252 else 253 out[n2++] = ch - 10 + 'a'; 254 /* second nibble */ 255 ch = in[n1] & 0x0f; 256 if (ch <= 0x09) 257 out[n2++] = ch + '0'; 258 else 259 out[n2++] = ch - 10 + 'a'; 260 } 261 return n2; 262} 263 264/* NB: this return the number of _bits_ read */ 265int bint2bin(const char *in, int len, unsigned char *out) 266 { 267 int n; 268 269 memset(out,0,len); 270 for(n=0 ; n < len ; ++n) 271 if(in[n] == '1') 272 out[n/8]|=(0x80 >> (n%8)); 273 return len; 274 } 275 276int bin2bint(const unsigned char *in,int len,char *out) 277 { 278 int n; 279 280 for(n=0 ; n < len ; ++n) 281 out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0'; 282 return n; 283 } 284 285/*-----------------------------------------------*/ 286 287void PrintValue(char *tag, unsigned char *val, int len) 288{ 289#if VERBOSE 290 char obuf[2048]; 291 int olen; 292 olen = bin2hex(val, len, obuf); 293 printf("%s = %.*s\n", tag, olen, obuf); 294#endif 295} 296 297void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode) 298 { 299 char obuf[2048]; 300 int olen; 301 302 if(bitmode) 303 olen=bin2bint(val,len,obuf); 304 else 305 olen=bin2hex(val,len,obuf); 306 307 fprintf(rfp, "%s = %.*s\n", tag, olen, obuf); 308#if VERBOSE 309 printf("%s = %.*s\n", tag, olen, obuf); 310#endif 311 } 312 313/*-----------------------------------------------*/ 314char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; 315char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"}; 316enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128}; 317enum XCrypt {XDECRYPT, XENCRYPT}; 318 319/*=============================*/ 320/* Monte Carlo Tests */ 321/*-----------------------------*/ 322 323/*#define gb(a,b) (((a)[(b)/8] >> ((b)%8))&1)*/ 324/*#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << ((b)%8)))|(!!(v) << ((b)%8)))*/ 325 326#define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1) 327#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8))) 328 329int do_mct(char *amode, 330 int akeysz, unsigned char *aKey,unsigned char *iVec, 331 int dir, unsigned char *text, int len, 332 FILE *rfp) 333 { 334 int ret = 0; 335 unsigned char key[101][32]; 336 unsigned char iv[101][AES_BLOCK_SIZE]; 337 unsigned char ptext[1001][32]; 338 unsigned char ctext[1001][32]; 339 unsigned char ciphertext[64+4]; 340 int i, j, n, n1, n2; 341 int imode = 0, nkeysz = akeysz/8; 342 EVP_CIPHER_CTX ctx; 343 344 if (len > 32) 345 { 346 printf("\n>>>> Length exceeds 32 for %s %d <<<<\n\n", 347 amode, akeysz); 348 return -1; 349 } 350 for (imode = 0; imode < 6; ++imode) 351 if (strcmp(amode, t_mode[imode]) == 0) 352 break; 353 if (imode == 6) 354 { 355 printf("Unrecognized mode: %s\n", amode); 356 return -1; 357 } 358 359 memcpy(key[0], aKey, nkeysz); 360 if (iVec) 361 memcpy(iv[0], iVec, AES_BLOCK_SIZE); 362 if (dir == XENCRYPT) 363 memcpy(ptext[0], text, len); 364 else 365 memcpy(ctext[0], text, len); 366 for (i = 0; i < 100; ++i) 367 { 368 /* printf("Iteration %d\n", i); */ 369 if (i > 0) 370 { 371 fprintf(rfp,"COUNT = %d\n",i); 372 OutputValue("KEY",key[i],nkeysz,rfp,0); 373 if (imode != ECB) /* ECB */ 374 OutputValue("IV",iv[i],AES_BLOCK_SIZE,rfp,0); 375 /* Output Ciphertext | Plaintext */ 376 OutputValue(t_tag[dir^1],dir ? ptext[0] : ctext[0],len,rfp, 377 imode == CFB1); 378 } 379 for (j = 0; j < 1000; ++j) 380 { 381 switch (imode) 382 { 383 case ECB: 384 if (j == 0) 385 { /* set up encryption */ 386 ret = AESTest(&ctx, amode, akeysz, key[i], NULL, 387 dir, /* 0 = decrypt, 1 = encrypt */ 388 ptext[j], ctext[j], len); 389 if (dir == XENCRYPT) 390 memcpy(ptext[j+1], ctext[j], len); 391 else 392 memcpy(ctext[j+1], ptext[j], len); 393 } 394 else 395 { 396 if (dir == XENCRYPT) 397 { 398 EVP_Cipher(&ctx, ctext[j], ptext[j], len); 399 memcpy(ptext[j+1], ctext[j], len); 400 } 401 else 402 { 403 EVP_Cipher(&ctx, ptext[j], ctext[j], len); 404 memcpy(ctext[j+1], ptext[j], len); 405 } 406 } 407 break; 408 409 case CBC: 410 case OFB: 411 case CFB128: 412 if (j == 0) 413 { 414 ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], 415 dir, /* 0 = decrypt, 1 = encrypt */ 416 ptext[j], ctext[j], len); 417 if (dir == XENCRYPT) 418 memcpy(ptext[j+1], iv[i], len); 419 else 420 memcpy(ctext[j+1], iv[i], len); 421 } 422 else 423 { 424 if (dir == XENCRYPT) 425 { 426 EVP_Cipher(&ctx, ctext[j], ptext[j], len); 427 memcpy(ptext[j+1], ctext[j-1], len); 428 } 429 else 430 { 431 EVP_Cipher(&ctx, ptext[j], ctext[j], len); 432 memcpy(ctext[j+1], ptext[j-1], len); 433 } 434 } 435 break; 436 437 case CFB8: 438 if (j == 0) 439 { 440 ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], 441 dir, /* 0 = decrypt, 1 = encrypt */ 442 ptext[j], ctext[j], len); 443 } 444 else 445 { 446 if (dir == XENCRYPT) 447 EVP_Cipher(&ctx, ctext[j], ptext[j], len); 448 else 449 EVP_Cipher(&ctx, ptext[j], ctext[j], len); 450 } 451 if (dir == XENCRYPT) 452 { 453 if (j < 16) 454 memcpy(ptext[j+1], &iv[i][j], len); 455 else 456 memcpy(ptext[j+1], ctext[j-16], len); 457 } 458 else 459 { 460 if (j < 16) 461 memcpy(ctext[j+1], &iv[i][j], len); 462 else 463 memcpy(ctext[j+1], ptext[j-16], len); 464 } 465 break; 466 467 case CFB1: 468 if(j == 0) 469 { 470 /* compensate for wrong endianness of input file */ 471 if(i == 0) 472 ptext[0][0]<<=7; 473 ret=AESTest(&ctx,amode,akeysz,key[i],iv[i],dir, 474 ptext[j], ctext[j], len); 475 } 476 else 477 { 478 if (dir == XENCRYPT) 479 EVP_Cipher(&ctx, ctext[j], ptext[j], len); 480 else 481 EVP_Cipher(&ctx, ptext[j], ctext[j], len); 482 483 } 484 if(dir == XENCRYPT) 485 { 486 if(j < 128) 487 sb(ptext[j+1],0,gb(iv[i],j)); 488 else 489 sb(ptext[j+1],0,gb(ctext[j-128],0)); 490 } 491 else 492 { 493 if(j < 128) 494 sb(ctext[j+1],0,gb(iv[i],j)); 495 else 496 sb(ctext[j+1],0,gb(ptext[j-128],0)); 497 } 498 break; 499 } 500 } 501 --j; /* reset to last of range */ 502 /* Output Ciphertext | Plaintext */ 503 OutputValue(t_tag[dir],dir ? ctext[j] : ptext[j],len,rfp, 504 imode == CFB1); 505 fprintf(rfp, "\n"); /* add separator */ 506 507 /* Compute next KEY */ 508 if (dir == XENCRYPT) 509 { 510 if (imode == CFB8) 511 { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ 512 for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) 513 ciphertext[n1] = ctext[j-n2][0]; 514 } 515 else if(imode == CFB1) 516 { 517 for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) 518 sb(ciphertext,n1,gb(ctext[j-n2],0)); 519 } 520 else 521 switch (akeysz) 522 { 523 case 128: 524 memcpy(ciphertext, ctext[j], 16); 525 break; 526 case 192: 527 memcpy(ciphertext, ctext[j-1]+8, 8); 528 memcpy(ciphertext+8, ctext[j], 16); 529 break; 530 case 256: 531 memcpy(ciphertext, ctext[j-1], 16); 532 memcpy(ciphertext+16, ctext[j], 16); 533 break; 534 } 535 } 536 else 537 { 538 if (imode == CFB8) 539 { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ 540 for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) 541 ciphertext[n1] = ptext[j-n2][0]; 542 } 543 else if(imode == CFB1) 544 { 545 for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) 546 sb(ciphertext,n1,gb(ptext[j-n2],0)); 547 } 548 else 549 switch (akeysz) 550 { 551 case 128: 552 memcpy(ciphertext, ptext[j], 16); 553 break; 554 case 192: 555 memcpy(ciphertext, ptext[j-1]+8, 8); 556 memcpy(ciphertext+8, ptext[j], 16); 557 break; 558 case 256: 559 memcpy(ciphertext, ptext[j-1], 16); 560 memcpy(ciphertext+16, ptext[j], 16); 561 break; 562 } 563 } 564 /* Compute next key: Key[i+1] = Key[i] xor ct */ 565 for (n = 0; n < nkeysz; ++n) 566 key[i+1][n] = key[i][n] ^ ciphertext[n]; 567 568 /* Compute next IV and text */ 569 if (dir == XENCRYPT) 570 { 571 switch (imode) 572 { 573 case ECB: 574 memcpy(ptext[0], ctext[j], AES_BLOCK_SIZE); 575 break; 576 case CBC: 577 case OFB: 578 case CFB128: 579 memcpy(iv[i+1], ctext[j], AES_BLOCK_SIZE); 580 memcpy(ptext[0], ctext[j-1], AES_BLOCK_SIZE); 581 break; 582 case CFB8: 583 /* IV[i+1] = ct */ 584 for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) 585 iv[i+1][n1] = ctext[j-n2][0]; 586 ptext[0][0] = ctext[j-16][0]; 587 break; 588 case CFB1: 589 for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) 590 sb(iv[i+1],n1,gb(ctext[j-n2],0)); 591 ptext[0][0]=ctext[j-128][0]&0x80; 592 break; 593 } 594 } 595 else 596 { 597 switch (imode) 598 { 599 case ECB: 600 memcpy(ctext[0], ptext[j], AES_BLOCK_SIZE); 601 break; 602 case CBC: 603 case OFB: 604 case CFB128: 605 memcpy(iv[i+1], ptext[j], AES_BLOCK_SIZE); 606 memcpy(ctext[0], ptext[j-1], AES_BLOCK_SIZE); 607 break; 608 case CFB8: 609 for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) 610 iv[i+1][n1] = ptext[j-n2][0]; 611 ctext[0][0] = ptext[j-16][0]; 612 break; 613 case CFB1: 614 for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) 615 sb(iv[i+1],n1,gb(ptext[j-n2],0)); 616 ctext[0][0]=ptext[j-128][0]&0x80; 617 break; 618 } 619 } 620 } 621 622 return ret; 623 } 624 625/*================================================*/ 626/*---------------------------- 627 # Config info for v-one 628 # AESVS MMT test data for ECB 629 # State : Encrypt and Decrypt 630 # Key Length : 256 631 # Fri Aug 30 04:07:22 PM 632 ----------------------------*/ 633 634int proc_file(char *rqfile) 635 { 636 char afn[256], rfn[256]; 637 FILE *afp = NULL, *rfp = NULL; 638 char ibuf[2048]; 639 int ilen, len, ret = 0; 640 char algo[8] = ""; 641 char amode[8] = ""; 642 char atest[8] = ""; 643 int akeysz = 0; 644 unsigned char iVec[20], aKey[40]; 645 int dir = -1, err = 0, step = 0; 646 unsigned char plaintext[2048]; 647 unsigned char ciphertext[2048]; 648 char *rp; 649 EVP_CIPHER_CTX ctx; 650 651 if (!rqfile || !(*rqfile)) 652 { 653 printf("No req file\n"); 654 return -1; 655 } 656 strcpy(afn, rqfile); 657 658 if ((afp = fopen(afn, "r")) == NULL) 659 { 660 printf("Cannot open file: %s, %s\n", 661 afn, strerror(errno)); 662 return -1; 663 } 664 strcpy(rfn,afn); 665 rp=strstr(rfn,"req/"); 666 assert(rp); 667 memcpy(rp,"rsp",3); 668 rp = strstr(rfn, ".req"); 669 memcpy(rp, ".rsp", 4); 670 if ((rfp = fopen(rfn, "w")) == NULL) 671 { 672 printf("Cannot open file: %s, %s\n", 673 rfn, strerror(errno)); 674 fclose(afp); 675 afp = NULL; 676 return -1; 677 } 678 while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) 679 { 680 ilen = strlen(ibuf); 681 /* printf("step=%d ibuf=%s",step,ibuf); */ 682 switch (step) 683 { 684 case 0: /* read preamble */ 685 if (ibuf[0] == '\n') 686 { /* end of preamble */ 687 if ((*algo == '\0') || 688 (*amode == '\0') || 689 (akeysz == 0)) 690 { 691 printf("Missing Algorithm, Mode or KeySize (%s/%s/%d)\n", 692 algo,amode,akeysz); 693 err = 1; 694 } 695 else 696 { 697 fputs(ibuf, rfp); 698 ++ step; 699 } 700 } 701 else if (ibuf[0] != '#') 702 { 703 printf("Invalid preamble item: %s\n", ibuf); 704 err = 1; 705 } 706 else 707 { /* process preamble */ 708 char *xp, *pp = ibuf+2; 709 int n; 710 if (akeysz) 711 { /* insert current time & date */ 712 time_t rtim = time(0); 713 fprintf(rfp, "# %s", ctime(&rtim)); 714 } 715 else 716 { 717 fputs(ibuf, rfp); 718 if (strncmp(pp, "AESVS ", 6) == 0) 719 { 720 strcpy(algo, "AES"); 721 /* get test type */ 722 pp += 6; 723 xp = strchr(pp, ' '); 724 n = xp-pp; 725 strncpy(atest, pp, n); 726 atest[n] = '\0'; 727 /* get mode */ 728 xp = strrchr(pp, ' '); /* get mode" */ 729 n = strlen(xp+1)-1; 730 strncpy(amode, xp+1, n); 731 amode[n] = '\0'; 732 /* amode[3] = '\0'; */ 733 printf("Test = %s, Mode = %s\n", atest, amode); 734 } 735 else if (strncasecmp(pp, "Key Length : ", 13) == 0) 736 { 737 akeysz = atoi(pp+13); 738 printf("Key size = %d\n", akeysz); 739 } 740 } 741 } 742 break; 743 744 case 1: /* [ENCRYPT] | [DECRYPT] */ 745 if (ibuf[0] == '[') 746 { 747 fputs(ibuf, rfp); 748 ++step; 749 if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) 750 dir = 1; 751 else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) 752 dir = 0; 753 else 754 { 755 printf("Invalid keyword: %s\n", ibuf); 756 err = 1; 757 } 758 break; 759 } 760 else if (dir == -1) 761 { 762 err = 1; 763 printf("Missing ENCRYPT/DECRYPT keyword\n"); 764 break; 765 } 766 else 767 step = 2; 768 769 case 2: /* KEY = xxxx */ 770 fputs(ibuf, rfp); 771 if(*ibuf == '\n') 772 break; 773 if(!strncasecmp(ibuf,"COUNT = ",8)) 774 break; 775 776 if (strncasecmp(ibuf, "KEY = ", 6) != 0) 777 { 778 printf("Missing KEY\n"); 779 err = 1; 780 } 781 else 782 { 783 len = hex2bin((char*)ibuf+6, strlen(ibuf+6)-1, aKey); 784 if (len < 0) 785 { 786 printf("Invalid KEY\n"); 787 err =1; 788 break; 789 } 790 PrintValue("KEY", aKey, len); 791 if (strcmp(amode, "ECB") == 0) 792 { 793 memset(iVec, 0, sizeof(iVec)); 794 step = (dir)? 4: 5; /* no ivec for ECB */ 795 } 796 else 797 ++step; 798 } 799 break; 800 801 case 3: /* IV = xxxx */ 802 fputs(ibuf, rfp); 803 if (strncasecmp(ibuf, "IV = ", 5) != 0) 804 { 805 printf("Missing IV\n"); 806 err = 1; 807 } 808 else 809 { 810 len = hex2bin((char*)ibuf+5, strlen(ibuf+5)-1, iVec); 811 if (len < 0) 812 { 813 printf("Invalid IV\n"); 814 err =1; 815 break; 816 } 817 PrintValue("IV", iVec, len); 818 step = (dir)? 4: 5; 819 } 820 break; 821 822 case 4: /* PLAINTEXT = xxxx */ 823 fputs(ibuf, rfp); 824 if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) 825 { 826 printf("Missing PLAINTEXT\n"); 827 err = 1; 828 } 829 else 830 { 831 int nn = strlen(ibuf+12); 832 if(!strcmp(amode,"CFB1")) 833 len=bint2bin(ibuf+12,nn-1,plaintext); 834 else 835 len=hex2bin(ibuf+12, nn-1,plaintext); 836 if (len < 0) 837 { 838 printf("Invalid PLAINTEXT: %s", ibuf+12); 839 err =1; 840 break; 841 } 842 if (len >= sizeof(plaintext)) 843 { 844 printf("Buffer overflow\n"); 845 } 846 PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); 847 if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ 848 { 849 if(do_mct(amode, akeysz, aKey, iVec, 850 dir, (unsigned char*)plaintext, len, 851 rfp) < 0) 852 EXIT(1); 853 } 854 else 855 { 856 ret = AESTest(&ctx, amode, akeysz, aKey, iVec, 857 dir, /* 0 = decrypt, 1 = encrypt */ 858 plaintext, ciphertext, len); 859 OutputValue("CIPHERTEXT",ciphertext,len,rfp, 860 !strcmp(amode,"CFB1")); 861 } 862 step = 6; 863 } 864 break; 865 866 case 5: /* CIPHERTEXT = xxxx */ 867 fputs(ibuf, rfp); 868 if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) 869 { 870 printf("Missing KEY\n"); 871 err = 1; 872 } 873 else 874 { 875 if(!strcmp(amode,"CFB1")) 876 len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); 877 else 878 len = hex2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); 879 if (len < 0) 880 { 881 printf("Invalid CIPHERTEXT\n"); 882 err =1; 883 break; 884 } 885 886 PrintValue("CIPHERTEXT", ciphertext, len); 887 if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ 888 { 889 do_mct(amode, akeysz, aKey, iVec, 890 dir, ciphertext, len, rfp); 891 } 892 else 893 { 894 ret = AESTest(&ctx, amode, akeysz, aKey, iVec, 895 dir, /* 0 = decrypt, 1 = encrypt */ 896 plaintext, ciphertext, len); 897 OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, 898 !strcmp(amode,"CFB1")); 899 } 900 step = 6; 901 } 902 break; 903 904 case 6: 905 if (ibuf[0] != '\n') 906 { 907 err = 1; 908 printf("Missing terminator\n"); 909 } 910 else if (strcmp(atest, "MCT") != 0) 911 { /* MCT already added terminating nl */ 912 fputs(ibuf, rfp); 913 } 914 step = 1; 915 break; 916 } 917 } 918 if (rfp) 919 fclose(rfp); 920 if (afp) 921 fclose(afp); 922 return err; 923 } 924 925/*-------------------------------------------------- 926 Processes either a single file or 927 a set of files whose names are passed in a file. 928 A single file is specified as: 929 aes_test -f xxx.req 930 A set of files is specified as: 931 aes_test -d xxxxx.xxx 932 The default is: -d req.txt 933--------------------------------------------------*/ 934int main(int argc, char **argv) 935 { 936 char *rqlist = "req.txt"; 937 FILE *fp = NULL; 938 char fn[250] = "", rfn[256] = ""; 939 int f_opt = 0, d_opt = 1; 940 941#ifdef OPENSSL_FIPS 942 if(!FIPS_mode_set(1,argv[0])) 943 { 944 ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); 945 EXIT(1); 946 } 947#endif 948 ERR_load_crypto_strings(); 949 if (argc > 1) 950 { 951 if (strcasecmp(argv[1], "-d") == 0) 952 { 953 d_opt = 1; 954 } 955 else if (strcasecmp(argv[1], "-f") == 0) 956 { 957 f_opt = 1; 958 d_opt = 0; 959 } 960 else 961 { 962 printf("Invalid parameter: %s\n", argv[1]); 963 return 0; 964 } 965 if (argc < 3) 966 { 967 printf("Missing parameter\n"); 968 return 0; 969 } 970 if (d_opt) 971 rqlist = argv[2]; 972 else 973 strcpy(fn, argv[2]); 974 } 975 if (d_opt) 976 { /* list of files (directory) */ 977 if (!(fp = fopen(rqlist, "r"))) 978 { 979 printf("Cannot open req list file\n"); 980 return -1; 981 } 982 while (fgets(fn, sizeof(fn), fp)) 983 { 984 strtok(fn, "\r\n"); 985 strcpy(rfn, fn); 986 printf("Processing: %s\n", rfn); 987 if (proc_file(rfn)) 988 { 989 printf(">>> Processing failed for: %s <<<\n", rfn); 990 EXIT(1); 991 } 992 } 993 fclose(fp); 994 } 995 else /* single file */ 996 { 997 printf("Processing: %s\n", fn); 998 if (proc_file(fn)) 999 { 1000 printf(">>> Processing failed for: %s <<<\n", fn); 1001 } 1002 } 1003 EXIT(0); 1004 return 0; 1005 } 1006