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 DES Modes of Operation Validation System 51 Test Program 52 53 Based on the AES Validation Suite, which was: 54 Donated to OpenSSL by: 55 V-ONE Corporation 56 20250 Century Blvd, Suite 300 57 Germantown, MD 20874 58 U.S.A. 59 ----------------------------------------------*/ 60 61#include <stdio.h> 62#include <stdlib.h> 63#include <string.h> 64#include <errno.h> 65#include <assert.h> 66 67#include <openssl/des.h> 68#include <openssl/evp.h> 69#include <openssl/fips.h> 70#include <openssl/err.h> 71#include "e_os.h" 72 73/*#define AES_BLOCK_SIZE 16*/ 74 75#define VERBOSE 0 76 77/*-----------------------------------------------*/ 78 79int DESTest(EVP_CIPHER_CTX *ctx, 80 char *amode, int akeysz, unsigned char *aKey, 81 unsigned char *iVec, 82 int dir, /* 0 = decrypt, 1 = encrypt */ 83 unsigned char *out, unsigned char *in, int len) 84 { 85 const EVP_CIPHER *cipher = NULL; 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, "CFB64") == 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 (akeysz != 64 && akeysz != 192) 109 { 110 printf("Invalid key size: %d\n", akeysz); 111 EXIT(1); 112 } 113 else 114 { 115 kt += akeysz; 116 switch (kt) 117 { 118 case 1064: 119 cipher=EVP_des_cbc(); 120 break; 121 case 1192: 122 cipher=EVP_des_ede3_cbc(); 123 break; 124 case 2064: 125 cipher=EVP_des_ecb(); 126 break; 127 case 2192: 128 cipher=EVP_des_ede3_ecb(); 129 break; 130 case 3064: 131 cipher=EVP_des_cfb64(); 132 break; 133 case 3192: 134 cipher=EVP_des_ede3_cfb64(); 135 break; 136 case 4064: 137 cipher=EVP_des_ofb(); 138 break; 139 case 4192: 140 cipher=EVP_des_ede3_ofb(); 141 break; 142 case 5064: 143 cipher=EVP_des_cfb1(); 144 break; 145 case 5192: 146 cipher=EVP_des_ede3_cfb1(); 147 break; 148 case 6064: 149 cipher=EVP_des_cfb8(); 150 break; 151 case 6192: 152 cipher=EVP_des_ede3_cfb8(); 153 break; 154 default: 155 printf("Didn't handle mode %d\n",kt); 156 EXIT(1); 157 } 158 if(!EVP_CipherInit(ctx, cipher, aKey, iVec, dir)) 159 { 160 ERR_print_errors_fp(stderr); 161 EXIT(1); 162 } 163 EVP_Cipher(ctx, out, in, len); 164 } 165 return 1; 166 } 167 168/*-----------------------------------------------*/ 169 170int hex2bin(char *in, int len, unsigned char *out) 171 { 172 int n1, n2; 173 unsigned char ch; 174 175 for (n1 = 0, n2 = 0; n1 < len; ) 176 { /* first byte */ 177 if ((in[n1] >= '0') && (in[n1] <= '9')) 178 ch = in[n1++] - '0'; 179 else if ((in[n1] >= 'A') && (in[n1] <= 'F')) 180 ch = in[n1++] - 'A' + 10; 181 else if ((in[n1] >= 'a') && (in[n1] <= 'f')) 182 ch = in[n1++] - 'a' + 10; 183 else 184 return -1; 185 if(len == 1) 186 { 187 out[n2++]=ch; 188 break; 189 } 190 out[n2] = ch << 4; 191 /* second byte */ 192 if ((in[n1] >= '0') && (in[n1] <= '9')) 193 ch = in[n1++] - '0'; 194 else if ((in[n1] >= 'A') && (in[n1] <= 'F')) 195 ch = in[n1++] - 'A' + 10; 196 else if ((in[n1] >= 'a') && (in[n1] <= 'f')) 197 ch = in[n1++] - 'a' + 10; 198 else 199 return -1; 200 out[n2++] |= ch; 201 } 202 return n2; 203 } 204 205/*-----------------------------------------------*/ 206 207int bin2hex(unsigned char *in, int len, char *out) 208 { 209 int n1, n2; 210 unsigned char ch; 211 212 for (n1 = 0, n2 = 0; n1 < len; ++n1) 213 { 214 /* first nibble */ 215 ch = in[n1] >> 4; 216 if (ch <= 0x09) 217 out[n2++] = ch + '0'; 218 else 219 out[n2++] = ch - 10 + 'a'; 220 /* second nibble */ 221 ch = in[n1] & 0x0f; 222 if (ch <= 0x09) 223 out[n2++] = ch + '0'; 224 else 225 out[n2++] = ch - 10 + 'a'; 226 } 227 return n2; 228 } 229 230/* NB: this return the number of _bits_ read */ 231int bint2bin(const char *in, int len, unsigned char *out) 232 { 233 int n; 234 235 memset(out,0,len); 236 for(n=0 ; n < len ; ++n) 237 if(in[n] == '1') 238 out[n/8]|=(0x80 >> (n%8)); 239 return len; 240 } 241 242int bin2bint(const unsigned char *in,int len,char *out) 243 { 244 int n; 245 246 for(n=0 ; n < len ; ++n) 247 out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0'; 248 return n; 249 } 250 251/*-----------------------------------------------*/ 252 253void PrintValue(char *tag, unsigned char *val, int len) 254 { 255#if VERBOSE 256 char obuf[2048]; 257 int olen; 258 olen = bin2hex(val, len, obuf); 259 printf("%s = %.*s\n", tag, olen, obuf); 260#endif 261 } 262 263void DebugValue(char *tag, unsigned char *val, int len) 264 { 265 char obuf[2048]; 266 int olen; 267 olen = bin2hex(val, len, obuf); 268 printf("%s = %.*s\n", tag, olen, obuf); 269 } 270 271void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode) 272 { 273 char obuf[2048]; 274 int olen; 275 276 if(bitmode) 277 olen=bin2bint(val,len,obuf); 278 else 279 olen=bin2hex(val,len,obuf); 280 281 fprintf(rfp, "%s = %.*s\n", tag, olen, obuf); 282#if VERBOSE 283 printf("%s = %.*s\n", tag, olen, obuf); 284#endif 285 } 286 287void shiftin(unsigned char *dst,unsigned char *src,int nbits) 288 { 289 int n; 290 291 /* move the bytes... */ 292 memmove(dst,dst+nbits/8,3*8-nbits/8); 293 /* append new data */ 294 memcpy(dst+3*8-nbits/8,src,(nbits+7)/8); 295 /* left shift the bits */ 296 if(nbits%8) 297 for(n=0 ; n < 3*8 ; ++n) 298 dst[n]=(dst[n] << (nbits%8))|(dst[n+1] >> (8-nbits%8)); 299 } 300 301/*-----------------------------------------------*/ 302char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; 303char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB64"}; 304enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB64}; 305int Sizes[6]={64,64,64,1,8,64}; 306 307void do_mct(char *amode, 308 int akeysz, int numkeys, unsigned char *akey,unsigned char *ivec, 309 int dir, unsigned char *text, int len, 310 FILE *rfp) 311 { 312 int i,imode; 313 unsigned char nk[4*8]; /* longest key+8 */ 314 unsigned char text0[8]; 315 316 for (imode=0 ; imode < 6 ; ++imode) 317 if(!strcmp(amode,t_mode[imode])) 318 break; 319 if (imode == 6) 320 { 321 printf("Unrecognized mode: %s\n", amode); 322 EXIT(1); 323 } 324 325 for(i=0 ; i < 400 ; ++i) 326 { 327 int j; 328 int n; 329 EVP_CIPHER_CTX ctx; 330 int kp=akeysz/64; 331 unsigned char old_iv[8]; 332 333 fprintf(rfp,"\nCOUNT = %d\n",i); 334 if(kp == 1) 335 OutputValue("KEY",akey,8,rfp,0); 336 else 337 for(n=0 ; n < kp ; ++n) 338 { 339 fprintf(rfp,"KEY%d",n+1); 340 OutputValue("",akey+n*8,8,rfp,0); 341 } 342 343 if(imode != ECB) 344 OutputValue("IV",ivec,8,rfp,0); 345 OutputValue(t_tag[dir^1],text,len,rfp,imode == CFB1); 346 347 /* compensate for endianness */ 348 if(imode == CFB1) 349 text[0]<<=7; 350 351 memcpy(text0,text,8); 352 353 for(j=0 ; j < 10000 ; ++j) 354 { 355 unsigned char old_text[8]; 356 357 memcpy(old_text,text,8); 358 if(j == 0) 359 { 360 memcpy(old_iv,ivec,8); 361 DESTest(&ctx,amode,akeysz,akey,ivec,dir,text,text,len); 362 } 363 else 364 { 365 memcpy(old_iv,ctx.iv,8); 366 EVP_Cipher(&ctx,text,text,len); 367 } 368 if(j == 9999) 369 { 370 OutputValue(t_tag[dir],text,len,rfp,imode == CFB1); 371 /* memcpy(ivec,text,8); */ 372 } 373 /* DebugValue("iv",ctx.iv,8); */ 374 /* accumulate material for the next key */ 375 shiftin(nk,text,Sizes[imode]); 376 /* DebugValue("nk",nk,24);*/ 377 if((dir && (imode == CFB1 || imode == CFB8 || imode == CFB64 378 || imode == CBC)) || imode == OFB) 379 memcpy(text,old_iv,8); 380 381 if(!dir && (imode == CFB1 || imode == CFB8 || imode == CFB64)) 382 { 383 /* the test specifies using the output of the raw DES operation 384 which we don't have, so reconstruct it... */ 385 for(n=0 ; n < 8 ; ++n) 386 text[n]^=old_text[n]; 387 } 388 } 389 for(n=0 ; n < 8 ; ++n) 390 akey[n]^=nk[16+n]; 391 for(n=0 ; n < 8 ; ++n) 392 akey[8+n]^=nk[8+n]; 393 for(n=0 ; n < 8 ; ++n) 394 akey[16+n]^=nk[n]; 395 if(numkeys < 3) 396 memcpy(&akey[2*8],akey,8); 397 if(numkeys < 2) 398 memcpy(&akey[8],akey,8); 399 DES_set_odd_parity((DES_cblock *)akey); 400 DES_set_odd_parity((DES_cblock *)(akey+8)); 401 DES_set_odd_parity((DES_cblock *)(akey+16)); 402 memcpy(ivec,ctx.iv,8); 403 404 /* pointless exercise - the final text doesn't depend on the 405 initial text in OFB mode, so who cares what it is? (Who 406 designed these tests?) */ 407 if(imode == OFB) 408 for(n=0 ; n < 8 ; ++n) 409 text[n]=text0[n]^old_iv[n]; 410 } 411 } 412 413int proc_file(char *rqfile) 414 { 415 char afn[256], rfn[256]; 416 FILE *afp = NULL, *rfp = NULL; 417 char ibuf[2048]; 418 int ilen, len, ret = 0; 419 char amode[8] = ""; 420 char atest[100] = ""; 421 int akeysz=0; 422 unsigned char iVec[20], aKey[40]; 423 int dir = -1, err = 0, step = 0; 424 unsigned char plaintext[2048]; 425 unsigned char ciphertext[2048]; 426 char *rp; 427 EVP_CIPHER_CTX ctx; 428 int numkeys=1; 429 430 if (!rqfile || !(*rqfile)) 431 { 432 printf("No req file\n"); 433 return -1; 434 } 435 strcpy(afn, rqfile); 436 437 if ((afp = fopen(afn, "r")) == NULL) 438 { 439 printf("Cannot open file: %s, %s\n", 440 afn, strerror(errno)); 441 return -1; 442 } 443 strcpy(rfn,afn); 444 rp=strstr(rfn,"req/"); 445 assert(rp); 446 memcpy(rp,"rsp",3); 447 rp = strstr(rfn, ".req"); 448 memcpy(rp, ".rsp", 4); 449 if ((rfp = fopen(rfn, "w")) == NULL) 450 { 451 printf("Cannot open file: %s, %s\n", 452 rfn, strerror(errno)); 453 fclose(afp); 454 afp = NULL; 455 return -1; 456 } 457 while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) 458 { 459 ilen = strlen(ibuf); 460 /* printf("step=%d ibuf=%s",step,ibuf);*/ 461 if(step == 3 && !strcmp(amode,"ECB")) 462 { 463 memset(iVec, 0, sizeof(iVec)); 464 step = (dir)? 4: 5; /* no ivec for ECB */ 465 } 466 switch (step) 467 { 468 case 0: /* read preamble */ 469 if (ibuf[0] == '\n') 470 { /* end of preamble */ 471 if (*amode == '\0') 472 { 473 printf("Missing Mode\n"); 474 err = 1; 475 } 476 else 477 { 478 fputs(ibuf, rfp); 479 ++ step; 480 } 481 } 482 else if (ibuf[0] != '#') 483 { 484 printf("Invalid preamble item: %s\n", ibuf); 485 err = 1; 486 } 487 else 488 { /* process preamble */ 489 char *xp, *pp = ibuf+2; 490 int n; 491 if(*amode) 492 { /* insert current time & date */ 493 time_t rtim = time(0); 494 fprintf(rfp, "# %s", ctime(&rtim)); 495 } 496 else 497 { 498 fputs(ibuf, rfp); 499 if(!strncmp(pp,"INVERSE ",8) || !strncmp(pp,"DES ",4) 500 || !strncmp(pp,"TDES ",5) 501 || !strncmp(pp,"PERMUTATION ",12) 502 || !strncmp(pp,"SUBSTITUTION ",13) 503 || !strncmp(pp,"VARIABLE ",9)) 504 { 505 /* get test type */ 506 if(!strncmp(pp,"DES ",4)) 507 pp+=4; 508 else if(!strncmp(pp,"TDES ",5)) 509 pp+=5; 510 xp = strchr(pp, ' '); 511 n = xp-pp; 512 strncpy(atest, pp, n); 513 atest[n] = '\0'; 514 /* get mode */ 515 xp = strrchr(pp, ' '); /* get mode" */ 516 n = strlen(xp+1)-1; 517 strncpy(amode, xp+1, n); 518 amode[n] = '\0'; 519 /* amode[3] = '\0'; */ 520 printf("Test=%s, Mode=%s\n",atest,amode); 521 } 522 } 523 } 524 break; 525 526 case 1: /* [ENCRYPT] | [DECRYPT] */ 527 if(ibuf[0] == '\n') 528 break; 529 if (ibuf[0] == '[') 530 { 531 fputs(ibuf, rfp); 532 ++step; 533 if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) 534 dir = 1; 535 else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) 536 dir = 0; 537 else 538 { 539 printf("Invalid keyword: %s\n", ibuf); 540 err = 1; 541 } 542 break; 543 } 544 else if (dir == -1) 545 { 546 err = 1; 547 printf("Missing ENCRYPT/DECRYPT keyword\n"); 548 break; 549 } 550 else 551 step = 2; 552 553 case 2: /* KEY = xxxx */ 554 if(*ibuf == '\n') 555 { 556 fputs(ibuf, rfp); 557 break; 558 } 559 if(!strncasecmp(ibuf,"COUNT = ",8)) 560 { 561 fputs(ibuf, rfp); 562 break; 563 } 564 if(!strncasecmp(ibuf,"COUNT=",6)) 565 { 566 fputs(ibuf, rfp); 567 break; 568 } 569 if(!strncasecmp(ibuf,"NumKeys = ",10)) 570 { 571 numkeys=atoi(ibuf+10); 572 break; 573 } 574 575 fputs(ibuf, rfp); 576 if(!strncasecmp(ibuf,"KEY = ",6)) 577 { 578 akeysz=64; 579 len = hex2bin((char*)ibuf+6, strlen(ibuf+6)-1, aKey); 580 if (len < 0) 581 { 582 printf("Invalid KEY\n"); 583 err=1; 584 break; 585 } 586 PrintValue("KEY", aKey, len); 587 ++step; 588 } 589 else if(!strncasecmp(ibuf,"KEYs = ",7)) 590 { 591 akeysz=64*3; 592 len=hex2bin(ibuf+7,strlen(ibuf+7)-1,aKey); 593 if(len != 8) 594 { 595 printf("Invalid KEY\n"); 596 err=1; 597 break; 598 } 599 memcpy(aKey+8,aKey,8); 600 memcpy(aKey+16,aKey,8); 601 ibuf[4]='\0'; 602 PrintValue("KEYs",aKey,len); 603 ++step; 604 } 605 else if(!strncasecmp(ibuf,"KEY",3)) 606 { 607 int n=ibuf[3]-'1'; 608 609 akeysz=64*3; 610 len=hex2bin(ibuf+7,strlen(ibuf+7)-1,aKey+n*8); 611 if(len != 8) 612 { 613 printf("Invalid KEY\n"); 614 err=1; 615 break; 616 } 617 ibuf[4]='\0'; 618 PrintValue(ibuf,aKey,len); 619 if(n == 2) 620 ++step; 621 } 622 else 623 { 624 printf("Missing KEY\n"); 625 err = 1; 626 } 627 break; 628 629 case 3: /* IV = xxxx */ 630 fputs(ibuf, rfp); 631 if (strncasecmp(ibuf, "IV = ", 5) != 0) 632 { 633 printf("Missing IV\n"); 634 err = 1; 635 } 636 else 637 { 638 len = hex2bin((char*)ibuf+5, strlen(ibuf+5)-1, iVec); 639 if (len < 0) 640 { 641 printf("Invalid IV\n"); 642 err =1; 643 break; 644 } 645 PrintValue("IV", iVec, len); 646 step = (dir)? 4: 5; 647 } 648 break; 649 650 case 4: /* PLAINTEXT = xxxx */ 651 fputs(ibuf, rfp); 652 if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) 653 { 654 printf("Missing PLAINTEXT\n"); 655 err = 1; 656 } 657 else 658 { 659 int nn = strlen(ibuf+12); 660 if(!strcmp(amode,"CFB1")) 661 len=bint2bin(ibuf+12,nn-1,plaintext); 662 else 663 len=hex2bin(ibuf+12, nn-1,plaintext); 664 if (len < 0) 665 { 666 printf("Invalid PLAINTEXT: %s", ibuf+12); 667 err =1; 668 break; 669 } 670 if (len >= sizeof(plaintext)) 671 { 672 printf("Buffer overflow\n"); 673 } 674 PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); 675 if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ 676 { 677 do_mct(amode,akeysz,numkeys,aKey,iVec,dir,plaintext,len,rfp); 678 } 679 else 680 { 681 assert(dir == 1); 682 ret = DESTest(&ctx, amode, akeysz, aKey, iVec, 683 dir, /* 0 = decrypt, 1 = encrypt */ 684 ciphertext, plaintext, len); 685 OutputValue("CIPHERTEXT",ciphertext,len,rfp, 686 !strcmp(amode,"CFB1")); 687 } 688 step = 6; 689 } 690 break; 691 692 case 5: /* CIPHERTEXT = xxxx */ 693 fputs(ibuf, rfp); 694 if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) 695 { 696 printf("Missing KEY\n"); 697 err = 1; 698 } 699 else 700 { 701 if(!strcmp(amode,"CFB1")) 702 len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); 703 else 704 len = hex2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); 705 if (len < 0) 706 { 707 printf("Invalid CIPHERTEXT\n"); 708 err =1; 709 break; 710 } 711 712 PrintValue("CIPHERTEXT", ciphertext, len); 713 if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ 714 { 715 do_mct(amode, akeysz, numkeys, aKey, iVec, 716 dir, ciphertext, len, rfp); 717 } 718 else 719 { 720 assert(dir == 0); 721 ret = DESTest(&ctx, amode, akeysz, aKey, iVec, 722 dir, /* 0 = decrypt, 1 = encrypt */ 723 plaintext, ciphertext, len); 724 OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, 725 !strcmp(amode,"CFB1")); 726 } 727 step = 6; 728 } 729 break; 730 731 case 6: 732 if (ibuf[0] != '\n') 733 { 734 err = 1; 735 printf("Missing terminator\n"); 736 } 737 else if (strcmp(atest, "MCT") != 0) 738 { /* MCT already added terminating nl */ 739 fputs(ibuf, rfp); 740 } 741 step = 1; 742 break; 743 } 744 } 745 if (rfp) 746 fclose(rfp); 747 if (afp) 748 fclose(afp); 749 return err; 750 } 751 752/*-------------------------------------------------- 753 Processes either a single file or 754 a set of files whose names are passed in a file. 755 A single file is specified as: 756 aes_test -f xxx.req 757 A set of files is specified as: 758 aes_test -d xxxxx.xxx 759 The default is: -d req.txt 760--------------------------------------------------*/ 761int main(int argc, char **argv) 762 { 763 char *rqlist = "req.txt"; 764 FILE *fp = NULL; 765 char fn[250] = "", rfn[256] = ""; 766 int f_opt = 0, d_opt = 1; 767 768#ifdef OPENSSL_FIPS 769 if(!FIPS_mode_set(1,argv[0])) 770 { 771 ERR_load_crypto_strings(); 772 ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); 773 EXIT(1); 774 } 775#endif 776 ERR_load_crypto_strings(); 777 if (argc > 1) 778 { 779 if (strcasecmp(argv[1], "-d") == 0) 780 { 781 d_opt = 1; 782 } 783 else if (strcasecmp(argv[1], "-f") == 0) 784 { 785 f_opt = 1; 786 d_opt = 0; 787 } 788 else 789 { 790 printf("Invalid parameter: %s\n", argv[1]); 791 return 0; 792 } 793 if (argc < 3) 794 { 795 printf("Missing parameter\n"); 796 return 0; 797 } 798 if (d_opt) 799 rqlist = argv[2]; 800 else 801 strcpy(fn, argv[2]); 802 } 803 if (d_opt) 804 { /* list of files (directory) */ 805 if (!(fp = fopen(rqlist, "r"))) 806 { 807 printf("Cannot open req list file\n"); 808 return -1; 809 } 810 while (fgets(fn, sizeof(fn), fp)) 811 { 812 strtok(fn, "\r\n"); 813 strcpy(rfn, fn); 814 printf("Processing: %s\n", rfn); 815 if (proc_file(rfn)) 816 { 817 printf(">>> Processing failed for: %s <<<\n", rfn); 818 EXIT(1); 819 } 820 } 821 fclose(fp); 822 } 823 else /* single file */ 824 { 825 printf("Processing: %s\n", fn); 826 if (proc_file(fn)) 827 { 828 printf(">>> Processing failed for: %s <<<\n", fn); 829 } 830 } 831 EXIT(0); 832 return 0; 833 } 834