1/* Written by Ben Laurie, 2001 */ 2/* 3 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * openssl-core@openssl.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 */ 49 50#include <stdio.h> 51#include <string.h> 52 53#include "../e_os.h" 54 55#include <openssl/opensslconf.h> 56#include <openssl/evp.h> 57#ifndef OPENSSL_NO_ENGINE 58# include <openssl/engine.h> 59#endif 60#include <openssl/err.h> 61#include <openssl/conf.h> 62 63static void hexdump(FILE *f, const char *title, const unsigned char *s, int l) 64{ 65 int n = 0; 66 67 fprintf(f, "%s", title); 68 for (; n < l; ++n) { 69 if ((n % 16) == 0) 70 fprintf(f, "\n%04x", n); 71 fprintf(f, " %02x", s[n]); 72 } 73 fprintf(f, "\n"); 74} 75 76static int convert(unsigned char *s) 77{ 78 unsigned char *d; 79 80 for (d = s; *s; s += 2, ++d) { 81 unsigned int n; 82 83 if (!s[1]) { 84 fprintf(stderr, "Odd number of hex digits!"); 85 EXIT(4); 86 } 87 sscanf((char *)s, "%2x", &n); 88 *d = (unsigned char)n; 89 } 90 return s - d; 91} 92 93static char *sstrsep(char **string, const char *delim) 94{ 95 char isdelim[256]; 96 char *token = *string; 97 98 if (**string == 0) 99 return NULL; 100 101 memset(isdelim, 0, 256); 102 isdelim[0] = 1; 103 104 while (*delim) { 105 isdelim[(unsigned char)(*delim)] = 1; 106 delim++; 107 } 108 109 while (!isdelim[(unsigned char)(**string)]) { 110 (*string)++; 111 } 112 113 if (**string) { 114 **string = 0; 115 (*string)++; 116 } 117 118 return token; 119} 120 121static unsigned char *ustrsep(char **p, const char *sep) 122{ 123 return (unsigned char *)sstrsep(p, sep); 124} 125 126static int test1_exit(int ec) 127{ 128 EXIT(ec); 129 return (0); /* To keep some compilers quiet */ 130} 131 132static void test1(const EVP_CIPHER *c, const unsigned char *key, int kn, 133 const unsigned char *iv, int in, 134 const unsigned char *plaintext, int pn, 135 const unsigned char *ciphertext, int cn, 136 const unsigned char *aad, int an, 137 const unsigned char *tag, int tn, int encdec) 138{ 139 EVP_CIPHER_CTX ctx; 140 unsigned char out[4096]; 141 int outl, outl2, mode; 142 143 printf("Testing cipher %s%s\n", EVP_CIPHER_name(c), 144 (encdec == 145 1 ? "(encrypt)" : (encdec == 146 0 ? "(decrypt)" : "(encrypt/decrypt)"))); 147 hexdump(stdout, "Key", key, kn); 148 if (in) 149 hexdump(stdout, "IV", iv, in); 150 hexdump(stdout, "Plaintext", plaintext, pn); 151 hexdump(stdout, "Ciphertext", ciphertext, cn); 152 if (an) 153 hexdump(stdout, "AAD", aad, an); 154 if (tn) 155 hexdump(stdout, "Tag", tag, tn); 156 mode = EVP_CIPHER_mode(c); 157 if (kn != EVP_CIPHER_key_length(c)) { 158 fprintf(stderr, "Key length doesn't match, got %d expected %lu\n", kn, 159 (unsigned long)EVP_CIPHER_key_length(c)); 160 test1_exit(5); 161 } 162 EVP_CIPHER_CTX_init(&ctx); 163 EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); 164 if (encdec != 0) { 165 if (mode == EVP_CIPH_GCM_MODE) { 166 if (!EVP_EncryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 167 fprintf(stderr, "EncryptInit failed\n"); 168 ERR_print_errors_fp(stderr); 169 test1_exit(10); 170 } 171 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { 172 fprintf(stderr, "IV length set failed\n"); 173 ERR_print_errors_fp(stderr); 174 test1_exit(11); 175 } 176 if (!EVP_EncryptInit_ex(&ctx, NULL, NULL, key, iv)) { 177 fprintf(stderr, "Key/IV set failed\n"); 178 ERR_print_errors_fp(stderr); 179 test1_exit(12); 180 } 181 if (an && !EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) { 182 fprintf(stderr, "AAD set failed\n"); 183 ERR_print_errors_fp(stderr); 184 test1_exit(13); 185 } 186 } else if (mode == EVP_CIPH_CCM_MODE) { 187 if (!EVP_EncryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 188 fprintf(stderr, "EncryptInit failed\n"); 189 ERR_print_errors_fp(stderr); 190 test1_exit(10); 191 } 192 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { 193 fprintf(stderr, "IV length set failed\n"); 194 ERR_print_errors_fp(stderr); 195 test1_exit(11); 196 } 197 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, tn, NULL)) { 198 fprintf(stderr, "Tag length set failed\n"); 199 ERR_print_errors_fp(stderr); 200 test1_exit(11); 201 } 202 if (!EVP_EncryptInit_ex(&ctx, NULL, NULL, key, iv)) { 203 fprintf(stderr, "Key/IV set failed\n"); 204 ERR_print_errors_fp(stderr); 205 test1_exit(12); 206 } 207 if (!EVP_EncryptUpdate(&ctx, NULL, &outl, NULL, pn)) { 208 fprintf(stderr, "Plaintext length set failed\n"); 209 ERR_print_errors_fp(stderr); 210 test1_exit(12); 211 } 212 if (an && !EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) { 213 fprintf(stderr, "AAD set failed\n"); 214 ERR_print_errors_fp(stderr); 215 test1_exit(13); 216 } 217 } else if (mode == EVP_CIPH_WRAP_MODE) { 218 if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, in ? iv : NULL)) { 219 fprintf(stderr, "EncryptInit failed\n"); 220 ERR_print_errors_fp(stderr); 221 test1_exit(10); 222 } 223 } else if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, iv)) { 224 fprintf(stderr, "EncryptInit failed\n"); 225 ERR_print_errors_fp(stderr); 226 test1_exit(10); 227 } 228 EVP_CIPHER_CTX_set_padding(&ctx, 0); 229 230 if (!EVP_EncryptUpdate(&ctx, out, &outl, plaintext, pn)) { 231 fprintf(stderr, "Encrypt failed\n"); 232 ERR_print_errors_fp(stderr); 233 test1_exit(6); 234 } 235 if (!EVP_EncryptFinal_ex(&ctx, out + outl, &outl2)) { 236 fprintf(stderr, "EncryptFinal failed\n"); 237 ERR_print_errors_fp(stderr); 238 test1_exit(7); 239 } 240 241 if (outl + outl2 != cn) { 242 fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n", 243 outl + outl2, cn); 244 test1_exit(8); 245 } 246 247 if (memcmp(out, ciphertext, cn)) { 248 fprintf(stderr, "Ciphertext mismatch\n"); 249 hexdump(stderr, "Got", out, cn); 250 hexdump(stderr, "Expected", ciphertext, cn); 251 test1_exit(9); 252 } 253 if (mode == EVP_CIPH_GCM_MODE || mode == EVP_CIPH_CCM_MODE) { 254 unsigned char rtag[16]; 255 /* 256 * Note: EVP_CTRL_CCM_GET_TAG has same value as 257 * EVP_CTRL_GCM_GET_TAG 258 */ 259 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tn, rtag)) { 260 fprintf(stderr, "Get tag failed\n"); 261 ERR_print_errors_fp(stderr); 262 test1_exit(14); 263 } 264 if (memcmp(rtag, tag, tn)) { 265 fprintf(stderr, "Tag mismatch\n"); 266 hexdump(stderr, "Got", rtag, tn); 267 hexdump(stderr, "Expected", tag, tn); 268 test1_exit(9); 269 } 270 } 271 } 272 273 if (encdec <= 0) { 274 if (mode == EVP_CIPH_GCM_MODE) { 275 if (!EVP_DecryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 276 fprintf(stderr, "EncryptInit failed\n"); 277 ERR_print_errors_fp(stderr); 278 test1_exit(10); 279 } 280 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { 281 fprintf(stderr, "IV length set failed\n"); 282 ERR_print_errors_fp(stderr); 283 test1_exit(11); 284 } 285 if (!EVP_DecryptInit_ex(&ctx, NULL, NULL, key, iv)) { 286 fprintf(stderr, "Key/IV set failed\n"); 287 ERR_print_errors_fp(stderr); 288 test1_exit(12); 289 } 290 if (!EVP_CIPHER_CTX_ctrl 291 (&ctx, EVP_CTRL_GCM_SET_TAG, tn, (void *)tag)) { 292 fprintf(stderr, "Set tag failed\n"); 293 ERR_print_errors_fp(stderr); 294 test1_exit(14); 295 } 296 if (an && !EVP_DecryptUpdate(&ctx, NULL, &outl, aad, an)) { 297 fprintf(stderr, "AAD set failed\n"); 298 ERR_print_errors_fp(stderr); 299 test1_exit(13); 300 } 301 } else if (mode == EVP_CIPH_CCM_MODE) { 302 if (!EVP_DecryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 303 fprintf(stderr, "DecryptInit failed\n"); 304 ERR_print_errors_fp(stderr); 305 test1_exit(10); 306 } 307 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { 308 fprintf(stderr, "IV length set failed\n"); 309 ERR_print_errors_fp(stderr); 310 test1_exit(11); 311 } 312 if (!EVP_CIPHER_CTX_ctrl 313 (&ctx, EVP_CTRL_CCM_SET_TAG, tn, (void *)tag)) { 314 fprintf(stderr, "Tag length set failed\n"); 315 ERR_print_errors_fp(stderr); 316 test1_exit(11); 317 } 318 if (!EVP_DecryptInit_ex(&ctx, NULL, NULL, key, iv)) { 319 fprintf(stderr, "Key/Nonce set failed\n"); 320 ERR_print_errors_fp(stderr); 321 test1_exit(12); 322 } 323 if (!EVP_DecryptUpdate(&ctx, NULL, &outl, NULL, pn)) { 324 fprintf(stderr, "Plaintext length set failed\n"); 325 ERR_print_errors_fp(stderr); 326 test1_exit(12); 327 } 328 if (an && !EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) { 329 fprintf(stderr, "AAD set failed\n"); 330 ERR_print_errors_fp(stderr); 331 test1_exit(13); 332 } 333 } else if (mode == EVP_CIPH_WRAP_MODE) { 334 if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, in ? iv : NULL)) { 335 fprintf(stderr, "EncryptInit failed\n"); 336 ERR_print_errors_fp(stderr); 337 test1_exit(10); 338 } 339 } else if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, iv)) { 340 fprintf(stderr, "DecryptInit failed\n"); 341 ERR_print_errors_fp(stderr); 342 test1_exit(11); 343 } 344 EVP_CIPHER_CTX_set_padding(&ctx, 0); 345 346 if (!EVP_DecryptUpdate(&ctx, out, &outl, ciphertext, cn)) { 347 fprintf(stderr, "Decrypt failed\n"); 348 ERR_print_errors_fp(stderr); 349 test1_exit(6); 350 } 351 if (mode != EVP_CIPH_CCM_MODE 352 && !EVP_DecryptFinal_ex(&ctx, out + outl, &outl2)) { 353 fprintf(stderr, "DecryptFinal failed\n"); 354 ERR_print_errors_fp(stderr); 355 test1_exit(7); 356 } 357 358 if (outl + outl2 != pn) { 359 fprintf(stderr, "Plaintext length mismatch got %d expected %d\n", 360 outl + outl2, pn); 361 test1_exit(8); 362 } 363 364 if (memcmp(out, plaintext, pn)) { 365 fprintf(stderr, "Plaintext mismatch\n"); 366 hexdump(stderr, "Got", out, pn); 367 hexdump(stderr, "Expected", plaintext, pn); 368 test1_exit(9); 369 } 370 } 371 372 EVP_CIPHER_CTX_cleanup(&ctx); 373 374 printf("\n"); 375} 376 377static int test_cipher(const char *cipher, const unsigned char *key, int kn, 378 const unsigned char *iv, int in, 379 const unsigned char *plaintext, int pn, 380 const unsigned char *ciphertext, int cn, 381 const unsigned char *aad, int an, 382 const unsigned char *tag, int tn, int encdec) 383{ 384 const EVP_CIPHER *c; 385 386 c = EVP_get_cipherbyname(cipher); 387 if (!c) 388 return 0; 389 390 test1(c, key, kn, iv, in, plaintext, pn, ciphertext, cn, aad, an, tag, tn, 391 encdec); 392 393 return 1; 394} 395 396static int test_digest(const char *digest, 397 const unsigned char *plaintext, int pn, 398 const unsigned char *ciphertext, unsigned int cn) 399{ 400 const EVP_MD *d; 401 EVP_MD_CTX ctx; 402 unsigned char md[EVP_MAX_MD_SIZE]; 403 unsigned int mdn; 404 405 d = EVP_get_digestbyname(digest); 406 if (!d) 407 return 0; 408 409 printf("Testing digest %s\n", EVP_MD_name(d)); 410 hexdump(stdout, "Plaintext", plaintext, pn); 411 hexdump(stdout, "Digest", ciphertext, cn); 412 413 EVP_MD_CTX_init(&ctx); 414 if (!EVP_DigestInit_ex(&ctx, d, NULL)) { 415 fprintf(stderr, "DigestInit failed\n"); 416 ERR_print_errors_fp(stderr); 417 EXIT(100); 418 } 419 if (!EVP_DigestUpdate(&ctx, plaintext, pn)) { 420 fprintf(stderr, "DigestUpdate failed\n"); 421 ERR_print_errors_fp(stderr); 422 EXIT(101); 423 } 424 if (!EVP_DigestFinal_ex(&ctx, md, &mdn)) { 425 fprintf(stderr, "DigestFinal failed\n"); 426 ERR_print_errors_fp(stderr); 427 EXIT(101); 428 } 429 EVP_MD_CTX_cleanup(&ctx); 430 431 if (mdn != cn) { 432 fprintf(stderr, "Digest length mismatch, got %d expected %d\n", mdn, 433 cn); 434 EXIT(102); 435 } 436 437 if (memcmp(md, ciphertext, cn)) { 438 fprintf(stderr, "Digest mismatch\n"); 439 hexdump(stderr, "Got", md, cn); 440 hexdump(stderr, "Expected", ciphertext, cn); 441 EXIT(103); 442 } 443 444 printf("\n"); 445 446 EVP_MD_CTX_cleanup(&ctx); 447 448 return 1; 449} 450 451int main(int argc, char **argv) 452{ 453 const char *szTestFile; 454 FILE *f; 455 456 if (argc != 2) { 457 fprintf(stderr, "%s <test file>\n", argv[0]); 458 EXIT(1); 459 } 460 CRYPTO_malloc_debug_init(); 461 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 462 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 463 464 szTestFile = argv[1]; 465 466 f = fopen(szTestFile, "r"); 467 if (!f) { 468 perror(szTestFile); 469 EXIT(2); 470 } 471 ERR_load_crypto_strings(); 472 /* Load up the software EVP_CIPHER and EVP_MD definitions */ 473 OpenSSL_add_all_ciphers(); 474 OpenSSL_add_all_digests(); 475#ifndef OPENSSL_NO_ENGINE 476 /* Load all compiled-in ENGINEs */ 477 ENGINE_load_builtin_engines(); 478#endif 479#if 0 480 OPENSSL_config(); 481#endif 482#ifndef OPENSSL_NO_ENGINE 483 /* 484 * Register all available ENGINE implementations of ciphers and digests. 485 * This could perhaps be changed to "ENGINE_register_all_complete()"? 486 */ 487 ENGINE_register_all_ciphers(); 488 ENGINE_register_all_digests(); 489 /* 490 * If we add command-line options, this statement should be switchable. 491 * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use 492 * if they weren't already initialised. 493 */ 494 /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */ 495#endif 496 497 for (;;) { 498 char line[4096]; 499 char *p; 500 char *cipher; 501 unsigned char *iv, *key, *plaintext, *ciphertext, *aad, *tag; 502 int encdec; 503 int kn, in, pn, cn; 504 int an = 0; 505 int tn = 0; 506 507 if (!fgets((char *)line, sizeof line, f)) 508 break; 509 if (line[0] == '#' || line[0] == '\n') 510 continue; 511 p = line; 512 cipher = sstrsep(&p, ":"); 513 key = ustrsep(&p, ":"); 514 iv = ustrsep(&p, ":"); 515 plaintext = ustrsep(&p, ":"); 516 ciphertext = ustrsep(&p, ":"); 517 if (p[-1] == '\n') { 518 encdec = -1; 519 p[-1] = '\0'; 520 tag = aad = NULL; 521 an = tn = 0; 522 } else { 523 aad = ustrsep(&p, ":"); 524 tag = ustrsep(&p, ":"); 525 if (tag == NULL) { 526 p = (char *)aad; 527 tag = aad = NULL; 528 an = tn = 0; 529 } 530 if (p[-1] == '\n') { 531 encdec = -1; 532 p[-1] = '\0'; 533 } else 534 encdec = atoi(sstrsep(&p, "\n")); 535 } 536 537 kn = convert(key); 538 in = convert(iv); 539 pn = convert(plaintext); 540 cn = convert(ciphertext); 541 if (aad) { 542 an = convert(aad); 543 tn = convert(tag); 544 } 545 546 if (!test_cipher 547 (cipher, key, kn, iv, in, plaintext, pn, ciphertext, cn, aad, an, 548 tag, tn, encdec) 549 && !test_digest(cipher, plaintext, pn, ciphertext, cn)) { 550#ifdef OPENSSL_NO_AES 551 if (strstr(cipher, "AES") == cipher) { 552 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 553 continue; 554 } 555#endif 556#ifdef OPENSSL_NO_DES 557 if (strstr(cipher, "DES") == cipher) { 558 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 559 continue; 560 } 561#endif 562#ifdef OPENSSL_NO_RC4 563 if (strstr(cipher, "RC4") == cipher) { 564 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 565 continue; 566 } 567#endif 568#ifdef OPENSSL_NO_CAMELLIA 569 if (strstr(cipher, "CAMELLIA") == cipher) { 570 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 571 continue; 572 } 573#endif 574#ifdef OPENSSL_NO_SEED 575 if (strstr(cipher, "SEED") == cipher) { 576 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 577 continue; 578 } 579#endif 580 fprintf(stderr, "Can't find %s\n", cipher); 581 EXIT(3); 582 } 583 } 584 fclose(f); 585 586#ifndef OPENSSL_NO_ENGINE 587 ENGINE_cleanup(); 588#endif 589 EVP_cleanup(); 590 CRYPTO_cleanup_all_ex_data(); 591 ERR_remove_thread_state(NULL); 592 ERR_free_strings(); 593 CRYPTO_mem_leaks_fp(stderr); 594 595 return 0; 596} 597