diff --git a/lib/luks2/luks2_luks1_convert.c b/lib/luks2/luks2_luks1_convert.c index 4630ea30..a1755a91 100644 --- a/lib/luks2/luks2_luks1_convert.c +++ b/lib/luks2/luks2_luks1_convert.c @@ -586,8 +586,8 @@ out: return r; } -static int keyslot_LUKS1_compatible(struct crypt_device *cd, - struct luks2_hdr *hdr, int keyslot, uint32_t key_size) +static int keyslot_LUKS1_compatible(struct crypt_device *cd, struct luks2_hdr *hdr, + int keyslot, uint32_t key_size, const char *hash) { json_object *jobj_keyslot, *jobj, *jobj_kdf, *jobj_af; uint64_t l2_offset, l2_length; @@ -606,7 +606,9 @@ static int keyslot_LUKS1_compatible(struct crypt_device *cd, jobj = NULL; if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf) || !json_object_object_get_ex(jobj_kdf, "type", &jobj) || - strcmp(json_object_get_string(jobj), CRYPT_KDF_PBKDF2)) + strcmp(json_object_get_string(jobj), CRYPT_KDF_PBKDF2) || + !json_object_object_get_ex(jobj_kdf, "hash", &jobj) || + strcmp(json_object_get_string(jobj), hash)) return 0; jobj = NULL; @@ -617,7 +619,8 @@ static int keyslot_LUKS1_compatible(struct crypt_device *cd, jobj = NULL; if (!json_object_object_get_ex(jobj_af, "hash", &jobj) || - crypt_hash_size(json_object_get_string(jobj)) < 0) + (crypt_hash_size(json_object_get_string(jobj)) < 0) || + strcmp(json_object_get_string(jobj), hash)) return 0; /* FIXME: should this go to validation code instead (aka invalid luks2 header if assigned to segment 0)? */ @@ -646,6 +649,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct size_t buf_size, buf_offset; char cipher[LUKS_CIPHERNAME_L-1], cipher_mode[LUKS_CIPHERMODE_L-1]; char digest[LUKS_DIGESTSIZE], digest_salt[LUKS_SALTSIZE]; + const char *hash; size_t len; json_object *jobj_keyslot, *jobj_digest, *jobj_segment, *jobj_kdf, *jobj_area, *jobj1, *jobj2; uint32_t key_size; @@ -668,6 +672,9 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct log_err(cd, _("Cannot convert to LUKS1 format - key slot digests are not LUKS1 compatible.")); return -EINVAL; } + if (!json_object_object_get_ex(jobj_digest, "hash", &jobj2)) + return -EINVAL; + hash = json_object_get_string(jobj2); r = crypt_parse_name_and_mode(LUKS2_get_cipher(hdr2, CRYPT_DEFAULT_SEGMENT), cipher, NULL, cipher_mode); if (r < 0) @@ -705,7 +712,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct return -EINVAL; } - if (!keyslot_LUKS1_compatible(cd, hdr2, i, key_size)) { + if (!keyslot_LUKS1_compatible(cd, hdr2, i, key_size, hash)) { log_err(cd, _("Cannot convert to LUKS1 format - keyslot %u is not LUKS1 compatible."), i); return -EINVAL; } diff --git a/tests/api-test-2.c b/tests/api-test-2.c index d380505f..7fdc4c68 100644 --- a/tests/api-test-2.c +++ b/tests/api-test-2.c @@ -1852,16 +1852,21 @@ static void LuksConvert(void) // exercice LUKSv2 conversion with single pbkdf2 keyslot being active OK_(crypt_init(&cd, DEVICE_1)); + OK_(crypt_set_pbkdf_type(cd, &pbkdf2)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, 32, NULL)); offset = crypt_get_data_offset(cd); - OK_(crypt_set_pbkdf_type(cd, &pbkdf2)); EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 0); + OK_(crypt_set_pbkdf_type(cd, &argon)); + EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 1); + FAIL_(crypt_convert(cd, CRYPT_LUKS1, NULL), "Different hash for digest and keyslot."); + OK_(crypt_keyslot_destroy(cd, 1)); OK_(crypt_convert(cd, CRYPT_LUKS1, NULL)); EQ_(crypt_get_data_offset(cd), offset); crypt_free(cd); OK_(crypt_init(&cd, DEVICE_1)); OK_(crypt_load(cd, CRYPT_LUKS, NULL)); EQ_(crypt_get_data_offset(cd), offset); + EQ_(crypt_activate_by_passphrase(cd, NULL, 0, PASSPHRASE, strlen(PASSPHRASE), 0), 0); crypt_free(cd); // do not allow conversion on keyslot No > 7 @@ -3398,7 +3403,7 @@ int main(int argc, char *argv[]) if (_setup()) goto out; - crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE); + crypt_set_debug_level(_debug ? CRYPT_DEBUG_JSON : CRYPT_DEBUG_NONE); RUN_(AddDeviceLuks2, "Format and use LUKS2 device"); RUN_(Luks2HeaderLoad, "LUKS2 header load"); diff --git a/tests/compat-test2 b/tests/compat-test2 index 8bb10c9f..31bf9be3 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -683,6 +683,14 @@ $CRYPTSETUP -q convert --type luks2 $LOOPDEV || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "5: luks2" || fail $CRYPTSETUP -q convert --type luks1 $LOOPDEV || fail +# hash test +$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEY5 -S 0 --hash sha1 || fail +$CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 --hash sha256 || fail +$CRYPTSETUP -q convert --type luks1 $LOOPDEV >/dev/null 2>&1 && fail +$CRYPTSETUP -q luksKillSlot $LOOPDEV 1 || fail +$CRYPTSETUP -q convert --type luks1 $LOOPDEV || fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 0: ENABLED" || fail +$CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 0 -d $KEY5 || fail if dm_crypt_keyring_flawed; then prepare "[32a] LUKS2 keyring dm-crypt bug" wipe