enc.c revision 280297
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]; 129111147Snectar#ifndef OPENSSL_NO_ENGINE 130280297Sjkim char *engine = NULL; 131111147Snectar#endif 132280297Sjkim const EVP_MD *dgst = NULL; 133280297Sjkim int non_fips_allow = 0; 13455714Skris 135280297Sjkim apps_startup(); 13655714Skris 137280297Sjkim if (bio_err == NULL) 138280297Sjkim if ((bio_err = BIO_new(BIO_s_file())) != NULL) 139280297Sjkim BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 14055714Skris 141280297Sjkim if (!load_config(bio_err, NULL)) 142280297Sjkim goto end; 143109998Smarkm 144280297Sjkim /* first check the program name */ 145280297Sjkim program_name(argv[0], pname, sizeof pname); 146280297Sjkim if (strcmp(pname, "base64") == 0) 147280297Sjkim base64 = 1; 148238405Sjkim#ifdef ZLIB 149280297Sjkim if (strcmp(pname, "zlib") == 0) 150280297Sjkim do_zlib = 1; 151238405Sjkim#endif 15255714Skris 153280297Sjkim cipher = EVP_get_cipherbyname(pname); 154238405Sjkim#ifdef ZLIB 155280297Sjkim if (!do_zlib && !base64 && (cipher == NULL) 156280297Sjkim && (strcmp(pname, "enc") != 0)) 157238405Sjkim#else 158280297Sjkim if (!base64 && (cipher == NULL) && (strcmp(pname, "enc") != 0)) 159238405Sjkim#endif 160280297Sjkim { 161280297Sjkim BIO_printf(bio_err, "%s is an unknown cipher\n", pname); 162280297Sjkim goto bad; 163280297Sjkim } 16455714Skris 165280297Sjkim argc--; 166280297Sjkim argv++; 167280297Sjkim while (argc >= 1) { 168280297Sjkim if (strcmp(*argv, "-e") == 0) 169280297Sjkim enc = 1; 170280297Sjkim else if (strcmp(*argv, "-in") == 0) { 171280297Sjkim if (--argc < 1) 172280297Sjkim goto bad; 173280297Sjkim inf = *(++argv); 174280297Sjkim } else if (strcmp(*argv, "-out") == 0) { 175280297Sjkim if (--argc < 1) 176280297Sjkim goto bad; 177280297Sjkim outf = *(++argv); 178280297Sjkim } else if (strcmp(*argv, "-pass") == 0) { 179280297Sjkim if (--argc < 1) 180280297Sjkim goto bad; 181280297Sjkim passarg = *(++argv); 182280297Sjkim } 183111147Snectar#ifndef OPENSSL_NO_ENGINE 184280297Sjkim else if (strcmp(*argv, "-engine") == 0) { 185280297Sjkim if (--argc < 1) 186280297Sjkim goto bad; 187280297Sjkim engine = *(++argv); 188280297Sjkim } 189111147Snectar#endif 190280297Sjkim else if (strcmp(*argv, "-d") == 0) 191280297Sjkim enc = 0; 192280297Sjkim else if (strcmp(*argv, "-p") == 0) 193280297Sjkim printkey = 1; 194280297Sjkim else if (strcmp(*argv, "-v") == 0) 195280297Sjkim verbose = 1; 196280297Sjkim else if (strcmp(*argv, "-nopad") == 0) 197280297Sjkim nopad = 1; 198280297Sjkim else if (strcmp(*argv, "-salt") == 0) 199280297Sjkim nosalt = 0; 200280297Sjkim else if (strcmp(*argv, "-nosalt") == 0) 201280297Sjkim nosalt = 1; 202280297Sjkim else if (strcmp(*argv, "-debug") == 0) 203280297Sjkim debug = 1; 204280297Sjkim else if (strcmp(*argv, "-P") == 0) 205280297Sjkim printkey = 2; 206280297Sjkim else if (strcmp(*argv, "-A") == 0) 207280297Sjkim olb64 = 1; 208280297Sjkim else if (strcmp(*argv, "-a") == 0) 209280297Sjkim base64 = 1; 210280297Sjkim else if (strcmp(*argv, "-base64") == 0) 211280297Sjkim base64 = 1; 212238405Sjkim#ifdef ZLIB 213280297Sjkim else if (strcmp(*argv, "-z") == 0) 214280297Sjkim do_zlib = 1; 215238405Sjkim#endif 216280297Sjkim else if (strcmp(*argv, "-bufsize") == 0) { 217280297Sjkim if (--argc < 1) 218280297Sjkim goto bad; 219280297Sjkim bufsize = (unsigned char *)*(++argv); 220280297Sjkim } else if (strcmp(*argv, "-k") == 0) { 221280297Sjkim if (--argc < 1) 222280297Sjkim goto bad; 223280297Sjkim str = *(++argv); 224280297Sjkim } else if (strcmp(*argv, "-kfile") == 0) { 225280297Sjkim static char buf[128]; 226280297Sjkim FILE *infile; 227280297Sjkim char *file; 22855714Skris 229280297Sjkim if (--argc < 1) 230280297Sjkim goto bad; 231280297Sjkim file = *(++argv); 232280297Sjkim infile = fopen(file, "r"); 233280297Sjkim if (infile == NULL) { 234280297Sjkim BIO_printf(bio_err, "unable to read key from '%s'\n", file); 235280297Sjkim goto bad; 236280297Sjkim } 237280297Sjkim buf[0] = '\0'; 238280297Sjkim if (!fgets(buf, sizeof buf, infile)) { 239280297Sjkim BIO_printf(bio_err, "unable to read key from '%s'\n", file); 240280297Sjkim goto bad; 241280297Sjkim } 242280297Sjkim fclose(infile); 243280297Sjkim i = strlen(buf); 244280297Sjkim if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 245280297Sjkim buf[--i] = '\0'; 246280297Sjkim if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) 247280297Sjkim buf[--i] = '\0'; 248280297Sjkim if (i < 1) { 249280297Sjkim BIO_printf(bio_err, "zero length password\n"); 250280297Sjkim goto bad; 251280297Sjkim } 252280297Sjkim str = buf; 253280297Sjkim } else if (strcmp(*argv, "-K") == 0) { 254280297Sjkim if (--argc < 1) 255280297Sjkim goto bad; 256280297Sjkim hkey = *(++argv); 257280297Sjkim } else if (strcmp(*argv, "-S") == 0) { 258280297Sjkim if (--argc < 1) 259280297Sjkim goto bad; 260280297Sjkim hsalt = *(++argv); 261280297Sjkim } else if (strcmp(*argv, "-iv") == 0) { 262280297Sjkim if (--argc < 1) 263280297Sjkim goto bad; 264280297Sjkim hiv = *(++argv); 265280297Sjkim } else if (strcmp(*argv, "-md") == 0) { 266280297Sjkim if (--argc < 1) 267280297Sjkim goto bad; 268280297Sjkim md = *(++argv); 269280297Sjkim } else if (strcmp(*argv, "-non-fips-allow") == 0) 270280297Sjkim non_fips_allow = 1; 271280297Sjkim else if ((argv[0][0] == '-') && 272280297Sjkim ((c = EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { 273280297Sjkim cipher = c; 274280297Sjkim } else if (strcmp(*argv, "-none") == 0) 275280297Sjkim cipher = NULL; 276280297Sjkim else { 277280297Sjkim BIO_printf(bio_err, "unknown option '%s'\n", *argv); 278280297Sjkim bad: 279280297Sjkim BIO_printf(bio_err, "options are\n"); 280280297Sjkim BIO_printf(bio_err, "%-14s input file\n", "-in <file>"); 281280297Sjkim BIO_printf(bio_err, "%-14s output file\n", "-out <file>"); 282280297Sjkim BIO_printf(bio_err, "%-14s pass phrase source\n", "-pass <arg>"); 283280297Sjkim BIO_printf(bio_err, "%-14s encrypt\n", "-e"); 284280297Sjkim BIO_printf(bio_err, "%-14s decrypt\n", "-d"); 285280297Sjkim BIO_printf(bio_err, 286280297Sjkim "%-14s base64 encode/decode, depending on encryption flag\n", 287280297Sjkim "-a/-base64"); 288280297Sjkim BIO_printf(bio_err, "%-14s passphrase is the next argument\n", 289280297Sjkim "-k"); 290280297Sjkim BIO_printf(bio_err, 291280297Sjkim "%-14s passphrase is the first line of the file argument\n", 292280297Sjkim "-kfile"); 293280297Sjkim BIO_printf(bio_err, 294280297Sjkim "%-14s the next argument is the md to use to create a key\n", 295280297Sjkim "-md"); 296280297Sjkim BIO_printf(bio_err, 297280297Sjkim "%-14s from a passphrase. One of md2, md5, sha or sha1\n", 298280297Sjkim ""); 299280297Sjkim BIO_printf(bio_err, "%-14s salt in hex is the next argument\n", 300280297Sjkim "-S"); 301280297Sjkim BIO_printf(bio_err, "%-14s key/iv in hex is the next argument\n", 302280297Sjkim "-K/-iv"); 303280297Sjkim BIO_printf(bio_err, "%-14s print the iv/key (then exit if -P)\n", 304280297Sjkim "-[pP]"); 305280297Sjkim BIO_printf(bio_err, "%-14s buffer size\n", "-bufsize <n>"); 306280297Sjkim BIO_printf(bio_err, "%-14s disable standard block padding\n", 307280297Sjkim "-nopad"); 308111147Snectar#ifndef OPENSSL_NO_ENGINE 309280297Sjkim BIO_printf(bio_err, 310280297Sjkim "%-14s use engine e, possibly a hardware device.\n", 311280297Sjkim "-engine e"); 312111147Snectar#endif 31355714Skris 314280297Sjkim BIO_printf(bio_err, "Cipher Types\n"); 315280297Sjkim OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, 316280297Sjkim show_ciphers, bio_err); 317280297Sjkim BIO_printf(bio_err, "\n"); 31855714Skris 319280297Sjkim goto end; 320280297Sjkim } 321280297Sjkim argc--; 322280297Sjkim argv++; 323280297Sjkim } 32455714Skris 325111147Snectar#ifndef OPENSSL_NO_ENGINE 326280297Sjkim setup_engine(bio_err, engine, 0); 327111147Snectar#endif 328109998Smarkm 329280297Sjkim if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { 330280297Sjkim BIO_printf(bio_err, 331280297Sjkim "AEAD ciphers not supported by the enc utility\n"); 332280297Sjkim goto end; 333280297Sjkim } 334267256Sjkim 335280297Sjkim if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) { 336280297Sjkim BIO_printf(bio_err, 337280297Sjkim "Ciphers in XTS mode are not supported by the enc utility\n"); 338280297Sjkim goto end; 339280297Sjkim } 340269682Sjkim 341280297Sjkim if (md && (dgst = EVP_get_digestbyname(md)) == NULL) { 342280297Sjkim BIO_printf(bio_err, "%s is an unsupported message digest type\n", md); 343280297Sjkim goto end; 344280297Sjkim } 345142425Snectar 346280297Sjkim if (dgst == NULL) { 347280297Sjkim dgst = EVP_md5(); 348280297Sjkim } 349142425Snectar 350280297Sjkim if (bufsize != NULL) { 351280297Sjkim unsigned long n; 35255714Skris 353280297Sjkim for (n = 0; *bufsize; bufsize++) { 354280297Sjkim i = *bufsize; 355280297Sjkim if ((i <= '9') && (i >= '0')) 356280297Sjkim n = n * 10 + i - '0'; 357280297Sjkim else if (i == 'k') { 358280297Sjkim n *= 1024; 359280297Sjkim bufsize++; 360280297Sjkim break; 361280297Sjkim } 362280297Sjkim } 363280297Sjkim if (*bufsize != '\0') { 364280297Sjkim BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); 365280297Sjkim goto end; 366280297Sjkim } 36755714Skris 368280297Sjkim /* It must be large enough for a base64 encoded line */ 369280297Sjkim if (base64 && n < 80) 370280297Sjkim n = 80; 37155714Skris 372280297Sjkim bsize = (int)n; 373280297Sjkim if (verbose) 374280297Sjkim BIO_printf(bio_err, "bufsize=%d\n", bsize); 375280297Sjkim } 37655714Skris 377280297Sjkim strbuf = OPENSSL_malloc(SIZE); 378280297Sjkim buff = (unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); 379280297Sjkim if ((buff == NULL) || (strbuf == NULL)) { 380280297Sjkim BIO_printf(bio_err, "OPENSSL_malloc failure %ld\n", 381280297Sjkim (long)EVP_ENCODE_LENGTH(bsize)); 382280297Sjkim goto end; 383280297Sjkim } 38455714Skris 385280297Sjkim in = BIO_new(BIO_s_file()); 386280297Sjkim out = BIO_new(BIO_s_file()); 387280297Sjkim if ((in == NULL) || (out == NULL)) { 388280297Sjkim ERR_print_errors(bio_err); 389280297Sjkim goto end; 390280297Sjkim } 391280297Sjkim if (debug) { 392280297Sjkim BIO_set_callback(in, BIO_debug_callback); 393280297Sjkim BIO_set_callback(out, BIO_debug_callback); 394280297Sjkim BIO_set_callback_arg(in, (char *)bio_err); 395280297Sjkim BIO_set_callback_arg(out, (char *)bio_err); 396280297Sjkim } 39755714Skris 398280297Sjkim if (inf == NULL) { 399238405Sjkim#ifndef OPENSSL_NO_SETVBUF_IONBF 400280297Sjkim if (bufsize != NULL) 401280297Sjkim setvbuf(stdin, (char *)NULL, _IONBF, 0); 402280297Sjkim#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 403280297Sjkim BIO_set_fp(in, stdin, BIO_NOCLOSE); 404280297Sjkim } else { 405280297Sjkim if (BIO_read_filename(in, inf) <= 0) { 406280297Sjkim perror(inf); 407280297Sjkim goto end; 408280297Sjkim } 409280297Sjkim } 41055714Skris 411280297Sjkim if (!str && passarg) { 412280297Sjkim if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { 413280297Sjkim BIO_printf(bio_err, "Error getting password\n"); 414280297Sjkim goto end; 415280297Sjkim } 416280297Sjkim str = pass; 417280297Sjkim } 41859191Skris 419280297Sjkim if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { 420280297Sjkim for (;;) { 421280297Sjkim char buf[200]; 42255714Skris 423280297Sjkim BIO_snprintf(buf, sizeof buf, "enter %s %s password:", 424280297Sjkim OBJ_nid2ln(EVP_CIPHER_nid(cipher)), 425280297Sjkim (enc) ? "encryption" : "decryption"); 426280297Sjkim strbuf[0] = '\0'; 427280297Sjkim i = EVP_read_pw_string((char *)strbuf, SIZE, buf, enc); 428280297Sjkim if (i == 0) { 429280297Sjkim if (strbuf[0] == '\0') { 430280297Sjkim ret = 1; 431280297Sjkim goto end; 432280297Sjkim } 433280297Sjkim str = strbuf; 434280297Sjkim break; 435280297Sjkim } 436280297Sjkim if (i < 0) { 437280297Sjkim BIO_printf(bio_err, "bad password read\n"); 438280297Sjkim goto end; 439280297Sjkim } 440280297Sjkim } 441280297Sjkim } 44255714Skris 443280297Sjkim if (outf == NULL) { 444280297Sjkim BIO_set_fp(out, stdout, BIO_NOCLOSE); 445238405Sjkim#ifndef OPENSSL_NO_SETVBUF_IONBF 446280297Sjkim if (bufsize != NULL) 447280297Sjkim setvbuf(stdout, (char *)NULL, _IONBF, 0); 448280297Sjkim#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ 449109998Smarkm#ifdef OPENSSL_SYS_VMS 450280297Sjkim { 451280297Sjkim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 452280297Sjkim out = BIO_push(tmpbio, out); 453280297Sjkim } 45468651Skris#endif 455280297Sjkim } else { 456280297Sjkim if (BIO_write_filename(out, outf) <= 0) { 457280297Sjkim perror(outf); 458280297Sjkim goto end; 459280297Sjkim } 460280297Sjkim } 46159191Skris 462280297Sjkim rbio = in; 463280297Sjkim wbio = out; 46459191Skris 465238405Sjkim#ifdef ZLIB 466238405Sjkim 467280297Sjkim if (do_zlib) { 468280297Sjkim if ((bzl = BIO_new(BIO_f_zlib())) == NULL) 469280297Sjkim goto end; 470280297Sjkim if (enc) 471280297Sjkim wbio = BIO_push(bzl, wbio); 472280297Sjkim else 473280297Sjkim rbio = BIO_push(bzl, rbio); 474280297Sjkim } 475238405Sjkim#endif 476238405Sjkim 477280297Sjkim if (base64) { 478280297Sjkim if ((b64 = BIO_new(BIO_f_base64())) == NULL) 479280297Sjkim goto end; 480280297Sjkim if (debug) { 481280297Sjkim BIO_set_callback(b64, BIO_debug_callback); 482280297Sjkim BIO_set_callback_arg(b64, (char *)bio_err); 483280297Sjkim } 484280297Sjkim if (olb64) 485280297Sjkim BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 486280297Sjkim if (enc) 487280297Sjkim wbio = BIO_push(b64, wbio); 488280297Sjkim else 489280297Sjkim rbio = BIO_push(b64, rbio); 490280297Sjkim } 49159191Skris 492280297Sjkim if (cipher != NULL) { 493280297Sjkim /* 494280297Sjkim * Note that str is NULL if a key was passed on the command line, so 495280297Sjkim * we get no salt in that case. Is this a bug? 496280297Sjkim */ 497280297Sjkim if (str != NULL) { 498280297Sjkim /* 499280297Sjkim * Salt handling: if encrypting generate a salt and write to 500280297Sjkim * output BIO. If decrypting read salt from input BIO. 501280297Sjkim */ 502280297Sjkim unsigned char *sptr; 503280297Sjkim if (nosalt) 504280297Sjkim sptr = NULL; 505280297Sjkim else { 506280297Sjkim if (enc) { 507280297Sjkim if (hsalt) { 508280297Sjkim if (!set_hex(hsalt, salt, sizeof salt)) { 509280297Sjkim BIO_printf(bio_err, "invalid hex salt value\n"); 510280297Sjkim goto end; 511280297Sjkim } 512280297Sjkim } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0) 513280297Sjkim goto end; 514280297Sjkim /* 515280297Sjkim * If -P option then don't bother writing 516280297Sjkim */ 517280297Sjkim if ((printkey != 2) 518280297Sjkim && (BIO_write(wbio, magic, 519280297Sjkim sizeof magic - 1) != sizeof magic - 1 520280297Sjkim || BIO_write(wbio, 521280297Sjkim (char *)salt, 522280297Sjkim sizeof salt) != sizeof salt)) { 523280297Sjkim BIO_printf(bio_err, "error writing output file\n"); 524280297Sjkim goto end; 525280297Sjkim } 526280297Sjkim } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf 527280297Sjkim || BIO_read(rbio, 528280297Sjkim (unsigned char *)salt, 529280297Sjkim sizeof salt) != sizeof salt) { 530280297Sjkim BIO_printf(bio_err, "error reading input file\n"); 531280297Sjkim goto end; 532280297Sjkim } else if (memcmp(mbuf, magic, sizeof magic - 1)) { 533280297Sjkim BIO_printf(bio_err, "bad magic number\n"); 534280297Sjkim goto end; 535280297Sjkim } 53659191Skris 537280297Sjkim sptr = salt; 538280297Sjkim } 53959191Skris 540280297Sjkim EVP_BytesToKey(cipher, dgst, sptr, 541280297Sjkim (unsigned char *)str, strlen(str), 1, key, iv); 542280297Sjkim /* 543280297Sjkim * zero the complete buffer or the string passed from the command 544280297Sjkim * line bug picked up by Larry J. Hughes Jr. <hughes@indiana.edu> 545280297Sjkim */ 546280297Sjkim if (str == strbuf) 547280297Sjkim OPENSSL_cleanse(str, SIZE); 548280297Sjkim else 549280297Sjkim OPENSSL_cleanse(str, strlen(str)); 550280297Sjkim } 551280297Sjkim if ((hiv != NULL) && !set_hex(hiv, iv, sizeof iv)) { 552280297Sjkim BIO_printf(bio_err, "invalid hex iv value\n"); 553280297Sjkim goto end; 554280297Sjkim } 555280297Sjkim if ((hiv == NULL) && (str == NULL) 556280297Sjkim && EVP_CIPHER_iv_length(cipher) != 0) { 557280297Sjkim /* 558280297Sjkim * No IV was explicitly set and no IV was generated during 559280297Sjkim * EVP_BytesToKey. Hence the IV is undefined, making correct 560280297Sjkim * decryption impossible. 561280297Sjkim */ 562280297Sjkim BIO_printf(bio_err, "iv undefined\n"); 563280297Sjkim goto end; 564280297Sjkim } 565280297Sjkim if ((hkey != NULL) && !set_hex(hkey, key, sizeof key)) { 566280297Sjkim BIO_printf(bio_err, "invalid hex key value\n"); 567280297Sjkim goto end; 568280297Sjkim } 56955714Skris 570280297Sjkim if ((benc = BIO_new(BIO_f_cipher())) == NULL) 571280297Sjkim goto end; 572160814Ssimon 573280297Sjkim /* 574280297Sjkim * Since we may be changing parameters work on the encryption context 575280297Sjkim * rather than calling BIO_set_cipher(). 576280297Sjkim */ 577160814Ssimon 578280297Sjkim BIO_get_cipher_ctx(benc, &ctx); 579194206Ssimon 580280297Sjkim if (non_fips_allow) 581280297Sjkim EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); 582194206Ssimon 583280297Sjkim if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { 584280297Sjkim BIO_printf(bio_err, "Error setting cipher %s\n", 585280297Sjkim EVP_CIPHER_name(cipher)); 586280297Sjkim ERR_print_errors(bio_err); 587280297Sjkim goto end; 588280297Sjkim } 589160814Ssimon 590280297Sjkim if (nopad) 591280297Sjkim EVP_CIPHER_CTX_set_padding(ctx, 0); 592160814Ssimon 593280297Sjkim if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { 594280297Sjkim BIO_printf(bio_err, "Error setting cipher %s\n", 595280297Sjkim EVP_CIPHER_name(cipher)); 596280297Sjkim ERR_print_errors(bio_err); 597280297Sjkim goto end; 598280297Sjkim } 599160814Ssimon 600280297Sjkim if (debug) { 601280297Sjkim BIO_set_callback(benc, BIO_debug_callback); 602280297Sjkim BIO_set_callback_arg(benc, (char *)bio_err); 603280297Sjkim } 60455714Skris 605280297Sjkim if (printkey) { 606280297Sjkim if (!nosalt) { 607280297Sjkim printf("salt="); 608280297Sjkim for (i = 0; i < (int)sizeof(salt); i++) 609280297Sjkim printf("%02X", salt[i]); 610280297Sjkim printf("\n"); 611280297Sjkim } 612280297Sjkim if (cipher->key_len > 0) { 613280297Sjkim printf("key="); 614280297Sjkim for (i = 0; i < cipher->key_len; i++) 615280297Sjkim printf("%02X", key[i]); 616280297Sjkim printf("\n"); 617280297Sjkim } 618280297Sjkim if (cipher->iv_len > 0) { 619280297Sjkim printf("iv ="); 620280297Sjkim for (i = 0; i < cipher->iv_len; i++) 621280297Sjkim printf("%02X", iv[i]); 622280297Sjkim printf("\n"); 623280297Sjkim } 624280297Sjkim if (printkey == 2) { 625280297Sjkim ret = 0; 626280297Sjkim goto end; 627280297Sjkim } 628280297Sjkim } 629280297Sjkim } 63055714Skris 631280297Sjkim /* Only encrypt/decrypt as we write the file */ 632280297Sjkim if (benc != NULL) 633280297Sjkim wbio = BIO_push(benc, wbio); 63455714Skris 635280297Sjkim for (;;) { 636280297Sjkim inl = BIO_read(rbio, (char *)buff, bsize); 637280297Sjkim if (inl <= 0) 638280297Sjkim break; 639280297Sjkim if (BIO_write(wbio, (char *)buff, inl) != inl) { 640280297Sjkim BIO_printf(bio_err, "error writing output file\n"); 641280297Sjkim goto end; 642280297Sjkim } 643280297Sjkim } 644280297Sjkim if (!BIO_flush(wbio)) { 645280297Sjkim BIO_printf(bio_err, "bad decrypt\n"); 646280297Sjkim goto end; 647280297Sjkim } 64855714Skris 649280297Sjkim ret = 0; 650280297Sjkim if (verbose) { 651280297Sjkim BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); 652280297Sjkim BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); 653280297Sjkim } 654280297Sjkim end: 655280297Sjkim ERR_print_errors(bio_err); 656280297Sjkim if (strbuf != NULL) 657280297Sjkim OPENSSL_free(strbuf); 658280297Sjkim if (buff != NULL) 659280297Sjkim OPENSSL_free(buff); 660280297Sjkim if (in != NULL) 661280297Sjkim BIO_free(in); 662280297Sjkim if (out != NULL) 663280297Sjkim BIO_free_all(out); 664280297Sjkim if (benc != NULL) 665280297Sjkim BIO_free(benc); 666280297Sjkim if (b64 != NULL) 667280297Sjkim BIO_free(b64); 668238405Sjkim#ifdef ZLIB 669280297Sjkim if (bzl != NULL) 670280297Sjkim BIO_free(bzl); 671238405Sjkim#endif 672280297Sjkim if (pass) 673280297Sjkim OPENSSL_free(pass); 674280297Sjkim apps_shutdown(); 675280297Sjkim OPENSSL_EXIT(ret); 676280297Sjkim} 67755714Skris 67855714Skrisint set_hex(char *in, unsigned char *out, int size) 679280297Sjkim{ 680280297Sjkim int i, n; 681280297Sjkim unsigned char j; 68255714Skris 683280297Sjkim n = strlen(in); 684280297Sjkim if (n > (size * 2)) { 685280297Sjkim BIO_printf(bio_err, "hex string is too long\n"); 686280297Sjkim return (0); 687280297Sjkim } 688280297Sjkim memset(out, 0, size); 689280297Sjkim for (i = 0; i < n; i++) { 690280297Sjkim j = (unsigned char)*in; 691280297Sjkim *(in++) = '\0'; 692280297Sjkim if (j == 0) 693280297Sjkim break; 694280297Sjkim if ((j >= '0') && (j <= '9')) 695280297Sjkim j -= '0'; 696280297Sjkim else if ((j >= 'A') && (j <= 'F')) 697280297Sjkim j = j - 'A' + 10; 698280297Sjkim else if ((j >= 'a') && (j <= 'f')) 699280297Sjkim j = j - 'a' + 10; 700280297Sjkim else { 701280297Sjkim BIO_printf(bio_err, "non-hex digit\n"); 702280297Sjkim return (0); 703280297Sjkim } 704280297Sjkim if (i & 1) 705280297Sjkim out[i / 2] |= j; 706280297Sjkim else 707280297Sjkim out[i / 2] = (j << 4); 708280297Sjkim } 709280297Sjkim return (1); 710280297Sjkim} 711