1 /* $OpenBSD: enc.c,v 1.25 2022/11/11 17:07:39 joshua 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 (pledge("stdio cpath wpath rpath tty", NULL) == -1) { 348 perror("pledge"); 349 exit(1); 350 } 351 352 memset(&enc_config, 0, sizeof(enc_config)); 353 enc_config.enc = 1; 354 355 /* first check the program name */ 356 program_name(argv[0], pname, sizeof(pname)); 357 358 if (strcmp(pname, "base64") == 0) 359 enc_config.base64 = 1; 360 361 #ifdef ZLIB 362 if (strcmp(pname, "zlib") == 0) 363 enc_config.do_zlib = 1; 364 #endif 365 366 enc_config.cipher = EVP_get_cipherbyname(pname); 367 368 #ifdef ZLIB 369 if (!enc_config.do_zlib && !enc_config.base64 && 370 enc_config.cipher == NULL && strcmp(pname, "enc") != 0) 371 #else 372 if (!enc_config.base64 && enc_config.cipher == NULL && 373 strcmp(pname, "enc") != 0) 374 #endif 375 { 376 BIO_printf(bio_err, "%s is an unknown cipher\n", pname); 377 goto end; 378 } 379 380 if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) { 381 enc_usage(); 382 goto end; 383 } 384 385 if (enc_config.keyfile != NULL) { 386 static char buf[128]; 387 FILE *infile; 388 389 infile = fopen(enc_config.keyfile, "r"); 390 if (infile == NULL) { 391 BIO_printf(bio_err, "unable to read key from '%s'\n", 392 enc_config.keyfile); 393 goto end; 394 } 395 buf[0] = '\0'; 396 if (!fgets(buf, sizeof buf, infile)) { 397 BIO_printf(bio_err, "unable to read key from '%s'\n", 398 enc_config.keyfile); 399 fclose(infile); 400 goto end; 401 } 402 fclose(infile); 403 i = strlen(buf); 404 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 405 buf[--i] = '\0'; 406 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 407 buf[--i] = '\0'; 408 if (i < 1) { 409 BIO_printf(bio_err, "zero length password\n"); 410 goto end; 411 } 412 enc_config.keystr = buf; 413 } 414 415 if (enc_config.md != NULL && 416 (dgst = EVP_get_digestbyname(enc_config.md)) == NULL) { 417 BIO_printf(bio_err, 418 "%s is an unsupported message digest type\n", 419 enc_config.md); 420 goto end; 421 } 422 if (dgst == NULL) { 423 dgst = EVP_sha256(); 424 } 425 426 if (enc_config.bufsize != NULL) { 427 char *p = enc_config.bufsize; 428 unsigned long n; 429 430 /* XXX - provide an OPTION_ARG_DISKUNIT. */ 431 for (n = 0; *p != '\0'; p++) { 432 i = *p; 433 if ((i <= '9') && (i >= '0')) 434 n = n * 10 + i - '0'; 435 else if (i == 'k') { 436 n *= 1024; 437 p++; 438 break; 439 } 440 } 441 if (*p != '\0') { 442 BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); 443 goto end; 444 } 445 /* It must be large enough for a base64 encoded line. */ 446 if (enc_config.base64 && n < 80) 447 n = 80; 448 449 bsize = (int)n; 450 if (enc_config.verbose) 451 BIO_printf(bio_err, "bufsize=%d\n", bsize); 452 } 453 strbuf = malloc(SIZE); 454 buff = malloc(EVP_ENCODE_LENGTH(bsize)); 455 if ((buff == NULL) || (strbuf == NULL)) { 456 BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize)); 457 goto end; 458 } 459 in = BIO_new(BIO_s_file()); 460 out = BIO_new(BIO_s_file()); 461 if ((in == NULL) || (out == NULL)) { 462 ERR_print_errors(bio_err); 463 goto end; 464 } 465 if (enc_config.debug) { 466 BIO_set_callback(in, BIO_debug_callback); 467 BIO_set_callback(out, BIO_debug_callback); 468 BIO_set_callback_arg(in, (char *) bio_err); 469 BIO_set_callback_arg(out, (char *) bio_err); 470 } 471 if (enc_config.inf == NULL) { 472 if (enc_config.bufsize != NULL) 473 setvbuf(stdin, (char *) NULL, _IONBF, 0); 474 BIO_set_fp(in, stdin, BIO_NOCLOSE); 475 } else { 476 if (BIO_read_filename(in, enc_config.inf) <= 0) { 477 perror(enc_config.inf); 478 goto end; 479 } 480 } 481 482 if (!enc_config.keystr && enc_config.passarg) { 483 if (!app_passwd(bio_err, enc_config.passarg, NULL, 484 &pass, NULL)) { 485 BIO_printf(bio_err, "Error getting password\n"); 486 goto end; 487 } 488 enc_config.keystr = pass; 489 } 490 if (enc_config.keystr == NULL && enc_config.cipher != NULL && 491 enc_config.hkey == NULL) { 492 for (;;) { 493 char buf[200]; 494 int retval; 495 496 retval = snprintf(buf, sizeof buf, 497 "enter %s %s password:", 498 OBJ_nid2ln(EVP_CIPHER_nid(enc_config.cipher)), 499 enc_config.enc ? "encryption" : "decryption"); 500 if ((size_t)retval >= sizeof buf) { 501 BIO_printf(bio_err, 502 "Password prompt too long\n"); 503 goto end; 504 } 505 strbuf[0] = '\0'; 506 i = EVP_read_pw_string((char *)strbuf, SIZE, buf, 507 enc_config.enc); 508 if (i == 0) { 509 if (strbuf[0] == '\0') { 510 ret = 1; 511 goto end; 512 } 513 enc_config.keystr = strbuf; 514 break; 515 } 516 if (i < 0) { 517 BIO_printf(bio_err, "bad password read\n"); 518 goto end; 519 } 520 } 521 } 522 if (enc_config.outf == NULL) { 523 BIO_set_fp(out, stdout, BIO_NOCLOSE); 524 if (enc_config.bufsize != NULL) 525 setvbuf(stdout, (char *)NULL, _IONBF, 0); 526 } else { 527 if (BIO_write_filename(out, enc_config.outf) <= 0) { 528 perror(enc_config.outf); 529 goto end; 530 } 531 } 532 533 rbio = in; 534 wbio = out; 535 536 #ifdef ZLIB 537 if (do_zlib) { 538 if ((bzl = BIO_new(BIO_f_zlib())) == NULL) 539 goto end; 540 if (enc) 541 wbio = BIO_push(bzl, wbio); 542 else 543 rbio = BIO_push(bzl, rbio); 544 } 545 #endif 546 547 if (enc_config.base64) { 548 if ((b64 = BIO_new(BIO_f_base64())) == NULL) 549 goto end; 550 if (enc_config.debug) { 551 BIO_set_callback(b64, BIO_debug_callback); 552 BIO_set_callback_arg(b64, (char *) bio_err); 553 } 554 if (enc_config.olb64) 555 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 556 if (enc_config.enc) 557 wbio = BIO_push(b64, wbio); 558 else 559 rbio = BIO_push(b64, rbio); 560 } 561 if (enc_config.cipher != NULL) { 562 /* 563 * Note that keystr is NULL if a key was passed on the command 564 * line, so we get no salt in that case. Is this a bug? 565 */ 566 if (enc_config.keystr != NULL) { 567 /* 568 * Salt handling: if encrypting generate a salt and 569 * write to output BIO. If decrypting read salt from 570 * input BIO. 571 */ 572 unsigned char *sptr; 573 if (enc_config.nosalt) 574 sptr = NULL; 575 else { 576 if (enc_config.enc) { 577 if (enc_config.hsalt) { 578 if (!set_hex(enc_config.hsalt, salt, sizeof salt)) { 579 BIO_printf(bio_err, 580 "invalid hex salt value\n"); 581 goto end; 582 } 583 } else 584 arc4random_buf(salt, 585 sizeof(salt)); 586 /* 587 * If -P option then don't bother 588 * writing 589 */ 590 if ((enc_config.printkey != 2) 591 && (BIO_write(wbio, magic, 592 sizeof magic - 1) != sizeof magic - 1 593 || BIO_write(wbio, 594 (char *) salt, 595 sizeof salt) != sizeof salt)) { 596 BIO_printf(bio_err, "error writing output file\n"); 597 goto end; 598 } 599 } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf 600 || BIO_read(rbio, 601 (unsigned char *) salt, 602 sizeof salt) != sizeof salt) { 603 BIO_printf(bio_err, "error reading input file\n"); 604 goto end; 605 } else if (memcmp(mbuf, magic, sizeof magic - 1)) { 606 BIO_printf(bio_err, "bad magic number\n"); 607 goto end; 608 } 609 sptr = salt; 610 } 611 if (enc_config.pbkdf2 == 1 || enc_config.iter > 0) { 612 /* 613 * derive key and default iv 614 * concatenated into a temporary buffer 615 */ 616 unsigned char tmpkeyiv[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH]; 617 int iklen = EVP_CIPHER_key_length(enc_config.cipher); 618 int ivlen = EVP_CIPHER_iv_length(enc_config.cipher); 619 /* not needed if HASH_UPDATE() is fixed : */ 620 int islen = (sptr != NULL ? sizeof(salt) : 0); 621 622 if (enc_config.iter == 0) 623 enc_config.iter = 10000; 624 625 if (!PKCS5_PBKDF2_HMAC(enc_config.keystr, 626 strlen(enc_config.keystr), sptr, islen, 627 enc_config.iter, dgst, iklen+ivlen, tmpkeyiv)) { 628 BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n"); 629 goto end; 630 } 631 /* split and move data back to global buffer */ 632 memcpy(key, tmpkeyiv, iklen); 633 memcpy(iv, tmpkeyiv + iklen, ivlen); 634 explicit_bzero(tmpkeyiv, sizeof tmpkeyiv); 635 } else { 636 EVP_BytesToKey(enc_config.cipher, dgst, sptr, 637 (unsigned char *)enc_config.keystr, 638 strlen(enc_config.keystr), 1, key, iv); 639 } 640 641 /* 642 * zero the complete buffer or the string passed from 643 * the command line bug picked up by Larry J. Hughes 644 * Jr. <hughes@indiana.edu> 645 */ 646 if (enc_config.keystr == strbuf) 647 explicit_bzero(enc_config.keystr, SIZE); 648 else 649 explicit_bzero(enc_config.keystr, 650 strlen(enc_config.keystr)); 651 } 652 if (enc_config.hiv != NULL && 653 !set_hex(enc_config.hiv, iv, sizeof iv)) { 654 BIO_printf(bio_err, "invalid hex iv value\n"); 655 goto end; 656 } 657 if (enc_config.hiv == NULL && enc_config.keystr == NULL && 658 EVP_CIPHER_iv_length(enc_config.cipher) != 0) { 659 /* 660 * No IV was explicitly set and no IV was generated 661 * during EVP_BytesToKey. Hence the IV is undefined, 662 * making correct decryption impossible. 663 */ 664 BIO_printf(bio_err, "iv undefined\n"); 665 goto end; 666 } 667 if (enc_config.hkey != NULL && 668 !set_hex(enc_config.hkey, key, sizeof key)) { 669 BIO_printf(bio_err, "invalid hex key value\n"); 670 goto end; 671 } 672 if ((benc = BIO_new(BIO_f_cipher())) == NULL) 673 goto end; 674 675 /* 676 * Since we may be changing parameters work on the encryption 677 * context rather than calling BIO_set_cipher(). 678 */ 679 680 BIO_get_cipher_ctx(benc, &ctx); 681 682 if (!EVP_CipherInit_ex(ctx, enc_config.cipher, NULL, NULL, 683 NULL, enc_config.enc)) { 684 BIO_printf(bio_err, "Error setting cipher %s\n", 685 EVP_CIPHER_name(enc_config.cipher)); 686 ERR_print_errors(bio_err); 687 goto end; 688 } 689 if (enc_config.nopad) 690 EVP_CIPHER_CTX_set_padding(ctx, 0); 691 692 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 693 enc_config.enc)) { 694 BIO_printf(bio_err, "Error setting cipher %s\n", 695 EVP_CIPHER_name(enc_config.cipher)); 696 ERR_print_errors(bio_err); 697 goto end; 698 } 699 if (enc_config.debug) { 700 BIO_set_callback(benc, BIO_debug_callback); 701 BIO_set_callback_arg(benc, (char *) bio_err); 702 } 703 if (enc_config.printkey) { 704 int key_len, iv_len; 705 706 if (!enc_config.nosalt) { 707 printf("salt="); 708 for (i = 0; i < (int) sizeof(salt); i++) 709 printf("%02X", salt[i]); 710 printf("\n"); 711 } 712 key_len = EVP_CIPHER_key_length(enc_config.cipher); 713 if (key_len > 0) { 714 printf("key="); 715 for (i = 0; i < key_len; i++) 716 printf("%02X", key[i]); 717 printf("\n"); 718 } 719 iv_len = EVP_CIPHER_iv_length(enc_config.cipher); 720 if (iv_len > 0) { 721 printf("iv ="); 722 for (i = 0; i < iv_len; i++) 723 printf("%02X", iv[i]); 724 printf("\n"); 725 } 726 if (enc_config.printkey == 2) { 727 ret = 0; 728 goto end; 729 } 730 } 731 } 732 /* Only encrypt/decrypt as we write the file */ 733 if (benc != NULL) 734 wbio = BIO_push(benc, wbio); 735 736 for (;;) { 737 inl = BIO_read(rbio, (char *) buff, bsize); 738 if (inl <= 0) 739 break; 740 if (BIO_write(wbio, (char *) buff, inl) != inl) { 741 BIO_printf(bio_err, "error writing output file\n"); 742 goto end; 743 } 744 } 745 if (!BIO_flush(wbio)) { 746 BIO_printf(bio_err, "bad decrypt\n"); 747 goto end; 748 } 749 ret = 0; 750 if (enc_config.verbose) { 751 BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); 752 BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); 753 } 754 end: 755 ERR_print_errors(bio_err); 756 free(strbuf); 757 free(buff); 758 BIO_free(in); 759 BIO_free_all(out); 760 BIO_free(benc); 761 BIO_free(b64); 762 #ifdef ZLIB 763 BIO_free(bzl); 764 #endif 765 free(pass); 766 767 return (ret); 768 } 769 770 int 771 set_hex(char *in, unsigned char *out, int size) 772 { 773 int i, n; 774 unsigned char j; 775 776 n = strlen(in); 777 if (n > (size * 2)) { 778 BIO_printf(bio_err, "hex string is too long\n"); 779 return (0); 780 } 781 memset(out, 0, size); 782 for (i = 0; i < n; i++) { 783 j = (unsigned char) *in; 784 *(in++) = '\0'; 785 if (j == 0) 786 break; 787 if ((j >= '0') && (j <= '9')) 788 j -= '0'; 789 else if ((j >= 'A') && (j <= 'F')) 790 j = j - 'A' + 10; 791 else if ((j >= 'a') && (j <= 'f')) 792 j = j - 'a' + 10; 793 else { 794 BIO_printf(bio_err, "non-hex digit\n"); 795 return (0); 796 } 797 if (i & 1) 798 out[i / 2] |= j; 799 else 800 out[i / 2] = (j << 4); 801 } 802 return (1); 803 } 804