hammer2 - Fix flush issues with unmounted PFSs and shutdown panic
[dragonfly.git] / lib / libtcplay / tcplay.c
blobcd882cf19e8851de748d0c4a4f4c01db3543765e
1 /*
2 * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
30 #define _BSD_SOURCE
31 #include <sys/types.h>
32 #include <sys/stat.h>
34 #if defined(__DragonFly__)
35 #include <sys/param.h>
36 #endif
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <stdarg.h>
41 #include <inttypes.h>
42 #include <unistd.h>
43 #include <errno.h>
44 #include <string.h>
45 #include <err.h>
46 #include <time.h>
47 #if defined(__linux__)
48 #include <libdevmapper.h>
49 #include <uuid/uuid.h>
50 #elif defined(__DragonFly__)
51 #include <libdm.h>
52 #include <uuid.h>
53 #endif
55 #include <dirent.h>
57 #include "crc32.h"
58 #include "tcplay.h"
59 #include "humanize.h"
62 /* XXX TODO:
63 * - LRW-benbi support? needs further work in dm-crypt and even opencrypto
64 * - secure buffer review (i.e: is everything that needs it using secure mem?)
65 * - mlockall? (at least MCL_FUTURE, which is the only one we support)
68 summary_fn_t summary_fn = NULL;
69 int tc_internal_verbose = 1;
70 char tc_internal_log_buffer[LOG_BUFFER_SZ];
71 int tc_internal_state = STATE_UNKNOWN;
73 void
74 tc_log(int is_err, const char *fmt, ...)
76 va_list ap;
77 FILE *fp;
79 if (is_err)
80 fp = stderr;
81 else
82 fp = stdout;
84 va_start(ap, fmt);
86 vsnprintf(tc_internal_log_buffer, LOG_BUFFER_SZ, fmt, ap);
88 va_end(ap);
90 if (tc_internal_verbose)
91 fprintf(fp, "%s", tc_internal_log_buffer);
94 /* Supported algorithms */
95 struct pbkdf_prf_algo pbkdf_prf_algos[] = {
96 { "RIPEMD160", 2000 }, /* needs to come before the other RIPEMD160 */
97 { "RIPEMD160", 1000 },
98 { "SHA512", 1000 },
99 { "whirlpool", 1000 },
100 { NULL, 0 }
103 struct tc_crypto_algo tc_crypto_algos[] = {
104 #if 0
105 /* XXX: turns out TC doesn't support AES-128-XTS */
106 { "AES-128-XTS", "aes-xts-plain", 32, 8 },
107 { "TWOFISH-128-XTS", "twofish-xts-plain", 32, 8 },
108 { "SERPENT-128-XTS", "serpent-xts-plain", 32, 8 },
109 #endif
110 { "AES-256-XTS", "aes-xts-plain64", 64, 8 },
111 { "TWOFISH-256-XTS", "twofish-xts-plain64", 64, 8 },
112 { "SERPENT-256-XTS", "serpent-xts-plain64", 64, 8 },
113 { NULL, NULL, 0, 0 }
116 const char *valid_cipher_chains[][MAX_CIPHER_CHAINS] = {
117 { "AES-256-XTS", NULL },
118 { "TWOFISH-256-XTS", NULL },
119 { "SERPENT-256-XTS", NULL },
120 { "AES-256-XTS", "TWOFISH-256-XTS", "SERPENT-256-XTS", NULL },
121 { "SERPENT-256-XTS", "TWOFISH-256-XTS", "AES-256-XTS", NULL },
122 #if 0
123 /* It seems that all the two-way cascades are the other way round... */
124 { "AES-256-XTS", "TWOFISH-256-XTS", NULL },
125 { "SERPENT-256-XTS", "AES-256-XTS", NULL },
126 { "TWOFISH-256-XTS", "SERPENT-256-XTS", NULL },
128 #endif
129 { "TWOFISH-256-XTS", "AES-256-XTS", NULL },
130 { "AES-256-XTS", "SERPENT-256-XTS", NULL },
131 { "SERPENT-256-XTS", "TWOFISH-256-XTS", NULL },
132 { NULL }
135 struct tc_cipher_chain *tc_cipher_chains[MAX_CIPHER_CHAINS];
137 static
139 tc_build_cipher_chains(void)
141 struct tc_cipher_chain *chain, *elem, *prev;
142 int i = 0;
143 int k;
145 while (valid_cipher_chains[i][0] != NULL) {
146 chain = NULL;
147 prev = NULL;
148 k = 0;
150 while (valid_cipher_chains[i][k] != NULL) {
151 if ((elem = alloc_safe_mem(sizeof(*elem))) == NULL) {
152 tc_log(1, "Error allocating memory for "
153 "cipher chain\n");
154 return -1;
157 /* Initialize first element of chain */
158 if (chain == NULL) {
159 chain = elem;
160 elem->prev = NULL;
163 /* Populate previous element */
164 if (prev != NULL) {
165 prev->next = elem;
166 elem->prev = prev;
169 /* Assume we are the last element in the chain */
170 elem->next = NULL;
172 /* Initialize other fields */
173 elem->cipher = check_cipher(valid_cipher_chains[i][k], 0);
174 if (elem->cipher == NULL)
175 return -1;
177 elem->key = NULL;
179 prev = elem;
180 ++k;
183 /* Store cipher chain */
184 tc_cipher_chains[i++] = chain;
186 /* Integrity check */
187 if (i >= MAX_CIPHER_CHAINS) {
188 tc_log(1, "FATAL: tc_cipher_chains is full!!\n");
189 return -1;
192 /* Make sure array is NULL terminated */
193 tc_cipher_chains[i] = NULL;
196 return 0;
199 static
200 struct tc_cipher_chain *
201 tc_dup_cipher_chain(struct tc_cipher_chain *src)
203 struct tc_cipher_chain *first = NULL, *prev = NULL, *elem;
205 for (; src != NULL; src = src->next) {
206 if ((elem = alloc_safe_mem(sizeof(*elem))) == NULL) {
207 tc_log(1, "Error allocating memory for "
208 "duplicate cipher chain\n");
209 return NULL;
212 memcpy(elem, src, sizeof(*elem));
214 if (src->key != NULL) {
215 if ((elem->key = alloc_safe_mem(src->cipher->klen)) == NULL) {
216 tc_log(1, "Error allocating memory for "
217 "duplicate key in cipher chain\n");
218 return NULL;
221 memcpy(elem->key, src->key, src->cipher->klen);
224 if (first == NULL)
225 first = elem;
227 elem->next = NULL;
228 elem->prev = prev;
230 if (prev != NULL)
231 prev->next = elem;
233 prev = elem;
236 return first;
239 static
241 tc_free_cipher_chain(struct tc_cipher_chain *chain)
243 struct tc_cipher_chain *next = chain;
245 while ((chain = next) != NULL) {
246 next = chain->next;
248 if (chain->key != NULL)
249 free_safe_mem(chain->key);
250 free_safe_mem(chain);
253 return 0;
257 tc_cipher_chain_length(struct tc_cipher_chain *chain)
259 int len = 0;
261 for (; chain != NULL; chain = chain->next)
262 ++len;
264 return len;
268 tc_cipher_chain_klen(struct tc_cipher_chain *chain)
270 int klen_bytes = 0;
272 for (; chain != NULL; chain = chain->next) {
273 klen_bytes += chain->cipher->klen;
276 return klen_bytes;
279 char *
280 tc_cipher_chain_sprint(char *buf, size_t bufsz, struct tc_cipher_chain *chain)
282 static char sbuf[256];
283 int n = 0;
285 if (buf == NULL) {
286 buf = sbuf;
287 bufsz = sizeof(sbuf);
290 for (; chain != NULL; chain = chain->next) {
291 n += snprintf(buf+n, bufsz-n, "%s%s", chain->cipher->name,
292 (chain->next != NULL) ? "," : "\0");
295 return buf;
298 #ifdef DEBUG
299 static void
300 print_hex(unsigned char *buf, off_t start, size_t len)
302 size_t i;
304 for (i = start; i < start+len; i++)
305 printf("%02x", buf[i]);
307 printf("\n");
309 #endif
311 void
312 print_info(struct tcplay_info *info)
314 printf("Device:\t\t\t%s\n", info->dev);
316 if (info->pbkdf_prf != NULL) {
317 printf("PBKDF2 PRF:\t\t%s\n", info->pbkdf_prf->name);
318 printf("PBKDF2 iterations:\t%d\n",
319 info->pbkdf_prf->iteration_count);
322 printf("Cipher:\t\t\t%s\n",
323 tc_cipher_chain_sprint(NULL, 0, info->cipher_chain));
325 printf("Key Length:\t\t%d bits\n",
326 8*tc_cipher_chain_klen(info->cipher_chain));
328 if (info->hdr != NULL) {
329 printf("CRC Key Data:\t\t%#x\n", info->hdr->crc_keys);
330 printf("Sector size:\t\t%d\n", info->hdr->sec_sz);
331 } else {
332 printf("Sector size:\t\t512\n");
334 printf("Volume size:\t\t%"DISKSZ_FMT" sectors\n", info->size);
335 #if 0
336 /* Don't print this; it's always 0 and is rather confusing */
337 printf("Volume offset:\t\t%"PRIu64"\n", (uint64_t)info->start);
338 #endif
340 #ifdef DEBUG
341 printf("Vol Flags:\t\t%d\n", info->volflags);
342 #endif
344 printf("IV offset:\t\t%"PRIu64" sectors\n",
345 (uint64_t)info->skip);
346 printf("Block offset:\t\t%"PRIu64" sectors\n",
347 (uint64_t)info->offset);
350 static
351 struct tcplay_info *
352 new_info(const char *dev, int flags, struct tc_cipher_chain *cipher_chain,
353 struct pbkdf_prf_algo *prf, struct tchdr_dec *hdr, off_t start)
355 struct tc_cipher_chain *chain_start;
356 struct tcplay_info *info;
357 int i;
358 int error;
360 chain_start = cipher_chain;
362 if ((info = (struct tcplay_info *)alloc_safe_mem(sizeof(*info))) == NULL) {
363 tc_log(1, "could not allocate safe info memory\n");
364 return NULL;
367 strncpy(info->dev, dev, sizeof(info->dev));
368 info->cipher_chain = cipher_chain;
369 info->pbkdf_prf = prf;
370 info->start = start;
371 info->hdr = hdr;
372 info->blk_sz = hdr->sec_sz;
373 info->size = hdr->sz_mk_scope / hdr->sec_sz; /* volume size */
374 info->skip = hdr->off_mk_scope / hdr->sec_sz; /* iv skip */
376 info->volflags = hdr->flags;
377 info->flags = flags;
379 if (TC_FLAG_SET(flags, SYS))
380 info->offset = 0; /* offset is 0 for system volumes */
381 else
382 info->offset = hdr->off_mk_scope / hdr->sec_sz; /* block offset */
384 /* Associate a key out of the key pool with each cipher in the chain */
385 error = tc_cipher_chain_populate_keys(cipher_chain, hdr->keys);
386 if (error) {
387 tc_log(1, "could not populate keys in cipher chain\n");
388 return NULL;
391 for (; cipher_chain != NULL; cipher_chain = cipher_chain->next) {
392 for (i = 0; i < cipher_chain->cipher->klen; i++)
393 sprintf(&cipher_chain->dm_key[i*2], "%02x",
394 cipher_chain->key[i]);
397 tc_cipher_chain_free_keys(chain_start);
399 return info;
403 free_info(struct tcplay_info *info)
405 if (info->cipher_chain)
406 tc_free_cipher_chain(info->cipher_chain);
407 if (info->hdr)
408 free_safe_mem(info->hdr);
410 free_safe_mem(info);
412 return 0;
416 adjust_info(struct tcplay_info *info, struct tcplay_info *hinfo)
418 if (hinfo->hdr->sz_hidvol == 0)
419 return 1;
421 info->size -= hinfo->hdr->sz_hidvol / hinfo->hdr->sec_sz;
422 return 0;
426 process_hdr(const char *dev, int flags, unsigned char *pass, int passlen,
427 struct tchdr_enc *ehdr, struct tcplay_info **pinfo)
429 struct tchdr_dec *dhdr;
430 struct tcplay_info *info;
431 struct tc_cipher_chain *cipher_chain = NULL;
432 unsigned char *key;
433 int i, j, found, error;
435 *pinfo = NULL;
437 if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
438 tc_log(1, "could not allocate safe key memory\n");
439 return ENOMEM;
442 /* Start search for correct algorithm combination */
443 found = 0;
444 for (i = 0; !found && pbkdf_prf_algos[i].name != NULL; i++) {
445 #ifdef DEBUG
446 printf("\nTrying PRF algo %s (%d)\n", pbkdf_prf_algos[i].name,
447 pbkdf_prf_algos[i].iteration_count);
448 printf("Salt: ");
449 print_hex(ehdr->salt, 0, sizeof(ehdr->salt));
450 #endif
451 error = pbkdf2(&pbkdf_prf_algos[i], (char *)pass, passlen,
452 ehdr->salt, sizeof(ehdr->salt),
453 MAX_KEYSZ, key);
455 if (error) {
456 tc_log(1, "pbkdf failed for algorithm %s\n",
457 pbkdf_prf_algos[i].name);
458 free_safe_mem(key);
459 return EINVAL;
462 #if 0
463 printf("Derived Key: ");
464 print_hex(key, 0, MAX_KEYSZ);
465 #endif
467 for (j = 0; !found && tc_cipher_chains[j] != NULL; j++) {
468 cipher_chain = tc_dup_cipher_chain(tc_cipher_chains[j]);
469 #ifdef DEBUG
470 printf("\nTrying cipher chain %d\n", j);
471 #endif
473 dhdr = decrypt_hdr(ehdr, cipher_chain, key);
474 if (dhdr == NULL) {
475 tc_log(1, "hdr decryption failed for cipher "
476 "chain %d\n", j);
477 free_safe_mem(key);
478 return EINVAL;
481 if (verify_hdr(dhdr)) {
482 #ifdef DEBUG
483 printf("tc_str: %.4s, tc_ver: %d, tc_min_ver: %d, "
484 "crc_keys: %d, sz_vol: %"PRIu64", "
485 "off_mk_scope: %"PRIu64", sz_mk_scope: %"PRIu64", "
486 "flags: %d, sec_sz: %d crc_dhdr: %d\n",
487 dhdr->tc_str, dhdr->tc_ver, dhdr->tc_min_ver,
488 dhdr->crc_keys, dhdr->sz_vol, dhdr->off_mk_scope,
489 dhdr->sz_mk_scope, dhdr->flags, dhdr->sec_sz,
490 dhdr->crc_dhdr);
491 #endif
492 found = 1;
493 } else {
494 free_safe_mem(dhdr);
495 tc_free_cipher_chain(cipher_chain);
500 free_safe_mem(key);
502 if (!found)
503 return EINVAL;
505 if ((info = new_info(dev, flags, cipher_chain,
506 &pbkdf_prf_algos[i-1], dhdr, 0)) == NULL) {
507 free_safe_mem(dhdr);
508 return ENOMEM;
511 *pinfo = info;
513 return 0;
517 create_volume(struct tcplay_opts *opts)
519 char *pass, *pass_again;
520 char *h_pass = NULL;
521 char buf[1024];
522 disksz_t blocks, hidden_blocks = 0;
523 size_t blksz;
524 struct tchdr_enc *ehdr, *hehdr;
525 struct tchdr_enc *ehdr_backup, *hehdr_backup;
526 uint64_t tmp;
527 int error, r, ret;
529 pass = h_pass = pass_again = NULL;
530 ehdr = hehdr = NULL;
531 ehdr_backup = hehdr_backup = NULL;
532 ret = -1; /* Default to returning error */
534 if (opts->cipher_chain == NULL)
535 opts->cipher_chain = tc_cipher_chains[0];
536 if (opts->prf_algo == NULL)
537 opts->prf_algo = &pbkdf_prf_algos[0];
538 if (opts->h_cipher_chain == NULL)
539 opts->h_cipher_chain = opts->cipher_chain;
540 if (opts->h_prf_algo == NULL)
541 opts->h_prf_algo = opts->prf_algo;
543 if ((error = get_disk_info(opts->dev, &blocks, &blksz)) != 0) {
544 tc_log(1, "could not get disk info\n");
545 return -1;
548 if ((blocks*blksz) <= MIN_VOL_BYTES) {
549 tc_log(1, "Cannot create volumes on devices with less "
550 "than %d bytes\n", MIN_VOL_BYTES);
551 return -1;
554 if (opts->interactive) {
555 if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
556 ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
557 tc_log(1, "could not allocate safe passphrase memory\n");
558 goto out;
561 if ((error = read_passphrase("Passphrase: ", pass, MAX_PASSSZ,
562 PASS_BUFSZ, 0) ||
563 (read_passphrase("Repeat passphrase: ", pass_again,
564 MAX_PASSSZ, PASS_BUFSZ, 0)))) {
565 tc_log(1, "could not read passphrase\n");
566 goto out;
569 if (strcmp(pass, pass_again) != 0) {
570 tc_log(1, "Passphrases don't match\n");
571 goto out;
574 free_safe_mem(pass_again);
575 pass_again = NULL;
576 } else {
577 /* In batch mode, use provided passphrase */
578 if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
579 tc_log(1, "could not allocate safe "
580 "passphrase memory");
581 goto out;
584 if (opts->passphrase != NULL) {
585 strncpy(pass, opts->passphrase, MAX_PASSSZ);
586 pass[MAX_PASSSZ] = '\0';
590 if (opts->nkeyfiles > 0) {
591 /* Apply keyfiles to 'pass' */
592 if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
593 opts->keyfiles, opts->nkeyfiles))) {
594 tc_log(1, "could not apply keyfiles\n");
595 goto out;
599 if (opts->hidden) {
600 if (opts->interactive) {
601 if (((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
602 ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
603 tc_log(1, "could not allocate safe "
604 "passphrase memory\n");
605 goto out;
608 if ((error = read_passphrase("Passphrase for hidden volume: ",
609 h_pass, MAX_PASSSZ, PASS_BUFSZ, 0) ||
610 (read_passphrase("Repeat passphrase: ", pass_again,
611 MAX_PASSSZ, PASS_BUFSZ, 0)))) {
612 tc_log(1, "could not read passphrase\n");
613 goto out;
616 if (strcmp(h_pass, pass_again) != 0) {
617 tc_log(1, "Passphrases for hidden volume don't "
618 "match\n");
619 goto out;
622 free_safe_mem(pass_again);
623 pass_again = NULL;
624 } else {
625 /* In batch mode, use provided passphrase */
626 if ((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
627 tc_log(1, "could not allocate safe "
628 "passphrase memory");
629 goto out;
632 if (opts->h_passphrase != NULL) {
633 strncpy(h_pass, opts->h_passphrase, MAX_PASSSZ);
634 h_pass[MAX_PASSSZ] = '\0';
638 if (opts->n_hkeyfiles > 0) {
639 /* Apply keyfiles to 'h_pass' */
640 if ((error = apply_keyfiles((unsigned char *)h_pass,
641 PASS_BUFSZ, opts->h_keyfiles, opts->n_hkeyfiles))) {
642 tc_log(1, "could not apply keyfiles\n");
643 goto out;
647 if (opts->interactive) {
648 hidden_blocks = 0;
649 } else {
650 hidden_blocks = opts->hidden_size_bytes/blksz;
651 if (hidden_blocks == 0) {
652 tc_log(1, "hidden_blocks to create volume "
653 "cannot be zero!\n");
654 goto out;
657 if (opts->hidden_size_bytes >=
658 (blocks*blksz) - MIN_VOL_BYTES) {
659 tc_log(1, "Hidden volume needs to be "
660 "smaller than the outer volume\n");
661 goto out;
665 /* This only happens in interactive mode */
666 while (hidden_blocks == 0) {
667 if ((r = _humanize_number(buf, sizeof(buf),
668 (uint64_t)(blocks * blksz))) < 0) {
669 sprintf(buf, "%"DISKSZ_FMT" bytes", (blocks * blksz));
672 printf("The total volume size of %s is %s (bytes)\n", opts->dev, buf);
673 memset(buf, 0, sizeof(buf));
674 printf("Size of hidden volume (e.g. 127M): ");
675 fflush(stdout);
677 if ((fgets(buf, sizeof(buf), stdin)) == NULL) {
678 tc_log(1, "Could not read from stdin\n");
679 goto out;
682 /* get rid of trailing newline */
683 buf[strlen(buf)-1] = '\0';
684 if ((error = _dehumanize_number(buf,
685 &tmp)) != 0) {
686 tc_log(1, "Could not interpret input: %s\n", buf);
687 continue;
690 if (tmp >= (blocks*blksz) - MIN_VOL_BYTES) {
691 tc_log(1, "Hidden volume needs to be "
692 "smaller than the outer volume\n");
693 hidden_blocks = 0;
694 continue;
697 hidden_blocks = (size_t)tmp;
698 hidden_blocks /= blksz;
702 if (opts->interactive) {
703 /* Show summary and ask for confirmation */
704 printf("Summary of actions:\n");
705 if (opts->secure_erase)
706 printf(" - Completely erase *EVERYTHING* on %s\n", opts->dev);
707 printf(" - Create %svolume on %s\n", opts->hidden?("outer "):"", opts->dev);
708 if (opts->hidden) {
709 printf(" - Create hidden volume of %"DISKSZ_FMT" bytes at end of "
710 "outer volume\n",
711 hidden_blocks * blksz);
714 printf("\n Are you sure you want to proceed? (y/n) ");
715 fflush(stdout);
716 if ((fgets(buf, sizeof(buf), stdin)) == NULL) {
717 tc_log(1, "Could not read from stdin\n");
718 goto out;
721 if ((buf[0] != 'y') && (buf[0] != 'Y')) {
722 tc_log(1, "User cancelled action(s)\n");
723 goto out;
727 /* erase volume */
728 if (opts->secure_erase) {
729 tc_log(0, "Securely erasing the volume...\nThis process may take "
730 "some time depending on the size of the volume\n");
732 if (opts->state_change_fn)
733 opts->state_change_fn(opts->api_ctx, "secure_erase", 1);
735 if ((error = secure_erase(opts->dev, blocks * blksz, blksz)) != 0) {
736 tc_log(1, "could not securely erase device %s\n", opts->dev);
737 goto out;
740 if (opts->state_change_fn)
741 opts->state_change_fn(opts->api_ctx, "secure_erase", 0);
744 tc_log(0, "Creating volume headers...\nDepending on your system, this "
745 "process may take a few minutes as it uses true random data which "
746 "might take a while to refill\n");
748 if (opts->weak_keys_and_salt) {
749 tc_log(0, "WARNING: Using a weak random generator to get "
750 "entropy for the key material. Odds are this is NOT "
751 "what you want.\n");
754 if (opts->state_change_fn)
755 opts->state_change_fn(opts->api_ctx, "create_header", 1);
757 /* create encrypted headers */
758 ehdr = create_hdr((unsigned char *)pass,
759 (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
760 opts->prf_algo, opts->cipher_chain, blksz, blocks, VOL_RSVD_BYTES_START/blksz,
761 blocks - (MIN_VOL_BYTES/blksz), 0, opts->weak_keys_and_salt, &ehdr_backup);
762 if (ehdr == NULL) {
763 tc_log(1, "Could not create header\n");
764 goto out;
767 if (opts->hidden) {
768 hehdr = create_hdr((unsigned char *)h_pass,
769 (opts->n_hkeyfiles > 0)?MAX_PASSSZ:strlen(h_pass), opts->h_prf_algo,
770 opts->h_cipher_chain,
771 blksz, blocks,
772 blocks - (VOL_RSVD_BYTES_END/blksz) - hidden_blocks,
773 hidden_blocks, 1, opts->weak_keys_and_salt, &hehdr_backup);
774 if (hehdr == NULL) {
775 tc_log(1, "Could not create hidden volume header\n");
776 goto out;
780 if (opts->state_change_fn)
781 opts->state_change_fn(opts->api_ctx, "create_header", 0);
783 tc_log(0, "Writing volume headers to disk...\n");
785 if ((error = write_to_disk(opts->dev, 0, blksz, ehdr, sizeof(*ehdr))) != 0) {
786 tc_log(1, "Could not write volume header to device\n");
787 goto out;
790 /* Write backup header; it's offset is relative to the end */
791 if ((error = write_to_disk(opts->dev, (blocks*blksz - BACKUP_HDR_OFFSET_END),
792 blksz, ehdr_backup, sizeof(*ehdr_backup))) != 0) {
793 tc_log(1, "Could not write backup volume header to device\n");
794 goto out;
797 if (opts->hidden) {
798 if ((error = write_to_disk(opts->dev, HDR_OFFSET_HIDDEN, blksz, hehdr,
799 sizeof(*hehdr))) != 0) {
800 tc_log(1, "Could not write hidden volume header to "
801 "device\n");
802 goto out;
805 /* Write backup hidden header; offset is relative to end */
806 if ((error = write_to_disk(opts->dev,
807 (blocks*blksz - BACKUP_HDR_HIDDEN_OFFSET_END), blksz,
808 hehdr_backup, sizeof(*hehdr_backup))) != 0) {
809 tc_log(1, "Could not write backup hidden volume "
810 "header to device\n");
811 goto out;
815 /* Everything went ok */
816 tc_log(0, "All done!\n");
818 ret = 0;
820 out:
821 if (pass)
822 free_safe_mem(pass);
823 if (h_pass)
824 free_safe_mem(h_pass);
825 if (pass_again)
826 free_safe_mem(pass_again);
827 if (ehdr)
828 free_safe_mem(ehdr);
829 if (hehdr)
830 free_safe_mem(hehdr);
831 if (ehdr_backup)
832 free_safe_mem(ehdr_backup);
833 if (hehdr_backup)
834 free_safe_mem(hehdr_backup);
836 return ret;
839 struct tcplay_info *
840 info_map_common(struct tcplay_opts *opts, char *passphrase_out)
842 struct tchdr_enc *ehdr, *hehdr = NULL;
843 struct tcplay_info *info, *hinfo = NULL;
844 char *pass;
845 char *h_pass;
846 int error, error2 = 0;
847 size_t sz;
848 size_t blksz;
849 disksz_t blocks;
850 int is_hidden = 0;
851 int try_empty = 0;
852 int retries;
854 if ((error = get_disk_info(opts->dev, &blocks, &blksz)) != 0) {
855 tc_log(1, "could not get disk information\n");
856 return NULL;
859 if (opts->retries < 1)
860 retries = 1;
861 else
862 retries = opts->retries;
865 * Add one retry so we can do a first try without asking for
866 * a password if keyfiles are passed in.
868 if (opts->interactive && (opts->nkeyfiles > 0)) {
869 try_empty = 1;
870 ++retries;
873 info = NULL;
875 ehdr = NULL;
876 pass = h_pass = NULL;
878 while ((info == NULL) && retries-- > 0)
880 pass = h_pass = NULL;
881 ehdr = hehdr = NULL;
882 info = hinfo = NULL;
884 if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
885 tc_log(1, "could not allocate safe passphrase memory\n");
886 goto out;
889 if (try_empty) {
890 pass[0] = '\0';
891 } else if (opts->interactive) {
892 if ((error = read_passphrase("Passphrase: ", pass,
893 MAX_PASSSZ, PASS_BUFSZ, opts->timeout))) {
894 tc_log(1, "could not read passphrase\n");
895 /* XXX: handle timeout differently? */
896 goto out;
898 pass[MAX_PASSSZ] = '\0';
899 } else {
900 /* In batch mode, use provided passphrase */
901 if (opts->passphrase != NULL) {
902 strncpy(pass, opts->passphrase, MAX_PASSSZ);
903 pass[MAX_PASSSZ] = '\0';
907 if (passphrase_out != NULL) {
908 strcpy(passphrase_out, pass);
911 if (opts->nkeyfiles > 0) {
912 /* Apply keyfiles to 'pass' */
913 if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
914 opts->keyfiles, opts->nkeyfiles))) {
915 tc_log(1, "could not apply keyfiles");
916 goto out;
920 if (opts->protect_hidden) {
921 if ((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
922 tc_log(1, "could not allocate safe passphrase memory\n");
923 goto out;
926 if (opts->interactive) {
927 if ((error = read_passphrase(
928 "Passphrase for hidden volume: ", h_pass,
929 MAX_PASSSZ, PASS_BUFSZ, opts->timeout))) {
930 tc_log(1, "could not read passphrase\n");
931 goto out;
933 h_pass[MAX_PASSSZ] = '\0';
934 } else {
935 /* In batch mode, use provided passphrase */
936 if (opts->h_passphrase != NULL) {
937 strncpy(h_pass, opts->h_passphrase, MAX_PASSSZ);
938 h_pass[MAX_PASSSZ] = '\0';
942 if (opts->n_hkeyfiles > 0) {
943 /* Apply keyfiles to 'pass' */
944 if ((error = apply_keyfiles((unsigned char *)h_pass, PASS_BUFSZ,
945 opts->h_keyfiles, opts->n_hkeyfiles))) {
946 tc_log(1, "could not apply keyfiles");
947 goto out;
952 /* Always read blksz-sized chunks */
953 sz = blksz;
955 if (TC_FLAG_SET(opts->flags, HDR_FROM_FILE)) {
956 ehdr = (struct tchdr_enc *)read_to_safe_mem(
957 opts->hdr_file_in, 0, &sz);
958 if (ehdr == NULL) {
959 tc_log(1, "error read hdr_enc: %s", opts->hdr_file_in);
960 goto out;
962 } else {
963 ehdr = (struct tchdr_enc *)read_to_safe_mem(
964 (TC_FLAG_SET(opts->flags, SYS)) ? opts->sys_dev : opts->dev,
965 (TC_FLAG_SET(opts->flags, SYS) || TC_FLAG_SET(opts->flags, FDE)) ?
966 HDR_OFFSET_SYS :
967 (!TC_FLAG_SET(opts->flags, BACKUP)) ? 0 : -BACKUP_HDR_OFFSET_END,
968 &sz);
969 if (ehdr == NULL) {
970 tc_log(1, "error read hdr_enc: %s", opts->dev);
971 goto out;
975 if (!TC_FLAG_SET(opts->flags, SYS)) {
976 /* Always read blksz-sized chunks */
977 sz = blksz;
979 if (TC_FLAG_SET(opts->flags, H_HDR_FROM_FILE)) {
980 hehdr = (struct tchdr_enc *)read_to_safe_mem(
981 opts->h_hdr_file_in, 0, &sz);
982 if (hehdr == NULL) {
983 tc_log(1, "error read hdr_enc: %s", opts->h_hdr_file_in);
984 goto out;
986 } else {
987 hehdr = (struct tchdr_enc *)read_to_safe_mem(opts->dev,
988 (!TC_FLAG_SET(opts->flags, BACKUP)) ? HDR_OFFSET_HIDDEN :
989 -BACKUP_HDR_HIDDEN_OFFSET_END, &sz);
990 if (hehdr == NULL) {
991 tc_log(1, "error read hdr_enc: %s", opts->dev);
992 goto out;
995 } else {
996 hehdr = NULL;
999 error = process_hdr(opts->dev, opts->flags, (unsigned char *)pass,
1000 (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
1001 ehdr, &info);
1004 * Try to process hidden header if we have to protect the hidden
1005 * volume, or the decryption/verification of the main header
1006 * failed.
1008 if (hehdr && (error || opts->protect_hidden)) {
1009 if (error) {
1010 error2 = process_hdr(opts->dev, opts->flags, (unsigned char *)pass,
1011 (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass), hehdr,
1012 &info);
1013 is_hidden = !error2;
1014 } else if (opts->protect_hidden) {
1015 error2 = process_hdr(opts->dev, opts->flags, (unsigned char *)h_pass,
1016 (opts->n_hkeyfiles > 0)?MAX_PASSSZ:strlen(h_pass), hehdr,
1017 &hinfo);
1021 /* We need both to protect a hidden volume */
1022 if ((opts->protect_hidden && (error || error2)) ||
1023 (error && error2)) {
1024 if (!try_empty)
1025 tc_log(1, "Incorrect password or not a TrueCrypt volume\n");
1027 if (info) {
1028 free_info(info);
1029 info = NULL;
1031 if (hinfo) {
1032 free_info(hinfo);
1033 hinfo = NULL;
1036 /* Try again (or finish) */
1037 free_safe_mem(pass);
1038 pass = NULL;
1040 if (h_pass) {
1041 free_safe_mem(h_pass);
1042 h_pass = NULL;
1044 if (ehdr) {
1045 free_safe_mem(ehdr);
1046 ehdr = NULL;
1048 if (hehdr) {
1049 free_safe_mem(hehdr);
1050 hehdr = NULL;
1053 try_empty = 0;
1054 continue;
1057 if (opts->protect_hidden) {
1058 if (adjust_info(info, hinfo) != 0) {
1059 tc_log(1, "Could not protect hidden volume\n");
1060 if (info)
1061 free_info(info);
1062 info = NULL;
1064 if (hinfo)
1065 free_info(hinfo);
1066 hinfo = NULL;
1068 goto out;
1071 if (hinfo) {
1072 free_info(hinfo);
1073 hinfo = NULL;
1076 try_empty = 0;
1079 out:
1080 if (hinfo)
1081 free_info(hinfo);
1082 if (pass)
1083 free_safe_mem(pass);
1084 if (h_pass)
1085 free_safe_mem(h_pass);
1086 if (ehdr)
1087 free_safe_mem(ehdr);
1088 if (hehdr)
1089 free_safe_mem(hehdr);
1091 if (info != NULL)
1092 info->hidden = is_hidden;
1094 return info;
1098 info_mapped_volume(struct tcplay_opts *opts)
1100 struct tcplay_info *info;
1102 info = dm_info_map(opts->map_name);
1103 if (info != NULL) {
1104 if (opts->interactive)
1105 print_info(info);
1107 free_info(info);
1109 return 0;
1110 /* NOT REACHED */
1111 } else if (opts->interactive) {
1112 tc_log(1, "Could not retrieve information about mapped "
1113 "volume %s. Does it exist?\n", opts->map_name);
1116 return -1;
1120 info_volume(struct tcplay_opts *opts)
1122 struct tcplay_info *info;
1124 info = info_map_common(opts, NULL);
1126 if (info != NULL) {
1127 if (opts->interactive)
1128 print_info(info);
1130 free_info(info);
1132 return 0;
1133 /* NOT REACHED */
1136 return -1;
1140 map_volume(struct tcplay_opts *opts)
1142 struct tcplay_info *info;
1143 int error;
1145 info = info_map_common(opts, NULL);
1147 if (info == NULL)
1148 return -1;
1150 if ((error = dm_setup(opts->map_name, info)) != 0) {
1151 tc_log(1, "Could not set up mapping %s\n", opts->map_name);
1152 free_info(info);
1153 return -1;
1156 if (opts->interactive)
1157 printf("All ok!\n");
1159 free_info(info);
1161 return 0;
1165 modify_volume(struct tcplay_opts *opts)
1167 struct tcplay_info *info;
1168 struct tchdr_enc *ehdr, *ehdr_backup;
1169 const char *new_passphrase = opts->new_passphrase;
1170 const char **new_keyfiles = opts->new_keyfiles;
1171 struct pbkdf_prf_algo *new_prf_algo = opts->new_prf_algo;
1172 int n_newkeyfiles = opts->n_newkeyfiles;
1173 char *pass, *pass_again;
1174 int ret = -1;
1175 off_t offset, offset_backup = 0;
1176 const char *dev;
1177 size_t blksz;
1178 disksz_t blocks;
1179 int error;
1181 ehdr = ehdr_backup = NULL;
1182 pass = pass_again = NULL;
1183 info = NULL;
1185 if (TC_FLAG_SET(opts->flags, ONLY_RESTORE)) {
1186 if (opts->interactive) {
1187 if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
1188 tc_log(1, "could not allocate safe "
1189 "passphrase memory");
1190 goto out;
1192 } else {
1193 new_passphrase = opts->passphrase;
1195 new_keyfiles = opts->keyfiles;
1196 n_newkeyfiles = opts->nkeyfiles;
1197 new_prf_algo = NULL;
1200 info = info_map_common(opts, pass);
1201 if (info == NULL)
1202 goto out;
1204 if (opts->interactive && !TC_FLAG_SET(opts->flags, ONLY_RESTORE)) {
1205 if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
1206 ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
1207 tc_log(1, "could not allocate safe passphrase memory\n");
1208 goto out;
1211 if ((error = read_passphrase("New passphrase: ", pass, MAX_PASSSZ,
1212 PASS_BUFSZ, 0) ||
1213 (read_passphrase("Repeat passphrase: ", pass_again,
1214 MAX_PASSSZ, PASS_BUFSZ, 0)))) {
1215 tc_log(1, "could not read passphrase\n");
1216 goto out;
1219 if (strcmp(pass, pass_again) != 0) {
1220 tc_log(1, "Passphrases don't match\n");
1221 goto out;
1224 free_safe_mem(pass_again);
1225 pass_again = NULL;
1226 } else if (!opts->interactive) {
1227 /* In batch mode, use provided passphrase */
1228 if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
1229 tc_log(1, "could not allocate safe "
1230 "passphrase memory");
1231 goto out;
1234 if (new_passphrase != NULL) {
1235 strncpy(pass, new_passphrase, MAX_PASSSZ);
1236 pass[MAX_PASSSZ] = '\0';
1240 if (n_newkeyfiles > 0) {
1241 /* Apply keyfiles to 'pass' */
1242 if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
1243 new_keyfiles, n_newkeyfiles))) {
1244 tc_log(1, "could not apply keyfiles\n");
1245 goto out;
1249 ehdr = copy_reencrypt_hdr((unsigned char *)pass,
1250 (opts->n_newkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
1251 new_prf_algo, opts->weak_keys_and_salt, info, &ehdr_backup);
1252 if (ehdr == NULL) {
1253 tc_log(1, "Could not create header\n");
1254 goto out;
1257 dev = (TC_FLAG_SET(opts->flags, SYS)) ? opts->sys_dev : opts->dev;
1258 if (TC_FLAG_SET(opts->flags, SYS) || TC_FLAG_SET(opts->flags, FDE)) {
1259 /* SYS and FDE don't have backup headers (as far as I understand) */
1260 if (info->hidden) {
1261 offset = HDR_OFFSET_HIDDEN;
1262 } else {
1263 offset = HDR_OFFSET_SYS;
1265 } else {
1266 if (info->hidden) {
1267 offset = HDR_OFFSET_HIDDEN;
1268 offset_backup = -BACKUP_HDR_HIDDEN_OFFSET_END;
1269 } else {
1270 offset = 0;
1271 offset_backup = -BACKUP_HDR_OFFSET_END;
1275 if ((error = get_disk_info(dev, &blocks, &blksz)) != 0) {
1276 tc_log(1, "could not get disk information\n");
1277 goto out;
1280 tc_log(0, "Writing new volume headers to disk/file...\n");
1282 if (TC_FLAG_SET(opts->flags, SAVE_TO_FILE)) {
1283 if ((error = write_to_file(opts->hdr_file_out, ehdr, sizeof(*ehdr))) != 0) {
1284 tc_log(1, "Could not write volume header to file\n");
1285 goto out;
1287 } else {
1288 if ((error = write_to_disk(dev, offset, blksz, ehdr,
1289 sizeof(*ehdr))) != 0) {
1290 tc_log(1, "Could not write volume header to device\n");
1291 goto out;
1294 if (!TC_FLAG_SET(opts->flags, SYS) && !TC_FLAG_SET(opts->flags, FDE)) {
1295 if ((error = write_to_disk(dev, offset_backup, blksz,
1296 ehdr_backup, sizeof(*ehdr_backup))) != 0) {
1297 tc_log(1, "Could not write backup volume header to device\n");
1298 goto out;
1303 /* Everything went ok */
1304 tc_log(0, "All done!\n");
1306 ret = 0;
1308 out:
1309 if (pass)
1310 free_safe_mem(pass);
1311 if (pass_again)
1312 free_safe_mem(pass_again);
1313 if (ehdr)
1314 free_safe_mem(ehdr);
1315 if (ehdr_backup)
1316 free_safe_mem(ehdr_backup);
1317 if (info)
1318 free_safe_mem(info);
1320 return ret;
1323 static
1325 dm_get_info(const char *name, struct dm_info *dmi)
1327 struct dm_task *dmt = NULL;
1328 int error = -1;
1330 if ((dmt = dm_task_create(DM_DEVICE_INFO)) == NULL)
1331 goto out;
1333 if ((dm_task_set_name(dmt, name)) == 0)
1334 goto out;
1336 if ((dm_task_run(dmt)) == 0)
1337 goto out;
1339 if ((dm_task_get_info(dmt, dmi)) == 0)
1340 goto out;
1342 error = 0;
1344 out:
1345 if (dmt)
1346 dm_task_destroy(dmt);
1348 return error;
1351 #if defined(__DragonFly__)
1352 static
1354 xlate_maj_min(const char *start_path __unused, int max_depth __unused,
1355 char *buf, size_t bufsz, uint32_t maj, uint32_t min)
1357 dev_t dev = makedev(maj, min);
1359 snprintf(buf, bufsz, "/dev/%s", devname(dev, S_IFCHR));
1360 return 1;
1362 #else
1363 static
1365 xlate_maj_min(const char *start_path, int max_depth, char *buf, size_t bufsz,
1366 uint32_t maj, uint32_t min)
1368 dev_t dev = makedev(maj, min);
1369 char path[PATH_MAX];
1370 struct stat sb;
1371 struct dirent *ent;
1372 DIR *dirp;
1373 int found = 0;
1375 if (max_depth <= 0)
1376 return -1;
1378 if ((dirp = opendir(start_path)) == NULL)
1379 return -1;
1381 while ((ent = readdir(dirp)) != NULL) {
1382 /* d_name, d_type, DT_BLK, DT_CHR, DT_DIR, DT_LNK */
1383 if (ent->d_name[0] == '.')
1384 continue;
1386 /* Linux' /dev is littered with junk, so skip over it */
1388 * The dm-<number> devices seem to be the raw DM devices
1389 * things in mapper/ link to.
1391 if (((strcmp(ent->d_name, "block")) == 0) ||
1392 ((strcmp(ent->d_name, "fd")) == 0) ||
1393 (((strncmp(ent->d_name, "dm-", 3) == 0) && strlen(ent->d_name) <= 5)))
1394 continue;
1396 snprintf(path, PATH_MAX, "%s/%s", start_path, ent->d_name);
1398 if ((stat(path, &sb)) < 0)
1399 continue;
1401 if (S_ISDIR(sb.st_mode)) {
1402 found = !xlate_maj_min(path, max_depth-1, buf, bufsz, maj, min);
1403 if (found)
1404 break;
1407 if (!S_ISBLK(sb.st_mode))
1408 continue;
1410 if (sb.st_rdev != dev)
1411 continue;
1413 snprintf(buf, bufsz, "%s", path);
1414 found = 1;
1415 break;
1418 if (dirp)
1419 closedir(dirp);
1421 return found ? 0 : -ENOENT;
1423 #endif
1425 static
1426 struct tcplay_dm_table *
1427 dm_get_table(const char *name)
1429 struct tcplay_dm_table *tc_table;
1430 struct dm_task *dmt = NULL;
1431 void *next = NULL;
1432 uint64_t start, length;
1433 char *target_type;
1434 char *params;
1435 char *p1;
1436 int c = 0;
1437 uint32_t maj, min;
1439 if ((tc_table = (struct tcplay_dm_table *)alloc_safe_mem(sizeof(*tc_table))) == NULL) {
1440 tc_log(1, "could not allocate safe tc_table memory\n");
1441 return NULL;
1444 if ((dmt = dm_task_create(DM_DEVICE_TABLE)) == NULL)
1445 goto error;
1447 if ((dm_task_set_name(dmt, name)) == 0)
1448 goto error;
1450 if ((dm_task_run(dmt)) == 0)
1451 goto error;
1453 tc_table->start = (off_t)0;
1454 tc_table->size = (size_t)0;
1456 do {
1457 next = dm_get_next_target(dmt, next, &start, &length,
1458 &target_type, &params);
1460 tc_table->size += (size_t)length;
1461 strncpy(tc_table->target, target_type,
1462 sizeof(tc_table->target));
1464 /* Skip any leading whitespace */
1465 while (params && *params == ' ')
1466 params++;
1468 if (strcmp(target_type, "crypt") == 0) {
1469 while ((p1 = strsep(&params, " ")) != NULL) {
1470 /* Skip any whitespace before the next strsep */
1471 while (params && *params == ' ')
1472 params++;
1474 /* Process p1 */
1475 if (c == 0) {
1476 /* cipher */
1477 strncpy(tc_table->cipher, p1,
1478 sizeof(tc_table->cipher));
1479 } else if (c == 2) {
1480 /* iv offset */
1481 tc_table->skip = (off_t)strtoll(p1, NULL, 10);
1482 } else if (c == 3) {
1483 /* major:minor */
1484 maj = strtoul(p1, NULL, 10);
1485 while (*p1 != ':' && *p1 != '\0')
1486 p1++;
1487 min = strtoul(++p1, NULL, 10);
1488 if ((xlate_maj_min("/dev", 2, tc_table->device,
1489 sizeof(tc_table->device), maj, min)) != 0)
1490 snprintf(tc_table->device,
1491 sizeof(tc_table->device),
1492 "%u:%u", maj, min);
1493 } else if (c == 4) {
1494 /* block offset */
1495 tc_table->offset = (off_t)strtoll(p1,
1496 NULL, 10);
1498 ++c;
1501 if (c < 5) {
1502 tc_log(1, "could not get all the info required from "
1503 "the table\n");
1504 goto error;
1507 } while (next != NULL);
1509 if (dmt)
1510 dm_task_destroy(dmt);
1512 #ifdef DEBUG
1513 printf("device: %s\n", tc_table->device);
1514 printf("target: %s\n", tc_table->target);
1515 printf("cipher: %s\n", tc_table->cipher);
1516 printf("size: %ju\n", tc_table->size);
1517 printf("offset: %"PRId64"\n", tc_table->offset);
1518 printf("skip: %"PRId64"\n", tc_table->skip);
1519 #endif
1521 return tc_table;
1523 error:
1524 if (dmt)
1525 dm_task_destroy(dmt);
1526 if (tc_table)
1527 free_safe_mem(tc_table);
1529 return NULL;
1532 struct tcplay_info *
1533 dm_info_map(const char *map_name)
1535 struct dm_task *dmt = NULL;
1536 struct dm_info dmi[3];
1537 struct tcplay_dm_table *dm_table[3];
1538 struct tc_crypto_algo *crypto_algo;
1539 struct tcplay_info *info;
1540 char map[PATH_MAX];
1541 char ciphers[512];
1542 int i, outermost = -1;
1544 memset(dm_table, 0, sizeof(dm_table));
1546 if ((info = (struct tcplay_info *)alloc_safe_mem(sizeof(*info))) == NULL) {
1547 tc_log(1, "could not allocate safe info memory\n");
1548 return NULL;
1551 strncpy(map, map_name, PATH_MAX);
1552 for (i = 0; i < 3; i++) {
1553 if ((dm_get_info(map, &dmi[i])) != 0)
1554 goto error;
1556 if (dmi[i].exists)
1557 dm_table[i] = dm_get_table(map);
1559 snprintf(map, PATH_MAX, "%s.%d", map_name, i);
1562 if (dmt)
1563 dm_task_destroy(dmt);
1565 if (dm_table[0] == NULL)
1566 goto error;
1569 * Process our dmi, dm_table fun into the info structure.
1571 /* First find which cipher chain we are using */
1572 ciphers[0] = '\0';
1573 for (i = 0; i < 3; i++) {
1574 if (dm_table[i] == NULL)
1575 continue;
1577 if (outermost < i)
1578 outermost = i;
1580 crypto_algo = &tc_crypto_algos[0];
1581 while ((crypto_algo != NULL) &&
1582 (strcmp(dm_table[i]->cipher, crypto_algo->dm_crypt_str) != 0))
1583 ++crypto_algo;
1584 if (crypto_algo == NULL) {
1585 tc_log(1, "could not find corresponding cipher\n");
1586 goto error;
1588 strcat(ciphers, crypto_algo->name);
1589 strcat(ciphers, ",");
1591 ciphers[strlen(ciphers)-1] = '\0';
1593 info->cipher_chain = check_cipher_chain(ciphers, 1);
1594 if (info->cipher_chain == NULL) {
1595 tc_log(1, "could not find cipher chain\n");
1596 goto error;
1599 /* Copy over the name */
1600 strncpy(info->dev, dm_table[outermost]->device, sizeof(info->dev));
1602 /* Other fields */
1603 info->hdr = NULL;
1604 info->pbkdf_prf = NULL;
1605 info->start = dm_table[outermost]->start;
1606 info->size = dm_table[0]->size;
1607 info->skip = dm_table[outermost]->skip;
1608 info->offset = dm_table[outermost]->offset;
1609 info->blk_sz = 512;
1611 return info;
1613 error:
1614 if (dmt)
1615 dm_task_destroy(dmt);
1616 if (info)
1617 free_safe_mem(info);
1618 for (i = 0; i < 3; i++)
1619 if (dm_table[i] != NULL)
1620 free_safe_mem(dm_table[i]);
1622 return NULL;
1625 static
1627 dm_exists_device(const char *name)
1629 struct dm_info dmi;
1630 int exists = 0;
1632 if (dm_get_info(name, &dmi) != 0)
1633 goto out;
1635 exists = dmi.exists;
1637 out:
1638 return exists;
1641 static
1643 dm_remove_device(const char *name)
1645 struct dm_task *dmt = NULL;
1646 int ret = EINVAL;
1648 if ((dmt = dm_task_create(DM_DEVICE_REMOVE)) == NULL)
1649 goto out;
1651 if ((dm_task_set_name(dmt, name)) == 0)
1652 goto out;
1654 if ((dm_task_run(dmt)) == 0)
1655 goto out;
1657 ret = 0;
1658 out:
1659 if (dmt)
1660 dm_task_destroy(dmt);
1662 return ret;
1666 dm_setup(const char *mapname, struct tcplay_info *info)
1668 struct tc_cipher_chain *cipher_chain;
1669 struct dm_task *dmt = NULL;
1670 struct dm_info dmi;
1671 char *params = NULL;
1672 char *uu, *uu_temp;
1673 char *uu_stack[64];
1674 int uu_stack_idx;
1675 #if defined(__DragonFly__)
1676 uint32_t status;
1677 #endif
1678 int r, ret = 0;
1679 int j, len;
1680 off_t start, offset;
1681 char dev[PATH_MAX];
1682 char map[PATH_MAX];
1683 uint32_t cookie;
1685 dm_udev_set_sync_support(1);
1687 if ((params = alloc_safe_mem(512)) == NULL) {
1688 tc_log(1, "could not allocate safe parameters memory");
1689 return ENOMEM;
1692 strcpy(dev, info->dev);
1695 * Device Mapper blocks are always 512-byte blocks, so convert
1696 * from the "native" block size to the dm block size here.
1698 start = INFO_TO_DM_BLOCKS(info, start);
1699 offset = INFO_TO_DM_BLOCKS(info, offset);
1700 uu_stack_idx = 0;
1703 * Find length of cipher chain. Could use the for below, but doesn't
1704 * really matter.
1706 len = tc_cipher_chain_length(info->cipher_chain);
1708 /* Get to the end of the chain */
1709 for (cipher_chain = info->cipher_chain; cipher_chain->next != NULL;
1710 cipher_chain = cipher_chain->next)
1714 * Start j at len-2, as we want to use .0, and the final one has no
1715 * suffix.
1717 for (j = len-2; cipher_chain != NULL;
1718 cipher_chain = cipher_chain->prev, j--) {
1720 cookie = 0;
1722 if ((dmt = dm_task_create(DM_DEVICE_CREATE)) == NULL) {
1723 tc_log(1, "dm_task_create failed\n");
1724 ret = -1;
1725 goto out;
1729 * If this is the last element in the cipher chain, use the
1730 * final map name. Otherwise pick a secondary name...
1732 if (cipher_chain->prev == NULL)
1733 strcpy(map, mapname);
1734 else
1735 sprintf(map, "%s.%d", mapname, j);
1737 if ((dm_task_set_name(dmt, map)) == 0) {
1738 tc_log(1, "dm_task_set_name failed\n");
1739 ret = -1;
1740 goto out;
1743 #if defined(__linux__)
1744 uuid_generate(info->uuid);
1745 if ((uu_temp = malloc(1024)) == NULL) {
1746 tc_log(1, "uuid_unparse memory failed\n");
1747 ret = -1;
1748 goto out;
1750 uuid_unparse(info->uuid, uu_temp);
1751 #elif defined(__DragonFly__)
1752 uuid_create(&info->uuid, &status);
1753 if (status != uuid_s_ok) {
1754 tc_log(1, "uuid_create failed\n");
1755 ret = -1;
1756 goto out;
1759 uuid_to_string(&info->uuid, &uu_temp, &status);
1760 if (uu_temp == NULL) {
1761 tc_log(1, "uuid_to_string failed\n");
1762 ret = -1;
1763 goto out;
1765 #endif
1767 if ((uu = malloc(1024)) == NULL) {
1768 free(uu_temp);
1769 tc_log(1, "uuid second malloc failed\n");
1770 ret = -1;
1771 goto out;
1774 snprintf(uu, 1024, "CRYPT-TCPLAY-%s", uu_temp);
1775 free(uu_temp);
1777 if ((dm_task_set_uuid(dmt, uu)) == 0) {
1778 free(uu);
1779 tc_log(1, "dm_task_set_uuid failed\n");
1780 ret = -1;
1781 goto out;
1784 free(uu);
1786 if (TC_FLAG_SET(info->flags, FDE)) {
1788 * When the full disk encryption (FDE) flag is set,
1789 * we map the first N sectors using a linear target
1790 * as they aren't encrypted.
1793 /* /dev/ad0s0a 0 */
1794 /* dev---^ block off --^ */
1795 snprintf(params, 512, "%s 0", dev);
1797 if ((dm_task_add_target(dmt, 0,
1798 INFO_TO_DM_BLOCKS(info, offset),
1799 "linear", params)) == 0) {
1800 tc_log(1, "dm_task_add_target failed\n");
1801 ret = -1;
1802 goto out;
1805 start = INFO_TO_DM_BLOCKS(info, offset);
1808 /* aes-cbc-essiv:sha256 7997f8af... 0 /dev/ad0s0a 8 <opts> */
1809 /* iv off---^ block off--^ <opts> */
1810 snprintf(params, 512, "%s %s %"PRIu64 " %s %"PRIu64 " %s",
1811 cipher_chain->cipher->dm_crypt_str, cipher_chain->dm_key,
1812 (uint64_t)INFO_TO_DM_BLOCKS(info, skip), dev,
1813 (uint64_t)offset,
1814 TC_FLAG_SET(info->flags, ALLOW_TRIM) ? "1 allow_discards" : "");
1815 #ifdef DEBUG
1816 printf("Params: %s\n", params);
1817 #endif
1819 if ((dm_task_add_target(dmt, start,
1820 INFO_TO_DM_BLOCKS(info, size), "crypt", params)) == 0) {
1821 tc_log(1, "dm_task_add_target failed\n");
1822 ret = -1;
1823 goto out;
1826 if ((dm_task_set_cookie(dmt, &cookie, 0)) == 0) {
1827 tc_log(1, "dm_task_set_cookie failed\n");
1828 ret = -1;
1829 goto out;
1832 if ((dm_task_run(dmt)) == 0) {
1833 dm_udev_wait(cookie);
1834 tc_log(1, "dm_task_run failed\n");
1835 ret = -1;
1836 goto out;
1839 if ((dm_task_get_info(dmt, &dmi)) == 0) {
1840 dm_udev_wait(cookie);
1841 tc_log(1, "dm_task_get info failed\n");
1842 ret = -1;
1843 goto out;
1846 dm_udev_wait(cookie);
1848 if ((r = asprintf(&uu_stack[uu_stack_idx++], "%s", map)) < 0)
1849 tc_log(1, "warning, asprintf failed. won't be able to "
1850 "unroll changes\n");
1853 offset = 0;
1854 start = 0;
1855 sprintf(dev, "/dev/mapper/%s.%d", mapname, j);
1857 dm_task_destroy(dmt);
1858 dm_task_update_nodes();
1861 out:
1863 * If an error occured, try to unroll changes made before it
1864 * happened.
1866 if (ret) {
1867 j = uu_stack_idx;
1868 while (j > 0) {
1869 #ifdef DEBUG
1870 printf("Unrolling dm changes! j = %d (%s)\n", j-1,
1871 uu_stack[j-1]);
1872 #endif
1873 if ((uu_stack[j-1] == NULL) ||
1874 ((r = dm_remove_device(uu_stack[--j])) != 0)) {
1875 tc_log(1, "Tried to unroll dm changes, "
1876 "giving up.\n");
1877 break;
1882 while (uu_stack_idx > 0)
1883 free(uu_stack[--uu_stack_idx]);
1885 free_safe_mem(params);
1887 return ret;
1891 dm_teardown(const char *mapname, const char *device __unused)
1893 #if 0
1894 struct dm_task *dmt = NULL;
1895 struct dm_info dmi;
1896 #endif
1897 char map[PATH_MAX];
1898 int i, error;
1900 if ((error = dm_remove_device(mapname)) != 0) {
1901 tc_log(1, "Could not remove mapping %s\n", mapname);
1902 return error;
1905 /* Try to remove other cascade devices */
1906 for (i = 0; i < 2; i++) {
1907 sprintf(map, "%s.%d", mapname, i);
1908 if (dm_exists_device(map))
1909 dm_remove_device(map);
1912 return 0;
1915 struct tc_crypto_algo *
1916 check_cipher(const char *cipher, int quiet)
1918 int i, found = 0;
1920 for (i = 0; tc_crypto_algos[i].name != NULL; i++) {
1921 if (strcmp(cipher, tc_crypto_algos[i].name) == 0) {
1922 found = 1;
1923 break;
1927 if (!found && !quiet) {
1928 fprintf(stderr, "Valid ciphers are: ");
1929 for (i = 0; tc_crypto_algos[i].name != NULL; i++)
1930 fprintf(stderr, "%s ", tc_crypto_algos[i].name);
1931 fprintf(stderr, "\n");
1932 return NULL;
1935 return &tc_crypto_algos[i];
1938 struct tc_cipher_chain *
1939 check_cipher_chain(const char *cipher_chain, int quiet)
1941 struct tc_cipher_chain *cipher = NULL;
1942 int i,k, nciphers = 0, mismatch = 0;
1943 char *ciphers[8];
1944 char *tmp_chain, *tmp_chain_free;
1945 char *token;
1947 if ((tmp_chain = strdup(cipher_chain)) == NULL) {
1948 tc_log(1, "Could not allocate strdup memory\n");
1949 return NULL;
1952 tmp_chain_free = tmp_chain;
1954 while ((token = strsep(&tmp_chain, ",")) != NULL)
1955 ciphers[nciphers++] = token;
1957 cipher = NULL;
1959 for (i = 0; valid_cipher_chains[i][0] != NULL; i++) {
1960 mismatch = 0;
1962 for (k = 0; (valid_cipher_chains[i][k] != NULL); k++) {
1964 * If there are more ciphers in the chain than in the
1965 * ciphers[] variable this is not the right chain.
1967 if (k == nciphers) {
1968 mismatch = 1;
1969 break;
1972 if (strcmp(ciphers[k], valid_cipher_chains[i][k]) != 0)
1973 mismatch = 1;
1977 * If all ciphers matched and there are exactly nciphers,
1978 * then we found the right cipher chain.
1980 if ((k == nciphers) && !mismatch) {
1981 cipher = tc_cipher_chains[i];
1982 break;
1986 if (cipher == NULL) {
1987 tc_log(1, "Invalid cipher: %s\n", cipher_chain);
1988 if (!quiet) {
1989 fprintf(stderr, "Valid cipher chains are:\n");
1990 for (i = 0; valid_cipher_chains[i][0] != NULL; i++) {
1991 for (k = 0; valid_cipher_chains[i][k] != NULL;
1992 k++) {
1993 fprintf(stderr, "%s%c",
1994 valid_cipher_chains[i][k],
1995 (valid_cipher_chains[i][k+1] != NULL) ?
1996 ',' : '\0');
1998 fprintf(stderr, "\n");
2003 free(tmp_chain_free);
2004 return cipher;
2007 struct pbkdf_prf_algo *
2008 check_prf_algo(const char *algo, int quiet)
2010 int i, found = 0;
2012 for (i = 0; pbkdf_prf_algos[i].name != NULL; i++) {
2013 if (strcmp(algo, pbkdf_prf_algos[i].name) == 0) {
2014 found = 1;
2015 break;
2019 if (!found && !quiet) {
2020 fprintf(stderr, "Valid PBKDF PRF algorithms are: ");
2021 for (i = 0; pbkdf_prf_algos[i].name != NULL; i++)
2022 fprintf(stderr, "%s ", pbkdf_prf_algos[i].name);
2023 fprintf(stderr, "\n");
2024 return NULL;
2027 return &pbkdf_prf_algos[i];
2031 tc_play_init(void)
2033 int error;
2035 if ((error = tc_build_cipher_chains()) != 0)
2036 return error;
2038 if ((error = tc_crypto_init()) != 0)
2039 return error;
2041 return 0;
2044 struct tcplay_opts *opts_init(void)
2046 struct tcplay_opts *opts;
2048 if ((opts = (struct tcplay_opts *)alloc_safe_mem(sizeof(*opts))) == NULL) {
2049 tc_log(1, "could not allocate safe opts memory\n");
2050 return NULL;
2053 memset(opts, 0, sizeof(*opts));
2055 opts->retries = DEFAULT_RETRIES;
2056 opts->secure_erase = 1;
2058 return opts;
2062 opts_add_keyfile(struct tcplay_opts *opts, const char *keyfile)
2064 const char *keyf;
2066 if (opts->nkeyfiles == MAX_KEYFILES)
2067 return -1;
2069 if ((keyf = strdup_safe_mem(keyfile)) == NULL) {
2070 return -1;
2073 opts->keyfiles[opts->nkeyfiles++] = keyf;
2075 return 0;
2079 opts_add_keyfile_hidden(struct tcplay_opts *opts, const char *keyfile)
2081 const char *keyf;
2083 if (opts->n_hkeyfiles == MAX_KEYFILES)
2084 return -1;
2086 if ((keyf = strdup_safe_mem(keyfile)) == NULL) {
2087 return -1;
2090 opts->h_keyfiles[opts->n_hkeyfiles++] = keyf;
2092 return 0;
2096 opts_add_keyfile_new(struct tcplay_opts *opts, const char *keyfile)
2098 const char *keyf;
2100 if (opts->n_newkeyfiles == MAX_KEYFILES)
2101 return -1;
2103 if ((keyf = strdup_safe_mem(keyfile)) == NULL) {
2104 return -1;
2107 opts->new_keyfiles[opts->n_newkeyfiles++] = keyf;
2109 return 0;
2112 void
2113 opts_clear_keyfile(struct tcplay_opts *opts)
2115 int i;
2117 for (i = 0; i < opts->nkeyfiles; i++) {
2118 free_safe_mem(opts->keyfiles[i]);
2121 opts->nkeyfiles = 0;
2124 void
2125 opts_clear_keyfile_hidden(struct tcplay_opts *opts)
2127 int i;
2129 for (i = 0; i < opts->n_hkeyfiles; i++) {
2130 free_safe_mem(opts->h_keyfiles[i]);
2133 opts->n_hkeyfiles = 0;
2137 void
2138 opts_clear_keyfile_new(struct tcplay_opts *opts)
2140 int i;
2142 for (i = 0; i < opts->n_newkeyfiles; i++) {
2143 free_safe_mem(opts->new_keyfiles[i]);
2146 opts->n_newkeyfiles = 0;
2150 void
2151 opts_free(struct tcplay_opts *opts)
2153 int i;
2155 for (i = 0; i < opts->nkeyfiles; i++) {
2156 free_safe_mem(opts->keyfiles[i]);
2159 for (i = 0; i < opts->n_hkeyfiles; i++) {
2160 free_safe_mem(opts->h_keyfiles[i]);
2163 for (i = 0; i < opts->n_newkeyfiles; i++) {
2164 free_safe_mem(opts->new_keyfiles[i]);
2167 if (opts->dev)
2168 free_safe_mem(opts->dev);
2169 if (opts->passphrase)
2170 free_safe_mem(opts->passphrase);
2171 if (opts->h_passphrase)
2172 free_safe_mem(opts->h_passphrase);
2173 if (opts->new_passphrase)
2174 free_safe_mem(opts->new_passphrase);
2175 if (opts->map_name)
2176 free_safe_mem(opts->map_name);
2177 if (opts->sys_dev)
2178 free_safe_mem(opts->sys_dev);
2179 if (opts->hdr_file_in)
2180 free_safe_mem(opts->hdr_file_in);
2181 if (opts->h_hdr_file_in)
2182 free_safe_mem(opts->h_hdr_file_in);
2183 if (opts->hdr_file_out)
2184 free_safe_mem(opts->hdr_file_out);
2186 free_safe_mem(opts);