[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 07/10] tpm2_key_protector: Support NV index handles
From: |
Gary Lin |
Subject: |
Re: [PATCH v2 07/10] tpm2_key_protector: Support NV index handles |
Date: |
Fri, 10 Jan 2025 14:00:16 +0800 |
On Thu, Jan 09, 2025 at 01:03:54PM -0500, Stefan Berger wrote:
>
>
> On 1/8/25 10:58 PM, Gary Lin wrote:
> > Previously, NV index mode only supported persistent handles which are
> > only for TPM objects.
> >
> > On the other hand, the "NV index" handle allows the user-defined data,
> > so it can be an alternative to the key file and support TPM 2.0 Key
> > File format immediately.
> >
> > The following tpm2-tools commands store the given key file, sealed.tpm,
> > in either TPM 2.0 Key File format or the raw format into the NV index
> > handle 0x1000000.
> >
> > # tpm2_nvdefine -C o \
> > -a "ownerread|ownerwrite" \
> > -s $(stat -c %s sealed.tpm) \
> > 0x1000000
> > # tpm2_nvwrite -C o -i sealed.tpm 0x1000000
> >
> > To unseal the key in GRUB, add the 'tpm2_key_protector_init' command to
> > grub.cfg:
> >
> > tpm2_key_protector_init --mode=nv --nvindex=0x1000000
> > cryptomount -u <UUID> --protector tpm2
> >
> > To remove the NV index handle:
> >
> > # tpm2_nvundefine -C o 0x1000000
> >
> > Signed-off-by: Gary Lin <glin@suse.com>
> > ---
> > .../commands/tpm2_key_protector/module.c | 70 ++++++++++++++++---
> > 1 file changed, 60 insertions(+), 10 deletions(-)
> >
> > diff --git a/grub-core/commands/tpm2_key_protector/module.c
> > b/grub-core/commands/tpm2_key_protector/module.c
> > index 8ec143542..56b44012c 100644
> > --- a/grub-core/commands/tpm2_key_protector/module.c
> > +++ b/grub-core/commands/tpm2_key_protector/module.c
> > @@ -1133,10 +1133,9 @@ tpm2_protector_srk_recover (const
> > tpm2_protector_context_t *ctx,
> > }
> > static grub_err_t
> > -tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx,
> > - grub_uint8_t **key, grub_size_t *key_size)
> > +tpm2_protector_unseal_persistent (const tpm2_protector_context_t *ctx,
> > TPM_HANDLE_t sealed_handle,
> > + grub_uint8_t **key, grub_size_t *key_size)
> > {
> > - TPM_HANDLE_t sealed_handle = ctx->nv;
> > tpm2key_policy_t policy_seq = NULL;
> > bool dump_pcr = false;
> > grub_err_t err;
> > @@ -1163,6 +1162,51 @@ tpm2_protector_nv_recover (const
> > tpm2_protector_context_t *ctx,
> > return err;
> > }
> > +static grub_err_t
> > +tpm2_protector_unseal_nvindex (const tpm2_protector_context_t *ctx,
> > TPM_HANDLE_t nvindex,
>
> I doubt you are unsealing an nvindex. You seem to be reading a key from the
> nvindex and then the key will be loaded into the TPM and fail if the PCRs do
> not match, right?
>
> -> should this not rather be 'tpm2_protector_key_from_nvindex'?
>
I was forging the names with tpm2_protector_unseal_ + <source> to
indicate where the key comes from. Anyway, the names you proposed looks
better. I'll change them in v3.
Thanks,
Gary Lin
> > + grub_uint8_t **key, grub_size_t *key_size)
> > +{
> > + TPMS_AUTH_COMMAND_t authCmd = {0};
> > + TPM2B_NV_PUBLIC_t nv_public;
> > + TPM2B_NAME_t nv_name;
> > + grub_uint16_t data_size;
> > + TPM2B_MAX_NV_BUFFER_t data;
> > + TPM_RC_t rc;
> > +
> > + /* Get the data size in the NV index handle */
> > + rc = grub_tpm2_nv_readpublic (nvindex, NULL, &nv_public, &nv_name);
> > + if (rc != TPM_RC_SUCCESS)
> > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to retrieve info
> > from 0x%x (TPM2_NV_ReadPublic: 0x%x)", nvindex, rc);
> > +
> > + data_size = nv_public.nvPublic.dataSize;
> > + if (data_size > TPM_MAX_NV_BUFFER_SIZE)
> > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "insufficient data buffer");
> > +
> > + /* Read the data from the NV index handle */
> > + authCmd.sessionHandle = TPM_RS_PW;
> > + rc = grub_tpm2_nv_read (TPM_RH_OWNER, nvindex, &authCmd, data_size, 0,
> > &data);
> > + if (rc != TPM_RC_SUCCESS)
> > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to read data from
> > 0x%x (TPM2_NV_Read: 0x%x)", nvindex, rc);
> > +
> > + return tpm2_protector_unseal_buffer (ctx, data.buffer, data_size, key,
> > key_size);
>
> tpm2_protector_key_from_buffer () ?
>
> > +}
> > +
> > +static grub_err_t
> > +tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx,
> > + grub_uint8_t **key, grub_size_t *key_size)
> > +{
> > + grub_err_t err;
> > +
> > + if (TPM_HT_IS_PERSISTENT (ctx->nv) == true)
> > + err = tpm2_protector_unseal_persistent (ctx, ctx->nv, key, key_size);
>
> tpm2_protector_load_persistent () ?
>
> > + else if (TPM_HT_IS_NVINDEX (ctx->nv) == true)
> > + err = tpm2_protector_unseal_nvindex (ctx, ctx->nv, key, key_size);
> > + else
> > + err = GRUB_ERR_BAD_ARGUMENT;
> > +
> > + return err;
> > +}
> > +
> > static grub_err_t
> > tpm2_protector_recover (const tpm2_protector_context_t *ctx,
> > grub_uint8_t **key, grub_size_t *key_size)
> > @@ -1215,14 +1259,15 @@ tpm2_protector_check_args (tpm2_protector_context_t
> > *ctx)
> > if (ctx->mode == TPM2_PROTECTOR_MODE_NV &&
> > (ctx->tpm2key != NULL || ctx->keyfile != NULL))
> > - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, a
> > keyfile cannot be specified"));
> > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("a key file cannot be
> > specified when using NV index mode"));
> > - if (ctx->mode == TPM2_PROTECTOR_MODE_NV && ctx->srk != 0)
> > - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, an SRK
> > cannot be specified"));
> > + if (ctx->mode == TPM2_PROTECTOR_MODE_NV && TPM_HT_IS_PERSISTENT
> > (ctx->nv) == true &&
> > + (ctx->srk != 0 || ctx->srk_type.type != TPM_ALG_ERROR))
> > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("an SRK cannot be
> > specified when using NV index mode with a persistent handle"));
> > if (ctx->mode == TPM2_PROTECTOR_MODE_NV &&
> > - ctx->srk_type.type != TPM_ALG_ERROR)
> > - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, an
> > asymmetric key type cannot be specified"));
> > + (TPM_HT_IS_PERSISTENT (ctx->nv) == false && TPM_HT_IS_NVINDEX
> > (ctx->nv) == false))
> > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("an NV index must be
> > either a persistent handle or an NV index handle when using NV index
> > mode"));
> > /* Defaults assignment */
> > if (ctx->bank == TPM_ALG_ERROR)
> > @@ -1234,8 +1279,13 @@ tpm2_protector_check_args (tpm2_protector_context_t
> > *ctx)
> > ctx->pcr_count = 1;
> > }
> > - if (ctx->mode == TPM2_PROTECTOR_MODE_SRK &&
> > - ctx->srk_type.type == TPM_ALG_ERROR)
> > + /*
> > + * Set ECC_NIST_P256 as the default SRK when using SRK mode or NV mode
> > with
> > + * an NV index handle
> > + */
> > + if (ctx->srk_type.type == TPM_ALG_ERROR &&
> > + (ctx->mode == TPM2_PROTECTOR_MODE_SRK ||
> > + (ctx->mode == TPM2_PROTECTOR_MODE_NV && TPM_HT_IS_NVINDEX (ctx->nv)
> > == true)))
> > {
> > ctx->srk_type.type = TPM_ALG_ECC;
> > ctx->srk_type.detail.ecc_curve = TPM_ECC_NIST_P256;
>
- [PATCH v2 00/10] TPM2 key protector follow-up patches, Gary Lin, 2025/01/08
- [PATCH v2 01/10] tpm2_key_protector: dump PCRs on policy fail, Gary Lin, 2025/01/08
- [PATCH v2 02/10] tpm2_key_protector: Add 'tpm2_dump_pcr' command, Gary Lin, 2025/01/08
- [PATCH v2 03/10] docs: Document tpm2_dump_pcr, Gary Lin, 2025/01/08
- [PATCH v2 04/10] tss2: Fix the missing authCommand, Gary Lin, 2025/01/08
- [PATCH v2 05/10] tss2: Add TPM 2.0 NV index commands, Gary Lin, 2025/01/08
- [PATCH v2 06/10] tpm2_key_protector: Unseal key from a buffer, Gary Lin, 2025/01/08
- [PATCH v2 07/10] tpm2_key_protector: Support NV index handles, Gary Lin, 2025/01/08
- [PATCH v2 08/10] util/grub-protect: Support NV index mode, Gary Lin, 2025/01/08
- [PATCH v2 09/10] tests/tpm2_key_protector_test: Amend the NV index mode test, Gary Lin, 2025/01/08
- [PATCH v2 10/10] docs: Update NV index mode of TPM2 key protector, Gary Lin, 2025/01/08