evp_test.c revision 306195
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 int digits = 0; 80 81 for (d = s; *s; s += 2, ++d) { 82 unsigned int n; 83 84 if (!s[1]) { 85 fprintf(stderr, "Odd number of hex digits!"); 86 EXIT(4); 87 } 88 sscanf((char *)s, "%2x", &n); 89 *d = (unsigned char)n; 90 digits++; 91 } 92 return digits; 93} 94 95static char *sstrsep(char **string, const char *delim) 96{ 97 char isdelim[256]; 98 char *token = *string; 99 100 if (**string == 0) 101 return NULL; 102 103 memset(isdelim, 0, 256); 104 isdelim[0] = 1; 105 106 while (*delim) { 107 isdelim[(unsigned char)(*delim)] = 1; 108 delim++; 109 } 110 111 while (!isdelim[(unsigned char)(**string)]) { 112 (*string)++; 113 } 114 115 if (**string) { 116 **string = 0; 117 (*string)++; 118 } 119 120 return token; 121} 122 123static unsigned char *ustrsep(char **p, const char *sep) 124{ 125 return (unsigned char *)sstrsep(p, sep); 126} 127 128static int test1_exit(int ec) 129{ 130 EXIT(ec); 131 return (0); /* To keep some compilers quiet */ 132} 133 134static void test1(const EVP_CIPHER *c, const unsigned char *key, int kn, 135 const unsigned char *iv, int in, 136 const unsigned char *plaintext, int pn, 137 const unsigned char *ciphertext, int cn, 138 const unsigned char *aad, int an, 139 const unsigned char *tag, int tn, int encdec) 140{ 141 EVP_CIPHER_CTX ctx; 142 unsigned char out[4096]; 143 int outl, outl2, mode; 144 145 printf("Testing cipher %s%s\n", EVP_CIPHER_name(c), 146 (encdec == 147 1 ? "(encrypt)" : (encdec == 148 0 ? "(decrypt)" : "(encrypt/decrypt)"))); 149 hexdump(stdout, "Key", key, kn); 150 if (in) 151 hexdump(stdout, "IV", iv, in); 152 hexdump(stdout, "Plaintext", plaintext, pn); 153 hexdump(stdout, "Ciphertext", ciphertext, cn); 154 if (an) 155 hexdump(stdout, "AAD", aad, an); 156 if (tn) 157 hexdump(stdout, "Tag", tag, tn); 158 mode = EVP_CIPHER_mode(c); 159 if (kn != EVP_CIPHER_key_length(c)) { 160 fprintf(stderr, "Key length doesn't match, got %d expected %lu\n", kn, 161 (unsigned long)EVP_CIPHER_key_length(c)); 162 test1_exit(5); 163 } 164 EVP_CIPHER_CTX_init(&ctx); 165 EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); 166 if (encdec != 0) { 167 if (mode == EVP_CIPH_GCM_MODE) { 168 if (!EVP_EncryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 169 fprintf(stderr, "EncryptInit failed\n"); 170 ERR_print_errors_fp(stderr); 171 test1_exit(10); 172 } 173 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { 174 fprintf(stderr, "IV length set failed\n"); 175 ERR_print_errors_fp(stderr); 176 test1_exit(11); 177 } 178 if (!EVP_EncryptInit_ex(&ctx, NULL, NULL, key, iv)) { 179 fprintf(stderr, "Key/IV set failed\n"); 180 ERR_print_errors_fp(stderr); 181 test1_exit(12); 182 } 183 if (an && !EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) { 184 fprintf(stderr, "AAD set failed\n"); 185 ERR_print_errors_fp(stderr); 186 test1_exit(13); 187 } 188 } else if (mode == EVP_CIPH_CCM_MODE) { 189 if (!EVP_EncryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 190 fprintf(stderr, "EncryptInit failed\n"); 191 ERR_print_errors_fp(stderr); 192 test1_exit(10); 193 } 194 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { 195 fprintf(stderr, "IV length set failed\n"); 196 ERR_print_errors_fp(stderr); 197 test1_exit(11); 198 } 199 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, tn, NULL)) { 200 fprintf(stderr, "Tag length set failed\n"); 201 ERR_print_errors_fp(stderr); 202 test1_exit(11); 203 } 204 if (!EVP_EncryptInit_ex(&ctx, NULL, NULL, key, iv)) { 205 fprintf(stderr, "Key/IV set failed\n"); 206 ERR_print_errors_fp(stderr); 207 test1_exit(12); 208 } 209 if (!EVP_EncryptUpdate(&ctx, NULL, &outl, NULL, pn)) { 210 fprintf(stderr, "Plaintext length set failed\n"); 211 ERR_print_errors_fp(stderr); 212 test1_exit(12); 213 } 214 if (an && !EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) { 215 fprintf(stderr, "AAD set failed\n"); 216 ERR_print_errors_fp(stderr); 217 test1_exit(13); 218 } 219 } else if (mode == EVP_CIPH_WRAP_MODE) { 220 if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, in ? iv : NULL)) { 221 fprintf(stderr, "EncryptInit failed\n"); 222 ERR_print_errors_fp(stderr); 223 test1_exit(10); 224 } 225 } else if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, iv)) { 226 fprintf(stderr, "EncryptInit failed\n"); 227 ERR_print_errors_fp(stderr); 228 test1_exit(10); 229 } 230 EVP_CIPHER_CTX_set_padding(&ctx, 0); 231 232 if (!EVP_EncryptUpdate(&ctx, out, &outl, plaintext, pn)) { 233 fprintf(stderr, "Encrypt failed\n"); 234 ERR_print_errors_fp(stderr); 235 test1_exit(6); 236 } 237 if (!EVP_EncryptFinal_ex(&ctx, out + outl, &outl2)) { 238 fprintf(stderr, "EncryptFinal failed\n"); 239 ERR_print_errors_fp(stderr); 240 test1_exit(7); 241 } 242 243 if (outl + outl2 != cn) { 244 fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n", 245 outl + outl2, cn); 246 test1_exit(8); 247 } 248 249 if (memcmp(out, ciphertext, cn)) { 250 fprintf(stderr, "Ciphertext mismatch\n"); 251 hexdump(stderr, "Got", out, cn); 252 hexdump(stderr, "Expected", ciphertext, cn); 253 test1_exit(9); 254 } 255 if (mode == EVP_CIPH_GCM_MODE || mode == EVP_CIPH_CCM_MODE) { 256 unsigned char rtag[16]; 257 /* 258 * Note: EVP_CTRL_CCM_GET_TAG has same value as 259 * EVP_CTRL_GCM_GET_TAG 260 */ 261 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tn, rtag)) { 262 fprintf(stderr, "Get tag failed\n"); 263 ERR_print_errors_fp(stderr); 264 test1_exit(14); 265 } 266 if (memcmp(rtag, tag, tn)) { 267 fprintf(stderr, "Tag mismatch\n"); 268 hexdump(stderr, "Got", rtag, tn); 269 hexdump(stderr, "Expected", tag, tn); 270 test1_exit(9); 271 } 272 } 273 } 274 275 if (encdec <= 0) { 276 if (mode == EVP_CIPH_GCM_MODE) { 277 if (!EVP_DecryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 278 fprintf(stderr, "EncryptInit failed\n"); 279 ERR_print_errors_fp(stderr); 280 test1_exit(10); 281 } 282 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { 283 fprintf(stderr, "IV length set failed\n"); 284 ERR_print_errors_fp(stderr); 285 test1_exit(11); 286 } 287 if (!EVP_DecryptInit_ex(&ctx, NULL, NULL, key, iv)) { 288 fprintf(stderr, "Key/IV set failed\n"); 289 ERR_print_errors_fp(stderr); 290 test1_exit(12); 291 } 292 if (!EVP_CIPHER_CTX_ctrl 293 (&ctx, EVP_CTRL_GCM_SET_TAG, tn, (void *)tag)) { 294 fprintf(stderr, "Set tag failed\n"); 295 ERR_print_errors_fp(stderr); 296 test1_exit(14); 297 } 298 if (an && !EVP_DecryptUpdate(&ctx, NULL, &outl, aad, an)) { 299 fprintf(stderr, "AAD set failed\n"); 300 ERR_print_errors_fp(stderr); 301 test1_exit(13); 302 } 303 } else if (mode == EVP_CIPH_CCM_MODE) { 304 if (!EVP_DecryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 305 fprintf(stderr, "DecryptInit failed\n"); 306 ERR_print_errors_fp(stderr); 307 test1_exit(10); 308 } 309 if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { 310 fprintf(stderr, "IV length set failed\n"); 311 ERR_print_errors_fp(stderr); 312 test1_exit(11); 313 } 314 if (!EVP_CIPHER_CTX_ctrl 315 (&ctx, EVP_CTRL_CCM_SET_TAG, tn, (void *)tag)) { 316 fprintf(stderr, "Tag length set failed\n"); 317 ERR_print_errors_fp(stderr); 318 test1_exit(11); 319 } 320 if (!EVP_DecryptInit_ex(&ctx, NULL, NULL, key, iv)) { 321 fprintf(stderr, "Key/Nonce set failed\n"); 322 ERR_print_errors_fp(stderr); 323 test1_exit(12); 324 } 325 if (!EVP_DecryptUpdate(&ctx, NULL, &outl, NULL, pn)) { 326 fprintf(stderr, "Plaintext length set failed\n"); 327 ERR_print_errors_fp(stderr); 328 test1_exit(12); 329 } 330 if (an && !EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) { 331 fprintf(stderr, "AAD set failed\n"); 332 ERR_print_errors_fp(stderr); 333 test1_exit(13); 334 } 335 } else if (mode == EVP_CIPH_WRAP_MODE) { 336 if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, in ? iv : NULL)) { 337 fprintf(stderr, "EncryptInit failed\n"); 338 ERR_print_errors_fp(stderr); 339 test1_exit(10); 340 } 341 } else if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, iv)) { 342 fprintf(stderr, "DecryptInit failed\n"); 343 ERR_print_errors_fp(stderr); 344 test1_exit(11); 345 } 346 EVP_CIPHER_CTX_set_padding(&ctx, 0); 347 348 if (!EVP_DecryptUpdate(&ctx, out, &outl, ciphertext, cn)) { 349 fprintf(stderr, "Decrypt failed\n"); 350 ERR_print_errors_fp(stderr); 351 test1_exit(6); 352 } 353 if (mode != EVP_CIPH_CCM_MODE 354 && !EVP_DecryptFinal_ex(&ctx, out + outl, &outl2)) { 355 fprintf(stderr, "DecryptFinal failed\n"); 356 ERR_print_errors_fp(stderr); 357 test1_exit(7); 358 } 359 360 if (outl + outl2 != pn) { 361 fprintf(stderr, "Plaintext length mismatch got %d expected %d\n", 362 outl + outl2, pn); 363 test1_exit(8); 364 } 365 366 if (memcmp(out, plaintext, pn)) { 367 fprintf(stderr, "Plaintext mismatch\n"); 368 hexdump(stderr, "Got", out, pn); 369 hexdump(stderr, "Expected", plaintext, pn); 370 test1_exit(9); 371 } 372 } 373 374 EVP_CIPHER_CTX_cleanup(&ctx); 375 376 printf("\n"); 377} 378 379static int test_cipher(const char *cipher, const unsigned char *key, int kn, 380 const unsigned char *iv, int in, 381 const unsigned char *plaintext, int pn, 382 const unsigned char *ciphertext, int cn, 383 const unsigned char *aad, int an, 384 const unsigned char *tag, int tn, int encdec) 385{ 386 const EVP_CIPHER *c; 387 388 c = EVP_get_cipherbyname(cipher); 389 if (!c) 390 return 0; 391 392 test1(c, key, kn, iv, in, plaintext, pn, ciphertext, cn, aad, an, tag, tn, 393 encdec); 394 395 return 1; 396} 397 398static int test_digest(const char *digest, 399 const unsigned char *plaintext, int pn, 400 const unsigned char *ciphertext, unsigned int cn) 401{ 402 const EVP_MD *d; 403 EVP_MD_CTX ctx; 404 unsigned char md[EVP_MAX_MD_SIZE]; 405 unsigned int mdn; 406 407 d = EVP_get_digestbyname(digest); 408 if (!d) 409 return 0; 410 411 printf("Testing digest %s\n", EVP_MD_name(d)); 412 hexdump(stdout, "Plaintext", plaintext, pn); 413 hexdump(stdout, "Digest", ciphertext, cn); 414 415 EVP_MD_CTX_init(&ctx); 416 if (!EVP_DigestInit_ex(&ctx, d, NULL)) { 417 fprintf(stderr, "DigestInit failed\n"); 418 ERR_print_errors_fp(stderr); 419 EXIT(100); 420 } 421 if (!EVP_DigestUpdate(&ctx, plaintext, pn)) { 422 fprintf(stderr, "DigestUpdate failed\n"); 423 ERR_print_errors_fp(stderr); 424 EXIT(101); 425 } 426 if (!EVP_DigestFinal_ex(&ctx, md, &mdn)) { 427 fprintf(stderr, "DigestFinal failed\n"); 428 ERR_print_errors_fp(stderr); 429 EXIT(101); 430 } 431 EVP_MD_CTX_cleanup(&ctx); 432 433 if (mdn != cn) { 434 fprintf(stderr, "Digest length mismatch, got %d expected %d\n", mdn, 435 cn); 436 EXIT(102); 437 } 438 439 if (memcmp(md, ciphertext, cn)) { 440 fprintf(stderr, "Digest mismatch\n"); 441 hexdump(stderr, "Got", md, cn); 442 hexdump(stderr, "Expected", ciphertext, cn); 443 EXIT(103); 444 } 445 446 printf("\n"); 447 448 EVP_MD_CTX_cleanup(&ctx); 449 450 return 1; 451} 452 453int main(int argc, char **argv) 454{ 455 const char *szTestFile; 456 FILE *f; 457 458 if (argc != 2) { 459 fprintf(stderr, "%s <test file>\n", argv[0]); 460 EXIT(1); 461 } 462 CRYPTO_malloc_debug_init(); 463 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 464 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 465 466 szTestFile = argv[1]; 467 468 f = fopen(szTestFile, "r"); 469 if (!f) { 470 perror(szTestFile); 471 EXIT(2); 472 } 473 ERR_load_crypto_strings(); 474 /* Load up the software EVP_CIPHER and EVP_MD definitions */ 475 OpenSSL_add_all_ciphers(); 476 OpenSSL_add_all_digests(); 477#ifndef OPENSSL_NO_ENGINE 478 /* Load all compiled-in ENGINEs */ 479 ENGINE_load_builtin_engines(); 480#endif 481#if 0 482 OPENSSL_config(); 483#endif 484#ifndef OPENSSL_NO_ENGINE 485 /* 486 * Register all available ENGINE implementations of ciphers and digests. 487 * This could perhaps be changed to "ENGINE_register_all_complete()"? 488 */ 489 ENGINE_register_all_ciphers(); 490 ENGINE_register_all_digests(); 491 /* 492 * If we add command-line options, this statement should be switchable. 493 * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use 494 * if they weren't already initialised. 495 */ 496 /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */ 497#endif 498 499 for (;;) { 500 char line[4096]; 501 char *p; 502 char *cipher; 503 unsigned char *iv, *key, *plaintext, *ciphertext, *aad, *tag; 504 int encdec; 505 int kn, in, pn, cn; 506 int an = 0; 507 int tn = 0; 508 509 if (!fgets((char *)line, sizeof line, f)) 510 break; 511 if (line[0] == '#' || line[0] == '\n') 512 continue; 513 p = line; 514 cipher = sstrsep(&p, ":"); 515 key = ustrsep(&p, ":"); 516 iv = ustrsep(&p, ":"); 517 plaintext = ustrsep(&p, ":"); 518 ciphertext = ustrsep(&p, ":"); 519 if (p[-1] == '\n') { 520 encdec = -1; 521 p[-1] = '\0'; 522 tag = aad = NULL; 523 an = tn = 0; 524 } else { 525 aad = ustrsep(&p, ":"); 526 tag = ustrsep(&p, ":"); 527 if (tag == NULL) { 528 p = (char *)aad; 529 tag = aad = NULL; 530 an = tn = 0; 531 } 532 if (p[-1] == '\n') { 533 encdec = -1; 534 p[-1] = '\0'; 535 } else 536 encdec = atoi(sstrsep(&p, "\n")); 537 } 538 539 kn = convert(key); 540 in = convert(iv); 541 pn = convert(plaintext); 542 cn = convert(ciphertext); 543 if (aad) { 544 an = convert(aad); 545 tn = convert(tag); 546 } 547 548 if (!test_cipher 549 (cipher, key, kn, iv, in, plaintext, pn, ciphertext, cn, aad, an, 550 tag, tn, encdec) 551 && !test_digest(cipher, plaintext, pn, ciphertext, cn)) { 552#ifdef OPENSSL_NO_AES 553 if (strstr(cipher, "AES") == cipher) { 554 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 555 continue; 556 } 557#endif 558#ifdef OPENSSL_NO_DES 559 if (strstr(cipher, "DES") == cipher) { 560 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 561 continue; 562 } 563#endif 564#ifdef OPENSSL_NO_RC4 565 if (strstr(cipher, "RC4") == cipher) { 566 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 567 continue; 568 } 569#endif 570#ifdef OPENSSL_NO_CAMELLIA 571 if (strstr(cipher, "CAMELLIA") == cipher) { 572 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 573 continue; 574 } 575#endif 576#ifdef OPENSSL_NO_SEED 577 if (strstr(cipher, "SEED") == cipher) { 578 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 579 continue; 580 } 581#endif 582 fprintf(stderr, "Can't find %s\n", cipher); 583 EXIT(3); 584 } 585 } 586 fclose(f); 587 588#ifndef OPENSSL_NO_ENGINE 589 ENGINE_cleanup(); 590#endif 591 EVP_cleanup(); 592 CRYPTO_cleanup_all_ex_data(); 593 ERR_remove_thread_state(NULL); 594 ERR_free_strings(); 595 CRYPTO_mem_leaks_fp(stderr); 596 597 return 0; 598} 599