1 /* $OpenBSD: evptest.c,v 1.13 2023/11/19 13:11:06 tb Exp $ */ 2 /* Written by Ben Laurie, 2001 */ 3 /* 4 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * 3. All advertising materials mentioning features or use of this 19 * software must display the following acknowledgment: 20 * "This product includes software developed by the OpenSSL Project 21 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 22 * 23 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 24 * endorse or promote products derived from this software without 25 * prior written permission. For written permission, please contact 26 * openssl-core@openssl.org. 27 * 28 * 5. Products derived from this software may not be called "OpenSSL" 29 * nor may "OpenSSL" appear in their names without prior written 30 * permission of the OpenSSL Project. 31 * 32 * 6. Redistributions of any form whatsoever must retain the following 33 * acknowledgment: 34 * "This product includes software developed by the OpenSSL Project 35 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 36 * 37 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 38 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 48 * OF THE POSSIBILITY OF SUCH DAMAGE. 49 */ 50 51 #include <stdio.h> 52 #include <string.h> 53 54 #include <openssl/opensslconf.h> 55 #include <openssl/evp.h> 56 #include <openssl/err.h> 57 #include <openssl/conf.h> 58 59 int verbose; 60 61 static void 62 hexdump(FILE *f, const char *title, const unsigned char *s, int l) 63 { 64 int n = 0; 65 66 fprintf(f, "%s",title); 67 for (; n < l; ++n) { 68 if ((n % 16) == 0) 69 fprintf(f, "\n%04x",n); 70 fprintf(f, " %02x",s[n]); 71 } 72 fprintf(f, "\n"); 73 } 74 75 static int 76 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!\n"); 85 exit(4); 86 } 87 if (sscanf((char *)s, "%2x", &n) != 1) { 88 fprintf(stderr, "Invalid hex value at %s\n", s); 89 exit(4); 90 } 91 92 *d = (unsigned char)n; 93 } 94 return s - d; 95 } 96 97 static char * 98 sstrsep(char **string, const char *delim) 99 { 100 char isdelim[256]; 101 char *token = *string; 102 103 if (**string == 0) 104 return NULL; 105 106 memset(isdelim, 0, 256); 107 isdelim[0] = 1; 108 109 while (*delim) { 110 isdelim[(unsigned char)(*delim)] = 1; 111 delim++; 112 } 113 114 while (!isdelim[(unsigned char)(**string)]) { 115 (*string)++; 116 } 117 118 if (**string) { 119 **string = 0; 120 (*string)++; 121 } 122 123 return token; 124 } 125 126 static unsigned char * 127 ustrsep(char **p, const char *sep) 128 { 129 return (unsigned char *)sstrsep(p, sep); 130 } 131 132 static int 133 test1_exit(int ec) 134 { 135 exit(ec); 136 return(0); /* To keep some compilers quiet */ 137 } 138 139 static void 140 test1(const EVP_CIPHER *c, const unsigned char *key, int kn, 141 const unsigned char *iv, int in, const unsigned char *plaintext, int pn, 142 const unsigned char *ciphertext, int cn, int encdec) 143 { 144 EVP_CIPHER_CTX *ctx; 145 unsigned char out[4096]; 146 const unsigned char *eiv; 147 int outl, outl2; 148 149 if (verbose) { 150 printf("Testing cipher %s%s\n", EVP_CIPHER_name(c), 151 (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)"))); 152 hexdump(stdout, "Key",key,kn); 153 if (in) 154 hexdump(stdout, "IV",iv,in); 155 hexdump(stdout, "Plaintext",plaintext,pn); 156 hexdump(stdout, "Ciphertext",ciphertext,cn); 157 } 158 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 if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { 165 fprintf(stderr, "EVP_CIPHER_CTX_new failed\n"); 166 ERR_print_errors_fp(stderr); 167 test1_exit(12); 168 } 169 EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); 170 if (encdec != 0) { 171 eiv = iv; 172 if (EVP_CIPHER_mode(c) == EVP_CIPH_WRAP_MODE && in == 0) 173 eiv = NULL; 174 if (!EVP_EncryptInit_ex(ctx, c, NULL, key, eiv)) { 175 fprintf(stderr, "EncryptInit failed\n"); 176 ERR_print_errors_fp(stderr); 177 test1_exit(10); 178 } 179 EVP_CIPHER_CTX_set_padding(ctx, 0); 180 181 if (!EVP_EncryptUpdate(ctx, out, &outl, plaintext, pn)) { 182 fprintf(stderr, "Encrypt failed\n"); 183 ERR_print_errors_fp(stderr); 184 test1_exit(6); 185 } 186 if (!EVP_EncryptFinal_ex(ctx, out + outl, &outl2)) { 187 fprintf(stderr, "EncryptFinal failed\n"); 188 ERR_print_errors_fp(stderr); 189 test1_exit(7); 190 } 191 192 if (outl + outl2 != cn) { 193 fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n", 194 outl + outl2, cn); 195 test1_exit(8); 196 } 197 198 if (memcmp(out, ciphertext, cn)) { 199 fprintf(stderr, "Ciphertext mismatch\n"); 200 hexdump(stderr, "Got",out,cn); 201 hexdump(stderr, "Expected",ciphertext,cn); 202 test1_exit(9); 203 } 204 } 205 206 if (encdec <= 0) { 207 eiv = iv; 208 if (EVP_CIPHER_mode(c) == EVP_CIPH_WRAP_MODE && in == 0) 209 eiv = NULL; 210 if (!EVP_DecryptInit_ex(ctx, c,NULL, key, eiv)) { 211 fprintf(stderr, "DecryptInit failed\n"); 212 ERR_print_errors_fp(stderr); 213 test1_exit(11); 214 } 215 EVP_CIPHER_CTX_set_padding(ctx, 0); 216 217 if (!EVP_DecryptUpdate(ctx, out, &outl, ciphertext, cn)) { 218 fprintf(stderr, "Decrypt failed\n"); 219 ERR_print_errors_fp(stderr); 220 test1_exit(6); 221 } 222 if (!EVP_DecryptFinal_ex(ctx, out + outl, &outl2)) { 223 fprintf(stderr, "DecryptFinal failed\n"); 224 ERR_print_errors_fp(stderr); 225 test1_exit(7); 226 } 227 228 if (outl + outl2 != pn) { 229 fprintf(stderr, "Plaintext length mismatch got %d expected %d\n", 230 outl + outl2, pn); 231 test1_exit(8); 232 } 233 234 if (memcmp(out, plaintext, pn)) { 235 fprintf(stderr, "Plaintext mismatch\n"); 236 hexdump(stderr, "Got",out,pn); 237 hexdump(stderr, "Expected",plaintext,pn); 238 test1_exit(9); 239 } 240 } 241 242 EVP_CIPHER_CTX_free(ctx); 243 244 if (verbose) 245 printf("\n"); 246 } 247 248 static int 249 test_cipher(const char *cipher, const unsigned char *key, int kn, 250 const unsigned char *iv, int in, const unsigned char *plaintext, int pn, 251 const unsigned char *ciphertext, int cn, int encdec) 252 { 253 const EVP_CIPHER *c; 254 255 c = EVP_get_cipherbyname(cipher); 256 if (!c) 257 return 0; 258 259 test1(c, key, kn, iv, in, plaintext, pn, ciphertext, cn, encdec); 260 261 return 1; 262 } 263 264 static int 265 test_digest(const char *digest, const unsigned char *plaintext, int pn, 266 const unsigned char *ciphertext, unsigned int cn) 267 { 268 const EVP_MD *d; 269 EVP_MD_CTX *ctx; 270 unsigned char md[EVP_MAX_MD_SIZE]; 271 unsigned int mdn; 272 273 d = EVP_get_digestbyname(digest); 274 if (!d) 275 return 0; 276 277 if (verbose) { 278 printf("Testing digest %s\n",EVP_MD_name(d)); 279 hexdump(stdout, "Plaintext",plaintext,pn); 280 hexdump(stdout, "Digest",ciphertext,cn); 281 } 282 283 if ((ctx = EVP_MD_CTX_new()) == NULL) { 284 fprintf(stderr, "EVP_CIPHER_CTX_new failed\n"); 285 ERR_print_errors_fp(stderr); 286 test1_exit(104); 287 } 288 if (!EVP_DigestInit_ex(ctx, d, NULL)) { 289 fprintf(stderr, "DigestInit failed\n"); 290 ERR_print_errors_fp(stderr); 291 exit(100); 292 } 293 if (!EVP_DigestUpdate(ctx, plaintext, pn)) { 294 fprintf(stderr, "DigestUpdate failed\n"); 295 ERR_print_errors_fp(stderr); 296 exit(101); 297 } 298 if (!EVP_DigestFinal_ex(ctx, md, &mdn)) { 299 fprintf(stderr, "DigestFinal failed\n"); 300 ERR_print_errors_fp(stderr); 301 exit(101); 302 } 303 EVP_MD_CTX_free(ctx); 304 ctx = NULL; 305 306 if (mdn != cn) { 307 fprintf(stderr, "Digest length mismatch, got %d expected %d\n",mdn,cn); 308 exit(102); 309 } 310 311 if (memcmp(md, ciphertext, cn)) { 312 fprintf(stderr, "Digest mismatch\n"); 313 hexdump(stderr, "Got",md,cn); 314 hexdump(stderr, "Expected",ciphertext,cn); 315 exit(103); 316 } 317 if (verbose) 318 printf("\n"); 319 320 return 1; 321 } 322 323 int 324 main(int argc, char **argv) 325 { 326 const char *szTestFile; 327 FILE *f; 328 329 if (argc != 2 && argc != 3) { 330 fprintf(stderr, "%s <test file>\n",argv[0]); 331 exit(1); 332 } 333 if (argc == 3 && strcmp(argv[1], "-v") == 0) { 334 verbose = 1; 335 argv++; 336 argc--; 337 } 338 339 szTestFile = argv[1]; 340 341 f=fopen(szTestFile, "r"); 342 if (!f) { 343 perror(szTestFile); 344 exit(2); 345 } 346 347 /* Load up the software EVP_CIPHER and EVP_MD definitions */ 348 OpenSSL_add_all_ciphers(); 349 OpenSSL_add_all_digests(); 350 351 for (;;) { 352 char line[8 * 1024]; 353 char *p; 354 char *cipher; 355 unsigned char *iv, *key, *plaintext, *ciphertext; 356 int encdec; 357 int kn, in, pn, cn; 358 359 if (!fgets((char *)line, sizeof line, f)) 360 break; 361 if (line[0] == '#' || line[0] == '\n') 362 continue; 363 p = line; 364 cipher=sstrsep(&p, ":"); 365 key=ustrsep(&p, ":"); 366 iv=ustrsep(&p, ":"); 367 plaintext=ustrsep(&p, ":"); 368 ciphertext=ustrsep(&p, ":"); 369 if (p[-1] == '\n') { 370 p[-1] = '\0'; 371 encdec = -1; 372 } else { 373 encdec = atoi(sstrsep(&p, "\n")); 374 } 375 376 377 kn = convert(key); 378 in = convert(iv); 379 pn = convert(plaintext); 380 cn = convert(ciphertext); 381 382 if (!test_cipher(cipher, key, kn, iv, in, plaintext, pn, ciphertext, cn, encdec) && 383 !test_digest(cipher, plaintext, pn, ciphertext, cn)) { 384 #ifdef OPENSSL_NO_AES 385 if (strstr(cipher, "AES") == cipher && verbose) { 386 if (verbose) 387 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 388 continue; 389 } 390 #endif 391 #ifdef OPENSSL_NO_DES 392 if (strstr(cipher, "DES") == cipher && verbose) { 393 if (verbose) 394 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 395 continue; 396 } 397 #endif 398 #ifdef OPENSSL_NO_RC4 399 if (strstr(cipher, "RC4") == cipher && verbose) { 400 if (verbose) 401 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 402 continue; 403 } 404 #endif 405 #ifdef OPENSSL_NO_CAMELLIA 406 if (strstr(cipher, "CAMELLIA") == cipher && verbose) { 407 if (verbose) 408 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 409 continue; 410 } 411 #endif 412 #ifdef OPENSSL_NO_SEED 413 if (strstr(cipher, "SEED") == cipher) { 414 if (verbose) 415 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 416 continue; 417 } 418 #endif 419 #ifdef OPENSSL_NO_CHACHA 420 if (strstr(cipher, "ChaCha") == cipher) { 421 if (verbose) 422 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 423 continue; 424 } 425 #endif 426 #ifdef OPENSSL_NO_GOST 427 if (strstr(cipher, "md_gost") == cipher || 428 strstr(cipher, "streebog") == cipher) { 429 if (verbose) 430 fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 431 continue; 432 } 433 #endif 434 fprintf(stderr, "Can't find %s\n",cipher); 435 exit(3); 436 } 437 } 438 fclose(f); 439 440 EVP_cleanup(); 441 CRYPTO_cleanup_all_ex_data(); 442 ERR_remove_thread_state(NULL); 443 ERR_free_strings(); 444 CRYPTO_mem_leaks_fp(stderr); 445 446 return 0; 447 } 448