projects/sencrypt

view sencrypt.c @ 18:07f525330bc7

Mark fallthrough case
author Guido Berhoerster <guido+sencrypt@berhoerster.name>
date Wed Jul 31 09:58:53 2019 +0200 (2019-07-31)
parents d9c4bdc004d2
children c45f17f58de1
line source
1 /*
2 * Copyright (C) 2016 Guido Berhoerster <guido+sencrypt@berhoerster.name>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdint.h>
27 #include <stdbool.h>
28 #include <unistd.h>
29 #include <limits.h>
30 #include <libgen.h>
31 #include <arpa/inet.h>
32 #include <sys/stat.h>
33 #include <openssl/conf.h>
34 #include <openssl/rand.h>
35 #include <openssl/evp.h>
36 #include <openssl/err.h>
38 #ifdef HAVE_ERR_H
39 #include <err.h>
40 #endif /* HAVE_ERR_H */
41 #include "compat.h"
43 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
45 #define EXIT_USAGE 2
47 #define SENCRYPT_FORMAT_VERSION 1
48 #define PBKDF2_ITERATIONS 500000
49 #define SALT_LEN 16
50 #define BUFFER_SIZE (16 * 1024)
51 #define MAX_PASSWORD_LEN 256
53 enum {
54 CMD_SENCRYPT,
55 CMD_SDECRYPT
56 };
58 static void
59 openssl_warn(void) {
60 unsigned long errcode;
62 while ((errcode = ERR_get_error()) != 0) {
63 warnx("%s", ERR_error_string(errcode, NULL));
64 }
65 }
67 static size_t
68 read_keyfile(const char *filename, unsigned char *key, size_t key_size_max)
69 {
70 size_t keyfile_size = 0;
71 FILE *fp = NULL;
72 struct stat statbuf;
74 fp = fopen(filename, "r");
75 if (fp == NULL) {
76 warn("could not open key file \"%s\"", filename);
77 goto out;
78 }
80 if (fstat(fileno(fp), &statbuf) == -1) {
81 warn("could not stat key file \"%s\"", filename);
82 goto out;
83 }
85 if (!S_ISREG(statbuf.st_mode)) {
86 warnx("key file \"%s\" is not a regular file", filename);
87 goto out;
88 }
90 if ((uintmax_t)statbuf.st_size > SIZE_MAX) {
91 warnx("key file \"%s\" is too large", filename);
92 goto out;
93 }
94 keyfile_size = (size_t)statbuf.st_size;
95 if ((keyfile_size > key_size_max) ||
96 (keyfile_size == 0)) {
97 warnx("invalid key size");
98 goto out;
99 }
101 if (fread(key, 1, keyfile_size, fp) != keyfile_size) {
102 warnx("could not read key file \"%s\"", filename);
103 goto out;
104 }
106 out:
107 if (fp != NULL) {
108 fclose(fp);
109 }
111 return (keyfile_size);
112 }
114 static int
115 find_algorithm(const char *algo_name, const EVP_CIPHER **cipher_ptr,
116 size_t *key_len_ptr)
117 {
118 int retval = 0;
119 const EVP_CIPHER *cipher = NULL;
120 size_t key_len = *key_len_ptr;
122 if (strcmp(algo_name, "aes") == 0) {
123 switch (key_len) {
124 case 0:
125 key_len = 16;
126 /* FALLTHROUGH */
127 case 16:
128 cipher = EVP_aes_128_cbc();
129 break;
130 case 24:
131 cipher = EVP_aes_192_cbc();
132 break;
133 case 32:
134 cipher = EVP_aes_256_cbc();
135 break;
136 default:
137 warnx("invalid key length %zu", key_len);
138 retval = -1;
139 }
140 } else if (strcmp(algo_name, "arcfour") == 0) {
141 if (key_len == 0) {
142 key_len = 16;
143 cipher = EVP_rc4();
144 } else if (key_len <= EVP_MAX_KEY_LENGTH) {
145 /*
146 * for RC4 keys are not used verbatim but dervied using
147 * PBKDF2 with a hardcoded key length of 128 bit
148 */
149 key_len = 16;
150 cipher = EVP_rc4();
151 } else {
152 warnx("invalid key length %zu", key_len);
153 retval = -1;
154 }
155 } else if (strcmp(algo_name, "des") == 0) {
156 if (key_len == 0) {
157 key_len = 8;
158 cipher = EVP_des_cbc();
159 } else if (key_len == 8) {
160 cipher = EVP_des_cbc();
161 } else {
162 warnx("invalid key length %zu", key_len);
163 retval = -1;
164 }
165 } else if (strcmp(algo_name, "3des") == 0) {
166 if (key_len == 0) {
167 key_len = 24;
168 cipher = EVP_des_ede3_cbc();
169 } else if (key_len == 24) {
170 cipher = EVP_des_ede3_cbc();
171 } else {
172 warnx("invalid key length %zu", key_len);
173 retval = -1;
174 }
175 } else {
176 warnx("unknown algorithm \"%s\"", algo_name);
177 retval = -1;
178 }
180 *cipher_ptr = cipher;
181 *key_len_ptr = key_len;
183 return (retval);
184 }
186 static int
187 read_header(BIO *bio_in, uint32_t *iterations, unsigned char *iv, int iv_len,
188 unsigned char *salt, int salt_len)
189 {
190 int read_len;
191 uint32_t version;
192 int retval = 0;
194 read_len = BIO_read(bio_in, &version, sizeof (version));
195 if (read_len != sizeof (version)) {
196 warnx("failed to read version from input file");
197 if (read_len < 0) {
198 openssl_warn();
199 }
200 retval = -1;
201 goto out;
202 }
203 version = htonl(version);
204 if (version != SENCRYPT_FORMAT_VERSION) {
205 warnx("unknown format version %d", version);
206 retval = -1;
207 goto out;
208 }
210 read_len = BIO_read(bio_in, iterations, sizeof (*iterations));
211 if (read_len != sizeof (*iterations)) {
212 warnx("failed to read iterations from input file");
213 if (read_len < 0) {
214 openssl_warn();
215 }
216 retval = -1;
217 goto out;
218 }
219 *iterations = htonl(*iterations);
220 if ((*iterations == 0) || ((sizeof (int) <= sizeof (uint32_t)) &&
221 (*iterations > INT_MAX))) {
222 warnx("invalid number of iterations");
223 retval = -1;
224 goto out;
225 }
227 if (iv_len > 0) {
228 read_len = BIO_read(bio_in, iv, iv_len);
229 if (read_len != iv_len) {
230 warnx("failed to read IV from input file");
231 if (read_len < 0) {
232 openssl_warn();
233 }
234 retval = -1;
235 goto out;
236 }
237 }
239 read_len = BIO_read(bio_in, salt, salt_len);
240 if (read_len != salt_len) {
241 warnx("failed to read salt from input file");
242 if (read_len < 0) {
243 openssl_warn();
244 }
245 retval = -1;
246 goto out;
247 }
249 out:
250 return (retval);
251 }
253 static int
254 sencrypt(const EVP_CIPHER *cipher, BIO *bio_in, BIO *bio_out,
255 const unsigned char *key, size_t key_len, const unsigned char *iv,
256 const unsigned char *salt)
257 {
258 int retval = 0;
259 uint32_t version;
260 uint32_t iterations;
261 int iv_len;
262 int write_len;
263 int read_len;
264 BIO *bio_cipher = NULL;
265 char *buf = NULL;
266 EVP_CIPHER_CTX *cipher_ctx;
268 /* set up cipher filter */
269 bio_cipher = BIO_new(BIO_f_cipher());
270 BIO_set_cipher(bio_cipher, cipher, NULL, NULL, 1);
271 BIO_get_cipher_ctx(bio_cipher, &cipher_ctx);
272 if (EVP_CIPHER_CTX_set_key_length(cipher_ctx, (int)key_len) != 1) {
273 warnx("failed to set key length");
274 openssl_warn();
275 retval = 1;
276 goto out;
277 }
278 if (EVP_CipherInit_ex(cipher_ctx, NULL, NULL, key, iv, 1) != 1) {
279 warnx("failed to initialize cipher");
280 openssl_warn();
281 retval = 1;
282 goto out;
283 }
284 BIO_push(bio_cipher, bio_out);
286 /* write header */
287 version = htonl(SENCRYPT_FORMAT_VERSION);
288 write_len = BIO_write(bio_out, &version, sizeof (version));
289 if (write_len != sizeof (version)) {
290 warnx("failed to write version to output file");
291 if (write_len < 0) {
292 openssl_warn();
293 }
294 retval = 1;
295 goto out;
296 }
298 iterations = htonl(PBKDF2_ITERATIONS);
299 write_len = BIO_write(bio_out, &iterations, sizeof (iterations));
300 if (write_len != sizeof (iterations)) {
301 warnx("failed to write iterations to output file");
302 if (write_len < 0) {
303 openssl_warn();
304 }
305 retval = 1;
306 goto out;
307 }
309 iv_len = EVP_CIPHER_iv_length(cipher);
310 if (iv_len > 0) {
311 write_len = BIO_write(bio_out, iv, iv_len);
312 if (write_len != iv_len) {
313 warnx("failed to write IV to output file");
314 if (write_len < 0) {
315 openssl_warn();
316 }
317 retval = 1;
318 goto out;
319 }
320 }
322 write_len = BIO_write(bio_out, salt, SALT_LEN);
323 if (write_len != SALT_LEN) {
324 warnx("failed to write salt to output file");
325 if (write_len < 0) {
326 openssl_warn();
327 }
328 retval = 1;
329 goto out;
330 }
332 if (BIO_flush(bio_out) < 1) {
333 warnx("failed to flush output file");
334 openssl_warn();
335 retval = 1;
336 goto out;
337 }
339 buf = malloc(BUFFER_SIZE);
340 if (buf == NULL) {
341 warn(NULL);
342 retval = 1;
343 goto out;
344 }
346 /* encrypt data */
347 while ((read_len = BIO_read(bio_in, buf, BUFFER_SIZE)) > 0) {
348 if ((write_len = BIO_write(bio_cipher, buf, read_len)) !=
349 read_len) {
350 warnx("failed to write to output file");
351 if (write_len < 0) {
352 openssl_warn();
353 }
354 retval = 1;
355 goto out;
356 }
357 }
358 if (read_len < 0) {
359 warnx("failed to read from input file");
360 openssl_warn();
361 retval = 1;
362 goto out;
363 }
365 if (BIO_flush(bio_cipher) < 1) {
366 warnx("failed to flush output file");
367 openssl_warn();
368 retval = 1;
369 goto out;
370 }
372 out:
373 free(buf);
375 if (bio_cipher != NULL) {
376 BIO_pop(bio_cipher);
377 BIO_free(bio_cipher);
378 }
380 return (retval);
381 }
383 static int
384 sdecrypt(const EVP_CIPHER *cipher, BIO *bio_in, BIO *bio_out,
385 const unsigned char *key, size_t key_len, const unsigned char *iv)
386 {
387 int read_len;
388 BIO *bio_cipher = NULL;
389 int write_len;
390 char *buf = NULL;
391 EVP_CIPHER_CTX *cipher_ctx;
392 int retval = 0;
394 buf = malloc(BUFFER_SIZE);
395 if (buf == NULL) {
396 warn(NULL);
397 retval = 1;
398 goto out;
399 }
401 /* set up cipher filter */
402 bio_cipher = BIO_new(BIO_f_cipher());
403 BIO_set_cipher(bio_cipher, cipher, NULL, NULL, 0);
404 BIO_get_cipher_ctx(bio_cipher, &cipher_ctx);
405 if (EVP_CIPHER_CTX_set_key_length(cipher_ctx, (int)key_len) != 1) {
406 warnx("failed to set key length");
407 openssl_warn();
408 retval = 1;
409 goto out;
410 }
411 if (EVP_CipherInit_ex(cipher_ctx, NULL, NULL, key, iv, 0) != 1) {
412 warnx("failed to initialize cipher");
413 openssl_warn();
414 retval = 1;
415 goto out;
416 }
417 BIO_push(bio_cipher, bio_in);
419 /* decrypt data */
420 while ((read_len = BIO_read(bio_cipher, buf, BUFFER_SIZE)) > 0) {
421 if ((write_len = BIO_write(bio_out, buf, read_len)) !=
422 read_len) {
423 warnx("failed to write to to output file");
424 if (write_len < 0) {
425 openssl_warn();
426 }
427 retval = 1;
428 goto out;
429 }
430 }
431 if (read_len < 0) {
432 warnx("failed to read from input file");
433 openssl_warn();
434 retval = 1;
435 goto out;
436 }
438 if (BIO_flush(bio_out) < 1) {
439 warnx("failed to flush output file");
440 openssl_warn();
441 retval = 1;
442 goto out;
443 }
445 if (BIO_get_cipher_status(bio_cipher) == 0) {
446 warnx("decryption failed");
447 openssl_warn();
448 retval = 1;
449 goto out;
450 }
452 out:
453 free(buf);
455 if (bio_cipher != NULL) {
456 BIO_pop(bio_cipher);
457 BIO_free(bio_cipher);
458 }
460 return (retval);
461 }
463 static void
464 list_algorithms(void)
465 {
466 printf("Algorithm Keysize: Min Max (bits)\n"
467 "------------------------------------------\n");
468 printf("%-15s %5u %5u\n", "aes", 128, 256);
469 printf("%-15s %5u %5u\n", "arcfour", 8,
470 EVP_MAX_KEY_LENGTH * 8);
471 printf("%-15s %5u %5u\n", "des", 64, 64);
472 printf("%-15s %5u %5u\n", "3des", 192, 192);
473 }
475 static void
476 usage(int cmd)
477 {
478 if (cmd == CMD_SENCRYPT) {
479 fprintf(stderr, "usage: sencrypt -l | [-v] -a algorithm "
480 "[-k key_file] [-i input_file] [-o output_file]\n");
481 } else if (cmd == CMD_SDECRYPT) {
482 fprintf(stderr, "usage: sdecrypt -l | [-v] -a algorithm "
483 "[-k key_file] [-i input_file] [-o output_file]\n");
484 }
485 }
487 int
488 main(int argc, char *argv[])
489 {
490 char *progname;
491 int cmd;
492 int c;
493 bool aflag = false;
494 char *algo_name = NULL;
495 bool is_algo_rc4 = false;
496 bool iflag = false;
497 char *in_filename = NULL;
498 bool kflag = false;
499 char *key_filename = NULL;
500 bool lflag = false;
501 bool oflag = false;
502 char *out_filename = NULL;
503 bool vflag = false;
504 bool errflag = false;
505 unsigned char key[EVP_MAX_KEY_LENGTH];
506 size_t key_len = 0;
507 size_t key_file_len;
508 const EVP_CIPHER *cipher;
509 BIO *bio_in = NULL;
510 uint32_t iterations = PBKDF2_ITERATIONS;
511 unsigned char iv[EVP_MAX_IV_LENGTH];
512 unsigned char salt[SALT_LEN];
513 BIO *bio_out = NULL;
514 int need_tmpfile = 0;
515 FILE *fp_in;
516 struct stat statbuf_in;
517 struct stat statbuf_out;
518 int fd_tmp = -1;
519 FILE *fp_tmp = NULL;
520 char *out_filename_tmp = NULL;
521 char *out_dir = NULL;
522 char *tmp_filename = NULL;
523 int len;
524 mode_t old_mode;
525 char pwdata[MAX(MAX_PASSWORD_LEN, EVP_MAX_KEY_LENGTH)];
526 size_t pwdata_len = 0;
527 int status = EXIT_SUCCESS;
529 #if OPENSSL_VERSION_NUMBER < 0x10100000L
530 /* initialize OpenSSL */
531 OpenSSL_add_all_algorithms();
532 ERR_load_crypto_strings();
533 OPENSSL_config(NULL);
534 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
536 progname = strrchr(argv[0], '/');
537 progname = (progname != NULL) ? progname + 1 : argv[0];
538 if ((strcmp(progname, "sencrypt") == 0) ||
539 (strcmp(progname, "encrypt") == 0)) {
540 cmd = CMD_SENCRYPT;
541 } else if ((strcmp(progname, "sdecrypt") == 0) ||
542 (strcmp(progname, "decrypt") == 0)) {
543 cmd = CMD_SDECRYPT;
544 } else {
545 fprintf(stderr, "invalid command name");
546 status = EXIT_FAILURE;
547 goto out;
548 }
550 while (!errflag && (c = getopt(argc, argv, "a:i:k:lo:v")) != -1) {
551 switch (c) {
552 case 'a':
553 aflag = true;
554 algo_name = optarg;
555 is_algo_rc4 = (strcmp(algo_name, "arcfour") == 0);
556 break;
557 case 'i':
558 iflag = true;
559 in_filename = optarg;
560 break;
561 case 'k':
562 kflag = true;
563 key_filename = optarg;
564 break;
565 case 'l':
566 lflag = true;
567 break;
568 case 'o':
569 oflag = true;
570 out_filename = optarg;
571 break;
572 case 'v':
573 vflag = true;
574 break;
575 default:
576 errflag = true;
577 }
578 }
579 if (errflag || (!lflag && !aflag) || (lflag && aflag) ||
580 (argc > optind)) {
581 usage(cmd);
582 status = EXIT_USAGE;
583 goto out;
584 }
586 if (lflag) {
587 list_algorithms();
588 goto out;
589 }
591 if (kflag) {
592 key_file_len = read_keyfile(key_filename, key,
593 (off_t)sizeof (key));
594 if (key_file_len < 1) {
595 status = EXIT_FAILURE;
596 goto out;
597 }
598 key_len = key_file_len;
599 } else {
600 if (EVP_read_pw_string(pwdata, sizeof (pwdata), "Enter key:",
601 (cmd == CMD_SENCRYPT) ? 1 : 0) != 0) {
602 warnx("could not read passphrase");
603 openssl_warn();
604 status = EXIT_FAILURE;
605 goto out;
606 }
607 pwdata_len = strlen(pwdata);
608 if (pwdata_len < 1) {
609 warnx("invalid passphrase");
610 status = EXIT_FAILURE;
611 goto out;
612 }
613 }
615 /* the cipher is determined based on name and length of the key file */
616 if (find_algorithm(algo_name, &cipher, &key_len) == -1) {
617 status = EXIT_FAILURE;
618 goto out;
619 }
620 if ((cmd == CMD_SENCRYPT) && ((cipher != EVP_aes_128_cbc()) &&
621 (cipher != EVP_aes_192_cbc()) && (cipher != EVP_aes_256_cbc()))) {
622 fprintf(stderr, "warning: the %s algorithm is no longer "
623 "considered secure", algo_name);
624 }
626 if (iflag) {
627 bio_in = BIO_new_file(in_filename, "r");
628 } else {
629 bio_in = BIO_new_fp(stdin, BIO_NOCLOSE);
630 }
631 if (bio_in == NULL) {
632 warnx("could not open input file");
633 openssl_warn();
634 status = EXIT_FAILURE;
635 goto out;
636 }
638 if (cmd == CMD_SENCRYPT) {
639 /* generate random salt and IV */
640 if ((RAND_bytes(salt, sizeof (salt)) != 1) ||
641 (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1)) {
642 /* not enough entropy or unknown error */
643 warnx("failed to generate random data");
644 status = EXIT_FAILURE;
645 goto out;
646 }
647 } else {
648 read_header(bio_in, &iterations, iv,
649 EVP_CIPHER_iv_length(cipher), salt, (int)sizeof (salt));
650 }
652 /*
653 * if no keyfile was given or the RC4 cipher is used, derive the key
654 * from the password and salt
655 */
656 if (kflag && is_algo_rc4) {
657 memcpy(pwdata, key, key_file_len);
658 pwdata_len = key_file_len;
659 }
660 if (!kflag || is_algo_rc4) {
661 if (PKCS5_PBKDF2_HMAC_SHA1(pwdata, (int)pwdata_len, salt,
662 sizeof (salt), (int)iterations, (int)key_len, key) == 0) {
663 warnx("failed to generate key");
664 status = EXIT_FAILURE;
665 goto out;
666 }
667 }
669 if (oflag) {
670 /*
671 * if input and output files are identical, create and write the
672 * output to a temporary file for the output which is then
673 * renamed to out_filename
674 */
675 if (iflag) {
676 BIO_get_fp(bio_in, &fp_in);
677 if (fstat(fileno(fp_in), &statbuf_in) == -1) {
678 warn("could not stat input file");
679 status = EXIT_FAILURE;
680 goto out;
681 }
682 if (stat(out_filename, &statbuf_out) == -1) {
683 if (errno != ENOENT) {
684 warn("could not stat output file");
685 status = EXIT_FAILURE;
686 goto out;
687 }
688 } else if ((statbuf_in.st_ino == statbuf_out.st_ino) &&
689 (statbuf_in.st_dev == statbuf_out.st_dev)) {
690 need_tmpfile = 1;
691 }
692 }
694 if (need_tmpfile) {
695 out_filename_tmp = strdup(out_filename);
696 if (out_filename_tmp == NULL) {
697 warn(NULL);
698 status = EXIT_FAILURE;
699 goto out;
700 }
701 out_dir = dirname(out_filename_tmp);
702 len = snprintf(NULL, 0, "%s/sencryptXXXXXX", out_dir);
703 if (len < 0) {
704 warn(NULL);
705 status = EXIT_FAILURE;
706 goto out;
707 }
708 tmp_filename = malloc((size_t)len + 1);
709 if (tmp_filename == NULL) {
710 warn(NULL);
711 status = EXIT_FAILURE;
712 goto out;
713 }
714 if (snprintf(tmp_filename, (size_t)len + 1,
715 "%s/sencryptXXXXXX", out_dir) != len) {
716 warn(NULL);
717 status = EXIT_FAILURE;
718 goto out;
719 }
720 old_mode = umask(077);
721 fd_tmp = mkstemp(tmp_filename);
722 umask(old_mode);
723 if (fd_tmp == -1) {
724 warn("could not create temporary file");
725 status = EXIT_FAILURE;
726 goto out;
727 }
728 fp_tmp = fdopen(fd_tmp, "w");
729 if (fp_tmp == NULL) {
730 warn("could not open temporary file");
731 status = EXIT_FAILURE;
732 goto out;
733 }
734 fd_tmp = -1;
735 bio_out = BIO_new_fp(fp_tmp, BIO_CLOSE);
736 if (bio_out == NULL) {
737 warnx("could not open temporary file");
738 openssl_warn();
739 status = EXIT_FAILURE;
740 goto out;
741 }
742 fp_tmp = NULL;
743 } else {
744 old_mode = umask(077);
745 bio_out = BIO_new_file(out_filename, "w");
746 umask(old_mode);
747 if (bio_out == NULL) {
748 warnx("could not open output file");
749 openssl_warn();
750 status = EXIT_FAILURE;
751 goto out;
752 }
753 }
754 } else {
755 bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
756 if (bio_out == NULL) {
757 warnx("could not open output file");
758 openssl_warn();
759 status = EXIT_FAILURE;
760 goto out;
761 }
762 }
764 if (cmd == CMD_SENCRYPT) {
765 if (sencrypt(cipher, bio_in, bio_out, key, key_len,
766 iv, salt) == -1) {
767 status = EXIT_FAILURE;
768 }
769 } else {
770 if (sdecrypt(cipher, bio_in, bio_out, key, key_len,
771 iv) == -1) {
772 status = EXIT_FAILURE;
773 }
774 }
776 out:
777 OPENSSL_cleanse(pwdata, pwdata_len);
778 OPENSSL_cleanse(key, key_len);
780 if (fd_tmp != -1) {
781 close(fd_tmp);
782 }
784 if (fp_tmp != NULL) {
785 fclose(fp_tmp);
786 }
788 if (bio_in != NULL) {
789 BIO_free_all(bio_in);
790 }
792 if (bio_out != NULL) {
793 BIO_free_all(bio_out);
795 if (status == 0) {
796 if (need_tmpfile) {
797 if (rename(tmp_filename, out_filename) == -1) {
798 warn("could not create output file");
799 status = EXIT_FAILURE;
800 unlink(tmp_filename);
801 }
802 }
803 } else {
804 if (need_tmpfile) {
805 unlink(tmp_filename);
806 } else if (oflag) {
807 unlink(out_filename);
808 }
809 }
810 }
812 free(out_filename_tmp);
813 free(tmp_filename);
815 #if OPENSSL_VERSION_NUMBER < 0x10100000L
816 EVP_cleanup();
817 ERR_free_strings();
818 CONF_modules_free();
819 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
821 exit(status);
822 }