Annotation of src/usr.bin/openssl/enc.c, Revision 1.2
1.2 ! doug 1: /* $OpenBSD: enc.c,v 1.1 2014/08/26 17:47:24 jsing Exp $ */
1.1 jsing 2: /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3: * All rights reserved.
4: *
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.
8: *
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).
15: *
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.
22: *
23: * Redistribution and use in source and binary forms, with or without
24: * modification, are permitted provided that the following conditions
25: * are met:
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)"
40: *
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
51: * SUCH DAMAGE.
52: *
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.]
57: */
58:
59: #include <ctype.h>
60: #include <stdio.h>
61: #include <stdlib.h>
62: #include <string.h>
63:
64: #include "apps.h"
65:
66: #include <openssl/bio.h>
67: #include <openssl/comp.h>
68: #include <openssl/err.h>
69: #include <openssl/evp.h>
70: #include <openssl/objects.h>
71: #include <openssl/pem.h>
72: #include <openssl/rand.h>
73: #include <openssl/x509.h>
74:
75: int set_hex(char *in, unsigned char *out, int size);
76:
77: #define SIZE (512)
78: #define BSIZE (8*1024)
79: #define PROG enc_main
80:
81: static void
82: show_ciphers(const OBJ_NAME * name, void *bio_)
83: {
84: BIO *bio = bio_;
85: static int n;
86:
87: if (!islower((unsigned char) *name->name))
88: return;
89:
90: BIO_printf(bio, "-%-25s", name->name);
91: if (++n == 3) {
92: BIO_printf(bio, "\n");
93: n = 0;
94: } else
95: BIO_printf(bio, " ");
96: }
97:
98: int enc_main(int, char **);
99:
100: int
101: enc_main(int argc, char **argv)
102: {
103: static const char magic[] = "Salted__";
104: char mbuf[sizeof magic - 1];
105: char *strbuf = NULL;
106: unsigned char *buff = NULL, *bufsize = NULL;
107: int bsize = BSIZE, verbose = 0;
108: int ret = 1, inl;
109: int nopad = 0;
110: unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
111: unsigned char salt[PKCS5_SALT_LEN];
112: char *str = NULL, *passarg = NULL, *pass = NULL;
113: char *hkey = NULL, *hiv = NULL, *hsalt = NULL;
114: char *md = NULL;
115: int enc = 1, printkey = 0, i, base64 = 0;
116: #ifdef ZLIB
117: int do_zlib = 0;
118: BIO *bzl = NULL;
119: #endif
120: int debug = 0, olb64 = 0, nosalt = 0;
121: const EVP_CIPHER *cipher = NULL, *c;
122: EVP_CIPHER_CTX *ctx = NULL;
123: char *inf = NULL, *outf = NULL;
124: BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = NULL,
125: *wbio = NULL;
126: #define PROG_NAME_SIZE 39
127: char pname[PROG_NAME_SIZE + 1];
128: #ifndef OPENSSL_NO_ENGINE
129: char *engine = NULL;
130: #endif
131: const EVP_MD *dgst = NULL;
132:
133: /* first check the program name */
134: program_name(argv[0], pname, sizeof pname);
135: if (strcmp(pname, "base64") == 0)
136: base64 = 1;
137: #ifdef ZLIB
138: if (strcmp(pname, "zlib") == 0)
139: do_zlib = 1;
140: #endif
141:
142: cipher = EVP_get_cipherbyname(pname);
143: #ifdef ZLIB
144: if (!do_zlib && !base64 && (cipher == NULL)
145: && (strcmp(pname, "enc") != 0))
146: #else
147: if (!base64 && (cipher == NULL) && (strcmp(pname, "enc") != 0))
148: #endif
149: {
150: BIO_printf(bio_err, "%s is an unknown cipher\n", pname);
151: goto bad;
152: }
153: argc--;
154: argv++;
155: while (argc >= 1) {
156: if (strcmp(*argv, "-e") == 0)
157: enc = 1;
158: else if (strcmp(*argv, "-in") == 0) {
159: if (--argc < 1)
160: goto bad;
161: inf = *(++argv);
162: } else if (strcmp(*argv, "-out") == 0) {
163: if (--argc < 1)
164: goto bad;
165: outf = *(++argv);
166: } else if (strcmp(*argv, "-pass") == 0) {
167: if (--argc < 1)
168: goto bad;
169: passarg = *(++argv);
170: }
171: #ifndef OPENSSL_NO_ENGINE
172: else if (strcmp(*argv, "-engine") == 0) {
173: if (--argc < 1)
174: goto bad;
175: engine = *(++argv);
176: }
177: #endif
178: else if (strcmp(*argv, "-d") == 0)
179: enc = 0;
180: else if (strcmp(*argv, "-p") == 0)
181: printkey = 1;
182: else if (strcmp(*argv, "-v") == 0)
183: verbose = 1;
184: else if (strcmp(*argv, "-nopad") == 0)
185: nopad = 1;
186: else if (strcmp(*argv, "-salt") == 0)
187: nosalt = 0;
188: else if (strcmp(*argv, "-nosalt") == 0)
189: nosalt = 1;
190: else if (strcmp(*argv, "-debug") == 0)
191: debug = 1;
192: else if (strcmp(*argv, "-P") == 0)
193: printkey = 2;
194: else if (strcmp(*argv, "-A") == 0)
195: olb64 = 1;
196: else if (strcmp(*argv, "-a") == 0)
197: base64 = 1;
198: else if (strcmp(*argv, "-base64") == 0)
199: base64 = 1;
200: #ifdef ZLIB
201: else if (strcmp(*argv, "-z") == 0)
202: do_zlib = 1;
203: #endif
204: else if (strcmp(*argv, "-bufsize") == 0) {
205: if (--argc < 1)
206: goto bad;
207: bufsize = (unsigned char *) *(++argv);
208: } else if (strcmp(*argv, "-k") == 0) {
209: if (--argc < 1)
210: goto bad;
211: str = *(++argv);
212: } else if (strcmp(*argv, "-kfile") == 0) {
213: static char buf[128];
214: FILE *infile;
215: char *file;
216:
217: if (--argc < 1)
218: goto bad;
219: file = *(++argv);
220: infile = fopen(file, "r");
221: if (infile == NULL) {
222: BIO_printf(bio_err, "unable to read key from '%s'\n",
223: file);
224: goto bad;
225: }
226: buf[0] = '\0';
227: if (!fgets(buf, sizeof buf, infile)) {
228: BIO_printf(bio_err, "unable to read key from '%s'\n",
229: file);
230: fclose(infile);
231: goto bad;
232: }
233: fclose(infile);
234: i = strlen(buf);
235: if ((i > 0) &&
236: ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
237: buf[--i] = '\0';
238: if ((i > 0) &&
239: ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
240: buf[--i] = '\0';
241: if (i < 1) {
242: BIO_printf(bio_err, "zero length password\n");
243: goto bad;
244: }
245: str = buf;
246: } else if (strcmp(*argv, "-K") == 0) {
247: if (--argc < 1)
248: goto bad;
249: hkey = *(++argv);
250: } else if (strcmp(*argv, "-S") == 0) {
251: if (--argc < 1)
252: goto bad;
253: hsalt = *(++argv);
254: } else if (strcmp(*argv, "-iv") == 0) {
255: if (--argc < 1)
256: goto bad;
257: hiv = *(++argv);
258: } else if (strcmp(*argv, "-md") == 0) {
259: if (--argc < 1)
260: goto bad;
261: md = *(++argv);
262: } else if ((argv[0][0] == '-') &&
263: ((c = EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) {
264: cipher = c;
265: } else if (strcmp(*argv, "-none") == 0)
266: cipher = NULL;
267: else {
268: BIO_printf(bio_err, "unknown option '%s'\n", *argv);
269: bad:
270: BIO_printf(bio_err, "options are\n");
271: BIO_printf(bio_err, "%-14s input file\n", "-in <file>");
272: BIO_printf(bio_err, "%-14s output file\n", "-out <file>");
273: BIO_printf(bio_err, "%-14s pass phrase source\n", "-pass <arg>");
274: BIO_printf(bio_err, "%-14s encrypt\n", "-e");
275: BIO_printf(bio_err, "%-14s decrypt\n", "-d");
276: BIO_printf(bio_err, "%-14s base64 encode/decode, depending on encryption flag\n", "-a/-base64");
277: BIO_printf(bio_err, "%-14s passphrase is the next argument\n", "-k");
278: BIO_printf(bio_err, "%-14s passphrase is the first line of the file argument\n", "-kfile");
279: BIO_printf(bio_err, "%-14s the next argument is the md to use to create a key\n", "-md");
280: BIO_printf(bio_err, "%-14s from a passphrase. One of md2, md5, sha or sha1\n", "");
281: BIO_printf(bio_err, "%-14s salt in hex is the next argument\n", "-S");
282: BIO_printf(bio_err, "%-14s key/iv in hex is the next argument\n", "-K/-iv");
283: BIO_printf(bio_err, "%-14s print the iv/key (then exit if -P)\n", "-[pP]");
284: BIO_printf(bio_err, "%-14s buffer size\n", "-bufsize <n>");
285: BIO_printf(bio_err, "%-14s disable standard block padding\n", "-nopad");
286: #ifndef OPENSSL_NO_ENGINE
287: BIO_printf(bio_err, "%-14s use engine e, possibly a hardware device.\n", "-engine e");
288: #endif
289:
290: BIO_printf(bio_err, "Cipher Types\n");
291: OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
292: show_ciphers,
293: bio_err);
294: BIO_printf(bio_err, "\n");
295:
296: goto end;
297: }
298: argc--;
299: argv++;
300: }
301:
302: #ifndef OPENSSL_NO_ENGINE
303: setup_engine(bio_err, engine, 0);
304: #endif
305:
306: if (md && (dgst = EVP_get_digestbyname(md)) == NULL) {
307: BIO_printf(bio_err, "%s is an unsupported message digest type\n", md);
308: goto end;
309: }
310: if (dgst == NULL) {
311: dgst = EVP_md5();
312: }
313: if (bufsize != NULL) {
314: unsigned long n;
315:
316: for (n = 0; *bufsize; bufsize++) {
317: i = *bufsize;
318: if ((i <= '9') && (i >= '0'))
319: n = n * 10 + i - '0';
320: else if (i == 'k') {
321: n *= 1024;
322: bufsize++;
323: break;
324: }
325: }
326: if (*bufsize != '\0') {
327: BIO_printf(bio_err, "invalid 'bufsize' specified.\n");
328: goto end;
329: }
330: /* It must be large enough for a base64 encoded line */
331: if (base64 && n < 80)
332: n = 80;
333:
334: bsize = (int) n;
335: if (verbose)
336: BIO_printf(bio_err, "bufsize=%d\n", bsize);
337: }
338: strbuf = malloc(SIZE);
339: buff = malloc(EVP_ENCODE_LENGTH(bsize));
340: if ((buff == NULL) || (strbuf == NULL)) {
341: BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize));
342: goto end;
343: }
344: in = BIO_new(BIO_s_file());
345: out = BIO_new(BIO_s_file());
346: if ((in == NULL) || (out == NULL)) {
347: ERR_print_errors(bio_err);
348: goto end;
349: }
350: if (debug) {
351: BIO_set_callback(in, BIO_debug_callback);
352: BIO_set_callback(out, BIO_debug_callback);
353: BIO_set_callback_arg(in, (char *) bio_err);
354: BIO_set_callback_arg(out, (char *) bio_err);
355: }
356: if (inf == NULL) {
357: if (bufsize != NULL)
358: setvbuf(stdin, (char *) NULL, _IONBF, 0);
359: BIO_set_fp(in, stdin, BIO_NOCLOSE);
360: } else {
361: if (BIO_read_filename(in, inf) <= 0) {
362: perror(inf);
363: goto end;
364: }
365: }
366:
367: if (!str && passarg) {
368: if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
369: BIO_printf(bio_err, "Error getting password\n");
370: goto end;
371: }
372: str = pass;
373: }
374: if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) {
375: for (;;) {
376: char buf[200];
1.2 ! doug 377: int retval;
1.1 jsing 378:
1.2 ! doug 379: retval = snprintf(buf, sizeof buf, "enter %s %s password:",
1.1 jsing 380: OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
381: (enc) ? "encryption" : "decryption");
1.2 ! doug 382: if ((size_t)retval >= sizeof buf) {
1.1 jsing 383: BIO_printf(bio_err, "Password prompt too long\n");
384: goto end;
385: }
386: strbuf[0] = '\0';
387: i = EVP_read_pw_string((char *) strbuf, SIZE, buf, enc);
388: if (i == 0) {
389: if (strbuf[0] == '\0') {
390: ret = 1;
391: goto end;
392: }
393: str = strbuf;
394: break;
395: }
396: if (i < 0) {
397: BIO_printf(bio_err, "bad password read\n");
398: goto end;
399: }
400: }
401: }
402: if (outf == NULL) {
403: BIO_set_fp(out, stdout, BIO_NOCLOSE);
404: if (bufsize != NULL)
405: setvbuf(stdout, (char *) NULL, _IONBF, 0);
406: } else {
407: if (BIO_write_filename(out, outf) <= 0) {
408: perror(outf);
409: goto end;
410: }
411: }
412:
413: rbio = in;
414: wbio = out;
415:
416: #ifdef ZLIB
417:
418: if (do_zlib) {
419: if ((bzl = BIO_new(BIO_f_zlib())) == NULL)
420: goto end;
421: if (enc)
422: wbio = BIO_push(bzl, wbio);
423: else
424: rbio = BIO_push(bzl, rbio);
425: }
426: #endif
427:
428: if (base64) {
429: if ((b64 = BIO_new(BIO_f_base64())) == NULL)
430: goto end;
431: if (debug) {
432: BIO_set_callback(b64, BIO_debug_callback);
433: BIO_set_callback_arg(b64, (char *) bio_err);
434: }
435: if (olb64)
436: BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
437: if (enc)
438: wbio = BIO_push(b64, wbio);
439: else
440: rbio = BIO_push(b64, rbio);
441: }
442: if (cipher != NULL) {
443: /*
444: * Note that str is NULL if a key was passed on the command
445: * line, so we get no salt in that case. Is this a bug?
446: */
447: if (str != NULL) {
448: /*
449: * Salt handling: if encrypting generate a salt and
450: * write to output BIO. If decrypting read salt from
451: * input BIO.
452: */
453: unsigned char *sptr;
454: if (nosalt)
455: sptr = NULL;
456: else {
457: if (enc) {
458: if (hsalt) {
459: if (!set_hex(hsalt, salt, sizeof salt)) {
460: BIO_printf(bio_err,
461: "invalid hex salt value\n");
462: goto end;
463: }
464: } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
465: goto end;
466: /*
467: * If -P option then don't bother
468: * writing
469: */
470: if ((printkey != 2)
471: && (BIO_write(wbio, magic,
472: sizeof magic - 1) != sizeof magic - 1
473: || BIO_write(wbio,
474: (char *) salt,
475: sizeof salt) != sizeof salt)) {
476: BIO_printf(bio_err, "error writing output file\n");
477: goto end;
478: }
479: } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf
480: || BIO_read(rbio,
481: (unsigned char *) salt,
482: sizeof salt) != sizeof salt) {
483: BIO_printf(bio_err, "error reading input file\n");
484: goto end;
485: } else if (memcmp(mbuf, magic, sizeof magic - 1)) {
486: BIO_printf(bio_err, "bad magic number\n");
487: goto end;
488: }
489: sptr = salt;
490: }
491:
492: EVP_BytesToKey(cipher, dgst, sptr,
493: (unsigned char *) str,
494: strlen(str), 1, key, iv);
495: /*
496: * zero the complete buffer or the string passed from
497: * the command line bug picked up by Larry J. Hughes
498: * Jr. <hughes@indiana.edu>
499: */
500: if (str == strbuf)
501: OPENSSL_cleanse(str, SIZE);
502: else
503: OPENSSL_cleanse(str, strlen(str));
504: }
505: if ((hiv != NULL) && !set_hex(hiv, iv, sizeof iv)) {
506: BIO_printf(bio_err, "invalid hex iv value\n");
507: goto end;
508: }
509: if ((hiv == NULL) && (str == NULL)
510: && EVP_CIPHER_iv_length(cipher) != 0) {
511: /*
512: * No IV was explicitly set and no IV was generated
513: * during EVP_BytesToKey. Hence the IV is undefined,
514: * making correct decryption impossible.
515: */
516: BIO_printf(bio_err, "iv undefined\n");
517: goto end;
518: }
519: if ((hkey != NULL) && !set_hex(hkey, key, sizeof key)) {
520: BIO_printf(bio_err, "invalid hex key value\n");
521: goto end;
522: }
523: if ((benc = BIO_new(BIO_f_cipher())) == NULL)
524: goto end;
525:
526: /*
527: * Since we may be changing parameters work on the encryption
528: * context rather than calling BIO_set_cipher().
529: */
530:
531: BIO_get_cipher_ctx(benc, &ctx);
532:
533: if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) {
534: BIO_printf(bio_err, "Error setting cipher %s\n",
535: EVP_CIPHER_name(cipher));
536: ERR_print_errors(bio_err);
537: goto end;
538: }
539: if (nopad)
540: EVP_CIPHER_CTX_set_padding(ctx, 0);
541:
542: if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) {
543: BIO_printf(bio_err, "Error setting cipher %s\n",
544: EVP_CIPHER_name(cipher));
545: ERR_print_errors(bio_err);
546: goto end;
547: }
548: if (debug) {
549: BIO_set_callback(benc, BIO_debug_callback);
550: BIO_set_callback_arg(benc, (char *) bio_err);
551: }
552: if (printkey) {
553: if (!nosalt) {
554: printf("salt=");
555: for (i = 0; i < (int) sizeof(salt); i++)
556: printf("%02X", salt[i]);
557: printf("\n");
558: }
559: if (cipher->key_len > 0) {
560: printf("key=");
561: for (i = 0; i < cipher->key_len; i++)
562: printf("%02X", key[i]);
563: printf("\n");
564: }
565: if (cipher->iv_len > 0) {
566: printf("iv =");
567: for (i = 0; i < cipher->iv_len; i++)
568: printf("%02X", iv[i]);
569: printf("\n");
570: }
571: if (printkey == 2) {
572: ret = 0;
573: goto end;
574: }
575: }
576: }
577: /* Only encrypt/decrypt as we write the file */
578: if (benc != NULL)
579: wbio = BIO_push(benc, wbio);
580:
581: for (;;) {
582: inl = BIO_read(rbio, (char *) buff, bsize);
583: if (inl <= 0)
584: break;
585: if (BIO_write(wbio, (char *) buff, inl) != inl) {
586: BIO_printf(bio_err, "error writing output file\n");
587: goto end;
588: }
589: }
590: if (!BIO_flush(wbio)) {
591: BIO_printf(bio_err, "bad decrypt\n");
592: goto end;
593: }
594: ret = 0;
595: if (verbose) {
596: BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in));
597: BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out));
598: }
599: end:
600: ERR_print_errors(bio_err);
601: free(strbuf);
602: free(buff);
603: BIO_free(in);
604: if (out != NULL)
605: BIO_free_all(out);
606: BIO_free(benc);
607: BIO_free(b64);
608: #ifdef ZLIB
609: BIO_free(bzl);
610: #endif
611: free(pass);
612:
613: return (ret);
614: }
615:
616: int
617: set_hex(char *in, unsigned char *out, int size)
618: {
619: int i, n;
620: unsigned char j;
621:
622: n = strlen(in);
623: if (n > (size * 2)) {
624: BIO_printf(bio_err, "hex string is too long\n");
625: return (0);
626: }
627: memset(out, 0, size);
628: for (i = 0; i < n; i++) {
629: j = (unsigned char) *in;
630: *(in++) = '\0';
631: if (j == 0)
632: break;
633: if ((j >= '0') && (j <= '9'))
634: j -= '0';
635: else if ((j >= 'A') && (j <= 'F'))
636: j = j - 'A' + 10;
637: else if ((j >= 'a') && (j <= 'f'))
638: j = j - 'a' + 10;
639: else {
640: BIO_printf(bio_err, "non-hex digit\n");
641: return (0);
642: }
643: if (i & 1)
644: out[i / 2] |= j;
645: else
646: out[i / 2] = (j << 4);
647: }
648: return (1);
649: }