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. 8280304Sjkim * 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). 15280304Sjkim * 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. 22280304Sjkim * 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 :-). 37280304Sjkim * 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)" 40280304Sjkim * 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. 52280304Sjkim * 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> 70269686Sjkim#ifndef OPENSSL_NO_COMP 71280304Sjkim# include <openssl/comp.h> 72269686Sjkim#endif 73109998Smarkm#include <ctype.h> 7455714Skris 75280304Sjkimint set_hex(char *in, unsigned char *out, int size); 7655714Skris#undef SIZE 7755714Skris#undef BSIZE 7855714Skris#undef PROG 7955714Skris 80280304Sjkim#define SIZE (512) 81280304Sjkim#define BSIZE (8*1024) 82280304Sjkim#define PROG enc_main 8355714Skris 84280304Sjkimstatic void show_ciphers(const OBJ_NAME *name, void *bio_) 85280304Sjkim{ 86280304Sjkim BIO *bio = bio_; 87280304Sjkim static int n; 88109998Smarkm 89280304Sjkim if (!islower((unsigned char)*name->name)) 90280304Sjkim return; 91109998Smarkm 92280304Sjkim BIO_printf(bio, "-%-25s", name->name); 93280304Sjkim if (++n == 3) { 94280304Sjkim BIO_printf(bio, "\n"); 95280304Sjkim n = 0; 96280304Sjkim } else 97280304Sjkim BIO_printf(bio, " "); 98280304Sjkim} 99109998Smarkm 10059191Skrisint MAIN(int, char **); 10159191Skris 10255714Skrisint MAIN(int argc, char **argv) 103280304Sjkim{ 104280304Sjkim static const char magic[] = "Salted__"; 105280304Sjkim char mbuf[sizeof magic - 1]; 106280304Sjkim char *strbuf = NULL; 107280304Sjkim unsigned char *buff = NULL, *bufsize = NULL; 108280304Sjkim int bsize = BSIZE, verbose = 0; 109280304Sjkim int ret = 1, inl; 110280304Sjkim int nopad = 0; 111280304Sjkim unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; 112280304Sjkim unsigned char salt[PKCS5_SALT_LEN]; 113280304Sjkim char *str = NULL, *passarg = NULL, *pass = NULL; 114280304Sjkim char *hkey = NULL, *hiv = NULL, *hsalt = NULL; 115280304Sjkim char *md = NULL; 116280304Sjkim int enc = 1, printkey = 0, i, base64 = 0; 117238405Sjkim#ifdef ZLIB 118280304Sjkim int do_zlib = 0; 119280304Sjkim BIO *bzl = NULL; 120238405Sjkim#endif 121280304Sjkim int debug = 0, olb64 = 0, nosalt = 0; 122280304Sjkim const EVP_CIPHER *cipher = NULL, *c; 123280304Sjkim EVP_CIPHER_CTX *ctx = NULL; 124280304Sjkim char *inf = NULL, *outf = NULL; 125280304Sjkim BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = 126280304Sjkim NULL, *wbio = NULL; 127100928Snectar#define PROG_NAME_SIZE 39 128280304Sjkim char pname[PROG_NAME_SIZE + 1]; 129111147Snectar#ifndef OPENSSL_NO_ENGINE 130280304Sjkim char *engine = NULL; 131111147Snectar#endif 132280304Sjkim const EVP_MD *dgst = NULL; 133280304Sjkim int non_fips_allow = 0; 13455714Skris 135280304Sjkim apps_startup(); 13655714Skris 137280304Sjkim if (bio_err == NULL) 138280304Sjkim if ((bio_err = BIO_new(BIO_s_file())) != NULL) 139280304Sjkim BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 14055714Skris 141280304Sjkim if (!load_config(bio_err, NULL)) 142280304Sjkim goto end; 143109998Smarkm 144280304Sjkim /* first check the program name */ 145280304Sjkim program_name(argv[0], pname, sizeof pname); 146280304Sjkim if (strcmp(pname, "base64") == 0) 147280304Sjkim base64 = 1; 148238405Sjkim#ifdef ZLIB 149280304Sjkim if (strcmp(pname, "zlib") == 0) 150280304Sjkim do_zlib = 1; 151238405Sjkim#endif 15255714Skris 153280304Sjkim cipher = EVP_get_cipherbyname(pname); 154238405Sjkim#ifdef ZLIB 155280304Sjkim if (!do_zlib && !base64 && (cipher == NULL) 156280304Sjkim && (strcmp(pname, "enc") != 0)) 157238405Sjkim#else 158280304Sjkim if (!base64 && (cipher == NULL) && (strcmp(pname, "enc") != 0)) 159238405Sjkim#endif 160280304Sjkim { 161280304Sjkim BIO_printf(bio_err, "%s is an unknown cipher\n", pname); 162280304Sjkim goto bad; 163280304Sjkim } 16455714Skris 165280304Sjkim argc--; 166280304Sjkim argv++; 167280304Sjkim while (argc >= 1) { 168280304Sjkim if (strcmp(*argv, "-e") == 0) 169280304Sjkim enc = 1; 170280304Sjkim else if (strcmp(*argv, "-in") == 0) { 171280304Sjkim if (--argc < 1) 172280304Sjkim goto bad; 173280304Sjkim inf = *(++argv); 174280304Sjkim } else if (strcmp(*argv, "-out") == 0) { 175280304Sjkim if (--argc < 1) 176280304Sjkim goto bad; 177280304Sjkim outf = *(++argv); 178280304Sjkim } else if (strcmp(*argv, "-pass") == 0) { 179280304Sjkim if (--argc < 1) 180280304Sjkim goto bad; 181280304Sjkim passarg = *(++argv); 182280304Sjkim } 183111147Snectar#ifndef OPENSSL_NO_ENGINE 184280304Sjkim else if (strcmp(*argv, "-engine") == 0) { 185280304Sjkim if (--argc < 1) 186280304Sjkim goto bad; 187280304Sjkim engine = *(++argv); 188280304Sjkim } 189111147Snectar#endif 190280304Sjkim else if (strcmp(*argv, "-d") == 0) 191280304Sjkim enc = 0; 192280304Sjkim else if (strcmp(*argv, "-p") == 0) 193280304Sjkim printkey = 1; 194280304Sjkim else if (strcmp(*argv, "-v") == 0) 195280304Sjkim verbose = 1; 196280304Sjkim else if (strcmp(*argv, "-nopad") == 0) 197280304Sjkim nopad = 1; 198280304Sjkim else if (strcmp(*argv, "-salt") == 0) 199280304Sjkim nosalt = 0; 200280304Sjkim else if (strcmp(*argv, "-nosalt") == 0) 201280304Sjkim nosalt = 1; 202280304Sjkim else if (strcmp(*argv, "-debug") == 0) 203280304Sjkim debug = 1; 204280304Sjkim else if (strcmp(*argv, "-P") == 0) 205280304Sjkim printkey = 2; 206280304Sjkim else if (strcmp(*argv, "-A") == 0) 207280304Sjkim olb64 = 1; 208280304Sjkim else if (strcmp(*argv, "-a") == 0) 209280304Sjkim base64 = 1; 210280304Sjkim else if (strcmp(*argv, "-base64") == 0) 211280304Sjkim base64 = 1; 212238405Sjkim#ifdef ZLIB 213280304Sjkim else if (strcmp(*argv, "-z") == 0) 214280304Sjkim do_zlib = 1; 215238405Sjkim#endif 216280304Sjkim else if (strcmp(*argv, "-bufsize") == 0) { 217280304Sjkim if (--argc < 1) 218280304Sjkim goto bad; 219280304Sjkim bufsize = (unsigned char *)*(++argv); 220280304Sjkim } else if (strcmp(*argv, "-k") == 0) { 221280304Sjkim if (--argc < 1) 222280304Sjkim goto bad; 223280304Sjkim str = *(++argv); 224280304Sjkim } else if (strcmp(*argv, "-kfile") == 0) { 225280304Sjkim static char buf[128]; 226280304Sjkim FILE *infile; 227280304Sjkim char *file; 22855714Skris 229280304Sjkim if (--argc < 1) 230280304Sjkim goto bad; 231280304Sjkim file = *(++argv); 232280304Sjkim infile = fopen(file, "r"); 233280304Sjkim if (infile == NULL) { 234280304Sjkim BIO_printf(bio_err, "unable to read key from '%s'\n", file); 235280304Sjkim goto bad; 236280304Sjkim } 237280304Sjkim buf[0] = '\0'; 238280304Sjkim if (!fgets(buf, sizeof buf, infile)) { 239280304Sjkim BIO_printf(bio_err, "unable to read key from '%s'\n", file); 240280304Sjkim goto bad; 241280304Sjkim } 242280304Sjkim fclose(infile); 243280304Sjkim i = strlen(buf); 244280304Sjkim if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 245280304Sjkim buf[--i] = '\0'; 246280304Sjkim if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 247280304Sjkim buf[--i] = '\0'; 248280304Sjkim if (i < 1) { 249280304Sjkim BIO_printf(bio_err, "zero length password\n"); 250280304Sjkim goto bad; 251280304Sjkim } 252280304Sjkim str = buf; 253280304Sjkim } else if (strcmp(*argv, "-K") == 0) { 254280304Sjkim if (--argc < 1) 255280304Sjkim goto bad; 256280304Sjkim hkey = *(++argv); 257280304Sjkim } else if (strcmp(*argv, "-S") == 0) { 258280304Sjkim if (--argc < 1) 259280304Sjkim goto bad; 260280304Sjkim hsalt = *(++argv); 261280304Sjkim } else if (strcmp(*argv, "-iv") == 0) { 262280304Sjkim if (--argc < 1) 263280304Sjkim goto bad; 264280304Sjkim hiv = *(++argv); 265280304Sjkim } else if (strcmp(*argv, "-md") == 0) { 266280304Sjkim if (--argc < 1) 267280304Sjkim goto bad; 268280304Sjkim md = *(++argv); 269280304Sjkim } else if (strcmp(*argv, "-non-fips-allow") == 0) 270280304Sjkim non_fips_allow = 1; 271280304Sjkim else if ((argv[0][0] == '-') && 272280304Sjkim ((c = EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { 273280304Sjkim cipher = c; 274280304Sjkim } else if (strcmp(*argv, "-none") == 0) 275280304Sjkim cipher = NULL; 276280304Sjkim else { 277280304Sjkim BIO_printf(bio_err, "unknown option '%s'\n", *argv); 278280304Sjkim bad: 279280304Sjkim BIO_printf(bio_err, "options are\n"); 280280304Sjkim BIO_printf(bio_err, "%-14s input file\n", "-in <file>"); 281280304Sjkim BIO_printf(bio_err, "%-14s output file\n", "-out <file>"); 282280304Sjkim BIO_printf(bio_err, "%-14s pass phrase source\n", "-pass <arg>"); 283280304Sjkim BIO_printf(bio_err, "%-14s encrypt\n", "-e"); 284280304Sjkim BIO_printf(bio_err, "%-14s decrypt\n", "-d"); 285280304Sjkim BIO_printf(bio_err, 286280304Sjkim "%-14s base64 encode/decode, depending on encryption flag\n", 287280304Sjkim "-a/-base64"); 288280304Sjkim BIO_printf(bio_err, "%-14s passphrase is the next argument\n", 289280304Sjkim "-k"); 290280304Sjkim BIO_printf(bio_err, 291280304Sjkim "%-14s passphrase is the first line of the file argument\n", 292280304Sjkim "-kfile"); 293280304Sjkim BIO_printf(bio_err, 294280304Sjkim "%-14s the next argument is the md to use to create a key\n", 295280304Sjkim "-md"); 296280304Sjkim BIO_printf(bio_err, 297280304Sjkim "%-14s from a passphrase. One of md2, md5, sha or sha1\n", 298280304Sjkim ""); 299280304Sjkim BIO_printf(bio_err, "%-14s salt in hex is the next argument\n", 300280304Sjkim "-S"); 301280304Sjkim BIO_printf(bio_err, "%-14s key/iv in hex is the next argument\n", 302280304Sjkim "-K/-iv"); 303280304Sjkim BIO_printf(bio_err, "%-14s print the iv/key (then exit if -P)\n", 304280304Sjkim "-[pP]"); 305280304Sjkim BIO_printf(bio_err, "%-14s buffer size\n", "-bufsize <n>"); 306280304Sjkim BIO_printf(bio_err, "%-14s disable standard block padding\n", 307280304Sjkim "-nopad"); 308111147Snectar#ifndef OPENSSL_NO_ENGINE 309280304Sjkim BIO_printf(bio_err, 310280304Sjkim "%-14s use engine e, possibly a hardware device.\n", 311280304Sjkim "-engine e"); 312111147Snectar#endif 31355714Skris 314280304Sjkim BIO_printf(bio_err, "Cipher Types\n"); 315280304Sjkim OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, 316280304Sjkim show_ciphers, bio_err); 317280304Sjkim BIO_printf(bio_err, "\n"); 31855714Skris 319280304Sjkim goto end; 320280304Sjkim } 321280304Sjkim argc--; 322280304Sjkim argv++; 323280304Sjkim } 32455714Skris 325111147Snectar#ifndef OPENSSL_NO_ENGINE 326280304Sjkim setup_engine(bio_err, engine, 0); 327111147Snectar#endif 328109998Smarkm 329280304Sjkim if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { 330280304Sjkim BIO_printf(bio_err, 331280304Sjkim "AEAD ciphers not supported by the enc utility\n"); 332280304Sjkim goto end; 333280304Sjkim } 334267258Sjkim 335280304Sjkim if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) { 336280304Sjkim BIO_printf(bio_err, 337280304Sjkim "Ciphers in XTS mode are not supported by the enc utility\n"); 338280304Sjkim goto end; 339280304Sjkim } 340269686Sjkim 341280304Sjkim if (md && (dgst = EVP_get_digestbyname(md)) == NULL) { 342280304Sjkim BIO_printf(bio_err, "%s is an unsupported message digest type\n", md); 343280304Sjkim goto end; 344280304Sjkim } 345142425Snectar 346280304Sjkim if (dgst == NULL) { 347280304Sjkim dgst = EVP_md5(); 348280304Sjkim } 349142425Snectar 350280304Sjkim if (bufsize != NULL) { 351280304Sjkim unsigned long n; 35255714Skris 353280304Sjkim for (n = 0; *bufsize; bufsize++) { 354280304Sjkim i = *bufsize; 355280304Sjkim if ((i <= '9') && (i >= '0')) 356280304Sjkim n = n * 10 + i - '0'; 357280304Sjkim else if (i == 'k') { 358280304Sjkim n *= 1024; 359280304Sjkim bufsize++; 360280304Sjkim break; 361280304Sjkim } 362280304Sjkim } 363280304Sjkim if (*bufsize != '\0') { 364280304Sjkim BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); 365280304Sjkim goto end; 366280304Sjkim } 36755714Skris 368280304Sjkim /* It must be large enough for a base64 encoded line */ 369280304Sjkim if (base64 && n < 80) 370280304Sjkim n = 80; 37155714Skris 372280304Sjkim bsize = (int)n; 373280304Sjkim if (verbose) 374280304Sjkim BIO_printf(bio_err, "bufsize=%d\n", bsize); 375280304Sjkim } 37655714Skris 377280304Sjkim strbuf = OPENSSL_malloc(SIZE); 378280304Sjkim buff = (unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); 379280304Sjkim if ((buff == NULL) || (strbuf == NULL)) { 380280304Sjkim BIO_printf(bio_err, "OPENSSL_malloc failure %ld\n", 381280304Sjkim (long)EVP_ENCODE_LENGTH(bsize)); 382280304Sjkim goto end; 383280304Sjkim } 38455714Skris 385280304Sjkim in = BIO_new(BIO_s_file()); 386280304Sjkim out = BIO_new(BIO_s_file()); 387280304Sjkim if ((in == NULL) || (out == NULL)) { 388280304Sjkim ERR_print_errors(bio_err); 389280304Sjkim goto end; 390280304Sjkim } 391280304Sjkim if (debug) { 392280304Sjkim BIO_set_callback(in, BIO_debug_callback); 393280304Sjkim BIO_set_callback(out, BIO_debug_callback); 394280304Sjkim BIO_set_callback_arg(in, (char *)bio_err); 395280304Sjkim BIO_set_callback_arg(out, (char *)bio_err); 396280304Sjkim } 39755714Skris 398280304Sjkim if (inf == NULL) { 399238405Sjkim#ifndef OPENSSL_NO_SETVBUF_IONBF 400280304Sjkim if (bufsize != NULL) 401280304Sjkim setvbuf(stdin, (char *)NULL, _IONBF, 0); 402280304Sjkim#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 403280304Sjkim BIO_set_fp(in, stdin, BIO_NOCLOSE); 404280304Sjkim } else { 405280304Sjkim if (BIO_read_filename(in, inf) <= 0) { 406280304Sjkim perror(inf); 407280304Sjkim goto end; 408280304Sjkim } 409280304Sjkim } 41055714Skris 411280304Sjkim if (!str && passarg) { 412280304Sjkim if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { 413280304Sjkim BIO_printf(bio_err, "Error getting password\n"); 414280304Sjkim goto end; 415280304Sjkim } 416280304Sjkim str = pass; 417280304Sjkim } 41859191Skris 419280304Sjkim if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { 420280304Sjkim for (;;) { 421280304Sjkim char buf[200]; 42255714Skris 423280304Sjkim BIO_snprintf(buf, sizeof buf, "enter %s %s password:", 424280304Sjkim OBJ_nid2ln(EVP_CIPHER_nid(cipher)), 425280304Sjkim (enc) ? "encryption" : "decryption"); 426280304Sjkim strbuf[0] = '\0'; 427280304Sjkim i = EVP_read_pw_string((char *)strbuf, SIZE, buf, enc); 428280304Sjkim if (i == 0) { 429280304Sjkim if (strbuf[0] == '\0') { 430280304Sjkim ret = 1; 431280304Sjkim goto end; 432280304Sjkim } 433280304Sjkim str = strbuf; 434280304Sjkim break; 435280304Sjkim } 436280304Sjkim if (i < 0) { 437280304Sjkim BIO_printf(bio_err, "bad password read\n"); 438280304Sjkim goto end; 439280304Sjkim } 440280304Sjkim } 441280304Sjkim } 44255714Skris 443280304Sjkim if (outf == NULL) { 444280304Sjkim BIO_set_fp(out, stdout, BIO_NOCLOSE); 445238405Sjkim#ifndef OPENSSL_NO_SETVBUF_IONBF 446280304Sjkim if (bufsize != NULL) 447280304Sjkim setvbuf(stdout, (char *)NULL, _IONBF, 0); 448280304Sjkim#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 449109998Smarkm#ifdef OPENSSL_SYS_VMS 450280304Sjkim { 451280304Sjkim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 452280304Sjkim out = BIO_push(tmpbio, out); 453280304Sjkim } 45468651Skris#endif 455280304Sjkim } else { 456280304Sjkim if (BIO_write_filename(out, outf) <= 0) { 457280304Sjkim perror(outf); 458280304Sjkim goto end; 459280304Sjkim } 460280304Sjkim } 46159191Skris 462280304Sjkim rbio = in; 463280304Sjkim wbio = out; 46459191Skris 465238405Sjkim#ifdef ZLIB 466238405Sjkim 467280304Sjkim if (do_zlib) { 468280304Sjkim if ((bzl = BIO_new(BIO_f_zlib())) == NULL) 469280304Sjkim goto end; 470280304Sjkim if (enc) 471280304Sjkim wbio = BIO_push(bzl, wbio); 472280304Sjkim else 473280304Sjkim rbio = BIO_push(bzl, rbio); 474280304Sjkim } 475238405Sjkim#endif 476238405Sjkim 477280304Sjkim if (base64) { 478280304Sjkim if ((b64 = BIO_new(BIO_f_base64())) == NULL) 479280304Sjkim goto end; 480280304Sjkim if (debug) { 481280304Sjkim BIO_set_callback(b64, BIO_debug_callback); 482280304Sjkim BIO_set_callback_arg(b64, (char *)bio_err); 483280304Sjkim } 484280304Sjkim if (olb64) 485280304Sjkim BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 486280304Sjkim if (enc) 487280304Sjkim wbio = BIO_push(b64, wbio); 488280304Sjkim else 489280304Sjkim rbio = BIO_push(b64, rbio); 490280304Sjkim } 49159191Skris 492280304Sjkim if (cipher != NULL) { 493280304Sjkim /* 494280304Sjkim * Note that str is NULL if a key was passed on the command line, so 495280304Sjkim * we get no salt in that case. Is this a bug? 496280304Sjkim */ 497280304Sjkim if (str != NULL) { 498280304Sjkim /* 499280304Sjkim * Salt handling: if encrypting generate a salt and write to 500280304Sjkim * output BIO. If decrypting read salt from input BIO. 501280304Sjkim */ 502280304Sjkim unsigned char *sptr; 503280304Sjkim if (nosalt) 504280304Sjkim sptr = NULL; 505280304Sjkim else { 506280304Sjkim if (enc) { 507280304Sjkim if (hsalt) { 508280304Sjkim if (!set_hex(hsalt, salt, sizeof salt)) { 509280304Sjkim BIO_printf(bio_err, "invalid hex salt value\n"); 510280304Sjkim goto end; 511280304Sjkim } 512306196Sjkim } else if (RAND_bytes(salt, sizeof salt) <= 0) 513280304Sjkim goto end; 514280304Sjkim /* 515280304Sjkim * If -P option then don't bother writing 516280304Sjkim */ 517280304Sjkim if ((printkey != 2) 518280304Sjkim && (BIO_write(wbio, magic, 519280304Sjkim sizeof magic - 1) != sizeof magic - 1 520280304Sjkim || BIO_write(wbio, 521280304Sjkim (char *)salt, 522280304Sjkim sizeof salt) != sizeof salt)) { 523280304Sjkim BIO_printf(bio_err, "error writing output file\n"); 524280304Sjkim goto end; 525280304Sjkim } 526280304Sjkim } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf 527280304Sjkim || BIO_read(rbio, 528280304Sjkim (unsigned char *)salt, 529280304Sjkim sizeof salt) != sizeof salt) { 530280304Sjkim BIO_printf(bio_err, "error reading input file\n"); 531280304Sjkim goto end; 532280304Sjkim } else if (memcmp(mbuf, magic, sizeof magic - 1)) { 533280304Sjkim BIO_printf(bio_err, "bad magic number\n"); 534280304Sjkim goto end; 535280304Sjkim } 53659191Skris 537280304Sjkim sptr = salt; 538280304Sjkim } 53959191Skris 540280304Sjkim EVP_BytesToKey(cipher, dgst, sptr, 541280304Sjkim (unsigned char *)str, strlen(str), 1, key, iv); 542280304Sjkim /* 543280304Sjkim * zero the complete buffer or the string passed from the command 544280304Sjkim * line bug picked up by Larry J. Hughes Jr. <hughes@indiana.edu> 545280304Sjkim */ 546280304Sjkim if (str == strbuf) 547280304Sjkim OPENSSL_cleanse(str, SIZE); 548280304Sjkim else 549280304Sjkim OPENSSL_cleanse(str, strlen(str)); 550280304Sjkim } 551284285Sjkim if (hiv != NULL) { 552284285Sjkim int siz = EVP_CIPHER_iv_length(cipher); 553284285Sjkim if (siz == 0) { 554284285Sjkim BIO_printf(bio_err, "warning: iv not use by this cipher\n"); 555284285Sjkim } else if (!set_hex(hiv, iv, sizeof iv)) { 556284285Sjkim BIO_printf(bio_err, "invalid hex iv value\n"); 557284285Sjkim goto end; 558284285Sjkim } 559280304Sjkim } 560280304Sjkim if ((hiv == NULL) && (str == NULL) 561280304Sjkim && EVP_CIPHER_iv_length(cipher) != 0) { 562280304Sjkim /* 563280304Sjkim * No IV was explicitly set and no IV was generated during 564280304Sjkim * EVP_BytesToKey. Hence the IV is undefined, making correct 565280304Sjkim * decryption impossible. 566280304Sjkim */ 567280304Sjkim BIO_printf(bio_err, "iv undefined\n"); 568280304Sjkim goto end; 569280304Sjkim } 570284285Sjkim if ((hkey != NULL) && !set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) { 571280304Sjkim BIO_printf(bio_err, "invalid hex key value\n"); 572280304Sjkim goto end; 573280304Sjkim } 57455714Skris 575280304Sjkim if ((benc = BIO_new(BIO_f_cipher())) == NULL) 576280304Sjkim goto end; 577160814Ssimon 578280304Sjkim /* 579280304Sjkim * Since we may be changing parameters work on the encryption context 580280304Sjkim * rather than calling BIO_set_cipher(). 581280304Sjkim */ 582160814Ssimon 583280304Sjkim BIO_get_cipher_ctx(benc, &ctx); 584194206Ssimon 585280304Sjkim if (non_fips_allow) 586280304Sjkim EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); 587194206Ssimon 588280304Sjkim if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { 589280304Sjkim BIO_printf(bio_err, "Error setting cipher %s\n", 590280304Sjkim EVP_CIPHER_name(cipher)); 591280304Sjkim ERR_print_errors(bio_err); 592280304Sjkim goto end; 593280304Sjkim } 594160814Ssimon 595280304Sjkim if (nopad) 596280304Sjkim EVP_CIPHER_CTX_set_padding(ctx, 0); 597160814Ssimon 598280304Sjkim if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { 599280304Sjkim BIO_printf(bio_err, "Error setting cipher %s\n", 600280304Sjkim EVP_CIPHER_name(cipher)); 601280304Sjkim ERR_print_errors(bio_err); 602280304Sjkim goto end; 603280304Sjkim } 604160814Ssimon 605280304Sjkim if (debug) { 606280304Sjkim BIO_set_callback(benc, BIO_debug_callback); 607280304Sjkim BIO_set_callback_arg(benc, (char *)bio_err); 608280304Sjkim } 60955714Skris 610280304Sjkim if (printkey) { 611280304Sjkim if (!nosalt) { 612280304Sjkim printf("salt="); 613280304Sjkim for (i = 0; i < (int)sizeof(salt); i++) 614280304Sjkim printf("%02X", salt[i]); 615280304Sjkim printf("\n"); 616280304Sjkim } 617280304Sjkim if (cipher->key_len > 0) { 618280304Sjkim printf("key="); 619280304Sjkim for (i = 0; i < cipher->key_len; i++) 620280304Sjkim printf("%02X", key[i]); 621280304Sjkim printf("\n"); 622280304Sjkim } 623280304Sjkim if (cipher->iv_len > 0) { 624280304Sjkim printf("iv ="); 625280304Sjkim for (i = 0; i < cipher->iv_len; i++) 626280304Sjkim printf("%02X", iv[i]); 627280304Sjkim printf("\n"); 628280304Sjkim } 629280304Sjkim if (printkey == 2) { 630280304Sjkim ret = 0; 631280304Sjkim goto end; 632280304Sjkim } 633280304Sjkim } 634280304Sjkim } 63555714Skris 636280304Sjkim /* Only encrypt/decrypt as we write the file */ 637280304Sjkim if (benc != NULL) 638280304Sjkim wbio = BIO_push(benc, wbio); 63955714Skris 640280304Sjkim for (;;) { 641280304Sjkim inl = BIO_read(rbio, (char *)buff, bsize); 642280304Sjkim if (inl <= 0) 643280304Sjkim break; 644280304Sjkim if (BIO_write(wbio, (char *)buff, inl) != inl) { 645280304Sjkim BIO_printf(bio_err, "error writing output file\n"); 646280304Sjkim goto end; 647280304Sjkim } 648280304Sjkim } 649280304Sjkim if (!BIO_flush(wbio)) { 650280304Sjkim BIO_printf(bio_err, "bad decrypt\n"); 651280304Sjkim goto end; 652280304Sjkim } 65355714Skris 654280304Sjkim ret = 0; 655280304Sjkim if (verbose) { 656280304Sjkim BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); 657280304Sjkim BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); 658280304Sjkim } 659280304Sjkim end: 660280304Sjkim ERR_print_errors(bio_err); 661280304Sjkim if (strbuf != NULL) 662280304Sjkim OPENSSL_free(strbuf); 663280304Sjkim if (buff != NULL) 664280304Sjkim OPENSSL_free(buff); 665280304Sjkim if (in != NULL) 666280304Sjkim BIO_free(in); 667280304Sjkim if (out != NULL) 668280304Sjkim BIO_free_all(out); 669280304Sjkim if (benc != NULL) 670280304Sjkim BIO_free(benc); 671280304Sjkim if (b64 != NULL) 672280304Sjkim BIO_free(b64); 673238405Sjkim#ifdef ZLIB 674280304Sjkim if (bzl != NULL) 675280304Sjkim BIO_free(bzl); 676238405Sjkim#endif 677280304Sjkim if (pass) 678280304Sjkim OPENSSL_free(pass); 679280304Sjkim apps_shutdown(); 680280304Sjkim OPENSSL_EXIT(ret); 681280304Sjkim} 68255714Skris 68355714Skrisint set_hex(char *in, unsigned char *out, int size) 684280304Sjkim{ 685280304Sjkim int i, n; 686280304Sjkim unsigned char j; 68755714Skris 688280304Sjkim n = strlen(in); 689280304Sjkim if (n > (size * 2)) { 690280304Sjkim BIO_printf(bio_err, "hex string is too long\n"); 691280304Sjkim return (0); 692280304Sjkim } 693280304Sjkim memset(out, 0, size); 694280304Sjkim for (i = 0; i < n; i++) { 695280304Sjkim j = (unsigned char)*in; 696280304Sjkim *(in++) = '\0'; 697280304Sjkim if (j == 0) 698280304Sjkim break; 699280304Sjkim if ((j >= '0') && (j <= '9')) 700280304Sjkim j -= '0'; 701280304Sjkim else if ((j >= 'A') && (j <= 'F')) 702280304Sjkim j = j - 'A' + 10; 703280304Sjkim else if ((j >= 'a') && (j <= 'f')) 704280304Sjkim j = j - 'a' + 10; 705280304Sjkim else { 706280304Sjkim BIO_printf(bio_err, "non-hex digit\n"); 707280304Sjkim return (0); 708280304Sjkim } 709280304Sjkim if (i & 1) 710280304Sjkim out[i / 2] |= j; 711280304Sjkim else 712280304Sjkim out[i / 2] = (j << 4); 713280304Sjkim } 714280304Sjkim return (1); 715280304Sjkim} 716