diff --git a/lib/luks2/luks2_luks1_convert.c b/lib/luks2/luks2_luks1_convert.c index ee6bce70..7f5f26b7 100644 --- a/lib/luks2/luks2_luks1_convert.c +++ b/lib/luks2/luks2_luks1_convert.c @@ -518,7 +518,7 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct int r; json_object *jobj = NULL; size_t buf_size, buf_offset, luks1_size, luks1_shift = 2 * LUKS2_HDR_16K_LEN - LUKS_ALIGN_KEYSLOTS; - uint64_t max_size = crypt_get_data_offset(cd) * SECTOR_SIZE; + uint64_t required_size, max_size = crypt_get_data_offset(cd) * SECTOR_SIZE; /* for detached headers max size == device size */ if (!max_size && (r = device_size(crypt_metadata_device(cd), &max_size))) @@ -539,11 +539,18 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct log_dbg(cd, "Max size: %" PRIu64 ", LUKS1 (full) header size %zu , required shift: %zu", max_size, luks1_size, luks1_shift); - if ((max_size - luks1_size) < luks1_shift) { + + required_size = luks1_size + luks1_shift; + + if ((max_size < required_size) && + device_fallocate(crypt_metadata_device(cd), required_size)) { log_err(cd, _("Unable to move keyslot area. Not enough space.")); return -EINVAL; } + if (max_size < required_size) + max_size = required_size; + r = json_luks1_object(hdr1, &jobj, max_size - 2 * LUKS2_HDR_16K_LEN); if (r < 0) return r; diff --git a/tests/api-test-2.c b/tests/api-test-2.c index 693b37b7..b0488040 100644 --- a/tests/api-test-2.c +++ b/tests/api-test-2.c @@ -67,6 +67,7 @@ typedef int32_t key_serial_t; #define IMAGE1 "compatimage2.img" #define IMAGE_EMPTY "empty.img" #define IMAGE_EMPTY_SMALL "empty_small.img" +#define IMAGE_EMPTY_SMALL_2 "empty_small2.img" #define IMAGE_PV_LUKS2_SEC "blkid-luks2-pv.img" #define KEYFILE1 "key1.file" @@ -322,6 +323,7 @@ static void _cleanup(void) remove(IMAGE_PV_LUKS2_SEC); remove(IMAGE_PV_LUKS2_SEC ".bcp"); remove(IMAGE_EMPTY_SMALL); + remove(IMAGE_EMPTY_SMALL_2); _remove_keyfiles(); @@ -379,6 +381,8 @@ static int _setup(void) _system("dd if=/dev/zero of=" IMAGE_EMPTY_SMALL " bs=1M count=7 2>/dev/null", 1); + _system("dd if=/dev/zero of=" IMAGE_EMPTY_SMALL_2 " bs=512 count=2050 2>/dev/null", 1); + _system(" [ ! -e " NO_REQS_LUKS2_HEADER " ] && xz -dk " NO_REQS_LUKS2_HEADER ".xz", 1); fd = loop_attach(&DEVICE_4, NO_REQS_LUKS2_HEADER, 0, 0, &ro); close(fd); @@ -1949,6 +1953,11 @@ static void LuksConvert(void) .time_ms = 1 }; + struct crypt_params_luks1 luks1 = { + .hash = "sha256", + .data_device = DMDIR L_DEVICE_1S + }; + struct crypt_params_luks2 luks2 = { .pbkdf = &pbkdf2, .sector_size = 512 @@ -2432,6 +2441,26 @@ static void LuksConvert(void) EQ_(crypt_activate_by_passphrase(cd, NULL, 6, PASS6, strlen(PASS6), 0), 6); CRYPT_FREE(cd); + // detached LUKS1 header upconversion + OK_(create_dmdevice_over_loop(H_DEVICE, 2050)); // default LUKS1 header should fit there + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + crypt_set_iteration_time(cd, 1); + //OK_(crypt_set_pbkdf_type(cd, &pbkdf2)); + OK_(crypt_format(cd, CRYPT_LUKS1, "aes", "xts-plain64", NULL, NULL, 32, &luks1)); + EQ_(crypt_keyslot_add_by_volume_key(cd, 7, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 7); + FAIL_(crypt_convert(cd, CRYPT_LUKS2, NULL), "Unable to move keyslots. Not enough space."); + CRYPT_FREE(cd); + + // 2050 sectors, empty file + OK_(crypt_init(&cd, IMAGE_EMPTY_SMALL_2)); + //OK_(crypt_set_pbkdf_type(cd, &pbkdf2)); + crypt_set_iteration_time(cd, 1); + OK_(crypt_format(cd, CRYPT_LUKS1, "aes", "xts-plain64", NULL, NULL, 32, &luks1)); + EQ_(crypt_get_data_offset(cd), 0); + EQ_(crypt_keyslot_add_by_volume_key(cd, 7, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 7); + OK_(crypt_convert(cd, CRYPT_LUKS2, NULL)); + CRYPT_FREE(cd); + _cleanup_dmdevices(); }