Skip to content

Commit

Permalink
Simplify LUKS2_wipe_header_areas.
Browse files Browse the repository at this point in the history
For LUKS2 headers with non zero data offset LUKS2_wipe_header_areas
will always erase the smallest from following:

- metadata device size
- data offset value
- maximal LUKS2 metadata size (twice 2 MiBs json area including 128 MiB for
binary keyslot areas) even with detached header.

For zero value data offset (LUKS2 header can not be restored back to
data device), we erase up to smallest from the following values:

- metadata device size
- maximal LUKS2 metadata size (twice 2 MiBs json area including 128 MiB for
  • Loading branch information
oniko committed Jun 5, 2024
1 parent 2a13ef5 commit 494c510
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 24 deletions.
4 changes: 3 additions & 1 deletion lib/luks2/luks2.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ struct luks2_keyslot_params {

#define LUKS2_HDR_OFFSET_MAX 0x400000 /* 4 MiB */

#define LUKS2_HDR_MAX_MDA_SIZE 2 * LUKS2_HDR_OFFSET_MAX + LUKS2_MAX_KEYSLOTS_SIZE

/* Offsets for secondary header (for scan if primary header is corrupted). */
#define LUKS2_HDR2_OFFSETS { 0x04000, 0x008000, 0x010000, 0x020000, \
0x40000, 0x080000, 0x100000, 0x200000, LUKS2_HDR_OFFSET_MAX }
Expand Down Expand Up @@ -389,7 +391,7 @@ int LUKS2_check_metadata_area_size(uint64_t metadata_size);
int LUKS2_check_keyslots_area_size(uint64_t keyslots_size);

int LUKS2_wipe_header_areas(struct crypt_device *cd,
struct luks2_hdr *hdr, bool detached_header);
struct luks2_hdr *hdr);

uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic);
Expand Down
43 changes: 23 additions & 20 deletions lib/luks2/luks2_json_format.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,40 +313,43 @@ int LUKS2_generate_hdr(
}

int LUKS2_wipe_header_areas(struct crypt_device *cd,
struct luks2_hdr *hdr, bool detached_header)
struct luks2_hdr *hdr)
{
int r;
uint64_t offset, length;
size_t wipe_block;
uint64_t device_size_bytes, length, offset;
size_t wipe_block = 1024 * 1024;

/* Wipe complete header, keyslots and padding areas with zeroes. */
offset = 0;
length = LUKS2_get_data_offset(hdr) * SECTOR_SIZE;
wipe_block = 1024 * 1024;
if (!hdr || LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
return -EINVAL;

if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
r = device_size(crypt_metadata_device(cd), &device_size_bytes);
if (r < 0)
return -EINVAL;

/* On detached header wipe at least the first 4k */
if (detached_header) {
length = 4096;
wipe_block = 4096;
}
/* Wipe up to maximal allowed metadata size, but do not write beyond data offset. */
length = LUKS2_get_data_offset(hdr) * SECTOR_SIZE;
if (!length || length > LUKS2_HDR_MAX_MDA_SIZE)
length = LUKS2_HDR_MAX_MDA_SIZE;

r = device_check_size(cd, crypt_metadata_device(cd), length, 1);
if (r)
return r;
/* Also do not extend the device size yet (file backends) */
if (length > device_size_bytes)
length = device_size_bytes;

log_dbg(cd, "Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.",
offset, length + offset);
0, length);

r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO,
offset, length, wipe_block, NULL, NULL);
r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO, 0,
length, wipe_block, NULL, NULL);
if (r < 0)
return r;

/* Allocate at least actual LUKS2 metadata size */
r = device_check_size(cd, crypt_metadata_device(cd),
LUKS2_hdr_and_areas_size(hdr), 1);
if (r)
return r;

/* Wipe keyslot area */
wipe_block = 1024 * 1024;
offset = get_min_offset(hdr);
length = LUKS2_keyslots_size(hdr);

Expand Down
4 changes: 2 additions & 2 deletions lib/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -2139,7 +2139,7 @@ static int _crypt_format_luks2(struct crypt_device *cd,

device_set_block_size(crypt_data_device(cd), sector_size);

r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr, cd->metadata_device != NULL);
r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr);
if (r < 0) {
log_err(cd, _("Cannot wipe header on device %s."),
mdata_device_path(cd));
Expand Down Expand Up @@ -2544,7 +2544,7 @@ int crypt_format_luks2_opal(struct crypt_device *cd,

device_set_block_size(crypt_data_device(cd), sector_size);

r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr, cd->metadata_device != NULL);
r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr);
if (r < 0) {
log_err(cd, _("Cannot wipe header on device %s."),
mdata_device_path(cd));
Expand Down
2 changes: 1 addition & 1 deletion lib/utils_wipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,5 +366,5 @@ int crypt_wipe_hw_opal(struct crypt_device *cd,
if (r < 0)
return r;

return LUKS2_wipe_header_areas(cd, hdr, crypt_header_is_detached(cd));
return LUKS2_wipe_header_areas(cd, hdr);
}

0 comments on commit 494c510

Please sign in to comment.