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 <g...@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; > _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel