Commit f30bbbff authored by Ondrej Kozina's avatar Ondrej Kozina Committed by Milan Broz

Fix minimal size expectations failure for backup header file

- backup header file must be page size aligned
- fix for https://bugzilla.redhat.com/show_bug.cgi?id=1030288
- add regression test to api-tests
parent 6b884615
......@@ -154,6 +154,7 @@ int LUKS_hdr_backup(
{
struct device *device = crypt_metadata_device(ctx);
int r = 0, devfd = -1;
ssize_t hdr_size;
ssize_t buffer_size;
char *buffer = NULL;
......@@ -161,15 +162,19 @@ int LUKS_hdr_backup(
if (r)
return r;
buffer_size = LUKS_device_sectors(hdr->keyBytes) << SECTOR_SHIFT;
hdr_size = LUKS_device_sectors(hdr->keyBytes) << SECTOR_SHIFT;
buffer_size = size_round_up(hdr_size, crypt_getpagesize());
buffer = crypt_safe_alloc(buffer_size);
if (!buffer || buffer_size < LUKS_ALIGN_KEYSLOTS) {
if (!buffer || hdr_size < LUKS_ALIGN_KEYSLOTS || hdr_size > buffer_size) {
r = -ENOMEM;
goto out;
}
log_dbg("Storing backup of header (%u bytes) and keyslot area (%u bytes).",
sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS);
sizeof(*hdr), hdr_size - LUKS_ALIGN_KEYSLOTS);
log_dbg("Output backup file size: %u bytes.", buffer_size);
devfd = device_open(device, O_RDONLY);
if(devfd == -1) {
......@@ -178,7 +183,7 @@ int LUKS_hdr_backup(
goto out;
}
if (read_blockwise(devfd, device_block_size(device), buffer, buffer_size) < buffer_size) {
if (read_blockwise(devfd, device_block_size(device), buffer, hdr_size) < hdr_size) {
r = -EIO;
goto out;
}
......
/*
* cryptsetup library API check functions
*
* Copyright (C) 2009-2012 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2013 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2013, Milan Broz
*
* This program is free software; you can redistribute it and/or
......@@ -94,6 +94,7 @@ static int global_lines = 0;
static char *DEVICE_1 = NULL;
static char *DEVICE_2 = NULL;
static char *DEVICE_3 = NULL;
static char *THE_LOOP_DEV = NULL;
static char *tmp_file_1 = NULL;
......@@ -374,6 +375,9 @@ static void _cleanup(void)
if (crypt_loop_device(DEVICE_2))
crypt_loop_detach(DEVICE_2);
if (crypt_loop_device(DEVICE_3))
crypt_loop_detach(DEVICE_3);
_system("rm -f " IMAGE_EMPTY, 0);
_system("rm -f " IMAGE1, 0);
......@@ -394,6 +398,7 @@ static void _cleanup(void)
free(THE_LOOP_DEV);
free(DEVICE_1);
free(DEVICE_2);
free(DEVICE_3);
}
static int _setup(void)
......@@ -458,6 +463,12 @@ static int _setup(void)
fd = crypt_loop_attach(DEVICE_2, IMAGE_EMPTY, 0, 0, &ro);
close(fd);
}
if (!DEVICE_3)
DEVICE_3 = crypt_loop_get_device();
if (!DEVICE_3) {
printf("Cannot find free loop device.\n");
return 1;
}
/* Keymaterial offset is less than 8 sectors */
_system(" [ ! -e " EVL_HEADER_1 " ] && bzip2 -dk " EVL_HEADER_1 ".bz2", 1);
/* keymaterial offset aims into payload area */
......@@ -1428,6 +1439,7 @@ static void LuksHeaderBackup(void)
.data_alignment = 2048,
};
char key[128];
int fd, ro = O_RDONLY;
const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
size_t key_size = strlen(mk_hex) / 2;
......@@ -1435,6 +1447,8 @@ static void LuksHeaderBackup(void)
const char *cipher_mode = "cbc-essiv:sha256";
uint64_t r_payload_offset;
const char *passphrase = PASSPHRASE;
crypt_decode_key(key, mk_hex, key_size);
OK_(get_luks_offsets(0, key_size, params.data_alignment, 0, NULL, &r_payload_offset));
......@@ -1444,6 +1458,8 @@ static void LuksHeaderBackup(void)
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params));
OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
EQ_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)), 7);
EQ_(crypt_keyslot_add_by_volume_key(cd, 0, key, key_size, passphrase, strlen(passphrase)), 0);
OK_(crypt_header_backup(cd, CRYPT_LUKS1, BACKUP_FILE));
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
......@@ -1457,6 +1473,43 @@ static void LuksHeaderBackup(void)
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
// exercise luksOpen using backup header in file
OK_(crypt_init(&cd, BACKUP_FILE));
OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK));
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0);
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
OK_(crypt_init(&cd, BACKUP_FILE));
OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK));
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 7, passphrase, strlen(passphrase), 0), 7);
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
// exercise luksOpen using backup header on block device
fd = crypt_loop_attach(DEVICE_3, BACKUP_FILE, 0, 0, &ro);
close(fd);
OK_(fd < 0);
OK_(crypt_init(&cd, DEVICE_3));
OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK));
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0);
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
OK_(crypt_init(&cd, DEVICE_3));
OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK));
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 7, passphrase, strlen(passphrase), 0), 7);
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd);
_cleanup_dmdevices();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment