"Fossies" - the Fresh Open Source Software Archive

Member "tc-play-3.3/tcplay.c" (2 Mar 2020, 50972 Bytes) of package /linux/misc/tc-play-3.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tcplay.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.1_vs_3.3.

    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 }