"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/bitlk/bitlk.c" (13 Jan 2022, 44043 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 "bitlk.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.4.2_vs_2.4.3.

    1 /*
    2  * BITLK (BitLocker-compatible) volume handling
    3  *
    4  * Copyright (C) 2019-2021 Red Hat, Inc. All rights reserved.
    5  * Copyright (C) 2019-2021 Milan Broz
    6  * Copyright (C) 2019-2021 Vojtech Trefny
    7  *
    8  * This file is free software; you can redistribute it and/or
    9  * modify it under the terms of the GNU Lesser General Public
   10  * License as published by the Free Software Foundation; either
   11  * version 2.1 of the License, or (at your option) any later version.
   12  *
   13  * This file is distributed in the hope that it will be useful,
   14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   16  * Lesser General Public License for more details.
   17  *
   18  * You should have received a copy of the GNU Lesser General Public
   19  * License along with this file; if not, write to the Free Software
   20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   21  */
   22 
   23 #include <errno.h>
   24 #include <string.h>
   25 #include <uuid/uuid.h>
   26 #include <time.h>
   27 #include <iconv.h>
   28 #include <limits.h>
   29 
   30 #include "bitlk.h"
   31 #include "internal.h"
   32 
   33 #define BITLK_BOOTCODE_V1 "\xeb\x52\x90"
   34 #define BITLK_BOOTCODE_V2 "\xeb\x58\x90"
   35 #define BITLK_SIGNATURE "-FVE-FS-"
   36 #define BITLK_SIGNATURE_TOGO "MSWIN4.1"
   37 #define BITLK_HEADER_METADATA_OFFSET 160
   38 #define BITLK_HEADER_METADATA_OFFSET_TOGO 424
   39 
   40 /* FVE metadata header is split into two parts */
   41 #define BITLK_FVE_METADATA_BLOCK_HEADER_LEN 64
   42 #define BITLK_FVE_METADATA_HEADER_LEN 48
   43 #define BITLK_FVE_METADATA_HEADERS_LEN BITLK_FVE_METADATA_BLOCK_HEADER_LEN + BITLK_FVE_METADATA_HEADER_LEN
   44 
   45 /* total size of the FVE area (64 KiB) */
   46 #define BITLK_FVE_METADATA_SIZE 64 * 1024
   47 
   48 #define BITLK_ENTRY_HEADER_LEN 8
   49 #define BITLK_VMK_HEADER_LEN 28
   50 
   51 #define BITLK_OPEN_KEY_METADATA_LEN 12
   52 
   53 #define BITLK_RECOVERY_KEY_LEN 55
   54 #define BITLK_RECOVERY_PARTS 8
   55 #define BITLK_RECOVERY_PART_LEN 6
   56 
   57 #define BITLK_BEK_FILE_HEADER_LEN 48
   58 #define BITLK_STARTUP_KEY_HEADER_LEN 24
   59 
   60 #define BITLK_KDF_HASH "sha256"
   61 #define BITLK_KDF_ITERATION_COUNT 0x100000
   62 
   63 /* maximum number of segments for the DM device */
   64 #define MAX_BITLK_SEGMENTS 10
   65 
   66 /* January 1, 1970 as MS file time */
   67 #define EPOCH_AS_FILETIME 116444736000000000
   68 #define HUNDREDS_OF_NANOSECONDS 10000000
   69 
   70 /* not available in older version of libuuid */
   71 #ifndef UUID_STR_LEN
   72 #define UUID_STR_LEN    37
   73 #endif
   74 
   75 /* known types of GUIDs from the BITLK superblock */
   76 const uint8_t BITLK_GUID_NORMAL[16] = { 0x3b, 0xd6, 0x67, 0x49, 0x29, 0x2e, 0xd8, 0x4a,
   77                     0x83, 0x99, 0xf6, 0xa3, 0x39, 0xe3, 0xd0, 0x01 };
   78 const uint8_t BITLK_GUID_EOW[16] = { 0x3b, 0x4d, 0xa8, 0x92, 0x80, 0xdd, 0x0e, 0x4d,
   79                      0x9e, 0x4e, 0xb1, 0xe3, 0x28, 0x4e, 0xae, 0xd8 };
   80 
   81 /* taken from libfdisk gpt.c -- TODO: this is a good candidate for adding to libuuid */
   82 struct bitlk_guid {
   83     uint32_t   time_low;
   84     uint16_t   time_mid;
   85     uint16_t   time_hi_and_version;
   86     uint8_t    clock_seq_hi;
   87     uint8_t    clock_seq_low;
   88     uint8_t    node[6];
   89 } __attribute__ ((packed));
   90 
   91 static void swap_guid(struct bitlk_guid *guid) {
   92     guid->time_low = swab32(guid->time_low);
   93     guid->time_mid = swab16(guid->time_mid);
   94     guid->time_hi_and_version = swab16(guid->time_hi_and_version);
   95 }
   96 
   97 static void guid_to_string(struct bitlk_guid *guid, char *out) {
   98     swap_guid(guid);
   99     uuid_unparse((unsigned char *) guid, out);
  100 }
  101 
  102 typedef enum {
  103     BITLK_SEGTYPE_CRYPT,
  104     BITLK_SEGTYPE_ZERO,
  105 } BitlkSegmentType;
  106 
  107 struct segment {
  108     uint64_t offset;
  109     uint64_t length;
  110     uint64_t iv_offset;
  111     BitlkSegmentType type;
  112 };
  113 
  114 struct bitlk_signature {
  115     uint8_t boot_code[3];
  116     uint8_t signature[8];
  117     uint16_t sector_size;
  118 } __attribute__ ((packed));
  119 
  120 struct bitlk_superblock {
  121     struct bitlk_guid guid;
  122     uint64_t fve_offset[3];
  123 } __attribute__ ((packed));
  124 
  125 struct bitlk_fve_metadata {
  126     /* FVE metadata block header */
  127     uint8_t signature[8];
  128     uint16_t fve_size;
  129     uint16_t fve_version;
  130     uint16_t curr_state;
  131     uint16_t next_state;
  132     uint64_t volume_size;
  133     uint32_t unknown2;
  134     uint32_t volume_header_size;
  135     uint64_t fve_offset[3];
  136     uint64_t volume_header_offset;
  137     /* FVE metadata header */
  138     uint32_t metadata_size;
  139     uint32_t metadata_version;
  140     uint32_t metadata_header_size;
  141     uint32_t metada_size_copy;
  142     struct bitlk_guid guid;
  143     uint32_t next_nonce;
  144     uint16_t encryption;
  145     uint16_t unknown3;
  146     uint64_t creation_time;
  147 } __attribute__ ((packed));
  148 
  149 struct bitlk_entry_header_block {
  150     uint64_t offset;
  151     uint64_t size;
  152 } __attribute__ ((packed));
  153 
  154 struct bitlk_entry_vmk {
  155     struct bitlk_guid guid;
  156     uint8_t modified[8];
  157     uint16_t _unknown;
  158     uint16_t protection;
  159 } __attribute__ ((packed));
  160 
  161 struct bitlk_kdf_data {
  162     char last_sha256[32];
  163     char initial_sha256[32];
  164     char salt[16];
  165     uint64_t count;
  166 };
  167 
  168 struct bitlk_bek_header {
  169     uint32_t metadata_size;
  170     uint32_t metadata_version;
  171     uint32_t metadata_header_size;
  172     uint32_t metada_size_copy;
  173     struct bitlk_guid guid;
  174     uint32_t next_nonce;
  175     uint16_t encryption;
  176     uint16_t unknown;
  177     uint64_t creation_time;
  178 } __attribute__ ((packed));
  179 
  180 static BITLKVMKProtection get_vmk_protection(uint16_t protection)
  181 {
  182     switch (protection) {
  183     case 0x0000:
  184         return BITLK_PROTECTION_CLEAR_KEY;
  185     case 0x0100:
  186         return BITLK_PROTECTION_TPM;
  187     case 0x0200:
  188         return BITLK_PROTECTION_STARTUP_KEY;
  189     case 0x0500:
  190         return BITLK_PROTECTION_TPM_PIN;
  191     case 0x0800:
  192         return BITLK_PROTECTION_RECOVERY_PASSPHRASE;
  193     case 0x1000:
  194         return BITLK_PROTECTION_SMART_CARD;
  195     case 0x2000:
  196         return BITLK_PROTECTION_PASSPHRASE;
  197     default:
  198         return BITLK_PROTECTION_UNKNOWN;
  199     }
  200 }
  201 
  202 static const char* get_vmk_protection_string(BITLKVMKProtection protection)
  203 {
  204     switch (protection) {
  205     case BITLK_PROTECTION_CLEAR_KEY:
  206         return "VMK protected with clear key";
  207     case BITLK_PROTECTION_TPM:
  208         return "VMK protected with TPM";
  209     case BITLK_PROTECTION_STARTUP_KEY:
  210         return "VMK protected with startup key";
  211     case BITLK_PROTECTION_TPM_PIN:
  212         return "VMK protected with TPM and PIN";
  213     case BITLK_PROTECTION_PASSPHRASE:
  214         return "VMK protected with passphrase";
  215     case BITLK_PROTECTION_RECOVERY_PASSPHRASE:
  216         return "VMK protected with recovery passphrase";
  217     case BITLK_PROTECTION_SMART_CARD:
  218         return "VMK protected with smart card";
  219     default:
  220         return "VMK with unknown protection";
  221     }
  222 }
  223 
  224 static const char* get_bitlk_type_string(BITLKEncryptionType type)
  225 {
  226     switch (type)
  227     {
  228     case BITLK_ENCRYPTION_TYPE_NORMAL:
  229         return "normal";
  230     case BITLK_ENCRYPTION_TYPE_EOW:
  231         return "encrypt-on-write";
  232     default:
  233         return "unknown";
  234     }
  235 }
  236 
  237 /* TODO -- move to some utils file */
  238 static void hexprint(struct crypt_device *cd, const char *d, int n, const char *sep)
  239 {
  240     int i;
  241     for(i = 0; i < n; i++)
  242         log_std(cd, "%02hhx%s", (const char)d[i], sep);
  243 }
  244 
  245 static uint64_t filetime_to_unixtime(uint64_t time)
  246 {
  247     return (time - EPOCH_AS_FILETIME) / HUNDREDS_OF_NANOSECONDS;
  248 }
  249 
  250 static int convert_to_utf8(struct crypt_device *cd, uint8_t *input, size_t inlen, char **out)
  251 {
  252     char *outbuf = NULL;
  253     iconv_t ic;
  254     size_t ic_inlen = inlen;
  255     size_t ic_outlen = inlen;
  256     char *ic_outbuf = NULL;
  257     size_t r = 0;
  258 
  259     outbuf = malloc(inlen);
  260     if (outbuf == NULL)
  261         return -ENOMEM;
  262 
  263     memset(outbuf, 0, inlen);
  264     ic_outbuf = outbuf;
  265 
  266     ic = iconv_open("UTF-8", "UTF-16LE");
  267     r = iconv(ic, (char **) &input, &ic_inlen, &ic_outbuf, &ic_outlen);
  268     iconv_close(ic);
  269 
  270     if (r == 0)
  271         *out = strdup(outbuf);
  272     else {
  273         *out = NULL;
  274         log_dbg(cd, "Failed to convert volume description: %s", strerror(errno));
  275         r = 0;
  276     }
  277 
  278     free(outbuf);
  279     return r;
  280 }
  281 
  282 static int passphrase_to_utf16(struct crypt_device *cd, char *input, size_t inlen, char **out)
  283 {
  284     char *outbuf = NULL;
  285     iconv_t ic;
  286     size_t ic_inlen = inlen;
  287     size_t ic_outlen = inlen * 2;
  288     char *ic_outbuf = NULL;
  289     size_t r = 0;
  290 
  291     if (inlen == 0)
  292         return r;
  293 
  294     outbuf = crypt_safe_alloc(inlen * 2);
  295     if (outbuf == NULL)
  296         return -ENOMEM;
  297 
  298     memset(outbuf, 0, inlen * 2);
  299     ic_outbuf = outbuf;
  300 
  301     ic = iconv_open("UTF-16LE", "UTF-8");
  302     r = iconv(ic, &input, &ic_inlen, &ic_outbuf, &ic_outlen);
  303     iconv_close(ic);
  304 
  305     if (r == 0) {
  306         *out = outbuf;
  307     } else {
  308         *out = NULL;
  309         crypt_safe_free(outbuf);
  310         log_dbg(cd, "Failed to convert passphrase: %s", strerror(errno));
  311         r = -errno;
  312     }
  313 
  314     return r;
  315 }
  316 
  317 static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, int end, struct bitlk_vmk **vmk)
  318 {
  319     uint16_t key_entry_size = 0;
  320     uint16_t key_entry_type = 0;
  321     uint16_t key_entry_value = 0;
  322     size_t key_size = 0;
  323     char *string = NULL;
  324     const char *key = NULL;
  325     struct volume_key *vk = NULL;
  326     bool supported = false;
  327 
  328     /* only passphrase or recovery passphrase vmks are supported (can be used to activate) */
  329     supported = (*vmk)->protection == BITLK_PROTECTION_PASSPHRASE ||
  330             (*vmk)->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE ||
  331             (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY;
  332 
  333     while (end - start > 2) {
  334         /* size of this entry */
  335         memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
  336         key_entry_size = le16_to_cpu(key_entry_size);
  337         if (key_entry_size == 0)
  338             break;
  339 
  340         /* type and value of this entry */
  341         memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
  342         memcpy(&key_entry_value,
  343                data + start + sizeof(key_entry_size) + sizeof(key_entry_type),
  344                sizeof(key_entry_value));
  345         key_entry_type = le16_to_cpu(key_entry_type);
  346         key_entry_value = le16_to_cpu(key_entry_value);
  347 
  348         if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY) {
  349             if (supported) {
  350                 log_err(cd, _("Unexpected metadata entry type '%u' found when parsing supported Volume Master Key."), key_entry_type);
  351                 return -EINVAL;
  352             } else {
  353                 log_dbg(cd, "Unexpected metadata entry type '%u' found when parsing unsupported VMK.", key_entry_type);
  354             }
  355         }
  356 
  357         /* stretch key with salt, skip 4 B (encryption method of the stretch key) */
  358         if (key_entry_value == BITLK_ENTRY_VALUE_STRETCH_KEY)
  359             memcpy((*vmk)->salt,
  360                    data + start + BITLK_ENTRY_HEADER_LEN + 4,
  361                    sizeof((*vmk)->salt));
  362         /* AES-CCM encrypted key */
  363         else if (key_entry_value == BITLK_ENTRY_VALUE_ENCRYPTED_KEY) {
  364             /* nonce */
  365             memcpy((*vmk)->nonce,
  366                    data + start + BITLK_ENTRY_HEADER_LEN,
  367                    sizeof((*vmk)->nonce));
  368             /* MAC tag */
  369             memcpy((*vmk)->mac_tag,
  370                    data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
  371                    sizeof((*vmk)->mac_tag));
  372             /* AES-CCM encrypted key */
  373             key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
  374             key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
  375             vk = crypt_alloc_volume_key(key_size, key);
  376             if (vk == NULL)
  377                 return -ENOMEM;
  378             crypt_volume_key_add_next(&((*vmk)->vk), vk);
  379         /* clear key for a partially decrypted volume */
  380         } else if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
  381             /* We currently don't want to support opening a partially decrypted
  382              * device so we don't need to store this key.
  383              *
  384              * key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
  385              * key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
  386              * vk = crypt_alloc_volume_key(key_size, key);
  387              * if (vk == NULL)
  388              *  return -ENOMEM;
  389              * crypt_volume_key_add_next(&((*vmk)->vk), vk);
  390              */
  391             log_dbg(cd, "Skipping clear key metadata entry.");
  392         /* unknown timestamps in recovery protected VMK */
  393         } else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) {
  394             ;
  395         } else if (key_entry_value == BITLK_ENTRY_VALUE_STRING) {
  396             if (convert_to_utf8(cd, data + start + BITLK_ENTRY_HEADER_LEN, key_entry_size - BITLK_ENTRY_HEADER_LEN, &string) < 0) {
  397                 log_err(cd, _("Invalid string found when parsing Volume Master Key."));
  398                 free(string);
  399                 return -EINVAL;
  400             } else if ((*vmk)->name != NULL) {
  401                 if (supported) {
  402                     log_err(cd, _("Unexpected string ('%s') found when parsing supported Volume Master Key."), string);
  403                     free(string);
  404                     return -EINVAL;
  405                 }
  406                 log_dbg(cd, "Unexpected string ('%s') found when parsing unsupported VMK.", string);
  407                 free(string);
  408                 string = NULL;
  409             } else {
  410                 /* Assume that strings in VMK are the name of the VMK */
  411                 (*vmk)->name = string;
  412                 string = NULL;
  413             }
  414         /* no idea what this is, lets hope it's not important */
  415         } else if (key_entry_value == BITLK_ENTRY_VALUE_USE_KEY && (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY) {
  416             ;
  417         } else {
  418             if (supported) {
  419                 log_err(cd, _("Unexpected metadata entry value '%u' found when parsing supported Volume Master Key."), key_entry_value);
  420                 return -EINVAL;
  421             } else {
  422                 log_dbg(cd, "Unexpected metadata entry value '%u' found when parsing unsupported VMK.", key_entry_value);
  423             }
  424         }
  425 
  426         start += key_entry_size;
  427     }
  428 
  429     return 0;
  430 }
  431 
  432 void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek)
  433 {
  434     if (!fvek)
  435         return;
  436 
  437     crypt_free_volume_key(fvek->vk);
  438     free(fvek);
  439 }
  440 
  441 void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk)
  442 {
  443     struct bitlk_vmk *vmk_next = NULL;
  444 
  445     while (vmk) {
  446         if (vmk->guid)
  447             free(vmk->guid);
  448         if (vmk->name)
  449             free(vmk->name);
  450         crypt_free_volume_key(vmk->vk);
  451         vmk_next = vmk->next;
  452         free(vmk);
  453         vmk = vmk_next;
  454     }
  455 }
  456 
  457 void BITLK_bitlk_metadata_free(struct bitlk_metadata *metadata)
  458 {
  459     if (!metadata)
  460         return;
  461 
  462     free(metadata->guid);
  463     if (metadata->description)
  464         free(metadata->description);
  465     BITLK_bitlk_vmk_free(metadata->vmks);
  466     BITLK_bitlk_fvek_free(metadata->fvek);
  467 }
  468 
  469 int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
  470 {
  471     int devfd;
  472     struct device *device = crypt_metadata_device(cd);
  473     struct bitlk_signature sig = {};
  474     struct bitlk_superblock sb = {};
  475     struct bitlk_fve_metadata fve = {};
  476     struct bitlk_entry_vmk entry_vmk = {};
  477     uint8_t *fve_entries = NULL;
  478     uint32_t fve_metadata_size = 0;
  479     int fve_offset = 0;
  480     char guid_buf[UUID_STR_LEN] = {0};
  481     uint16_t entry_size = 0;
  482     uint16_t entry_type = 0;
  483     int i = 0;
  484     int r = 0;
  485     int start = 0;
  486     int end = 0;
  487     size_t key_size = 0;
  488     const char *key = NULL;
  489 
  490     struct bitlk_vmk *vmk = NULL;
  491     struct bitlk_vmk *vmk_p = params->vmks;
  492 
  493     devfd = device_open(cd, crypt_data_device(cd), O_RDONLY);
  494     if (devfd < 0) {
  495         r = -EINVAL;
  496         goto out;
  497     }
  498 
  499     /* read and check the signature */
  500     if (read_lseek_blockwise(devfd, device_block_size(cd, device),
  501         device_alignment(device), &sig, sizeof(sig), 0) != sizeof(sig)) {
  502         log_err(cd, _("Failed to read BITLK signature from %s."), device_path(device));
  503         r = -EINVAL;
  504         goto out;
  505     }
  506 
  507     if (memcmp(sig.signature, BITLK_SIGNATURE, sizeof(sig.signature)) == 0) {
  508         params->togo = false;
  509         fve_offset = BITLK_HEADER_METADATA_OFFSET;
  510     } else if (memcmp(sig.signature, BITLK_SIGNATURE_TOGO, sizeof(sig.signature)) == 0) {
  511         params->togo = true;
  512         fve_offset = BITLK_HEADER_METADATA_OFFSET_TOGO;
  513     } else {
  514         log_err(cd, _("Invalid or unknown signature for BITLK device."));
  515         r = -EINVAL;
  516         goto out;
  517     }
  518 
  519     if (memcmp(sig.boot_code, BITLK_BOOTCODE_V1, sizeof(sig.boot_code)) == 0) {
  520         log_err(cd, _("BITLK version 1 is currently not supported."));
  521         r = -ENOTSUP;
  522         goto out;
  523     } else if (memcmp(sig.boot_code, BITLK_BOOTCODE_V2, sizeof(sig.boot_code)) == 0)
  524         ;
  525     else {
  526         log_err(cd, _("Invalid or unknown boot signature for BITLK device."));
  527         r = -EINVAL;
  528         goto out;
  529     }
  530 
  531     params->sector_size = le16_to_cpu(sig.sector_size);
  532     if (params->sector_size == 0) {
  533         log_dbg(cd, "Got sector size 0, assuming 512.");
  534         params->sector_size = SECTOR_SIZE;
  535     }
  536 
  537     if (!(params->sector_size == 512 || params->sector_size == 4096)) {
  538         log_err(cd, _("Unsupported sector size %" PRIu16 "."), params->sector_size);
  539         r = -EINVAL;
  540         goto out;
  541     }
  542 
  543     /* read GUID and FVE metadata offsets */
  544     if (read_lseek_blockwise(devfd, device_block_size(cd, device),
  545         device_alignment(device), &sb, sizeof(sb), fve_offset) != sizeof(sb)) {
  546         log_err(cd, _("Failed to read BITLK header from %s."), device_path(device));
  547         r = -EINVAL;
  548         goto out;
  549     }
  550 
  551     /* get encryption "type" based on the GUID from BITLK superblock */
  552     if (memcmp(&sb.guid, BITLK_GUID_NORMAL, 16) == 0)
  553         params->type = BITLK_ENCRYPTION_TYPE_NORMAL;
  554     else if (memcmp(&sb.guid, BITLK_GUID_EOW, 16) == 0)
  555         params->type = BITLK_ENCRYPTION_TYPE_EOW;
  556     else
  557         params->type = BITLK_ENCRYPTION_TYPE_UNKNOWN;
  558     log_dbg(cd, "BITLK type from GUID: %s.", get_bitlk_type_string(params->type));
  559 
  560     for (i = 0; i < 3; i++)
  561         params->metadata_offset[i] = le64_to_cpu(sb.fve_offset[i]);
  562 
  563     log_dbg(cd, "Reading BITLK FVE metadata of size %zu on device %s, offset %" PRIu64 ".",
  564         sizeof(fve), device_path(device), params->metadata_offset[0]);
  565 
  566     /* read FVE metadata from the first metadata area */
  567     if (read_lseek_blockwise(devfd, device_block_size(cd, device),
  568         device_alignment(device), &fve, sizeof(fve), params->metadata_offset[0]) != sizeof(fve) ||
  569         memcmp(fve.signature, BITLK_SIGNATURE, sizeof(fve.signature)) ||
  570         le16_to_cpu(fve.fve_version) != 2) {
  571         log_err(cd, _("Failed to read BITLK FVE metadata from %s."), device_path(device));
  572         r = -EINVAL;
  573         goto out;
  574     }
  575 
  576     /* check encryption state for the device */
  577     params->state = true;
  578     if (le16_to_cpu(fve.curr_state) != BITLK_STATE_NORMAL || le16_to_cpu(fve.next_state) != BITLK_STATE_NORMAL) {
  579         params->state = false;
  580         log_dbg(cd, "Unknown/unsupported state detected. Current state: %"PRIu16", next state: %"PRIu16".",
  581             le16_to_cpu(fve.curr_state), le16_to_cpu(fve.next_state));
  582     }
  583 
  584     params->metadata_version = le16_to_cpu(fve.fve_version);
  585     fve_metadata_size = le32_to_cpu(fve.metadata_size);
  586 
  587     switch (le16_to_cpu(fve.encryption)) {
  588     /* AES-CBC with Elephant difuser */
  589     case 0x8000:
  590         params->key_size = 256;
  591         params->cipher = "aes";
  592         params->cipher_mode = "cbc-elephant";
  593         break;
  594     case 0x8001:
  595         params->key_size = 512;
  596         params->cipher = "aes";
  597         params->cipher_mode = "cbc-elephant";
  598         break;
  599     /* AES-CBC */
  600     case 0x8002:
  601         params->key_size = 128;
  602         params->cipher = "aes";
  603         params->cipher_mode = "cbc-eboiv";
  604         break;
  605     case 0x8003:
  606         params->key_size = 256;
  607         params->cipher = "aes";
  608         params->cipher_mode = "cbc-eboiv";
  609         break;
  610     /* AES-XTS */
  611     case 0x8004:
  612         params->key_size = 256;
  613         params->cipher = "aes";
  614         params->cipher_mode = "xts-plain64";
  615         break;
  616     case 0x8005:
  617         params->key_size = 512;
  618         params->cipher = "aes";
  619         params->cipher_mode = "xts-plain64";
  620         break;
  621     default:
  622         log_err(cd, _("Unknown or unsupported encryption type."));
  623         params->key_size = 0;
  624         params->cipher = NULL;
  625         params->cipher_mode = NULL;
  626         r = -ENOTSUP;
  627         goto out;
  628     };
  629 
  630     /* device GUID */
  631     guid_to_string(&fve.guid, guid_buf);
  632     params->guid = strdup(guid_buf);
  633     if (!params->guid) {
  634         r = -ENOMEM;
  635         goto out;
  636     }
  637 
  638     params->creation_time = filetime_to_unixtime(le64_to_cpu(fve.creation_time));
  639 
  640     /* read and parse all FVE metadata entries */
  641     fve_entries = malloc(fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN);
  642     if (!fve_entries) {
  643         r = -ENOMEM;
  644         goto out;
  645     }
  646     memset(fve_entries, 0, (fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN));
  647 
  648     log_dbg(cd, "Reading BITLK FVE metadata entries of size %" PRIu32 " on device %s, offset %" PRIu64 ".",
  649         fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN, device_path(device),
  650         params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN);
  651 
  652     if (read_lseek_blockwise(devfd, device_block_size(cd, device),
  653         device_alignment(device), fve_entries, fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN,
  654         params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN) != (ssize_t)(fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN)) {
  655         log_err(cd, _("Failed to read BITLK metadata entries from %s."), device_path(device));
  656         r = -EINVAL;
  657         goto out;
  658     }
  659 
  660     end = fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN;
  661     while (end - start > 2) {
  662         /* size of this entry */
  663         memcpy(&entry_size, fve_entries + start, sizeof(entry_size));
  664         entry_size = le16_to_cpu(entry_size);
  665         if (entry_size == 0)
  666             break;
  667 
  668         /* type of this entry */
  669         memcpy(&entry_type, fve_entries + start + sizeof(entry_size), sizeof(entry_type));
  670         entry_type = le16_to_cpu(entry_type);
  671 
  672         /* VMK */
  673         if (entry_type == BITLK_ENTRY_TYPE_VMK) {
  674             /* skip first four variables in the entry (entry size, type, value and version) */
  675             memcpy(&entry_vmk,
  676                    fve_entries + start + BITLK_ENTRY_HEADER_LEN,
  677                    sizeof(entry_vmk));
  678 
  679             vmk = malloc(sizeof(struct bitlk_vmk));
  680             if (!vmk) {
  681                 r = -ENOMEM;
  682                 goto out;
  683             }
  684             memset(vmk, 0, sizeof(struct bitlk_vmk));
  685 
  686             guid_to_string(&entry_vmk.guid, guid_buf);
  687             vmk->guid = strdup (guid_buf);
  688 
  689             vmk->name = NULL;
  690 
  691             vmk->protection = get_vmk_protection(le16_to_cpu(entry_vmk.protection));
  692 
  693             /* more data in another entry list */
  694             r = parse_vmk_entry(cd, fve_entries,
  695                                   start + BITLK_ENTRY_HEADER_LEN + BITLK_VMK_HEADER_LEN,
  696                           start + entry_size, &vmk);
  697             if (r < 0) {
  698                 BITLK_bitlk_vmk_free(vmk);
  699                 goto out;
  700             }
  701 
  702             if (params->vmks == NULL)
  703                 params->vmks = vmk;
  704             else
  705                 vmk_p->next = vmk;
  706 
  707             vmk_p = vmk;
  708             vmk = vmk->next;
  709         /* FVEK */
  710         } else if (entry_type == BITLK_ENTRY_TYPE_FVEK) {
  711             params->fvek = malloc(sizeof(struct bitlk_fvek));
  712             if (!params->fvek) {
  713                 r = -ENOMEM;
  714                 goto out;
  715             }
  716             memcpy(params->fvek->nonce,
  717                    fve_entries + start + BITLK_ENTRY_HEADER_LEN,
  718                    sizeof(params->fvek->nonce));
  719             /* MAC tag */
  720             memcpy(params->fvek->mac_tag,
  721                    fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
  722                    sizeof(params->fvek->mac_tag));
  723             /* AES-CCM encrypted key */
  724             key_size = entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
  725             key = (const char *) fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
  726             params->fvek->vk = crypt_alloc_volume_key(key_size, key);
  727             if (params->fvek->vk == NULL) {
  728                 r = -ENOMEM;
  729                 goto out;
  730             }
  731         /* volume header info (location and size) */
  732         } else if (entry_type == BITLK_ENTRY_TYPE_VOLUME_HEADER) {
  733             struct bitlk_entry_header_block entry_header;
  734             memcpy(&entry_header,
  735                    fve_entries + start + BITLK_ENTRY_HEADER_LEN,
  736                    sizeof(entry_header));
  737             params->volume_header_offset = le64_to_cpu(entry_header.offset);
  738             params->volume_header_size = le64_to_cpu(entry_header.size);
  739         /* volume description (utf-16 string) */
  740         } else if (entry_type == BITLK_ENTRY_TYPE_DESCRIPTION) {
  741             r = convert_to_utf8(cd, fve_entries + start + BITLK_ENTRY_HEADER_LEN,
  742                         entry_size - BITLK_ENTRY_HEADER_LEN,
  743                         &(params->description));
  744             if (r < 0) {
  745                 BITLK_bitlk_vmk_free(vmk);
  746                 goto out;
  747             }
  748         }
  749 
  750         start += entry_size;
  751     }
  752 
  753 out:
  754     if (fve_entries)
  755         free(fve_entries);
  756     return r;
  757 }
  758 
  759 int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_metadata *params)
  760 {
  761     struct volume_key *vk_p;
  762     struct bitlk_vmk *vmk_p;
  763     int next_id = 0;
  764     int i = 0;
  765 
  766     log_std(cd, "Info for BITLK%s device %s.\n", params->togo ? " To Go" : "", device_path(device));
  767     log_std(cd, "Version:      \t%u\n", params->metadata_version);
  768     log_std(cd, "GUID:         \t%s\n", params->guid);
  769     log_std(cd, "Sector size:  \t%u [bytes]\n", params->sector_size);
  770     log_std(cd, "Created:      \t%s", ctime((time_t *)&(params->creation_time)));
  771     log_std(cd, "Description:  \t%s\n", params->description);
  772     log_std(cd, "Cipher name:  \t%s\n", params->cipher);
  773     log_std(cd, "Cipher mode:  \t%s\n", params->cipher_mode);
  774     log_std(cd, "Cipher key:   \t%u bits\n", params->key_size);
  775 
  776     log_std(cd, "\n");
  777 
  778     log_std(cd, "Keyslots:\n");
  779     vmk_p = params->vmks;
  780     while (vmk_p) {
  781         log_std(cd, " %d: VMK\n", next_id);
  782         if (vmk_p->name != NULL) {
  783             log_std(cd, "\tName:       \t%s\n", vmk_p->name);
  784         }
  785         log_std(cd, "\tGUID:       \t%s\n", vmk_p->guid);
  786         log_std(cd, "\tProtection: \t%s\n", get_vmk_protection_string (vmk_p->protection));
  787         log_std(cd, "\tSalt:       \t");
  788         hexprint(cd, (const char *) vmk_p->salt, 16, "");
  789         log_std(cd, "\n");
  790 
  791         vk_p = vmk_p->vk;
  792         while (vk_p) {
  793             log_std(cd, "\tKey data size:\t%zu [bytes]\n", vk_p->keylength);
  794             vk_p = vk_p->next;
  795         }
  796         vmk_p = vmk_p->next;
  797         next_id++;
  798     }
  799 
  800     log_std(cd, " %d: FVEK\n", next_id);
  801     log_std(cd, "\tKey data size:\t%zu [bytes]\n", params->fvek->vk->keylength);
  802 
  803     log_std(cd, "\n");
  804 
  805     log_std(cd, "Metadata segments:\n");
  806 
  807     for (i = 0; i < 3; i++) {
  808         log_std(cd, " %d: FVE metadata area\n", i);
  809         log_std(cd, "\tOffset: \t%" PRIu64 " [bytes]\n", params->metadata_offset[i]);
  810         log_std(cd, "\tSize:   \t%d [bytes]\n", BITLK_FVE_METADATA_SIZE);
  811     }
  812 
  813     log_std(cd, " %d: Volume header\n", i);
  814     log_std(cd, "\tOffset: \t%" PRIu64 " [bytes]\n", params->volume_header_offset);
  815     log_std(cd, "\tSize:   \t%" PRIu64 " [bytes]\n", params->volume_header_size);
  816     log_std(cd, "\tCipher: \t%s-%s\n", params->cipher, params->cipher_mode);
  817 
  818     return 0;
  819 }
  820 
  821 /* check if given passphrase can be a recovery key (has right format) and convert it */
  822 static int get_recovery_key(struct crypt_device *cd,
  823                 const char *password,
  824                 size_t passwordLen,
  825                 struct volume_key **rc_key)
  826 {
  827     unsigned int i, j = 0;
  828     uint16_t parts[BITLK_RECOVERY_PARTS] = {0};
  829     char part_str[BITLK_RECOVERY_PART_LEN + 1] = {0};
  830     long part_num = 0;
  831 
  832     /* check the passphrase it should be:
  833         - 55 characters
  834         - 8 groups of 6 divided by '-'
  835         - each part is a number dividable by 11
  836     */
  837     if (passwordLen != BITLK_RECOVERY_KEY_LEN) {
  838                 if (passwordLen == BITLK_RECOVERY_KEY_LEN + 1 && password[passwordLen - 1] == '\n') {
  839                         /* looks like a recovery key with an extra newline, possibly from a key file */
  840                         passwordLen--;
  841                         log_dbg(cd, "Possible extra EOL stripped from the recovery key.");
  842                 } else
  843                         return 0;
  844         }
  845 
  846     for (i = BITLK_RECOVERY_PART_LEN; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1) {
  847         if (password[i] != '-')
  848             return 0;
  849     }
  850 
  851     for (i = 0, j = 0; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1, j++) {
  852         strncpy(part_str, password + i, BITLK_RECOVERY_PART_LEN);
  853 
  854         errno = 0;
  855         part_num = strtol(part_str, NULL, 10);
  856         if ((errno == ERANGE && (part_num == LONG_MAX || part_num == LONG_MIN)) ||
  857             (errno != 0 && part_num == 0))
  858             return -errno;
  859 
  860         if (part_num % 11 != 0)
  861             return 0;
  862         parts[j] = cpu_to_le16(part_num / 11);
  863     }
  864 
  865     *rc_key = crypt_alloc_volume_key(16, (const char*) parts);
  866     if (*rc_key == NULL)
  867         return -ENOMEM;
  868 
  869     return 0;
  870 }
  871 
  872 static int parse_external_key_entry(struct crypt_device *cd,
  873                     const char *data,
  874                     int start,
  875                     int end,
  876                     struct volume_key **vk,
  877                     const struct bitlk_metadata *params)
  878 {
  879     uint16_t key_entry_size = 0;
  880     uint16_t key_entry_type = 0;
  881     uint16_t key_entry_value = 0;
  882     size_t key_size = 0;
  883     const char *key = NULL;
  884     struct bitlk_guid guid;
  885     char guid_buf[UUID_STR_LEN] = {0};
  886 
  887     while (end - start > 2) {
  888         /* size of this entry */
  889         memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
  890         key_entry_size = le16_to_cpu(key_entry_size);
  891         if (key_entry_size == 0)
  892             break;
  893 
  894         /* type and value of this entry */
  895         memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
  896         memcpy(&key_entry_value,
  897                data + start + sizeof(key_entry_size) + sizeof(key_entry_type),
  898                sizeof(key_entry_value));
  899         key_entry_type = le16_to_cpu(key_entry_type);
  900         key_entry_value = le16_to_cpu(key_entry_value);
  901 
  902         if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY && key_entry_type != BITLK_ENTRY_TYPE_VOLUME_GUID) {
  903             log_err(cd, _("Unexpected metadata entry type '%u' found when parsing external key."), key_entry_type);
  904             return -EINVAL;
  905         }
  906 
  907         if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
  908             key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
  909             key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
  910             *vk = crypt_alloc_volume_key(key_size, key);
  911             if (*vk == NULL)
  912                 return -ENOMEM;
  913             return 0;
  914         /* optional "ExternalKey" string, we can safely ignore it */
  915         } else if (key_entry_value == BITLK_ENTRY_VALUE_STRING)
  916             ;
  917         /* GUID of the BitLocker device we are trying to open with this key */
  918         else if (key_entry_value == BITLK_ENTRY_VALUE_GUID) {
  919             memcpy(&guid, data + start + BITLK_ENTRY_HEADER_LEN, sizeof(struct bitlk_guid));
  920             guid_to_string(&guid, guid_buf);
  921             if (strcmp(guid_buf, params->guid) != 0) {
  922                 log_err(cd, _("BEK file GUID '%s' does not match GUID of the volume."), guid_buf);
  923                 return -EINVAL;
  924             }
  925         } else {
  926             log_err(cd, _("Unexpected metadata entry value '%u' found when parsing external key."), key_entry_value);
  927             return -EINVAL;
  928         }
  929 
  930         start += key_entry_size;
  931     }
  932 
  933     /* if we got here we failed to parse the metadata */
  934     return -EINVAL;
  935 }
  936 
  937 /* check if given passphrase can be a startup key (has right format) and convert it */
  938 static int get_startup_key(struct crypt_device *cd,
  939                const char *password,
  940                size_t passwordLen,
  941                const struct bitlk_vmk *vmk,
  942                struct volume_key **su_key,
  943                const struct bitlk_metadata *params)
  944 {
  945     struct bitlk_bek_header bek_header = {0};
  946     char guid_buf[UUID_STR_LEN] = {0};
  947 
  948     uint16_t key_entry_size = 0;
  949     uint16_t key_entry_type = 0;
  950     uint16_t key_entry_value = 0;
  951 
  952     if (passwordLen < BITLK_BEK_FILE_HEADER_LEN)
  953         return -EPERM;
  954 
  955     memcpy(&bek_header, password, BITLK_BEK_FILE_HEADER_LEN);
  956 
  957     /* metadata should contain GUID of the VMK this startup key is used for */
  958     guid_to_string(&bek_header.guid, guid_buf);
  959     if (strcmp(guid_buf, vmk->guid) == 0)
  960         log_dbg(cd, "Found matching startup key for VMK %s", vmk->guid);
  961     else
  962         return -EPERM;
  963 
  964     if (bek_header.metadata_version != 1) {
  965         log_err(cd, _("Unsupported BEK metadata version %" PRIu32), bek_header.metadata_version);
  966         return -ENOTSUP;
  967     }
  968 
  969     if (bek_header.metadata_size != passwordLen) {
  970         log_err(cd, _("Unexpected BEK metadata size %" PRIu32 " does not match BEK file length"), bek_header.metadata_size);
  971         return -EINVAL;
  972     }
  973 
  974     /* we are expecting exactly one metadata entry starting immediately after the header */
  975     memcpy(&key_entry_size, password + BITLK_BEK_FILE_HEADER_LEN, sizeof(key_entry_size));
  976     key_entry_size = le16_to_cpu(key_entry_size);
  977     if (key_entry_size < BITLK_ENTRY_HEADER_LEN) {
  978         log_dbg(cd, "Unexpected metadata entry size %" PRIu16 " when parsing BEK file", key_entry_size);
  979         return -EINVAL;
  980     }
  981 
  982     /* type and value of this entry */
  983     memcpy(&key_entry_type, password + BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size), sizeof(key_entry_type));
  984     memcpy(&key_entry_value,
  985            password + BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size) + sizeof(key_entry_type),
  986            sizeof(key_entry_value));
  987     key_entry_type = le16_to_cpu(key_entry_type);
  988     key_entry_value = le16_to_cpu(key_entry_value);
  989 
  990     if (key_entry_type == BITLK_ENTRY_TYPE_STARTUP_KEY && key_entry_value == BITLK_ENTRY_VALUE_EXTERNAL_KEY) {
  991         return parse_external_key_entry(cd, password,
  992                         BITLK_BEK_FILE_HEADER_LEN + BITLK_ENTRY_HEADER_LEN + BITLK_STARTUP_KEY_HEADER_LEN,
  993                         passwordLen, su_key, params);
  994     } else {
  995         log_err(cd, _("Unexpected metadata entry found when parsing startup key."));
  996         log_dbg(cd, "Entry type: %u, entry value: %u", key_entry_type, key_entry_value);
  997         return -EINVAL;
  998     }
  999 }
 1000 
 1001 static int bitlk_kdf(struct crypt_device *cd,
 1002              const char *password,
 1003              size_t passwordLen,
 1004              bool recovery,
 1005              const uint8_t *salt,
 1006              struct volume_key **vk)
 1007 {
 1008     struct bitlk_kdf_data kdf = {};
 1009     struct crypt_hash *hd = NULL;
 1010     int len = 0;
 1011     char *utf16Password = NULL;
 1012     int i = 0;
 1013     int r = 0;
 1014 
 1015     memcpy(kdf.salt, salt, 16);
 1016 
 1017     r = crypt_hash_init(&hd, BITLK_KDF_HASH);
 1018     if (r < 0)
 1019         return r;
 1020     len = crypt_hash_size(BITLK_KDF_HASH);
 1021     if (len < 0) {
 1022         crypt_hash_destroy(hd);
 1023         return len;
 1024     }
 1025 
 1026     if (!recovery) {
 1027         /* passphrase: convert to UTF-16 first, then sha256(sha256(pw)) */
 1028         r = passphrase_to_utf16(cd, CONST_CAST(char*)password, passwordLen, &utf16Password);
 1029         if (r < 0)
 1030             goto out;
 1031 
 1032         crypt_hash_write(hd, utf16Password, passwordLen * 2);
 1033         r = crypt_hash_final(hd, kdf.initial_sha256, len);
 1034         if (r < 0)
 1035             goto out;
 1036 
 1037         crypt_hash_write(hd, kdf.initial_sha256, len);
 1038         r = crypt_hash_final(hd, kdf.initial_sha256, len);
 1039         if (r < 0)
 1040             goto out;
 1041     } else {
 1042         /* recovery passphrase: already converted in #get_recovery_key, now just sha256(rpw) */
 1043         crypt_hash_write(hd, password, passwordLen);
 1044         r = crypt_hash_final(hd, kdf.initial_sha256, len);
 1045         if (r < 0)
 1046             goto out;
 1047     }
 1048 
 1049     for (i = 0; i < BITLK_KDF_ITERATION_COUNT; i++) {
 1050         crypt_hash_write(hd, (const char*) &kdf, sizeof(kdf));
 1051         r = crypt_hash_final(hd, kdf.last_sha256, len);
 1052         if (r < 0)
 1053             goto out;
 1054         kdf.count = cpu_to_le64(le64_to_cpu(kdf.count) + 1);
 1055     }
 1056 
 1057     *vk = crypt_alloc_volume_key(len, kdf.last_sha256);
 1058 
 1059 out:
 1060     crypt_safe_free(utf16Password);
 1061     if (hd)
 1062         crypt_hash_destroy(hd);
 1063     return r;
 1064 }
 1065 
 1066 static int decrypt_key(struct crypt_device *cd,
 1067                struct volume_key **vk,
 1068                struct volume_key *enc_key,
 1069                struct volume_key *key,
 1070                const uint8_t *tag, size_t tag_size,
 1071                const uint8_t *iv, size_t iv_size,
 1072                bool is_fvek)
 1073 {
 1074     char *outbuf;
 1075     int r;
 1076     uint16_t key_size = 0;
 1077 
 1078     outbuf = crypt_safe_alloc(enc_key->keylength);
 1079     if (!outbuf)
 1080         return -ENOMEM;
 1081 
 1082     r = crypt_bitlk_decrypt_key(key->key, key->keylength, enc_key->key, outbuf, enc_key->keylength,
 1083                 (const char*)iv, iv_size, (const char*)tag, tag_size);
 1084     if (r < 0) {
 1085         if (r == -ENOTSUP)
 1086             log_err(cd, _("This operation is not supported."));
 1087         goto out;
 1088     }
 1089 
 1090     /* key_data has it's size as part of the metadata */
 1091     memcpy(&key_size, outbuf, 2);
 1092     key_size = le16_to_cpu(key_size);
 1093     if (enc_key->keylength != key_size) {
 1094         log_err(cd, _("Unexpected key data size."));
 1095         log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "", enc_key->keylength, key_size);
 1096 
 1097         r = -EINVAL;
 1098         goto out;
 1099     }
 1100 
 1101     if (is_fvek && strcmp(crypt_get_cipher_mode(cd), "cbc-elephant") == 0 &&
 1102         crypt_get_volume_key_size(cd) == 32) {
 1103         /* 128bit AES-CBC with Elephant -- key size is 256 bit (2 keys) but key data is 512 bits,
 1104            data: 16B CBC key, 16B empty, 16B elephant key, 16B empty */
 1105         memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN,
 1106             outbuf + 2 * 16 + BITLK_OPEN_KEY_METADATA_LEN, 16);
 1107         key_size = 32 + BITLK_OPEN_KEY_METADATA_LEN;
 1108     }
 1109 
 1110 
 1111     *vk = crypt_alloc_volume_key(key_size - BITLK_OPEN_KEY_METADATA_LEN,
 1112                     (const char *)(outbuf + BITLK_OPEN_KEY_METADATA_LEN));
 1113     r = *vk ? 0 : -ENOMEM;
 1114 out:
 1115     crypt_safe_free(outbuf);
 1116     return r;
 1117 }
 1118 
 1119 int BITLK_get_volume_key(struct crypt_device *cd,
 1120              const char *password,
 1121              size_t passwordLen,
 1122              const struct bitlk_metadata *params,
 1123              struct volume_key **open_fvek_key)
 1124 {
 1125     int r = 0;
 1126     struct volume_key *open_vmk_key = NULL;
 1127     struct volume_key *vmk_dec_key = NULL;
 1128     struct volume_key *recovery_key = NULL;
 1129     const struct bitlk_vmk *next_vmk = NULL;
 1130 
 1131     next_vmk = params->vmks;
 1132     while (next_vmk) {
 1133         if (next_vmk->protection == BITLK_PROTECTION_PASSPHRASE) {
 1134             r = bitlk_kdf(cd, password, passwordLen, false, next_vmk->salt, &vmk_dec_key);
 1135             if (r) {
 1136                 /* something wrong happened, but we still want to check other key slots */
 1137                 next_vmk = next_vmk->next;
 1138                 continue;
 1139             }
 1140         } else if (next_vmk->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE) {
 1141             r = get_recovery_key(cd, password, passwordLen, &recovery_key);
 1142             if (r) {
 1143                 /* something wrong happened, but we still want to check other key slots */
 1144                 next_vmk = next_vmk->next;
 1145                 continue;
 1146             }
 1147             if (recovery_key == NULL) {
 1148                 /* r = 0 but no key -> given passphrase is not a recovery passphrase */
 1149                 r = -EPERM;
 1150                 next_vmk = next_vmk->next;
 1151                 continue;
 1152             }
 1153             log_dbg(cd, "Trying to use given password as a recovery key.");
 1154             r = bitlk_kdf(cd, recovery_key->key, recovery_key->keylength,
 1155                       true, next_vmk->salt, &vmk_dec_key);
 1156             crypt_free_volume_key(recovery_key);
 1157             if (r)
 1158                 return r;
 1159         } else if (next_vmk->protection == BITLK_PROTECTION_STARTUP_KEY) {
 1160             r = get_startup_key(cd, password, passwordLen, next_vmk, &vmk_dec_key, params);
 1161             if (r) {
 1162                 next_vmk = next_vmk->next;
 1163                 continue;
 1164             }
 1165             log_dbg(cd, "Trying to use external key found in provided password.");
 1166         } else {
 1167             /* only passphrase, recovery passphrase and startup key VMKs supported right now */
 1168             log_dbg(cd, "Skipping %s", get_vmk_protection_string(next_vmk->protection));
 1169             next_vmk = next_vmk->next;
 1170             if (r == 0)
 1171                 /* we need to set error code in case we have only unsupported VMKs */
 1172                 r = -ENOTSUP;
 1173             continue;
 1174         }
 1175 
 1176         log_dbg(cd, "Trying to decrypt %s.", get_vmk_protection_string(next_vmk->protection));
 1177         r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
 1178                 next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
 1179                 next_vmk->nonce, BITLK_NONCE_SIZE, false);
 1180         if (r < 0) {
 1181             log_dbg(cd, "Failed to decrypt VMK using provided passphrase.");
 1182             crypt_free_volume_key(vmk_dec_key);
 1183             if (r == -ENOTSUP)
 1184                 return r;
 1185             next_vmk = next_vmk->next;
 1186             continue;
 1187         }
 1188         crypt_free_volume_key(vmk_dec_key);
 1189 
 1190         r = decrypt_key(cd, open_fvek_key, params->fvek->vk, open_vmk_key,
 1191                 params->fvek->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
 1192                 params->fvek->nonce, BITLK_NONCE_SIZE, true);
 1193         if (r < 0) {
 1194             log_dbg(cd, "Failed to decrypt FVEK using VMK.");
 1195             crypt_free_volume_key(open_vmk_key);
 1196             if (r == -ENOTSUP)
 1197                 return r;
 1198         } else {
 1199             crypt_free_volume_key(open_vmk_key);
 1200             break;
 1201         }
 1202 
 1203         next_vmk = next_vmk->next;
 1204     }
 1205 
 1206     if (r) {
 1207         log_dbg(cd, "No more VMKs to try.");
 1208         return r;
 1209     }
 1210 
 1211     return 0;
 1212 }
 1213 
 1214 static int _activate_check(struct crypt_device *cd,
 1215                    const struct bitlk_metadata *params)
 1216 {
 1217     const struct bitlk_vmk *next_vmk = NULL;
 1218 
 1219     if (!params->state) {
 1220         log_err(cd, _("This BITLK device is in an unsupported state and cannot be activated."));
 1221         return -ENOTSUP;
 1222     }
 1223 
 1224     if (params->type != BITLK_ENCRYPTION_TYPE_NORMAL) {
 1225         log_err(cd, _("BITLK devices with type '%s' cannot be activated."), get_bitlk_type_string(params->type));
 1226         return -ENOTSUP;
 1227     }
 1228 
 1229     next_vmk = params->vmks;
 1230     while (next_vmk) {
 1231         if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
 1232             log_err(cd, _("Activation of partially decrypted BITLK device is not supported."));
 1233             return -ENOTSUP;
 1234         }
 1235         next_vmk = next_vmk->next;
 1236     }
 1237 
 1238     return 0;
 1239 }
 1240 
 1241 static int _activate(struct crypt_device *cd,
 1242              const char *name,
 1243              struct volume_key *open_fvek_key,
 1244              const struct bitlk_metadata *params,
 1245              uint32_t flags)
 1246 {
 1247     int r = 0;
 1248     int i = 0;
 1249     int j = 0;
 1250     int min = 0;
 1251     int num_segments = 0;
 1252     struct crypt_dm_active_device dmd = {
 1253         .flags = flags,
 1254     };
 1255     struct dm_target *next_segment = NULL;
 1256     struct segment segments[MAX_BITLK_SEGMENTS] = {};
 1257     struct segment temp;
 1258     uint64_t next_start = 0;
 1259     uint64_t next_end = 0;
 1260     uint64_t last_segment = 0;
 1261     uint32_t dmt_flags;
 1262 
 1263     r = _activate_check(cd, params);
 1264     if (r)
 1265         return r;
 1266 
 1267     r = device_block_adjust(cd, crypt_data_device(cd), DEV_EXCL,
 1268                 0, &dmd.size, &dmd.flags);
 1269     if (r)
 1270         return r;
 1271 
 1272     /* there will be always 4 dm-zero segments: 3x metadata, 1x FS header */
 1273     for (i = 0; i < 3; i++) {
 1274         segments[num_segments].offset = params->metadata_offset[i] / SECTOR_SIZE;
 1275         segments[num_segments].length = BITLK_FVE_METADATA_SIZE / SECTOR_SIZE;
 1276         segments[num_segments].iv_offset = 0;
 1277         segments[num_segments].type = BITLK_SEGTYPE_ZERO;
 1278         num_segments++;
 1279     }
 1280     segments[num_segments].offset = params->volume_header_offset / SECTOR_SIZE;
 1281     segments[num_segments].length = params->volume_header_size / SECTOR_SIZE;
 1282     segments[num_segments].iv_offset = 0;
 1283     segments[num_segments].type = BITLK_SEGTYPE_ZERO;
 1284     num_segments++;
 1285 
 1286     /* filesystem header (moved from the special location) */
 1287     segments[num_segments].offset = 0;
 1288     segments[num_segments].length = params->volume_header_size / SECTOR_SIZE;
 1289     segments[num_segments].iv_offset = params->volume_header_offset / SECTOR_SIZE;
 1290     segments[num_segments].type = BITLK_SEGTYPE_CRYPT;
 1291     num_segments++;
 1292 
 1293     /* now fill gaps between the dm-zero segments with dm-crypt */
 1294     last_segment = params->volume_header_size / SECTOR_SIZE;
 1295     while (true) {
 1296         next_start = dmd.size;
 1297         next_end = dmd.size;
 1298 
 1299         /* start of the next segment: end of the first existing segment after the last added */
 1300         for (i = 0; i < num_segments; i++)
 1301             if (segments[i].offset + segments[i].length < next_start && segments[i].offset + segments[i].length >= last_segment)
 1302                 next_start = segments[i].offset + segments[i].length;
 1303 
 1304         /* end of the next segment: start of the next segment after start we found above */
 1305         for (i = 0; i < num_segments; i++)
 1306             if (segments[i].offset < next_end && segments[i].offset >= next_start)
 1307                 next_end = segments[i].offset;
 1308 
 1309         /* two zero segments next to each other, just bump the last_segment
 1310            so the algorithm moves */
 1311         if (next_end - next_start == 0) {
 1312             last_segment = next_end + 1;
 1313             continue;
 1314         }
 1315 
 1316         segments[num_segments].offset = next_start;
 1317         segments[num_segments].length = next_end - next_start;
 1318         segments[num_segments].iv_offset = next_start;
 1319         segments[num_segments].type = BITLK_SEGTYPE_CRYPT;
 1320         last_segment = next_end;
 1321         num_segments++;
 1322 
 1323         if (next_end == dmd.size)
 1324             break;
 1325 
 1326         if (num_segments == 10) {
 1327             log_dbg(cd, "Failed to calculate number of dm-crypt segments for open.");
 1328             r = -EINVAL;
 1329             goto out;
 1330         }
 1331     }
 1332 
 1333     /* device mapper needs the segment sorted */
 1334     for (i = 0; i < num_segments - 1; i++) {
 1335         min = i;
 1336         for (j = i + 1; j < num_segments; j++)
 1337             if (segments[j].offset < segments[min].offset)
 1338                 min = j;
 1339 
 1340         if (min != i) {
 1341             temp.offset = segments[min].offset;
 1342             temp.length = segments[min].length;
 1343             temp.iv_offset = segments[min].iv_offset;
 1344             temp.type = segments[min].type;
 1345 
 1346             segments[min].offset = segments[i].offset;
 1347             segments[min].length = segments[i].length;
 1348             segments[min].iv_offset = segments[i].iv_offset;
 1349             segments[min].type = segments[i].type;
 1350 
 1351             segments[i].offset = temp.offset;
 1352             segments[i].length = temp.length;
 1353             segments[i].iv_offset = temp.iv_offset;
 1354             segments[i].type = temp.type;
 1355         }
 1356     }
 1357 
 1358     if (params->sector_size != SECTOR_SIZE)
 1359         dmd.flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
 1360 
 1361     r = dm_targets_allocate(&dmd.segment, num_segments);
 1362     if (r)
 1363         goto out;
 1364     next_segment = &dmd.segment;
 1365 
 1366     for (i = 0; i < num_segments; i++) {
 1367         if (segments[i].type == BITLK_SEGTYPE_ZERO)
 1368             r = dm_zero_target_set(next_segment,
 1369                            segments[i].offset,
 1370                            segments[i].length);
 1371         else if (segments[i].type == BITLK_SEGTYPE_CRYPT)
 1372             r = dm_crypt_target_set(next_segment,
 1373                         segments[i].offset,
 1374                         segments[i].length,
 1375                         crypt_data_device(cd),
 1376                         open_fvek_key,
 1377                         crypt_get_cipher_spec(cd),
 1378                         segments[i].iv_offset,
 1379                         segments[i].iv_offset,
 1380                         NULL, 0,
 1381                         params->sector_size);
 1382         if (r)
 1383             goto out;
 1384 
 1385         next_segment = next_segment->next;
 1386     }
 1387 
 1388     log_dbg(cd, "Trying to activate BITLK on device %s%s%s.",
 1389         device_path(crypt_data_device(cd)), name ? " with name " :"", name ?: "");
 1390 
 1391     r = dm_create_device(cd, name, CRYPT_BITLK, &dmd);
 1392     if (r < 0) {
 1393         dm_flags(cd, DM_CRYPT, &dmt_flags);
 1394         if (!strcmp(params->cipher_mode, "cbc-eboiv") && !(dmt_flags & DM_BITLK_EBOIV_SUPPORTED)) {
 1395             log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for BITLK IV."));
 1396             r = -ENOTSUP;
 1397         }
 1398         if (!strcmp(params->cipher_mode, "cbc-elephant") && !(dmt_flags & DM_BITLK_ELEPHANT_SUPPORTED)) {
 1399             log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for BITLK Elephant diffuser."));
 1400             r = -ENOTSUP;
 1401         }
 1402     }
 1403 out:
 1404     dm_targets_free(cd, &dmd);
 1405     return r;
 1406 }
 1407 
 1408 int BITLK_activate_by_passphrase(struct crypt_device *cd,
 1409                  const char *name,
 1410                  const char *password,
 1411                  size_t passwordLen,
 1412                  const struct bitlk_metadata *params,
 1413                  uint32_t flags)
 1414 {
 1415     int r = 0;
 1416     struct volume_key *open_fvek_key = NULL;
 1417 
 1418     r = _activate_check(cd, params);
 1419     if (r)
 1420         return r;
 1421 
 1422     r = BITLK_get_volume_key(cd, password, passwordLen, params, &open_fvek_key);
 1423     if (r < 0)
 1424         goto out;
 1425 
 1426     /* Password verify only */
 1427     if (!name)
 1428         goto out;
 1429 
 1430     r = _activate(cd, name, open_fvek_key, params, flags);
 1431 out:
 1432     crypt_free_volume_key(open_fvek_key);
 1433     return r;
 1434 }
 1435 
 1436 int BITLK_activate_by_volume_key(struct crypt_device *cd,
 1437                  const char *name,
 1438                  const char *volume_key,
 1439                  size_t volume_key_size,
 1440                  const struct bitlk_metadata *params,
 1441                  uint32_t flags)
 1442 {
 1443     int r = 0;
 1444     struct volume_key *open_fvek_key = NULL;
 1445 
 1446     r = _activate_check(cd, params);
 1447     if (r)
 1448         return r;
 1449 
 1450     open_fvek_key = crypt_alloc_volume_key(volume_key_size, volume_key);
 1451     if (!open_fvek_key)
 1452         return -ENOMEM;
 1453 
 1454     r = _activate(cd, name, open_fvek_key, params, flags);
 1455 
 1456     crypt_free_volume_key(open_fvek_key);
 1457     return r;
 1458 }