Grub Development Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: James Bottomley <jejb@linux.ibm.com>
To: grub-devel@gnu.org
Cc: dovmurik@linux.vnet.ibm.com, Dov.Murik1@il.ibm.com,
	ashish.kalra@amd.com,  brijesh.singh@amd.com, tobin@ibm.com,
	david.kaplan@amd.com, jon.grimm@amd.com, thomas.lendacky@amd.com,
	jejb@linux.ibm.com, frankeh@us.ibm.com,
	"Dr . David Alan Gilbert" <dgilbert@redhat.com>
Subject: [PATCH v2 2/3] cryptodisk: add OS provided secret support
Date: Fri, 13 Nov 2020 14:25:09 -0800	[thread overview]
Message-ID: <20201113222510.16958-3-jejb@linux.ibm.com> (raw)
In-Reply-To: <20201113222510.16958-1-jejb@linux.ibm.com>

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: James Bottomley <jejb@linux.ibm.com>

---

v2: add callback for after secret use
---
 grub-core/disk/cryptodisk.c | 61 ++++++++++++++++++++++++++++++++++---
 include/grub/cryptodisk.h   |  5 +++
 2 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index 682f5a55d..508b25450 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
     /* TRANSLATORS: It's still restricted to cryptodisks only.  */
     {"all", 'a', 0, N_("Mount all."), 0, 0},
     {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0},
+    {"secret", 's', 0, N_("Get OS provisioned secret and mount all volumes encrypted with that secret"), 0, 0},
     {0, 0, 0, 0, 0, 0}
   };
 
@@ -967,6 +968,12 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk)
 
 static int check_boot, have_it;
 static char *search_uuid;
+static char *os_passwd;
+
+/* variable to hold the passed in secret area. */
+static char *os_secret_area;
+static grub_secret_cb *os_secret_cb;
+static void *os_secret_arg;
 
 static void
 cryptodisk_close (grub_cryptodisk_t dev)
@@ -977,6 +984,17 @@ cryptodisk_close (grub_cryptodisk_t dev)
   grub_free (dev);
 }
 
+static int
+os_password_get(char buf[], unsigned len)
+{
+  /* os_passwd should be null terminated, so just copy everything */
+  grub_strncpy(buf, os_passwd, len);
+  /* and add a terminator just in case */
+  buf[len - 1] = 0;
+
+  return 1;
+}
+
 static grub_err_t
 grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
 {
@@ -996,8 +1014,17 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
       return grub_errno;
     if (!dev)
       continue;
-    
-    err = cr->recover_key (source, dev, grub_password_get);
+
+    if (os_passwd)
+      {
+	err = cr->recover_key (source, dev, os_password_get);
+	if (err)
+	  /* if the key doesn't work ignore the access denied error */
+	  grub_error_pop();
+      }
+    else
+      err = cr->recover_key (source, dev, grub_password_get);
+
     if (err)
     {
       cryptodisk_close (dev);
@@ -1013,6 +1040,16 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
   return GRUB_ERR_NONE;
 }
 
+grub_err_t
+grub_cryptodisk_set_secret (char *secret, grub_secret_cb *cb, void *arg)
+{
+  os_secret_area = secret;
+  os_secret_cb = cb;
+  os_secret_arg = arg;
+
+  return GRUB_ERR_NONE;
+}
+
 #ifdef GRUB_UTIL
 #include <grub/util/misc.h>
 grub_err_t
@@ -1089,7 +1126,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
 {
   struct grub_arg_list *state = ctxt->state;
 
-  if (argc < 1 && !state[1].set && !state[2].set)
+  if (argc < 1 && !state[1].set && !state[2].set && !state[3].set)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
 
   have_it = 0;
@@ -1107,6 +1144,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
 
       check_boot = state[2].set;
       search_uuid = args[0];
+      os_passwd = NULL;
       grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
       search_uuid = NULL;
 
@@ -1117,11 +1155,25 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
   else if (state[1].set || (argc == 0 && state[2].set))
     {
       search_uuid = NULL;
+      os_passwd = NULL;
       check_boot = state[2].set;
       grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
       search_uuid = NULL;
       return GRUB_ERR_NONE;
     }
+  else if (state[3].set)
+    {
+      /* do we have a secret? */
+      if (os_secret_area == NULL)
+	return grub_error (GRUB_ERR_INVALID_COMMAND, "No OS secret is provisioned");
+
+      os_passwd = os_secret_area;
+      search_uuid = NULL;
+      grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
+      os_passwd = NULL;
+
+      return os_secret_cb (have_it, os_secret_arg);
+    }
   else
     {
       grub_err_t err;
@@ -1132,6 +1184,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
       grub_size_t len;
 
       search_uuid = NULL;
+      os_passwd = NULL;
       check_boot = state[2].set;
       diskname = args[0];
       len = grub_strlen (diskname);
@@ -1299,7 +1352,7 @@ GRUB_MOD_INIT (cryptodisk)
 {
   grub_disk_dev_register (&grub_cryptodisk_dev);
   cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
-			      N_("SOURCE|-u UUID|-a|-b"),
+			      N_("SOURCE|-u UUID|-a|-b|-s"),
 			      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 45dae5483..8236b5933 100644
--- a/include/grub/cryptodisk.h
+++ b/include/grub/cryptodisk.h
@@ -163,4 +163,9 @@ 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);
 
+typedef grub_err_t (grub_secret_cb)(int have_it, void *arg);
+
+grub_err_t grub_cryptodisk_set_secret(char *secret, grub_secret_cb *cb,
+				      void *arg);
+
 #endif
-- 
2.26.2



  parent reply	other threads:[~2020-11-13 22:28 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-13 22:25 [PATCH v2 0/3] Add ability to use SEV provisioned secrets for disk decryption James Bottomley
2020-11-13 22:25 ` [PATCH v2 1/3] cryptodisk: make the password getter and additional argument to recover_key James Bottomley
2020-11-14  1:50   ` Glenn Washburn
2020-11-15 11:07   ` Patrick Steinhardt
2020-11-13 22:25 ` James Bottomley [this message]
2020-11-14  1:52   ` [PATCH v2 2/3] cryptodisk: add OS provided secret support Glenn Washburn
2020-11-13 22:25 ` [PATCH v2 3/3] efi: Add API for retrieving the AMD SEV injected secret for cryptodisk James Bottomley
2020-11-14  1:50 ` [PATCH v2 0/3] Add ability to use SEV provisioned secrets for disk decryption Glenn Washburn
2020-11-14  2:48   ` James Bottomley
2020-11-14  4:23     ` Glenn Washburn
2020-11-15 11:11   ` Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201113222510.16958-3-jejb@linux.ibm.com \
    --to=jejb@linux.ibm.com \
    --cc=Dov.Murik1@il.ibm.com \
    --cc=ashish.kalra@amd.com \
    --cc=brijesh.singh@amd.com \
    --cc=david.kaplan@amd.com \
    --cc=dgilbert@redhat.com \
    --cc=dovmurik@linux.vnet.ibm.com \
    --cc=frankeh@us.ibm.com \
    --cc=grub-devel@gnu.org \
    --cc=jon.grimm@amd.com \
    --cc=thomas.lendacky@amd.com \
    --cc=tobin@ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox