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