]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/openssl/fips/aes/fips_aesavs.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / openssl / fips / aes / fips_aesavs.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 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 #include <ctype.h>
66 #include <openssl/aes.h>
67 #include <openssl/evp.h>
68 #include <openssl/bn.h>
69
70 #include <openssl/err.h>
71 #include "e_os.h"
72
73 #ifndef OPENSSL_FIPS
74
75 int main(int argc, char *argv[])
76 {
77     printf("No FIPS AES support\n");
78     return(0);
79 }
80
81 #else
82
83 #include <openssl/fips.h>
84 #include "fips_utl.h"
85
86 #define AES_BLOCK_SIZE 16
87
88 #define VERBOSE 0
89
90 /*-----------------------------------------------*/
91
92 static int AESTest(EVP_CIPHER_CTX *ctx,
93             char *amode, int akeysz, unsigned char *aKey, 
94             unsigned char *iVec, 
95             int dir,  /* 0 = decrypt, 1 = encrypt */
96             unsigned char *plaintext, unsigned char *ciphertext, int len)
97     {
98     const EVP_CIPHER *cipher = NULL;
99
100     if (strcasecmp(amode, "CBC") == 0)
101         {
102         switch (akeysz)
103                 {
104                 case 128:
105                 cipher = EVP_aes_128_cbc();
106                 break;
107
108                 case 192:
109                 cipher = EVP_aes_192_cbc();
110                 break;
111
112                 case 256:
113                 cipher = EVP_aes_256_cbc();
114                 break;
115                 }
116
117         }
118     else if (strcasecmp(amode, "ECB") == 0)
119         {
120         switch (akeysz)
121                 {
122                 case 128:
123                 cipher = EVP_aes_128_ecb();
124                 break;
125
126                 case 192:
127                 cipher = EVP_aes_192_ecb();
128                 break;
129
130                 case 256:
131                 cipher = EVP_aes_256_ecb();
132                 break;
133                 }
134         }
135     else if (strcasecmp(amode, "CFB128") == 0)
136         {
137         switch (akeysz)
138                 {
139                 case 128:
140                 cipher = EVP_aes_128_cfb128();
141                 break;
142
143                 case 192:
144                 cipher = EVP_aes_192_cfb128();
145                 break;
146
147                 case 256:
148                 cipher = EVP_aes_256_cfb128();
149                 break;
150                 }
151
152         }
153     else if (strncasecmp(amode, "OFB", 3) == 0)
154         {
155         switch (akeysz)
156                 {
157                 case 128:
158                 cipher = EVP_aes_128_ofb();
159                 break;
160
161                 case 192:
162                 cipher = EVP_aes_192_ofb();
163                 break;
164
165                 case 256:
166                 cipher = EVP_aes_256_ofb();
167                 break;
168                 }
169         }
170     else if(!strcasecmp(amode,"CFB1"))
171         {
172         switch (akeysz)
173                 {
174                 case 128:
175                 cipher = EVP_aes_128_cfb1();
176                 break;
177
178                 case 192:
179                 cipher = EVP_aes_192_cfb1();
180                 break;
181
182                 case 256:
183                 cipher = EVP_aes_256_cfb1();
184                 break;
185                 }
186         }
187     else if(!strcasecmp(amode,"CFB8"))
188         {
189         switch (akeysz)
190                 {
191                 case 128:
192                 cipher = EVP_aes_128_cfb8();
193                 break;
194
195                 case 192:
196                 cipher = EVP_aes_192_cfb8();
197                 break;
198
199                 case 256:
200                 cipher = EVP_aes_256_cfb8();
201                 break;
202                 }
203         }
204     else
205         {
206         printf("Unknown mode: %s\n", amode);
207         return 0;
208         }
209     if (!cipher)
210         {
211         printf("Invalid key size: %d\n", akeysz);
212         return 0; 
213         }
214     if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
215         return 0;
216     if(!strcasecmp(amode,"CFB1"))
217         M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
218     if (dir)
219                 EVP_Cipher(ctx, ciphertext, plaintext, len);
220         else
221                 EVP_Cipher(ctx, plaintext, ciphertext, len);
222     return 1;
223     }
224
225 /*-----------------------------------------------*/
226 char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"};
227 char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"};
228 enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128};
229 enum XCrypt {XDECRYPT, XENCRYPT};
230
231 /*=============================*/
232 /*  Monte Carlo Tests          */
233 /*-----------------------------*/
234
235 /*#define gb(a,b) (((a)[(b)/8] >> ((b)%8))&1)*/
236 /*#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << ((b)%8)))|(!!(v) << ((b)%8)))*/
237
238 #define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1)
239 #define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8)))
240
241 static int do_mct(char *amode, 
242            int akeysz, unsigned char *aKey,unsigned char *iVec,
243            int dir, unsigned char *text, int len,
244            FILE *rfp)
245     {
246     int ret = 0;
247     unsigned char key[101][32];
248     unsigned char iv[101][AES_BLOCK_SIZE];
249     unsigned char ptext[1001][32];
250     unsigned char ctext[1001][32];
251     unsigned char ciphertext[64+4];
252     int i, j, n, n1, n2;
253     int imode = 0, nkeysz = akeysz/8;
254     EVP_CIPHER_CTX ctx;
255     EVP_CIPHER_CTX_init(&ctx);
256
257     if (len > 32)
258         {
259         printf("\n>>>> Length exceeds 32 for %s %d <<<<\n\n", 
260                amode, akeysz);
261         return -1;
262         }
263     for (imode = 0; imode < 6; ++imode)
264         if (strcmp(amode, t_mode[imode]) == 0)
265             break;
266     if (imode == 6)
267         { 
268         printf("Unrecognized mode: %s\n", amode);
269         return -1;
270         }
271
272     memcpy(key[0], aKey, nkeysz);
273     if (iVec)
274         memcpy(iv[0], iVec, AES_BLOCK_SIZE);
275     if (dir == XENCRYPT)
276         memcpy(ptext[0], text, len);
277     else
278         memcpy(ctext[0], text, len);
279     for (i = 0; i < 100; ++i)
280         {
281         /* printf("Iteration %d\n", i); */
282         if (i > 0)
283             {
284             fprintf(rfp,"COUNT = %d\n",i);
285             OutputValue("KEY",key[i],nkeysz,rfp,0);
286             if (imode != ECB)  /* ECB */
287                 OutputValue("IV",iv[i],AES_BLOCK_SIZE,rfp,0);
288             /* Output Ciphertext | Plaintext */
289             OutputValue(t_tag[dir^1],dir ? ptext[0] : ctext[0],len,rfp,
290                         imode == CFB1);
291             }
292         for (j = 0; j < 1000; ++j)
293             {
294             switch (imode)
295                 {
296             case ECB:
297                 if (j == 0)
298                     { /* set up encryption */
299                     ret = AESTest(&ctx, amode, akeysz, key[i], NULL, 
300                                   dir,  /* 0 = decrypt, 1 = encrypt */
301                                   ptext[j], ctext[j], len);
302                     if (dir == XENCRYPT)
303                         memcpy(ptext[j+1], ctext[j], len);
304                     else
305                         memcpy(ctext[j+1], ptext[j], len);
306                     }
307                 else
308                     {
309                     if (dir == XENCRYPT)
310                         {
311                         EVP_Cipher(&ctx, ctext[j], ptext[j], len);
312                         memcpy(ptext[j+1], ctext[j], len);
313                         }
314                     else
315                         {
316                         EVP_Cipher(&ctx, ptext[j], ctext[j], len);
317                         memcpy(ctext[j+1], ptext[j], len);
318                         }
319                     }
320                 break;
321
322             case CBC:
323             case OFB:  
324             case CFB128:
325                 if (j == 0)
326                     {
327                     ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], 
328                                   dir,  /* 0 = decrypt, 1 = encrypt */
329                                   ptext[j], ctext[j], len);
330                     if (dir == XENCRYPT)
331                         memcpy(ptext[j+1], iv[i], len);
332                     else
333                         memcpy(ctext[j+1], iv[i], len);
334                     }
335                 else
336                     {
337                     if (dir == XENCRYPT)
338                         {
339                         EVP_Cipher(&ctx, ctext[j], ptext[j], len);
340                         memcpy(ptext[j+1], ctext[j-1], len);
341                         }
342                     else
343                         {
344                         EVP_Cipher(&ctx, ptext[j], ctext[j], len);
345                         memcpy(ctext[j+1], ptext[j-1], len);
346                         }
347                     }
348                 break;
349
350             case CFB8:
351                 if (j == 0)
352                     {
353                     ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], 
354                                   dir,  /* 0 = decrypt, 1 = encrypt */
355                                   ptext[j], ctext[j], len);
356                     }
357                 else
358                     {
359                     if (dir == XENCRYPT)
360                         EVP_Cipher(&ctx, ctext[j], ptext[j], len);
361                     else
362                         EVP_Cipher(&ctx, ptext[j], ctext[j], len);
363                     }
364                 if (dir == XENCRYPT)
365                     {
366                     if (j < 16)
367                         memcpy(ptext[j+1], &iv[i][j], len);
368                     else
369                         memcpy(ptext[j+1], ctext[j-16], len);
370                     }
371                 else
372                     {
373                     if (j < 16)
374                         memcpy(ctext[j+1], &iv[i][j], len);
375                     else
376                         memcpy(ctext[j+1], ptext[j-16], len);
377                     }
378                 break;
379
380             case CFB1:
381                 if(j == 0)
382                     {
383 #if 0
384                     /* compensate for wrong endianness of input file */
385                     if(i == 0)
386                         ptext[0][0]<<=7;
387 #endif
388                     ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir,
389                                 ptext[j], ctext[j], len);
390                     }
391                 else
392                     {
393                     if (dir == XENCRYPT)
394                         EVP_Cipher(&ctx, ctext[j], ptext[j], len);
395                     else
396                         EVP_Cipher(&ctx, ptext[j], ctext[j], len);
397
398                     }
399                 if(dir == XENCRYPT)
400                     {
401                     if(j < 128)
402                         sb(ptext[j+1],0,gb(iv[i],j));
403                     else
404                         sb(ptext[j+1],0,gb(ctext[j-128],0));
405                     }
406                 else
407                     {
408                     if(j < 128)
409                         sb(ctext[j+1],0,gb(iv[i],j));
410                     else
411                         sb(ctext[j+1],0,gb(ptext[j-128],0));
412                     }
413                 break;
414                 }
415             }
416         --j; /* reset to last of range */
417         /* Output Ciphertext | Plaintext */
418         OutputValue(t_tag[dir],dir ? ctext[j] : ptext[j],len,rfp,
419                     imode == CFB1);
420         fprintf(rfp, "\n");  /* add separator */
421
422         /* Compute next KEY */
423         if (dir == XENCRYPT)
424             {
425             if (imode == CFB8)
426                 { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */
427                 for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2)
428                     ciphertext[n1] = ctext[j-n2][0];
429                 }
430             else if(imode == CFB1)
431                 {
432                 for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2)
433                     sb(ciphertext,n1,gb(ctext[j-n2],0));
434                 }
435             else
436                 switch (akeysz)
437                     {
438                 case 128:
439                     memcpy(ciphertext, ctext[j], 16);
440                     break;
441                 case 192:
442                     memcpy(ciphertext, ctext[j-1]+8, 8);
443                     memcpy(ciphertext+8, ctext[j], 16);
444                     break;
445                 case 256:
446                     memcpy(ciphertext, ctext[j-1], 16);
447                     memcpy(ciphertext+16, ctext[j], 16);
448                     break;
449                     }
450             }
451         else
452             {
453             if (imode == CFB8)
454                 { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */
455                 for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2)
456                     ciphertext[n1] = ptext[j-n2][0];
457                 }
458             else if(imode == CFB1)
459                 {
460                 for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2)
461                     sb(ciphertext,n1,gb(ptext[j-n2],0));
462                 }
463             else
464                 switch (akeysz)
465                     {
466                 case 128:
467                     memcpy(ciphertext, ptext[j], 16);
468                     break;
469                 case 192:
470                     memcpy(ciphertext, ptext[j-1]+8, 8);
471                     memcpy(ciphertext+8, ptext[j], 16);
472                     break;
473                 case 256:
474                     memcpy(ciphertext, ptext[j-1], 16);
475                     memcpy(ciphertext+16, ptext[j], 16);
476                     break;
477                     }
478             }
479         /* Compute next key: Key[i+1] = Key[i] xor ct */
480         for (n = 0; n < nkeysz; ++n)
481             key[i+1][n] = key[i][n] ^ ciphertext[n];
482         
483         /* Compute next IV and text */
484         if (dir == XENCRYPT)
485             {
486             switch (imode)
487                 {
488             case ECB:
489                 memcpy(ptext[0], ctext[j], AES_BLOCK_SIZE);
490                 break;
491             case CBC:
492             case OFB:
493             case CFB128:
494                 memcpy(iv[i+1], ctext[j], AES_BLOCK_SIZE);
495                 memcpy(ptext[0], ctext[j-1], AES_BLOCK_SIZE);
496                 break;
497             case CFB8:
498                 /* IV[i+1] = ct */
499                 for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2)
500                     iv[i+1][n1] = ctext[j-n2][0];
501                 ptext[0][0] = ctext[j-16][0];
502                 break;
503             case CFB1:
504                 for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2)
505                     sb(iv[i+1],n1,gb(ctext[j-n2],0));
506                 ptext[0][0]=ctext[j-128][0]&0x80;
507                 break;
508                 }
509             }
510         else
511             {
512             switch (imode)
513                 {
514             case ECB:
515                 memcpy(ctext[0], ptext[j], AES_BLOCK_SIZE);
516                 break;
517             case CBC:
518             case OFB:
519             case CFB128:
520                 memcpy(iv[i+1], ptext[j], AES_BLOCK_SIZE);
521                 memcpy(ctext[0], ptext[j-1], AES_BLOCK_SIZE);
522                 break;
523             case CFB8:
524                 for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2)
525                     iv[i+1][n1] = ptext[j-n2][0];
526                 ctext[0][0] = ptext[j-16][0];
527                 break;
528             case CFB1:
529                 for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2)
530                     sb(iv[i+1],n1,gb(ptext[j-n2],0));
531                 ctext[0][0]=ptext[j-128][0]&0x80;
532                 break;
533                 }
534             }
535         }
536     
537     return ret;
538     }
539
540 /*================================================*/
541 /*----------------------------
542   # Config info for v-one
543   # AESVS MMT test data for ECB
544   # State : Encrypt and Decrypt
545   # Key Length : 256
546   # Fri Aug 30 04:07:22 PM
547   ----------------------------*/
548
549 static int proc_file(char *rqfile, char *rspfile)
550     {
551     char afn[256], rfn[256];
552     FILE *afp = NULL, *rfp = NULL;
553     char ibuf[2048];
554     char tbuf[2048];
555     int ilen, len, ret = 0;
556     char algo[8] = "";
557     char amode[8] = "";
558     char atest[8] = "";
559     int akeysz = 0;
560     unsigned char iVec[20], aKey[40];
561     int dir = -1, err = 0, step = 0;
562     unsigned char plaintext[2048];
563     unsigned char ciphertext[2048];
564     char *rp;
565     EVP_CIPHER_CTX ctx;
566     EVP_CIPHER_CTX_init(&ctx);
567
568     if (!rqfile || !(*rqfile))
569         {
570         printf("No req file\n");
571         return -1;
572         }
573     strcpy(afn, rqfile);
574
575     if ((afp = fopen(afn, "r")) == NULL)
576         {
577         printf("Cannot open file: %s, %s\n", 
578                afn, strerror(errno));
579         return -1;
580         }
581     if (!rspfile)
582         {
583         strcpy(rfn,afn);
584         rp=strstr(rfn,"req/");
585 #ifdef OPENSSL_SYS_WIN32
586         if (!rp)
587             rp=strstr(rfn,"req\\");
588 #endif
589         assert(rp);
590         memcpy(rp,"rsp",3);
591         rp = strstr(rfn, ".req");
592         memcpy(rp, ".rsp", 4);
593         rspfile = rfn;
594         }
595     if ((rfp = fopen(rspfile, "w")) == NULL)
596         {
597         printf("Cannot open file: %s, %s\n", 
598                rfn, strerror(errno));
599         fclose(afp);
600         afp = NULL;
601         return -1;
602         }
603     while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL)
604         {
605         tidy_line(tbuf, ibuf);
606         ilen = strlen(ibuf);
607         /*      printf("step=%d ibuf=%s",step,ibuf); */
608         switch (step)
609             {
610         case 0:  /* read preamble */
611             if (ibuf[0] == '\n')
612                 { /* end of preamble */
613                 if ((*algo == '\0') ||
614                     (*amode == '\0') ||
615                     (akeysz == 0))
616                     {
617                     printf("Missing Algorithm, Mode or KeySize (%s/%s/%d)\n",
618                            algo,amode,akeysz);
619                     err = 1;
620                     }
621                 else
622                     {
623                     fputs(ibuf, rfp);
624                     ++ step;
625                     }
626                 }
627             else if (ibuf[0] != '#')
628                 {
629                 printf("Invalid preamble item: %s\n", ibuf);
630                 err = 1;
631                 }
632             else
633                 { /* process preamble */
634                 char *xp, *pp = ibuf+2;
635                 int n;
636                 if (akeysz)
637                     { /* insert current time & date */
638                     time_t rtim = time(0);
639                     fprintf(rfp, "# %s", ctime(&rtim));
640                     }
641                 else
642                     {
643                     fputs(ibuf, rfp);
644                     if (strncmp(pp, "AESVS ", 6) == 0)
645                         {
646                         strcpy(algo, "AES");
647                         /* get test type */
648                         pp += 6;
649                         xp = strchr(pp, ' ');
650                         n = xp-pp;
651                         strncpy(atest, pp, n);
652                         atest[n] = '\0';
653                         /* get mode */
654                         xp = strrchr(pp, ' '); /* get mode" */
655                         n = strlen(xp+1)-1;
656                         strncpy(amode, xp+1, n);
657                         amode[n] = '\0';
658                         /* amode[3] = '\0'; */
659                         if (VERBOSE)
660                                 printf("Test = %s, Mode = %s\n", atest, amode);
661                         }
662                     else if (strncasecmp(pp, "Key Length : ", 13) == 0)
663                         {
664                         akeysz = atoi(pp+13);
665                         if (VERBOSE)
666                                 printf("Key size = %d\n", akeysz);
667                         }
668                     }
669                 }
670             break;
671
672         case 1:  /* [ENCRYPT] | [DECRYPT] */
673             if (ibuf[0] == '[')
674                 {
675                 fputs(ibuf, rfp);
676                 ++step;
677                 if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0)
678                     dir = 1;
679                 else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0)
680                     dir = 0;
681                 else
682                     {
683                     printf("Invalid keyword: %s\n", ibuf);
684                     err = 1;
685                     }
686                 break;
687                 }
688             else if (dir == -1)
689                 {
690                 err = 1;
691                 printf("Missing ENCRYPT/DECRYPT keyword\n");
692                 break;
693                 }
694             else 
695                 step = 2;
696
697         case 2: /* KEY = xxxx */
698             fputs(ibuf, rfp);
699             if(*ibuf == '\n')
700                 break;
701             if(!strncasecmp(ibuf,"COUNT = ",8))
702                 break;
703
704             if (strncasecmp(ibuf, "KEY = ", 6) != 0)
705                 {
706                 printf("Missing KEY\n");
707                 err = 1;
708                 }
709             else
710                 {
711                 len = hex2bin((char*)ibuf+6, aKey);
712                 if (len < 0)
713                     {
714                     printf("Invalid KEY\n");
715                     err =1;
716                     break;
717                     }
718                 PrintValue("KEY", aKey, len);
719                 if (strcmp(amode, "ECB") == 0)
720                     {
721                     memset(iVec, 0, sizeof(iVec));
722                     step = (dir)? 4: 5;  /* no ivec for ECB */
723                     }
724                 else
725                     ++step;
726                 }
727             break;
728
729         case 3: /* IV = xxxx */
730             fputs(ibuf, rfp);
731             if (strncasecmp(ibuf, "IV = ", 5) != 0)
732                 {
733                 printf("Missing IV\n");
734                 err = 1;
735                 }
736             else
737                 {
738                 len = hex2bin((char*)ibuf+5, iVec);
739                 if (len < 0)
740                     {
741                     printf("Invalid IV\n");
742                     err =1;
743                     break;
744                     }
745                 PrintValue("IV", iVec, len);
746                 step = (dir)? 4: 5;
747                 }
748             break;
749
750         case 4: /* PLAINTEXT = xxxx */
751             fputs(ibuf, rfp);
752             if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0)
753                 {
754                 printf("Missing PLAINTEXT\n");
755                 err = 1;
756                 }
757             else
758                 {
759                 int nn = strlen(ibuf+12);
760                 if(!strcmp(amode,"CFB1"))
761                     len=bint2bin(ibuf+12,nn-1,plaintext);
762                 else
763                     len=hex2bin(ibuf+12, plaintext);
764                 if (len < 0)
765                     {
766                     printf("Invalid PLAINTEXT: %s", ibuf+12);
767                     err =1;
768                     break;
769                     }
770                 if (len >= (int)sizeof(plaintext))
771                     {
772                     printf("Buffer overflow\n");
773                     }
774                 PrintValue("PLAINTEXT", (unsigned char*)plaintext, len);
775                 if (strcmp(atest, "MCT") == 0)  /* Monte Carlo Test */
776                     {
777                     if(do_mct(amode, akeysz, aKey, iVec, 
778                               dir, (unsigned char*)plaintext, len, 
779                               rfp) < 0)
780                         EXIT(1);
781                     }
782                 else
783                     {
784                     ret = AESTest(&ctx, amode, akeysz, aKey, iVec, 
785                                   dir,  /* 0 = decrypt, 1 = encrypt */
786                                   plaintext, ciphertext, len);
787                     OutputValue("CIPHERTEXT",ciphertext,len,rfp,
788                                 !strcmp(amode,"CFB1"));
789                     }
790                 step = 6;
791                 }
792             break;
793
794         case 5: /* CIPHERTEXT = xxxx */
795             fputs(ibuf, rfp);
796             if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0)
797                 {
798                 printf("Missing KEY\n");
799                 err = 1;
800                 }
801             else
802                 {
803                 if(!strcmp(amode,"CFB1"))
804                     len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext);
805                 else
806                     len = hex2bin(ibuf+13,ciphertext);
807                 if (len < 0)
808                     {
809                     printf("Invalid CIPHERTEXT\n");
810                     err =1;
811                     break;
812                     }
813
814                 PrintValue("CIPHERTEXT", ciphertext, len);
815                 if (strcmp(atest, "MCT") == 0)  /* Monte Carlo Test */
816                     {
817                     do_mct(amode, akeysz, aKey, iVec, 
818                            dir, ciphertext, len, rfp);
819                     }
820                 else
821                     {
822                     ret = AESTest(&ctx, amode, akeysz, aKey, iVec, 
823                                   dir,  /* 0 = decrypt, 1 = encrypt */
824                                   plaintext, ciphertext, len);
825                     OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp,
826                                 !strcmp(amode,"CFB1"));
827                     }
828                 step = 6;
829                 }
830             break;
831
832         case 6:
833             if (ibuf[0] != '\n')
834                 {
835                 err = 1;
836                 printf("Missing terminator\n");
837                 }
838             else if (strcmp(atest, "MCT") != 0)
839                 { /* MCT already added terminating nl */
840                 fputs(ibuf, rfp);
841                 }
842             step = 1;
843             break;
844             }
845         }
846     if (rfp)
847         fclose(rfp);
848     if (afp)
849         fclose(afp);
850     return err;
851     }
852
853 /*--------------------------------------------------
854   Processes either a single file or 
855   a set of files whose names are passed in a file.
856   A single file is specified as:
857     aes_test -f xxx.req
858   A set of files is specified as:
859     aes_test -d xxxxx.xxx
860   The default is: -d req.txt
861 --------------------------------------------------*/
862 int main(int argc, char **argv)
863     {
864     char *rqlist = "req.txt", *rspfile = NULL;
865     FILE *fp = NULL;
866     char fn[250] = "", rfn[256] = "";
867     int f_opt = 0, d_opt = 1;
868
869 #ifdef OPENSSL_FIPS
870     if(!FIPS_mode_set(1))
871         {
872         do_print_errors();
873         EXIT(1);
874         }
875 #endif
876     if (argc > 1)
877         {
878         if (strcasecmp(argv[1], "-d") == 0)
879             {
880             d_opt = 1;
881             }
882         else if (strcasecmp(argv[1], "-f") == 0)
883             {
884             f_opt = 1;
885             d_opt = 0;
886             }
887         else
888             {
889             printf("Invalid parameter: %s\n", argv[1]);
890             return 0;
891             }
892         if (argc < 3)
893             {
894             printf("Missing parameter\n");
895             return 0;
896             }
897         if (d_opt)
898             rqlist = argv[2];
899         else
900             {
901             strcpy(fn, argv[2]);
902             rspfile = argv[3];
903             }
904         }
905     if (d_opt)
906         { /* list of files (directory) */
907         if (!(fp = fopen(rqlist, "r")))
908             {
909             printf("Cannot open req list file\n");
910             return -1;
911             }
912         while (fgets(fn, sizeof(fn), fp))
913             {
914             strtok(fn, "\r\n");
915             strcpy(rfn, fn);
916             if (VERBOSE)
917                 printf("Processing: %s\n", rfn);
918             if (proc_file(rfn, rspfile))
919                 {
920                 printf(">>> Processing failed for: %s <<<\n", rfn);
921                 EXIT(1);
922                 }
923             }
924         fclose(fp);
925         }
926     else /* single file */
927         {
928         if (VERBOSE)
929             printf("Processing: %s\n", fn);
930         if (proc_file(fn, rspfile))
931             {
932             printf(">>> Processing failed for: %s <<<\n", fn);
933             }
934         }
935     EXIT(0);
936     return 0;
937     }
938
939 #endif