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