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
78int 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
204int 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
241int 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 */
265int 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
276int 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
287void 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
297void 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/*-----------------------------------------------*/
314char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"};
315char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"};
316enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128};
317enum 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
329int 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
634int 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--------------------------------------------------*/
934int 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    EXIT(0);
1004    return 0;
1005    }
1006