"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/luks2/luks2_json_format.c" (13 Jan 2022, 12602 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 "luks2_json_format.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  * LUKS - Linux Unified Key Setup v2, LUKS2 header format code
    3  *
    4  * Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
    5  * Copyright (C) 2015-2021 Milan Broz
    6  *
    7  * This program is free software; you can redistribute it and/or
    8  * modify it under the terms of the GNU General Public License
    9  * as published by the Free Software Foundation; either version 2
   10  * of the License, or (at your option) any later version.
   11  *
   12  * This program 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
   15  * GNU General Public License for more details.
   16  *
   17  * You should have received a copy of the GNU General Public License
   18  * along with this program; if not, write to the Free Software
   19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   20  */
   21 
   22 #include "luks2_internal.h"
   23 #include <uuid/uuid.h>
   24 #include <assert.h>
   25 
   26 struct area {
   27     uint64_t offset;
   28     uint64_t length;
   29 };
   30 
   31 static size_t get_area_size(size_t keylength)
   32 {
   33     /* for now it is AF_split_sectors */
   34     return size_round_up(keylength * 4000, 4096);
   35 }
   36 
   37 static size_t get_min_offset(struct luks2_hdr *hdr)
   38 {
   39     return 2 * hdr->hdr_size;
   40 }
   41 
   42 static size_t get_max_offset(struct luks2_hdr *hdr)
   43 {
   44     return LUKS2_hdr_and_areas_size(hdr);
   45 }
   46 
   47 int LUKS2_find_area_max_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
   48             uint64_t *area_offset, uint64_t *area_length)
   49 {
   50     struct area areas[LUKS2_KEYSLOTS_MAX], sorted_areas[LUKS2_KEYSLOTS_MAX+1] = {};
   51     int i, j, k, area_i;
   52     size_t valid_offset, offset, length;
   53 
   54     /* fill area offset + length table */
   55     for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) {
   56         if (!LUKS2_keyslot_area(hdr, i, &areas[i].offset, &areas[i].length))
   57             continue;
   58         areas[i].length = 0;
   59         areas[i].offset = 0;
   60     }
   61 
   62     /* sort table */
   63     k = 0; /* index in sorted table */
   64     for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) {
   65         offset = get_max_offset(hdr) ?: UINT64_MAX;
   66         area_i = -1;
   67         /* search for the smallest offset in table */
   68         for (j = 0; j < LUKS2_KEYSLOTS_MAX; j++)
   69             if (areas[j].offset && areas[j].offset <= offset) {
   70                 area_i = j;
   71                 offset = areas[j].offset;
   72             }
   73 
   74         if (area_i >= 0) {
   75             sorted_areas[k].length = areas[area_i].length;
   76             sorted_areas[k].offset = areas[area_i].offset;
   77             areas[area_i].length = 0;
   78             areas[area_i].offset = 0;
   79             k++;
   80         }
   81     }
   82 
   83     sorted_areas[LUKS2_KEYSLOTS_MAX].offset = get_max_offset(hdr);
   84     sorted_areas[LUKS2_KEYSLOTS_MAX].length = 1;
   85 
   86     /* search for the gap we can use */
   87     length = valid_offset = 0;
   88     offset = get_min_offset(hdr);
   89     for (i = 0; i < LUKS2_KEYSLOTS_MAX+1; i++) {
   90         /* skip empty */
   91         if (sorted_areas[i].offset == 0 || sorted_areas[i].length == 0)
   92             continue;
   93 
   94         /* found bigger gap than the last one */
   95         if ((offset < sorted_areas[i].offset) && (sorted_areas[i].offset - offset) > length) {
   96             length = sorted_areas[i].offset - offset;
   97             valid_offset = offset;
   98         }
   99 
  100         /* move beyond allocated area */
  101         offset = sorted_areas[i].offset + sorted_areas[i].length;
  102     }
  103 
  104     /* this search 'algorithm' does not work with unaligned areas */
  105     assert(length == size_round_up(length, 4096));
  106     assert(valid_offset == size_round_up(valid_offset, 4096));
  107 
  108     if (!length) {
  109         log_dbg(cd, "Not enough space in header keyslot area.");
  110         return -EINVAL;
  111     }
  112 
  113     log_dbg(cd, "Found largest free area %zu -> %zu", valid_offset, length + valid_offset);
  114 
  115     *area_offset = valid_offset;
  116     *area_length = length;
  117 
  118     return 0;
  119 }
  120 
  121 int LUKS2_find_area_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
  122             size_t keylength, uint64_t *area_offset, uint64_t *area_length)
  123 {
  124     struct area areas[LUKS2_KEYSLOTS_MAX], sorted_areas[LUKS2_KEYSLOTS_MAX] = {};
  125     int i, j, k, area_i;
  126     size_t offset, length;
  127 
  128     /* fill area offset + length table */
  129     for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) {
  130         if (!LUKS2_keyslot_area(hdr, i, &areas[i].offset, &areas[i].length))
  131             continue;
  132         areas[i].length = 0;
  133         areas[i].offset = 0;
  134     }
  135 
  136     /* sort table */
  137     k = 0; /* index in sorted table */
  138     for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) {
  139         offset = get_max_offset(hdr) ?: UINT64_MAX;
  140         area_i = -1;
  141         /* search for the smallest offset in table */
  142         for (j = 0; j < LUKS2_KEYSLOTS_MAX; j++)
  143             if (areas[j].offset && areas[j].offset <= offset) {
  144                 area_i = j;
  145                 offset = areas[j].offset;
  146             }
  147 
  148         if (area_i >= 0) {
  149             sorted_areas[k].length = areas[area_i].length;
  150             sorted_areas[k].offset = areas[area_i].offset;
  151             areas[area_i].length = 0;
  152             areas[area_i].offset = 0;
  153             k++;
  154         }
  155     }
  156 
  157     /* search for the gap we can use */
  158     offset = get_min_offset(hdr);
  159     length = get_area_size(keylength);
  160     for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) {
  161         /* skip empty */
  162         if (sorted_areas[i].offset == 0 || sorted_areas[i].length == 0)
  163             continue;
  164 
  165         /* enough space before the used area */
  166         if ((offset < sorted_areas[i].offset) && ((offset + length) <= sorted_areas[i].offset))
  167             break;
  168 
  169         /* both offset and length are already aligned to 4096 bytes */
  170         offset = sorted_areas[i].offset + sorted_areas[i].length;
  171     }
  172 
  173     if ((offset + length) > get_max_offset(hdr)) {
  174         log_dbg(cd, "Not enough space in header keyslot area.");
  175         return -EINVAL;
  176     }
  177 
  178     log_dbg(cd, "Found area %zu -> %zu", offset, length + offset);
  179 
  180     if (area_offset)
  181         *area_offset = offset;
  182     if (area_length)
  183         *area_length = length;
  184 
  185     return 0;
  186 }
  187 
  188 int LUKS2_check_metadata_area_size(uint64_t metadata_size)
  189 {
  190     /* see LUKS2_HDR2_OFFSETS */
  191     return (metadata_size != 0x004000 &&
  192         metadata_size != 0x008000 && metadata_size != 0x010000 &&
  193         metadata_size != 0x020000 && metadata_size != 0x040000 &&
  194         metadata_size != 0x080000 && metadata_size != 0x100000 &&
  195         metadata_size != 0x200000 && metadata_size != 0x400000);
  196 }
  197 
  198 int LUKS2_check_keyslots_area_size(uint64_t keyslots_size)
  199 {
  200     return (MISALIGNED_4K(keyslots_size) ||
  201         keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE);
  202 }
  203 
  204 int LUKS2_generate_hdr(
  205     struct crypt_device *cd,
  206     struct luks2_hdr *hdr,
  207     const struct volume_key *vk,
  208     const char *cipherName,
  209     const char *cipherMode,
  210     const char *integrity,
  211     const char *uuid,
  212     unsigned int sector_size,  /* in bytes */
  213     uint64_t data_offset,      /* in bytes */
  214     uint64_t align_offset,     /* in bytes */
  215     uint64_t required_alignment,
  216     uint64_t metadata_size,
  217     uint64_t keyslots_size)
  218 {
  219     struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_segments, *jobj_config;
  220     char cipher[128];
  221     uuid_t partitionUuid;
  222     int r, digest;
  223     uint64_t mdev_size;
  224 
  225     if (!metadata_size)
  226         metadata_size = LUKS2_HDR_16K_LEN;
  227     hdr->hdr_size = metadata_size;
  228 
  229     if (data_offset && data_offset < get_min_offset(hdr)) {
  230         log_err(cd, _("Requested data offset is too small."));
  231         return -EINVAL;
  232     }
  233 
  234     /* Increase keyslot size according to data offset */
  235     if (!keyslots_size && data_offset)
  236         keyslots_size = data_offset - get_min_offset(hdr);
  237 
  238     /* keyslots size has to be 4 KiB aligned */
  239     keyslots_size -= (keyslots_size % 4096);
  240 
  241     if (keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE)
  242         keyslots_size = LUKS2_MAX_KEYSLOTS_SIZE;
  243 
  244     if (!keyslots_size) {
  245         assert(LUKS2_DEFAULT_HDR_SIZE > 2 * LUKS2_HDR_OFFSET_MAX);
  246         keyslots_size = LUKS2_DEFAULT_HDR_SIZE - get_min_offset(hdr);
  247         /* Decrease keyslots_size due to metadata device being too small */
  248         if (!device_size(crypt_metadata_device(cd), &mdev_size) &&
  249             ((keyslots_size + get_min_offset(hdr)) > mdev_size) &&
  250             device_fallocate(crypt_metadata_device(cd), keyslots_size + get_min_offset(hdr)) &&
  251             (get_min_offset(hdr) <= mdev_size))
  252             keyslots_size = mdev_size - get_min_offset(hdr);
  253     }
  254 
  255     /* Decrease keyslots_size if we have smaller data_offset */
  256     if (data_offset && (keyslots_size + get_min_offset(hdr)) > data_offset) {
  257         keyslots_size = data_offset - get_min_offset(hdr);
  258         log_dbg(cd, "Decreasing keyslot area size to %" PRIu64
  259             " bytes due to the requested data offset %"
  260             PRIu64 " bytes.", keyslots_size, data_offset);
  261     }
  262 
  263     /* Data offset has priority */
  264     if (!data_offset && required_alignment) {
  265         data_offset = size_round_up(get_min_offset(hdr) + keyslots_size,
  266                         (size_t)required_alignment);
  267         data_offset += align_offset;
  268     }
  269 
  270     log_dbg(cd, "Formatting LUKS2 with JSON metadata area %" PRIu64
  271         " bytes and keyslots area %" PRIu64 " bytes.",
  272         metadata_size - LUKS2_HDR_BIN_LEN, keyslots_size);
  273 
  274     if (keyslots_size < (LUKS2_HDR_OFFSET_MAX - 2*LUKS2_HDR_16K_LEN))
  275         log_std(cd, _("WARNING: keyslots area (%" PRIu64 " bytes) is very small,"
  276             " available LUKS2 keyslot count is very limited.\n"),
  277             keyslots_size);
  278 
  279     hdr->seqid = 1;
  280     hdr->version = 2;
  281     memset(hdr->label, 0, LUKS2_LABEL_L);
  282     strcpy(hdr->checksum_alg, "sha256");
  283     crypt_random_get(cd, (char*)hdr->salt1, LUKS2_SALT_L, CRYPT_RND_SALT);
  284     crypt_random_get(cd, (char*)hdr->salt2, LUKS2_SALT_L, CRYPT_RND_SALT);
  285 
  286     if (uuid && uuid_parse(uuid, partitionUuid) == -1) {
  287         log_err(cd, _("Wrong LUKS UUID format provided."));
  288         return -EINVAL;
  289     }
  290     if (!uuid)
  291         uuid_generate(partitionUuid);
  292 
  293     uuid_unparse(partitionUuid, hdr->uuid);
  294 
  295     if (*cipherMode != '\0')
  296         r = snprintf(cipher, sizeof(cipher), "%s-%s", cipherName, cipherMode);
  297     else
  298         r = snprintf(cipher, sizeof(cipher), "%s", cipherName);
  299     if (r < 0 || (size_t)r >= sizeof(cipher))
  300         return -EINVAL;
  301 
  302     hdr->jobj = json_object_new_object();
  303 
  304     jobj_keyslots = json_object_new_object();
  305     json_object_object_add(hdr->jobj, "keyslots", jobj_keyslots);
  306     json_object_object_add(hdr->jobj, "tokens", json_object_new_object());
  307     jobj_segments = json_object_new_object();
  308     json_object_object_add(hdr->jobj, "segments", jobj_segments);
  309     json_object_object_add(hdr->jobj, "digests", json_object_new_object());
  310     jobj_config = json_object_new_object();
  311     json_object_object_add(hdr->jobj, "config", jobj_config);
  312 
  313     digest = LUKS2_digest_create(cd, "pbkdf2", hdr, vk);
  314     if (digest < 0)
  315         goto err;
  316 
  317     if (LUKS2_digest_segment_assign(cd, hdr, 0, digest, 1, 0) < 0)
  318         goto err;
  319 
  320     jobj_segment = json_segment_create_crypt(data_offset, 0, NULL, cipher, sector_size, 0);
  321     if (!jobj_segment)
  322         goto err;
  323 
  324     if (integrity) {
  325         jobj_integrity = json_object_new_object();
  326         json_object_object_add(jobj_integrity, "type", json_object_new_string(integrity));
  327         json_object_object_add(jobj_integrity, "journal_encryption", json_object_new_string("none"));
  328         json_object_object_add(jobj_integrity, "journal_integrity", json_object_new_string("none"));
  329         json_object_object_add(jobj_segment, "integrity", jobj_integrity);
  330     }
  331 
  332     json_object_object_add_by_uint(jobj_segments, 0, jobj_segment);
  333 
  334     json_object_object_add(jobj_config, "json_size", crypt_jobj_new_uint64(metadata_size - LUKS2_HDR_BIN_LEN));
  335     json_object_object_add(jobj_config, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
  336 
  337     JSON_DBG(cd, hdr->jobj, "Header JSON:");
  338     return 0;
  339 err:
  340     json_object_put(hdr->jobj);
  341     hdr->jobj = NULL;
  342     return -EINVAL;
  343 }
  344 
  345 int LUKS2_wipe_header_areas(struct crypt_device *cd,
  346     struct luks2_hdr *hdr, bool detached_header)
  347 {
  348     int r;
  349     uint64_t offset, length;
  350     size_t wipe_block;
  351 
  352     /* Wipe complete header, keyslots and padding areas with zeroes. */
  353     offset = 0;
  354     length = LUKS2_get_data_offset(hdr) * SECTOR_SIZE;
  355     wipe_block = 1024 * 1024;
  356 
  357     if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
  358         return -EINVAL;
  359 
  360     /* On detached header wipe at least the first 4k */
  361     if (detached_header) {
  362         length = 4096;
  363         wipe_block = 4096;
  364     }
  365 
  366     log_dbg(cd, "Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.",
  367         offset, length + offset);
  368 
  369     r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO,
  370                   offset, length, wipe_block, NULL, NULL);
  371     if (r < 0)
  372         return r;
  373 
  374     /* Wipe keyslot area */
  375     wipe_block = 1024 * 1024;
  376     offset = get_min_offset(hdr);
  377     length = LUKS2_keyslots_size(hdr);
  378 
  379     log_dbg(cd, "Wiping keyslots area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.",
  380         offset, length + offset);
  381 
  382     return crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_RANDOM,
  383                  offset, length, wipe_block, NULL, NULL);
  384 }
  385 
  386 int LUKS2_set_keyslots_size(struct crypt_device *cd __attribute__((unused)),
  387         struct luks2_hdr *hdr,
  388         uint64_t data_offset)
  389 {
  390     json_object *jobj_config;
  391     uint64_t keyslots_size;
  392 
  393     if (data_offset < get_min_offset(hdr))
  394         return 1;
  395 
  396     keyslots_size = data_offset - get_min_offset(hdr);
  397 
  398     /* keep keyslots_size reasonable for custom data alignments */
  399     if (keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE)
  400         keyslots_size = LUKS2_MAX_KEYSLOTS_SIZE;
  401 
  402     /* keyslots size has to be 4 KiB aligned */
  403     keyslots_size -= (keyslots_size % 4096);
  404 
  405     if (!json_object_object_get_ex(hdr->jobj, "config", &jobj_config))
  406         return 1;
  407 
  408     json_object_object_add(jobj_config, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
  409     return 0;
  410 }