Cryptomount LUKS allow multiple unlock attempts cryptomount_luks_v5
authorTJ <grub-devel@iam.tj>
Thu, 22 Mar 2018 13:52:43 +0000 (13:52 +0000)
committerTJ <grub-devel@iam.tj>
Thu, 22 Mar 2018 13:52:43 +0000 (13:52 +0000)
Wrap luks_recover_key() in a loop to allow multiple attempts at
unlocking. Use a preprocessor-set limit to allow for setting the number
of attempts via a build-time option in the future.

grub-core/disk/luks.c

index 6fbd32e..27da9de 100644 (file)
@@ -319,12 +319,48 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
   return newdev;
 }
 
+#ifndef GRUB_LUKS_KEY_ATTEMPTS
+#define GRUB_LUKS_KEY_ATTEMPTS 3
+#endif
+static grub_err_t
+luks_recover_key_real ( grub_disk_t source, grub_cryptodisk_t dev,
+    grub_file_t hdr, grub_uint8_t *keyfile_bytes,
+    grub_size_t keyfile_bytes_size);
+
 static grub_err_t
 luks_recover_key (grub_disk_t source,
                  grub_cryptodisk_t dev,
                  grub_file_t hdr,
                  grub_uint8_t *keyfile_bytes,
                  grub_size_t keyfile_bytes_size)
+{
+  grub_err_t err;
+  grub_uint8_t *key = keyfile_bytes;
+  unsigned attempts = GRUB_LUKS_KEY_ATTEMPTS - 1;
+
+  do
+    {
+      err = luks_recover_key_real (source, dev, hdr, key, keyfile_bytes_size);
+      if (err == GRUB_ERR_NONE)
+          break;
+
+         key = NULL; /* try keyfile only once */
+      grub_printf (N_("Failed to decrypt master key.\n"));
+      grub_printf (N_("%u attempt%s remaining.\n"), attempts,
+                   (attempts == 1) "" : "s");
+    }
+  while (attempts--);
+  grub_free (keyfile_bytes);
+
+  return err;
+}
+
+static grub_err_t
+luks_recover_key_real ( grub_disk_t source,
+                 grub_cryptodisk_t dev,
+                 grub_file_t hdr,
+                 grub_uint8_t *keyfile_bytes,
+                 grub_size_t keyfile_bytes_size)
 {
   struct grub_luks_phdr header;
   grub_size_t keysize;