Fix LUKS1 repair to repair wrong ECB mode.

1) Crypsetup repair should try to call crypt_repair() even
if crypt_load is ok - it has no validate system unlike LUKS2
and some errors cannot be hard load errors.

2) Move ECB fix to repair code, do not try magic on load that
no longer works.

And do not use ECB :)

Fixes: #664
This commit is contained in:
Milan Broz
2021-08-25 09:22:46 +02:00
parent 46b70d7317
commit 0066f9dd83
3 changed files with 27 additions and 8 deletions

View File

@@ -385,6 +385,17 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
return -EINVAL;
}
/*
* ECB mode does not use IV but legacy dmcrypt silently allows it.
* Today device cannot be activated anyway, so we need to fix it here.
*/
if (!strncmp(phdr->cipherMode, "ecb-", 4)) {
log_err(ctx, _("Cipher mode repaired (%s -> %s)."), phdr->cipherMode, "ecb");
memset(phdr->cipherMode, 0, LUKS_CIPHERMODE_L);
strcpy(phdr->cipherMode, "ecb");
need_write = 1;
}
r = LUKS_check_cipher(ctx, phdr->keyBytes, phdr->cipherName, phdr->cipherMode);
if (r < 0)
return -EINVAL;
@@ -510,6 +521,11 @@ static int _check_and_convert_hdr(const char *device,
hdr->uuid[UUID_STRING_L - 1] = '\0';
if (repair) {
if (!strncmp(hdr->cipherMode, "ecb-", 4)) {
log_err(ctx, _("LUKS cipher mode %s is invalid."), hdr->cipherMode);
r = -EINVAL;
}
if (r == -EINVAL)
r = _keyslot_repair(hdr, ctx);
else
@@ -531,13 +547,6 @@ static void LUKS_fix_header_compatible(struct luks_phdr *header)
/* Old cryptsetup expects "sha1", gcrypt allows case insensitive names,
* so always convert hash to lower case in header */
_to_lower(header->hashSpec, LUKS_HASHSPEC_L);
/* ECB mode does not use IV but dmcrypt silently allows it.
* Drop any IV here if ECB is used (that is not secure anyway).*/
if (!strncmp(header->cipherMode, "ecb-", 4)) {
memset(header->cipherMode, 0, LUKS_CIPHERMODE_L);
strcpy(header->cipherMode, "ecb");
}
}
int LUKS_read_phdr_backup(const char *backup_file,

View File

@@ -1235,7 +1235,11 @@ static int action_luksRepair(void)
crypt_set_log_callback(cd, quiet_log, &log_parms);
r = crypt_load(cd, luksType(device_type), NULL);
crypt_set_log_callback(cd, tool_log, &log_parms);
if (r == 0) {
if (r == 0 && isLUKS2(crypt_get_type(cd))) {
/*
* LUKS2 triggers autorepair in crypt_load() above
* LUKS1 need to call crypt_repair() even if crypt_load() is ok
*/
log_verbose(_("No known problems detected for LUKS header."));
goto out;
}

View File

@@ -790,6 +790,12 @@ $CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME >/dev/null 2>&1 && fail
$CRYPTSETUP -q repair $LOOPDEV >/dev/null 2>&1 || fail
$CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME || fail
$CRYPTSETUP luksClose $DEV_NAME || fail
# fix ecb-plain
$CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV $KEY1 --hash sha256 -c aes-ecb || fail
echo -n "ecb-xxx" | dd of=$LOOPDEV bs=1 seek=40 >/dev/null 2>&1
$CRYPTSETUP -q repair $LOOPDEV >/dev/null 2>&1 || fail
$CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME || fail
$CRYPTSETUP luksClose $DEV_NAME || fail
prepare "[30] LUKS erase" wipe
$CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV $KEY5 --key-slot 5 || fail