From: Gary Lin via Grub-devel <grub-devel@gnu.org>
To: The development of GNU GRUB <grub-devel@gnu.org>
Cc: Gary Lin <glin@suse.com>, Daniel Kiper <daniel.kiper@oracle.com>,
mchang@suse.com, patrick.colp@oracle.com,
Stefan Berger <stefanb@linux.ibm.com>,
jejb@linux.ibm.com, Glenn Washburn <development@efficientek.com>
Subject: [PATCH v4 05/12] tpm2_key_protector: Unseal key from a buffer
Date: Fri, 21 Mar 2025 15:59:01 +0800 [thread overview]
Message-ID: <20250321075908.10523-6-glin@suse.com> (raw)
In-Reply-To: <20250321075908.10523-1-glin@suse.com>
Extract the logic to handle the file buffer from the SRK recover
function to prepare to load the sealed key from the NV index handle,
so the NV index mode can share the same code path in the later patch.
The SRK recover function now only reads the file and sends the file
buffer to the new function.
Besides this, to avoid introducing more options for the NV index mode,
the file format is detected automatically before unmarshalling the data,
so there is no need to use the command option to specify the file format
anymore. In other words, '--tpm2key' and '--keyfile' are the same now.
Also update grub.text to address the change.
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
docs/grub.texi | 13 +-
.../commands/tpm2_key_protector/module.c | 122 +++++++++++++-----
2 files changed, 96 insertions(+), 39 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 54d3ab52f..ae89838bc 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -8075,12 +8075,13 @@ options are @option{-T}, @option{-k}, @option{-a}, and @option{-s}. On the
other hand, the NV index-specific option is @option{-n}.
The key file for SRK mode can be supplied with either @option{-T} or
-@option{-k}. The @option{-T} option is for the path to the key file in
-TPM 2.0 Key File format. Since the parameters for the TPM commands are written
-in the file, there is no need to set the PCR list(@option{-p}) and
-bank(@option{-b}) when using the @option{-T} option. The @option{-k} option
-is for the key file in the raw format, and the @option{-p} and @option{-b}
-options are necessary for the non-default PCR list or bank. In general,
+@option{-k}. Those two options were used to distinguish the file formats but
+are same now. There are two supported file formats: raw format and TPM 2.0
+Key File format. When using the key file in the raw format, the @option{-p}
+and @option{-b} options are necessary for the non-default PCR list or bank.
+On the other hand, when using the key file in TPM 2.0 Key File format, the
+the parameters for the TPM commands are written in the file, and there is no
+need to set the PCR list(@option{-p}) and bank(@option{-b}). In general,
TPM 2.0 Key File format is preferred due to the simplified GRUB command
options and the authorized policy support
diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c
index 0a5d81e4c..795f61518 100644
--- a/grub-core/commands/tpm2_key_protector/module.c
+++ b/grub-core/commands/tpm2_key_protector/module.c
@@ -218,10 +218,51 @@ tpm2_protector_srk_read_file (const char *filepath, void **buffer, grub_size_t *
return err;
}
+/* Check if the data is in TPM 2.0 Key File format */
+static bool
+tpm2_protector_is_tpm2key (grub_uint8_t *buffer, grub_size_t buffer_size)
+{
+ /* id-sealedkey OID (2.23.133.10.1.5) in DER */
+ const grub_uint8_t sealed_key_oid[] = {0x06, 0x06, 0x67, 0x81, 0x05, 0x0a};
+ grub_size_t skip = 0;
+
+ /* Need at least the first two bytes to check the tag and the length */
+ if (buffer_size < 2)
+ return false;
+
+ /* The first byte is always 0x30 (SEQUENCE). */
+ if (buffer[0] != 0x30)
+ return false;
+
+ /*
+ * Get the bytes of the length
+ *
+ * If the bit 8 of the second byte is 0, it is in the short form, so the second byte
+ * alone represents the length. Thus, the first two bytes are skipped.
+ *
+ * Otherwise, it is in the long form, and bits 1~7 indicate how many more bytes are in
+ * the length field, so we skip the first two bytes plus the bytes for the length.
+ */
+ if ((buffer[1] & 0x80) == 0)
+ skip = 2;
+ else
+ skip = (buffer[1] & 0x7F) + 2;
+
+ /* Make sure the buffer is large enough to contain id-sealedkey OID */
+ if (buffer_size < skip + sizeof (sealed_key_oid))
+ return false;
+
+ /* Check id-sealedkey OID */
+ if (grub_memcmp (buffer + skip, sealed_key_oid, sizeof (sealed_key_oid)) != 0)
+ return false;
+
+ return true;
+}
+
static grub_err_t
-tpm2_protector_srk_unmarshal_keyfile (void *sealed_key,
- grub_size_t sealed_key_size,
- tpm2_sealed_key_t *sk)
+tpm2_protector_unmarshal_raw (void *sealed_key,
+ grub_size_t sealed_key_size,
+ tpm2_sealed_key_t *sk)
{
struct grub_tpm2_buffer buf;
@@ -242,13 +283,13 @@ tpm2_protector_srk_unmarshal_keyfile (void *sealed_key,
}
static grub_err_t
-tpm2_protector_srk_unmarshal_tpm2key (void *sealed_key,
- grub_size_t sealed_key_size,
- tpm2key_policy_t *policy_seq,
- tpm2key_authpolicy_t *authpol_seq,
- grub_uint8_t *rsaparent,
- grub_uint32_t *parent,
- tpm2_sealed_key_t *sk)
+tpm2_protector_unmarshal_tpm2key (void *sealed_key,
+ grub_size_t sealed_key_size,
+ tpm2key_policy_t *policy_seq,
+ tpm2key_authpolicy_t *authpol_seq,
+ grub_uint8_t *rsaparent,
+ grub_uint32_t *parent,
+ tpm2_sealed_key_t *sk)
{
asn1_node tpm2key = NULL;
grub_uint8_t rsaparent_tmp;
@@ -942,12 +983,11 @@ tpm2_protector_dump_pcr (const TPM_ALG_ID_t bank)
}
static grub_err_t
-tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
- grub_uint8_t **key, grub_size_t *key_size)
+tpm2_protector_key_from_buffer (const tpm2_protector_context_t *ctx,
+ void *buffer, grub_size_t buf_size,
+ grub_uint8_t **key, grub_size_t *key_size)
{
tpm2_sealed_key_t sealed_key = {0};
- void *file_bytes = NULL;
- grub_size_t file_size = 0;
grub_uint8_t rsaparent = 0;
TPM_HANDLE_t parent_handle = 0;
TPM_HANDLE_t srk_handle = 0;
@@ -960,22 +1000,17 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
/*
* Retrieve sealed key, parent handle, policy sequence, and authpolicy
- * sequence from the key file
+ * sequence from the buffer
*/
- if (ctx->tpm2key != NULL)
+ if (tpm2_protector_is_tpm2key (buffer, buf_size) == true)
{
- err = tpm2_protector_srk_read_file (ctx->tpm2key, &file_bytes,
- &file_size);
- if (err != GRUB_ERR_NONE)
- return err;
-
- err = tpm2_protector_srk_unmarshal_tpm2key (file_bytes,
- file_size,
- &policy_seq,
- &authpol_seq,
- &rsaparent,
- &parent_handle,
- &sealed_key);
+ err = tpm2_protector_unmarshal_tpm2key (buffer,
+ buf_size,
+ &policy_seq,
+ &authpol_seq,
+ &rsaparent,
+ &parent_handle,
+ &sealed_key);
if (err != GRUB_ERR_NONE)
goto exit1;
@@ -991,12 +1026,8 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
}
else
{
- err = tpm2_protector_srk_read_file (ctx->keyfile, &file_bytes, &file_size);
- if (err != GRUB_ERR_NONE)
- return err;
-
parent_handle = TPM_RH_OWNER;
- err = tpm2_protector_srk_unmarshal_keyfile (file_bytes, file_size, &sealed_key);
+ err = tpm2_protector_unmarshal_raw (buffer, buf_size, &sealed_key);
if (err != GRUB_ERR_NONE)
goto exit1;
}
@@ -1072,6 +1103,31 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
exit1:
grub_tpm2key_free_policy_seq (policy_seq);
grub_tpm2key_free_authpolicy_seq (authpol_seq);
+ return err;
+}
+
+static grub_err_t
+tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
+ grub_uint8_t **key, grub_size_t *key_size)
+{
+ const char *filepath;
+ void *file_bytes = NULL;
+ grub_size_t file_size = 0;
+ grub_err_t err;
+
+ if (ctx->tpm2key != NULL)
+ filepath = ctx->tpm2key;
+ else if (ctx->keyfile != NULL)
+ filepath = ctx->keyfile;
+ else
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("key file not specified"));
+
+ err = tpm2_protector_srk_read_file (filepath, &file_bytes, &file_size);
+ if (err != GRUB_ERR_NONE)
+ return err;
+
+ err = tpm2_protector_key_from_buffer (ctx, file_bytes, file_size, key, key_size);
+
grub_free (file_bytes);
return err;
}
--
2.43.0
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
next prev parent reply other threads:[~2025-03-21 8:01 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-21 7:58 [PATCH v4 00/12] TPM2 key protector follow-up patches Gary Lin via Grub-devel
2025-03-21 7:58 ` [PATCH v4 01/12] tpm2_key_protector: dump PCRs on policy fail Gary Lin via Grub-devel
2025-03-21 7:58 ` [PATCH v4 02/12] tpm2_key_protector: Add 'tpm2_dump_pcr' command Gary Lin via Grub-devel
2025-03-21 7:58 ` [PATCH v4 03/12] tss2: Fix the missing authCommand Gary Lin via Grub-devel
2025-03-21 7:59 ` [PATCH v4 04/12] tss2: Add TPM 2.0 NV index commands Gary Lin via Grub-devel
2025-03-21 7:59 ` Gary Lin via Grub-devel [this message]
2025-03-25 16:01 ` [PATCH v4 05/12] tpm2_key_protector: Unseal key from a buffer Daniel Kiper via Grub-devel
2025-03-26 7:54 ` Gary Lin via Grub-devel
2025-03-21 7:59 ` [PATCH v4 06/12] tpm2_key_protector: Support NV index handles Gary Lin via Grub-devel
2025-03-21 7:59 ` [PATCH v4 07/12] util/grub-protect: Support NV index mode Gary Lin via Grub-devel
2025-03-26 16:14 ` Daniel Kiper via Grub-devel
2025-03-21 7:59 ` [PATCH v4 08/12] tests/tpm2_key_protector_test: Simplify the NV index mode test Gary Lin via Grub-devel
2025-03-24 14:21 ` Stefan Berger
2025-03-26 16:16 ` Daniel Kiper via Grub-devel
2025-03-21 7:59 ` [PATCH v4 09/12] tests/tpm2_key_protector_test: Reset 'ret' on fail Gary Lin via Grub-devel
2025-03-24 13:48 ` Stefan Berger
2025-03-24 14:29 ` Vladimir 'phcoder' Serbinenko
2025-03-24 14:35 ` Stefan Berger
2025-03-25 7:18 ` Gary Lin via Grub-devel
2025-03-21 7:59 ` [PATCH v4 10/12] tests/tpm2_key_protector_test: Add more NV index mode tests Gary Lin via Grub-devel
2025-03-24 14:19 ` Stefan Berger
2025-03-21 7:59 ` [PATCH v4 11/12] docs: Update NV index mode of TPM2 key protector Gary Lin via Grub-devel
2025-03-21 7:59 ` [PATCH v4 12/12] INSTALL: Document the packages needed for TPM2 key protector tests Gary Lin via Grub-devel
2025-03-26 16:19 ` Daniel Kiper via Grub-devel
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=20250321075908.10523-6-glin@suse.com \
--to=grub-devel@gnu.org \
--cc=daniel.kiper@oracle.com \
--cc=development@efficientek.com \
--cc=glin@suse.com \
--cc=jejb@linux.ibm.com \
--cc=mchang@suse.com \
--cc=patrick.colp@oracle.com \
--cc=stefanb@linux.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.