/*
* LUKS - Linux Unified Key Setup v2, LUKS2 header format code
*
- * Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2015-2020 Milan Broz
+ * Copyright (C) 2015-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2015-2023 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#include "luks2_internal.h"
#include <uuid/uuid.h>
-#include <assert.h>
struct area {
uint64_t offset;
static size_t get_area_size(size_t keylength)
{
- //FIXME: calculate this properly, for now it is AF_split_sectors
+ /* for now it is AF_split_sectors */
return size_round_up(keylength * 4000, 4096);
}
static size_t get_max_offset(struct luks2_hdr *hdr)
{
- return LUKS2_hdr_and_areas_size(hdr->jobj);
+ return LUKS2_hdr_and_areas_size(hdr);
}
int LUKS2_find_area_max_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
log_dbg(cd, "Found area %zu -> %zu", offset, length + offset);
- *area_offset = offset;
- *area_length = length;
+ if (area_offset)
+ *area_offset = offset;
+ if (area_length)
+ *area_length = length;
+
return 0;
}
struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_segments, *jobj_config;
char cipher[128];
uuid_t partitionUuid;
- int digest;
+ int r, digest;
uint64_t mdev_size;
if (!metadata_size)
/* Decrease keyslots_size due to metadata device being too small */
if (!device_size(crypt_metadata_device(cd), &mdev_size) &&
((keyslots_size + get_min_offset(hdr)) > mdev_size) &&
- device_fallocate(crypt_metadata_device(cd), keyslots_size + get_min_offset(hdr)))
+ device_fallocate(crypt_metadata_device(cd), keyslots_size + get_min_offset(hdr)) &&
+ (get_min_offset(hdr) <= mdev_size))
keyslots_size = mdev_size - get_min_offset(hdr);
}
uuid_unparse(partitionUuid, hdr->uuid);
if (*cipherMode != '\0')
- snprintf(cipher, sizeof(cipher), "%s-%s", cipherName, cipherMode);
+ r = snprintf(cipher, sizeof(cipher), "%s-%s", cipherName, cipherMode);
else
- snprintf(cipher, sizeof(cipher), "%s", cipherName);
+ r = snprintf(cipher, sizeof(cipher), "%s", cipherName);
+ if (r < 0 || (size_t)r >= sizeof(cipher))
+ return -EINVAL;
hdr->jobj = json_object_new_object();
}
int LUKS2_wipe_header_areas(struct crypt_device *cd,
- struct luks2_hdr *hdr)
+ struct luks2_hdr *hdr, bool detached_header)
{
int r;
uint64_t offset, length;
return -EINVAL;
/* On detached header wipe at least the first 4k */
- if (length == 0) {
+ if (detached_header) {
length = 4096;
wipe_block = 4096;
}
+ r = device_check_size(cd, crypt_metadata_device(cd), length, 1);
+ if (r)
+ return r;
+
log_dbg(cd, "Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.",
offset, length + offset);
/* Wipe keyslot area */
wipe_block = 1024 * 1024;
offset = get_min_offset(hdr);
- length = LUKS2_keyslots_size(hdr->jobj);
+ length = LUKS2_keyslots_size(hdr);
log_dbg(cd, "Wiping keyslots area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.",
offset, length + offset);
offset, length, wipe_block, NULL, NULL);
}
-/* FIXME: what if user wanted to keep original keyslots size? */
-int LUKS2_set_keyslots_size(struct crypt_device *cd,
- struct luks2_hdr *hdr,
- uint64_t data_offset)
+int LUKS2_set_keyslots_size(struct luks2_hdr *hdr, uint64_t data_offset)
{
json_object *jobj_config;
uint64_t keyslots_size;