1 /*
2 * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
15 *
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.
28 */
29
30 #define _BSD_SOURCE
31 #include <sys/types.h>
32 #include <sys/stat.h>
33
34 #if defined(__DragonFly__)
35 #include <sys/param.h>
36 #endif
37
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 #include <sys/sysmacros.h>
51 #elif defined(__DragonFly__)
52 #include <libdm.h>
53 #include <uuid.h>
54 #endif
55
56 #include <dirent.h>
57
58 #include "crc32.h"
59 #include "tcplay.h"
60 #include "humanize.h"
61
62
63 /* XXX TODO:
64 * - LRW-benbi support? needs further work in dm-crypt and even opencrypto
65 * - secure buffer review (i.e: is everything that needs it using secure mem?)
66 * - mlockall? (at least MCL_FUTURE, which is the only one we support)
67 */
68
69 summary_fn_t summary_fn = NULL;
70 int tc_internal_verbose = 1;
71 char tc_internal_log_buffer[LOG_BUFFER_SZ];
72 int tc_internal_state = STATE_UNKNOWN;
73
74 void
tc_log(int is_err,const char * fmt,...)75 tc_log(int is_err, const char *fmt, ...)
76 {
77 va_list ap;
78 FILE *fp;
79
80 if (is_err)
81 fp = stderr;
82 else
83 fp = stdout;
84
85 va_start(ap, fmt);
86
87 vsnprintf(tc_internal_log_buffer, LOG_BUFFER_SZ, fmt, ap);
88
89 va_end(ap);
90
91 if (tc_internal_verbose)
92 fprintf(fp, "%s", tc_internal_log_buffer);
93 }
94
95 /* Supported algorithms */
96 struct pbkdf_prf_algo pbkdf_prf_algos[] = {
97 { "RIPEMD160", "RIPEMD160", 2000, TC_SIG, 0},
98 { "RIPEMD160", "RIPEMD160", 1000, TC_SIG, 1},
99 { "SHA512", "SHA512", 1000, TC_SIG, 0},
100 { "whirlpool", "whirlpool", 1000, TC_SIG, 0},
101 { "RIPEMD160-VC", "RIPEMD160", 655331, VC_SIG, 0},
102 { "RIPEMD160-VC", "RIPEMD160", 327661, VC_SIG, 1},
103 { "SHA512-VC", "SHA512", 500000, VC_SIG, 0},
104 { "whirlpool-VC", "whirlpool", 500000, VC_SIG, 0},
105 { "SHA256-VC", "SHA256", 500000, VC_SIG, 0},
106 { "SHA256-VC", "SHA256", 200000, VC_SIG, 1},
107 { NULL, NULL, 0, NULL, 0}
108 };
109
110 struct tc_crypto_algo tc_crypto_algos[] = {
111 #if 0
112 /* XXX: turns out TC doesn't support AES-128-XTS */
113 { "AES-128-XTS", "aes-xts-plain", 32, 8 },
114 { "TWOFISH-128-XTS", "twofish-xts-plain", 32, 8 },
115 { "SERPENT-128-XTS", "serpent-xts-plain", 32, 8 },
116 #endif
117 { "AES-256-XTS", "aes-xts-plain64", 64, 8 },
118 { "TWOFISH-256-XTS", "twofish-xts-plain64", 64, 8 },
119 { "SERPENT-256-XTS", "serpent-xts-plain64", 64, 8 },
120 { NULL, NULL, 0, 0 }
121 };
122
123 const char *valid_cipher_chains[][MAX_CIPHER_CHAINS] = {
124 { "AES-256-XTS", NULL },
125 { "TWOFISH-256-XTS", NULL },
126 { "SERPENT-256-XTS", NULL },
127 { "AES-256-XTS", "TWOFISH-256-XTS", "SERPENT-256-XTS", NULL },
128 { "SERPENT-256-XTS", "TWOFISH-256-XTS", "AES-256-XTS", NULL },
129 #if 0
130 /* It seems that all the two-way cascades are the other way round... */
131 { "AES-256-XTS", "TWOFISH-256-XTS", NULL },
132 { "SERPENT-256-XTS", "AES-256-XTS", NULL },
133 { "TWOFISH-256-XTS", "SERPENT-256-XTS", NULL },
134
135 #endif
136 { "TWOFISH-256-XTS", "AES-256-XTS", NULL },
137 { "AES-256-XTS", "SERPENT-256-XTS", NULL },
138 { "SERPENT-256-XTS", "TWOFISH-256-XTS", NULL },
139 { NULL }
140 };
141
142 struct tc_cipher_chain *tc_cipher_chains[MAX_CIPHER_CHAINS];
143
144 static
145 int
tc_build_cipher_chains(void)146 tc_build_cipher_chains(void)
147 {
148 struct tc_cipher_chain *chain, *elem, *prev;
149 int i = 0;
150 int k;
151
152 while (valid_cipher_chains[i][0] != NULL) {
153 chain = NULL;
154 prev = NULL;
155 k = 0;
156
157 while (valid_cipher_chains[i][k] != NULL) {
158 if ((elem = alloc_safe_mem(sizeof(*elem))) == NULL) {
159 tc_log(1, "Error allocating memory for "
160 "cipher chain\n");
161 return -1;
162 }
163
164 /* Initialize first element of chain */
165 if (chain == NULL) {
166 chain = elem;
167 elem->prev = NULL;
168 }
169
170 /* Populate previous element */
171 if (prev != NULL) {
172 prev->next = elem;
173 elem->prev = prev;
174 }
175
176 /* Assume we are the last element in the chain */
177 elem->next = NULL;
178
179 /* Initialize other fields */
180 elem->cipher = check_cipher(valid_cipher_chains[i][k], 0);
181 if (elem->cipher == NULL)
182 return -1;
183
184 elem->key = NULL;
185
186 prev = elem;
187 ++k;
188 }
189
190 /* Store cipher chain */
191 tc_cipher_chains[i++] = chain;
192
193 /* Integrity check */
194 if (i >= MAX_CIPHER_CHAINS) {
195 tc_log(1, "FATAL: tc_cipher_chains is full!!\n");
196 return -1;
197 }
198
199 /* Make sure array is NULL terminated */
200 tc_cipher_chains[i] = NULL;
201 }
202
203 return 0;
204 }
205
206 static
207 struct tc_cipher_chain *
tc_dup_cipher_chain(struct tc_cipher_chain * src)208 tc_dup_cipher_chain(struct tc_cipher_chain *src)
209 {
210 struct tc_cipher_chain *first = NULL, *prev = NULL, *elem;
211
212 for (; src != NULL; src = src->next) {
213 if ((elem = alloc_safe_mem(sizeof(*elem))) == NULL) {
214 tc_log(1, "Error allocating memory for "
215 "duplicate cipher chain\n");
216 return NULL;
217 }
218
219 memcpy(elem, src, sizeof(*elem));
220
221 if (src->key != NULL) {
222 if ((elem->key = alloc_safe_mem(src->cipher->klen)) == NULL) {
223 tc_log(1, "Error allocating memory for "
224 "duplicate key in cipher chain\n");
225 return NULL;
226 }
227
228 memcpy(elem->key, src->key, src->cipher->klen);
229 }
230
231 if (first == NULL)
232 first = elem;
233
234 elem->next = NULL;
235 elem->prev = prev;
236
237 if (prev != NULL)
238 prev->next = elem;
239
240 prev = elem;
241 }
242
243 return first;
244 }
245
246 static
247 int
tc_free_cipher_chain(struct tc_cipher_chain * chain)248 tc_free_cipher_chain(struct tc_cipher_chain *chain)
249 {
250 struct tc_cipher_chain *next = chain;
251
252 while ((chain = next) != NULL) {
253 next = chain->next;
254
255 if (chain->key != NULL)
256 free_safe_mem(chain->key);
257 free_safe_mem(chain);
258 }
259
260 return 0;
261 }
262
263 int
tc_cipher_chain_length(struct tc_cipher_chain * chain)264 tc_cipher_chain_length(struct tc_cipher_chain *chain)
265 {
266 int len = 0;
267
268 for (; chain != NULL; chain = chain->next)
269 ++len;
270
271 return len;
272 }
273
274 int
tc_cipher_chain_klen(struct tc_cipher_chain * chain)275 tc_cipher_chain_klen(struct tc_cipher_chain *chain)
276 {
277 int klen_bytes = 0;
278
279 for (; chain != NULL; chain = chain->next) {
280 klen_bytes += chain->cipher->klen;
281 }
282
283 return klen_bytes;
284 }
285
286 char *
tc_cipher_chain_sprint(char * buf,size_t bufsz,struct tc_cipher_chain * chain)287 tc_cipher_chain_sprint(char *buf, size_t bufsz, struct tc_cipher_chain *chain)
288 {
289 static char sbuf[256];
290 int n = 0;
291
292 if (buf == NULL) {
293 buf = sbuf;
294 bufsz = sizeof(sbuf);
295 }
296
297 for (; chain != NULL; chain = chain->next) {
298 n += snprintf(buf+n, bufsz-n, "%s%s", chain->cipher->name,
299 (chain->next != NULL) ? "," : "\0");
300 }
301
302 return buf;
303 }
304
305 #ifdef DEBUG
306 static void
print_hex(unsigned char * buf,off_t start,size_t len)307 print_hex(unsigned char *buf, off_t start, size_t len)
308 {
309 size_t i;
310
311 for (i = start; i < start+len; i++)
312 printf("%02x", buf[i]);
313
314 printf("\n");
315 }
316 #endif
317
318 void
print_info(struct tcplay_info * info)319 print_info(struct tcplay_info *info)
320 {
321 printf("Device:\t\t\t%s\n", info->dev);
322
323 if (info->pbkdf_prf != NULL) {
324 printf("PBKDF2 PRF:\t\t%s\n", info->pbkdf_prf->name);
325 printf("PBKDF2 iterations:\t%d\n",
326 info->pbkdf_prf->iteration_count);
327 }
328
329 printf("Cipher:\t\t\t%s\n",
330 tc_cipher_chain_sprint(NULL, 0, info->cipher_chain));
331
332 printf("Key Length:\t\t%d bits\n",
333 8*tc_cipher_chain_klen(info->cipher_chain));
334
335 if (info->hdr != NULL) {
336 printf("CRC Key Data:\t\t%#x\n", info->hdr->crc_keys);
337 printf("Sector size:\t\t%d\n", info->hdr->sec_sz);
338 printf("Signature:\t\t%c%c%c%c\n", info->hdr->tc_str[0],
339 info->hdr->tc_str[1], info->hdr->tc_str[2],
340 info->hdr->tc_str[3]);
341 } else {
342 printf("Sector size:\t\t512\n");
343 }
344 printf("Volume size:\t\t%"DISKSZ_FMT" sectors\n", info->size);
345 #if 0
346 /* Don't print this; it's always 0 and is rather confusing */
347 printf("Volume offset:\t\t%"PRIu64"\n", (uint64_t)info->start);
348 #endif
349
350 #ifdef DEBUG
351 printf("Vol Flags:\t\t%d\n", info->volflags);
352 #endif
353
354 printf("IV offset:\t\t%"PRIu64" sectors\n",
355 (uint64_t)info->skip);
356 printf("Block offset:\t\t%"PRIu64" sectors\n",
357 (uint64_t)info->offset);
358 }
359
360 static
361 struct tcplay_info *
new_info(const char * dev,int flags,struct tc_cipher_chain * cipher_chain,struct pbkdf_prf_algo * prf,struct tchdr_dec * hdr,off_t start)362 new_info(const char *dev, int flags, struct tc_cipher_chain *cipher_chain,
363 struct pbkdf_prf_algo *prf, struct tchdr_dec *hdr, off_t start)
364 {
365 struct tc_cipher_chain *chain_start;
366 struct tcplay_info *info;
367 int i;
368 int error;
369
370 chain_start = cipher_chain;
371
372 if ((info = (struct tcplay_info *)alloc_safe_mem(sizeof(*info))) == NULL) {
373 tc_log(1, "could not allocate safe info memory\n");
374 return NULL;
375 }
376
377 strncpy(info->dev, dev, sizeof(info->dev));
378 info->cipher_chain = cipher_chain;
379 info->pbkdf_prf = prf;
380 info->start = start;
381 info->hdr = hdr;
382 info->blk_sz = hdr->sec_sz;
383 info->size = hdr->sz_mk_scope / hdr->sec_sz; /* volume size */
384 info->skip = hdr->off_mk_scope / hdr->sec_sz; /* iv skip */
385
386 info->volflags = hdr->flags;
387 info->flags = flags;
388
389 if (TC_FLAG_SET(flags, SYS))
390 info->offset = 0; /* offset is 0 for system volumes */
391 else
392 info->offset = hdr->off_mk_scope / hdr->sec_sz; /* block offset */
393
394 /* Associate a key out of the key pool with each cipher in the chain */
395 error = tc_cipher_chain_populate_keys(cipher_chain, hdr->keys);
396 if (error) {
397 tc_log(1, "could not populate keys in cipher chain\n");
398 return NULL;
399 }
400
401 for (; cipher_chain != NULL; cipher_chain = cipher_chain->next) {
402 for (i = 0; i < cipher_chain->cipher->klen; i++)
403 sprintf(&cipher_chain->dm_key[i*2], "%02x",
404 cipher_chain->key[i]);
405 }
406
407 tc_cipher_chain_free_keys(chain_start);
408
409 return info;
410 }
411
412 int
free_info(struct tcplay_info * info)413 free_info(struct tcplay_info *info)
414 {
415 if (info->cipher_chain)
416 tc_free_cipher_chain(info->cipher_chain);
417 if (info->hdr)
418 free_safe_mem(info->hdr);
419
420 free_safe_mem(info);
421
422 return 0;
423 }
424
425 int
adjust_info(struct tcplay_info * info,struct tcplay_info * hinfo)426 adjust_info(struct tcplay_info *info, struct tcplay_info *hinfo)
427 {
428 if (hinfo->hdr->sz_hidvol == 0)
429 return 1;
430
431 info->size -= hinfo->hdr->sz_hidvol / hinfo->hdr->sec_sz;
432 return 0;
433 }
434
435 int
process_hdr(const char * dev,int flags,unsigned char * pass,int passlen,struct tchdr_enc * ehdr,struct tcplay_info ** pinfo)436 process_hdr(const char *dev, int flags, unsigned char *pass, int passlen,
437 struct tchdr_enc *ehdr, struct tcplay_info **pinfo)
438 {
439 struct tchdr_dec *dhdr;
440 struct tcplay_info *info;
441 struct tc_cipher_chain *cipher_chain = NULL;
442 unsigned char *key;
443 int i, j, found, error;
444
445 *pinfo = NULL;
446
447 if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
448 tc_log(1, "could not allocate safe key memory\n");
449 return ENOMEM;
450 }
451
452 /* Start search for correct algorithm combination */
453 found = 0;
454 for (i = 0; !found && pbkdf_prf_algos[i].name != NULL; i++) {
455 #ifdef DEBUG
456 printf("\nTrying PRF algo %s (%d)\n", pbkdf_prf_algos[i].name,
457 pbkdf_prf_algos[i].iteration_count);
458 printf("Salt: ");
459 print_hex(ehdr->salt, 0, sizeof(ehdr->salt));
460 #endif
461 error = pbkdf2(&pbkdf_prf_algos[i], (char *)pass, passlen,
462 ehdr->salt, sizeof(ehdr->salt),
463 MAX_KEYSZ, key);
464
465 if (error) {
466 tc_log(1, "pbkdf failed for algorithm %s\n",
467 pbkdf_prf_algos[i].name);
468 free_safe_mem(key);
469 return EINVAL;
470 }
471
472 #if 0
473 printf("Derived Key: ");
474 print_hex(key, 0, MAX_KEYSZ);
475 #endif
476
477 for (j = 0; !found && tc_cipher_chains[j] != NULL; j++) {
478 cipher_chain = tc_dup_cipher_chain(tc_cipher_chains[j]);
479 #ifdef DEBUG
480 printf("\nTrying cipher chain %d\n", j);
481 #endif
482
483 dhdr = decrypt_hdr(ehdr, cipher_chain, key);
484 if (dhdr == NULL) {
485 tc_log(1, "hdr decryption failed for cipher "
486 "chain %d\n", j);
487 free_safe_mem(key);
488 return EINVAL;
489 }
490
491 if (verify_hdr(dhdr, &pbkdf_prf_algos[i])) {
492 #ifdef DEBUG
493 printf("tc_str: %.4s, tc_ver: %d, tc_min_ver: %d, "
494 "crc_keys: %d, sz_vol: %"PRIu64", "
495 "off_mk_scope: %"PRIu64", sz_mk_scope: %"PRIu64", "
496 "flags: %d, sec_sz: %d crc_dhdr: %d\n",
497 dhdr->tc_str, dhdr->tc_ver, dhdr->tc_min_ver,
498 dhdr->crc_keys, dhdr->sz_vol, dhdr->off_mk_scope,
499 dhdr->sz_mk_scope, dhdr->flags, dhdr->sec_sz,
500 dhdr->crc_dhdr);
501 #endif
502 found = 1;
503 } else {
504 free_safe_mem(dhdr);
505 tc_free_cipher_chain(cipher_chain);
506 }
507 }
508 }
509
510 free_safe_mem(key);
511
512 if (!found)
513 return EINVAL;
514
515 if ((info = new_info(dev, flags, cipher_chain,
516 &pbkdf_prf_algos[i-1], dhdr, 0)) == NULL) {
517 free_safe_mem(dhdr);
518 return ENOMEM;
519 }
520
521 *pinfo = info;
522
523 return 0;
524 }
525
526 int
create_volume(struct tcplay_opts * opts)527 create_volume(struct tcplay_opts *opts)
528 {
529 char *pass, *pass_again;
530 char *h_pass = NULL;
531 char buf[1024];
532 disksz_t blocks, hidden_blocks = 0;
533 size_t blksz;
534 struct tchdr_enc *ehdr, *hehdr;
535 struct tchdr_enc *ehdr_backup, *hehdr_backup;
536 uint64_t tmp;
537 int error, r, ret;
538
539 pass = h_pass = pass_again = NULL;
540 ehdr = hehdr = NULL;
541 ehdr_backup = hehdr_backup = NULL;
542 ret = -1; /* Default to returning error */
543
544 if (opts->cipher_chain == NULL)
545 opts->cipher_chain = tc_cipher_chains[0];
546 if (opts->prf_algo == NULL)
547 opts->prf_algo = &pbkdf_prf_algos[DEFAULT_PRF_ALGO_IDX];
548 if (opts->h_cipher_chain == NULL)
549 opts->h_cipher_chain = opts->cipher_chain;
550 if (opts->h_prf_algo == NULL)
551 opts->h_prf_algo = opts->prf_algo;
552
553 if ((error = get_disk_info(opts->dev, &blocks, &blksz)) != 0) {
554 tc_log(1, "could not get disk info\n");
555 return -1;
556 }
557
558 if ((blocks*blksz) <= MIN_VOL_BYTES) {
559 tc_log(1, "Cannot create volumes on devices with less "
560 "than %d bytes\n", MIN_VOL_BYTES);
561 return -1;
562 }
563
564 if (opts->interactive) {
565 if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
566 ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
567 tc_log(1, "could not allocate safe passphrase memory\n");
568 goto out;
569 }
570
571 if ((error = read_passphrase("Passphrase: ", pass, MAX_PASSSZ,
572 PASS_BUFSZ, 0) ||
573 (read_passphrase("Repeat passphrase: ", pass_again,
574 MAX_PASSSZ, PASS_BUFSZ, 0)))) {
575 tc_log(1, "could not read passphrase\n");
576 goto out;
577 }
578
579 if (strcmp(pass, pass_again) != 0) {
580 tc_log(1, "Passphrases don't match\n");
581 goto out;
582 }
583
584 free_safe_mem(pass_again);
585 pass_again = NULL;
586 } else {
587 /* In batch mode, use provided passphrase */
588 if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
589 tc_log(1, "could not allocate safe "
590 "passphrase memory");
591 goto out;
592 }
593
594 if (opts->passphrase != NULL) {
595 strncpy(pass, opts->passphrase, MAX_PASSSZ);
596 pass[MAX_PASSSZ] = '\0';
597 }
598 }
599
600 if (opts->nkeyfiles > 0) {
601 /* Apply keyfiles to 'pass' */
602 if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
603 opts->keyfiles, opts->nkeyfiles))) {
604 tc_log(1, "could not apply keyfiles\n");
605 goto out;
606 }
607 }
608
609 if (opts->hidden) {
610 if (opts->interactive) {
611 if (((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
612 ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
613 tc_log(1, "could not allocate safe "
614 "passphrase memory\n");
615 goto out;
616 }
617
618 if ((error = read_passphrase("Passphrase for hidden volume: ",
619 h_pass, MAX_PASSSZ, PASS_BUFSZ, 0) ||
620 (read_passphrase("Repeat passphrase: ", pass_again,
621 MAX_PASSSZ, PASS_BUFSZ, 0)))) {
622 tc_log(1, "could not read passphrase\n");
623 goto out;
624 }
625
626 if (strcmp(h_pass, pass_again) != 0) {
627 tc_log(1, "Passphrases for hidden volume don't "
628 "match\n");
629 goto out;
630 }
631
632 free_safe_mem(pass_again);
633 pass_again = NULL;
634 } else {
635 /* In batch mode, use provided passphrase */
636 if ((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
637 tc_log(1, "could not allocate safe "
638 "passphrase memory");
639 goto out;
640 }
641
642 if (opts->h_passphrase != NULL) {
643 strncpy(h_pass, opts->h_passphrase, MAX_PASSSZ);
644 h_pass[MAX_PASSSZ] = '\0';
645 }
646 }
647
648 if (opts->n_hkeyfiles > 0) {
649 /* Apply keyfiles to 'h_pass' */
650 if ((error = apply_keyfiles((unsigned char *)h_pass,
651 PASS_BUFSZ, opts->h_keyfiles, opts->n_hkeyfiles))) {
652 tc_log(1, "could not apply keyfiles\n");
653 goto out;
654 }
655 }
656
657 if (opts->interactive) {
658 hidden_blocks = 0;
659 } else {
660 hidden_blocks = opts->hidden_size_bytes/blksz;
661 if (hidden_blocks == 0) {
662 tc_log(1, "hidden_blocks to create volume "
663 "cannot be zero!\n");
664 goto out;
665 }
666
667 if (opts->hidden_size_bytes >=
668 (blocks*blksz) - MIN_VOL_BYTES) {
669 tc_log(1, "Hidden volume needs to be "
670 "smaller than the outer volume\n");
671 goto out;
672 }
673 }
674
675 /* This only happens in interactive mode */
676 while (hidden_blocks == 0) {
677 if ((r = _humanize_number(buf, sizeof(buf),
678 (uint64_t)(blocks * blksz))) < 0) {
679 sprintf(buf, "%"DISKSZ_FMT" bytes", (blocks * blksz));
680 }
681
682 printf("The total volume size of %s is %s (bytes)\n", opts->dev, buf);
683 memset(buf, 0, sizeof(buf));
684 printf("Size of hidden volume (e.g. 127M): ");
685 fflush(stdout);
686
687 if ((fgets(buf, sizeof(buf), stdin)) == NULL) {
688 tc_log(1, "Could not read from stdin\n");
689 goto out;
690 }
691
692 /* get rid of trailing newline */
693 buf[strlen(buf)-1] = '\0';
694 if ((error = _dehumanize_number(buf,
695 &tmp)) != 0) {
696 tc_log(1, "Could not interpret input: %s\n", buf);
697 continue;
698 }
699
700 if (tmp >= (blocks*blksz) - MIN_VOL_BYTES) {
701 tc_log(1, "Hidden volume needs to be "
702 "smaller than the outer volume\n");
703 hidden_blocks = 0;
704 continue;
705 }
706
707 hidden_blocks = (size_t)tmp;
708 hidden_blocks /= blksz;
709 }
710 }
711
712 if (opts->interactive) {
713 /* Show summary and ask for confirmation */
714 printf("Summary of actions:\n");
715 if (opts->secure_erase)
716 printf(" - Completely erase *EVERYTHING* on %s\n", opts->dev);
717 printf(" - Create %svolume on %s\n", opts->hidden?("outer "):"", opts->dev);
718 if (opts->hidden) {
719 printf(" - Create hidden volume of %"DISKSZ_FMT" bytes at end of "
720 "outer volume\n",
721 hidden_blocks * blksz);
722 }
723
724 printf("\n Are you sure you want to proceed? (y/n) ");
725 fflush(stdout);
726 if ((fgets(buf, sizeof(buf), stdin)) == NULL) {
727 tc_log(1, "Could not read from stdin\n");
728 goto out;
729 }
730
731 if ((buf[0] != 'y') && (buf[0] != 'Y')) {
732 tc_log(1, "User cancelled action(s)\n");
733 goto out;
734 }
735 }
736
737 /* erase volume */
738 if (opts->secure_erase) {
739 tc_log(0, "Securely erasing the volume...\nThis process may take "
740 "some time depending on the size of the volume\n");
741
742 if (opts->state_change_fn)
743 opts->state_change_fn(opts->api_ctx, "secure_erase", 1);
744
745 if ((error = secure_erase(opts->dev, blocks * blksz, blksz)) != 0) {
746 tc_log(1, "could not securely erase device %s\n", opts->dev);
747 goto out;
748 }
749
750 if (opts->state_change_fn)
751 opts->state_change_fn(opts->api_ctx, "secure_erase", 0);
752 }
753
754 tc_log(0, "Creating volume headers...\nDepending on your system, this "
755 "process may take a few minutes as it uses true random data which "
756 "might take a while to refill\n");
757
758 if (opts->weak_keys_and_salt) {
759 tc_log(0, "WARNING: Using a weak random generator to get "
760 "entropy for the key material. Odds are this is NOT "
761 "what you want.\n");
762 }
763
764 if (opts->state_change_fn)
765 opts->state_change_fn(opts->api_ctx, "create_header", 1);
766
767 /* create encrypted headers */
768 ehdr = create_hdr((unsigned char *)pass,
769 (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
770 opts->prf_algo, opts->cipher_chain, blksz, blocks, VOL_RSVD_BYTES_START/blksz,
771 blocks - (MIN_VOL_BYTES/blksz), 0, opts->weak_keys_and_salt, &ehdr_backup);
772 if (ehdr == NULL) {
773 tc_log(1, "Could not create header\n");
774 goto out;
775 }
776
777 if (opts->hidden) {
778 hehdr = create_hdr((unsigned char *)h_pass,
779 (opts->n_hkeyfiles > 0)?MAX_PASSSZ:strlen(h_pass), opts->h_prf_algo,
780 opts->h_cipher_chain,
781 blksz, blocks,
782 blocks - (VOL_RSVD_BYTES_END/blksz) - hidden_blocks,
783 hidden_blocks, 1, opts->weak_keys_and_salt, &hehdr_backup);
784 if (hehdr == NULL) {
785 tc_log(1, "Could not create hidden volume header\n");
786 goto out;
787 }
788 }
789
790 if (opts->state_change_fn)
791 opts->state_change_fn(opts->api_ctx, "create_header", 0);
792
793 tc_log(0, "Writing volume headers to disk...\n");
794
795 if ((error = write_to_disk(opts->dev, 0, blksz, ehdr, sizeof(*ehdr))) != 0) {
796 tc_log(1, "Could not write volume header to device\n");
797 goto out;
798 }
799
800 /* Write backup header; it's offset is relative to the end */
801 if ((error = write_to_disk(opts->dev, (blocks*blksz - BACKUP_HDR_OFFSET_END),
802 blksz, ehdr_backup, sizeof(*ehdr_backup))) != 0) {
803 tc_log(1, "Could not write backup volume header to device\n");
804 goto out;
805 }
806
807 if (opts->hidden) {
808 if ((error = write_to_disk(opts->dev, HDR_OFFSET_HIDDEN, blksz, hehdr,
809 sizeof(*hehdr))) != 0) {
810 tc_log(1, "Could not write hidden volume header to "
811 "device\n");
812 goto out;
813 }
814
815 /* Write backup hidden header; offset is relative to end */
816 if ((error = write_to_disk(opts->dev,
817 (blocks*blksz - BACKUP_HDR_HIDDEN_OFFSET_END), blksz,
818 hehdr_backup, sizeof(*hehdr_backup))) != 0) {
819 tc_log(1, "Could not write backup hidden volume "
820 "header to device\n");
821 goto out;
822 }
823 }
824
825 /* Everything went ok */
826 tc_log(0, "All done!\n");
827
828 ret = 0;
829
830 out:
831 if (pass)
832 free_safe_mem(pass);
833 if (h_pass)
834 free_safe_mem(h_pass);
835 if (pass_again)
836 free_safe_mem(pass_again);
837 if (ehdr)
838 free_safe_mem(ehdr);
839 if (hehdr)
840 free_safe_mem(hehdr);
841 if (ehdr_backup)
842 free_safe_mem(ehdr_backup);
843 if (hehdr_backup)
844 free_safe_mem(hehdr_backup);
845
846 return ret;
847 }
848
849 struct tcplay_info *
info_map_common(struct tcplay_opts * opts,char * passphrase_out)850 info_map_common(struct tcplay_opts *opts, char *passphrase_out)
851 {
852 struct tchdr_enc *ehdr, *hehdr = NULL;
853 struct tcplay_info *info, *hinfo = NULL;
854 char *pass;
855 char *h_pass;
856 int error, error2 = 0;
857 size_t sz;
858 size_t blksz;
859 disksz_t blocks;
860 int is_hidden = 0;
861 int try_empty = 0;
862 int retries;
863
864 if ((error = get_disk_info(opts->dev, &blocks, &blksz)) != 0) {
865 tc_log(1, "could not get disk information\n");
866 return NULL;
867 }
868
869 if (opts->retries < 1)
870 retries = 1;
871 else
872 retries = opts->retries;
873
874 /*
875 * Add one retry so we can do a first try without asking for
876 * a password if keyfiles are passed in.
877 */
878 if (opts->interactive &&
879 !opts->prompt_passphrase &&
880 (opts->nkeyfiles > 0)) {
881 try_empty = 1;
882 ++retries;
883 }
884
885 info = NULL;
886
887 ehdr = NULL;
888 pass = h_pass = NULL;
889
890 while ((info == NULL) && retries-- > 0)
891 {
892 pass = h_pass = NULL;
893 ehdr = hehdr = NULL;
894 info = hinfo = NULL;
895
896 if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
897 tc_log(1, "could not allocate safe passphrase memory\n");
898 goto out;
899 }
900
901 if (try_empty) {
902 pass[0] = '\0';
903 } else if (opts->interactive) {
904 if ((error = read_passphrase("Passphrase: ", pass,
905 MAX_PASSSZ, PASS_BUFSZ, opts->timeout))) {
906 tc_log(1, "could not read passphrase\n");
907 /* XXX: handle timeout differently? */
908 goto out;
909 }
910 pass[MAX_PASSSZ] = '\0';
911 } else {
912 /* In batch mode, use provided passphrase */
913 if (opts->passphrase != NULL) {
914 strncpy(pass, opts->passphrase, MAX_PASSSZ);
915 pass[MAX_PASSSZ] = '\0';
916 }
917 }
918
919 if (passphrase_out != NULL) {
920 strcpy(passphrase_out, pass);
921 }
922
923 if (opts->nkeyfiles > 0) {
924 /* Apply keyfiles to 'pass' */
925 if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
926 opts->keyfiles, opts->nkeyfiles))) {
927 tc_log(1, "could not apply keyfiles");
928 goto out;
929 }
930 }
931
932 if (opts->protect_hidden) {
933 if ((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
934 tc_log(1, "could not allocate safe passphrase memory\n");
935 goto out;
936 }
937
938 if (opts->interactive) {
939 if ((error = read_passphrase(
940 "Passphrase for hidden volume: ", h_pass,
941 MAX_PASSSZ, PASS_BUFSZ, opts->timeout))) {
942 tc_log(1, "could not read passphrase\n");
943 goto out;
944 }
945 h_pass[MAX_PASSSZ] = '\0';
946 } else {
947 /* In batch mode, use provided passphrase */
948 if (opts->h_passphrase != NULL) {
949 strncpy(h_pass, opts->h_passphrase, MAX_PASSSZ);
950 h_pass[MAX_PASSSZ] = '\0';
951 }
952 }
953
954 if (opts->n_hkeyfiles > 0) {
955 /* Apply keyfiles to 'pass' */
956 if ((error = apply_keyfiles((unsigned char *)h_pass, PASS_BUFSZ,
957 opts->h_keyfiles, opts->n_hkeyfiles))) {
958 tc_log(1, "could not apply keyfiles");
959 goto out;
960 }
961 }
962 }
963
964 /* Always read blksz-sized chunks */
965 sz = blksz;
966
967 if (TC_FLAG_SET(opts->flags, HDR_FROM_FILE)) {
968 ehdr = (struct tchdr_enc *)read_to_safe_mem(
969 opts->hdr_file_in, 0, &sz);
970 if (ehdr == NULL) {
971 tc_log(1, "error read hdr_enc: %s", opts->hdr_file_in);
972 goto out;
973 }
974 } else {
975 ehdr = (struct tchdr_enc *)read_to_safe_mem(
976 (TC_FLAG_SET(opts->flags, SYS)) ? opts->sys_dev : opts->dev,
977 (TC_FLAG_SET(opts->flags, SYS) || TC_FLAG_SET(opts->flags, FDE)) ?
978 HDR_OFFSET_SYS :
979 (!TC_FLAG_SET(opts->flags, BACKUP)) ? 0 : -BACKUP_HDR_OFFSET_END,
980 &sz);
981 if (ehdr == NULL) {
982 tc_log(1, "error read hdr_enc: %s", opts->dev);
983 goto out;
984 }
985 }
986
987 if (!TC_FLAG_SET(opts->flags, SYS)) {
988 /* Always read blksz-sized chunks */
989 sz = blksz;
990
991 if (TC_FLAG_SET(opts->flags, H_HDR_FROM_FILE)) {
992 hehdr = (struct tchdr_enc *)read_to_safe_mem(
993 opts->h_hdr_file_in, 0, &sz);
994 if (hehdr == NULL) {
995 tc_log(1, "error read hdr_enc: %s", opts->h_hdr_file_in);
996 goto out;
997 }
998 } else {
999 hehdr = (struct tchdr_enc *)read_to_safe_mem(opts->dev,
1000 (!TC_FLAG_SET(opts->flags, BACKUP)) ? HDR_OFFSET_HIDDEN :
1001 -BACKUP_HDR_HIDDEN_OFFSET_END, &sz);
1002 if (hehdr == NULL) {
1003 tc_log(1, "error read hdr_enc: %s", opts->dev);
1004 goto out;
1005 }
1006 }
1007 } else {
1008 hehdr = NULL;
1009 }
1010
1011 error = process_hdr(opts->dev, opts->flags, (unsigned char *)pass,
1012 (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
1013 ehdr, &info);
1014
1015 /*
1016 * Try to process hidden header if we have to protect the hidden
1017 * volume, or the decryption/verification of the main header
1018 * failed.
1019 */
1020 if (hehdr && (error || opts->protect_hidden)) {
1021 if (error) {
1022 error2 = process_hdr(opts->dev, opts->flags, (unsigned char *)pass,
1023 (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass), hehdr,
1024 &info);
1025 is_hidden = !error2;
1026 } else if (opts->protect_hidden) {
1027 error2 = process_hdr(opts->dev, opts->flags, (unsigned char *)h_pass,
1028 (opts->n_hkeyfiles > 0)?MAX_PASSSZ:strlen(h_pass), hehdr,
1029 &hinfo);
1030 }
1031 }
1032
1033 /* We need both to protect a hidden volume */
1034 if ((opts->protect_hidden && (error || error2)) ||
1035 (error && error2)) {
1036 if (!try_empty)
1037 tc_log(1, "Incorrect password or not a TrueCrypt volume\n");
1038
1039 if (info) {
1040 free_info(info);
1041 info = NULL;
1042 }
1043 if (hinfo) {
1044 free_info(hinfo);
1045 hinfo = NULL;
1046 }
1047
1048 /* Try again (or finish) */
1049 free_safe_mem(pass);
1050 pass = NULL;
1051
1052 if (h_pass) {
1053 free_safe_mem(h_pass);
1054 h_pass = NULL;
1055 }
1056 if (ehdr) {
1057 free_safe_mem(ehdr);
1058 ehdr = NULL;
1059 }
1060 if (hehdr) {
1061 free_safe_mem(hehdr);
1062 hehdr = NULL;
1063 }
1064
1065 try_empty = 0;
1066 continue;
1067 }
1068
1069 if (opts->protect_hidden) {
1070 if (adjust_info(info, hinfo) != 0) {
1071 tc_log(1, "Could not protect hidden volume\n");
1072 if (info)
1073 free_info(info);
1074 info = NULL;
1075
1076 if (hinfo)
1077 free_info(hinfo);
1078 hinfo = NULL;
1079
1080 goto out;
1081 }
1082
1083 if (hinfo) {
1084 free_info(hinfo);
1085 hinfo = NULL;
1086 }
1087 }
1088 try_empty = 0;
1089 }
1090
1091 out:
1092 if (hinfo)
1093 free_info(hinfo);
1094 if (pass)
1095 free_safe_mem(pass);
1096 if (h_pass)
1097 free_safe_mem(h_pass);
1098 if (ehdr)
1099 free_safe_mem(ehdr);
1100 if (hehdr)
1101 free_safe_mem(hehdr);
1102
1103 if (info != NULL)
1104 info->hidden = is_hidden;
1105
1106 return info;
1107 }
1108
1109 int
info_mapped_volume(struct tcplay_opts * opts)1110 info_mapped_volume(struct tcplay_opts *opts)
1111 {
1112 struct tcplay_info *info;
1113
1114 info = dm_info_map(opts->map_name);
1115 if (info != NULL) {
1116 if (opts->interactive)
1117 print_info(info);
1118
1119 free_info(info);
1120
1121 return 0;
1122 /* NOT REACHED */
1123 } else if (opts->interactive) {
1124 tc_log(1, "Could not retrieve information about mapped "
1125 "volume %s. Does it exist?\n", opts->map_name);
1126 }
1127
1128 return -1;
1129 }
1130
1131 int
info_volume(struct tcplay_opts * opts)1132 info_volume(struct tcplay_opts *opts)
1133 {
1134 struct tcplay_info *info;
1135
1136 info = info_map_common(opts, NULL);
1137
1138 if (info != NULL) {
1139 if (opts->interactive)
1140 print_info(info);
1141
1142 free_info(info);
1143
1144 return 0;
1145 /* NOT REACHED */
1146 }
1147
1148 return -1;
1149 }
1150
1151 int
map_volume(struct tcplay_opts * opts)1152 map_volume(struct tcplay_opts *opts)
1153 {
1154 struct tcplay_info *info;
1155 int error;
1156
1157 info = info_map_common(opts, NULL);
1158
1159 if (info == NULL)
1160 return -1;
1161
1162 if ((error = dm_setup(opts->map_name, info)) != 0) {
1163 tc_log(1, "Could not set up mapping %s\n", opts->map_name);
1164 free_info(info);
1165 return -1;
1166 }
1167
1168 if (opts->interactive)
1169 printf("All ok!\n");
1170
1171 free_info(info);
1172
1173 return 0;
1174 }
1175
1176 int
modify_volume(struct tcplay_opts * opts)1177 modify_volume(struct tcplay_opts *opts)
1178 {
1179 struct tcplay_info *info;
1180 struct tchdr_enc *ehdr, *ehdr_backup;
1181 const char *new_passphrase = opts->new_passphrase;
1182 const char **new_keyfiles = opts->new_keyfiles;
1183 struct pbkdf_prf_algo *new_prf_algo = opts->new_prf_algo;
1184 int n_newkeyfiles = opts->n_newkeyfiles;
1185 char *pass, *pass_again;
1186 int ret = -1;
1187 off_t offset, offset_backup = 0;
1188 const char *dev;
1189 size_t blksz;
1190 disksz_t blocks;
1191 int error;
1192
1193 ehdr = ehdr_backup = NULL;
1194 pass = pass_again = NULL;
1195 info = NULL;
1196
1197 if (TC_FLAG_SET(opts->flags, ONLY_RESTORE)) {
1198 if (opts->interactive) {
1199 if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
1200 tc_log(1, "could not allocate safe "
1201 "passphrase memory");
1202 goto out;
1203 }
1204 } else {
1205 new_passphrase = opts->passphrase;
1206 }
1207 new_keyfiles = opts->keyfiles;
1208 n_newkeyfiles = opts->nkeyfiles;
1209 new_prf_algo = NULL;
1210 }
1211
1212 info = info_map_common(opts, pass);
1213 if (info == NULL)
1214 goto out;
1215
1216 if (opts->interactive && !TC_FLAG_SET(opts->flags, ONLY_RESTORE)) {
1217 if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
1218 ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
1219 tc_log(1, "could not allocate safe passphrase memory\n");
1220 goto out;
1221 }
1222
1223 if ((error = read_passphrase("New passphrase: ", pass, MAX_PASSSZ,
1224 PASS_BUFSZ, 0) ||
1225 (read_passphrase("Repeat passphrase: ", pass_again,
1226 MAX_PASSSZ, PASS_BUFSZ, 0)))) {
1227 tc_log(1, "could not read passphrase\n");
1228 goto out;
1229 }
1230
1231 if (strcmp(pass, pass_again) != 0) {
1232 tc_log(1, "Passphrases don't match\n");
1233 goto out;
1234 }
1235
1236 free_safe_mem(pass_again);
1237 pass_again = NULL;
1238 } else if (!opts->interactive) {
1239 /* In batch mode, use provided passphrase */
1240 if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
1241 tc_log(1, "could not allocate safe "
1242 "passphrase memory");
1243 goto out;
1244 }
1245
1246 if (new_passphrase != NULL) {
1247 strncpy(pass, new_passphrase, MAX_PASSSZ);
1248 pass[MAX_PASSSZ] = '\0';
1249 }
1250 }
1251
1252 if (n_newkeyfiles > 0) {
1253 /* Apply keyfiles to 'pass' */
1254 if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
1255 new_keyfiles, n_newkeyfiles))) {
1256 tc_log(1, "could not apply keyfiles\n");
1257 goto out;
1258 }
1259 }
1260
1261 ehdr = copy_reencrypt_hdr((unsigned char *)pass,
1262 (opts->n_newkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
1263 new_prf_algo, opts->weak_keys_and_salt, info, &ehdr_backup);
1264 if (ehdr == NULL) {
1265 tc_log(1, "Could not create header\n");
1266 goto out;
1267 }
1268
1269 dev = (TC_FLAG_SET(opts->flags, SYS)) ? opts->sys_dev : opts->dev;
1270 if (TC_FLAG_SET(opts->flags, SYS) || TC_FLAG_SET(opts->flags, FDE)) {
1271 /* SYS and FDE don't have backup headers (as far as I understand) */
1272 if (info->hidden) {
1273 offset = HDR_OFFSET_HIDDEN;
1274 } else {
1275 offset = HDR_OFFSET_SYS;
1276 }
1277 } else {
1278 if (info->hidden) {
1279 offset = HDR_OFFSET_HIDDEN;
1280 offset_backup = -BACKUP_HDR_HIDDEN_OFFSET_END;
1281 } else {
1282 offset = 0;
1283 offset_backup = -BACKUP_HDR_OFFSET_END;
1284 }
1285 }
1286
1287 if ((error = get_disk_info(dev, &blocks, &blksz)) != 0) {
1288 tc_log(1, "could not get disk information\n");
1289 goto out;
1290 }
1291
1292 tc_log(0, "Writing new volume headers to disk/file...\n");
1293
1294 if (TC_FLAG_SET(opts->flags, SAVE_TO_FILE)) {
1295 if ((error = write_to_file(opts->hdr_file_out, ehdr, sizeof(*ehdr))) != 0) {
1296 tc_log(1, "Could not write volume header to file\n");
1297 goto out;
1298 }
1299 } else {
1300 if ((error = write_to_disk(dev, offset, blksz, ehdr,
1301 sizeof(*ehdr))) != 0) {
1302 tc_log(1, "Could not write volume header to device\n");
1303 goto out;
1304 }
1305
1306 if (!TC_FLAG_SET(opts->flags, SYS) && !TC_FLAG_SET(opts->flags, FDE)) {
1307 if ((error = write_to_disk(dev, offset_backup, blksz,
1308 ehdr_backup, sizeof(*ehdr_backup))) != 0) {
1309 tc_log(1, "Could not write backup volume header to device\n");
1310 goto out;
1311 }
1312 }
1313 }
1314
1315 /* Everything went ok */
1316 tc_log(0, "All done!\n");
1317
1318 ret = 0;
1319
1320 out:
1321 if (pass)
1322 free_safe_mem(pass);
1323 if (pass_again)
1324 free_safe_mem(pass_again);
1325 if (ehdr)
1326 free_safe_mem(ehdr);
1327 if (ehdr_backup)
1328 free_safe_mem(ehdr_backup);
1329 if (info)
1330 free_safe_mem(info);
1331
1332 return ret;
1333 }
1334
1335 static
1336 int
dm_get_info(const char * name,struct dm_info * dmi)1337 dm_get_info(const char *name, struct dm_info *dmi)
1338 {
1339 struct dm_task *dmt = NULL;
1340 int error = -1;
1341
1342 if ((dmt = dm_task_create(DM_DEVICE_INFO)) == NULL)
1343 goto out;
1344
1345 if ((dm_task_set_name(dmt, name)) == 0)
1346 goto out;
1347
1348 if ((dm_task_run(dmt)) == 0)
1349 goto out;
1350
1351 if ((dm_task_get_info(dmt, dmi)) == 0)
1352 goto out;
1353
1354 error = 0;
1355
1356 out:
1357 if (dmt)
1358 dm_task_destroy(dmt);
1359
1360 return error;
1361 }
1362
1363 #if defined(__DragonFly__)
1364 static
1365 int
xlate_maj_min(const char * start_path __unused,int max_depth __unused,char * buf,size_t bufsz,uint32_t maj,uint32_t min)1366 xlate_maj_min(const char *start_path __unused, int max_depth __unused,
1367 char *buf, size_t bufsz, uint32_t maj, uint32_t min)
1368 {
1369 dev_t dev = makedev(maj, min);
1370
1371 snprintf(buf, bufsz, "/dev/%s", devname(dev, S_IFCHR));
1372 return 1;
1373 }
1374 #else
1375 static
1376 int
xlate_maj_min(const char * start_path,int max_depth,char * buf,size_t bufsz,uint32_t maj,uint32_t min)1377 xlate_maj_min(const char *start_path, int max_depth, char *buf, size_t bufsz,
1378 uint32_t maj, uint32_t min)
1379 {
1380 dev_t dev = makedev(maj, min);
1381 char path[PATH_MAX];
1382 struct stat sb;
1383 struct dirent *ent;
1384 DIR *dirp;
1385 int found = 0;
1386
1387 if (max_depth <= 0)
1388 return -1;
1389
1390 if ((dirp = opendir(start_path)) == NULL)
1391 return -1;
1392
1393 while ((ent = readdir(dirp)) != NULL) {
1394 /* d_name, d_type, DT_BLK, DT_CHR, DT_DIR, DT_LNK */
1395 if (ent->d_name[0] == '.')
1396 continue;
1397
1398 /* Linux' /dev is littered with junk, so skip over it */
1399 /*
1400 * The dm-<number> devices seem to be the raw DM devices
1401 * things in mapper/ link to.
1402 */
1403 if (((strcmp(ent->d_name, "block")) == 0) ||
1404 ((strcmp(ent->d_name, "fd")) == 0) ||
1405 (((strncmp(ent->d_name, "dm-", 3) == 0) && strlen(ent->d_name) <= 5)))
1406 continue;
1407
1408 snprintf(path, PATH_MAX, "%s/%s", start_path, ent->d_name);
1409
1410 if ((stat(path, &sb)) < 0)
1411 continue;
1412
1413 if (S_ISDIR(sb.st_mode)) {
1414 found = !xlate_maj_min(path, max_depth-1, buf, bufsz, maj, min);
1415 if (found)
1416 break;
1417 }
1418
1419 if (!S_ISBLK(sb.st_mode))
1420 continue;
1421
1422 if (sb.st_rdev != dev)
1423 continue;
1424
1425 snprintf(buf, bufsz, "%s", path);
1426 found = 1;
1427 break;
1428 }
1429
1430 if (dirp)
1431 closedir(dirp);
1432
1433 return found ? 0 : -ENOENT;
1434 }
1435 #endif
1436
1437 static
1438 struct tcplay_dm_table *
dm_get_table(const char * name)1439 dm_get_table(const char *name)
1440 {
1441 struct tcplay_dm_table *tc_table;
1442 struct dm_task *dmt = NULL;
1443 void *next = NULL;
1444 uint64_t start, length;
1445 char *target_type;
1446 char *params;
1447 char *p1;
1448 int c = 0;
1449 uint32_t maj, min;
1450
1451 if ((tc_table = (struct tcplay_dm_table *)alloc_safe_mem(sizeof(*tc_table))) == NULL) {
1452 tc_log(1, "could not allocate safe tc_table memory\n");
1453 return NULL;
1454 }
1455
1456 if ((dmt = dm_task_create(DM_DEVICE_TABLE)) == NULL)
1457 goto error;
1458
1459 if ((dm_task_set_name(dmt, name)) == 0)
1460 goto error;
1461
1462 if ((dm_task_run(dmt)) == 0)
1463 goto error;
1464
1465 tc_table->start = (off_t)0;
1466 tc_table->size = (size_t)0;
1467
1468 do {
1469 next = dm_get_next_target(dmt, next, &start, &length,
1470 &target_type, ¶ms);
1471
1472 tc_table->size += (size_t)length;
1473 strncpy(tc_table->target, target_type,
1474 sizeof(tc_table->target));
1475
1476 /* Skip any leading whitespace */
1477 while (params && *params == ' ')
1478 params++;
1479
1480 if (strcmp(target_type, "crypt") == 0) {
1481 while ((p1 = strsep(¶ms, " ")) != NULL) {
1482 /* Skip any whitespace before the next strsep */
1483 while (params && *params == ' ')
1484 params++;
1485
1486 /* Process p1 */
1487 if (c == 0) {
1488 /* cipher */
1489 strncpy(tc_table->cipher, p1,
1490 sizeof(tc_table->cipher));
1491 } else if (c == 2) {
1492 /* iv offset */
1493 tc_table->skip = (off_t)strtoll(p1, NULL, 10);
1494 } else if (c == 3) {
1495 /* major:minor */
1496 maj = strtoul(p1, NULL, 10);
1497 while (*p1 != ':' && *p1 != '\0')
1498 p1++;
1499 min = strtoul(++p1, NULL, 10);
1500 if ((xlate_maj_min("/dev", 2, tc_table->device,
1501 sizeof(tc_table->device), maj, min)) != 0)
1502 snprintf(tc_table->device,
1503 sizeof(tc_table->device),
1504 "%u:%u", maj, min);
1505 } else if (c == 4) {
1506 /* block offset */
1507 tc_table->offset = (off_t)strtoll(p1,
1508 NULL, 10);
1509 }
1510 ++c;
1511 }
1512
1513 if (c < 5) {
1514 tc_log(1, "could not get all the info required from "
1515 "the table\n");
1516 goto error;
1517 }
1518 }
1519 } while (next != NULL);
1520
1521 if (dmt)
1522 dm_task_destroy(dmt);
1523
1524 #ifdef DEBUG
1525 printf("device: %s\n", tc_table->device);
1526 printf("target: %s\n", tc_table->target);
1527 printf("cipher: %s\n", tc_table->cipher);
1528 printf("size: %ju\n", tc_table->size);
1529 printf("offset: %"PRId64"\n", tc_table->offset);
1530 printf("skip: %"PRId64"\n", tc_table->skip);
1531 #endif
1532
1533 return tc_table;
1534
1535 error:
1536 if (dmt)
1537 dm_task_destroy(dmt);
1538 if (tc_table)
1539 free_safe_mem(tc_table);
1540
1541 return NULL;
1542 }
1543
1544 struct tcplay_info *
dm_info_map(const char * map_name)1545 dm_info_map(const char *map_name)
1546 {
1547 struct dm_task *dmt = NULL;
1548 struct dm_info dmi[3];
1549 struct tcplay_dm_table *dm_table[3];
1550 struct tc_crypto_algo *crypto_algo;
1551 struct tcplay_info *info;
1552 char map[PATH_MAX];
1553 char ciphers[512];
1554 int i, outermost = -1;
1555
1556 memset(dm_table, 0, sizeof(dm_table));
1557
1558 if ((info = (struct tcplay_info *)alloc_safe_mem(sizeof(*info))) == NULL) {
1559 tc_log(1, "could not allocate safe info memory\n");
1560 return NULL;
1561 }
1562
1563 strncpy(map, map_name, PATH_MAX);
1564 for (i = 0; i < 3; i++) {
1565 if ((dm_get_info(map, &dmi[i])) != 0)
1566 goto error;
1567
1568 if (dmi[i].exists)
1569 dm_table[i] = dm_get_table(map);
1570
1571 snprintf(map, PATH_MAX, "%s.%d", map_name, i);
1572 }
1573
1574 if (dmt)
1575 dm_task_destroy(dmt);
1576
1577 if (dm_table[0] == NULL)
1578 goto error;
1579
1580 /*
1581 * Process our dmi, dm_table fun into the info structure.
1582 */
1583 /* First find which cipher chain we are using */
1584 ciphers[0] = '\0';
1585 for (i = 0; i < 3; i++) {
1586 if (dm_table[i] == NULL)
1587 continue;
1588
1589 if (outermost < i)
1590 outermost = i;
1591
1592 crypto_algo = &tc_crypto_algos[0];
1593 while ((crypto_algo != NULL) &&
1594 (strcmp(dm_table[i]->cipher, crypto_algo->dm_crypt_str) != 0))
1595 ++crypto_algo;
1596 if (crypto_algo == NULL) {
1597 tc_log(1, "could not find corresponding cipher\n");
1598 goto error;
1599 }
1600 strcat(ciphers, crypto_algo->name);
1601 strcat(ciphers, ",");
1602 }
1603 ciphers[strlen(ciphers)-1] = '\0';
1604
1605 info->cipher_chain = check_cipher_chain(ciphers, 1);
1606 if (info->cipher_chain == NULL) {
1607 tc_log(1, "could not find cipher chain\n");
1608 goto error;
1609 }
1610
1611 info->cipher_chain = tc_dup_cipher_chain(info->cipher_chain);
1612 if (info->cipher_chain == NULL) {
1613 tc_log(1, "could not dup cipher chain\n");
1614 goto error;
1615 }
1616
1617 /* Copy over the name */
1618 strncpy(info->dev, dm_table[outermost]->device, sizeof(info->dev));
1619
1620 /* Other fields */
1621 info->hdr = NULL;
1622 info->pbkdf_prf = NULL;
1623 info->start = dm_table[outermost]->start;
1624 info->size = dm_table[0]->size;
1625 info->skip = dm_table[outermost]->skip;
1626 info->offset = dm_table[outermost]->offset;
1627 info->blk_sz = 512;
1628
1629 for (i = 0; i < 3; i++)
1630 if (dm_table[i] != NULL)
1631 free_safe_mem(dm_table[i]);
1632
1633 return info;
1634
1635 error:
1636 if (dmt)
1637 dm_task_destroy(dmt);
1638 if (info)
1639 free_safe_mem(info);
1640 for (i = 0; i < 3; i++)
1641 if (dm_table[i] != NULL)
1642 free_safe_mem(dm_table[i]);
1643
1644 return NULL;
1645 }
1646
1647 static
1648 int
dm_exists_device(const char * name)1649 dm_exists_device(const char *name)
1650 {
1651 struct dm_info dmi;
1652 int exists = 0;
1653
1654 if (dm_get_info(name, &dmi) != 0)
1655 goto out;
1656
1657 exists = dmi.exists;
1658
1659 out:
1660 return exists;
1661 }
1662
1663 static
1664 int
dm_remove_device(const char * name)1665 dm_remove_device(const char *name)
1666 {
1667 struct dm_task *dmt = NULL;
1668 int ret = EINVAL;
1669
1670 if ((dmt = dm_task_create(DM_DEVICE_REMOVE)) == NULL)
1671 goto out;
1672
1673 if ((dm_task_set_name(dmt, name)) == 0)
1674 goto out;
1675
1676 if ((dm_task_run(dmt)) == 0)
1677 goto out;
1678
1679 ret = 0;
1680 out:
1681 if (dmt)
1682 dm_task_destroy(dmt);
1683
1684 return ret;
1685 }
1686
1687 int
dm_setup(const char * mapname,struct tcplay_info * info)1688 dm_setup(const char *mapname, struct tcplay_info *info)
1689 {
1690 struct tc_cipher_chain *cipher_chain;
1691 struct dm_task *dmt = NULL;
1692 struct dm_info dmi;
1693 char *params = NULL;
1694 char *uu, *uu_temp;
1695 char *uu_stack[64];
1696 int uu_stack_idx;
1697 #if defined(__DragonFly__)
1698 uint32_t status;
1699 #endif
1700 int r, ret = 0;
1701 int j, len;
1702 off_t start, offset;
1703 char dev[PATH_MAX];
1704 char map[PATH_MAX];
1705 uint32_t cookie;
1706
1707 dm_udev_set_sync_support(1);
1708
1709 if ((params = alloc_safe_mem(512)) == NULL) {
1710 tc_log(1, "could not allocate safe parameters memory");
1711 return ENOMEM;
1712 }
1713
1714 strcpy(dev, info->dev);
1715
1716 /*
1717 * Device Mapper blocks are always 512-byte blocks, so convert
1718 * from the "native" block size to the dm block size here.
1719 */
1720 start = INFO_TO_DM_BLOCKS(info, start);
1721 offset = INFO_TO_DM_BLOCKS(info, offset);
1722 uu_stack_idx = 0;
1723
1724 /*
1725 * Find length of cipher chain. Could use the for below, but doesn't
1726 * really matter.
1727 */
1728 len = tc_cipher_chain_length(info->cipher_chain);
1729
1730 /* Get to the end of the chain */
1731 for (cipher_chain = info->cipher_chain; cipher_chain->next != NULL;
1732 cipher_chain = cipher_chain->next)
1733 ;
1734
1735 /*
1736 * Start j at len-2, as we want to use .0, and the final one has no
1737 * suffix.
1738 */
1739 for (j = len-2; cipher_chain != NULL;
1740 cipher_chain = cipher_chain->prev, j--) {
1741
1742 cookie = 0;
1743
1744 if ((dmt = dm_task_create(DM_DEVICE_CREATE)) == NULL) {
1745 tc_log(1, "dm_task_create failed\n");
1746 ret = -1;
1747 goto out;
1748 }
1749
1750 /*
1751 * If this is the last element in the cipher chain, use the
1752 * final map name. Otherwise pick a secondary name...
1753 */
1754 if (cipher_chain->prev == NULL)
1755 strcpy(map, mapname);
1756 else
1757 sprintf(map, "%s.%d", mapname, j);
1758
1759 if ((dm_task_set_name(dmt, map)) == 0) {
1760 tc_log(1, "dm_task_set_name failed\n");
1761 ret = -1;
1762 goto out;
1763 }
1764
1765 #if defined(__linux__)
1766 uuid_generate(info->uuid);
1767 if ((uu_temp = malloc(1024)) == NULL) {
1768 tc_log(1, "uuid_unparse memory failed\n");
1769 ret = -1;
1770 goto out;
1771 }
1772 uuid_unparse(info->uuid, uu_temp);
1773 #elif defined(__DragonFly__)
1774 uuid_create(&info->uuid, &status);
1775 if (status != uuid_s_ok) {
1776 tc_log(1, "uuid_create failed\n");
1777 ret = -1;
1778 goto out;
1779 }
1780
1781 uuid_to_string(&info->uuid, &uu_temp, &status);
1782 if (uu_temp == NULL) {
1783 tc_log(1, "uuid_to_string failed\n");
1784 ret = -1;
1785 goto out;
1786 }
1787 #endif
1788
1789 if ((uu = malloc(1024)) == NULL) {
1790 free(uu_temp);
1791 tc_log(1, "uuid second malloc failed\n");
1792 ret = -1;
1793 goto out;
1794 }
1795
1796 snprintf(uu, 1024, "CRYPT-TCPLAY-%s", uu_temp);
1797 free(uu_temp);
1798
1799 if ((dm_task_set_uuid(dmt, uu)) == 0) {
1800 free(uu);
1801 tc_log(1, "dm_task_set_uuid failed\n");
1802 ret = -1;
1803 goto out;
1804 }
1805
1806 free(uu);
1807
1808 if (TC_FLAG_SET(info->flags, FDE)) {
1809 /*
1810 * When the full disk encryption (FDE) flag is set,
1811 * we map the first N sectors using a linear target
1812 * as they aren't encrypted.
1813 */
1814
1815 /* /dev/ad0s0a 0 */
1816 /* dev---^ block off --^ */
1817 snprintf(params, 512, "%s 0", dev);
1818
1819 if ((dm_task_add_target(dmt, 0,
1820 INFO_TO_DM_BLOCKS(info, offset),
1821 "linear", params)) == 0) {
1822 tc_log(1, "dm_task_add_target failed\n");
1823 ret = -1;
1824 goto out;
1825 }
1826
1827 start = INFO_TO_DM_BLOCKS(info, offset);
1828 }
1829
1830 /* aes-cbc-essiv:sha256 7997f8af... 0 /dev/ad0s0a 8 <opts> */
1831 /* iv off---^ block off--^ <opts> */
1832 snprintf(params, 512, "%s %s %"PRIu64 " %s %"PRIu64 " %s",
1833 cipher_chain->cipher->dm_crypt_str, cipher_chain->dm_key,
1834 (uint64_t)INFO_TO_DM_BLOCKS(info, skip), dev,
1835 (uint64_t)offset,
1836 TC_FLAG_SET(info->flags, ALLOW_TRIM) ? "1 allow_discards" : "");
1837 #ifdef DEBUG
1838 printf("Params: %s\n", params);
1839 #endif
1840
1841 if ((dm_task_add_target(dmt, start,
1842 INFO_TO_DM_BLOCKS(info, size), "crypt", params)) == 0) {
1843 tc_log(1, "dm_task_add_target failed\n");
1844 ret = -1;
1845 goto out;
1846 }
1847
1848 if ((dm_task_set_cookie(dmt, &cookie, 0)) == 0) {
1849 tc_log(1, "dm_task_set_cookie failed\n");
1850 ret = -1;
1851 goto out;
1852 }
1853
1854 if ((dm_task_run(dmt)) == 0) {
1855 dm_udev_wait(cookie);
1856 tc_log(1, "dm_task_run failed\n");
1857 ret = -1;
1858 goto out;
1859 }
1860
1861 if ((dm_task_get_info(dmt, &dmi)) == 0) {
1862 dm_udev_wait(cookie);
1863 tc_log(1, "dm_task_get info failed\n");
1864 ret = -1;
1865 goto out;
1866 }
1867
1868 dm_udev_wait(cookie);
1869
1870 if ((r = asprintf(&uu_stack[uu_stack_idx++], "%s", map)) < 0)
1871 tc_log(1, "warning, asprintf failed. won't be able to "
1872 "unroll changes\n");
1873
1874
1875 offset = 0;
1876 start = 0;
1877 sprintf(dev, "/dev/mapper/%s.%d", mapname, j);
1878
1879 dm_task_destroy(dmt);
1880 dm_task_update_nodes();
1881 }
1882
1883 out:
1884 /*
1885 * If an error occured, try to unroll changes made before it
1886 * happened.
1887 */
1888 if (ret) {
1889 j = uu_stack_idx;
1890 while (j > 0) {
1891 #ifdef DEBUG
1892 printf("Unrolling dm changes! j = %d (%s)\n", j-1,
1893 uu_stack[j-1]);
1894 #endif
1895 if ((uu_stack[j-1] == NULL) ||
1896 ((r = dm_remove_device(uu_stack[--j])) != 0)) {
1897 tc_log(1, "Tried to unroll dm changes, "
1898 "giving up.\n");
1899 break;
1900 }
1901 }
1902 }
1903
1904 while (uu_stack_idx > 0)
1905 free(uu_stack[--uu_stack_idx]);
1906
1907 free_safe_mem(params);
1908
1909 return ret;
1910 }
1911
1912 int
dm_teardown(const char * mapname,const char * device __unused)1913 dm_teardown(const char *mapname, const char *device __unused)
1914 {
1915 #if 0
1916 struct dm_task *dmt = NULL;
1917 struct dm_info dmi;
1918 #endif
1919 char map[PATH_MAX];
1920 int i, error;
1921
1922 if ((error = dm_remove_device(mapname)) != 0) {
1923 tc_log(1, "Could not remove mapping %s\n", mapname);
1924 return error;
1925 }
1926
1927 /* Try to remove other cascade devices */
1928 for (i = 0; i < 2; i++) {
1929 sprintf(map, "%s.%d", mapname, i);
1930 if (dm_exists_device(map))
1931 dm_remove_device(map);
1932 }
1933
1934 return 0;
1935 }
1936
1937 struct tc_crypto_algo *
check_cipher(const char * cipher,int quiet)1938 check_cipher(const char *cipher, int quiet)
1939 {
1940 int i, found = 0;
1941
1942 for (i = 0; tc_crypto_algos[i].name != NULL; i++) {
1943 if (strcmp(cipher, tc_crypto_algos[i].name) == 0) {
1944 found = 1;
1945 break;
1946 }
1947 }
1948
1949 if (!found && !quiet) {
1950 fprintf(stderr, "Valid ciphers are: ");
1951 for (i = 0; tc_crypto_algos[i].name != NULL; i++)
1952 fprintf(stderr, "%s ", tc_crypto_algos[i].name);
1953 fprintf(stderr, "\n");
1954 return NULL;
1955 }
1956
1957 return &tc_crypto_algos[i];
1958 }
1959
1960 struct tc_cipher_chain *
check_cipher_chain(const char * cipher_chain,int quiet)1961 check_cipher_chain(const char *cipher_chain, int quiet)
1962 {
1963 struct tc_cipher_chain *cipher = NULL;
1964 int i,k, nciphers = 0, mismatch = 0;
1965 char *ciphers[8];
1966 char *tmp_chain, *tmp_chain_free;
1967 char *token;
1968
1969 if ((tmp_chain = strdup(cipher_chain)) == NULL) {
1970 tc_log(1, "Could not allocate strdup memory\n");
1971 return NULL;
1972 }
1973
1974 tmp_chain_free = tmp_chain;
1975
1976 while ((token = strsep(&tmp_chain, ",")) != NULL)
1977 ciphers[nciphers++] = token;
1978
1979 cipher = NULL;
1980
1981 for (i = 0; valid_cipher_chains[i][0] != NULL; i++) {
1982 mismatch = 0;
1983
1984 for (k = 0; (valid_cipher_chains[i][k] != NULL); k++) {
1985 /*
1986 * If there are more ciphers in the chain than in the
1987 * ciphers[] variable this is not the right chain.
1988 */
1989 if (k == nciphers) {
1990 mismatch = 1;
1991 break;
1992 }
1993
1994 if (strcmp(ciphers[k], valid_cipher_chains[i][k]) != 0)
1995 mismatch = 1;
1996 }
1997
1998 /*
1999 * If all ciphers matched and there are exactly nciphers,
2000 * then we found the right cipher chain.
2001 */
2002 if ((k == nciphers) && !mismatch) {
2003 cipher = tc_cipher_chains[i];
2004 break;
2005 }
2006 }
2007
2008 if (cipher == NULL) {
2009 tc_log(1, "Invalid cipher: %s\n", cipher_chain);
2010 if (!quiet) {
2011 fprintf(stderr, "Valid cipher chains are:\n");
2012 for (i = 0; valid_cipher_chains[i][0] != NULL; i++) {
2013 for (k = 0; valid_cipher_chains[i][k] != NULL;
2014 k++) {
2015 fprintf(stderr, "%s%c",
2016 valid_cipher_chains[i][k],
2017 (valid_cipher_chains[i][k+1] != NULL) ?
2018 ',' : '\0');
2019 }
2020 fprintf(stderr, "\n");
2021 }
2022 }
2023 }
2024
2025 free(tmp_chain_free);
2026 return cipher;
2027 }
2028
2029 struct pbkdf_prf_algo *
check_prf_algo(const char * algo,int sys,int quiet)2030 check_prf_algo(const char *algo, int sys, int quiet)
2031 {
2032 int i, found = 0;
2033
2034 for (i = 0; pbkdf_prf_algos[i].name != NULL; i++) {
2035 if (sys != pbkdf_prf_algos[i].sys)
2036 continue;
2037
2038 if (strcmp(algo, pbkdf_prf_algos[i].name) == 0) {
2039 found = 1;
2040 break;
2041 }
2042 }
2043
2044 if (!found && !quiet) {
2045 fprintf(stderr, "Valid PBKDF PRF algorithms are: ");
2046 for (i = 0; pbkdf_prf_algos[i].name != NULL; i++) {
2047 if (sys != pbkdf_prf_algos[i].sys)
2048 continue;
2049 fprintf(stderr, "%s ", pbkdf_prf_algos[i].name);
2050 }
2051 fprintf(stderr, "\n");
2052 return NULL;
2053 }
2054
2055 return &pbkdf_prf_algos[i];
2056 }
2057
2058 int
tc_play_init(void)2059 tc_play_init(void)
2060 {
2061 int error;
2062
2063 if ((error = tc_build_cipher_chains()) != 0)
2064 return error;
2065
2066 if ((error = tc_crypto_init()) != 0)
2067 return error;
2068
2069 return 0;
2070 }
2071
opts_init(void)2072 struct tcplay_opts *opts_init(void)
2073 {
2074 struct tcplay_opts *opts;
2075
2076 if ((opts = (struct tcplay_opts *)alloc_safe_mem(sizeof(*opts))) == NULL) {
2077 tc_log(1, "could not allocate safe opts memory\n");
2078 return NULL;
2079 }
2080
2081 memset(opts, 0, sizeof(*opts));
2082
2083 opts->retries = DEFAULT_RETRIES;
2084 opts->secure_erase = 1;
2085
2086 return opts;
2087 }
2088
2089 int
opts_add_keyfile(struct tcplay_opts * opts,const char * keyfile)2090 opts_add_keyfile(struct tcplay_opts *opts, const char *keyfile)
2091 {
2092 const char *keyf;
2093
2094 if (opts->nkeyfiles == MAX_KEYFILES)
2095 return -1;
2096
2097 if ((keyf = strdup_safe_mem(keyfile)) == NULL) {
2098 return -1;
2099 }
2100
2101 opts->keyfiles[opts->nkeyfiles++] = keyf;
2102
2103 return 0;
2104 }
2105
2106 int
opts_add_keyfile_hidden(struct tcplay_opts * opts,const char * keyfile)2107 opts_add_keyfile_hidden(struct tcplay_opts *opts, const char *keyfile)
2108 {
2109 const char *keyf;
2110
2111 if (opts->n_hkeyfiles == MAX_KEYFILES)
2112 return -1;
2113
2114 if ((keyf = strdup_safe_mem(keyfile)) == NULL) {
2115 return -1;
2116 }
2117
2118 opts->h_keyfiles[opts->n_hkeyfiles++] = keyf;
2119
2120 return 0;
2121 }
2122
2123 int
opts_add_keyfile_new(struct tcplay_opts * opts,const char * keyfile)2124 opts_add_keyfile_new(struct tcplay_opts *opts, const char *keyfile)
2125 {
2126 const char *keyf;
2127
2128 if (opts->n_newkeyfiles == MAX_KEYFILES)
2129 return -1;
2130
2131 if ((keyf = strdup_safe_mem(keyfile)) == NULL) {
2132 return -1;
2133 }
2134
2135 opts->new_keyfiles[opts->n_newkeyfiles++] = keyf;
2136
2137 return 0;
2138 }
2139
2140 void
opts_clear_keyfile(struct tcplay_opts * opts)2141 opts_clear_keyfile(struct tcplay_opts *opts)
2142 {
2143 int i;
2144
2145 for (i = 0; i < opts->nkeyfiles; i++) {
2146 free_safe_mem(opts->keyfiles[i]);
2147 }
2148
2149 opts->nkeyfiles = 0;
2150 }
2151
2152 void
opts_clear_keyfile_hidden(struct tcplay_opts * opts)2153 opts_clear_keyfile_hidden(struct tcplay_opts *opts)
2154 {
2155 int i;
2156
2157 for (i = 0; i < opts->n_hkeyfiles; i++) {
2158 free_safe_mem(opts->h_keyfiles[i]);
2159 }
2160
2161 opts->n_hkeyfiles = 0;
2162 }
2163
2164
2165 void
opts_clear_keyfile_new(struct tcplay_opts * opts)2166 opts_clear_keyfile_new(struct tcplay_opts *opts)
2167 {
2168 int i;
2169
2170 for (i = 0; i < opts->n_newkeyfiles; i++) {
2171 free_safe_mem(opts->new_keyfiles[i]);
2172 }
2173
2174 opts->n_newkeyfiles = 0;
2175 }
2176
2177
2178 void
opts_free(struct tcplay_opts * opts)2179 opts_free(struct tcplay_opts *opts)
2180 {
2181 int i;
2182
2183 for (i = 0; i < opts->nkeyfiles; i++) {
2184 free_safe_mem(opts->keyfiles[i]);
2185 }
2186
2187 for (i = 0; i < opts->n_hkeyfiles; i++) {
2188 free_safe_mem(opts->h_keyfiles[i]);
2189 }
2190
2191 for (i = 0; i < opts->n_newkeyfiles; i++) {
2192 free_safe_mem(opts->new_keyfiles[i]);
2193 }
2194
2195 if (opts->dev)
2196 free_safe_mem(opts->dev);
2197 if (opts->passphrase)
2198 free_safe_mem(opts->passphrase);
2199 if (opts->h_passphrase)
2200 free_safe_mem(opts->h_passphrase);
2201 if (opts->new_passphrase)
2202 free_safe_mem(opts->new_passphrase);
2203 if (opts->map_name)
2204 free_safe_mem(opts->map_name);
2205 if (opts->sys_dev)
2206 free_safe_mem(opts->sys_dev);
2207 if (opts->hdr_file_in)
2208 free_safe_mem(opts->hdr_file_in);
2209 if (opts->h_hdr_file_in)
2210 free_safe_mem(opts->h_hdr_file_in);
2211 if (opts->hdr_file_out)
2212 free_safe_mem(opts->hdr_file_out);
2213
2214 free_safe_mem(opts);
2215 }
2216