1 /* $OpenBSD: enc.c,v 1.24 2021/12/07 20:13:15 tb Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 #include <stdio.h> 60 #include <stdlib.h> 61 #include <string.h> 62 63 #include "apps.h" 64 65 #include <openssl/bio.h> 66 #include <openssl/comp.h> 67 #include <openssl/err.h> 68 #include <openssl/evp.h> 69 #include <openssl/objects.h> 70 #include <openssl/pem.h> 71 #include <openssl/x509.h> 72 73 int set_hex(char *in, unsigned char *out, int size); 74 75 #define SIZE (512) 76 #define BSIZE (8*1024) 77 78 static struct { 79 int base64; 80 char *bufsize; 81 const EVP_CIPHER *cipher; 82 int debug; 83 #ifdef ZLIB 84 int do_zlib; 85 #endif 86 int enc; 87 char *hiv; 88 char *hkey; 89 char *hsalt; 90 char *inf; 91 int iter; 92 char *keyfile; 93 char *keystr; 94 char *md; 95 int nopad; 96 int nosalt; 97 int olb64; 98 char *outf; 99 char *passarg; 100 int pbkdf2; 101 int printkey; 102 int verbose; 103 } enc_config; 104 105 static int 106 enc_opt_cipher(int argc, char **argv, int *argsused) 107 { 108 char *name = argv[0]; 109 110 if (*name++ != '-') 111 return (1); 112 113 if (strcmp(name, "none") == 0) { 114 enc_config.cipher = NULL; 115 *argsused = 1; 116 return (0); 117 } 118 119 if ((enc_config.cipher = EVP_get_cipherbyname(name)) != NULL) { 120 *argsused = 1; 121 return (0); 122 } 123 124 return (1); 125 } 126 127 static const struct option enc_options[] = { 128 { 129 .name = "A", 130 .desc = "Process base64 data on one line (requires -a)", 131 .type = OPTION_FLAG, 132 .opt.flag = &enc_config.olb64, 133 }, 134 { 135 .name = "a", 136 .desc = "Perform base64 encoding/decoding (alias -base64)", 137 .type = OPTION_FLAG, 138 .opt.flag = &enc_config.base64, 139 }, 140 { 141 .name = "base64", 142 .type = OPTION_FLAG, 143 .opt.flag = &enc_config.base64, 144 }, 145 { 146 .name = "bufsize", 147 .argname = "size", 148 .desc = "Specify the buffer size to use for I/O", 149 .type = OPTION_ARG, 150 .opt.arg = &enc_config.bufsize, 151 }, 152 { 153 .name = "d", 154 .desc = "Decrypt the input data", 155 .type = OPTION_VALUE, 156 .opt.value = &enc_config.enc, 157 .value = 0, 158 }, 159 { 160 .name = "debug", 161 .desc = "Print debugging information", 162 .type = OPTION_FLAG, 163 .opt.flag = &enc_config.debug, 164 }, 165 { 166 .name = "e", 167 .desc = "Encrypt the input data (default)", 168 .type = OPTION_VALUE, 169 .opt.value = &enc_config.enc, 170 .value = 1, 171 }, 172 { 173 .name = "in", 174 .argname = "file", 175 .desc = "Input file to read from (default stdin)", 176 .type = OPTION_ARG, 177 .opt.arg = &enc_config.inf, 178 }, 179 { 180 .name = "iter", 181 .argname = "iterations", 182 .desc = "Specify iteration count and force use of PBKDF2", 183 .type = OPTION_ARG_INT, 184 .opt.value = &enc_config.iter, 185 }, 186 { 187 .name = "iv", 188 .argname = "IV", 189 .desc = "IV to use, specified as a hexadecimal string", 190 .type = OPTION_ARG, 191 .opt.arg = &enc_config.hiv, 192 }, 193 { 194 .name = "K", 195 .argname = "key", 196 .desc = "Key to use, specified as a hexadecimal string", 197 .type = OPTION_ARG, 198 .opt.arg = &enc_config.hkey, 199 }, 200 { 201 .name = "k", /* Superseded by -pass. */ 202 .type = OPTION_ARG, 203 .opt.arg = &enc_config.keystr, 204 }, 205 { 206 .name = "kfile", /* Superseded by -pass. */ 207 .type = OPTION_ARG, 208 .opt.arg = &enc_config.keyfile, 209 }, 210 { 211 .name = "md", 212 .argname = "digest", 213 .desc = "Digest to use to create a key from the passphrase", 214 .type = OPTION_ARG, 215 .opt.arg = &enc_config.md, 216 }, 217 { 218 .name = "none", 219 .desc = "Use NULL cipher (no encryption or decryption)", 220 .type = OPTION_ARGV_FUNC, 221 .opt.argvfunc = enc_opt_cipher, 222 }, 223 { 224 .name = "nopad", 225 .desc = "Disable standard block padding", 226 .type = OPTION_FLAG, 227 .opt.flag = &enc_config.nopad, 228 }, 229 { 230 .name = "nosalt", 231 .type = OPTION_VALUE, 232 .opt.value = &enc_config.nosalt, 233 .value = 1, 234 }, 235 { 236 .name = "out", 237 .argname = "file", 238 .desc = "Output file to write to (default stdout)", 239 .type = OPTION_ARG, 240 .opt.arg = &enc_config.outf, 241 }, 242 { 243 .name = "P", 244 .desc = "Print out the salt, key and IV used, then exit\n" 245 " (no encryption or decryption is performed)", 246 .type = OPTION_VALUE, 247 .opt.value = &enc_config.printkey, 248 .value = 2, 249 }, 250 { 251 .name = "p", 252 .desc = "Print out the salt, key and IV used", 253 .type = OPTION_VALUE, 254 .opt.value = &enc_config.printkey, 255 .value = 1, 256 }, 257 { 258 .name = "pass", 259 .argname = "source", 260 .desc = "Password source", 261 .type = OPTION_ARG, 262 .opt.arg = &enc_config.passarg, 263 }, 264 { 265 .name = "pbkdf2", 266 .desc = "Use the pbkdf2 key derivation function", 267 .type = OPTION_FLAG, 268 .opt.flag = &enc_config.pbkdf2, 269 }, 270 { 271 .name = "S", 272 .argname = "salt", 273 .desc = "Salt to use, specified as a hexadecimal string", 274 .type = OPTION_ARG, 275 .opt.arg = &enc_config.hsalt, 276 }, 277 { 278 .name = "salt", 279 .desc = "Use a salt in the key derivation routines (default)", 280 .type = OPTION_VALUE, 281 .opt.value = &enc_config.nosalt, 282 .value = 0, 283 }, 284 { 285 .name = "v", 286 .desc = "Verbose", 287 .type = OPTION_FLAG, 288 .opt.flag = &enc_config.verbose, 289 }, 290 #ifdef ZLIB 291 { 292 .name = "z", 293 .desc = "Perform zlib compression/decompression", 294 .type = OPTION_FLAG, 295 .opt.flag = &enc_config.do_zlib, 296 }, 297 #endif 298 { 299 .name = NULL, 300 .type = OPTION_ARGV_FUNC, 301 .opt.argvfunc = enc_opt_cipher, 302 }, 303 { NULL }, 304 }; 305 306 static void 307 enc_usage(void) 308 { 309 int n = 0; 310 311 fprintf(stderr, "usage: enc -ciphername [-AadePp] [-base64] " 312 "[-bufsize number] [-debug]\n" 313 " [-in file] [-iter iterations] [-iv IV] [-K key] " 314 "[-k password]\n" 315 " [-kfile file] [-md digest] [-none] [-nopad] [-nosalt]\n" 316 " [-out file] [-pass source] [-pbkdf2] [-S salt] [-salt]\n\n"); 317 options_usage(enc_options); 318 fprintf(stderr, "\n"); 319 320 fprintf(stderr, "Valid ciphername values:\n\n"); 321 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n); 322 fprintf(stderr, "\n"); 323 } 324 325 int 326 enc_main(int argc, char **argv) 327 { 328 static const char magic[] = "Salted__"; 329 char mbuf[sizeof magic - 1]; 330 char *strbuf = NULL, *pass = NULL; 331 unsigned char *buff = NULL; 332 int bsize = BSIZE; 333 int ret = 1, inl; 334 unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; 335 unsigned char salt[PKCS5_SALT_LEN]; 336 #ifdef ZLIB 337 BIO *bzl = NULL; 338 #endif 339 EVP_CIPHER_CTX *ctx = NULL; 340 const EVP_MD *dgst = NULL; 341 BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL; 342 BIO *rbio = NULL, *wbio = NULL; 343 #define PROG_NAME_SIZE 39 344 char pname[PROG_NAME_SIZE + 1]; 345 int i; 346 347 if (single_execution) { 348 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { 349 perror("pledge"); 350 exit(1); 351 } 352 } 353 354 memset(&enc_config, 0, sizeof(enc_config)); 355 enc_config.enc = 1; 356 357 /* first check the program name */ 358 program_name(argv[0], pname, sizeof(pname)); 359 360 if (strcmp(pname, "base64") == 0) 361 enc_config.base64 = 1; 362 363 #ifdef ZLIB 364 if (strcmp(pname, "zlib") == 0) 365 enc_config.do_zlib = 1; 366 #endif 367 368 enc_config.cipher = EVP_get_cipherbyname(pname); 369 370 #ifdef ZLIB 371 if (!enc_config.do_zlib && !enc_config.base64 && 372 enc_config.cipher == NULL && strcmp(pname, "enc") != 0) 373 #else 374 if (!enc_config.base64 && enc_config.cipher == NULL && 375 strcmp(pname, "enc") != 0) 376 #endif 377 { 378 BIO_printf(bio_err, "%s is an unknown cipher\n", pname); 379 goto end; 380 } 381 382 if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) { 383 enc_usage(); 384 goto end; 385 } 386 387 if (enc_config.keyfile != NULL) { 388 static char buf[128]; 389 FILE *infile; 390 391 infile = fopen(enc_config.keyfile, "r"); 392 if (infile == NULL) { 393 BIO_printf(bio_err, "unable to read key from '%s'\n", 394 enc_config.keyfile); 395 goto end; 396 } 397 buf[0] = '\0'; 398 if (!fgets(buf, sizeof buf, infile)) { 399 BIO_printf(bio_err, "unable to read key from '%s'\n", 400 enc_config.keyfile); 401 fclose(infile); 402 goto end; 403 } 404 fclose(infile); 405 i = strlen(buf); 406 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 407 buf[--i] = '\0'; 408 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 409 buf[--i] = '\0'; 410 if (i < 1) { 411 BIO_printf(bio_err, "zero length password\n"); 412 goto end; 413 } 414 enc_config.keystr = buf; 415 } 416 417 if (enc_config.md != NULL && 418 (dgst = EVP_get_digestbyname(enc_config.md)) == NULL) { 419 BIO_printf(bio_err, 420 "%s is an unsupported message digest type\n", 421 enc_config.md); 422 goto end; 423 } 424 if (dgst == NULL) { 425 dgst = EVP_sha256(); 426 } 427 428 if (enc_config.bufsize != NULL) { 429 char *p = enc_config.bufsize; 430 unsigned long n; 431 432 /* XXX - provide an OPTION_ARG_DISKUNIT. */ 433 for (n = 0; *p != '\0'; p++) { 434 i = *p; 435 if ((i <= '9') && (i >= '0')) 436 n = n * 10 + i - '0'; 437 else if (i == 'k') { 438 n *= 1024; 439 p++; 440 break; 441 } 442 } 443 if (*p != '\0') { 444 BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); 445 goto end; 446 } 447 /* It must be large enough for a base64 encoded line. */ 448 if (enc_config.base64 && n < 80) 449 n = 80; 450 451 bsize = (int)n; 452 if (enc_config.verbose) 453 BIO_printf(bio_err, "bufsize=%d\n", bsize); 454 } 455 strbuf = malloc(SIZE); 456 buff = malloc(EVP_ENCODE_LENGTH(bsize)); 457 if ((buff == NULL) || (strbuf == NULL)) { 458 BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize)); 459 goto end; 460 } 461 in = BIO_new(BIO_s_file()); 462 out = BIO_new(BIO_s_file()); 463 if ((in == NULL) || (out == NULL)) { 464 ERR_print_errors(bio_err); 465 goto end; 466 } 467 if (enc_config.debug) { 468 BIO_set_callback(in, BIO_debug_callback); 469 BIO_set_callback(out, BIO_debug_callback); 470 BIO_set_callback_arg(in, (char *) bio_err); 471 BIO_set_callback_arg(out, (char *) bio_err); 472 } 473 if (enc_config.inf == NULL) { 474 if (enc_config.bufsize != NULL) 475 setvbuf(stdin, (char *) NULL, _IONBF, 0); 476 BIO_set_fp(in, stdin, BIO_NOCLOSE); 477 } else { 478 if (BIO_read_filename(in, enc_config.inf) <= 0) { 479 perror(enc_config.inf); 480 goto end; 481 } 482 } 483 484 if (!enc_config.keystr && enc_config.passarg) { 485 if (!app_passwd(bio_err, enc_config.passarg, NULL, 486 &pass, NULL)) { 487 BIO_printf(bio_err, "Error getting password\n"); 488 goto end; 489 } 490 enc_config.keystr = pass; 491 } 492 if (enc_config.keystr == NULL && enc_config.cipher != NULL && 493 enc_config.hkey == NULL) { 494 for (;;) { 495 char buf[200]; 496 int retval; 497 498 retval = snprintf(buf, sizeof buf, 499 "enter %s %s password:", 500 OBJ_nid2ln(EVP_CIPHER_nid(enc_config.cipher)), 501 enc_config.enc ? "encryption" : "decryption"); 502 if ((size_t)retval >= sizeof buf) { 503 BIO_printf(bio_err, 504 "Password prompt too long\n"); 505 goto end; 506 } 507 strbuf[0] = '\0'; 508 i = EVP_read_pw_string((char *)strbuf, SIZE, buf, 509 enc_config.enc); 510 if (i == 0) { 511 if (strbuf[0] == '\0') { 512 ret = 1; 513 goto end; 514 } 515 enc_config.keystr = strbuf; 516 break; 517 } 518 if (i < 0) { 519 BIO_printf(bio_err, "bad password read\n"); 520 goto end; 521 } 522 } 523 } 524 if (enc_config.outf == NULL) { 525 BIO_set_fp(out, stdout, BIO_NOCLOSE); 526 if (enc_config.bufsize != NULL) 527 setvbuf(stdout, (char *)NULL, _IONBF, 0); 528 } else { 529 if (BIO_write_filename(out, enc_config.outf) <= 0) { 530 perror(enc_config.outf); 531 goto end; 532 } 533 } 534 535 rbio = in; 536 wbio = out; 537 538 #ifdef ZLIB 539 if (do_zlib) { 540 if ((bzl = BIO_new(BIO_f_zlib())) == NULL) 541 goto end; 542 if (enc) 543 wbio = BIO_push(bzl, wbio); 544 else 545 rbio = BIO_push(bzl, rbio); 546 } 547 #endif 548 549 if (enc_config.base64) { 550 if ((b64 = BIO_new(BIO_f_base64())) == NULL) 551 goto end; 552 if (enc_config.debug) { 553 BIO_set_callback(b64, BIO_debug_callback); 554 BIO_set_callback_arg(b64, (char *) bio_err); 555 } 556 if (enc_config.olb64) 557 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 558 if (enc_config.enc) 559 wbio = BIO_push(b64, wbio); 560 else 561 rbio = BIO_push(b64, rbio); 562 } 563 if (enc_config.cipher != NULL) { 564 /* 565 * Note that keystr is NULL if a key was passed on the command 566 * line, so we get no salt in that case. Is this a bug? 567 */ 568 if (enc_config.keystr != NULL) { 569 /* 570 * Salt handling: if encrypting generate a salt and 571 * write to output BIO. If decrypting read salt from 572 * input BIO. 573 */ 574 unsigned char *sptr; 575 if (enc_config.nosalt) 576 sptr = NULL; 577 else { 578 if (enc_config.enc) { 579 if (enc_config.hsalt) { 580 if (!set_hex(enc_config.hsalt, salt, sizeof salt)) { 581 BIO_printf(bio_err, 582 "invalid hex salt value\n"); 583 goto end; 584 } 585 } else 586 arc4random_buf(salt, 587 sizeof(salt)); 588 /* 589 * If -P option then don't bother 590 * writing 591 */ 592 if ((enc_config.printkey != 2) 593 && (BIO_write(wbio, magic, 594 sizeof magic - 1) != sizeof magic - 1 595 || BIO_write(wbio, 596 (char *) salt, 597 sizeof salt) != sizeof salt)) { 598 BIO_printf(bio_err, "error writing output file\n"); 599 goto end; 600 } 601 } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf 602 || BIO_read(rbio, 603 (unsigned char *) salt, 604 sizeof salt) != sizeof salt) { 605 BIO_printf(bio_err, "error reading input file\n"); 606 goto end; 607 } else if (memcmp(mbuf, magic, sizeof magic - 1)) { 608 BIO_printf(bio_err, "bad magic number\n"); 609 goto end; 610 } 611 sptr = salt; 612 } 613 if (enc_config.pbkdf2 == 1 || enc_config.iter > 0) { 614 /* 615 * derive key and default iv 616 * concatenated into a temporary buffer 617 */ 618 unsigned char tmpkeyiv[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH]; 619 int iklen = EVP_CIPHER_key_length(enc_config.cipher); 620 int ivlen = EVP_CIPHER_iv_length(enc_config.cipher); 621 /* not needed if HASH_UPDATE() is fixed : */ 622 int islen = (sptr != NULL ? sizeof(salt) : 0); 623 624 if (enc_config.iter == 0) 625 enc_config.iter = 10000; 626 627 if (!PKCS5_PBKDF2_HMAC(enc_config.keystr, 628 strlen(enc_config.keystr), sptr, islen, 629 enc_config.iter, dgst, iklen+ivlen, tmpkeyiv)) { 630 BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n"); 631 goto end; 632 } 633 /* split and move data back to global buffer */ 634 memcpy(key, tmpkeyiv, iklen); 635 memcpy(iv, tmpkeyiv + iklen, ivlen); 636 explicit_bzero(tmpkeyiv, sizeof tmpkeyiv); 637 } else { 638 EVP_BytesToKey(enc_config.cipher, dgst, sptr, 639 (unsigned char *)enc_config.keystr, 640 strlen(enc_config.keystr), 1, key, iv); 641 } 642 643 /* 644 * zero the complete buffer or the string passed from 645 * the command line bug picked up by Larry J. Hughes 646 * Jr. <hughes@indiana.edu> 647 */ 648 if (enc_config.keystr == strbuf) 649 explicit_bzero(enc_config.keystr, SIZE); 650 else 651 explicit_bzero(enc_config.keystr, 652 strlen(enc_config.keystr)); 653 } 654 if (enc_config.hiv != NULL && 655 !set_hex(enc_config.hiv, iv, sizeof iv)) { 656 BIO_printf(bio_err, "invalid hex iv value\n"); 657 goto end; 658 } 659 if (enc_config.hiv == NULL && enc_config.keystr == NULL && 660 EVP_CIPHER_iv_length(enc_config.cipher) != 0) { 661 /* 662 * No IV was explicitly set and no IV was generated 663 * during EVP_BytesToKey. Hence the IV is undefined, 664 * making correct decryption impossible. 665 */ 666 BIO_printf(bio_err, "iv undefined\n"); 667 goto end; 668 } 669 if (enc_config.hkey != NULL && 670 !set_hex(enc_config.hkey, key, sizeof key)) { 671 BIO_printf(bio_err, "invalid hex key value\n"); 672 goto end; 673 } 674 if ((benc = BIO_new(BIO_f_cipher())) == NULL) 675 goto end; 676 677 /* 678 * Since we may be changing parameters work on the encryption 679 * context rather than calling BIO_set_cipher(). 680 */ 681 682 BIO_get_cipher_ctx(benc, &ctx); 683 684 if (!EVP_CipherInit_ex(ctx, enc_config.cipher, NULL, NULL, 685 NULL, enc_config.enc)) { 686 BIO_printf(bio_err, "Error setting cipher %s\n", 687 EVP_CIPHER_name(enc_config.cipher)); 688 ERR_print_errors(bio_err); 689 goto end; 690 } 691 if (enc_config.nopad) 692 EVP_CIPHER_CTX_set_padding(ctx, 0); 693 694 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 695 enc_config.enc)) { 696 BIO_printf(bio_err, "Error setting cipher %s\n", 697 EVP_CIPHER_name(enc_config.cipher)); 698 ERR_print_errors(bio_err); 699 goto end; 700 } 701 if (enc_config.debug) { 702 BIO_set_callback(benc, BIO_debug_callback); 703 BIO_set_callback_arg(benc, (char *) bio_err); 704 } 705 if (enc_config.printkey) { 706 int key_len, iv_len; 707 708 if (!enc_config.nosalt) { 709 printf("salt="); 710 for (i = 0; i < (int) sizeof(salt); i++) 711 printf("%02X", salt[i]); 712 printf("\n"); 713 } 714 key_len = EVP_CIPHER_key_length(enc_config.cipher); 715 if (key_len > 0) { 716 printf("key="); 717 for (i = 0; i < key_len; i++) 718 printf("%02X", key[i]); 719 printf("\n"); 720 } 721 iv_len = EVP_CIPHER_iv_length(enc_config.cipher); 722 if (iv_len > 0) { 723 printf("iv ="); 724 for (i = 0; i < iv_len; i++) 725 printf("%02X", iv[i]); 726 printf("\n"); 727 } 728 if (enc_config.printkey == 2) { 729 ret = 0; 730 goto end; 731 } 732 } 733 } 734 /* Only encrypt/decrypt as we write the file */ 735 if (benc != NULL) 736 wbio = BIO_push(benc, wbio); 737 738 for (;;) { 739 inl = BIO_read(rbio, (char *) buff, bsize); 740 if (inl <= 0) 741 break; 742 if (BIO_write(wbio, (char *) buff, inl) != inl) { 743 BIO_printf(bio_err, "error writing output file\n"); 744 goto end; 745 } 746 } 747 if (!BIO_flush(wbio)) { 748 BIO_printf(bio_err, "bad decrypt\n"); 749 goto end; 750 } 751 ret = 0; 752 if (enc_config.verbose) { 753 BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); 754 BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); 755 } 756 end: 757 ERR_print_errors(bio_err); 758 free(strbuf); 759 free(buff); 760 BIO_free(in); 761 BIO_free_all(out); 762 BIO_free(benc); 763 BIO_free(b64); 764 #ifdef ZLIB 765 BIO_free(bzl); 766 #endif 767 free(pass); 768 769 return (ret); 770 } 771 772 int 773 set_hex(char *in, unsigned char *out, int size) 774 { 775 int i, n; 776 unsigned char j; 777 778 n = strlen(in); 779 if (n > (size * 2)) { 780 BIO_printf(bio_err, "hex string is too long\n"); 781 return (0); 782 } 783 memset(out, 0, size); 784 for (i = 0; i < n; i++) { 785 j = (unsigned char) *in; 786 *(in++) = '\0'; 787 if (j == 0) 788 break; 789 if ((j >= '0') && (j <= '9')) 790 j -= '0'; 791 else if ((j >= 'A') && (j <= 'F')) 792 j = j - 'A' + 10; 793 else if ((j >= 'a') && (j <= 'f')) 794 j = j - 'a' + 10; 795 else { 796 BIO_printf(bio_err, "non-hex digit\n"); 797 return (0); 798 } 799 if (i & 1) 800 out[i / 2] |= j; 801 else 802 out[i / 2] = (j << 4); 803 } 804 return (1); 805 } 806