"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/tcrypt/tcrypt.c" (13 Jan 2022, 33070 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:


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 "tcrypt.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.3.6_vs_2.4.0.

    1 /*
    2  * TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling
    3  *
    4  * Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
    5  * Copyright (C) 2012-2021 Milan Broz
    6  *
    7  * This file is free software; you can redistribute it and/or
    8  * modify it under the terms of the GNU Lesser General Public
    9  * License as published by the Free Software Foundation; either
   10  * version 2.1 of the License, or (at your option) any later version.
   11  *
   12  * This file is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15  * Lesser General Public License for more details.
   16  *
   17  * You should have received a copy of the GNU Lesser General Public
   18  * License along with this file; if not, write to the Free Software
   19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   20  */
   21 
   22 #include <errno.h>
   23 #include <stdio.h>
   24 #include <stdlib.h>
   25 #include <string.h>
   26 #include <assert.h>
   27 
   28 #include "libcryptsetup.h"
   29 #include "tcrypt.h"
   30 #include "internal.h"
   31 
   32 /* TCRYPT PBKDF variants */
   33 static const struct {
   34     unsigned int legacy:1;
   35     unsigned int veracrypt:1;
   36     const char *name;
   37     const char *hash;
   38     unsigned int iterations;
   39     uint32_t veracrypt_pim_const;
   40     uint32_t veracrypt_pim_mult;
   41 } tcrypt_kdf[] = {
   42     { 0, 0, "pbkdf2", "ripemd160",   2000, 0, 0 },
   43     { 0, 0, "pbkdf2", "ripemd160",   1000, 0, 0 },
   44     { 0, 0, "pbkdf2", "sha512",      1000, 0, 0 },
   45     { 0, 0, "pbkdf2", "whirlpool",   1000, 0, 0 },
   46     { 1, 0, "pbkdf2", "sha1",        2000, 0, 0 },
   47     { 0, 1, "pbkdf2", "sha512",    500000, 15000, 1000 },
   48     { 0, 1, "pbkdf2", "whirlpool", 500000, 15000, 1000 },
   49     { 0, 1, "pbkdf2", "sha256",    500000, 15000, 1000 }, // VeraCrypt 1.0f
   50     { 0, 1, "pbkdf2", "sha256",    200000,     0, 2048 }, // boot only
   51     { 0, 1, "pbkdf2", "ripemd160", 655331, 15000, 1000 },
   52     { 0, 1, "pbkdf2", "ripemd160", 327661,     0, 2048 }, // boot only
   53     { 0, 1, "pbkdf2", "stribog512",500000, 15000, 1000 },
   54 //  { 0, 1, "pbkdf2", "stribog512",200000,     0, 2048 }, // boot only
   55     { 0, 0,     NULL,        NULL,      0,     0,    0 }
   56 };
   57 
   58 struct tcrypt_alg {
   59         const char *name;
   60         unsigned int key_size;
   61         unsigned int iv_size;
   62         unsigned int key_offset;
   63         unsigned int iv_offset; /* or tweak key offset */
   64         unsigned int key_extra_size;
   65 };
   66 
   67 struct tcrypt_algs {
   68     unsigned int legacy:1;
   69     unsigned int chain_count;
   70     unsigned int chain_key_size;
   71     const char *long_name;
   72     const char *mode;
   73     struct tcrypt_alg cipher[3];
   74 };
   75 
   76 /* TCRYPT cipher variants */
   77 static struct tcrypt_algs tcrypt_cipher[] = {
   78 /* XTS mode */
   79 {0,1,64,"aes","xts-plain64",
   80     {{"aes",    64,16,0,32,0}}},
   81 {0,1,64,"serpent","xts-plain64",
   82     {{"serpent",64,16,0,32,0}}},
   83 {0,1,64,"twofish","xts-plain64",
   84     {{"twofish",64,16,0,32,0}}},
   85 {0,2,128,"twofish-aes","xts-plain64",
   86     {{"twofish",64,16, 0,64,0},
   87      {"aes",    64,16,32,96,0}}},
   88 {0,3,192,"serpent-twofish-aes","xts-plain64",
   89     {{"serpent",64,16, 0, 96,0},
   90      {"twofish",64,16,32,128,0},
   91      {"aes",    64,16,64,160,0}}},
   92 {0,2,128,"aes-serpent","xts-plain64",
   93     {{"aes",    64,16, 0,64,0},
   94      {"serpent",64,16,32,96,0}}},
   95 {0,3,192,"aes-twofish-serpent","xts-plain64",
   96     {{"aes",    64,16, 0, 96,0},
   97      {"twofish",64,16,32,128,0},
   98      {"serpent",64,16,64,160,0}}},
   99 {0,2,128,"serpent-twofish","xts-plain64",
  100     {{"serpent",64,16, 0,64,0},
  101      {"twofish",64,16,32,96,0}}},
  102 {0,1,64,"camellia","xts-plain64",
  103     {{"camellia",    64,16,0,32,0}}},
  104 {0,1,64,"kuznyechik","xts-plain64",
  105     {{"kuznyechik",  64,16,0,32,0}}},
  106 {0,2,128,"kuznyechik-camellia","xts-plain64",
  107     {{"kuznyechik",64,16, 0,64,0},
  108      {"camellia",  64,16,32,96,0}}},
  109 {0,2,128,"twofish-kuznyechik","xts-plain64",
  110     {{"twofish",   64,16, 0,64,0},
  111      {"kuznyechik",64,16,32,96,0}}},
  112 {0,2,128,"serpent-camellia","xts-plain64",
  113     {{"serpent",   64,16, 0,64,0},
  114      {"camellia",  64,16,32,96,0}}},
  115 {0,2,128,"aes-kuznyechik","xts-plain64",
  116     {{"aes",       64,16, 0,64,0},
  117      {"kuznyechik",64,16,32,96,0}}},
  118 {0,3,192,"camellia-serpent-kuznyechik","xts-plain64",
  119     {{"camellia",  64,16, 0, 96,0},
  120      {"serpent",   64,16,32,128,0},
  121      {"kuznyechik",64,16,64,160,0}}},
  122 
  123 /* LRW mode */
  124 {0,1,48,"aes","lrw-benbi",
  125     {{"aes",    48,16,32,0,0}}},
  126 {0,1,48,"serpent","lrw-benbi",
  127     {{"serpent",48,16,32,0,0}}},
  128 {0,1,48,"twofish","lrw-benbi",
  129     {{"twofish",48,16,32,0,0}}},
  130 {0,2,96,"twofish-aes","lrw-benbi",
  131     {{"twofish",48,16,32,0,0},
  132      {"aes",    48,16,64,0,0}}},
  133 {0,3,144,"serpent-twofish-aes","lrw-benbi",
  134     {{"serpent",48,16,32,0,0},
  135      {"twofish",48,16,64,0,0},
  136      {"aes",    48,16,96,0,0}}},
  137 {0,2,96,"aes-serpent","lrw-benbi",
  138     {{"aes",    48,16,32,0,0},
  139      {"serpent",48,16,64,0,0}}},
  140 {0,3,144,"aes-twofish-serpent","lrw-benbi",
  141     {{"aes",    48,16,32,0,0},
  142      {"twofish",48,16,64,0,0},
  143      {"serpent",48,16,96,0,0}}},
  144 {0,2,96,"serpent-twofish", "lrw-benbi",
  145     {{"serpent",48,16,32,0,0},
  146      {"twofish",48,16,64,0,0}}},
  147 
  148 /* Kernel LRW block size is fixed to 16 bytes for GF(2^128)
  149  * thus cannot be used with blowfish where block is 8 bytes.
  150  * There also no GF(2^64) support.
  151 {1,1,64,"blowfish_le","lrw-benbi",
  152      {{"blowfish_le",64,8,32,0,0}}},
  153 {1,2,112,"blowfish_le-aes","lrw-benbi",
  154      {{"blowfish_le",64, 8,32,0,0},
  155       {"aes",        48,16,88,0,0}}},
  156 {1,3,160,"serpent-blowfish_le-aes","lrw-benbi",
  157       {{"serpent",    48,16, 32,0,0},
  158        {"blowfish_le",64, 8, 64,0,0},
  159        {"aes",        48,16,120,0,0}}},*/
  160 
  161 /*
  162  * CBC + "outer" CBC (both with whitening)
  163  * chain_key_size: alg_keys_bytes + IV_seed_bytes + whitening_bytes
  164  */
  165 {1,1,32+16+16,"aes","cbc-tcw",
  166     {{"aes",    32,16,32,0,32}}},
  167 {1,1,32+16+16,"serpent","cbc-tcw",
  168     {{"serpent",32,16,32,0,32}}},
  169 {1,1,32+16+16,"twofish","cbc-tcw",
  170     {{"twofish",32,16,32,0,32}}},
  171 {1,2,64+16+16,"twofish-aes","cbci-tcrypt",
  172     {{"twofish",32,16,32,0,0},
  173      {"aes",    32,16,64,0,32}}},
  174 {1,3,96+16+16,"serpent-twofish-aes","cbci-tcrypt",
  175     {{"serpent",32,16,32,0,0},
  176      {"twofish",32,16,64,0,0},
  177      {"aes",    32,16,96,0,32}}},
  178 {1,2,64+16+16,"aes-serpent","cbci-tcrypt",
  179     {{"aes",    32,16,32,0,0},
  180      {"serpent",32,16,64,0,32}}},
  181 {1,3,96+16+16,"aes-twofish-serpent", "cbci-tcrypt",
  182     {{"aes",    32,16,32,0,0},
  183      {"twofish",32,16,64,0,0},
  184      {"serpent",32,16,96,0,32}}},
  185 {1,2,64+16+16,"serpent-twofish", "cbci-tcrypt",
  186     {{"serpent",32,16,32,0,0},
  187      {"twofish",32,16,64,0,32}}},
  188 {1,1,16+8+16,"cast5","cbc-tcw",
  189     {{"cast5",   16,8,32,0,24}}},
  190 {1,1,24+8+16,"des3_ede","cbc-tcw",
  191     {{"des3_ede",24,8,32,0,24}}},
  192 {1,1,56+8+16,"blowfish_le","cbc-tcrypt",
  193     {{"blowfish_le",56,8,32,0,24}}},
  194 {1,2,88+16+16,"blowfish_le-aes","cbc-tcrypt",
  195     {{"blowfish_le",56, 8,32,0,0},
  196      {"aes",        32,16,88,0,32}}},
  197 {1,3,120+16+16,"serpent-blowfish_le-aes","cbc-tcrypt",
  198     {{"serpent",    32,16, 32,0,0},
  199      {"blowfish_le",56, 8, 64,0,0},
  200      {"aes",        32,16,120,0,32}}},
  201 {}
  202 };
  203 
  204 static int TCRYPT_hdr_from_disk(struct crypt_device *cd,
  205                 struct tcrypt_phdr *hdr,
  206                 struct crypt_params_tcrypt *params,
  207                 int kdf_index, int cipher_index)
  208 {
  209     uint32_t crc32;
  210     size_t size;
  211 
  212     /* Check CRC32 of header */
  213     size = TCRYPT_HDR_LEN - sizeof(hdr->d.keys) - sizeof(hdr->d.header_crc32);
  214     crc32 = crypt_crc32(~0, (unsigned char*)&hdr->d, size) ^ ~0;
  215     if (be16_to_cpu(hdr->d.version) > 3 &&
  216         crc32 != be32_to_cpu(hdr->d.header_crc32)) {
  217         log_dbg(cd, "TCRYPT header CRC32 mismatch.");
  218         return -EINVAL;
  219     }
  220 
  221     /* Check CRC32 of keys */
  222     crc32 = crypt_crc32(~0, (unsigned char*)hdr->d.keys, sizeof(hdr->d.keys)) ^ ~0;
  223     if (crc32 != be32_to_cpu(hdr->d.keys_crc32)) {
  224         log_dbg(cd, "TCRYPT keys CRC32 mismatch.");
  225         return -EINVAL;
  226     }
  227 
  228     /* Convert header to cpu format */
  229     hdr->d.version  =  be16_to_cpu(hdr->d.version);
  230     hdr->d.version_tc = be16_to_cpu(hdr->d.version_tc);
  231 
  232     hdr->d.keys_crc32 = be32_to_cpu(hdr->d.keys_crc32);
  233 
  234     hdr->d.hidden_volume_size = be64_to_cpu(hdr->d.hidden_volume_size);
  235     hdr->d.volume_size        = be64_to_cpu(hdr->d.volume_size);
  236 
  237     hdr->d.mk_offset = be64_to_cpu(hdr->d.mk_offset);
  238     if (!hdr->d.mk_offset)
  239         hdr->d.mk_offset = 512;
  240 
  241     hdr->d.mk_size = be64_to_cpu(hdr->d.mk_size);
  242 
  243     hdr->d.flags = be32_to_cpu(hdr->d.flags);
  244 
  245     hdr->d.sector_size = be32_to_cpu(hdr->d.sector_size);
  246     if (!hdr->d.sector_size)
  247         hdr->d.sector_size = 512;
  248 
  249     hdr->d.header_crc32 = be32_to_cpu(hdr->d.header_crc32);
  250 
  251     /* Set params */
  252     params->passphrase = NULL;
  253     params->passphrase_size = 0;
  254     params->hash_name  = tcrypt_kdf[kdf_index].hash;
  255     params->key_size = tcrypt_cipher[cipher_index].chain_key_size;
  256     params->cipher = tcrypt_cipher[cipher_index].long_name;
  257     params->mode = tcrypt_cipher[cipher_index].mode;
  258 
  259     return 0;
  260 }
  261 
  262 /*
  263  * Kernel implements just big-endian version of blowfish, hack it here
  264  */
  265 static void TCRYPT_swab_le(char *buf)
  266 {
  267     uint32_t *l = (uint32_t*)&buf[0];
  268     uint32_t *r = (uint32_t*)&buf[4];
  269     *l = swab32(*l);
  270     *r = swab32(*r);
  271 }
  272 
  273 static int decrypt_blowfish_le_cbc(struct tcrypt_alg *alg,
  274                    const char *key, char *buf)
  275 {
  276     int bs = alg->iv_size;
  277     char iv[8], iv_old[8];
  278     struct crypt_cipher *cipher = NULL;
  279     int i, j, r;
  280 
  281     assert(bs == 8);
  282 
  283     r = crypt_cipher_init(&cipher, "blowfish", "ecb",
  284                   &key[alg->key_offset], alg->key_size);
  285     if (r < 0)
  286         return r;
  287 
  288     memcpy(iv, &key[alg->iv_offset], alg->iv_size);
  289     for (i = 0; i < TCRYPT_HDR_LEN; i += bs) {
  290         memcpy(iv_old, &buf[i], bs);
  291         TCRYPT_swab_le(&buf[i]);
  292         r = crypt_cipher_decrypt(cipher, &buf[i], &buf[i],
  293                       bs, NULL, 0);
  294         TCRYPT_swab_le(&buf[i]);
  295         if (r < 0)
  296             break;
  297         for (j = 0; j < bs; j++)
  298             buf[i + j] ^= iv[j];
  299         memcpy(iv, iv_old, bs);
  300     }
  301 
  302     crypt_cipher_destroy(cipher);
  303     crypt_safe_memzero(iv, bs);
  304     crypt_safe_memzero(iv_old, bs);
  305     return r;
  306 }
  307 
  308 static void TCRYPT_remove_whitening(char *buf, const char *key)
  309 {
  310     int j;
  311 
  312     for (j = 0; j < TCRYPT_HDR_LEN; j++)
  313         buf[j] ^= key[j % 8];
  314 }
  315 
  316 static void TCRYPT_copy_key(struct tcrypt_alg *alg, const char *mode,
  317                  char *out_key, const char *key)
  318 {
  319     int ks2;
  320     if (!strncmp(mode, "xts", 3)) {
  321         ks2 = alg->key_size / 2;
  322         memcpy(out_key, &key[alg->key_offset], ks2);
  323         memcpy(&out_key[ks2], &key[alg->iv_offset], ks2);
  324     } else if (!strncmp(mode, "lrw", 3)) {
  325         ks2 = alg->key_size - TCRYPT_LRW_IKEY_LEN;
  326         memcpy(out_key, &key[alg->key_offset], ks2);
  327         memcpy(&out_key[ks2], key, TCRYPT_LRW_IKEY_LEN);
  328     } else if (!strncmp(mode, "cbc", 3)) {
  329         memcpy(out_key, &key[alg->key_offset], alg->key_size);
  330         /* IV + whitening */
  331         memcpy(&out_key[alg->key_size], &key[alg->iv_offset],
  332                alg->key_extra_size);
  333     }
  334 }
  335 
  336 static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode,
  337                    const char *key,struct tcrypt_phdr *hdr)
  338 {
  339     char backend_key[TCRYPT_HDR_KEY_LEN];
  340     char iv[TCRYPT_HDR_IV_LEN] = {};
  341     char mode_name[MAX_CIPHER_LEN + 1];
  342     struct crypt_cipher *cipher;
  343     char *c, *buf = (char*)&hdr->e;
  344     int r;
  345 
  346     /* Remove IV if present */
  347     mode_name[MAX_CIPHER_LEN] = '\0';
  348     strncpy(mode_name, mode, MAX_CIPHER_LEN);
  349     c = strchr(mode_name, '-');
  350     if (c)
  351         *c = '\0';
  352 
  353     if (!strncmp(mode, "lrw", 3))
  354         iv[alg->iv_size - 1] = 1;
  355     else if (!strncmp(mode, "cbc", 3)) {
  356         TCRYPT_remove_whitening(buf, &key[8]);
  357         if (!strcmp(alg->name, "blowfish_le"))
  358             return decrypt_blowfish_le_cbc(alg, key, buf);
  359         memcpy(iv, &key[alg->iv_offset], alg->iv_size);
  360     }
  361 
  362     TCRYPT_copy_key(alg, mode, backend_key, key);
  363     r = crypt_cipher_init(&cipher, alg->name, mode_name,
  364                   backend_key, alg->key_size);
  365     if (!r) {
  366         r = crypt_cipher_decrypt(cipher, buf, buf, TCRYPT_HDR_LEN,
  367                      iv, alg->iv_size);
  368         crypt_cipher_destroy(cipher);
  369     }
  370 
  371     crypt_safe_memzero(backend_key, sizeof(backend_key));
  372     crypt_safe_memzero(iv, TCRYPT_HDR_IV_LEN);
  373     return r;
  374 }
  375 
  376 /*
  377  * For chained ciphers and CBC mode we need "outer" decryption.
  378  * Backend doesn't provide this, so implement it here directly using ECB.
  379  */
  380 static int TCRYPT_decrypt_cbci(struct tcrypt_algs *ciphers,
  381                 const char *key, struct tcrypt_phdr *hdr)
  382 {
  383     struct crypt_cipher *cipher[3];
  384     unsigned int bs = ciphers->cipher[0].iv_size;
  385     char *buf = (char*)&hdr->e, iv[16], iv_old[16];
  386     unsigned int i, j;
  387     int r = -EINVAL;
  388 
  389     assert(ciphers->chain_count <= 3);
  390     assert(bs <= 16);
  391 
  392     TCRYPT_remove_whitening(buf, &key[8]);
  393 
  394     memcpy(iv, &key[ciphers->cipher[0].iv_offset], bs);
  395 
  396     /* Initialize all ciphers in chain in ECB mode */
  397     for (j = 0; j < ciphers->chain_count; j++)
  398         cipher[j] = NULL;
  399     for (j = 0; j < ciphers->chain_count; j++) {
  400         r = crypt_cipher_init(&cipher[j], ciphers->cipher[j].name, "ecb",
  401                       &key[ciphers->cipher[j].key_offset],
  402                       ciphers->cipher[j].key_size);
  403         if (r < 0)
  404             goto out;
  405     }
  406 
  407     /* Implements CBC with chained ciphers in loop inside */
  408     for (i = 0; i < TCRYPT_HDR_LEN; i += bs) {
  409         memcpy(iv_old, &buf[i], bs);
  410         for (j = ciphers->chain_count; j > 0; j--) {
  411             r = crypt_cipher_decrypt(cipher[j - 1], &buf[i], &buf[i],
  412                           bs, NULL, 0);
  413             if (r < 0)
  414                 goto out;
  415         }
  416         for (j = 0; j < bs; j++)
  417             buf[i + j] ^= iv[j];
  418         memcpy(iv, iv_old, bs);
  419     }
  420 out:
  421     for (j = 0; j < ciphers->chain_count; j++)
  422         if (cipher[j])
  423             crypt_cipher_destroy(cipher[j]);
  424 
  425     crypt_safe_memzero(iv, bs);
  426     crypt_safe_memzero(iv_old, bs);
  427     return r;
  428 }
  429 
  430 static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
  431                    const char *key, struct crypt_params_tcrypt *params)
  432 {
  433     struct tcrypt_phdr hdr2;
  434     int i, j, r = -EINVAL;
  435 
  436     for (i = 0; tcrypt_cipher[i].chain_count; i++) {
  437         if (params->cipher && !strstr(tcrypt_cipher[i].long_name, params->cipher))
  438             continue;
  439         if (!(params->flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_cipher[i].legacy)
  440             continue;
  441         log_dbg(cd, "TCRYPT:  trying cipher %s-%s",
  442             tcrypt_cipher[i].long_name, tcrypt_cipher[i].mode);
  443 
  444         memcpy(&hdr2.e, &hdr->e, TCRYPT_HDR_LEN);
  445 
  446         if (!strncmp(tcrypt_cipher[i].mode, "cbci", 4))
  447             r = TCRYPT_decrypt_cbci(&tcrypt_cipher[i], key, &hdr2);
  448         else for (j = tcrypt_cipher[i].chain_count - 1; j >= 0 ; j--) {
  449             if (!tcrypt_cipher[i].cipher[j].name)
  450                 continue;
  451             r = TCRYPT_decrypt_hdr_one(&tcrypt_cipher[i].cipher[j],
  452                         tcrypt_cipher[i].mode, key, &hdr2);
  453             if (r < 0)
  454                 break;
  455         }
  456 
  457         if (r < 0) {
  458             log_dbg(cd, "TCRYPT:   returned error %d, skipped.", r);
  459             if (r == -ENOTSUP)
  460                 break;
  461             r = -ENOENT;
  462             continue;
  463         }
  464 
  465         if (!strncmp(hdr2.d.magic, TCRYPT_HDR_MAGIC, TCRYPT_HDR_MAGIC_LEN)) {
  466             log_dbg(cd, "TCRYPT: Signature magic detected.");
  467             memcpy(&hdr->e, &hdr2.e, TCRYPT_HDR_LEN);
  468             r = i;
  469             break;
  470         }
  471         if ((params->flags & CRYPT_TCRYPT_VERA_MODES) &&
  472              !strncmp(hdr2.d.magic, VCRYPT_HDR_MAGIC, TCRYPT_HDR_MAGIC_LEN)) {
  473             log_dbg(cd, "TCRYPT: Signature magic detected (Veracrypt).");
  474             memcpy(&hdr->e, &hdr2.e, TCRYPT_HDR_LEN);
  475             r = i;
  476             break;
  477         }
  478         r = -EPERM;
  479     }
  480 
  481     crypt_safe_memzero(&hdr2, sizeof(hdr2));
  482     return r;
  483 }
  484 
  485 static int TCRYPT_pool_keyfile(struct crypt_device *cd,
  486                 unsigned char pool[VCRYPT_KEY_POOL_LEN],
  487                 const char *keyfile, int keyfiles_pool_length)
  488 {
  489     unsigned char *data;
  490     int i, j, fd, data_size, r = -EIO;
  491     uint32_t crc;
  492 
  493     log_dbg(cd, "TCRYPT: using keyfile %s.", keyfile);
  494 
  495     data = malloc(TCRYPT_KEYFILE_LEN);
  496     if (!data)
  497         return -ENOMEM;
  498     memset(data, 0, TCRYPT_KEYFILE_LEN);
  499 
  500     fd = open(keyfile, O_RDONLY);
  501     if (fd < 0) {
  502         log_err(cd, _("Failed to open key file."));
  503         goto out;
  504     }
  505 
  506     data_size = read_buffer(fd, data, TCRYPT_KEYFILE_LEN);
  507     close(fd);
  508     if (data_size < 0) {
  509         log_err(cd, _("Error reading keyfile %s."), keyfile);
  510         goto out;
  511     }
  512 
  513     for (i = 0, j = 0, crc = ~0U; i < data_size; i++) {
  514         crc = crypt_crc32(crc, &data[i], 1);
  515         pool[j++] += (unsigned char)(crc >> 24);
  516         pool[j++] += (unsigned char)(crc >> 16);
  517         pool[j++] += (unsigned char)(crc >>  8);
  518         pool[j++] += (unsigned char)(crc);
  519         j %= keyfiles_pool_length;
  520     }
  521     r = 0;
  522 out:
  523     crypt_safe_memzero(&crc, sizeof(crc));
  524     crypt_safe_memzero(data, TCRYPT_KEYFILE_LEN);
  525     free(data);
  526 
  527     return r;
  528 }
  529 
  530 static int TCRYPT_init_hdr(struct crypt_device *cd,
  531                struct tcrypt_phdr *hdr,
  532                struct crypt_params_tcrypt *params)
  533 {
  534     unsigned char pwd[VCRYPT_KEY_POOL_LEN] = {};
  535     size_t passphrase_size, max_passphrase_size;
  536     char *key;
  537     unsigned int i, skipped = 0, iterations;
  538     int r = -EPERM, keyfiles_pool_length;
  539 
  540     if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
  541         return -ENOMEM;
  542 
  543     if (params->flags & CRYPT_TCRYPT_VERA_MODES &&
  544         params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
  545         /* Really. Keyfile pool length depends on passphrase size in Veracrypt. */
  546         max_passphrase_size = VCRYPT_KEY_POOL_LEN;
  547         keyfiles_pool_length = VCRYPT_KEY_POOL_LEN;
  548     } else {
  549         max_passphrase_size = TCRYPT_KEY_POOL_LEN;
  550         keyfiles_pool_length = TCRYPT_KEY_POOL_LEN;
  551     }
  552 
  553     if (params->keyfiles_count)
  554         passphrase_size = max_passphrase_size;
  555     else
  556         passphrase_size = params->passphrase_size;
  557 
  558     if (params->passphrase_size > max_passphrase_size) {
  559         log_err(cd, _("Maximum TCRYPT passphrase length (%zu) exceeded."),
  560                   max_passphrase_size);
  561         goto out;
  562     }
  563 
  564     /* Calculate pool content from keyfiles */
  565     for (i = 0; i < params->keyfiles_count; i++) {
  566         r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i], keyfiles_pool_length);
  567         if (r < 0)
  568             goto out;
  569     }
  570 
  571     /* If provided password, combine it with pool */
  572     for (i = 0; i < params->passphrase_size; i++)
  573         pwd[i] += params->passphrase[i];
  574 
  575     for (i = 0; tcrypt_kdf[i].name; i++) {
  576         if (params->hash_name && strcmp(params->hash_name, tcrypt_kdf[i].hash))
  577             continue;
  578         if (!(params->flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_kdf[i].legacy)
  579             continue;
  580         if (!(params->flags & CRYPT_TCRYPT_VERA_MODES) && tcrypt_kdf[i].veracrypt)
  581             continue;
  582         if ((params->flags & CRYPT_TCRYPT_VERA_MODES) && params->veracrypt_pim) {
  583             /* Do not try TrueCrypt modes if we have PIM value */
  584             if (!tcrypt_kdf[i].veracrypt)
  585                 continue;
  586             /* adjust iterations to given PIM cmdline parameter */
  587             iterations = tcrypt_kdf[i].veracrypt_pim_const +
  588                     (tcrypt_kdf[i].veracrypt_pim_mult * params->veracrypt_pim);
  589         } else
  590             iterations = tcrypt_kdf[i].iterations;
  591 
  592         /* Derive header key */
  593         log_dbg(cd, "TCRYPT: trying KDF: %s-%s-%d%s.",
  594             tcrypt_kdf[i].name, tcrypt_kdf[i].hash, tcrypt_kdf[i].iterations,
  595             params->veracrypt_pim && tcrypt_kdf[i].veracrypt ? "-PIM" : "");
  596         r = crypt_pbkdf(tcrypt_kdf[i].name, tcrypt_kdf[i].hash,
  597                 (char*)pwd, passphrase_size,
  598                 hdr->salt, TCRYPT_HDR_SALT_LEN,
  599                 key, TCRYPT_HDR_KEY_LEN,
  600                 iterations, 0, 0);
  601         if (r < 0) {
  602             log_verbose(cd, _("PBKDF2 hash algorithm %s not available, skipping."),
  603                       tcrypt_kdf[i].hash);
  604             continue;
  605         }
  606 
  607         /* Decrypt header */
  608         r = TCRYPT_decrypt_hdr(cd, hdr, key, params);
  609         if (r == -ENOENT) {
  610             skipped++;
  611             r = -EPERM;
  612         }
  613         if (r != -EPERM)
  614             break;
  615     }
  616 
  617     if ((r < 0 && r != -EPERM && skipped && skipped == i) || r == -ENOTSUP) {
  618         log_err(cd, _("Required kernel crypto interface not available."));
  619 #ifdef ENABLE_AF_ALG
  620         log_err(cd, _("Ensure you have algif_skcipher kernel module loaded."));
  621 #endif
  622     }
  623     if (r < 0)
  624         goto out;
  625 
  626     r = TCRYPT_hdr_from_disk(cd, hdr, params, i, r);
  627     if (!r) {
  628         log_dbg(cd, "TCRYPT: Magic: %s, Header version: %d, req. %d, sector %d"
  629             ", mk_offset %" PRIu64 ", hidden_size %" PRIu64
  630             ", volume size %" PRIu64, tcrypt_kdf[i].veracrypt ?
  631             VCRYPT_HDR_MAGIC : TCRYPT_HDR_MAGIC,
  632             (int)hdr->d.version, (int)hdr->d.version_tc, (int)hdr->d.sector_size,
  633             hdr->d.mk_offset, hdr->d.hidden_volume_size, hdr->d.volume_size);
  634         log_dbg(cd, "TCRYPT: Header cipher %s-%s, key size %zu",
  635             params->cipher, params->mode, params->key_size);
  636     }
  637 out:
  638     crypt_safe_memzero(pwd, TCRYPT_KEY_POOL_LEN);
  639     if (key)
  640         crypt_safe_memzero(key, TCRYPT_HDR_KEY_LEN);
  641     free(key);
  642     return r;
  643 }
  644 
  645 int TCRYPT_read_phdr(struct crypt_device *cd,
  646              struct tcrypt_phdr *hdr,
  647              struct crypt_params_tcrypt *params)
  648 {
  649     struct device *base_device = NULL, *device = crypt_metadata_device(cd);
  650     ssize_t hdr_size = sizeof(struct tcrypt_phdr);
  651     char *base_device_path;
  652     int devfd, r;
  653 
  654     assert(sizeof(struct tcrypt_phdr) == 512);
  655 
  656     log_dbg(cd, "Reading TCRYPT header of size %zu bytes from device %s.",
  657         hdr_size, device_path(device));
  658 
  659     if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER &&
  660         crypt_dev_is_partition(device_path(device))) {
  661         base_device_path = crypt_get_base_device(device_path(device));
  662 
  663         log_dbg(cd, "Reading TCRYPT system header from device %s.", base_device_path ?: "?");
  664         if (!base_device_path)
  665             return -EINVAL;
  666 
  667         r = device_alloc(cd, &base_device, base_device_path);
  668         free(base_device_path);
  669         if (r < 0)
  670             return r;
  671         devfd = device_open(cd, base_device, O_RDONLY);
  672     } else
  673         devfd = device_open(cd, device, O_RDONLY);
  674 
  675     if (devfd < 0) {
  676         device_free(cd, base_device);
  677         log_err(cd, _("Cannot open device %s."), device_path(device));
  678         return -EINVAL;
  679     }
  680 
  681     r = -EIO;
  682     if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) {
  683         if (read_lseek_blockwise(devfd, device_block_size(cd, device),
  684             device_alignment(device), hdr, hdr_size,
  685             TCRYPT_HDR_SYSTEM_OFFSET) == hdr_size) {
  686             r = TCRYPT_init_hdr(cd, hdr, params);
  687         }
  688     } else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
  689         if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) {
  690             if (read_lseek_blockwise(devfd, device_block_size(cd, device),
  691                 device_alignment(device), hdr, hdr_size,
  692                 TCRYPT_HDR_HIDDEN_OFFSET_BCK) == hdr_size)
  693                 r = TCRYPT_init_hdr(cd, hdr, params);
  694         } else {
  695             if (read_lseek_blockwise(devfd, device_block_size(cd, device),
  696                 device_alignment(device), hdr, hdr_size,
  697                 TCRYPT_HDR_HIDDEN_OFFSET) == hdr_size)
  698                 r = TCRYPT_init_hdr(cd, hdr, params);
  699             if (r && read_lseek_blockwise(devfd, device_block_size(cd, device),
  700                 device_alignment(device), hdr, hdr_size,
  701                 TCRYPT_HDR_HIDDEN_OFFSET_OLD) == hdr_size)
  702                 r = TCRYPT_init_hdr(cd, hdr, params);
  703         }
  704     } else if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) {
  705         if (read_lseek_blockwise(devfd, device_block_size(cd, device),
  706             device_alignment(device), hdr, hdr_size,
  707             TCRYPT_HDR_OFFSET_BCK) == hdr_size)
  708             r = TCRYPT_init_hdr(cd, hdr, params);
  709     } else if (read_lseek_blockwise(devfd, device_block_size(cd, device),
  710             device_alignment(device), hdr, hdr_size, 0) == hdr_size)
  711         r = TCRYPT_init_hdr(cd, hdr, params);
  712 
  713     device_free(cd, base_device);
  714     if (r < 0)
  715         memset(hdr, 0, sizeof (*hdr));
  716     return r;
  717 }
  718 
  719 static struct tcrypt_algs *TCRYPT_get_algs(const char *cipher, const char *mode)
  720 {
  721     int i;
  722 
  723     if (!cipher || !mode)
  724         return NULL;
  725 
  726     for (i = 0; tcrypt_cipher[i].chain_count; i++)
  727         if (!strcmp(tcrypt_cipher[i].long_name, cipher) &&
  728             !strcmp(tcrypt_cipher[i].mode, mode))
  729             return &tcrypt_cipher[i];
  730 
  731     return NULL;
  732 }
  733 
  734 int TCRYPT_activate(struct crypt_device *cd,
  735              const char *name,
  736              struct tcrypt_phdr *hdr,
  737              struct crypt_params_tcrypt *params,
  738              uint32_t flags)
  739 {
  740     char dm_name[PATH_MAX], dm_dev_name[PATH_MAX], cipher_spec[MAX_CIPHER_LEN*2+1];
  741     char *part_path;
  742     unsigned int i;
  743     int r;
  744     uint32_t req_flags, dmc_flags;
  745     struct tcrypt_algs *algs;
  746     enum devcheck device_check;
  747     uint64_t offset = crypt_get_data_offset(cd);
  748     struct volume_key *vk = NULL;
  749     struct device  *ptr_dev = crypt_data_device(cd), *device = NULL, *part_device = NULL;
  750     struct crypt_dm_active_device dmd = {
  751         .flags = flags
  752     };
  753 
  754     if (!hdr->d.version) {
  755         log_dbg(cd, "TCRYPT: this function is not supported without encrypted header load.");
  756         return -ENOTSUP;
  757     }
  758 
  759     if (hdr->d.sector_size % SECTOR_SIZE) {
  760         log_err(cd, _("Activation is not supported for %d sector size."),
  761             hdr->d.sector_size);
  762         return -ENOTSUP;
  763     }
  764 
  765     if (strstr(params->mode, "-tcrypt")) {
  766         log_err(cd, _("Kernel does not support activation for this TCRYPT legacy mode."));
  767         return -ENOTSUP;
  768     }
  769 
  770     if (strstr(params->mode, "-tcw"))
  771         req_flags = DM_TCW_SUPPORTED;
  772     else
  773         req_flags = DM_PLAIN64_SUPPORTED;
  774 
  775     algs = TCRYPT_get_algs(params->cipher, params->mode);
  776     if (!algs)
  777         return -EINVAL;
  778 
  779     if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
  780         dmd.size = 0;
  781     else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER)
  782         dmd.size = hdr->d.hidden_volume_size / SECTOR_SIZE;
  783     else
  784         dmd.size = hdr->d.volume_size / SECTOR_SIZE;
  785 
  786     if (dmd.flags & CRYPT_ACTIVATE_SHARED)
  787         device_check = DEV_OK;
  788     else
  789         device_check = DEV_EXCL;
  790 
  791     if ((params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) &&
  792          !crypt_dev_is_partition(device_path(crypt_data_device(cd)))) {
  793         part_path = crypt_get_partition_device(device_path(crypt_data_device(cd)),
  794                                crypt_get_data_offset(cd), dmd.size);
  795         if (part_path) {
  796             if (!device_alloc(cd, &part_device, part_path)) {
  797                 log_verbose(cd, _("Activating TCRYPT system encryption for partition %s."),
  798                         part_path);
  799                 ptr_dev = part_device;
  800                 offset = 0;
  801             }
  802             free(part_path);
  803         } else
  804             /*
  805              * System encryption use the whole device mapping, there can
  806              * be active partitions.
  807              */
  808             device_check = DEV_OK;
  809     }
  810 
  811     r = device_block_adjust(cd, ptr_dev, device_check,
  812                 offset, &dmd.size, &dmd.flags);
  813     if (r)
  814         goto out;
  815 
  816     /* From here, key size for every cipher must be the same */
  817     vk = crypt_alloc_volume_key(algs->cipher[0].key_size +
  818                     algs->cipher[0].key_extra_size, NULL);
  819     if (!vk) {
  820         r = -ENOMEM;
  821         goto out;
  822     }
  823 
  824     for (i = algs->chain_count; i > 0; i--) {
  825         if (i == 1) {
  826             dm_name[sizeof(dm_name)-1] = '\0';
  827             strncpy(dm_name, name, sizeof(dm_name)-1);
  828             dmd.flags = flags;
  829         } else {
  830             snprintf(dm_name, sizeof(dm_name), "%s_%d", name, i-1);
  831             dmd.flags = flags | CRYPT_ACTIVATE_PRIVATE;
  832         }
  833 
  834         TCRYPT_copy_key(&algs->cipher[i-1], algs->mode,
  835                 vk->key, hdr->d.keys);
  836 
  837         if (algs->chain_count != i) {
  838             snprintf(dm_dev_name, sizeof(dm_dev_name), "%s/%s_%d",
  839                  dm_get_dir(), name, i);
  840             r = device_alloc(cd, &device, dm_dev_name);
  841             if (r)
  842                 break;
  843             ptr_dev = device;
  844             offset = 0;
  845         }
  846 
  847         r = snprintf(cipher_spec, sizeof(cipher_spec), "%s-%s", algs->cipher[i-1].name, algs->mode);
  848         if (r < 0 || (size_t)r >= sizeof(cipher_spec)) {
  849             r = -ENOMEM;
  850             break;
  851         }
  852 
  853         r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, ptr_dev, vk,
  854                 cipher_spec, crypt_get_iv_offset(cd), offset,
  855                 crypt_get_integrity(cd),
  856                 crypt_get_integrity_tag_size(cd),
  857                 crypt_get_sector_size(cd));
  858         if (r)
  859             break;
  860 
  861         log_dbg(cd, "Trying to activate TCRYPT device %s using cipher %s.",
  862             dm_name, dmd.segment.u.crypt.cipher);
  863         r = dm_create_device(cd, dm_name, CRYPT_TCRYPT, &dmd);
  864 
  865         dm_targets_free(cd, &dmd);
  866         device_free(cd, device);
  867         device = NULL;
  868 
  869         if (r)
  870             break;
  871     }
  872 
  873     if (r < 0 &&
  874         (dm_flags(cd, DM_CRYPT, &dmc_flags) || ((dmc_flags & req_flags) != req_flags))) {
  875         log_err(cd, _("Kernel does not support TCRYPT compatible mapping."));
  876         r = -ENOTSUP;
  877     }
  878 
  879 out:
  880     crypt_free_volume_key(vk);
  881     device_free(cd, device);
  882     device_free(cd, part_device);
  883     return r;
  884 }
  885 
  886 static int TCRYPT_remove_one(struct crypt_device *cd, const char *name,
  887               const char *base_uuid, int index, uint32_t flags)
  888 {
  889     struct crypt_dm_active_device dmd;
  890     char dm_name[PATH_MAX];
  891     int r;
  892 
  893     if (snprintf(dm_name, sizeof(dm_name), "%s_%d", name, index) < 0)
  894         return -ENOMEM;
  895 
  896     r = dm_status_device(cd, dm_name);
  897     if (r < 0)
  898         return r;
  899 
  900     r = dm_query_device(cd, dm_name, DM_ACTIVE_UUID, &dmd);
  901     if (!r && !strncmp(dmd.uuid, base_uuid, strlen(base_uuid)))
  902         r = dm_remove_device(cd, dm_name, flags);
  903 
  904     free(CONST_CAST(void*)dmd.uuid);
  905     return r;
  906 }
  907 
  908 int TCRYPT_deactivate(struct crypt_device *cd, const char *name, uint32_t flags)
  909 {
  910     struct crypt_dm_active_device dmd;
  911     int r;
  912 
  913     r = dm_query_device(cd, name, DM_ACTIVE_UUID, &dmd);
  914     if (r < 0)
  915         return r;
  916     if (!dmd.uuid)
  917         return -EINVAL;
  918 
  919     r = dm_remove_device(cd, name, flags);
  920     if (r < 0)
  921         goto out;
  922 
  923     r = TCRYPT_remove_one(cd, name, dmd.uuid, 1, flags);
  924     if (r < 0)
  925         goto out;
  926 
  927     r = TCRYPT_remove_one(cd, name, dmd.uuid, 2, flags);
  928 out:
  929     free(CONST_CAST(void*)dmd.uuid);
  930     return (r == -ENODEV) ? 0 : r;
  931 }
  932 
  933 static int TCRYPT_status_one(struct crypt_device *cd, const char *name,
  934                  const char *base_uuid, int index,
  935                  size_t *key_size, char *cipher,
  936                  struct tcrypt_phdr *tcrypt_hdr,
  937                  struct device **device)
  938 {
  939     struct crypt_dm_active_device dmd;
  940     struct dm_target *tgt = &dmd.segment;
  941     char dm_name[PATH_MAX], *c;
  942     int r;
  943 
  944     if (snprintf(dm_name, sizeof(dm_name), "%s_%d", name, index) < 0)
  945         return -ENOMEM;
  946 
  947     r = dm_status_device(cd, dm_name);
  948     if (r < 0)
  949         return r;
  950 
  951     r = dm_query_device(cd, dm_name, DM_ACTIVE_DEVICE |
  952                       DM_ACTIVE_UUID |
  953                       DM_ACTIVE_CRYPT_CIPHER |
  954                       DM_ACTIVE_CRYPT_KEYSIZE, &dmd);
  955     if (r < 0)
  956         return r;
  957     if (!single_segment(&dmd) || tgt->type != DM_CRYPT) {
  958         r = -ENOTSUP;
  959         goto out;
  960     }
  961 
  962     r = 0;
  963 
  964     if (!strncmp(dmd.uuid, base_uuid, strlen(base_uuid))) {
  965         if ((c = strchr(tgt->u.crypt.cipher, '-')))
  966             *c = '\0';
  967         strcat(cipher, "-");
  968         strncat(cipher, tgt->u.crypt.cipher, MAX_CIPHER_LEN);
  969         *key_size += tgt->u.crypt.vk->keylength;
  970         tcrypt_hdr->d.mk_offset = tgt->u.crypt.offset * SECTOR_SIZE;
  971         device_free(cd, *device);
  972         MOVE_REF(*device, tgt->data_device);
  973     } else
  974         r = -ENODEV;
  975 out:
  976     dm_targets_free(cd, &dmd);
  977     free(CONST_CAST(void*)dmd.uuid);
  978     return r;
  979 }
  980 
  981 int TCRYPT_init_by_name(struct crypt_device *cd, const char *name,
  982             const char *uuid,
  983             const struct dm_target *tgt,
  984             struct device **device,
  985             struct crypt_params_tcrypt *tcrypt_params,
  986             struct tcrypt_phdr *tcrypt_hdr)
  987 {
  988     struct tcrypt_algs *algs;
  989     char cipher[MAX_CIPHER_LEN * 4], mode[MAX_CIPHER_LEN+1], *tmp;
  990     size_t key_size;
  991     int r;
  992 
  993     memset(tcrypt_params, 0, sizeof(*tcrypt_params));
  994     memset(tcrypt_hdr, 0, sizeof(*tcrypt_hdr));
  995     tcrypt_hdr->d.sector_size = SECTOR_SIZE;
  996     tcrypt_hdr->d.mk_offset = tgt->u.crypt.offset * SECTOR_SIZE;
  997 
  998     strncpy(cipher, tgt->u.crypt.cipher, MAX_CIPHER_LEN);
  999     tmp = strchr(cipher, '-');
 1000     if (!tmp)
 1001         return -EINVAL;
 1002     *tmp = '\0';
 1003     mode[MAX_CIPHER_LEN] = '\0';
 1004     strncpy(mode, ++tmp, MAX_CIPHER_LEN);
 1005 
 1006     key_size = tgt->u.crypt.vk->keylength;
 1007     r = TCRYPT_status_one(cd, name, uuid, 1, &key_size,
 1008                   cipher, tcrypt_hdr, device);
 1009     if (!r)
 1010         r = TCRYPT_status_one(cd, name, uuid, 2, &key_size,
 1011                       cipher, tcrypt_hdr, device);
 1012 
 1013     if (r < 0 && r != -ENODEV)
 1014         return r;
 1015 
 1016     algs = TCRYPT_get_algs(cipher, mode);
 1017     if (!algs || key_size != algs->chain_key_size)
 1018         return -EINVAL;
 1019 
 1020     tcrypt_params->key_size = algs->chain_key_size;
 1021     tcrypt_params->cipher = algs->long_name;
 1022     tcrypt_params->mode = algs->mode;
 1023     return 0;
 1024 }
 1025 
 1026 uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
 1027                  struct tcrypt_phdr *hdr,
 1028                  struct crypt_params_tcrypt *params)
 1029 {
 1030     uint64_t size;
 1031 
 1032     if (!hdr->d.version) {
 1033         /* No real header loaded, initialized by active device, use default mk_offset */
 1034     } else if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) {
 1035         /* Mapping through whole device, not partition! */
 1036         if (crypt_dev_is_partition(device_path(crypt_data_device(cd))))
 1037             return 0;
 1038     } else if (params->mode && !strncmp(params->mode, "xts", 3)) {
 1039         if (hdr->d.version < 3)
 1040             return 1;
 1041 
 1042         if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
 1043             if (hdr->d.version > 3)
 1044                 return (hdr->d.mk_offset / SECTOR_SIZE);
 1045             if (device_size(crypt_metadata_device(cd), &size) < 0)
 1046                 return 0;
 1047             return (size - hdr->d.hidden_volume_size +
 1048                 (TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / SECTOR_SIZE;
 1049         }
 1050     } else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
 1051         if (device_size(crypt_metadata_device(cd), &size) < 0)
 1052             return 0;
 1053         return (size - hdr->d.hidden_volume_size +
 1054             (TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / SECTOR_SIZE;
 1055     }
 1056 
 1057     return hdr->d.mk_offset / SECTOR_SIZE;
 1058 }
 1059 
 1060 uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
 1061                   struct tcrypt_phdr *hdr,
 1062                   struct crypt_params_tcrypt *params)
 1063 {
 1064     uint64_t iv_offset;
 1065 
 1066     if (params->mode && !strncmp(params->mode, "xts", 3))
 1067         iv_offset = TCRYPT_get_data_offset(cd, hdr, params);
 1068     else if (params->mode && !strncmp(params->mode, "lrw", 3))
 1069         iv_offset = 0;
 1070     else
 1071         iv_offset = hdr->d.mk_offset / SECTOR_SIZE;
 1072 
 1073     if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
 1074         iv_offset += crypt_dev_partition_offset(device_path(crypt_data_device(cd)));
 1075 
 1076     return iv_offset;
 1077 }
 1078 
 1079 int TCRYPT_get_volume_key(struct crypt_device *cd,
 1080               struct tcrypt_phdr *hdr,
 1081               struct crypt_params_tcrypt *params,
 1082               struct volume_key **vk)
 1083 {
 1084     struct tcrypt_algs *algs;
 1085     unsigned int i, key_index;
 1086 
 1087     if (!hdr->d.version) {
 1088         log_err(cd, _("This function is not supported without TCRYPT header load."));
 1089         return -ENOTSUP;
 1090     }
 1091 
 1092     algs = TCRYPT_get_algs(params->cipher, params->mode);
 1093     if (!algs)
 1094         return -EINVAL;
 1095 
 1096     *vk = crypt_alloc_volume_key(params->key_size, NULL);
 1097     if (!*vk)
 1098         return -ENOMEM;
 1099 
 1100     for (i = 0, key_index = 0; i < algs->chain_count; i++) {
 1101         TCRYPT_copy_key(&algs->cipher[i], algs->mode,
 1102                 &(*vk)->key[key_index], hdr->d.keys);
 1103         key_index += algs->cipher[i].key_size;
 1104     }
 1105 
 1106     return 0;
 1107 }
 1108 
 1109 int TCRYPT_dump(struct crypt_device *cd,
 1110         struct tcrypt_phdr *hdr,
 1111         struct crypt_params_tcrypt *params)
 1112 {
 1113     log_std(cd, "%s header information for %s\n",
 1114         hdr->d.magic[0] == 'T' ? "TCRYPT" : "VERACRYPT",
 1115         device_path(crypt_metadata_device(cd)));
 1116     if (hdr->d.version) {
 1117         log_std(cd, "Version:       \t%d\n", hdr->d.version);
 1118         log_std(cd, "Driver req.:\t%x.%x\n", hdr->d.version_tc >> 8,
 1119                             hdr->d.version_tc & 0xFF);
 1120 
 1121         log_std(cd, "Sector size:\t%" PRIu32 "\n", hdr->d.sector_size);
 1122         log_std(cd, "MK offset:\t%" PRIu64 "\n", hdr->d.mk_offset);
 1123         log_std(cd, "PBKDF2 hash:\t%s\n", params->hash_name);
 1124     }
 1125     log_std(cd, "Cipher chain:\t%s\n", params->cipher);
 1126     log_std(cd, "Cipher mode:\t%s\n", params->mode);
 1127     log_std(cd, "MK bits:       \t%zu\n", params->key_size * 8);
 1128     return 0;
 1129 }