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