grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH RFC 1/2] cryptodisk: add OS provided secret support


From: Hyman Huang
Subject: [PATCH RFC 1/2] cryptodisk: add OS provided secret support
Date: Tue, 12 Mar 2024 11:03:18 +0800

Make use of the new OS provided secrets API so that if the new '-s'
option is passed in we try to extract the secret from the API rather
than prompting for it.

The primary consumer of this is AMD SEV, which has been programmed to
provide an injectable secret to the encrypted virtual machine.  OVMF
provides the secret area and passes it into the EFI Configuration
Tables.  The grub EFI layer pulls the secret out and primes the
secrets API with it.  The upshot of all of this is that a SEV
protected VM can do an encrypted boot with a protected boot secret.

Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
 grub-core/disk/cryptodisk.c | 49 ++++++++++++++++++++++++++++++++++---
 include/grub/cryptodisk.h   | 14 +++++++++++
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index 2246af51b..f1541d268 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -44,7 +44,8 @@ enum
     OPTION_KEYFILE,
     OPTION_KEYFILE_OFFSET,
     OPTION_KEYFILE_SIZE,
-    OPTION_HEADER
+    OPTION_HEADER,
+    OPTION_SECRET
   };
 
 static const struct grub_arg_option options[] =
@@ -58,6 +59,7 @@ static const struct grub_arg_option options[] =
     {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT},
     {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, 
ARG_TYPE_INT},
     {"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING},
+    {"secret", 's', 0, N_("Get secret passphrase from named module and 
optional identifier"), 0, 0},
     {0, 0, 0, 0, 0, 0}
   };
 
@@ -78,6 +80,8 @@ static inline int GF_PER_SECTOR (const struct grub_cryptodisk 
*dev)
 static grub_cryptodisk_t cryptodisk_list = NULL;
 static grub_uint8_t last_cryptodisk_id = 0;
 
+static struct grub_secret_entry *secret_providers;
+
 static void
 gf_mul_x (grub_uint8_t *g)
 {
@@ -1259,13 +1263,25 @@ grub_cryptodisk_scan_device (const char *name,
   return ret;
 }
 
+void
+grub_cryptodisk_add_secret_provider (struct grub_secret_entry *e)
+{
+  grub_list_push(GRUB_AS_LIST_P (&secret_providers), GRUB_AS_LIST (e));
+}
+
+void
+grub_cryptodisk_remove_secret_provider  (struct grub_secret_entry *e)
+{
+  grub_list_remove (GRUB_AS_LIST (e));
+}
+
 static grub_err_t
 grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
 {
   struct grub_arg_list *state = ctxt->state;
   struct grub_cryptomount_args cargs = {0};
 
-  if (argc < 1 && !state[OPTION_ALL].set && !state[OPTION_BOOT].set)
+  if (argc < 1 && !state[OPTION_ALL].set && !state[OPTION_BOOT].set && 
!state[OPTION_SECRET].set)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
 
   if (grub_cryptodisk_list == NULL)
@@ -1400,6 +1416,33 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int 
argc, char **args)
       grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
       return GRUB_ERR_NONE;
     }
+  else if (state[OPTION_SECRET].set) /* OS provided secret */
+    {
+      char *os_passwd;
+      struct grub_secret_entry *se;
+      grub_err_t rc;
+
+      if (argc < 1)
+        return grub_error (GRUB_ERR_BAD_ARGUMENT, "secret module must be 
specified");
+#ifndef GRUB_UTIL
+      grub_dl_load (args[0]);
+#endif
+      se = grub_named_list_find (GRUB_AS_NAMED_LIST (secret_providers), 
args[0]);
+      if (se == NULL)
+        return grub_error (GRUB_ERR_INVALID_COMMAND, "No secret provider is 
found");
+
+      rc = se->get (args[1], &os_passwd);
+      if (rc)
+        return grub_errno;
+
+      cargs.search_uuid = NULL;
+      cargs.key_data = (grub_uint8_t *) os_passwd;
+      cargs.key_len = grub_strlen (os_passwd);
+
+      grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
+      se->put (args[1], &os_passwd);
+      return grub_errno;
+    }
   else
     {
       grub_disk_t disk;
@@ -1590,7 +1633,7 @@ GRUB_MOD_INIT (cryptodisk)
   cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
                              N_("[ [-p password] | [-k keyfile"
                                 " [-O keyoffset] [-S keysize] ] ] [-H file]"
-                                " <SOURCE|-u UUID|-a|-b>"),
+                                " <SOURCE|-u UUID|-a|-b|-s MOD [ID]>"),
                              N_("Mount a crypto device."), options);
   grub_procfs_register ("luks_script", &luks_script);
 }
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
index d94df68b6..6fe9d4bcd 100644
--- a/include/grub/cryptodisk.h
+++ b/include/grub/cryptodisk.h
@@ -187,4 +187,18 @@ grub_util_get_geli_uuid (const char *dev);
 grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid);
 grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk);
 
+struct grub_secret_entry {
+  /* as named list */
+  struct grub_secret_entry *next;
+  struct grub_secret_entry **prev;
+  const char *name;
+
+  /* additional entries */
+  grub_err_t (*get)(const char *arg, char **secret);
+  void (*put)(const char *arg, char **secret);
+};
+
+void grub_cryptodisk_add_secret_provider (struct grub_secret_entry *e);
+void grub_cryptodisk_remove_secret_provider (struct grub_secret_entry *e);
+
 #endif
-- 
2.39.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]