enc.c revision 312826
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 84280297Sjkimstatic void show_ciphers(const OBJ_NAME *name, void *bio_) 85280297Sjkim{ 86280297Sjkim BIO *bio = bio_; 87280297Sjkim static int n; 88109998Smarkm 89280297Sjkim if (!islower((unsigned char)*name->name)) 90280297Sjkim return; 91109998Smarkm 92280297Sjkim BIO_printf(bio, "-%-25s", name->name); 93280297Sjkim if (++n == 3) { 94280297Sjkim BIO_printf(bio, "\n"); 95280297Sjkim n = 0; 96280297Sjkim } else 97280297Sjkim BIO_printf(bio, " "); 98280297Sjkim} 99109998Smarkm 10059191Skrisint MAIN(int, char **); 10159191Skris 10255714Skrisint MAIN(int argc, char **argv) 103280297Sjkim{ 104280297Sjkim static const char magic[] = "Salted__"; 105280297Sjkim char mbuf[sizeof magic - 1]; 106280297Sjkim char *strbuf = NULL; 107280297Sjkim unsigned char *buff = NULL, *bufsize = NULL; 108280297Sjkim int bsize = BSIZE, verbose = 0; 109280297Sjkim int ret = 1, inl; 110280297Sjkim int nopad = 0; 111280297Sjkim unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; 112280297Sjkim unsigned char salt[PKCS5_SALT_LEN]; 113280297Sjkim char *str = NULL, *passarg = NULL, *pass = NULL; 114280297Sjkim char *hkey = NULL, *hiv = NULL, *hsalt = NULL; 115280297Sjkim char *md = NULL; 116280297Sjkim int enc = 1, printkey = 0, i, base64 = 0; 117238405Sjkim#ifdef ZLIB 118280297Sjkim int do_zlib = 0; 119280297Sjkim BIO *bzl = NULL; 120238405Sjkim#endif 121280297Sjkim int debug = 0, olb64 = 0, nosalt = 0; 122280297Sjkim const EVP_CIPHER *cipher = NULL, *c; 123280297Sjkim EVP_CIPHER_CTX *ctx = NULL; 124280297Sjkim char *inf = NULL, *outf = NULL; 125280297Sjkim BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = 126280297Sjkim NULL, *wbio = NULL; 127100928Snectar#define PROG_NAME_SIZE 39 128280297Sjkim char pname[PROG_NAME_SIZE + 1]; 129280297Sjkim char *engine = NULL; 130312826Sjkim ENGINE *e = NULL; 131280297Sjkim const EVP_MD *dgst = NULL; 132280297Sjkim int non_fips_allow = 0; 13355714Skris 134280297Sjkim apps_startup(); 13555714Skris 136280297Sjkim if (bio_err == NULL) 137280297Sjkim if ((bio_err = BIO_new(BIO_s_file())) != NULL) 138280297Sjkim BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 13955714Skris 140280297Sjkim if (!load_config(bio_err, NULL)) 141280297Sjkim goto end; 142109998Smarkm 143280297Sjkim /* first check the program name */ 144280297Sjkim program_name(argv[0], pname, sizeof pname); 145280297Sjkim if (strcmp(pname, "base64") == 0) 146280297Sjkim base64 = 1; 147238405Sjkim#ifdef ZLIB 148280297Sjkim if (strcmp(pname, "zlib") == 0) 149280297Sjkim do_zlib = 1; 150238405Sjkim#endif 15155714Skris 152280297Sjkim cipher = EVP_get_cipherbyname(pname); 153238405Sjkim#ifdef ZLIB 154280297Sjkim if (!do_zlib && !base64 && (cipher == NULL) 155280297Sjkim && (strcmp(pname, "enc") != 0)) 156238405Sjkim#else 157280297Sjkim if (!base64 && (cipher == NULL) && (strcmp(pname, "enc") != 0)) 158238405Sjkim#endif 159280297Sjkim { 160280297Sjkim BIO_printf(bio_err, "%s is an unknown cipher\n", pname); 161280297Sjkim goto bad; 162280297Sjkim } 16355714Skris 164280297Sjkim argc--; 165280297Sjkim argv++; 166280297Sjkim while (argc >= 1) { 167280297Sjkim if (strcmp(*argv, "-e") == 0) 168280297Sjkim enc = 1; 169280297Sjkim else if (strcmp(*argv, "-in") == 0) { 170280297Sjkim if (--argc < 1) 171280297Sjkim goto bad; 172280297Sjkim inf = *(++argv); 173280297Sjkim } else if (strcmp(*argv, "-out") == 0) { 174280297Sjkim if (--argc < 1) 175280297Sjkim goto bad; 176280297Sjkim outf = *(++argv); 177280297Sjkim } else if (strcmp(*argv, "-pass") == 0) { 178280297Sjkim if (--argc < 1) 179280297Sjkim goto bad; 180280297Sjkim passarg = *(++argv); 181280297Sjkim } 182111147Snectar#ifndef OPENSSL_NO_ENGINE 183280297Sjkim else if (strcmp(*argv, "-engine") == 0) { 184280297Sjkim if (--argc < 1) 185280297Sjkim goto bad; 186280297Sjkim engine = *(++argv); 187280297Sjkim } 188111147Snectar#endif 189280297Sjkim else if (strcmp(*argv, "-d") == 0) 190280297Sjkim enc = 0; 191280297Sjkim else if (strcmp(*argv, "-p") == 0) 192280297Sjkim printkey = 1; 193280297Sjkim else if (strcmp(*argv, "-v") == 0) 194280297Sjkim verbose = 1; 195280297Sjkim else if (strcmp(*argv, "-nopad") == 0) 196280297Sjkim nopad = 1; 197280297Sjkim else if (strcmp(*argv, "-salt") == 0) 198280297Sjkim nosalt = 0; 199280297Sjkim else if (strcmp(*argv, "-nosalt") == 0) 200280297Sjkim nosalt = 1; 201280297Sjkim else if (strcmp(*argv, "-debug") == 0) 202280297Sjkim debug = 1; 203280297Sjkim else if (strcmp(*argv, "-P") == 0) 204280297Sjkim printkey = 2; 205280297Sjkim else if (strcmp(*argv, "-A") == 0) 206280297Sjkim olb64 = 1; 207280297Sjkim else if (strcmp(*argv, "-a") == 0) 208280297Sjkim base64 = 1; 209280297Sjkim else if (strcmp(*argv, "-base64") == 0) 210280297Sjkim base64 = 1; 211238405Sjkim#ifdef ZLIB 212280297Sjkim else if (strcmp(*argv, "-z") == 0) 213280297Sjkim do_zlib = 1; 214238405Sjkim#endif 215280297Sjkim else if (strcmp(*argv, "-bufsize") == 0) { 216280297Sjkim if (--argc < 1) 217280297Sjkim goto bad; 218280297Sjkim bufsize = (unsigned char *)*(++argv); 219280297Sjkim } else if (strcmp(*argv, "-k") == 0) { 220280297Sjkim if (--argc < 1) 221280297Sjkim goto bad; 222280297Sjkim str = *(++argv); 223280297Sjkim } else if (strcmp(*argv, "-kfile") == 0) { 224280297Sjkim static char buf[128]; 225280297Sjkim FILE *infile; 226280297Sjkim char *file; 22755714Skris 228280297Sjkim if (--argc < 1) 229280297Sjkim goto bad; 230280297Sjkim file = *(++argv); 231280297Sjkim infile = fopen(file, "r"); 232280297Sjkim if (infile == NULL) { 233280297Sjkim BIO_printf(bio_err, "unable to read key from '%s'\n", file); 234280297Sjkim goto bad; 235280297Sjkim } 236280297Sjkim buf[0] = '\0'; 237280297Sjkim if (!fgets(buf, sizeof buf, infile)) { 238280297Sjkim BIO_printf(bio_err, "unable to read key from '%s'\n", file); 239280297Sjkim goto bad; 240280297Sjkim } 241280297Sjkim fclose(infile); 242280297Sjkim i = strlen(buf); 243280297Sjkim if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 244280297Sjkim buf[--i] = '\0'; 245280297Sjkim if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 246280297Sjkim buf[--i] = '\0'; 247280297Sjkim if (i < 1) { 248280297Sjkim BIO_printf(bio_err, "zero length password\n"); 249280297Sjkim goto bad; 250280297Sjkim } 251280297Sjkim str = buf; 252280297Sjkim } else if (strcmp(*argv, "-K") == 0) { 253280297Sjkim if (--argc < 1) 254280297Sjkim goto bad; 255280297Sjkim hkey = *(++argv); 256280297Sjkim } else if (strcmp(*argv, "-S") == 0) { 257280297Sjkim if (--argc < 1) 258280297Sjkim goto bad; 259280297Sjkim hsalt = *(++argv); 260280297Sjkim } else if (strcmp(*argv, "-iv") == 0) { 261280297Sjkim if (--argc < 1) 262280297Sjkim goto bad; 263280297Sjkim hiv = *(++argv); 264280297Sjkim } else if (strcmp(*argv, "-md") == 0) { 265280297Sjkim if (--argc < 1) 266280297Sjkim goto bad; 267280297Sjkim md = *(++argv); 268280297Sjkim } else if (strcmp(*argv, "-non-fips-allow") == 0) 269280297Sjkim non_fips_allow = 1; 270280297Sjkim else if ((argv[0][0] == '-') && 271280297Sjkim ((c = EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { 272280297Sjkim cipher = c; 273280297Sjkim } else if (strcmp(*argv, "-none") == 0) 274280297Sjkim cipher = NULL; 275280297Sjkim else { 276280297Sjkim BIO_printf(bio_err, "unknown option '%s'\n", *argv); 277280297Sjkim bad: 278280297Sjkim BIO_printf(bio_err, "options are\n"); 279280297Sjkim BIO_printf(bio_err, "%-14s input file\n", "-in <file>"); 280280297Sjkim BIO_printf(bio_err, "%-14s output file\n", "-out <file>"); 281280297Sjkim BIO_printf(bio_err, "%-14s pass phrase source\n", "-pass <arg>"); 282280297Sjkim BIO_printf(bio_err, "%-14s encrypt\n", "-e"); 283280297Sjkim BIO_printf(bio_err, "%-14s decrypt\n", "-d"); 284280297Sjkim BIO_printf(bio_err, 285280297Sjkim "%-14s base64 encode/decode, depending on encryption flag\n", 286280297Sjkim "-a/-base64"); 287280297Sjkim BIO_printf(bio_err, "%-14s passphrase is the next argument\n", 288280297Sjkim "-k"); 289280297Sjkim BIO_printf(bio_err, 290280297Sjkim "%-14s passphrase is the first line of the file argument\n", 291280297Sjkim "-kfile"); 292280297Sjkim BIO_printf(bio_err, 293280297Sjkim "%-14s the next argument is the md to use to create a key\n", 294280297Sjkim "-md"); 295280297Sjkim BIO_printf(bio_err, 296280297Sjkim "%-14s from a passphrase. One of md2, md5, sha or sha1\n", 297280297Sjkim ""); 298280297Sjkim BIO_printf(bio_err, "%-14s salt in hex is the next argument\n", 299280297Sjkim "-S"); 300280297Sjkim BIO_printf(bio_err, "%-14s key/iv in hex is the next argument\n", 301280297Sjkim "-K/-iv"); 302280297Sjkim BIO_printf(bio_err, "%-14s print the iv/key (then exit if -P)\n", 303280297Sjkim "-[pP]"); 304280297Sjkim BIO_printf(bio_err, "%-14s buffer size\n", "-bufsize <n>"); 305280297Sjkim BIO_printf(bio_err, "%-14s disable standard block padding\n", 306280297Sjkim "-nopad"); 307111147Snectar#ifndef OPENSSL_NO_ENGINE 308280297Sjkim BIO_printf(bio_err, 309280297Sjkim "%-14s use engine e, possibly a hardware device.\n", 310280297Sjkim "-engine e"); 311111147Snectar#endif 31255714Skris 313280297Sjkim BIO_printf(bio_err, "Cipher Types\n"); 314280297Sjkim OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, 315280297Sjkim show_ciphers, bio_err); 316280297Sjkim BIO_printf(bio_err, "\n"); 31755714Skris 318280297Sjkim goto end; 319280297Sjkim } 320280297Sjkim argc--; 321280297Sjkim argv++; 322280297Sjkim } 32355714Skris 324312826Sjkim e = setup_engine(bio_err, engine, 0); 325109998Smarkm 326280297Sjkim if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { 327280297Sjkim BIO_printf(bio_err, 328280297Sjkim "AEAD ciphers not supported by the enc utility\n"); 329280297Sjkim goto end; 330280297Sjkim } 331267256Sjkim 332280297Sjkim if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) { 333280297Sjkim BIO_printf(bio_err, 334280297Sjkim "Ciphers in XTS mode are not supported by the enc utility\n"); 335280297Sjkim goto end; 336280297Sjkim } 337269682Sjkim 338280297Sjkim if (md && (dgst = EVP_get_digestbyname(md)) == NULL) { 339280297Sjkim BIO_printf(bio_err, "%s is an unsupported message digest type\n", md); 340280297Sjkim goto end; 341280297Sjkim } 342142425Snectar 343280297Sjkim if (dgst == NULL) { 344280297Sjkim dgst = EVP_md5(); 345280297Sjkim } 346142425Snectar 347280297Sjkim if (bufsize != NULL) { 348280297Sjkim unsigned long n; 34955714Skris 350280297Sjkim for (n = 0; *bufsize; bufsize++) { 351280297Sjkim i = *bufsize; 352280297Sjkim if ((i <= '9') && (i >= '0')) 353280297Sjkim n = n * 10 + i - '0'; 354280297Sjkim else if (i == 'k') { 355280297Sjkim n *= 1024; 356280297Sjkim bufsize++; 357280297Sjkim break; 358280297Sjkim } 359280297Sjkim } 360280297Sjkim if (*bufsize != '\0') { 361280297Sjkim BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); 362280297Sjkim goto end; 363280297Sjkim } 36455714Skris 365280297Sjkim /* It must be large enough for a base64 encoded line */ 366280297Sjkim if (base64 && n < 80) 367280297Sjkim n = 80; 36855714Skris 369280297Sjkim bsize = (int)n; 370280297Sjkim if (verbose) 371280297Sjkim BIO_printf(bio_err, "bufsize=%d\n", bsize); 372280297Sjkim } 37355714Skris 374280297Sjkim strbuf = OPENSSL_malloc(SIZE); 375280297Sjkim buff = (unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); 376280297Sjkim if ((buff == NULL) || (strbuf == NULL)) { 377280297Sjkim BIO_printf(bio_err, "OPENSSL_malloc failure %ld\n", 378280297Sjkim (long)EVP_ENCODE_LENGTH(bsize)); 379280297Sjkim goto end; 380280297Sjkim } 38155714Skris 382280297Sjkim in = BIO_new(BIO_s_file()); 383280297Sjkim out = BIO_new(BIO_s_file()); 384280297Sjkim if ((in == NULL) || (out == NULL)) { 385280297Sjkim ERR_print_errors(bio_err); 386280297Sjkim goto end; 387280297Sjkim } 388280297Sjkim if (debug) { 389280297Sjkim BIO_set_callback(in, BIO_debug_callback); 390280297Sjkim BIO_set_callback(out, BIO_debug_callback); 391280297Sjkim BIO_set_callback_arg(in, (char *)bio_err); 392280297Sjkim BIO_set_callback_arg(out, (char *)bio_err); 393280297Sjkim } 39455714Skris 395280297Sjkim if (inf == NULL) { 396238405Sjkim#ifndef OPENSSL_NO_SETVBUF_IONBF 397280297Sjkim if (bufsize != NULL) 398280297Sjkim setvbuf(stdin, (char *)NULL, _IONBF, 0); 399280297Sjkim#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 400280297Sjkim BIO_set_fp(in, stdin, BIO_NOCLOSE); 401280297Sjkim } else { 402280297Sjkim if (BIO_read_filename(in, inf) <= 0) { 403280297Sjkim perror(inf); 404280297Sjkim goto end; 405280297Sjkim } 406280297Sjkim } 40755714Skris 408280297Sjkim if (!str && passarg) { 409280297Sjkim if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { 410280297Sjkim BIO_printf(bio_err, "Error getting password\n"); 411280297Sjkim goto end; 412280297Sjkim } 413280297Sjkim str = pass; 414280297Sjkim } 41559191Skris 416280297Sjkim if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { 417280297Sjkim for (;;) { 418280297Sjkim char buf[200]; 41955714Skris 420280297Sjkim BIO_snprintf(buf, sizeof buf, "enter %s %s password:", 421280297Sjkim OBJ_nid2ln(EVP_CIPHER_nid(cipher)), 422280297Sjkim (enc) ? "encryption" : "decryption"); 423280297Sjkim strbuf[0] = '\0'; 424280297Sjkim i = EVP_read_pw_string((char *)strbuf, SIZE, buf, enc); 425280297Sjkim if (i == 0) { 426280297Sjkim if (strbuf[0] == '\0') { 427280297Sjkim ret = 1; 428280297Sjkim goto end; 429280297Sjkim } 430280297Sjkim str = strbuf; 431280297Sjkim break; 432280297Sjkim } 433280297Sjkim if (i < 0) { 434280297Sjkim BIO_printf(bio_err, "bad password read\n"); 435280297Sjkim goto end; 436280297Sjkim } 437280297Sjkim } 438280297Sjkim } 43955714Skris 440280297Sjkim if (outf == NULL) { 441280297Sjkim BIO_set_fp(out, stdout, BIO_NOCLOSE); 442238405Sjkim#ifndef OPENSSL_NO_SETVBUF_IONBF 443280297Sjkim if (bufsize != NULL) 444280297Sjkim setvbuf(stdout, (char *)NULL, _IONBF, 0); 445280297Sjkim#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 446109998Smarkm#ifdef OPENSSL_SYS_VMS 447280297Sjkim { 448280297Sjkim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 449280297Sjkim out = BIO_push(tmpbio, out); 450280297Sjkim } 45168651Skris#endif 452280297Sjkim } else { 453280297Sjkim if (BIO_write_filename(out, outf) <= 0) { 454280297Sjkim perror(outf); 455280297Sjkim goto end; 456280297Sjkim } 457280297Sjkim } 45859191Skris 459280297Sjkim rbio = in; 460280297Sjkim wbio = out; 46159191Skris 462238405Sjkim#ifdef ZLIB 463238405Sjkim 464280297Sjkim if (do_zlib) { 465280297Sjkim if ((bzl = BIO_new(BIO_f_zlib())) == NULL) 466280297Sjkim goto end; 467280297Sjkim if (enc) 468280297Sjkim wbio = BIO_push(bzl, wbio); 469280297Sjkim else 470280297Sjkim rbio = BIO_push(bzl, rbio); 471280297Sjkim } 472238405Sjkim#endif 473238405Sjkim 474280297Sjkim if (base64) { 475280297Sjkim if ((b64 = BIO_new(BIO_f_base64())) == NULL) 476280297Sjkim goto end; 477280297Sjkim if (debug) { 478280297Sjkim BIO_set_callback(b64, BIO_debug_callback); 479280297Sjkim BIO_set_callback_arg(b64, (char *)bio_err); 480280297Sjkim } 481280297Sjkim if (olb64) 482280297Sjkim BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 483280297Sjkim if (enc) 484280297Sjkim wbio = BIO_push(b64, wbio); 485280297Sjkim else 486280297Sjkim rbio = BIO_push(b64, rbio); 487280297Sjkim } 48859191Skris 489280297Sjkim if (cipher != NULL) { 490280297Sjkim /* 491280297Sjkim * Note that str is NULL if a key was passed on the command line, so 492280297Sjkim * we get no salt in that case. Is this a bug? 493280297Sjkim */ 494280297Sjkim if (str != NULL) { 495280297Sjkim /* 496280297Sjkim * Salt handling: if encrypting generate a salt and write to 497280297Sjkim * output BIO. If decrypting read salt from input BIO. 498280297Sjkim */ 499280297Sjkim unsigned char *sptr; 500280297Sjkim if (nosalt) 501280297Sjkim sptr = NULL; 502280297Sjkim else { 503280297Sjkim if (enc) { 504280297Sjkim if (hsalt) { 505280297Sjkim if (!set_hex(hsalt, salt, sizeof salt)) { 506280297Sjkim BIO_printf(bio_err, "invalid hex salt value\n"); 507280297Sjkim goto end; 508280297Sjkim } 509306195Sjkim } else if (RAND_bytes(salt, sizeof salt) <= 0) 510280297Sjkim goto end; 511280297Sjkim /* 512280297Sjkim * If -P option then don't bother writing 513280297Sjkim */ 514280297Sjkim if ((printkey != 2) 515280297Sjkim && (BIO_write(wbio, magic, 516280297Sjkim sizeof magic - 1) != sizeof magic - 1 517280297Sjkim || BIO_write(wbio, 518280297Sjkim (char *)salt, 519280297Sjkim sizeof salt) != sizeof salt)) { 520280297Sjkim BIO_printf(bio_err, "error writing output file\n"); 521280297Sjkim goto end; 522280297Sjkim } 523280297Sjkim } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf 524280297Sjkim || BIO_read(rbio, 525280297Sjkim (unsigned char *)salt, 526280297Sjkim sizeof salt) != sizeof salt) { 527280297Sjkim BIO_printf(bio_err, "error reading input file\n"); 528280297Sjkim goto end; 529280297Sjkim } else if (memcmp(mbuf, magic, sizeof magic - 1)) { 530280297Sjkim BIO_printf(bio_err, "bad magic number\n"); 531280297Sjkim goto end; 532280297Sjkim } 53359191Skris 534280297Sjkim sptr = salt; 535280297Sjkim } 53659191Skris 537280297Sjkim EVP_BytesToKey(cipher, dgst, sptr, 538280297Sjkim (unsigned char *)str, strlen(str), 1, key, iv); 539280297Sjkim /* 540280297Sjkim * zero the complete buffer or the string passed from the command 541280297Sjkim * line bug picked up by Larry J. Hughes Jr. <hughes@indiana.edu> 542280297Sjkim */ 543280297Sjkim if (str == strbuf) 544280297Sjkim OPENSSL_cleanse(str, SIZE); 545280297Sjkim else 546280297Sjkim OPENSSL_cleanse(str, strlen(str)); 547280297Sjkim } 548284283Sjkim if (hiv != NULL) { 549284283Sjkim int siz = EVP_CIPHER_iv_length(cipher); 550284283Sjkim if (siz == 0) { 551284283Sjkim BIO_printf(bio_err, "warning: iv not use by this cipher\n"); 552284283Sjkim } else if (!set_hex(hiv, iv, sizeof iv)) { 553284283Sjkim BIO_printf(bio_err, "invalid hex iv value\n"); 554284283Sjkim goto end; 555284283Sjkim } 556280297Sjkim } 557280297Sjkim if ((hiv == NULL) && (str == NULL) 558280297Sjkim && EVP_CIPHER_iv_length(cipher) != 0) { 559280297Sjkim /* 560280297Sjkim * No IV was explicitly set and no IV was generated during 561280297Sjkim * EVP_BytesToKey. Hence the IV is undefined, making correct 562280297Sjkim * decryption impossible. 563280297Sjkim */ 564280297Sjkim BIO_printf(bio_err, "iv undefined\n"); 565280297Sjkim goto end; 566280297Sjkim } 567284283Sjkim if ((hkey != NULL) && !set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) { 568280297Sjkim BIO_printf(bio_err, "invalid hex key value\n"); 569280297Sjkim goto end; 570280297Sjkim } 57155714Skris 572280297Sjkim if ((benc = BIO_new(BIO_f_cipher())) == NULL) 573280297Sjkim goto end; 574160814Ssimon 575280297Sjkim /* 576280297Sjkim * Since we may be changing parameters work on the encryption context 577280297Sjkim * rather than calling BIO_set_cipher(). 578280297Sjkim */ 579160814Ssimon 580280297Sjkim BIO_get_cipher_ctx(benc, &ctx); 581194206Ssimon 582280297Sjkim if (non_fips_allow) 583280297Sjkim EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); 584194206Ssimon 585280297Sjkim if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { 586280297Sjkim BIO_printf(bio_err, "Error setting cipher %s\n", 587280297Sjkim EVP_CIPHER_name(cipher)); 588280297Sjkim ERR_print_errors(bio_err); 589280297Sjkim goto end; 590280297Sjkim } 591160814Ssimon 592280297Sjkim if (nopad) 593280297Sjkim EVP_CIPHER_CTX_set_padding(ctx, 0); 594160814Ssimon 595280297Sjkim if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { 596280297Sjkim BIO_printf(bio_err, "Error setting cipher %s\n", 597280297Sjkim EVP_CIPHER_name(cipher)); 598280297Sjkim ERR_print_errors(bio_err); 599280297Sjkim goto end; 600280297Sjkim } 601160814Ssimon 602280297Sjkim if (debug) { 603280297Sjkim BIO_set_callback(benc, BIO_debug_callback); 604280297Sjkim BIO_set_callback_arg(benc, (char *)bio_err); 605280297Sjkim } 60655714Skris 607280297Sjkim if (printkey) { 608280297Sjkim if (!nosalt) { 609280297Sjkim printf("salt="); 610280297Sjkim for (i = 0; i < (int)sizeof(salt); i++) 611280297Sjkim printf("%02X", salt[i]); 612280297Sjkim printf("\n"); 613280297Sjkim } 614280297Sjkim if (cipher->key_len > 0) { 615280297Sjkim printf("key="); 616280297Sjkim for (i = 0; i < cipher->key_len; i++) 617280297Sjkim printf("%02X", key[i]); 618280297Sjkim printf("\n"); 619280297Sjkim } 620280297Sjkim if (cipher->iv_len > 0) { 621280297Sjkim printf("iv ="); 622280297Sjkim for (i = 0; i < cipher->iv_len; i++) 623280297Sjkim printf("%02X", iv[i]); 624280297Sjkim printf("\n"); 625280297Sjkim } 626280297Sjkim if (printkey == 2) { 627280297Sjkim ret = 0; 628280297Sjkim goto end; 629280297Sjkim } 630280297Sjkim } 631280297Sjkim } 63255714Skris 633280297Sjkim /* Only encrypt/decrypt as we write the file */ 634280297Sjkim if (benc != NULL) 635280297Sjkim wbio = BIO_push(benc, wbio); 63655714Skris 637280297Sjkim for (;;) { 638280297Sjkim inl = BIO_read(rbio, (char *)buff, bsize); 639280297Sjkim if (inl <= 0) 640280297Sjkim break; 641280297Sjkim if (BIO_write(wbio, (char *)buff, inl) != inl) { 642280297Sjkim BIO_printf(bio_err, "error writing output file\n"); 643280297Sjkim goto end; 644280297Sjkim } 645280297Sjkim } 646280297Sjkim if (!BIO_flush(wbio)) { 647280297Sjkim BIO_printf(bio_err, "bad decrypt\n"); 648280297Sjkim goto end; 649280297Sjkim } 65055714Skris 651280297Sjkim ret = 0; 652280297Sjkim if (verbose) { 653280297Sjkim BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); 654280297Sjkim BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); 655280297Sjkim } 656280297Sjkim end: 657280297Sjkim ERR_print_errors(bio_err); 658280297Sjkim if (strbuf != NULL) 659280297Sjkim OPENSSL_free(strbuf); 660280297Sjkim if (buff != NULL) 661280297Sjkim OPENSSL_free(buff); 662280297Sjkim if (in != NULL) 663280297Sjkim BIO_free(in); 664280297Sjkim if (out != NULL) 665280297Sjkim BIO_free_all(out); 666280297Sjkim if (benc != NULL) 667280297Sjkim BIO_free(benc); 668280297Sjkim if (b64 != NULL) 669280297Sjkim BIO_free(b64); 670238405Sjkim#ifdef ZLIB 671280297Sjkim if (bzl != NULL) 672280297Sjkim BIO_free(bzl); 673238405Sjkim#endif 674312826Sjkim release_engine(e); 675280297Sjkim if (pass) 676280297Sjkim OPENSSL_free(pass); 677280297Sjkim apps_shutdown(); 678280297Sjkim OPENSSL_EXIT(ret); 679280297Sjkim} 68055714Skris 68155714Skrisint set_hex(char *in, unsigned char *out, int size) 682280297Sjkim{ 683280297Sjkim int i, n; 684280297Sjkim unsigned char j; 68555714Skris 686280297Sjkim n = strlen(in); 687280297Sjkim if (n > (size * 2)) { 688280297Sjkim BIO_printf(bio_err, "hex string is too long\n"); 689280297Sjkim return (0); 690280297Sjkim } 691280297Sjkim memset(out, 0, size); 692280297Sjkim for (i = 0; i < n; i++) { 693280297Sjkim j = (unsigned char)*in; 694280297Sjkim *(in++) = '\0'; 695280297Sjkim if (j == 0) 696280297Sjkim break; 697280297Sjkim if ((j >= '0') && (j <= '9')) 698280297Sjkim j -= '0'; 699280297Sjkim else if ((j >= 'A') && (j <= 'F')) 700280297Sjkim j = j - 'A' + 10; 701280297Sjkim else if ((j >= 'a') && (j <= 'f')) 702280297Sjkim j = j - 'a' + 10; 703280297Sjkim else { 704280297Sjkim BIO_printf(bio_err, "non-hex digit\n"); 705280297Sjkim return (0); 706280297Sjkim } 707280297Sjkim if (i & 1) 708280297Sjkim out[i / 2] |= j; 709280297Sjkim else 710280297Sjkim out[i / 2] = (j << 4); 711280297Sjkim } 712280297Sjkim return (1); 713280297Sjkim} 714