201 lines
6.5 KiB
Diff
201 lines
6.5 KiB
Diff
From fa69deac565e5d5015ca396b017239cd96900673 Mon Sep 17 00:00:00 2001
|
|
From: Gary Lin <glin@suse.com>
|
|
Date: Mon, 7 Apr 2025 16:29:19 +0800
|
|
Subject: [PATCH 5/7] tpm2_key_protector: Unseal key from a buffer
|
|
|
|
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 unmarshaling the data,
|
|
so there is no need to use the command option to specify the file format
|
|
anymore. In other words, "-T" and "-k" 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>
|
|
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
---
|
|
docs/grub.texi | 13 +-
|
|
.../commands/tpm2_key_protector/module.c | 122 +++++++++++++-----
|
|
2 files changed, 96 insertions(+), 39 deletions(-)
|
|
|
|
Index: grub-2.12/grub-core/commands/tpm2_key_protector/module.c
|
|
===================================================================
|
|
--- grub-2.12.orig/grub-core/commands/tpm2_key_protector/module.c
|
|
+++ grub-2.12/grub-core/commands/tpm2_key_protector/module.c
|
|
@@ -218,10 +218,51 @@ tpm2_protector_srk_read_file (const char
|
|
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 (vo
|
|
}
|
|
|
|
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;
|
|
@@ -954,12 +995,11 @@ tpm2_protector_dump_pcr (const TPM_ALG_I
|
|
}
|
|
|
|
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;
|
|
@@ -972,22 +1012,17 @@ tpm2_protector_srk_recover (const tpm2_p
|
|
|
|
/*
|
|
* 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;
|
|
|
|
@@ -1003,12 +1038,8 @@ tpm2_protector_srk_recover (const tpm2_p
|
|
}
|
|
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;
|
|
}
|
|
@@ -1084,6 +1115,31 @@ tpm2_protector_srk_recover (const tpm2_p
|
|
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;
|
|
}
|