xref: /dragonfly/lib/libtcplay/tcplay.c (revision 7b1e1c8e1e00f6479eba04708b37a13383f7e197)
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, &params);
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(&params, " ")) != 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