1 /* $OpenBSD: enc.c,v 1.20 2019/04/01 16:06:54 jsing Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
65 #include <openssl/bio.h>
66 #include <openssl/comp.h>
67 #include <openssl/err.h>
68 #include <openssl/evp.h>
69 #include <openssl/objects.h>
70 #include <openssl/pem.h>
71 #include <openssl/x509.h>
73 int set_hex(char *in, unsigned char *out, int size);
76 #define BSIZE (8*1024)
81 const EVP_CIPHER *cipher;
106 enc_opt_cipher(int argc, char **argv, int *argsused)
108 char *name = argv[0];
113 if (strcmp(name, "none") == 0) {
114 enc_config.cipher = NULL;
119 if ((enc_config.cipher = EVP_get_cipherbyname(name)) != NULL) {
127 static struct option enc_options[] = {
130 .desc = "Process base64 data on one line (requires -a)",
132 .opt.flag = &enc_config.olb64,
136 .desc = "Perform base64 encoding/decoding (alias -base64)",
138 .opt.flag = &enc_config.base64,
143 .opt.flag = &enc_config.base64,
148 .desc = "Specify the buffer size to use for I/O",
150 .opt.arg = &enc_config.bufsize,
154 .desc = "Decrypt the input data",
155 .type = OPTION_VALUE,
156 .opt.value = &enc_config.enc,
161 .desc = "Print debugging information",
163 .opt.flag = &enc_config.debug,
167 .desc = "Encrypt the input data (default)",
168 .type = OPTION_VALUE,
169 .opt.value = &enc_config.enc,
175 .desc = "Input file to read from (default stdin)",
177 .opt.arg = &enc_config.inf,
181 .argname = "iterations",
182 .desc = "Specify iteration count and force use of PBKDF2",
183 .type = OPTION_ARG_INT,
184 .opt.value = &enc_config.iter,
189 .desc = "IV to use, specified as a hexadecimal string",
191 .opt.arg = &enc_config.hiv,
196 .desc = "Key to use, specified as a hexadecimal string",
198 .opt.arg = &enc_config.hkey,
201 .name = "k", /* Superseded by -pass. */
203 .opt.arg = &enc_config.keystr,
206 .name = "kfile", /* Superseded by -pass. */
208 .opt.arg = &enc_config.keyfile,
213 .desc = "Digest to use to create a key from the passphrase",
215 .opt.arg = &enc_config.md,
219 .desc = "Use NULL cipher (no encryption or decryption)",
220 .type = OPTION_ARGV_FUNC,
221 .opt.argvfunc = enc_opt_cipher,
225 .desc = "Disable standard block padding",
227 .opt.flag = &enc_config.nopad,
231 .type = OPTION_VALUE,
232 .opt.value = &enc_config.nosalt,
238 .desc = "Output file to write to (default stdout)",
240 .opt.arg = &enc_config.outf,
244 .desc = "Print out the salt, key and IV used, then exit\n"
245 " (no encryption or decryption is performed)",
246 .type = OPTION_VALUE,
247 .opt.value = &enc_config.printkey,
252 .desc = "Print out the salt, key and IV used",
253 .type = OPTION_VALUE,
254 .opt.value = &enc_config.printkey,
260 .desc = "Password source",
262 .opt.arg = &enc_config.passarg,
266 .desc = "Use the pbkdf2 key derivation function",
268 .opt.flag = &enc_config.pbkdf2,
273 .desc = "Salt to use, specified as a hexadecimal string",
275 .opt.arg = &enc_config.hsalt,
279 .desc = "Use a salt in the key derivation routines (default)",
280 .type = OPTION_VALUE,
281 .opt.value = &enc_config.nosalt,
288 .opt.flag = &enc_config.verbose,
293 .desc = "Perform zlib compression/decompression",
295 .opt.flag = &enc_config.do_zlib,
300 .type = OPTION_ARGV_FUNC,
301 .opt.argvfunc = enc_opt_cipher,
311 fprintf(stderr, "usage: enc -ciphername [-AadePp] [-base64] "
312 "[-bufsize number] [-debug]\n"
313 " [-in file] [-iter iterations] [-iv IV] [-K key] "
315 " [-kfile file] [-md digest] [-none] [-nopad] [-nosalt]\n"
316 " [-out file] [-pass source] [-pbkdf2] [-S salt] [-salt]\n\n");
317 options_usage(enc_options);
318 fprintf(stderr, "\n");
320 fprintf(stderr, "Valid ciphername values:\n\n");
321 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
322 fprintf(stderr, "\n");
326 enc_main(int argc, char **argv)
328 static const char magic[] = "Salted__";
329 char mbuf[sizeof magic - 1];
330 char *strbuf = NULL, *pass = NULL;
331 unsigned char *buff = NULL;
334 unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
335 unsigned char salt[PKCS5_SALT_LEN];
339 EVP_CIPHER_CTX *ctx = NULL;
340 const EVP_MD *dgst = NULL;
341 BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL;
342 BIO *rbio = NULL, *wbio = NULL;
343 #define PROG_NAME_SIZE 39
344 char pname[PROG_NAME_SIZE + 1];
347 if (single_execution) {
348 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
354 memset(&enc_config, 0, sizeof(enc_config));
357 /* first check the program name */
358 program_name(argv[0], pname, sizeof(pname));
360 if (strcmp(pname, "base64") == 0)
361 enc_config.base64 = 1;
364 if (strcmp(pname, "zlib") == 0)
365 enc_config.do_zlib = 1;
368 enc_config.cipher = EVP_get_cipherbyname(pname);
371 if (!enc_config.do_zlib && !enc_config.base64 &&
372 enc_config.cipher == NULL && strcmp(pname, "enc") != 0)
374 if (!enc_config.base64 && enc_config.cipher == NULL &&
375 strcmp(pname, "enc") != 0)
378 BIO_printf(bio_err, "%s is an unknown cipher\n", pname);
382 if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) {
387 if (enc_config.keyfile != NULL) {
388 static char buf[128];
391 infile = fopen(enc_config.keyfile, "r");
392 if (infile == NULL) {
393 BIO_printf(bio_err, "unable to read key from '%s'\n",
398 if (!fgets(buf, sizeof buf, infile)) {
399 BIO_printf(bio_err, "unable to read key from '%s'\n",
406 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
408 if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
411 BIO_printf(bio_err, "zero length password\n");
414 enc_config.keystr = buf;
417 if (enc_config.md != NULL &&
418 (dgst = EVP_get_digestbyname(enc_config.md)) == NULL) {
420 "%s is an unsupported message digest type\n",
428 if (enc_config.bufsize != NULL) {
429 char *p = enc_config.bufsize;
432 /* XXX - provide an OPTION_ARG_DISKUNIT. */
433 for (n = 0; *p != '\0'; p++) {
435 if ((i <= '9') && (i >= '0'))
436 n = n * 10 + i - '0';
444 BIO_printf(bio_err, "invalid 'bufsize' specified.\n");
447 /* It must be large enough for a base64 encoded line. */
448 if (enc_config.base64 && n < 80)
452 if (enc_config.verbose)
453 BIO_printf(bio_err, "bufsize=%d\n", bsize);
455 strbuf = malloc(SIZE);
456 buff = malloc(EVP_ENCODE_LENGTH(bsize));
457 if ((buff == NULL) || (strbuf == NULL)) {
458 BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize));
461 in = BIO_new(BIO_s_file());
462 out = BIO_new(BIO_s_file());
463 if ((in == NULL) || (out == NULL)) {
464 ERR_print_errors(bio_err);
467 if (enc_config.debug) {
468 BIO_set_callback(in, BIO_debug_callback);
469 BIO_set_callback(out, BIO_debug_callback);
470 BIO_set_callback_arg(in, (char *) bio_err);
471 BIO_set_callback_arg(out, (char *) bio_err);
473 if (enc_config.inf == NULL) {
474 if (enc_config.bufsize != NULL)
475 setvbuf(stdin, (char *) NULL, _IONBF, 0);
476 BIO_set_fp(in, stdin, BIO_NOCLOSE);
478 if (BIO_read_filename(in, enc_config.inf) <= 0) {
479 perror(enc_config.inf);
484 if (!enc_config.keystr && enc_config.passarg) {
485 if (!app_passwd(bio_err, enc_config.passarg, NULL,
487 BIO_printf(bio_err, "Error getting password\n");
490 enc_config.keystr = pass;
492 if (enc_config.keystr == NULL && enc_config.cipher != NULL &&
493 enc_config.hkey == NULL) {
498 retval = snprintf(buf, sizeof buf,
499 "enter %s %s password:",
500 OBJ_nid2ln(EVP_CIPHER_nid(enc_config.cipher)),
501 enc_config.enc ? "encryption" : "decryption");
502 if ((size_t)retval >= sizeof buf) {
504 "Password prompt too long\n");
508 i = EVP_read_pw_string((char *)strbuf, SIZE, buf,
511 if (strbuf[0] == '\0') {
515 enc_config.keystr = strbuf;
519 BIO_printf(bio_err, "bad password read\n");
524 if (enc_config.outf == NULL) {
525 BIO_set_fp(out, stdout, BIO_NOCLOSE);
526 if (enc_config.bufsize != NULL)
527 setvbuf(stdout, (char *)NULL, _IONBF, 0);
529 if (BIO_write_filename(out, enc_config.outf) <= 0) {
530 perror(enc_config.outf);
540 if ((bzl = BIO_new(BIO_f_zlib())) == NULL)
543 wbio = BIO_push(bzl, wbio);
545 rbio = BIO_push(bzl, rbio);
549 if (enc_config.base64) {
550 if ((b64 = BIO_new(BIO_f_base64())) == NULL)
552 if (enc_config.debug) {
553 BIO_set_callback(b64, BIO_debug_callback);
554 BIO_set_callback_arg(b64, (char *) bio_err);
556 if (enc_config.olb64)
557 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
559 wbio = BIO_push(b64, wbio);
561 rbio = BIO_push(b64, rbio);
563 if (enc_config.cipher != NULL) {
565 * Note that keystr is NULL if a key was passed on the command
566 * line, so we get no salt in that case. Is this a bug?
568 if (enc_config.keystr != NULL) {
570 * Salt handling: if encrypting generate a salt and
571 * write to output BIO. If decrypting read salt from
575 if (enc_config.nosalt)
578 if (enc_config.enc) {
579 if (enc_config.hsalt) {
580 if (!set_hex(enc_config.hsalt, salt, sizeof salt)) {
582 "invalid hex salt value\n");
589 * If -P option then don't bother
592 if ((enc_config.printkey != 2)
593 && (BIO_write(wbio, magic,
594 sizeof magic - 1) != sizeof magic - 1
597 sizeof salt) != sizeof salt)) {
598 BIO_printf(bio_err, "error writing output file\n");
601 } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf
603 (unsigned char *) salt,
604 sizeof salt) != sizeof salt) {
605 BIO_printf(bio_err, "error reading input file\n");
607 } else if (memcmp(mbuf, magic, sizeof magic - 1)) {
608 BIO_printf(bio_err, "bad magic number\n");
613 if (enc_config.pbkdf2 == 1 || enc_config.iter > 0) {
615 * derive key and default iv
616 * concatenated into a temporary buffer
618 unsigned char tmpkeyiv[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH];
619 int iklen = EVP_CIPHER_key_length(enc_config.cipher);
620 int ivlen = EVP_CIPHER_iv_length(enc_config.cipher);
621 /* not needed if HASH_UPDATE() is fixed : */
622 int islen = (sptr != NULL ? sizeof(salt) : 0);
624 if (enc_config.iter == 0)
625 enc_config.iter = 10000;
627 if (!PKCS5_PBKDF2_HMAC(enc_config.keystr,
628 strlen(enc_config.keystr), sptr, islen,
629 enc_config.iter, dgst, iklen+ivlen, tmpkeyiv)) {
630 BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n");
633 /* split and move data back to global buffer */
634 memcpy(key, tmpkeyiv, iklen);
635 memcpy(iv, tmpkeyiv+iklen, ivlen);
637 EVP_BytesToKey(enc_config.cipher, dgst, sptr,
638 (unsigned char *)enc_config.keystr,
639 strlen(enc_config.keystr), 1, key, iv);
643 * zero the complete buffer or the string passed from
644 * the command line bug picked up by Larry J. Hughes
645 * Jr. <hughes@indiana.edu>
647 if (enc_config.keystr == strbuf)
648 explicit_bzero(enc_config.keystr, SIZE);
650 explicit_bzero(enc_config.keystr,
651 strlen(enc_config.keystr));
653 if (enc_config.hiv != NULL &&
654 !set_hex(enc_config.hiv, iv, sizeof iv)) {
655 BIO_printf(bio_err, "invalid hex iv value\n");
658 if (enc_config.hiv == NULL && enc_config.keystr == NULL &&
659 EVP_CIPHER_iv_length(enc_config.cipher) != 0) {
661 * No IV was explicitly set and no IV was generated
662 * during EVP_BytesToKey. Hence the IV is undefined,
663 * making correct decryption impossible.
665 BIO_printf(bio_err, "iv undefined\n");
668 if (enc_config.hkey != NULL &&
669 !set_hex(enc_config.hkey, key, sizeof key)) {
670 BIO_printf(bio_err, "invalid hex key value\n");
673 if ((benc = BIO_new(BIO_f_cipher())) == NULL)
677 * Since we may be changing parameters work on the encryption
678 * context rather than calling BIO_set_cipher().
681 BIO_get_cipher_ctx(benc, &ctx);
683 if (!EVP_CipherInit_ex(ctx, enc_config.cipher, NULL, NULL,
684 NULL, enc_config.enc)) {
685 BIO_printf(bio_err, "Error setting cipher %s\n",
686 EVP_CIPHER_name(enc_config.cipher));
687 ERR_print_errors(bio_err);
690 if (enc_config.nopad)
691 EVP_CIPHER_CTX_set_padding(ctx, 0);
693 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv,
695 BIO_printf(bio_err, "Error setting cipher %s\n",
696 EVP_CIPHER_name(enc_config.cipher));
697 ERR_print_errors(bio_err);
700 if (enc_config.debug) {
701 BIO_set_callback(benc, BIO_debug_callback);
702 BIO_set_callback_arg(benc, (char *) bio_err);
704 if (enc_config.printkey) {
705 if (!enc_config.nosalt) {
707 for (i = 0; i < (int) sizeof(salt); i++)
708 printf("%02X", salt[i]);
711 if (enc_config.cipher->key_len > 0) {
713 for (i = 0; i < enc_config.cipher->key_len; i++)
714 printf("%02X", key[i]);
717 if (enc_config.cipher->iv_len > 0) {
719 for (i = 0; i < enc_config.cipher->iv_len; i++)
720 printf("%02X", iv[i]);
723 if (enc_config.printkey == 2) {
729 /* Only encrypt/decrypt as we write the file */
731 wbio = BIO_push(benc, wbio);
734 inl = BIO_read(rbio, (char *) buff, bsize);
737 if (BIO_write(wbio, (char *) buff, inl) != inl) {
738 BIO_printf(bio_err, "error writing output file\n");
742 if (!BIO_flush(wbio)) {
743 BIO_printf(bio_err, "bad decrypt\n");
747 if (enc_config.verbose) {
748 BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in));
749 BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out));
752 ERR_print_errors(bio_err);
768 set_hex(char *in, unsigned char *out, int size)
774 if (n > (size * 2)) {
775 BIO_printf(bio_err, "hex string is too long\n");
778 memset(out, 0, size);
779 for (i = 0; i < n; i++) {
780 j = (unsigned char) *in;
784 if ((j >= '0') && (j <= '9'))
786 else if ((j >= 'A') && (j <= 'F'))
788 else if ((j >= 'a') && (j <= 'f'))
791 BIO_printf(bio_err, "non-hex digit\n");
797 out[i / 2] = (j << 4);