Add our readmes.
[dragonfly.git] / crypto / openssl-0.9.7e / fips / des / fips_desmovs.c
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
79 int 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
170 int 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
207 int 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 */
231 int 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
242 int 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
253 void 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
263 void 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
271 void 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
287 void 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 /*-----------------------------------------------*/
302 char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"};
303 char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB64"};
304 enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB64};
305 int Sizes[6]={64,64,64,1,8,64};
306
307 void 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     
413 int 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 --------------------------------------------------*/
761 int 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     return 0;
832     }