| OLD | NEW |
| (Empty) |
| 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 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 /*-----------------------------------------------*/ | |
| 226 char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; | |
| 227 char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"}; | |
| 228 enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128}; | |
| 229 enum 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 | |
| 241 static 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 | |
| 549 static 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 --------------------------------------------------*/ | |
| 862 int 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 | |
| OLD | NEW |