Package: libcryptsetup12 Version: 2:2.1.0-7 Severity: important Tags: upstream
(Cloning upstream issue #466 so we can track it for Buster, Bullseye and sid.) Even when all (bound) key slots were removed from a LUKS header, the header is still salvageable given a copy of the master key. The crypt_keyslot_add_by_volume_key() API call works for LUKSv1 headers without keyslot, but fails for LUKSv2: $ dd if=/dev/zero of=./disk.img bs=1M count=64 $ cryptsetup luksFormat --pbkdf-force-iterations 1000 \ --type luks1 -q ./disk.img <<<test $ ./test ./disk.img "test" "test2" $ cryptsetup luksOpen --test-passphrase --verbose ./disk.img <<<test2 Key slot 0 unlocked. Command successful. $ cryptsetup luksFormat --pbkdf-force-iterations 4 --pbkdf-memory 32 \ --type luks2 -q ./disk.img <<<test $ ./test ./disk.img "test" "test2" Failed to initialise default LUKS2 keyslot parameters. test: Error: crypt_keyslot_add_by_volume_key As long as the volume key is known it's always possible to map the device as a plain crypt target, however the risk of data loss is real for applications like the above `test` that call crypt_volume_key_get(), crypt_keyslot_destroy(), and crypt_keyslot_add_by_volume_key() in that order, as they might leave the header in an unusable state (without bound keyslots). Hence the “Severity: important”. (These applications should use crypt_keyslot_change_by_passphrase() instead, though.) -- Guilhem.
#include <stdlib.h> #include <string.h> #include <err.h> #include "libcryptsetup.h" int main(int argc, char *argv[]) { struct crypt_device *cd = NULL; if (crypt_init(&cd, argv[1])) errx(EXIT_FAILURE, "Error: crypt_init"); if (crypt_load(cd, NULL, NULL)) errx(EXIT_FAILURE, "Error: crypt_load"); size_t vk_size = crypt_get_volume_key_size(cd); char *volume_key = malloc(vk_size); int keyslot = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, volume_key, &vk_size, argv[2], strlen(argv[2])); if (keyslot < 0) errx(EXIT_FAILURE, "Error: crypt_volume_key_get"); if (crypt_keyslot_destroy(cd, keyslot)) errx(EXIT_FAILURE, "Error: crypt_keyslot_destroy"); if (crypt_keyslot_add_by_volume_key(cd, keyslot, volume_key, vk_size, argv[3], strlen(argv[3]))) errx(EXIT_FAILURE, "Error: crypt_keyslot_add_by_volume_key"); return EXIT_SUCCESS; }
signature.asc
Description: PGP signature