1109998Smarkm/* Written by Ben Laurie, 2001 */ 2109998Smarkm/* 3344604Sjkim * Copyright (c) 2001-2019 The OpenSSL Project. All rights reserved. 4109998Smarkm * 5109998Smarkm * Redistribution and use in source and binary forms, with or without 6109998Smarkm * modification, are permitted provided that the following conditions 7109998Smarkm * are met: 8109998Smarkm * 9109998Smarkm * 1. Redistributions of source code must retain the above copyright 10280297Sjkim * notice, this list of conditions and the following disclaimer. 11109998Smarkm * 12109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 13109998Smarkm * notice, this list of conditions and the following disclaimer in 14109998Smarkm * the documentation and/or other materials provided with the 15109998Smarkm * distribution. 16109998Smarkm * 17109998Smarkm * 3. All advertising materials mentioning features or use of this 18109998Smarkm * software must display the following acknowledgment: 19109998Smarkm * "This product includes software developed by the OpenSSL Project 20109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21109998Smarkm * 22109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23109998Smarkm * endorse or promote products derived from this software without 24109998Smarkm * prior written permission. For written permission, please contact 25109998Smarkm * openssl-core@openssl.org. 26109998Smarkm * 27109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 28109998Smarkm * nor may "OpenSSL" appear in their names without prior written 29109998Smarkm * permission of the OpenSSL Project. 30109998Smarkm * 31109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 32109998Smarkm * acknowledgment: 33109998Smarkm * "This product includes software developed by the OpenSSL Project 34109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35109998Smarkm * 36109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 48109998Smarkm */ 49109998Smarkm 50109998Smarkm#include <stdio.h> 51109998Smarkm#include <string.h> 52109998Smarkm 53109998Smarkm#include "../e_os.h" 54109998Smarkm 55160814Ssimon#include <openssl/opensslconf.h> 56109998Smarkm#include <openssl/evp.h> 57111147Snectar#ifndef OPENSSL_NO_ENGINE 58280297Sjkim# include <openssl/engine.h> 59111147Snectar#endif 60111147Snectar#include <openssl/err.h> 61109998Smarkm#include <openssl/conf.h> 62109998Smarkm 63280297Sjkimstatic void hexdump(FILE *f, const char *title, const unsigned char *s, int l) 64280297Sjkim{ 65280297Sjkim int n = 0; 66109998Smarkm 67280297Sjkim fprintf(f, "%s", title); 68280297Sjkim for (; n < l; ++n) { 69280297Sjkim if ((n % 16) == 0) 70280297Sjkim fprintf(f, "\n%04x", n); 71280297Sjkim fprintf(f, " %02x", s[n]); 72109998Smarkm } 73280297Sjkim fprintf(f, "\n"); 74280297Sjkim} 75109998Smarkm 76109998Smarkmstatic int convert(unsigned char *s) 77280297Sjkim{ 78109998Smarkm unsigned char *d; 79306195Sjkim int digits = 0; 80109998Smarkm 81280297Sjkim for (d = s; *s; s += 2, ++d) { 82280297Sjkim unsigned int n; 83109998Smarkm 84280297Sjkim if (!s[1]) { 85280297Sjkim fprintf(stderr, "Odd number of hex digits!"); 86280297Sjkim EXIT(4); 87280297Sjkim } 88280297Sjkim sscanf((char *)s, "%2x", &n); 89280297Sjkim *d = (unsigned char)n; 90306195Sjkim digits++; 91109998Smarkm } 92306195Sjkim return digits; 93280297Sjkim} 94109998Smarkm 95109998Smarkmstatic char *sstrsep(char **string, const char *delim) 96280297Sjkim{ 97109998Smarkm char isdelim[256]; 98109998Smarkm char *token = *string; 99109998Smarkm 100109998Smarkm if (**string == 0) 101109998Smarkm return NULL; 102109998Smarkm 103109998Smarkm memset(isdelim, 0, 256); 104109998Smarkm isdelim[0] = 1; 105109998Smarkm 106280297Sjkim while (*delim) { 107109998Smarkm isdelim[(unsigned char)(*delim)] = 1; 108109998Smarkm delim++; 109280297Sjkim } 110109998Smarkm 111280297Sjkim while (!isdelim[(unsigned char)(**string)]) { 112109998Smarkm (*string)++; 113280297Sjkim } 114109998Smarkm 115280297Sjkim if (**string) { 116109998Smarkm **string = 0; 117109998Smarkm (*string)++; 118280297Sjkim } 119109998Smarkm 120109998Smarkm return token; 121280297Sjkim} 122109998Smarkm 123280297Sjkimstatic unsigned char *ustrsep(char **p, const char *sep) 124280297Sjkim{ 125280297Sjkim return (unsigned char *)sstrsep(p, sep); 126280297Sjkim} 127109998Smarkm 128109998Smarkmstatic int test1_exit(int ec) 129280297Sjkim{ 130280297Sjkim EXIT(ec); 131280297Sjkim return (0); /* To keep some compilers quiet */ 132280297Sjkim} 133109998Smarkm 134280297Sjkimstatic void test1(const EVP_CIPHER *c, const unsigned char *key, int kn, 135280297Sjkim const unsigned char *iv, int in, 136280297Sjkim const unsigned char *plaintext, int pn, 137290207Sjkim const unsigned char *ciphertext, int cn, 138290207Sjkim const unsigned char *aad, int an, 139290207Sjkim const unsigned char *tag, int tn, int encdec) 140280297Sjkim{ 141109998Smarkm EVP_CIPHER_CTX ctx; 142109998Smarkm unsigned char out[4096]; 143290207Sjkim int outl, outl2, mode; 144109998Smarkm 145280297Sjkim printf("Testing cipher %s%s\n", EVP_CIPHER_name(c), 146280297Sjkim (encdec == 147280297Sjkim 1 ? "(encrypt)" : (encdec == 148280297Sjkim 0 ? "(decrypt)" : "(encrypt/decrypt)"))); 149280297Sjkim hexdump(stdout, "Key", key, kn); 150280297Sjkim if (in) 151280297Sjkim hexdump(stdout, "IV", iv, in); 152280297Sjkim hexdump(stdout, "Plaintext", plaintext, pn); 153280297Sjkim hexdump(stdout, "Ciphertext", ciphertext, cn); 154290207Sjkim if (an) 155290207Sjkim hexdump(stdout, "AAD", aad, an); 156290207Sjkim if (tn) 157290207Sjkim hexdump(stdout, "Tag", tag, tn); 158290207Sjkim mode = EVP_CIPHER_mode(c); 159290207Sjkim if (kn != EVP_CIPHER_key_length(c)) { 160280297Sjkim fprintf(stderr, "Key length doesn't match, got %d expected %lu\n", kn, 161290207Sjkim (unsigned long)EVP_CIPHER_key_length(c)); 162280297Sjkim test1_exit(5); 163280297Sjkim } 164109998Smarkm EVP_CIPHER_CTX_init(&ctx); 165290207Sjkim EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); 166280297Sjkim if (encdec != 0) { 167290207Sjkim if (mode == EVP_CIPH_GCM_MODE) { 168290207Sjkim if (!EVP_EncryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 169290207Sjkim fprintf(stderr, "EncryptInit failed\n"); 170290207Sjkim ERR_print_errors_fp(stderr); 171290207Sjkim test1_exit(10); 172290207Sjkim } 173290207Sjkim if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { 174290207Sjkim fprintf(stderr, "IV length set failed\n"); 175290207Sjkim ERR_print_errors_fp(stderr); 176290207Sjkim test1_exit(11); 177290207Sjkim } 178290207Sjkim if (!EVP_EncryptInit_ex(&ctx, NULL, NULL, key, iv)) { 179290207Sjkim fprintf(stderr, "Key/IV set failed\n"); 180290207Sjkim ERR_print_errors_fp(stderr); 181290207Sjkim test1_exit(12); 182290207Sjkim } 183290207Sjkim if (an && !EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) { 184290207Sjkim fprintf(stderr, "AAD set failed\n"); 185290207Sjkim ERR_print_errors_fp(stderr); 186290207Sjkim test1_exit(13); 187290207Sjkim } 188290207Sjkim } else if (mode == EVP_CIPH_CCM_MODE) { 189290207Sjkim if (!EVP_EncryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 190290207Sjkim fprintf(stderr, "EncryptInit failed\n"); 191290207Sjkim ERR_print_errors_fp(stderr); 192290207Sjkim test1_exit(10); 193290207Sjkim } 194290207Sjkim if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { 195290207Sjkim fprintf(stderr, "IV length set failed\n"); 196290207Sjkim ERR_print_errors_fp(stderr); 197290207Sjkim test1_exit(11); 198290207Sjkim } 199290207Sjkim if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, tn, NULL)) { 200290207Sjkim fprintf(stderr, "Tag length set failed\n"); 201290207Sjkim ERR_print_errors_fp(stderr); 202290207Sjkim test1_exit(11); 203290207Sjkim } 204290207Sjkim if (!EVP_EncryptInit_ex(&ctx, NULL, NULL, key, iv)) { 205290207Sjkim fprintf(stderr, "Key/IV set failed\n"); 206290207Sjkim ERR_print_errors_fp(stderr); 207290207Sjkim test1_exit(12); 208290207Sjkim } 209290207Sjkim if (!EVP_EncryptUpdate(&ctx, NULL, &outl, NULL, pn)) { 210290207Sjkim fprintf(stderr, "Plaintext length set failed\n"); 211290207Sjkim ERR_print_errors_fp(stderr); 212290207Sjkim test1_exit(12); 213290207Sjkim } 214290207Sjkim if (an && !EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) { 215290207Sjkim fprintf(stderr, "AAD set failed\n"); 216290207Sjkim ERR_print_errors_fp(stderr); 217290207Sjkim test1_exit(13); 218290207Sjkim } 219290207Sjkim } else if (mode == EVP_CIPH_WRAP_MODE) { 220290207Sjkim if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, in ? iv : NULL)) { 221290207Sjkim fprintf(stderr, "EncryptInit failed\n"); 222290207Sjkim ERR_print_errors_fp(stderr); 223290207Sjkim test1_exit(10); 224290207Sjkim } 225290207Sjkim } else if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, iv)) { 226280297Sjkim fprintf(stderr, "EncryptInit failed\n"); 227280297Sjkim ERR_print_errors_fp(stderr); 228280297Sjkim test1_exit(10); 229280297Sjkim } 230280297Sjkim EVP_CIPHER_CTX_set_padding(&ctx, 0); 231109998Smarkm 232280297Sjkim if (!EVP_EncryptUpdate(&ctx, out, &outl, plaintext, pn)) { 233280297Sjkim fprintf(stderr, "Encrypt failed\n"); 234280297Sjkim ERR_print_errors_fp(stderr); 235280297Sjkim test1_exit(6); 236280297Sjkim } 237280297Sjkim if (!EVP_EncryptFinal_ex(&ctx, out + outl, &outl2)) { 238280297Sjkim fprintf(stderr, "EncryptFinal failed\n"); 239280297Sjkim ERR_print_errors_fp(stderr); 240280297Sjkim test1_exit(7); 241280297Sjkim } 242109998Smarkm 243280297Sjkim if (outl + outl2 != cn) { 244280297Sjkim fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n", 245280297Sjkim outl + outl2, cn); 246280297Sjkim test1_exit(8); 247280297Sjkim } 248109998Smarkm 249280297Sjkim if (memcmp(out, ciphertext, cn)) { 250280297Sjkim fprintf(stderr, "Ciphertext mismatch\n"); 251280297Sjkim hexdump(stderr, "Got", out, cn); 252280297Sjkim hexdump(stderr, "Expected", ciphertext, cn); 253280297Sjkim test1_exit(9); 254280297Sjkim } 255290207Sjkim if (mode == EVP_CIPH_GCM_MODE || mode == EVP_CIPH_CCM_MODE) { 256290207Sjkim unsigned char rtag[16]; 257290207Sjkim /* 258290207Sjkim * Note: EVP_CTRL_CCM_GET_TAG has same value as 259290207Sjkim * EVP_CTRL_GCM_GET_TAG 260290207Sjkim */ 261290207Sjkim if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tn, rtag)) { 262290207Sjkim fprintf(stderr, "Get tag failed\n"); 263290207Sjkim ERR_print_errors_fp(stderr); 264290207Sjkim test1_exit(14); 265290207Sjkim } 266290207Sjkim if (memcmp(rtag, tag, tn)) { 267290207Sjkim fprintf(stderr, "Tag mismatch\n"); 268290207Sjkim hexdump(stderr, "Got", rtag, tn); 269290207Sjkim hexdump(stderr, "Expected", tag, tn); 270290207Sjkim test1_exit(9); 271290207Sjkim } 272290207Sjkim } 273280297Sjkim } 274109998Smarkm 275280297Sjkim if (encdec <= 0) { 276290207Sjkim if (mode == EVP_CIPH_GCM_MODE) { 277290207Sjkim if (!EVP_DecryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 278290207Sjkim fprintf(stderr, "EncryptInit failed\n"); 279290207Sjkim ERR_print_errors_fp(stderr); 280290207Sjkim test1_exit(10); 281290207Sjkim } 282290207Sjkim if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { 283290207Sjkim fprintf(stderr, "IV length set failed\n"); 284290207Sjkim ERR_print_errors_fp(stderr); 285290207Sjkim test1_exit(11); 286290207Sjkim } 287290207Sjkim if (!EVP_DecryptInit_ex(&ctx, NULL, NULL, key, iv)) { 288290207Sjkim fprintf(stderr, "Key/IV set failed\n"); 289290207Sjkim ERR_print_errors_fp(stderr); 290290207Sjkim test1_exit(12); 291290207Sjkim } 292290207Sjkim if (!EVP_CIPHER_CTX_ctrl 293290207Sjkim (&ctx, EVP_CTRL_GCM_SET_TAG, tn, (void *)tag)) { 294290207Sjkim fprintf(stderr, "Set tag failed\n"); 295290207Sjkim ERR_print_errors_fp(stderr); 296290207Sjkim test1_exit(14); 297290207Sjkim } 298290207Sjkim if (an && !EVP_DecryptUpdate(&ctx, NULL, &outl, aad, an)) { 299290207Sjkim fprintf(stderr, "AAD set failed\n"); 300290207Sjkim ERR_print_errors_fp(stderr); 301290207Sjkim test1_exit(13); 302290207Sjkim } 303290207Sjkim } else if (mode == EVP_CIPH_CCM_MODE) { 304290207Sjkim if (!EVP_DecryptInit_ex(&ctx, c, NULL, NULL, NULL)) { 305290207Sjkim fprintf(stderr, "DecryptInit failed\n"); 306290207Sjkim ERR_print_errors_fp(stderr); 307290207Sjkim test1_exit(10); 308290207Sjkim } 309290207Sjkim if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { 310290207Sjkim fprintf(stderr, "IV length set failed\n"); 311290207Sjkim ERR_print_errors_fp(stderr); 312290207Sjkim test1_exit(11); 313290207Sjkim } 314290207Sjkim if (!EVP_CIPHER_CTX_ctrl 315290207Sjkim (&ctx, EVP_CTRL_CCM_SET_TAG, tn, (void *)tag)) { 316290207Sjkim fprintf(stderr, "Tag length set failed\n"); 317290207Sjkim ERR_print_errors_fp(stderr); 318290207Sjkim test1_exit(11); 319290207Sjkim } 320290207Sjkim if (!EVP_DecryptInit_ex(&ctx, NULL, NULL, key, iv)) { 321290207Sjkim fprintf(stderr, "Key/Nonce set failed\n"); 322290207Sjkim ERR_print_errors_fp(stderr); 323290207Sjkim test1_exit(12); 324290207Sjkim } 325290207Sjkim if (!EVP_DecryptUpdate(&ctx, NULL, &outl, NULL, pn)) { 326290207Sjkim fprintf(stderr, "Plaintext length set failed\n"); 327290207Sjkim ERR_print_errors_fp(stderr); 328290207Sjkim test1_exit(12); 329290207Sjkim } 330344604Sjkim if (an && !EVP_DecryptUpdate(&ctx, NULL, &outl, aad, an)) { 331290207Sjkim fprintf(stderr, "AAD set failed\n"); 332290207Sjkim ERR_print_errors_fp(stderr); 333290207Sjkim test1_exit(13); 334290207Sjkim } 335290207Sjkim } else if (mode == EVP_CIPH_WRAP_MODE) { 336290207Sjkim if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, in ? iv : NULL)) { 337290207Sjkim fprintf(stderr, "EncryptInit failed\n"); 338290207Sjkim ERR_print_errors_fp(stderr); 339290207Sjkim test1_exit(10); 340290207Sjkim } 341290207Sjkim } else if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, iv)) { 342280297Sjkim fprintf(stderr, "DecryptInit failed\n"); 343280297Sjkim ERR_print_errors_fp(stderr); 344280297Sjkim test1_exit(11); 345280297Sjkim } 346280297Sjkim EVP_CIPHER_CTX_set_padding(&ctx, 0); 347109998Smarkm 348280297Sjkim if (!EVP_DecryptUpdate(&ctx, out, &outl, ciphertext, cn)) { 349280297Sjkim fprintf(stderr, "Decrypt failed\n"); 350280297Sjkim ERR_print_errors_fp(stderr); 351280297Sjkim test1_exit(6); 352280297Sjkim } 353290207Sjkim if (mode != EVP_CIPH_CCM_MODE 354290207Sjkim && !EVP_DecryptFinal_ex(&ctx, out + outl, &outl2)) { 355280297Sjkim fprintf(stderr, "DecryptFinal failed\n"); 356280297Sjkim ERR_print_errors_fp(stderr); 357280297Sjkim test1_exit(7); 358280297Sjkim } 359109998Smarkm 360280297Sjkim if (outl + outl2 != pn) { 361280297Sjkim fprintf(stderr, "Plaintext length mismatch got %d expected %d\n", 362280297Sjkim outl + outl2, pn); 363280297Sjkim test1_exit(8); 364280297Sjkim } 365109998Smarkm 366280297Sjkim if (memcmp(out, plaintext, pn)) { 367280297Sjkim fprintf(stderr, "Plaintext mismatch\n"); 368280297Sjkim hexdump(stderr, "Got", out, pn); 369280297Sjkim hexdump(stderr, "Expected", plaintext, pn); 370280297Sjkim test1_exit(9); 371280297Sjkim } 372280297Sjkim } 373109998Smarkm 374109998Smarkm EVP_CIPHER_CTX_cleanup(&ctx); 375109998Smarkm 376109998Smarkm printf("\n"); 377280297Sjkim} 378109998Smarkm 379280297Sjkimstatic int test_cipher(const char *cipher, const unsigned char *key, int kn, 380280297Sjkim const unsigned char *iv, int in, 381280297Sjkim const unsigned char *plaintext, int pn, 382290207Sjkim const unsigned char *ciphertext, int cn, 383290207Sjkim const unsigned char *aad, int an, 384290207Sjkim const unsigned char *tag, int tn, int encdec) 385280297Sjkim{ 386109998Smarkm const EVP_CIPHER *c; 387109998Smarkm 388280297Sjkim c = EVP_get_cipherbyname(cipher); 389280297Sjkim if (!c) 390280297Sjkim return 0; 391109998Smarkm 392290207Sjkim test1(c, key, kn, iv, in, plaintext, pn, ciphertext, cn, aad, an, tag, tn, 393290207Sjkim encdec); 394109998Smarkm 395109998Smarkm return 1; 396280297Sjkim} 397109998Smarkm 398109998Smarkmstatic int test_digest(const char *digest, 399280297Sjkim const unsigned char *plaintext, int pn, 400280297Sjkim const unsigned char *ciphertext, unsigned int cn) 401280297Sjkim{ 402109998Smarkm const EVP_MD *d; 403109998Smarkm EVP_MD_CTX ctx; 404109998Smarkm unsigned char md[EVP_MAX_MD_SIZE]; 405109998Smarkm unsigned int mdn; 406109998Smarkm 407280297Sjkim d = EVP_get_digestbyname(digest); 408280297Sjkim if (!d) 409280297Sjkim return 0; 410109998Smarkm 411280297Sjkim printf("Testing digest %s\n", EVP_MD_name(d)); 412280297Sjkim hexdump(stdout, "Plaintext", plaintext, pn); 413280297Sjkim hexdump(stdout, "Digest", ciphertext, cn); 414109998Smarkm 415109998Smarkm EVP_MD_CTX_init(&ctx); 416280297Sjkim if (!EVP_DigestInit_ex(&ctx, d, NULL)) { 417280297Sjkim fprintf(stderr, "DigestInit failed\n"); 418280297Sjkim ERR_print_errors_fp(stderr); 419280297Sjkim EXIT(100); 420280297Sjkim } 421280297Sjkim if (!EVP_DigestUpdate(&ctx, plaintext, pn)) { 422280297Sjkim fprintf(stderr, "DigestUpdate failed\n"); 423280297Sjkim ERR_print_errors_fp(stderr); 424280297Sjkim EXIT(101); 425280297Sjkim } 426280297Sjkim if (!EVP_DigestFinal_ex(&ctx, md, &mdn)) { 427280297Sjkim fprintf(stderr, "DigestFinal failed\n"); 428280297Sjkim ERR_print_errors_fp(stderr); 429280297Sjkim EXIT(101); 430280297Sjkim } 431109998Smarkm EVP_MD_CTX_cleanup(&ctx); 432109998Smarkm 433280297Sjkim if (mdn != cn) { 434280297Sjkim fprintf(stderr, "Digest length mismatch, got %d expected %d\n", mdn, 435280297Sjkim cn); 436280297Sjkim EXIT(102); 437280297Sjkim } 438109998Smarkm 439280297Sjkim if (memcmp(md, ciphertext, cn)) { 440280297Sjkim fprintf(stderr, "Digest mismatch\n"); 441280297Sjkim hexdump(stderr, "Got", md, cn); 442280297Sjkim hexdump(stderr, "Expected", ciphertext, cn); 443280297Sjkim EXIT(103); 444280297Sjkim } 445109998Smarkm 446109998Smarkm printf("\n"); 447109998Smarkm 448109998Smarkm EVP_MD_CTX_cleanup(&ctx); 449109998Smarkm 450109998Smarkm return 1; 451280297Sjkim} 452109998Smarkm 453280297Sjkimint main(int argc, char **argv) 454280297Sjkim{ 455109998Smarkm const char *szTestFile; 456109998Smarkm FILE *f; 457109998Smarkm 458280297Sjkim if (argc != 2) { 459280297Sjkim fprintf(stderr, "%s <test file>\n", argv[0]); 460280297Sjkim EXIT(1); 461280297Sjkim } 462109998Smarkm CRYPTO_malloc_debug_init(); 463109998Smarkm CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 464109998Smarkm CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 465109998Smarkm 466280297Sjkim szTestFile = argv[1]; 467109998Smarkm 468280297Sjkim f = fopen(szTestFile, "r"); 469280297Sjkim if (!f) { 470280297Sjkim perror(szTestFile); 471280297Sjkim EXIT(2); 472280297Sjkim } 473290207Sjkim ERR_load_crypto_strings(); 474109998Smarkm /* Load up the software EVP_CIPHER and EVP_MD definitions */ 475109998Smarkm OpenSSL_add_all_ciphers(); 476109998Smarkm OpenSSL_add_all_digests(); 477111147Snectar#ifndef OPENSSL_NO_ENGINE 478109998Smarkm /* Load all compiled-in ENGINEs */ 479109998Smarkm ENGINE_load_builtin_engines(); 480111147Snectar#endif 481109998Smarkm#if 0 482109998Smarkm OPENSSL_config(); 483109998Smarkm#endif 484111147Snectar#ifndef OPENSSL_NO_ENGINE 485280297Sjkim /* 486280297Sjkim * Register all available ENGINE implementations of ciphers and digests. 487280297Sjkim * This could perhaps be changed to "ENGINE_register_all_complete()"? 488280297Sjkim */ 489109998Smarkm ENGINE_register_all_ciphers(); 490109998Smarkm ENGINE_register_all_digests(); 491280297Sjkim /* 492280297Sjkim * If we add command-line options, this statement should be switchable. 493280297Sjkim * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use 494280297Sjkim * if they weren't already initialised. 495280297Sjkim */ 496109998Smarkm /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */ 497111147Snectar#endif 498109998Smarkm 499280297Sjkim for (;;) { 500280297Sjkim char line[4096]; 501280297Sjkim char *p; 502280297Sjkim char *cipher; 503290207Sjkim unsigned char *iv, *key, *plaintext, *ciphertext, *aad, *tag; 504280297Sjkim int encdec; 505280297Sjkim int kn, in, pn, cn; 506290207Sjkim int an = 0; 507290207Sjkim int tn = 0; 508109998Smarkm 509331638Sjkim if (!fgets((char *)line, sizeof(line), f)) 510280297Sjkim break; 511280297Sjkim if (line[0] == '#' || line[0] == '\n') 512280297Sjkim continue; 513280297Sjkim p = line; 514280297Sjkim cipher = sstrsep(&p, ":"); 515280297Sjkim key = ustrsep(&p, ":"); 516280297Sjkim iv = ustrsep(&p, ":"); 517280297Sjkim plaintext = ustrsep(&p, ":"); 518280297Sjkim ciphertext = ustrsep(&p, ":"); 519280297Sjkim if (p[-1] == '\n') { 520290207Sjkim encdec = -1; 521280297Sjkim p[-1] = '\0'; 522290207Sjkim tag = aad = NULL; 523290207Sjkim an = tn = 0; 524280297Sjkim } else { 525290207Sjkim aad = ustrsep(&p, ":"); 526290207Sjkim tag = ustrsep(&p, ":"); 527290207Sjkim if (tag == NULL) { 528290207Sjkim p = (char *)aad; 529290207Sjkim tag = aad = NULL; 530290207Sjkim an = tn = 0; 531290207Sjkim } 532290207Sjkim if (p[-1] == '\n') { 533290207Sjkim encdec = -1; 534290207Sjkim p[-1] = '\0'; 535290207Sjkim } else 536290207Sjkim encdec = atoi(sstrsep(&p, "\n")); 537280297Sjkim } 538109998Smarkm 539280297Sjkim kn = convert(key); 540280297Sjkim in = convert(iv); 541280297Sjkim pn = convert(plaintext); 542280297Sjkim cn = convert(ciphertext); 543290207Sjkim if (aad) { 544290207Sjkim an = convert(aad); 545290207Sjkim tn = convert(tag); 546290207Sjkim } 547109998Smarkm 548280297Sjkim if (!test_cipher 549290207Sjkim (cipher, key, kn, iv, in, plaintext, pn, ciphertext, cn, aad, an, 550290207Sjkim tag, tn, encdec) 551280297Sjkim && !test_digest(cipher, plaintext, pn, ciphertext, cn)) { 552160814Ssimon#ifdef OPENSSL_NO_AES 553280297Sjkim if (strstr(cipher, "AES") == cipher) { 554280297Sjkim fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 555280297Sjkim continue; 556280297Sjkim } 557160814Ssimon#endif 558160814Ssimon#ifdef OPENSSL_NO_DES 559280297Sjkim if (strstr(cipher, "DES") == cipher) { 560280297Sjkim fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 561280297Sjkim continue; 562280297Sjkim } 563160814Ssimon#endif 564160814Ssimon#ifdef OPENSSL_NO_RC4 565280297Sjkim if (strstr(cipher, "RC4") == cipher) { 566280297Sjkim fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 567280297Sjkim continue; 568280297Sjkim } 569160814Ssimon#endif 570162911Ssimon#ifdef OPENSSL_NO_CAMELLIA 571280297Sjkim if (strstr(cipher, "CAMELLIA") == cipher) { 572280297Sjkim fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 573280297Sjkim continue; 574280297Sjkim } 575162911Ssimon#endif 576194206Ssimon#ifdef OPENSSL_NO_SEED 577280297Sjkim if (strstr(cipher, "SEED") == cipher) { 578280297Sjkim fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 579280297Sjkim continue; 580280297Sjkim } 581194206Ssimon#endif 582280297Sjkim fprintf(stderr, "Can't find %s\n", cipher); 583280297Sjkim EXIT(3); 584280297Sjkim } 585280297Sjkim } 586280297Sjkim fclose(f); 587109998Smarkm 588111147Snectar#ifndef OPENSSL_NO_ENGINE 589109998Smarkm ENGINE_cleanup(); 590111147Snectar#endif 591109998Smarkm EVP_cleanup(); 592109998Smarkm CRYPTO_cleanup_all_ex_data(); 593238405Sjkim ERR_remove_thread_state(NULL); 594109998Smarkm ERR_free_strings(); 595109998Smarkm CRYPTO_mem_leaks_fp(stderr); 596109998Smarkm 597109998Smarkm return 0; 598280297Sjkim} 599