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