Update tcplay from 2.0 to 3.3
[dragonfly.git] / lib / libtcplay / tcplay.c
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
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
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 *
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
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
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
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 *
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
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
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 *
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
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
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
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
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 *
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
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
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
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
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
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
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
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 *
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 *
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
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
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
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
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 *
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 *
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 *
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
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
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
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
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
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
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
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
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
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 }