From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: James Bottomley <jejb@linux.ibm.com>
Cc: grub-devel@gnu.org, 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, frankeh@us.ibm.com
Subject: Re: [PATCH 2/3] cryptodisk: add OS provided secret support
Date: Fri, 13 Nov 2020 13:23:09 +0000 [thread overview]
Message-ID: <20201113132309.GN3251@work-vm> (raw)
In-Reply-To: <20201113012206.24246-3-jejb@linux.ibm.com>
* James Bottomley (jejb@linux.ibm.com) wrote:
> 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>
> ---
> grub-core/disk/cryptodisk.c | 60 ++++++++++++++++++++++++++++++++++---
> include/grub/cryptodisk.h | 2 ++
> 2 files changed, 58 insertions(+), 4 deletions(-)
>
> diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
> index 682f5a55d..02104aad4 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,10 @@ 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 void
> cryptodisk_close (grub_cryptodisk_t dev)
> @@ -977,6 +982,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 +1012,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 +1038,14 @@ 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)
> +{
> + os_secret_area = secret;
> +
> + return GRUB_ERR_NONE;
> +}
> +
> #ifdef GRUB_UTIL
> #include <grub/util/misc.h>
> grub_err_t
> @@ -1089,7 +1122,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 +1140,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 +1151,28 @@ 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;
> +
> + if (!have_it)
> + return grub_error (GRUB_ERR_ACCESS_DENIED, "SEV password failed to unlock any volumes");
That's the only place you break the generality and admit to it being a
SEV password I think.
Dave
> + return GRUB_ERR_NONE;
> + }
> else
> {
> grub_err_t err;
> @@ -1132,6 +1183,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 +1351,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..55c411754 100644
> --- a/include/grub/cryptodisk.h
> +++ b/include/grub/cryptodisk.h
> @@ -163,4 +163,6 @@ 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);
>
> +grub_err_t grub_cryptodisk_set_secret(char *secret);
> +
> #endif
> --
> 2.26.2
>
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
next prev parent reply other threads:[~2020-11-13 18:18 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-13 1:22 [PATCH 0/3] Add ability to use SEV provisioned secrets for disk decryption James Bottomley
2020-11-13 1:22 ` [PATCH 1/3] cryptodisk: make the password getter and additional argument to recover_key James Bottomley
2020-11-13 6:02 ` Glenn Washburn
2020-11-13 15:44 ` James Bottomley
2020-11-13 1:22 ` [PATCH 2/3] cryptodisk: add OS provided secret support James Bottomley
2020-11-13 13:23 ` Dr. David Alan Gilbert [this message]
2020-11-13 15:49 ` James Bottomley
2020-11-13 1:22 ` [PATCH 3/3] efi: Add API for retrieving the AMD SEV injected secret for cryptodisk James Bottomley
2020-11-13 17:50 ` [PATCH 0/3] Add ability to use SEV provisioned secrets for disk decryption Dr. David Alan Gilbert
2020-11-13 17:58 ` James Bottomley
2020-11-13 18:21 ` Dr. David Alan Gilbert
2020-11-13 19:26 ` James Bottomley
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=20201113132309.GN3251@work-vm \
--to=dgilbert@redhat.com \
--cc=Dov.Murik1@il.ibm.com \
--cc=ashish.kalra@amd.com \
--cc=brijesh.singh@amd.com \
--cc=david.kaplan@amd.com \
--cc=dovmurik@linux.vnet.ibm.com \
--cc=frankeh@us.ibm.com \
--cc=grub-devel@gnu.org \
--cc=jejb@linux.ibm.com \
--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