155714Skris/* apps/enc.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8280297Sjkim * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280297Sjkim * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22280297Sjkim * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280297Sjkim * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52280297Sjkim * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include <stdlib.h> 6155714Skris#include <string.h> 6255714Skris#include "apps.h" 6355714Skris#include <openssl/bio.h> 6455714Skris#include <openssl/err.h> 6555714Skris#include <openssl/evp.h> 6655714Skris#include <openssl/objects.h> 6755714Skris#include <openssl/x509.h> 6859191Skris#include <openssl/rand.h> 6955714Skris#include <openssl/pem.h> 70269682Sjkim#ifndef OPENSSL_NO_COMP 71280297Sjkim# include <openssl/comp.h> 72269682Sjkim#endif 73109998Smarkm#include <ctype.h> 7455714Skris 75280297Sjkimint set_hex(char *in, unsigned char *out, int size); 7655714Skris#undef SIZE 7755714Skris#undef BSIZE 7855714Skris#undef PROG 7955714Skris 80280297Sjkim#define SIZE (512) 81280297Sjkim#define BSIZE (8*1024) 82280297Sjkim#define PROG enc_main 8355714Skris 84325335Sjkimstruct doall_enc_ciphers { 85325335Sjkim BIO *bio; 86325335Sjkim int n; 87325335Sjkim}; 88325335Sjkim 89325335Sjkimstatic void show_ciphers(const OBJ_NAME *name, void *arg) 90280297Sjkim{ 91325335Sjkim struct doall_enc_ciphers *dec = (struct doall_enc_ciphers *)arg; 92325335Sjkim const EVP_CIPHER *cipher; 93109998Smarkm 94280297Sjkim if (!islower((unsigned char)*name->name)) 95280297Sjkim return; 96109998Smarkm 97325335Sjkim /* Filter out ciphers that we cannot use */ 98325335Sjkim cipher = EVP_get_cipherbyname(name->name); 99325335Sjkim if (cipher == NULL || 100325335Sjkim (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0 || 101325335Sjkim EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE) 102325335Sjkim return; 103325335Sjkim 104325335Sjkim BIO_printf(dec->bio, "-%-25s", name->name); 105325335Sjkim if (++dec->n == 3) { 106325335Sjkim BIO_printf(dec->bio, "\n"); 107325335Sjkim dec->n = 0; 108280297Sjkim } else 109325335Sjkim BIO_printf(dec->bio, " "); 110280297Sjkim} 111109998Smarkm 11259191Skrisint MAIN(int, char **); 11359191Skris 11455714Skrisint MAIN(int argc, char **argv) 115280297Sjkim{ 116280297Sjkim static const char magic[] = "Salted__"; 117331638Sjkim char mbuf[sizeof(magic) - 1]; 118280297Sjkim char *strbuf = NULL; 119280297Sjkim unsigned char *buff = NULL, *bufsize = NULL; 120280297Sjkim int bsize = BSIZE, verbose = 0; 121280297Sjkim int ret = 1, inl; 122280297Sjkim int nopad = 0; 123280297Sjkim unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; 124280297Sjkim unsigned char salt[PKCS5_SALT_LEN]; 125280297Sjkim char *str = NULL, *passarg = NULL, *pass = NULL; 126280297Sjkim char *hkey = NULL, *hiv = NULL, *hsalt = NULL; 127280297Sjkim char *md = NULL; 128280297Sjkim int enc = 1, printkey = 0, i, base64 = 0; 129238405Sjkim#ifdef ZLIB 130280297Sjkim int do_zlib = 0; 131280297Sjkim BIO *bzl = NULL; 132238405Sjkim#endif 133280297Sjkim int debug = 0, olb64 = 0, nosalt = 0; 134280297Sjkim const EVP_CIPHER *cipher = NULL, *c; 135280297Sjkim EVP_CIPHER_CTX *ctx = NULL; 136280297Sjkim char *inf = NULL, *outf = NULL; 137280297Sjkim BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = 138280297Sjkim NULL, *wbio = NULL; 139100928Snectar#define PROG_NAME_SIZE 39 140280297Sjkim char pname[PROG_NAME_SIZE + 1]; 141280297Sjkim char *engine = NULL; 142312826Sjkim ENGINE *e = NULL; 143280297Sjkim const EVP_MD *dgst = NULL; 144280297Sjkim int non_fips_allow = 0; 145325335Sjkim struct doall_enc_ciphers dec; 14655714Skris 147280297Sjkim apps_startup(); 14855714Skris 149280297Sjkim if (bio_err == NULL) 150280297Sjkim if ((bio_err = BIO_new(BIO_s_file())) != NULL) 151280297Sjkim BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 15255714Skris 153280297Sjkim if (!load_config(bio_err, NULL)) 154280297Sjkim goto end; 155109998Smarkm 156280297Sjkim /* first check the program name */ 157331638Sjkim program_name(argv[0], pname, sizeof(pname)); 158280297Sjkim if (strcmp(pname, "base64") == 0) 159280297Sjkim base64 = 1; 160238405Sjkim#ifdef ZLIB 161280297Sjkim if (strcmp(pname, "zlib") == 0) 162280297Sjkim do_zlib = 1; 163238405Sjkim#endif 16455714Skris 165280297Sjkim cipher = EVP_get_cipherbyname(pname); 166238405Sjkim#ifdef ZLIB 167280297Sjkim if (!do_zlib && !base64 && (cipher == NULL) 168280297Sjkim && (strcmp(pname, "enc") != 0)) 169238405Sjkim#else 170280297Sjkim if (!base64 && (cipher == NULL) && (strcmp(pname, "enc") != 0)) 171238405Sjkim#endif 172280297Sjkim { 173280297Sjkim BIO_printf(bio_err, "%s is an unknown cipher\n", pname); 174280297Sjkim goto bad; 175280297Sjkim } 17655714Skris 177280297Sjkim argc--; 178280297Sjkim argv++; 179280297Sjkim while (argc >= 1) { 180280297Sjkim if (strcmp(*argv, "-e") == 0) 181280297Sjkim enc = 1; 182280297Sjkim else if (strcmp(*argv, "-in") == 0) { 183280297Sjkim if (--argc < 1) 184280297Sjkim goto bad; 185280297Sjkim inf = *(++argv); 186280297Sjkim } else if (strcmp(*argv, "-out") == 0) { 187280297Sjkim if (--argc < 1) 188280297Sjkim goto bad; 189280297Sjkim outf = *(++argv); 190280297Sjkim } else if (strcmp(*argv, "-pass") == 0) { 191280297Sjkim if (--argc < 1) 192280297Sjkim goto bad; 193280297Sjkim passarg = *(++argv); 194280297Sjkim } 195111147Snectar#ifndef OPENSSL_NO_ENGINE 196280297Sjkim else if (strcmp(*argv, "-engine") == 0) { 197280297Sjkim if (--argc < 1) 198280297Sjkim goto bad; 199280297Sjkim engine = *(++argv); 200280297Sjkim } 201111147Snectar#endif 202280297Sjkim else if (strcmp(*argv, "-d") == 0) 203280297Sjkim enc = 0; 204280297Sjkim else if (strcmp(*argv, "-p") == 0) 205280297Sjkim printkey = 1; 206280297Sjkim else if (strcmp(*argv, "-v") == 0) 207280297Sjkim verbose = 1; 208280297Sjkim else if (strcmp(*argv, "-nopad") == 0) 209280297Sjkim nopad = 1; 210280297Sjkim else if (strcmp(*argv, "-salt") == 0) 211280297Sjkim nosalt = 0; 212280297Sjkim else if (strcmp(*argv, "-nosalt") == 0) 213280297Sjkim nosalt = 1; 214280297Sjkim else if (strcmp(*argv, "-debug") == 0) 215280297Sjkim debug = 1; 216280297Sjkim else if (strcmp(*argv, "-P") == 0) 217280297Sjkim printkey = 2; 218280297Sjkim else if (strcmp(*argv, "-A") == 0) 219280297Sjkim olb64 = 1; 220280297Sjkim else if (strcmp(*argv, "-a") == 0) 221280297Sjkim base64 = 1; 222280297Sjkim else if (strcmp(*argv, "-base64") == 0) 223280297Sjkim base64 = 1; 224238405Sjkim#ifdef ZLIB 225280297Sjkim else if (strcmp(*argv, "-z") == 0) 226280297Sjkim do_zlib = 1; 227238405Sjkim#endif 228280297Sjkim else if (strcmp(*argv, "-bufsize") == 0) { 229280297Sjkim if (--argc < 1) 230280297Sjkim goto bad; 231280297Sjkim bufsize = (unsigned char *)*(++argv); 232280297Sjkim } else if (strcmp(*argv, "-k") == 0) { 233280297Sjkim if (--argc < 1) 234280297Sjkim goto bad; 235280297Sjkim str = *(++argv); 236280297Sjkim } else if (strcmp(*argv, "-kfile") == 0) { 237280297Sjkim static char buf[128]; 238280297Sjkim FILE *infile; 239280297Sjkim char *file; 24055714Skris 241280297Sjkim if (--argc < 1) 242280297Sjkim goto bad; 243280297Sjkim file = *(++argv); 244280297Sjkim infile = fopen(file, "r"); 245280297Sjkim if (infile == NULL) { 246280297Sjkim BIO_printf(bio_err, "unable to read key from '%s'\n", file); 247280297Sjkim goto bad; 248280297Sjkim } 249280297Sjkim buf[0] = '\0'; 250331638Sjkim if (!fgets(buf, sizeof(buf), infile)) { 251280297Sjkim BIO_printf(bio_err, "unable to read key from '%s'\n", file); 252280297Sjkim goto bad; 253280297Sjkim } 254280297Sjkim fclose(infile); 255280297Sjkim i = strlen(buf); 256280297Sjkim if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 257280297Sjkim buf[--i] = '\0'; 258280297Sjkim if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 259280297Sjkim buf[--i] = '\0'; 260280297Sjkim if (i < 1) { 261280297Sjkim BIO_printf(bio_err, "zero length password\n"); 262280297Sjkim goto bad; 263280297Sjkim } 264280297Sjkim str = buf; 265280297Sjkim } else if (strcmp(*argv, "-K") == 0) { 266280297Sjkim if (--argc < 1) 267280297Sjkim goto bad; 268280297Sjkim hkey = *(++argv); 269280297Sjkim } else if (strcmp(*argv, "-S") == 0) { 270280297Sjkim if (--argc < 1) 271280297Sjkim goto bad; 272280297Sjkim hsalt = *(++argv); 273280297Sjkim } else if (strcmp(*argv, "-iv") == 0) { 274280297Sjkim if (--argc < 1) 275280297Sjkim goto bad; 276280297Sjkim hiv = *(++argv); 277280297Sjkim } else if (strcmp(*argv, "-md") == 0) { 278280297Sjkim if (--argc < 1) 279280297Sjkim goto bad; 280280297Sjkim md = *(++argv); 281280297Sjkim } else if (strcmp(*argv, "-non-fips-allow") == 0) 282280297Sjkim non_fips_allow = 1; 283280297Sjkim else if ((argv[0][0] == '-') && 284280297Sjkim ((c = EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { 285280297Sjkim cipher = c; 286280297Sjkim } else if (strcmp(*argv, "-none") == 0) 287280297Sjkim cipher = NULL; 288280297Sjkim else { 289280297Sjkim BIO_printf(bio_err, "unknown option '%s'\n", *argv); 290280297Sjkim bad: 291280297Sjkim BIO_printf(bio_err, "options are\n"); 292280297Sjkim BIO_printf(bio_err, "%-14s input file\n", "-in <file>"); 293280297Sjkim BIO_printf(bio_err, "%-14s output file\n", "-out <file>"); 294280297Sjkim BIO_printf(bio_err, "%-14s pass phrase source\n", "-pass <arg>"); 295280297Sjkim BIO_printf(bio_err, "%-14s encrypt\n", "-e"); 296280297Sjkim BIO_printf(bio_err, "%-14s decrypt\n", "-d"); 297280297Sjkim BIO_printf(bio_err, 298280297Sjkim "%-14s base64 encode/decode, depending on encryption flag\n", 299280297Sjkim "-a/-base64"); 300280297Sjkim BIO_printf(bio_err, "%-14s passphrase is the next argument\n", 301280297Sjkim "-k"); 302280297Sjkim BIO_printf(bio_err, 303280297Sjkim "%-14s passphrase is the first line of the file argument\n", 304280297Sjkim "-kfile"); 305280297Sjkim BIO_printf(bio_err, 306280297Sjkim "%-14s the next argument is the md to use to create a key\n", 307280297Sjkim "-md"); 308280297Sjkim BIO_printf(bio_err, 309280297Sjkim "%-14s from a passphrase. One of md2, md5, sha or sha1\n", 310280297Sjkim ""); 311280297Sjkim BIO_printf(bio_err, "%-14s salt in hex is the next argument\n", 312280297Sjkim "-S"); 313280297Sjkim BIO_printf(bio_err, "%-14s key/iv in hex is the next argument\n", 314280297Sjkim "-K/-iv"); 315280297Sjkim BIO_printf(bio_err, "%-14s print the iv/key (then exit if -P)\n", 316280297Sjkim "-[pP]"); 317280297Sjkim BIO_printf(bio_err, "%-14s buffer size\n", "-bufsize <n>"); 318280297Sjkim BIO_printf(bio_err, "%-14s disable standard block padding\n", 319280297Sjkim "-nopad"); 320111147Snectar#ifndef OPENSSL_NO_ENGINE 321280297Sjkim BIO_printf(bio_err, 322280297Sjkim "%-14s use engine e, possibly a hardware device.\n", 323280297Sjkim "-engine e"); 324111147Snectar#endif 32555714Skris 326280297Sjkim BIO_printf(bio_err, "Cipher Types\n"); 327325335Sjkim dec.n = 0; 328325335Sjkim dec.bio = bio_err; 329280297Sjkim OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, 330325335Sjkim show_ciphers, &dec); 331280297Sjkim BIO_printf(bio_err, "\n"); 33255714Skris 333280297Sjkim goto end; 334280297Sjkim } 335280297Sjkim argc--; 336280297Sjkim argv++; 337280297Sjkim } 33855714Skris 339312826Sjkim e = setup_engine(bio_err, engine, 0); 340109998Smarkm 341280297Sjkim if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { 342280297Sjkim BIO_printf(bio_err, 343280297Sjkim "AEAD ciphers not supported by the enc utility\n"); 344280297Sjkim goto end; 345280297Sjkim } 346267256Sjkim 347280297Sjkim if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) { 348280297Sjkim BIO_printf(bio_err, 349280297Sjkim "Ciphers in XTS mode are not supported by the enc utility\n"); 350280297Sjkim goto end; 351280297Sjkim } 352269682Sjkim 353280297Sjkim if (md && (dgst = EVP_get_digestbyname(md)) == NULL) { 354280297Sjkim BIO_printf(bio_err, "%s is an unsupported message digest type\n", md); 355280297Sjkim goto end; 356280297Sjkim } 357142425Snectar 358280297Sjkim if (dgst == NULL) { 359280297Sjkim dgst = EVP_md5(); 360280297Sjkim } 361142425Snectar 362280297Sjkim if (bufsize != NULL) { 363280297Sjkim unsigned long n; 36455714Skris 365280297Sjkim for (n = 0; *bufsize; bufsize++) { 366280297Sjkim i = *bufsize; 367280297Sjkim if ((i <= '9') && (i >= '0')) 368280297Sjkim n = n * 10 + i - '0'; 369280297Sjkim else if (i == 'k') { 370280297Sjkim n *= 1024; 371280297Sjkim bufsize++; 372280297Sjkim break; 373280297Sjkim } 374280297Sjkim } 375280297Sjkim if (*bufsize != '\0') { 376280297Sjkim BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); 377280297Sjkim goto end; 378280297Sjkim } 37955714Skris 380280297Sjkim /* It must be large enough for a base64 encoded line */ 381280297Sjkim if (base64 && n < 80) 382280297Sjkim n = 80; 38355714Skris 384280297Sjkim bsize = (int)n; 385280297Sjkim if (verbose) 386280297Sjkim BIO_printf(bio_err, "bufsize=%d\n", bsize); 387280297Sjkim } 38855714Skris 389280297Sjkim strbuf = OPENSSL_malloc(SIZE); 390280297Sjkim buff = (unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); 391280297Sjkim if ((buff == NULL) || (strbuf == NULL)) { 392280297Sjkim BIO_printf(bio_err, "OPENSSL_malloc failure %ld\n", 393280297Sjkim (long)EVP_ENCODE_LENGTH(bsize)); 394280297Sjkim goto end; 395280297Sjkim } 39655714Skris 397280297Sjkim in = BIO_new(BIO_s_file()); 398280297Sjkim out = BIO_new(BIO_s_file()); 399280297Sjkim if ((in == NULL) || (out == NULL)) { 400280297Sjkim ERR_print_errors(bio_err); 401280297Sjkim goto end; 402280297Sjkim } 403280297Sjkim if (debug) { 404280297Sjkim BIO_set_callback(in, BIO_debug_callback); 405280297Sjkim BIO_set_callback(out, BIO_debug_callback); 406280297Sjkim BIO_set_callback_arg(in, (char *)bio_err); 407280297Sjkim BIO_set_callback_arg(out, (char *)bio_err); 408280297Sjkim } 40955714Skris 410280297Sjkim if (inf == NULL) { 411238405Sjkim#ifndef OPENSSL_NO_SETVBUF_IONBF 412280297Sjkim if (bufsize != NULL) 413280297Sjkim setvbuf(stdin, (char *)NULL, _IONBF, 0); 414280297Sjkim#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 415280297Sjkim BIO_set_fp(in, stdin, BIO_NOCLOSE); 416280297Sjkim } else { 417280297Sjkim if (BIO_read_filename(in, inf) <= 0) { 418280297Sjkim perror(inf); 419280297Sjkim goto end; 420280297Sjkim } 421280297Sjkim } 42255714Skris 423280297Sjkim if (!str && passarg) { 424280297Sjkim if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { 425280297Sjkim BIO_printf(bio_err, "Error getting password\n"); 426280297Sjkim goto end; 427280297Sjkim } 428280297Sjkim str = pass; 429280297Sjkim } 43059191Skris 431280297Sjkim if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { 432280297Sjkim for (;;) { 433280297Sjkim char buf[200]; 43455714Skris 435331638Sjkim BIO_snprintf(buf, sizeof(buf), "enter %s %s password:", 436280297Sjkim OBJ_nid2ln(EVP_CIPHER_nid(cipher)), 437280297Sjkim (enc) ? "encryption" : "decryption"); 438280297Sjkim strbuf[0] = '\0'; 439280297Sjkim i = EVP_read_pw_string((char *)strbuf, SIZE, buf, enc); 440280297Sjkim if (i == 0) { 441280297Sjkim if (strbuf[0] == '\0') { 442280297Sjkim ret = 1; 443280297Sjkim goto end; 444280297Sjkim } 445280297Sjkim str = strbuf; 446280297Sjkim break; 447280297Sjkim } 448280297Sjkim if (i < 0) { 449280297Sjkim BIO_printf(bio_err, "bad password read\n"); 450280297Sjkim goto end; 451280297Sjkim } 452280297Sjkim } 453280297Sjkim } 45455714Skris 455280297Sjkim if (outf == NULL) { 456280297Sjkim BIO_set_fp(out, stdout, BIO_NOCLOSE); 457238405Sjkim#ifndef OPENSSL_NO_SETVBUF_IONBF 458280297Sjkim if (bufsize != NULL) 459280297Sjkim setvbuf(stdout, (char *)NULL, _IONBF, 0); 460280297Sjkim#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 461109998Smarkm#ifdef OPENSSL_SYS_VMS 462280297Sjkim { 463280297Sjkim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 464280297Sjkim out = BIO_push(tmpbio, out); 465280297Sjkim } 46668651Skris#endif 467280297Sjkim } else { 468280297Sjkim if (BIO_write_filename(out, outf) <= 0) { 469280297Sjkim perror(outf); 470280297Sjkim goto end; 471280297Sjkim } 472280297Sjkim } 47359191Skris 474280297Sjkim rbio = in; 475280297Sjkim wbio = out; 47659191Skris 477238405Sjkim#ifdef ZLIB 478238405Sjkim 479280297Sjkim if (do_zlib) { 480280297Sjkim if ((bzl = BIO_new(BIO_f_zlib())) == NULL) 481280297Sjkim goto end; 482280297Sjkim if (enc) 483280297Sjkim wbio = BIO_push(bzl, wbio); 484280297Sjkim else 485280297Sjkim rbio = BIO_push(bzl, rbio); 486280297Sjkim } 487238405Sjkim#endif 488238405Sjkim 489280297Sjkim if (base64) { 490280297Sjkim if ((b64 = BIO_new(BIO_f_base64())) == NULL) 491280297Sjkim goto end; 492280297Sjkim if (debug) { 493280297Sjkim BIO_set_callback(b64, BIO_debug_callback); 494280297Sjkim BIO_set_callback_arg(b64, (char *)bio_err); 495280297Sjkim } 496280297Sjkim if (olb64) 497280297Sjkim BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 498280297Sjkim if (enc) 499280297Sjkim wbio = BIO_push(b64, wbio); 500280297Sjkim else 501280297Sjkim rbio = BIO_push(b64, rbio); 502280297Sjkim } 50359191Skris 504280297Sjkim if (cipher != NULL) { 505280297Sjkim /* 506280297Sjkim * Note that str is NULL if a key was passed on the command line, so 507280297Sjkim * we get no salt in that case. Is this a bug? 508280297Sjkim */ 509280297Sjkim if (str != NULL) { 510280297Sjkim /* 511280297Sjkim * Salt handling: if encrypting generate a salt and write to 512280297Sjkim * output BIO. If decrypting read salt from input BIO. 513280297Sjkim */ 514280297Sjkim unsigned char *sptr; 515280297Sjkim if (nosalt) 516280297Sjkim sptr = NULL; 517280297Sjkim else { 518280297Sjkim if (enc) { 519280297Sjkim if (hsalt) { 520331638Sjkim if (!set_hex(hsalt, salt, sizeof(salt))) { 521280297Sjkim BIO_printf(bio_err, "invalid hex salt value\n"); 522280297Sjkim goto end; 523280297Sjkim } 524331638Sjkim } else if (RAND_bytes(salt, sizeof(salt)) <= 0) 525280297Sjkim goto end; 526280297Sjkim /* 527280297Sjkim * If -P option then don't bother writing 528280297Sjkim */ 529280297Sjkim if ((printkey != 2) 530280297Sjkim && (BIO_write(wbio, magic, 531331638Sjkim sizeof(magic) - 1) != sizeof(magic) - 1 532280297Sjkim || BIO_write(wbio, 533280297Sjkim (char *)salt, 534331638Sjkim sizeof(salt)) != sizeof(salt))) { 535280297Sjkim BIO_printf(bio_err, "error writing output file\n"); 536280297Sjkim goto end; 537280297Sjkim } 538331638Sjkim } else if (BIO_read(rbio, mbuf, sizeof(mbuf)) != sizeof(mbuf) 539280297Sjkim || BIO_read(rbio, 540280297Sjkim (unsigned char *)salt, 541331638Sjkim sizeof(salt)) != sizeof(salt)) { 542280297Sjkim BIO_printf(bio_err, "error reading input file\n"); 543280297Sjkim goto end; 544331638Sjkim } else if (memcmp(mbuf, magic, sizeof(magic) - 1)) { 545280297Sjkim BIO_printf(bio_err, "bad magic number\n"); 546280297Sjkim goto end; 547280297Sjkim } 54859191Skris 549280297Sjkim sptr = salt; 550280297Sjkim } 55159191Skris 552280297Sjkim EVP_BytesToKey(cipher, dgst, sptr, 553280297Sjkim (unsigned char *)str, strlen(str), 1, key, iv); 554280297Sjkim /* 555280297Sjkim * zero the complete buffer or the string passed from the command 556280297Sjkim * line bug picked up by Larry J. Hughes Jr. <hughes@indiana.edu> 557280297Sjkim */ 558280297Sjkim if (str == strbuf) 559280297Sjkim OPENSSL_cleanse(str, SIZE); 560280297Sjkim else 561280297Sjkim OPENSSL_cleanse(str, strlen(str)); 562280297Sjkim } 563284283Sjkim if (hiv != NULL) { 564284283Sjkim int siz = EVP_CIPHER_iv_length(cipher); 565284283Sjkim if (siz == 0) { 566284283Sjkim BIO_printf(bio_err, "warning: iv not use by this cipher\n"); 567331638Sjkim } else if (!set_hex(hiv, iv, sizeof(iv))) { 568284283Sjkim BIO_printf(bio_err, "invalid hex iv value\n"); 569284283Sjkim goto end; 570284283Sjkim } 571280297Sjkim } 572280297Sjkim if ((hiv == NULL) && (str == NULL) 573280297Sjkim && EVP_CIPHER_iv_length(cipher) != 0) { 574280297Sjkim /* 575280297Sjkim * No IV was explicitly set and no IV was generated during 576280297Sjkim * EVP_BytesToKey. Hence the IV is undefined, making correct 577280297Sjkim * decryption impossible. 578280297Sjkim */ 579280297Sjkim BIO_printf(bio_err, "iv undefined\n"); 580280297Sjkim goto end; 581280297Sjkim } 582284283Sjkim if ((hkey != NULL) && !set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) { 583280297Sjkim BIO_printf(bio_err, "invalid hex key value\n"); 584280297Sjkim goto end; 585280297Sjkim } 58655714Skris 587280297Sjkim if ((benc = BIO_new(BIO_f_cipher())) == NULL) 588280297Sjkim goto end; 589160814Ssimon 590280297Sjkim /* 591280297Sjkim * Since we may be changing parameters work on the encryption context 592280297Sjkim * rather than calling BIO_set_cipher(). 593280297Sjkim */ 594160814Ssimon 595280297Sjkim BIO_get_cipher_ctx(benc, &ctx); 596194206Ssimon 597280297Sjkim if (non_fips_allow) 598280297Sjkim EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); 599194206Ssimon 600280297Sjkim if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { 601280297Sjkim BIO_printf(bio_err, "Error setting cipher %s\n", 602280297Sjkim EVP_CIPHER_name(cipher)); 603280297Sjkim ERR_print_errors(bio_err); 604280297Sjkim goto end; 605280297Sjkim } 606160814Ssimon 607280297Sjkim if (nopad) 608280297Sjkim EVP_CIPHER_CTX_set_padding(ctx, 0); 609160814Ssimon 610280297Sjkim if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { 611280297Sjkim BIO_printf(bio_err, "Error setting cipher %s\n", 612280297Sjkim EVP_CIPHER_name(cipher)); 613280297Sjkim ERR_print_errors(bio_err); 614280297Sjkim goto end; 615280297Sjkim } 616160814Ssimon 617280297Sjkim if (debug) { 618280297Sjkim BIO_set_callback(benc, BIO_debug_callback); 619280297Sjkim BIO_set_callback_arg(benc, (char *)bio_err); 620280297Sjkim } 62155714Skris 622280297Sjkim if (printkey) { 623280297Sjkim if (!nosalt) { 624280297Sjkim printf("salt="); 625280297Sjkim for (i = 0; i < (int)sizeof(salt); i++) 626280297Sjkim printf("%02X", salt[i]); 627280297Sjkim printf("\n"); 628280297Sjkim } 629280297Sjkim if (cipher->key_len > 0) { 630280297Sjkim printf("key="); 631280297Sjkim for (i = 0; i < cipher->key_len; i++) 632280297Sjkim printf("%02X", key[i]); 633280297Sjkim printf("\n"); 634280297Sjkim } 635280297Sjkim if (cipher->iv_len > 0) { 636280297Sjkim printf("iv ="); 637280297Sjkim for (i = 0; i < cipher->iv_len; i++) 638280297Sjkim printf("%02X", iv[i]); 639280297Sjkim printf("\n"); 640280297Sjkim } 641280297Sjkim if (printkey == 2) { 642280297Sjkim ret = 0; 643280297Sjkim goto end; 644280297Sjkim } 645280297Sjkim } 646280297Sjkim } 64755714Skris 648280297Sjkim /* Only encrypt/decrypt as we write the file */ 649280297Sjkim if (benc != NULL) 650280297Sjkim wbio = BIO_push(benc, wbio); 65155714Skris 652280297Sjkim for (;;) { 653280297Sjkim inl = BIO_read(rbio, (char *)buff, bsize); 654280297Sjkim if (inl <= 0) 655280297Sjkim break; 656280297Sjkim if (BIO_write(wbio, (char *)buff, inl) != inl) { 657280297Sjkim BIO_printf(bio_err, "error writing output file\n"); 658280297Sjkim goto end; 659280297Sjkim } 660280297Sjkim } 661280297Sjkim if (!BIO_flush(wbio)) { 662280297Sjkim BIO_printf(bio_err, "bad decrypt\n"); 663280297Sjkim goto end; 664280297Sjkim } 66555714Skris 666280297Sjkim ret = 0; 667280297Sjkim if (verbose) { 668280297Sjkim BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); 669280297Sjkim BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); 670280297Sjkim } 671280297Sjkim end: 672280297Sjkim ERR_print_errors(bio_err); 673280297Sjkim if (strbuf != NULL) 674280297Sjkim OPENSSL_free(strbuf); 675280297Sjkim if (buff != NULL) 676280297Sjkim OPENSSL_free(buff); 677280297Sjkim if (in != NULL) 678280297Sjkim BIO_free(in); 679280297Sjkim if (out != NULL) 680280297Sjkim BIO_free_all(out); 681280297Sjkim if (benc != NULL) 682280297Sjkim BIO_free(benc); 683280297Sjkim if (b64 != NULL) 684280297Sjkim BIO_free(b64); 685238405Sjkim#ifdef ZLIB 686280297Sjkim if (bzl != NULL) 687280297Sjkim BIO_free(bzl); 688238405Sjkim#endif 689312826Sjkim release_engine(e); 690280297Sjkim if (pass) 691280297Sjkim OPENSSL_free(pass); 692280297Sjkim apps_shutdown(); 693280297Sjkim OPENSSL_EXIT(ret); 694280297Sjkim} 69555714Skris 69655714Skrisint set_hex(char *in, unsigned char *out, int size) 697280297Sjkim{ 698280297Sjkim int i, n; 699280297Sjkim unsigned char j; 70055714Skris 701280297Sjkim n = strlen(in); 702280297Sjkim if (n > (size * 2)) { 703280297Sjkim BIO_printf(bio_err, "hex string is too long\n"); 704280297Sjkim return (0); 705280297Sjkim } 706280297Sjkim memset(out, 0, size); 707280297Sjkim for (i = 0; i < n; i++) { 708280297Sjkim j = (unsigned char)*in; 709280297Sjkim *(in++) = '\0'; 710280297Sjkim if (j == 0) 711280297Sjkim break; 712280297Sjkim if ((j >= '0') && (j <= '9')) 713280297Sjkim j -= '0'; 714280297Sjkim else if ((j >= 'A') && (j <= 'F')) 715280297Sjkim j = j - 'A' + 10; 716280297Sjkim else if ((j >= 'a') && (j <= 'f')) 717280297Sjkim j = j - 'a' + 10; 718280297Sjkim else { 719280297Sjkim BIO_printf(bio_err, "non-hex digit\n"); 720280297Sjkim return (0); 721280297Sjkim } 722280297Sjkim if (i & 1) 723280297Sjkim out[i / 2] |= j; 724280297Sjkim else 725280297Sjkim out[i / 2] = (j << 4); 726280297Sjkim } 727280297Sjkim return (1); 728280297Sjkim} 729