mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Fix internal crypt segment compare routine.
The function is supposed to check if manipulated active dm-crypt device matches the on-disk metadata. Unfortunately it did not take into account differences between normal cipher specification (aes-xts-plain64) and capi format specification (capi:xts(aes)-plain64). The internal query function always converted capi format in normal format and therefor failed if capi format was used in metadata. Fixes: #759.
This commit is contained in:
36
lib/setup.c
36
lib/setup.c
@@ -2458,6 +2458,9 @@ static int _compare_crypt_devices(struct crypt_device *cd,
|
|||||||
const struct dm_target *src,
|
const struct dm_target *src,
|
||||||
const struct dm_target *tgt)
|
const struct dm_target *tgt)
|
||||||
{
|
{
|
||||||
|
char *src_cipher = NULL, *src_integrity = NULL;
|
||||||
|
int r = -EINVAL;
|
||||||
|
|
||||||
/* for crypt devices keys are mandatory */
|
/* for crypt devices keys are mandatory */
|
||||||
if (!src->u.crypt.vk || !tgt->u.crypt.vk)
|
if (!src->u.crypt.vk || !tgt->u.crypt.vk)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -2465,21 +2468,30 @@ static int _compare_crypt_devices(struct crypt_device *cd,
|
|||||||
/* CIPHER checks */
|
/* CIPHER checks */
|
||||||
if (!src->u.crypt.cipher || !tgt->u.crypt.cipher)
|
if (!src->u.crypt.cipher || !tgt->u.crypt.cipher)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (strcmp(src->u.crypt.cipher, tgt->u.crypt.cipher)) {
|
|
||||||
log_dbg(cd, "Cipher specs do not match.");
|
/*
|
||||||
|
* dm_query_target converts capi cipher specification to dm-crypt format.
|
||||||
|
* We need to do same for cipher specification requested in source
|
||||||
|
* device.
|
||||||
|
*/
|
||||||
|
if (crypt_capi_to_cipher(&src_cipher, &src_integrity, src->u.crypt.cipher, src->u.crypt.integrity))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (strcmp(src_cipher, tgt->u.crypt.cipher)) {
|
||||||
|
log_dbg(cd, "Cipher specs do not match.");
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tgt->u.crypt.vk->keylength == 0 && crypt_is_cipher_null(tgt->u.crypt.cipher))
|
if (tgt->u.crypt.vk->keylength == 0 && crypt_is_cipher_null(tgt->u.crypt.cipher))
|
||||||
log_dbg(cd, "Existing device uses cipher null. Skipping key comparison.");
|
log_dbg(cd, "Existing device uses cipher null. Skipping key comparison.");
|
||||||
else if (_compare_volume_keys(src->u.crypt.vk, 0, tgt->u.crypt.vk, tgt->u.crypt.vk->key_description != NULL)) {
|
else if (_compare_volume_keys(src->u.crypt.vk, 0, tgt->u.crypt.vk, tgt->u.crypt.vk->key_description != NULL)) {
|
||||||
log_dbg(cd, "Keys in context and target device do not match.");
|
log_dbg(cd, "Keys in context and target device do not match.");
|
||||||
return -EINVAL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crypt_strcmp(src->u.crypt.integrity, tgt->u.crypt.integrity)) {
|
if (crypt_strcmp(src_integrity, tgt->u.crypt.integrity)) {
|
||||||
log_dbg(cd, "Integrity parameters do not match.");
|
log_dbg(cd, "Integrity parameters do not match.");
|
||||||
return -EINVAL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->u.crypt.offset != tgt->u.crypt.offset ||
|
if (src->u.crypt.offset != tgt->u.crypt.offset ||
|
||||||
@@ -2487,15 +2499,19 @@ static int _compare_crypt_devices(struct crypt_device *cd,
|
|||||||
src->u.crypt.iv_offset != tgt->u.crypt.iv_offset ||
|
src->u.crypt.iv_offset != tgt->u.crypt.iv_offset ||
|
||||||
src->u.crypt.tag_size != tgt->u.crypt.tag_size) {
|
src->u.crypt.tag_size != tgt->u.crypt.tag_size) {
|
||||||
log_dbg(cd, "Integer parameters do not match.");
|
log_dbg(cd, "Integer parameters do not match.");
|
||||||
return -EINVAL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device_is_identical(src->data_device, tgt->data_device) <= 0) {
|
if (device_is_identical(src->data_device, tgt->data_device) <= 0)
|
||||||
log_dbg(cd, "Data devices do not match.");
|
log_dbg(cd, "Data devices do not match.");
|
||||||
return -EINVAL;
|
else
|
||||||
}
|
r = 0;
|
||||||
|
|
||||||
return 0;
|
out:
|
||||||
|
free(src_cipher);
|
||||||
|
free(src_integrity);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _compare_integrity_devices(struct crypt_device *cd,
|
static int _compare_integrity_devices(struct crypt_device *cd,
|
||||||
|
|||||||
@@ -1585,8 +1585,8 @@ static void ResizeDeviceLuks2(void)
|
|||||||
|
|
||||||
const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
|
const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
|
||||||
size_t key_size = strlen(vk_hex) / 2;
|
size_t key_size = strlen(vk_hex) / 2;
|
||||||
const char *cipher = "aes";
|
const char *cipher = "aes", *capi_cipher = "capi:cbc(aes)";
|
||||||
const char *cipher_mode = "cbc-essiv:sha256";
|
const char *cipher_mode = "cbc-essiv:sha256", *capi_cipher_mode = "essiv:sha256";
|
||||||
uint64_t r_payload_offset, r_header_size, r_size;
|
uint64_t r_payload_offset, r_header_size, r_size;
|
||||||
|
|
||||||
/* Cannot use Argon2 in FIPS */
|
/* Cannot use Argon2 in FIPS */
|
||||||
@@ -1728,6 +1728,16 @@ static void ResizeDeviceLuks2(void)
|
|||||||
OK_(crypt_deactivate(cd, CDEVICE_1));
|
OK_(crypt_deactivate(cd, CDEVICE_1));
|
||||||
CRYPT_FREE(cd);
|
CRYPT_FREE(cd);
|
||||||
|
|
||||||
|
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
|
||||||
|
OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2));
|
||||||
|
OK_(crypt_format(cd, CRYPT_LUKS2, capi_cipher, capi_cipher_mode, NULL, key, key_size, NULL));
|
||||||
|
OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
|
||||||
|
OK_(crypt_resize(cd, CDEVICE_1, 8));
|
||||||
|
if (!t_device_size(DMDIR CDEVICE_1, &r_size))
|
||||||
|
EQ_(8, r_size >> TST_SECTOR_SHIFT);
|
||||||
|
OK_(crypt_deactivate(cd, CDEVICE_1));
|
||||||
|
CRYPT_FREE(cd);
|
||||||
|
|
||||||
_cleanup_dmdevices();
|
_cleanup_dmdevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user