All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: The development of GNU GRUB <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>,
	GNUtoo@cyberdimension.org
Subject: Re: [PATCH v2 1/3] cryptodisk: make the password getter and additional argument to recover_key
Date: Sun, 15 Nov 2020 12:07:01 +0100	[thread overview]
Message-ID: <X7EL1XC9aHkv9RB1@ncase> (raw)
In-Reply-To: <20201113222510.16958-2-jejb@linux.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 8246 bytes --]

On Fri, Nov 13, 2020 at 02:25:08PM -0800, James Bottomley wrote:
> For AMD SEV environments, the grub boot password has to be retrieved
> from a given memory location rather than prompted for.  This means
> that the standard password getter needs to be replaced with one that
> gets the passphrase from the SEV area and uses that instead.  Adding
> the password getter as a passed in argument to recover_key() makes
> this possible.
> 
> Signed-off-by: James Bottomley <jejb@linux.ibm.com>

I actually like this approach of having a callback to retrieve
passwords. Note though that this conflicts with the in-flight support
for detached headers and key files [1]. It's been a while since the last
revision has been posted, but this can mostly be attributed to the fact
that GRUB has been in a code freeze for some months in order to get
v2.06 out of the door.

In hindsight I'd have preferred your approach to the one in the
mentioned patch series. I'm not quite sure about a proper way forward
though -- depending on which series lands first, the other one'll have
to adjust code to make both play nicely with each other. Anyway, I'm
adding Denis to Cc.

Patrick

[1]: https://lists.gnu.org/archive/html/grub-devel/2020-08/msg00028.html

> ---
> 
> v2: add conditional prompting to geli.c
> ---
>  grub-core/disk/cryptodisk.c |  2 +-
>  grub-core/disk/geli.c       | 12 +++++++-----
>  grub-core/disk/luks.c       | 12 +++++++-----
>  grub-core/disk/luks2.c      | 12 +++++++-----
>  include/grub/cryptodisk.h   |  6 +++++-
>  5 files changed, 27 insertions(+), 17 deletions(-)
> 
> diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
> index a3d672f68..682f5a55d 100644
> --- a/grub-core/disk/cryptodisk.c
> +++ b/grub-core/disk/cryptodisk.c
> @@ -997,7 +997,7 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
>      if (!dev)
>        continue;
>      
> -    err = cr->recover_key (source, dev);
> +    err = cr->recover_key (source, dev, grub_password_get);
>      if (err)
>      {
>        cryptodisk_close (dev);
> diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
> index e9d23299a..3fece3f4a 100644
> --- a/grub-core/disk/geli.c
> +++ b/grub-core/disk/geli.c
> @@ -398,7 +398,8 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
>  }
>  
>  static grub_err_t
> -recover_key (grub_disk_t source, grub_cryptodisk_t dev)
> +recover_key (grub_disk_t source, grub_cryptodisk_t dev,
> +	     grub_passwd_cb *password_get)
>  {
>    grub_size_t keysize;
>    grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN];
> @@ -438,11 +439,12 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
>    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);
> +  if (password_get == grub_password_get)
> +    grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
> +		  source->partition ? "," : "", tmp ? : "",
> +		  dev->uuid);

Ideally we'd be moving this print into `grub_password_get`, but it's not
that easy. First, it gets called by others, so an unconditional print
would change output for those. Second, the interface would get a bit
weird if we just pass the message to any `grub_passwd_cb`.

One thing that does sound generic enough though would be to pass
something like a "subject" to the callback, where subject is the thing
which we want to retrieve the secret for. If it's set, the callback will
print above message, otherwise it'll stay silent. This'd also allow
other callbacks to print nice messages if they require user input.
Furthermore, it would nicely deduplicate those messages across all
cryptodisk backends.

>    grub_free (tmp);
> -  if (!grub_password_get (passphrase, MAX_PASSPHRASE))
> +  if (!password_get (passphrase, MAX_PASSPHRASE))
>      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
>  
>    /* Calculate the PBKDF2 of the user supplied passphrase.  */
> diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
> index 59702067a..165f4a6bd 100644
> --- a/grub-core/disk/luks.c
> +++ b/grub-core/disk/luks.c
> @@ -152,7 +152,8 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
>  
>  static grub_err_t
>  luks_recover_key (grub_disk_t source,
> -		  grub_cryptodisk_t dev)
> +		  grub_cryptodisk_t dev,
> +		  grub_passwd_cb *password_get)
>  {
>    struct grub_luks_phdr header;
>    grub_size_t keysize;
> @@ -187,11 +188,12 @@ luks_recover_key (grub_disk_t source,
>    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);
> +  if (password_get == grub_password_get)
> +	  grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
> +			source->partition ? "," : "", tmp ? : "",
> +			dev->uuid);
>    grub_free (tmp);
> -  if (!grub_password_get (passphrase, MAX_PASSPHRASE))
> +  if (!password_get (passphrase, MAX_PASSPHRASE))
>      {
>        grub_free (split_key);
>        return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
> diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> index 31d7166fc..984182aa9 100644
> --- a/grub-core/disk/luks2.c
> +++ b/grub-core/disk/luks2.c
> @@ -531,7 +531,8 @@ luks2_decrypt_key (grub_uint8_t *out_key,
>  
>  static grub_err_t
>  luks2_recover_key (grub_disk_t disk,
> -		   grub_cryptodisk_t crypt)
> +		   grub_cryptodisk_t crypt,
> +		   grub_passwd_cb *password_get)
>  {
>    grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
>    char passphrase[MAX_PASSPHRASE], cipher[32];
> @@ -573,10 +574,11 @@ luks2_recover_key (grub_disk_t disk,
>    /* Get the passphrase from the user. */
>    if (disk->partition)
>      part = grub_partition_get_name (disk->partition);
> -  grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), disk->name,
> -		disk->partition ? "," : "", part ? : "",
> -		crypt->uuid);
> -  if (!grub_password_get (passphrase, MAX_PASSPHRASE))
> +  if (password_get == grub_password_get)
> +    grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), disk->name,
> +		  disk->partition ? "," : "", part ? : "",
> +		  crypt->uuid);
> +  if (!password_get (passphrase, MAX_PASSPHRASE))
>      {
>        ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
>        goto err;
> diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
> index e1b21e785..45dae5483 100644
> --- a/include/grub/cryptodisk.h
> +++ b/include/grub/cryptodisk.h
> @@ -101,6 +101,9 @@ struct grub_cryptodisk
>  };
>  typedef struct grub_cryptodisk *grub_cryptodisk_t;
>  
> +/* must match prototype for grub_password_get */
> +typedef int (grub_passwd_cb)(char buf[], unsigned buf_size);
> +

Considering we have the keyfiles patch series in flight, we might want
to try make this function work for both. While `grub_password_get`
wouldn't require any additional input, the keyfile callback would need
to know where the file is located. So we might want to add an optional
payload here which is specific to the function.

Also, I'd maybe rename this to something like `grub_credentials_cb` or
`grub_secret_cb` to make it generic.

Patrick

>  struct grub_cryptodisk_dev
>  {
>    struct grub_cryptodisk_dev *next;
> @@ -108,7 +111,8 @@ struct grub_cryptodisk_dev
>  
>    grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid,
>  			     int boot_only);
> -  grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev);
> +  grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev,
> +			     grub_passwd_cb *get_password);
>  };
>  typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t;
>  
> -- 
> 2.26.2
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  parent reply	other threads:[~2020-11-15 11:07 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 [this message]
2020-11-13 22:25 ` [PATCH v2 2/3] cryptodisk: add OS provided secret support James Bottomley
2020-11-14  1:52   ` 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=X7EL1XC9aHkv9RB1@ncase \
    --to=ps@pks.im \
    --cc=Dov.Murik1@il.ibm.com \
    --cc=GNUtoo@cyberdimension.org \
    --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=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.