diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index 69349a62..377cc78d 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -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, diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 5b558e8e..180c46d7 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -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; } diff --git a/tests/compat-test b/tests/compat-test index ea8d7f3a..e8d6ee9e 100755 --- a/tests/compat-test +++ b/tests/compat-test @@ -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