1 /* $OpenBSD: enc.c,v 1.27 2023/03/06 14:32:06 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 } cfg; 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 cfg.cipher = NULL; 115 *argsused = 1; 116 return (0); 117 } 118 119 if ((cfg.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 = &cfg.olb64, 133 }, 134 { 135 .name = "a", 136 .desc = "Perform base64 encoding/decoding (alias -base64)", 137 .type = OPTION_FLAG, 138 .opt.flag = &cfg.base64, 139 }, 140 { 141 .name = "base64", 142 .type = OPTION_FLAG, 143 .opt.flag = &cfg.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 = &cfg.bufsize, 151 }, 152 { 153 .name = "d", 154 .desc = "Decrypt the input data", 155 .type = OPTION_VALUE, 156 .opt.value = &cfg.enc, 157 .value = 0, 158 }, 159 { 160 .name = "debug", 161 .desc = "Print debugging information", 162 .type = OPTION_FLAG, 163 .opt.flag = &cfg.debug, 164 }, 165 { 166 .name = "e", 167 .desc = "Encrypt the input data (default)", 168 .type = OPTION_VALUE, 169 .opt.value = &cfg.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 = &cfg.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 = &cfg.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 = &cfg.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 = &cfg.hkey, 199 }, 200 { 201 .name = "k", /* Superseded by -pass. */ 202 .type = OPTION_ARG, 203 .opt.arg = &cfg.keystr, 204 }, 205 { 206 .name = "kfile", /* Superseded by -pass. */ 207 .type = OPTION_ARG, 208 .opt.arg = &cfg.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 = &cfg.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 = &cfg.nopad, 228 }, 229 { 230 .name = "nosalt", 231 .type = OPTION_VALUE, 232 .opt.value = &cfg.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 = &cfg.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 = &cfg.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 = &cfg.printkey, 255 .value = 1, 256 }, 257 { 258 .name = "pass", 259 .argname = "source", 260 .desc = "Password source", 261 .type = OPTION_ARG, 262 .opt.arg = &cfg.passarg, 263 }, 264 { 265 .name = "pbkdf2", 266 .desc = "Use the pbkdf2 key derivation function", 267 .type = OPTION_FLAG, 268 .opt.flag = &cfg.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 = &cfg.hsalt, 276 }, 277 { 278 .name = "salt", 279 .desc = "Use a salt in the key derivation routines (default)", 280 .type = OPTION_VALUE, 281 .opt.value = &cfg.nosalt, 282 .value = 0, 283 }, 284 { 285 .name = "v", 286 .desc = "Verbose", 287 .type = OPTION_FLAG, 288 .opt.flag = &cfg.verbose, 289 }, 290 #ifdef ZLIB 291 { 292 .name = "z", 293 .desc = "Perform zlib compression/decompression", 294 .type = OPTION_FLAG, 295 .opt.flag = &cfg.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 skip_aead_and_xts(const OBJ_NAME *name, void *arg) 308 { 309 const EVP_CIPHER *cipher; 310 311 if ((cipher = EVP_get_cipherbyname(name->name)) == NULL) 312 return; 313 314 if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) 315 return; 316 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE) 317 return; 318 319 show_cipher(name, arg); 320 } 321 322 static void 323 enc_usage(void) 324 { 325 int n = 0; 326 327 fprintf(stderr, "usage: enc -ciphername [-AadePp] [-base64] " 328 "[-bufsize number] [-debug]\n" 329 " [-in file] [-iter iterations] [-iv IV] [-K key] " 330 "[-k password]\n" 331 " [-kfile file] [-md digest] [-none] [-nopad] [-nosalt]\n" 332 " [-out file] [-pass source] [-pbkdf2] [-S salt] [-salt]\n\n"); 333 options_usage(enc_options); 334 fprintf(stderr, "\n"); 335 336 fprintf(stderr, "Valid ciphername values:\n\n"); 337 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, skip_aead_and_xts, &n); 338 fprintf(stderr, "\n"); 339 } 340 341 int 342 enc_main(int argc, char **argv) 343 { 344 static const char magic[] = "Salted__"; 345 char mbuf[sizeof magic - 1]; 346 char *strbuf = NULL, *pass = NULL; 347 unsigned char *buff = NULL; 348 int bsize = BSIZE; 349 int ret = 1, inl; 350 unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; 351 unsigned char salt[PKCS5_SALT_LEN]; 352 #ifdef ZLIB 353 BIO *bzl = NULL; 354 #endif 355 EVP_CIPHER_CTX *ctx = NULL; 356 const EVP_MD *dgst = NULL; 357 BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL; 358 BIO *rbio = NULL, *wbio = NULL; 359 #define PROG_NAME_SIZE 39 360 char pname[PROG_NAME_SIZE + 1]; 361 int i; 362 363 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { 364 perror("pledge"); 365 exit(1); 366 } 367 368 memset(&cfg, 0, sizeof(cfg)); 369 cfg.enc = 1; 370 371 /* first check the program name */ 372 program_name(argv[0], pname, sizeof(pname)); 373 374 if (strcmp(pname, "base64") == 0) 375 cfg.base64 = 1; 376 377 #ifdef ZLIB 378 if (strcmp(pname, "zlib") == 0) 379 cfg.do_zlib = 1; 380 #endif 381 382 cfg.cipher = EVP_get_cipherbyname(pname); 383 384 #ifdef ZLIB 385 if (!cfg.do_zlib && !cfg.base64 && 386 cfg.cipher == NULL && strcmp(pname, "enc") != 0) 387 #else 388 if (!cfg.base64 && cfg.cipher == NULL && 389 strcmp(pname, "enc") != 0) 390 #endif 391 { 392 BIO_printf(bio_err, "%s is an unknown cipher\n", pname); 393 goto end; 394 } 395 396 if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) { 397 enc_usage(); 398 goto end; 399 } 400 401 if (cfg.keyfile != NULL) { 402 static char buf[128]; 403 FILE *infile; 404 405 infile = fopen(cfg.keyfile, "r"); 406 if (infile == NULL) { 407 BIO_printf(bio_err, "unable to read key from '%s'\n", 408 cfg.keyfile); 409 goto end; 410 } 411 buf[0] = '\0'; 412 if (!fgets(buf, sizeof buf, infile)) { 413 BIO_printf(bio_err, "unable to read key from '%s'\n", 414 cfg.keyfile); 415 fclose(infile); 416 goto end; 417 } 418 fclose(infile); 419 i = strlen(buf); 420 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 421 buf[--i] = '\0'; 422 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 423 buf[--i] = '\0'; 424 if (i < 1) { 425 BIO_printf(bio_err, "zero length password\n"); 426 goto end; 427 } 428 cfg.keystr = buf; 429 } 430 431 if (cfg.cipher != NULL && 432 (EVP_CIPHER_flags(cfg.cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) { 433 BIO_printf(bio_err, "enc does not support AEAD ciphers\n"); 434 goto end; 435 } 436 437 if (cfg.cipher != NULL && 438 EVP_CIPHER_mode(cfg.cipher) == EVP_CIPH_XTS_MODE) { 439 BIO_printf(bio_err, "enc does not support XTS mode\n"); 440 goto end; 441 } 442 443 if (cfg.md != NULL && 444 (dgst = EVP_get_digestbyname(cfg.md)) == NULL) { 445 BIO_printf(bio_err, 446 "%s is an unsupported message digest type\n", 447 cfg.md); 448 goto end; 449 } 450 if (dgst == NULL) { 451 dgst = EVP_sha256(); 452 } 453 454 if (cfg.bufsize != NULL) { 455 char *p = cfg.bufsize; 456 unsigned long n; 457 458 /* XXX - provide an OPTION_ARG_DISKUNIT. */ 459 for (n = 0; *p != '\0'; p++) { 460 i = *p; 461 if ((i <= '9') && (i >= '0')) 462 n = n * 10 + i - '0'; 463 else if (i == 'k') { 464 n *= 1024; 465 p++; 466 break; 467 } 468 } 469 if (*p != '\0') { 470 BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); 471 goto end; 472 } 473 /* It must be large enough for a base64 encoded line. */ 474 if (cfg.base64 && n < 80) 475 n = 80; 476 477 bsize = (int)n; 478 if (cfg.verbose) 479 BIO_printf(bio_err, "bufsize=%d\n", bsize); 480 } 481 strbuf = malloc(SIZE); 482 buff = malloc(EVP_ENCODE_LENGTH(bsize)); 483 if ((buff == NULL) || (strbuf == NULL)) { 484 BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize)); 485 goto end; 486 } 487 in = BIO_new(BIO_s_file()); 488 out = BIO_new(BIO_s_file()); 489 if ((in == NULL) || (out == NULL)) { 490 ERR_print_errors(bio_err); 491 goto end; 492 } 493 if (cfg.debug) { 494 BIO_set_callback(in, BIO_debug_callback); 495 BIO_set_callback(out, BIO_debug_callback); 496 BIO_set_callback_arg(in, (char *) bio_err); 497 BIO_set_callback_arg(out, (char *) bio_err); 498 } 499 if (cfg.inf == NULL) { 500 if (cfg.bufsize != NULL) 501 setvbuf(stdin, (char *) NULL, _IONBF, 0); 502 BIO_set_fp(in, stdin, BIO_NOCLOSE); 503 } else { 504 if (BIO_read_filename(in, cfg.inf) <= 0) { 505 perror(cfg.inf); 506 goto end; 507 } 508 } 509 510 if (!cfg.keystr && cfg.passarg) { 511 if (!app_passwd(bio_err, cfg.passarg, NULL, 512 &pass, NULL)) { 513 BIO_printf(bio_err, "Error getting password\n"); 514 goto end; 515 } 516 cfg.keystr = pass; 517 } 518 if (cfg.keystr == NULL && cfg.cipher != NULL && 519 cfg.hkey == NULL) { 520 for (;;) { 521 char buf[200]; 522 int retval; 523 524 retval = snprintf(buf, sizeof buf, 525 "enter %s %s password:", 526 OBJ_nid2ln(EVP_CIPHER_nid(cfg.cipher)), 527 cfg.enc ? "encryption" : "decryption"); 528 if ((size_t)retval >= sizeof buf) { 529 BIO_printf(bio_err, 530 "Password prompt too long\n"); 531 goto end; 532 } 533 strbuf[0] = '\0'; 534 i = EVP_read_pw_string((char *)strbuf, SIZE, buf, 535 cfg.enc); 536 if (i == 0) { 537 if (strbuf[0] == '\0') { 538 ret = 1; 539 goto end; 540 } 541 cfg.keystr = strbuf; 542 break; 543 } 544 if (i < 0) { 545 BIO_printf(bio_err, "bad password read\n"); 546 goto end; 547 } 548 } 549 } 550 if (cfg.outf == NULL) { 551 BIO_set_fp(out, stdout, BIO_NOCLOSE); 552 if (cfg.bufsize != NULL) 553 setvbuf(stdout, (char *)NULL, _IONBF, 0); 554 } else { 555 if (BIO_write_filename(out, cfg.outf) <= 0) { 556 perror(cfg.outf); 557 goto end; 558 } 559 } 560 561 rbio = in; 562 wbio = out; 563 564 #ifdef ZLIB 565 if (do_zlib) { 566 if ((bzl = BIO_new(BIO_f_zlib())) == NULL) 567 goto end; 568 if (enc) 569 wbio = BIO_push(bzl, wbio); 570 else 571 rbio = BIO_push(bzl, rbio); 572 } 573 #endif 574 575 if (cfg.base64) { 576 if ((b64 = BIO_new(BIO_f_base64())) == NULL) 577 goto end; 578 if (cfg.debug) { 579 BIO_set_callback(b64, BIO_debug_callback); 580 BIO_set_callback_arg(b64, (char *) bio_err); 581 } 582 if (cfg.olb64) 583 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 584 if (cfg.enc) 585 wbio = BIO_push(b64, wbio); 586 else 587 rbio = BIO_push(b64, rbio); 588 } 589 if (cfg.cipher != NULL) { 590 /* 591 * Note that keystr is NULL if a key was passed on the command 592 * line, so we get no salt in that case. Is this a bug? 593 */ 594 if (cfg.keystr != NULL) { 595 /* 596 * Salt handling: if encrypting generate a salt and 597 * write to output BIO. If decrypting read salt from 598 * input BIO. 599 */ 600 unsigned char *sptr; 601 if (cfg.nosalt) 602 sptr = NULL; 603 else { 604 if (cfg.enc) { 605 if (cfg.hsalt) { 606 if (!set_hex(cfg.hsalt, salt, sizeof salt)) { 607 BIO_printf(bio_err, 608 "invalid hex salt value\n"); 609 goto end; 610 } 611 } else 612 arc4random_buf(salt, 613 sizeof(salt)); 614 /* 615 * If -P option then don't bother 616 * writing 617 */ 618 if ((cfg.printkey != 2) 619 && (BIO_write(wbio, magic, 620 sizeof magic - 1) != sizeof magic - 1 621 || BIO_write(wbio, 622 (char *) salt, 623 sizeof salt) != sizeof salt)) { 624 BIO_printf(bio_err, "error writing output file\n"); 625 goto end; 626 } 627 } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf 628 || BIO_read(rbio, 629 (unsigned char *) salt, 630 sizeof salt) != sizeof salt) { 631 BIO_printf(bio_err, "error reading input file\n"); 632 goto end; 633 } else if (memcmp(mbuf, magic, sizeof magic - 1)) { 634 BIO_printf(bio_err, "bad magic number\n"); 635 goto end; 636 } 637 sptr = salt; 638 } 639 if (cfg.pbkdf2 == 1 || cfg.iter > 0) { 640 /* 641 * derive key and default iv 642 * concatenated into a temporary buffer 643 */ 644 unsigned char tmpkeyiv[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH]; 645 int iklen = EVP_CIPHER_key_length(cfg.cipher); 646 int ivlen = EVP_CIPHER_iv_length(cfg.cipher); 647 /* not needed if HASH_UPDATE() is fixed : */ 648 int islen = (sptr != NULL ? sizeof(salt) : 0); 649 650 if (cfg.iter == 0) 651 cfg.iter = 10000; 652 653 if (!PKCS5_PBKDF2_HMAC(cfg.keystr, 654 strlen(cfg.keystr), sptr, islen, 655 cfg.iter, dgst, iklen+ivlen, tmpkeyiv)) { 656 BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n"); 657 goto end; 658 } 659 /* split and move data back to global buffer */ 660 memcpy(key, tmpkeyiv, iklen); 661 memcpy(iv, tmpkeyiv + iklen, ivlen); 662 explicit_bzero(tmpkeyiv, sizeof tmpkeyiv); 663 } else { 664 EVP_BytesToKey(cfg.cipher, dgst, sptr, 665 (unsigned char *)cfg.keystr, 666 strlen(cfg.keystr), 1, key, iv); 667 } 668 669 /* 670 * zero the complete buffer or the string passed from 671 * the command line bug picked up by Larry J. Hughes 672 * Jr. <hughes@indiana.edu> 673 */ 674 if (cfg.keystr == strbuf) 675 explicit_bzero(cfg.keystr, SIZE); 676 else 677 explicit_bzero(cfg.keystr, 678 strlen(cfg.keystr)); 679 } 680 if (cfg.hiv != NULL && 681 !set_hex(cfg.hiv, iv, sizeof iv)) { 682 BIO_printf(bio_err, "invalid hex iv value\n"); 683 goto end; 684 } 685 if (cfg.hiv == NULL && cfg.keystr == NULL && 686 EVP_CIPHER_iv_length(cfg.cipher) != 0) { 687 /* 688 * No IV was explicitly set and no IV was generated 689 * during EVP_BytesToKey. Hence the IV is undefined, 690 * making correct decryption impossible. 691 */ 692 BIO_printf(bio_err, "iv undefined\n"); 693 goto end; 694 } 695 if (cfg.hkey != NULL && 696 !set_hex(cfg.hkey, key, sizeof key)) { 697 BIO_printf(bio_err, "invalid hex key value\n"); 698 goto end; 699 } 700 if ((benc = BIO_new(BIO_f_cipher())) == NULL) 701 goto end; 702 703 /* 704 * Since we may be changing parameters work on the encryption 705 * context rather than calling BIO_set_cipher(). 706 */ 707 708 BIO_get_cipher_ctx(benc, &ctx); 709 710 if (!EVP_CipherInit_ex(ctx, cfg.cipher, NULL, NULL, 711 NULL, cfg.enc)) { 712 BIO_printf(bio_err, "Error setting cipher %s\n", 713 EVP_CIPHER_name(cfg.cipher)); 714 ERR_print_errors(bio_err); 715 goto end; 716 } 717 if (cfg.nopad) 718 EVP_CIPHER_CTX_set_padding(ctx, 0); 719 720 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 721 cfg.enc)) { 722 BIO_printf(bio_err, "Error setting cipher %s\n", 723 EVP_CIPHER_name(cfg.cipher)); 724 ERR_print_errors(bio_err); 725 goto end; 726 } 727 if (cfg.debug) { 728 BIO_set_callback(benc, BIO_debug_callback); 729 BIO_set_callback_arg(benc, (char *) bio_err); 730 } 731 if (cfg.printkey) { 732 int key_len, iv_len; 733 734 if (!cfg.nosalt) { 735 printf("salt="); 736 for (i = 0; i < (int) sizeof(salt); i++) 737 printf("%02X", salt[i]); 738 printf("\n"); 739 } 740 key_len = EVP_CIPHER_key_length(cfg.cipher); 741 if (key_len > 0) { 742 printf("key="); 743 for (i = 0; i < key_len; i++) 744 printf("%02X", key[i]); 745 printf("\n"); 746 } 747 iv_len = EVP_CIPHER_iv_length(cfg.cipher); 748 if (iv_len > 0) { 749 printf("iv ="); 750 for (i = 0; i < iv_len; i++) 751 printf("%02X", iv[i]); 752 printf("\n"); 753 } 754 if (cfg.printkey == 2) { 755 ret = 0; 756 goto end; 757 } 758 } 759 } 760 /* Only encrypt/decrypt as we write the file */ 761 if (benc != NULL) 762 wbio = BIO_push(benc, wbio); 763 764 for (;;) { 765 inl = BIO_read(rbio, (char *) buff, bsize); 766 if (inl <= 0) 767 break; 768 if (BIO_write(wbio, (char *) buff, inl) != inl) { 769 BIO_printf(bio_err, "error writing output file\n"); 770 goto end; 771 } 772 } 773 if (!BIO_flush(wbio)) { 774 BIO_printf(bio_err, "bad decrypt\n"); 775 goto end; 776 } 777 ret = 0; 778 if (cfg.verbose) { 779 BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); 780 BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); 781 } 782 end: 783 ERR_print_errors(bio_err); 784 free(strbuf); 785 free(buff); 786 BIO_free(in); 787 BIO_free_all(out); 788 BIO_free(benc); 789 BIO_free(b64); 790 #ifdef ZLIB 791 BIO_free(bzl); 792 #endif 793 free(pass); 794 795 return (ret); 796 } 797 798 int 799 set_hex(char *in, unsigned char *out, int size) 800 { 801 int i, n; 802 unsigned char j; 803 804 n = strlen(in); 805 if (n > (size * 2)) { 806 BIO_printf(bio_err, "hex string is too long\n"); 807 return (0); 808 } 809 memset(out, 0, size); 810 for (i = 0; i < n; i++) { 811 j = (unsigned char) *in; 812 *(in++) = '\0'; 813 if (j == 0) 814 break; 815 if ((j >= '0') && (j <= '9')) 816 j -= '0'; 817 else if ((j >= 'A') && (j <= 'F')) 818 j = j - 'A' + 10; 819 else if ((j >= 'a') && (j <= 'f')) 820 j = j - 'a' + 10; 821 else { 822 BIO_printf(bio_err, "non-hex digit\n"); 823 return (0); 824 } 825 if (i & 1) 826 out[i / 2] |= j; 827 else 828 out[i / 2] = (j << 4); 829 } 830 return (1); 831 } 832