~ubuntu-branches/ubuntu/maverick/openssl/maverick

« back to all changes in this revision

Viewing changes to fips/aes/fips_aesavs.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Martin
  • Date: 2004-12-16 18:41:29 UTC
  • mto: (11.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20041216184129-z7xjkul57mh1jiha
Tags: upstream-0.9.7e
ImportĀ upstreamĀ versionĀ 0.9.7e

Show diffs side-by-side

added added

removed removed

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