diff options
Diffstat (limited to '0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch')
-rw-r--r-- | 0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch | 317 |
1 files changed, 0 insertions, 317 deletions
diff --git a/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch b/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch deleted file mode 100644 index 07239e95f43d..000000000000 --- a/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch +++ /dev/null @@ -1,317 +0,0 @@ -From f42b774020839b1e07c5fa0ad7be4735d35cc705 Mon Sep 17 00:00:00 2001 -From: Maxim Fomin <maxim@fomin.one> -Date: Fri, 8 Jan 2021 20:00:31 +0000 -Subject: [PATCH] Support for multiple LUKS passphrase attempts - ---- - grub-core/disk/luks.c | 273 ++++++++++++++++++++++-------------------- - 1 file changed, 141 insertions(+), 132 deletions(-) - -diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c -index eea85338d..3f98df287 100644 ---- a/grub-core/disk/luks.c -+++ b/grub-core/disk/luks.c -@@ -34,6 +34,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); - - #define LUKS_KEY_ENABLED 0x00AC71F3 - -+#define LUKS_PASSPHRASE_ATTEMPTS 3 -+ - /* On disk LUKS header */ - struct grub_luks_phdr - { -@@ -182,6 +184,7 @@ luks_recover_key (grub_disk_t source, - grub_size_t max_stripes = 1; - char *tmp; - grub_uint32_t sector; -+ unsigned int attempts = LUKS_PASSPHRASE_ATTEMPTS; - - err = GRUB_ERR_NONE; - -@@ -211,145 +214,151 @@ luks_recover_key (grub_disk_t source, - if (!split_key) - return grub_errno; - -- if (keyfile_bytes) -- { -- /* Use bytestring from key file as passphrase */ -- passphrase = keyfile_bytes; -- passphrase_length = keyfile_bytes_size; -- } -- else -+ while (attempts) - { -- /* Get the passphrase from the user. */ -- tmp = NULL; -- if (source->partition) -- tmp = grub_partition_get_name (source->partition); -- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, -- source->partition ? "," : "", tmp ? : "", dev->uuid); -- grub_free (tmp); -- if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE)) -+ if (keyfile_bytes) - { -- grub_free (split_key); -- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); -+ /* Use bytestring from key file as passphrase */ -+ passphrase = keyfile_bytes; -+ passphrase_length = keyfile_bytes_size; -+ keyfile_bytes = NULL; /* use it only once */ -+ } -+ else -+ { -+ /* Get the passphrase from the user. */ -+ tmp = NULL; -+ if (source->partition) -+ tmp = grub_partition_get_name (source->partition); -+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, -+ source->partition ? "," : "", tmp ? : "", dev->uuid); -+ grub_free (tmp); -+ if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE)) -+ { -+ grub_free (split_key); -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); -+ } -+ -+ passphrase = (grub_uint8_t *)interactive_passphrase; -+ passphrase_length = grub_strlen (interactive_passphrase); - } - -- passphrase = (grub_uint8_t *)interactive_passphrase; -- passphrase_length = grub_strlen (interactive_passphrase); -+ /* Try to recover master key from each active keyslot. */ -+ for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) -+ { -+ gcry_err_code_t gcry_err; -+ grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; -+ grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN]; -+ -+ /* Check if keyslot is enabled. */ -+ if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED) -+ continue; -+ -+ grub_dprintf ("luks", "Trying keyslot %d\n", i); -+ -+ /* Calculate the PBKDF2 of the user supplied passphrase. */ -+ gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, -+ passphrase_length, -+ header.keyblock[i].passwordSalt, -+ sizeof (header.keyblock[i].passwordSalt), -+ grub_be_to_cpu32 (header.keyblock[i]. -+ passwordIterations), -+ digest, keysize); -+ -+ if (gcry_err) -+ { -+ grub_free (split_key); -+ return grub_crypto_gcry_error (gcry_err); -+ } -+ -+ grub_dprintf ("luks", "PBKDF2 done\n"); -+ -+ gcry_err = grub_cryptodisk_setkey (dev, digest, keysize); -+ if (gcry_err) -+ { -+ grub_free (split_key); -+ return grub_crypto_gcry_error (gcry_err); -+ } -+ -+ sector = grub_be_to_cpu32 (header.keyblock[i].keyMaterialOffset); -+ length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes)); -+ -+ /* Read and decrypt the key material from the disk. */ -+ if (hdr) -+ { -+ grub_file_seek (hdr, sector * 512); -+ if (grub_file_read (hdr, split_key, length) != (grub_ssize_t)length) -+ err = GRUB_ERR_READ_ERROR; -+ } -+ else -+ err = grub_disk_read (source, sector, 0, length, split_key); -+ if (err) -+ { -+ grub_free (split_key); -+ return err; -+ } -+ -+ gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0, -+ GRUB_LUKS1_LOG_SECTOR_SIZE); -+ if (gcry_err) -+ { -+ grub_free (split_key); -+ return grub_crypto_gcry_error (gcry_err); -+ } -+ -+ /* Merge the decrypted key material to get the candidate master key. */ -+ gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize, -+ grub_be_to_cpu32 (header.keyblock[i].stripes)); -+ if (gcry_err) -+ { -+ grub_free (split_key); -+ return grub_crypto_gcry_error (gcry_err); -+ } -+ -+ grub_dprintf ("luks", "candidate key recovered\n"); -+ -+ /* Calculate the PBKDF2 of the candidate master key. */ -+ gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key, -+ grub_be_to_cpu32 (header.keyBytes), -+ header.mkDigestSalt, -+ sizeof (header.mkDigestSalt), -+ grub_be_to_cpu32 -+ (header.mkDigestIterations), -+ candidate_digest, -+ sizeof (candidate_digest)); -+ if (gcry_err) -+ { -+ grub_free (split_key); -+ return grub_crypto_gcry_error (gcry_err); -+ } -+ -+ /* Compare the calculated PBKDF2 to the digest stored -+ in the header to see if it's correct. */ -+ if (grub_memcmp (candidate_digest, header.mkDigest, -+ sizeof (header.mkDigest)) != 0) -+ { -+ grub_dprintf ("luks", "bad digest\n"); -+ continue; -+ } -+ -+ /* TRANSLATORS: It's a cryptographic key slot: one element of an array -+ where each element is either empty or holds a key. */ -+ grub_printf_ (N_("Slot %d opened\n"), i); -+ -+ /* Set the master key. */ -+ gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); -+ if (gcry_err) -+ { -+ grub_free (split_key); -+ return grub_crypto_gcry_error (gcry_err); -+ } - -- } -+ grub_free (split_key); - -- /* Try to recover master key from each active keyslot. */ -- for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) -- { -- gcry_err_code_t gcry_err; -- grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; -- grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN]; -- -- /* Check if keyslot is enabled. */ -- if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED) -- continue; -- -- grub_dprintf ("luks", "Trying keyslot %d\n", i); -- -- /* Calculate the PBKDF2 of the user supplied passphrase. */ -- gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, -- passphrase_length, -- header.keyblock[i].passwordSalt, -- sizeof (header.keyblock[i].passwordSalt), -- grub_be_to_cpu32 (header.keyblock[i]. -- passwordIterations), -- digest, keysize); -- -- if (gcry_err) -- { -- grub_free (split_key); -- return grub_crypto_gcry_error (gcry_err); -- } -- -- grub_dprintf ("luks", "PBKDF2 done\n"); -- -- gcry_err = grub_cryptodisk_setkey (dev, digest, keysize); -- if (gcry_err) -- { -- grub_free (split_key); -- return grub_crypto_gcry_error (gcry_err); -- } -- -- sector = grub_be_to_cpu32 (header.keyblock[i].keyMaterialOffset); -- length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes)); -- -- /* Read and decrypt the key material from the disk. */ -- if (hdr) -- { -- grub_file_seek (hdr, sector * 512); -- if (grub_file_read (hdr, split_key, length) != (grub_ssize_t)length) -- err = GRUB_ERR_READ_ERROR; -+ return GRUB_ERR_NONE; - } -- else -- err = grub_disk_read (source, sector, 0, length, split_key); -- if (err) -- { -- grub_free (split_key); -- return err; -- } -- -- gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0, -- GRUB_LUKS1_LOG_SECTOR_SIZE); -- if (gcry_err) -- { -- grub_free (split_key); -- return grub_crypto_gcry_error (gcry_err); -- } -- -- /* Merge the decrypted key material to get the candidate master key. */ -- gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize, -- grub_be_to_cpu32 (header.keyblock[i].stripes)); -- if (gcry_err) -- { -- grub_free (split_key); -- return grub_crypto_gcry_error (gcry_err); -- } -- -- grub_dprintf ("luks", "candidate key recovered\n"); -- -- /* Calculate the PBKDF2 of the candidate master key. */ -- gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key, -- grub_be_to_cpu32 (header.keyBytes), -- header.mkDigestSalt, -- sizeof (header.mkDigestSalt), -- grub_be_to_cpu32 -- (header.mkDigestIterations), -- candidate_digest, -- sizeof (candidate_digest)); -- if (gcry_err) -- { -- grub_free (split_key); -- return grub_crypto_gcry_error (gcry_err); -- } -- -- /* Compare the calculated PBKDF2 to the digest stored -- in the header to see if it's correct. */ -- if (grub_memcmp (candidate_digest, header.mkDigest, -- sizeof (header.mkDigest)) != 0) -- { -- grub_dprintf ("luks", "bad digest\n"); -- continue; -- } -- -- /* TRANSLATORS: It's a cryptographic key slot: one element of an array -- where each element is either empty or holds a key. */ -- grub_printf_ (N_("Slot %d opened\n"), i); -- -- /* Set the master key. */ -- gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); -- if (gcry_err) -- { -- grub_free (split_key); -- return grub_crypto_gcry_error (gcry_err); -- } -- -- grub_free (split_key); -- -- return GRUB_ERR_NONE; -+ grub_printf_ (N_("Failed to decrypt master key.\n")); -+ if (--attempts) grub_printf_ (N_("%u attempt%s remaining.\n"), attempts, -+ (attempts==1) ? "" : "s"); - } - - grub_free (split_key); --- -2.30.0 - |