mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Retain keyslot number in luksChangeKey for LUKS2.
With JSON, we can actually retain the slot number in all cases (except user intentionally set new slot #). This patch changes the crypt_keyslot_change_by_passphrase() API call to retain keyslot number for LUKS2. Fixes: #464
This commit is contained in:
@@ -224,6 +224,11 @@ int LUKS2_keyslot_priority_set(struct crypt_device *cd,
|
||||
crypt_keyslot_priority priority,
|
||||
int commit);
|
||||
|
||||
int LUKS2_keyslot_swap(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
int keyslot2);
|
||||
|
||||
/*
|
||||
* Generic LUKS2 token
|
||||
*/
|
||||
|
||||
@@ -935,3 +935,40 @@ int LUKS2_find_keyslot(struct luks2_hdr *hdr, const char *type)
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* assumes valid header, it does not move references in tokens/digests etc! */
|
||||
int LUKS2_keyslot_swap(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
int keyslot, int keyslot2)
|
||||
{
|
||||
json_object *jobj_keyslots, *jobj_keyslot, *jobj_keyslot2;
|
||||
int r;
|
||||
|
||||
if (!json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots))
|
||||
return -EINVAL;
|
||||
|
||||
jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
|
||||
if (!jobj_keyslot)
|
||||
return -EINVAL;
|
||||
|
||||
jobj_keyslot2 = LUKS2_get_keyslot_jobj(hdr, keyslot2);
|
||||
if (!jobj_keyslot2)
|
||||
return -EINVAL;
|
||||
|
||||
/* This transfer owner of object, no need for json_object_put */
|
||||
json_object_get(jobj_keyslot);
|
||||
json_object_get(jobj_keyslot2);
|
||||
|
||||
json_object_object_del_by_uint(jobj_keyslots, keyslot);
|
||||
r = json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot2);
|
||||
if (r < 0) {
|
||||
log_dbg(cd, "Failed to swap keyslot %d.", keyslot);
|
||||
return r;
|
||||
}
|
||||
|
||||
json_object_object_del_by_uint(jobj_keyslots, keyslot2);
|
||||
r = json_object_object_add_by_uint(jobj_keyslots, keyslot2, jobj_keyslot);
|
||||
if (r < 0)
|
||||
log_dbg(cd, "Failed to swap keyslot2 %d.", keyslot2);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
16
lib/setup.c
16
lib/setup.c
@@ -3415,7 +3415,7 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
|
||||
const char *new_passphrase,
|
||||
size_t new_passphrase_size)
|
||||
{
|
||||
int digest = -1, r;
|
||||
int digest = -1, r, keyslot_new_orig = keyslot_new;
|
||||
struct luks2_keyslot_params params;
|
||||
struct volume_key *vk = NULL;
|
||||
|
||||
@@ -3493,6 +3493,20 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
|
||||
r = LUKS2_keyslot_store(cd, &cd->u.luks2.hdr,
|
||||
keyslot_new, new_passphrase,
|
||||
new_passphrase_size, vk, ¶ms);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
/* Swap old & new so the final keyslot number remains */
|
||||
if (keyslot_new_orig == CRYPT_ANY_SLOT && keyslot_old != keyslot_new) {
|
||||
r = LUKS2_keyslot_swap(cd, &cd->u.luks2.hdr, keyslot_old, keyslot_new);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
/* Swap slot id */
|
||||
r = keyslot_old;
|
||||
keyslot_old = keyslot_new;
|
||||
keyslot_new = r;
|
||||
}
|
||||
} else
|
||||
r = -EINVAL;
|
||||
|
||||
|
||||
@@ -843,7 +843,7 @@ static void AddDeviceLuks2(void)
|
||||
key[1] = ~key[1];
|
||||
FAIL_(crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase)), "key mismatch");
|
||||
key[1] = ~key[1];
|
||||
EQ_(6, crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase)));
|
||||
EQ_(6, crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase2, strlen(passphrase2)));
|
||||
EQ_(CRYPT_SLOT_ACTIVE, crypt_keyslot_status(cd, 6));
|
||||
|
||||
FAIL_(crypt_keyslot_destroy(cd, 8), "invalid keyslot");
|
||||
@@ -853,6 +853,8 @@ static void AddDeviceLuks2(void)
|
||||
EQ_(CRYPT_SLOT_INACTIVE, crypt_keyslot_status(cd, 7));
|
||||
EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 6));
|
||||
|
||||
EQ_(6, crypt_keyslot_change_by_passphrase(cd, 6, CRYPT_ANY_SLOT, passphrase2, strlen(passphrase2), passphrase, strlen(passphrase)));
|
||||
EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 6));
|
||||
EQ_(7, crypt_keyslot_change_by_passphrase(cd, 6, 7, passphrase, strlen(passphrase), passphrase2, strlen(passphrase2)));
|
||||
EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 7));
|
||||
EQ_(7, crypt_activate_by_passphrase(cd, NULL, 7, passphrase2, strlen(passphrase2), 0));
|
||||
|
||||
@@ -543,10 +543,10 @@ $CRYPTSETUP close $DEV_NAME || fail
|
||||
add_scsi_device dev_size_mb=32 sector_size=4096
|
||||
echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $DEV || fail
|
||||
echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail
|
||||
OLD_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/')
|
||||
OLD_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/') #'
|
||||
echo $PWD1 | $CRYPTSETUP resize $DEV_NAME -b 7 2> /dev/null && fail
|
||||
dmsetup info $DEV_NAME | grep -q SUSPENDED && fail
|
||||
NEW_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/')
|
||||
NEW_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/') #'
|
||||
test $OLD_SIZE -eq $NEW_SIZE || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
|
||||
@@ -594,21 +594,15 @@ echo $PWD1 | $CRYPTSETUP luksAddKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 --key-slot
|
||||
$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 0 || fail
|
||||
# passphrase [1] / passphrase [1]
|
||||
echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT --key-slot 1 || fail
|
||||
# keyfile [0] / keyfile [new]
|
||||
# keyfile [0] / keyfile [new] - with LUKS2 it should stay
|
||||
$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY2 $KEY1 || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "0: luks2" && fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "0: luks2" || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2" && fail
|
||||
# passphrase [1] / passphrase [new]
|
||||
echo -e "$PWD2\n$PWD1\n" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT $LOOPDEV || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" && fail
|
||||
# use all slots
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail
|
||||
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail
|
||||
# still allows replace
|
||||
#FIXME
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2" && fail
|
||||
# FIXME: test out of raw area
|
||||
#$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 || fail
|
||||
#$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 2>/dev/null && fail
|
||||
|
||||
|
||||
Reference in New Issue
Block a user