Harden digest verification when adding new unbound key.

While adding new unbound key there is a check whether the
passed key parameter matches current volume key or not. If it
matches the existing volume key we handle the LUKS2 keyslot
addition as an ordinary LUKS2 keyslot (not unbound).

If the check failed we continued with the operation of adding
LUKS2 unbound keyslot. But we did not check if the error
was not a more general issue for example with in-memory metadata.

Let's contine with the operation only if the return code is
expected -EPERM (not matching digest) or -ENOENT (not matching any
existing unbound key).
This commit is contained in:
Ondrej Kozina
2025-05-19 14:35:31 +02:00
committed by Milan Broz
parent a39a0d00e5
commit bd2f7eb671

View File

@@ -7266,17 +7266,22 @@ static int keyslot_add_by_key(struct crypt_device *cd,
digest = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
if (digest >= 0) /* if key matches volume key digest tear down new vk flag */
flags &= ~CRYPT_VOLUME_KEY_SET;
else {
else if (digest == -EPERM) {
/* if key matches any existing digest, do not create new digest */
if ((flags & CRYPT_VOLUME_KEY_DIGEST_REUSE))
digest = LUKS2_digest_verify_by_any_matching(cd, vk);
/* Anything other than -EPERM or -ENOENT suggests broken metadata. Abort */
if (digest < 0 && digest != -ENOENT && digest != -EPERM)
return digest;
/* no segment flag or new vk flag requires new key digest */
if (flags & (CRYPT_VOLUME_KEY_NO_SEGMENT | CRYPT_VOLUME_KEY_SET)) {
if (digest < 0 || !(flags & CRYPT_VOLUME_KEY_DIGEST_REUSE))
digest = LUKS2_digest_create(cd, "pbkdf2", &cd->u.luks2.hdr, vk);
}
}
} else /* Anything other than -EPERM suggests broken metadata. Abort */
return digest;
r = digest;
if (r < 0) {