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