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