"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/luks2/luks2_json_format.c" between
cryptsetup-2.0.6.tar.xz and cryptsetup-2.1.0.tar.xz

About: cryptsetup is a utility used to conveniently setup disk encryption based on the dm-crypt kernel module. These include plain dm-crypt volumes, LUKS volumes, loop-AES and TrueCrypt compatible format.

luks2_json_format.c  (cryptsetup-2.0.6.tar.xz):luks2_json_format.c  (cryptsetup-2.1.0.tar.xz)
/* /*
* LUKS - Linux Unified Key Setup v2, LUKS2 header format code * LUKS - Linux Unified Key Setup v2, LUKS2 header format code
* *
* Copyright (C) 2015-2018, Red Hat, Inc. All rights reserved. * Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2018, Milan Broz. All rights reserved. * Copyright (C) 2015-2019 Milan Broz
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "luks2_internal.h" #include "luks2_internal.h"
#include <uuid/uuid.h> #include <uuid/uuid.h>
#include <assert.h>
struct area { struct area {
uint64_t offset; uint64_t offset;
uint64_t length; uint64_t length;
}; };
static size_t get_area_size(size_t keylength) static size_t get_area_size(size_t keylength)
{ {
//FIXME: calculate this properly, for now it is AF_split_sectors //FIXME: calculate this properly, for now it is AF_split_sectors
return size_round_up(keylength * 4000, 4096); return size_round_up(keylength * 4000, 4096);
skipping to change at line 103 skipping to change at line 104
/* both offset and length are already aligned to 4096 bytes */ /* both offset and length are already aligned to 4096 bytes */
offset = sorted_areas[i].offset + sorted_areas[i].length; offset = sorted_areas[i].offset + sorted_areas[i].length;
} }
if (get_max_offset(cd) && (offset + length) > get_max_offset(cd)) { if (get_max_offset(cd) && (offset + length) > get_max_offset(cd)) {
log_err(cd, _("No space for new keyslot.")); log_err(cd, _("No space for new keyslot."));
return -EINVAL; return -EINVAL;
} }
log_dbg("Found area %zu -> %zu", offset, length + offset); log_dbg(cd, "Found area %zu -> %zu", offset, length + offset);
/* /*
log_dbg("Area offset min: %zu, max %zu, slots max %u", log_dbg("Area offset min: %zu, max %zu, slots max %u",
get_min_offset(hdr), get_max_offset(cd), LUKS2_KEYSLOTS_MAX); get_min_offset(hdr), get_max_offset(cd), LUKS2_KEYSLOTS_MAX);
for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++)
log_dbg("SLOT[%02i]: %-8" PRIu64 " -> %-8" PRIu64, i, log_dbg("SLOT[%02i]: %-8" PRIu64 " -> %-8" PRIu64, i,
sorted_areas[i].offset, sorted_areas[i].offset,
sorted_areas[i].length + sorted_areas[i].offset); sorted_areas[i].length + sorted_areas[i].offset);
*/ */
*area_offset = offset; *area_offset = offset;
*area_length = length; *area_length = length;
skipping to change at line 142 skipping to change at line 143
int LUKS2_generate_hdr( int LUKS2_generate_hdr(
struct crypt_device *cd, struct crypt_device *cd,
struct luks2_hdr *hdr, struct luks2_hdr *hdr,
const struct volume_key *vk, const struct volume_key *vk,
const char *cipherName, const char *cipherName,
const char *cipherMode, const char *cipherMode,
const char *integrity, const char *integrity,
const char *uuid, const char *uuid,
unsigned int sector_size, /* in bytes */ unsigned int sector_size, /* in bytes */
unsigned int alignPayload, /* in bytes */ uint64_t data_offset, /* in bytes */
unsigned int alignOffset, /* in bytes */ uint64_t align_offset, /* in bytes */
int detached_metadata_device) uint64_t required_alignment,
uint64_t metadata_size,
uint64_t keyslots_size)
{ {
struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_ segments, *jobj_config; struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_ segments, *jobj_config;
char num[24], cipher[128]; char cipher[128];
uint64_t offset, json_size, keyslots_size;
uuid_t partitionUuid; uuid_t partitionUuid;
int digest; int digest;
hdr->hdr_size = LUKS2_HDR_16K_LEN; if (!metadata_size)
metadata_size = LUKS2_HDR_16K_LEN;
hdr->hdr_size = metadata_size;
if (data_offset && data_offset < get_min_offset(hdr)) {
log_err(cd, _("Requested data offset is too small."));
return -EINVAL;
}
/* Increase keyslot size according to data offset */
if (!keyslots_size && data_offset)
keyslots_size = data_offset - get_min_offset(hdr);
/* keyslots size has to be 4 KiB aligned */
keyslots_size -= (keyslots_size % 4096);
if (keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE)
keyslots_size = LUKS2_MAX_KEYSLOTS_SIZE;
if (!keyslots_size) {
assert(LUKS2_DEFAULT_HDR_SIZE > 2 * LUKS2_HDR_OFFSET_MAX);
keyslots_size = LUKS2_DEFAULT_HDR_SIZE - get_min_offset(hdr);
}
/* Decrease keyslots_size if we have smaller data_offset */
if (data_offset && (keyslots_size + get_min_offset(hdr)) > data_offset) {
keyslots_size = data_offset - get_min_offset(hdr);
log_dbg(cd, "Decreasing keyslot area size to %" PRIu64
" bytes due to the requested data offset %"
PRIu64 " bytes.", keyslots_size, data_offset);
}
/* Data offset has priority */
if (!data_offset && required_alignment) {
data_offset = size_round_up(get_min_offset(hdr) + keyslots_size,
(size_t)required_alignment);
data_offset += align_offset;
}
log_dbg(cd, "Formatting LUKS2 with JSON metadata area %" PRIu64
" bytes and keyslots area %" PRIu64 " bytes.",
metadata_size - LUKS2_HDR_BIN_LEN, keyslots_size);
if (keyslots_size < (LUKS2_HDR_OFFSET_MAX - 2*LUKS2_HDR_16K_LEN))
log_std(cd, _("WARNING: keyslots area (%" PRIu64 " bytes) is very
small,"
" available LUKS2 keyslot count is very limited.\n"),
keyslots_size);
hdr->seqid = 1; hdr->seqid = 1;
hdr->version = 2; hdr->version = 2;
memset(hdr->label, 0, LUKS2_LABEL_L); memset(hdr->label, 0, LUKS2_LABEL_L);
strcpy(hdr->checksum_alg, "sha256"); strcpy(hdr->checksum_alg, "sha256");
crypt_random_get(NULL, (char*)hdr->salt1, LUKS2_SALT_L, CRYPT_RND_SALT); crypt_random_get(cd, (char*)hdr->salt1, LUKS2_SALT_L, CRYPT_RND_SALT);
crypt_random_get(NULL, (char*)hdr->salt2, LUKS2_SALT_L, CRYPT_RND_SALT); crypt_random_get(cd, (char*)hdr->salt2, LUKS2_SALT_L, CRYPT_RND_SALT);
if (uuid && uuid_parse(uuid, partitionUuid) == -1) { if (uuid && uuid_parse(uuid, partitionUuid) == -1) {
log_err(cd, _("Wrong LUKS UUID format provided.")); log_err(cd, _("Wrong LUKS UUID format provided."));
return -EINVAL; return -EINVAL;
} }
if (!uuid) if (!uuid)
uuid_generate(partitionUuid); uuid_generate(partitionUuid);
uuid_unparse(partitionUuid, hdr->uuid); uuid_unparse(partitionUuid, hdr->uuid);
skipping to change at line 200 skipping to change at line 249
} }
if (LUKS2_digest_segment_assign(cd, hdr, CRYPT_DEFAULT_SEGMENT, digest, 1 , 0) < 0) { if (LUKS2_digest_segment_assign(cd, hdr, CRYPT_DEFAULT_SEGMENT, digest, 1 , 0) < 0) {
json_object_put(hdr->jobj); json_object_put(hdr->jobj);
hdr->jobj = NULL; hdr->jobj = NULL;
return -EINVAL; return -EINVAL;
} }
jobj_segment = json_object_new_object(); jobj_segment = json_object_new_object();
json_object_object_add(jobj_segment, "type", json_object_new_string("cryp t")); json_object_object_add(jobj_segment, "type", json_object_new_string("cryp t"));
if (detached_metadata_device) json_object_object_add(jobj_segment, "offset", json_object_new_uint64(dat
offset = (uint64_t)alignPayload; a_offset));
else {
//FIXME
//offset = size_round_up(areas[7].offset + areas[7].length, align
Payload * SECTOR_SIZE);
offset = size_round_up(LUKS2_HDR_DEFAULT_LEN, (size_t)alignPayloa
d);
offset += alignOffset;
}
json_object_object_add(jobj_segment, "offset", json_object_new_uint64(off
set));
json_object_object_add(jobj_segment, "iv_tweak", json_object_new_string(" 0")); json_object_object_add(jobj_segment, "iv_tweak", json_object_new_string(" 0"));
json_object_object_add(jobj_segment, "size", json_object_new_string("dyna mic")); json_object_object_add(jobj_segment, "size", json_object_new_string("dyna mic"));
json_object_object_add(jobj_segment, "encryption", json_object_new_string (cipher)); json_object_object_add(jobj_segment, "encryption", json_object_new_string (cipher));
json_object_object_add(jobj_segment, "sector_size", json_object_new_int(s ector_size)); json_object_object_add(jobj_segment, "sector_size", json_object_new_int(s ector_size));
if (integrity) { if (integrity) {
jobj_integrity = json_object_new_object(); jobj_integrity = json_object_new_object();
json_object_object_add(jobj_integrity, "type", json_object_new_st ring(integrity)); json_object_object_add(jobj_integrity, "type", json_object_new_st ring(integrity));
json_object_object_add(jobj_integrity, "journal_encryption", json _object_new_string("none")); json_object_object_add(jobj_integrity, "journal_encryption", json _object_new_string("none"));
json_object_object_add(jobj_integrity, "journal_integrity", json_ object_new_string("none")); json_object_object_add(jobj_integrity, "journal_integrity", json_ object_new_string("none"));
json_object_object_add(jobj_segment, "integrity", jobj_integrity) ; json_object_object_add(jobj_segment, "integrity", jobj_integrity) ;
} }
snprintf(num, sizeof(num), "%u", CRYPT_DEFAULT_SEGMENT); json_object_object_add_by_uint(jobj_segments, CRYPT_DEFAULT_SEGMENT, jobj
json_object_object_add(jobj_segments, num, jobj_segment); _segment);
json_size = hdr->hdr_size - LUKS2_HDR_BIN_LEN;
json_object_object_add(jobj_config, "json_size", json_object_new_uint64(j
son_size));
/* for detached metadata device compute reasonable keyslot areas size */
// FIXME: this is coupled with FIXME above
if (detached_metadata_device && !offset)
keyslots_size = LUKS2_HDR_DEFAULT_LEN - get_min_offset(hdr);
else
keyslots_size = offset - get_min_offset(hdr);
/* keep keyslots_size reasonable for custom data alignments */
if (keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE)
keyslots_size = LUKS2_MAX_KEYSLOTS_SIZE;
/* keyslots size has to be 4 KiB aligned */
keyslots_size -= (keyslots_size % 4096);
json_object_object_add(jobj_config, "json_size", json_object_new_uint64(m etadata_size - LUKS2_HDR_BIN_LEN));
json_object_object_add(jobj_config, "keyslots_size", json_object_new_uint 64(keyslots_size)); json_object_object_add(jobj_config, "keyslots_size", json_object_new_uint 64(keyslots_size));
JSON_DBG(hdr->jobj, "Header JSON"); JSON_DBG(cd, hdr->jobj, "Header JSON:");
return 0; return 0;
} }
int LUKS2_wipe_header_areas(struct crypt_device *cd, int LUKS2_wipe_header_areas(struct crypt_device *cd,
struct luks2_hdr *hdr) struct luks2_hdr *hdr)
{ {
int r; int r;
uint64_t offset, length; uint64_t offset, length;
size_t wipe_block; size_t wipe_block;
/* Wipe complete header, keyslots and padding areas with zeroes. */ /* Wipe complete header, keyslots and padding areas with zeroes. */
offset = 0; offset = 0;
length = LUKS2_get_data_offset(hdr) * SECTOR_SIZE; length = LUKS2_get_data_offset(hdr) * SECTOR_SIZE;
wipe_block = 1024 * 1024; wipe_block = 1024 * 1024;
if (LUKS2_hdr_validate(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN)) if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
return -EINVAL; return -EINVAL;
/* On detached header wipe at least the first 4k */ /* On detached header wipe at least the first 4k */
if (length == 0) { if (length == 0) {
length = 4096; length = 4096;
wipe_block = 4096; wipe_block = 4096;
} }
log_dbg("Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes .", log_dbg(cd, "Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with ze roes.",
offset, length + offset); offset, length + offset);
r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO, r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO,
offset, length, wipe_block, NULL, NULL); offset, length, wipe_block, NULL, NULL);
if (r < 0) if (r < 0)
return r; return r;
/* Wipe keyslot area */ /* Wipe keyslot area */
wipe_block = 1024 * 1024; wipe_block = 1024 * 1024;
offset = get_min_offset(hdr); offset = get_min_offset(hdr);
length = LUKS2_keyslots_size(hdr->jobj); length = LUKS2_keyslots_size(hdr->jobj);
log_dbg("Wiping keyslots area (0x%06" PRIx64 " - 0x%06" PRIx64") with ran dom data.", log_dbg(cd, "Wiping keyslots area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.",
offset, length + offset); offset, length + offset);
return crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_RANDOM , return crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_RANDOM ,
offset, length, wipe_block, NULL, NULL); offset, length, wipe_block, NULL, NULL);
} }
 End of changes. 14 change blocks. 
48 lines changed or deleted 70 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)