SHA256
1
0
forked from pool/grub2

Accepting request 1082613 from home:gary_lin:branches:Base:System

- Update TPM 2.0 key unsealing patches

OBS-URL: https://build.opensuse.org/request/show/1082613
OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=452
This commit is contained in:
Gary Ching-Pang Lin 2023-04-26 03:19:58 +00:00 committed by Git OBS Bridge
parent 5420dbe227
commit 03ce3384fd
27 changed files with 3259 additions and 4059 deletions

View File

@ -1,21 +1,22 @@
From 2d959549857305d5e4d95a19a0850885f85179d6 Mon Sep 17 00:00:00 2001
From 5affde982dea827580e36ccc658e439397f51ce8 Mon Sep 17 00:00:00 2001
From: Hernan Gatta <hegatta@linux.microsoft.com>
Date: Tue, 1 Feb 2022 05:02:53 -0800
Subject: [PATCH 10/14] protectors: Add key protectors framework
Subject: [PATCH 1/5] protectors: Add key protectors framework
A key protector encapsulates functionality to retrieve an unlocking key for a
fully-encrypted disk from a specific source. A key protector module registers
itself with the key protectors framework when it is loaded and unregisters when
unloaded. Additionally, a key protector may accept parameters that describe how
it should operate.
A key protector encapsulates functionality to retrieve an unlocking key
for a fully-encrypted disk from a specific source. A key protector
module registers itself with the key protectors framework when it is
loaded and unregisters when unloaded. Additionally, a key protector may
accept parameters that describe how it should operate.
The key protectors framework, besides offering registration and unregistration
functions, also offers a one-stop routine for finding and invoking a key
protector by name. If a key protector with the specified name exists and if an
unlocking key is successfully retrieved by it, the function returns to the
caller the retrieved key and its length.
The key protectors framework, besides offering registration and
unregistration functions, also offers a one-stop routine for finding and
invoking a key protector by name. If a key protector with the specified
name exists and if an unlocking key is successfully retrieved by it, the
function returns to the caller the retrieved key and its length.
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/Makefile.am | 1 +
grub-core/Makefile.core.def | 1 +
@ -26,7 +27,7 @@ Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
create mode 100644 include/grub/protector.h
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index de241f0d04..dc07ba6f87 100644
index 80e7a83ed..79d17a3d2 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -90,6 +90,7 @@ endif
@ -38,10 +39,10 @@ index de241f0d04..dc07ba6f87 100644
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index f3140815b8..b0001a33cf 100644
index d83c9f7b6..0335d9add 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -138,6 +138,7 @@ kernel = {
@@ -144,6 +144,7 @@ kernel = {
common = kern/misc.c;
common = kern/parser.c;
common = kern/partition.c;
@ -51,7 +52,7 @@ index f3140815b8..b0001a33cf 100644
common = kern/term.c;
diff --git a/grub-core/kern/protectors.c b/grub-core/kern/protectors.c
new file mode 100644
index 0000000000..21954dfa48
index 000000000..5ee059565
--- /dev/null
+++ b/grub-core/kern/protectors.c
@@ -0,0 +1,75 @@
@ -83,16 +84,16 @@ index 0000000000..21954dfa48
+grub_err_t
+grub_key_protector_register (struct grub_key_protector *protector)
+{
+ if (!protector || !protector->name || !grub_strlen(protector->name))
+ if (protector == NULL || protector->name == NULL || grub_strlen(protector->name) == 0)
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ if (grub_key_protectors &&
+ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
+ protector->name))
+ protector->name))
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors),
+ GRUB_AS_LIST (protector));
+ GRUB_AS_LIST (protector));
+
+ return GRUB_ERR_NONE;
+}
@ -100,7 +101,7 @@ index 0000000000..21954dfa48
+grub_err_t
+grub_key_protector_unregister (struct grub_key_protector *protector)
+{
+ if (!protector)
+ if (protector == NULL)
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ grub_list_remove (GRUB_AS_LIST (protector));
@ -110,29 +111,29 @@ index 0000000000..21954dfa48
+
+grub_err_t
+grub_key_protector_recover_key (const char *protector, grub_uint8_t **key,
+ grub_size_t *key_size)
+ grub_size_t *key_size)
+{
+ struct grub_key_protector *kp = NULL;
+
+ if (!grub_key_protectors)
+ if (grub_key_protectors == NULL)
+ return GRUB_ERR_OUT_OF_RANGE;
+
+ if (!protector || !grub_strlen (protector))
+ if (protector == NULL || grub_strlen (protector) == 0)
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
+ protector);
+ if (!kp)
+ protector);
+ if (kp == NULL)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ N_("A key protector with name '%s' could not be found. "
+ "Is the name spelled correctly and is the "
+ "corresponding module loaded?"), protector);
+ N_("A key protector with name '%s' could not be found. "
+ "Is the name spelled correctly and is the "
+ "corresponding module loaded?"), protector);
+
+ return kp->recover_key (key, key_size);
+}
diff --git a/include/grub/protector.h b/include/grub/protector.h
new file mode 100644
index 0000000000..179020a344
index 000000000..3d9f69bce
--- /dev/null
+++ b/include/grub/protector.h
@@ -0,0 +1,48 @@
@ -180,10 +181,10 @@ index 0000000000..179020a344
+
+grub_err_t
+EXPORT_FUNC (grub_key_protector_recover_key) (const char *protector,
+ grub_uint8_t **key,
+ grub_size_t *key_size);
+ grub_uint8_t **key,
+ grub_size_t *key_size);
+
+#endif /* ! GRUB_PROTECTOR_HEADER */
--
2.34.1
2.35.3

View File

@ -1,10 +1,9 @@
From 69a5cedcb206ca931ac2c2763c283954751d7072 Mon Sep 17 00:00:00 2001
From 5a417f32f1afe0ffca7f5cbff67145a157b1589b Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Tue, 7 Feb 2023 18:31:12 +0800
Subject: [PATCH 04/13] tpm2: add new TPM2 types, structures, and command
constants
Subject: [PATCH 1/4] tpm2: Add TPM2 types, structures, and command constants
Add new TPM2 types and structures as the preparation to support the
Add new TPM2 types and structures as the preparation to support
authorized policy.
* New types:
@ -18,20 +17,20 @@ authorized policy.
* New command constants:
TPM_CC_LoadExternal, TPM_CC_HashSequenceStart, TPM_CC_SequenceUpdate,
TPM_CC_SequenceComplete, TPM_CC_VerifySignature,
TPM_CC_SequenceComplete, TPM_CC_Hash, TPM_CC_VerifySignature,
TPM_CC_PolicyAuthorize
Signed-off-by: Gary Lin <glin@suse.com>
---
include/grub/tpm2/internal/structs.h | 60 ++++++++++++++++++++++++++++
include/grub/tpm2/internal/types.h | 42 ++++++++++++-------
2 files changed, 88 insertions(+), 14 deletions(-)
include/grub/tpm2/internal/structs.h | 86 ++++++++++++++++++++++++++++
include/grub/tpm2/internal/types.h | 42 +++++++++-----
2 files changed, 114 insertions(+), 14 deletions(-)
diff --git a/include/grub/tpm2/internal/structs.h b/include/grub/tpm2/internal/structs.h
index 75bf99ec8..50090892c 100644
index 72d71eb70..db9eb6cf6 100644
--- a/include/grub/tpm2/internal/structs.h
+++ b/include/grub/tpm2/internal/structs.h
@@ -672,4 +672,64 @@ struct TPMT_TK_CREATION
@@ -672,4 +672,90 @@ struct TPMT_TK_CREATION
};
typedef struct TPMT_TK_CREATION TPMT_TK_CREATION;
@ -87,6 +86,32 @@ index 75bf99ec8..50090892c 100644
+};
+typedef struct TPMT_SIGNATURE TPMT_SIGNATURE;
+
+static inline TPMI_ALG_HASH
+TPMT_SIGNATURE_get_hash_alg (TPMT_SIGNATURE *sig)
+{
+ switch (sig->sigAlg)
+ {
+ case TPM_ALG_RSASSA:
+ return sig->signature.rsassa.hash;
+ case TPM_ALG_RSAPSS:
+ return sig->signature.rsapss.hash;
+ case TPM_ALG_ECDSA:
+ return sig->signature.ecdsa.hash;
+ case TPM_ALG_ECDAA:
+ return sig->signature.ecdaa.hash;
+ case TPM_ALG_SM2:
+ return sig->signature.sm2.hash;
+ case TPM_ALG_ECSCHNORR:
+ return sig->signature.ecschnorr.hash;
+ case TPM_ALG_HMAC:
+ return sig->signature.hmac.hashAlg;
+ default:
+ break;
+ }
+
+ return TPM_ALG_NULL;
+}
+
+/* TPMT_TK_VERIFIED Structure */
+struct TPMT_TK_VERIFIED {
+ TPM_ST tag;

View File

@ -1,73 +0,0 @@
From bc5ecda21bb612f786f614623da782d7ad6d8325 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Tue, 7 Feb 2023 18:01:31 +0800
Subject: [PATCH 01/13] tpm2: adjust the input parameters of TPM2_EvictControl
Per "TCG TPM2 Part3 Commands", 'persistentHandle' of TPM2_EvictControl
is in the parameter area, i.e. after the authorization command. Adjust
the order of the arguments to match the spec definition.
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/tpm2.c | 2 +-
include/grub/tpm2/internal/functions.h | 2 +-
util/grub-protect.c | 8 ++++----
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index 2407a844d..1cd969d5d 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -662,8 +662,8 @@ TPM2_Create (TPMI_DH_OBJECT parentHandle,
TPM_RC
TPM2_EvictControl (TPMI_RH_PROVISION auth,
TPMI_DH_OBJECT objectHandle,
- TPMI_DH_PERSISTENT persistentHandle,
const TPMS_AUTH_COMMAND *authCommand,
+ TPMI_DH_PERSISTENT persistentHandle,
TPMS_AUTH_RESPONSE *authResponse)
{
struct grub_tpm2_buffer in;
diff --git a/include/grub/tpm2/internal/functions.h b/include/grub/tpm2/internal/functions.h
index a1c71fae5..f08b45ed2 100644
--- a/include/grub/tpm2/internal/functions.h
+++ b/include/grub/tpm2/internal/functions.h
@@ -110,8 +110,8 @@ TPM2_Create (TPMI_DH_OBJECT parentHandle,
TPM_RC
TPM2_EvictControl (TPMI_RH_PROVISION auth,
TPMI_DH_OBJECT objectHandle,
- TPMI_DH_PERSISTENT persistentHandle,
const TPMS_AUTH_COMMAND *authCommand,
+ TPMI_DH_PERSISTENT persistentHandle,
TPMS_AUTH_RESPONSE *authResponse);
#endif /* ! GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER */
diff --git a/util/grub-protect.c b/util/grub-protect.c
index d03be3e90..5ff76b613 100644
--- a/util/grub-protect.c
+++ b/util/grub-protect.c
@@ -695,8 +695,8 @@ grub_protect_tpm2_get_srk (struct grub_protect_args *args, TPM_HANDLE *srk)
/* Persist SRK */
if (args->tpm2_persist)
{
- rc = TPM2_EvictControl (TPM_RH_OWNER, srkHandle, args->tpm2_srk,
- &authCommand, NULL);
+ rc = TPM2_EvictControl (TPM_RH_OWNER, srkHandle, &authCommand,
+ args->tpm2_srk, NULL);
if (rc == TPM_RC_SUCCESS)
{
TPM2_FlushContext (srkHandle);
@@ -877,8 +877,8 @@ grub_protect_tpm2_remove (struct grub_protect_args *args)
/* Evict SRK */
authCommand.sessionHandle = TPM_RS_PW;
- rc = TPM2_EvictControl (TPM_RH_OWNER, args->tpm2_srk, args->tpm2_srk,
- &authCommand, NULL);
+ rc = TPM2_EvictControl (TPM_RH_OWNER, args->tpm2_srk, &authCommand,
+ args->tpm2_srk, NULL);
if (rc != TPM_RC_SUCCESS)
{
fprintf (stderr,
--
2.35.3

View File

@ -1,7 +1,7 @@
From ac5c47af318652a25df1788c73884e4e9b6e4ac1 Mon Sep 17 00:00:00 2001
From 1d34522075949581ccb34a08dd73607566517824 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Tue, 7 Feb 2023 18:33:42 +0800
Subject: [PATCH 05/13] tpm2: add more marshal/unmarshal functions
Subject: [PATCH 2/4] tpm2: Add more marshal/unmarshal functions
Add a few more marshal/unmarshal functions to support authorized policy.
@ -34,7 +34,7 @@ Signed-off-by: Gary Lin <glin@suse.com>
2 files changed, 337 insertions(+)
diff --git a/grub-core/tpm2/mu.c b/grub-core/tpm2/mu.c
index 6d3294c5b..150a8d37d 100644
index 1617f37cd..3a9a3c1be 100644
--- a/grub-core/tpm2/mu.c
+++ b/grub-core/tpm2/mu.c
@@ -383,6 +383,49 @@ grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
@ -86,7 +86,7 @@ index 6d3294c5b..150a8d37d 100644
+
void
grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
const TPM2B_SENSITIVE_CREATE *sensitiveCreate)
const TPM2B_SENSITIVE_CREATE *sensitiveCreate)
@@ -405,6 +448,113 @@ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
grub_tpm2_buffer_pack_u16 (buffer, 0);
}
@ -200,7 +200,7 @@ index 6d3294c5b..150a8d37d 100644
+
void
grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buffer,
TPM2B* p)
TPM2B* p)
@@ -775,6 +925,24 @@ grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer,
grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest);
}
@ -225,7 +225,7 @@ index 6d3294c5b..150a8d37d 100644
+
void
grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf,
TPMS_PCR_SELECTION* pcrSelection)
TPMS_PCR_SELECTION* pcrSelection)
@@ -805,3 +973,97 @@ grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf,
for (grub_uint32_t i = 0; i < digest->count; i++)
grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buf, &digest->digests[i]);
@ -325,11 +325,11 @@ index 6d3294c5b..150a8d37d 100644
+ grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (buffer, p->sigAlg, &p->signature);
+}
diff --git a/include/grub/tpm2/mu.h b/include/grub/tpm2/mu.h
index 1e5065bb4..158dbe188 100644
index c545976db..afb842ab5 100644
--- a/include/grub/tpm2/mu.h
+++ b/include/grub/tpm2/mu.h
@@ -147,6 +147,47 @@ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buf,
const TPM2B_SENSITIVE_CREATE *sensitiveCreate);
const TPM2B_SENSITIVE_CREATE *sensitiveCreate);
void
+grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buf,
@ -374,11 +374,11 @@ index 1e5065bb4..158dbe188 100644
+ const TPMT_TK_VERIFIED *p);
+void
grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buf,
TPM2B* p);
TPM2B* p);
@@ -277,6 +318,14 @@ void
grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buf,
TPMT_TK_CREATION *p);
TPMT_TK_CREATION *p);
+void
+grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buf,
@ -390,10 +390,10 @@ index 1e5065bb4..158dbe188 100644
+
void
grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf,
TPMS_PCR_SELECTION* pcrSelection);
TPMS_PCR_SELECTION* pcrSelection);
@@ -289,4 +338,30 @@ void
grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf,
TPML_DIGEST* digest);
TPML_DIGEST* digest);
+void
+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buf,

View File

@ -1,696 +0,0 @@
From 2b94a992464aa2d00333ab3f13f065da99196440 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Tue, 7 Feb 2023 18:14:59 +0800
Subject: [PATCH 02/13] tpm2: declare the input arguments of TPM2 functions as
const
The arguments, except the buffer, of the marshal functions are invariable.
Also, the TPM2 command parameters are supposed not changed by the
command. Declare those arguments as 'const' so that the compiler can
help to detect the undesired change on those arguments. Besides, it's
easier to tell which arguments are the command parameters and which are
the response parameters.
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/mu.c | 64 +++++++++++++-------------
grub-core/tpm2/tpm2.c | 64 +++++++++++++-------------
include/grub/tpm2/internal/functions.h | 64 +++++++++++++-------------
include/grub/tpm2/mu.h | 64 +++++++++++++-------------
4 files changed, 128 insertions(+), 128 deletions(-)
diff --git a/grub-core/tpm2/mu.c b/grub-core/tpm2/mu.c
index c5f5c7b5f..6d3294c5b 100644
--- a/grub-core/tpm2/mu.c
+++ b/grub-core/tpm2/mu.c
@@ -49,7 +49,7 @@ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buffer,
- grub_uint16_t size,
+ const grub_uint16_t size,
const grub_uint8_t* b)
{
grub_tpm2_buffer_pack_u16 (buffer, size);
@@ -60,8 +60,8 @@ grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer,
- TPMI_ALG_SYM_OBJECT algorithm,
- TPMU_SYM_KEY_BITS *p)
+ const TPMI_ALG_SYM_OBJECT algorithm,
+ const TPMU_SYM_KEY_BITS *p)
{
switch (algorithm)
{
@@ -78,8 +78,8 @@ grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer,
- TPMI_ALG_SYM_OBJECT algorithm,
- TPMU_SYM_MODE *p)
+ const TPMI_ALG_SYM_OBJECT algorithm,
+ const TPMU_SYM_MODE *p)
{
switch (algorithm)
{
@@ -96,7 +96,7 @@ grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer,
- TPMT_SYM_DEF *p)
+ const TPMT_SYM_DEF *p)
{
grub_tpm2_buffer_pack_u16 (buffer, p->algorithm);
grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits);
@@ -134,7 +134,7 @@ grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer,
- TPMS_SCHEME_XOR *p)
+ const TPMS_SCHEME_XOR *p)
{
grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg);
grub_tpm2_buffer_pack_u16 (buffer, p->kdf);
@@ -142,15 +142,15 @@ grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer,
- TPMS_SCHEME_HMAC *p)
+ const TPMS_SCHEME_HMAC *p)
{
grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg);
}
void
grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer,
- TPMI_ALG_KEYEDHASH_SCHEME scheme,
- TPMU_SCHEME_KEYEDHASH *p)
+ const TPMI_ALG_KEYEDHASH_SCHEME scheme,
+ const TPMU_SCHEME_KEYEDHASH *p)
{
switch (scheme)
{
@@ -170,7 +170,7 @@ grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
- TPMT_KEYEDHASH_SCHEME *p)
+ const TPMT_KEYEDHASH_SCHEME *p)
{
grub_tpm2_buffer_pack_u16 (buffer, p->scheme);
grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (buffer, p->scheme, &p->details);
@@ -178,14 +178,14 @@ grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer,
- TPMS_KEYEDHASH_PARMS *p)
+ const TPMS_KEYEDHASH_PARMS *p)
{
grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (buffer, &p->scheme);
}
void
grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
- TPMT_SYM_DEF_OBJECT *p)
+ const TPMT_SYM_DEF_OBJECT *p)
{
grub_tpm2_buffer_pack_u16 (buffer, p->algorithm);
grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits);
@@ -194,8 +194,8 @@ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
- TPMI_ALG_RSA_DECRYPT scheme,
- TPMU_ASYM_SCHEME *p __attribute__ ((unused)))
+ const TPMI_ALG_RSA_DECRYPT scheme,
+ const TPMU_ASYM_SCHEME *p __attribute__ ((unused)))
{
switch (scheme)
{
@@ -210,7 +210,7 @@ grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
- TPMT_RSA_SCHEME *p)
+ const TPMT_RSA_SCHEME *p)
{
grub_tpm2_buffer_pack_u16 (buffer, p->scheme);
grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details);
@@ -218,7 +218,7 @@ grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer,
- TPMS_RSA_PARMS *p)
+ const TPMS_RSA_PARMS *p)
{
grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric);
grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (buffer, &p->scheme);
@@ -228,14 +228,14 @@ grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer,
- TPMS_SYMCIPHER_PARMS *p)
+ const TPMS_SYMCIPHER_PARMS *p)
{
grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->sym);
}
void
grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
- TPMT_ECC_SCHEME *p)
+ const TPMT_ECC_SCHEME *p)
{
grub_tpm2_buffer_pack_u16 (buffer, p->scheme);
grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details);
@@ -243,8 +243,8 @@ grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
- TPMI_ALG_KDF scheme,
- TPMU_KDF_SCHEME *p)
+ const TPMI_ALG_KDF scheme,
+ const TPMU_KDF_SCHEME *p)
{
switch (scheme)
{
@@ -270,7 +270,7 @@ grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
- TPMT_KDF_SCHEME *p)
+ const TPMT_KDF_SCHEME *p)
{
grub_tpm2_buffer_pack_u16 (buffer, p->scheme);
grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (buffer, p->scheme, &p->details);
@@ -278,7 +278,7 @@ grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
- TPMS_ECC_PARMS *p)
+ const TPMS_ECC_PARMS *p)
{
grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric);
grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (buffer, &p->scheme);
@@ -288,8 +288,8 @@ grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
- grub_uint32_t type,
- TPMU_PUBLIC_PARMS *p)
+ const grub_uint32_t type,
+ const TPMU_PUBLIC_PARMS *p)
{
switch (type)
{
@@ -313,7 +313,7 @@ grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer,
- TPMS_ECC_POINT *p)
+ const TPMS_ECC_POINT *p)
{
grub_tpm2_mu_TPM2B_Marshal (buffer, p->x.size, p->x.buffer);
grub_tpm2_mu_TPM2B_Marshal (buffer, p->y.size, p->y.buffer);
@@ -321,8 +321,8 @@ grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer,
- TPMI_ALG_PUBLIC type,
- TPMU_PUBLIC_ID *p)
+ const TPMI_ALG_PUBLIC type,
+ const TPMU_PUBLIC_ID *p)
{
switch(type)
{
@@ -344,7 +344,7 @@ grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
- TPMT_PUBLIC *p)
+ const TPMT_PUBLIC *p)
{
grub_tpm2_buffer_pack_u16 (buffer, p->type);
grub_tpm2_buffer_pack_u16 (buffer, p->nameAlg);
@@ -356,7 +356,7 @@ grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
- TPM2B_PUBLIC *p)
+ const TPM2B_PUBLIC *p)
{
grub_uint32_t start;
grub_uint16_t size;
@@ -377,7 +377,7 @@ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
- TPMS_SENSITIVE_CREATE *p)
+ const TPMS_SENSITIVE_CREATE *p)
{
grub_tpm2_mu_TPM2B_Marshal (buffer, p->userAuth.size, p->userAuth.buffer);
grub_tpm2_mu_TPM2B_Marshal (buffer, p->data.size, p->data.buffer);
@@ -385,7 +385,7 @@ grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
void
grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
- TPM2B_SENSITIVE_CREATE *sensitiveCreate)
+ const TPM2B_SENSITIVE_CREATE *sensitiveCreate)
{
grub_uint32_t start;
grub_uint16_t size;
diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index 1cd969d5d..5377ad2c7 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -76,12 +76,12 @@ grub_tpm2_submit_command (TPMI_ST_COMMAND_TAG tag,
}
TPM_RC
-TPM2_CreatePrimary (TPMI_RH_HIERARCHY primaryHandle,
+TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle,
const TPMS_AUTH_COMMAND *authCommand,
- TPM2B_SENSITIVE_CREATE *inSensitive,
- TPM2B_PUBLIC *inPublic,
- TPM2B_DATA *outsideInfo,
- TPML_PCR_SELECTION *creationPCR,
+ const TPM2B_SENSITIVE_CREATE *inSensitive,
+ const TPM2B_PUBLIC *inPublic,
+ const TPM2B_DATA *outsideInfo,
+ const TPML_PCR_SELECTION *creationPCR,
TPM_HANDLE *objectHandle,
TPM2B_PUBLIC *outPublic,
TPM2B_CREATION_DATA *creationData,
@@ -165,14 +165,14 @@ TPM2_CreatePrimary (TPMI_RH_HIERARCHY primaryHandle,
}
TPM_RC
-TPM2_StartAuthSession (TPMI_DH_OBJECT tpmKey,
- TPMI_DH_ENTITY bind,
+TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey,
+ const TPMI_DH_ENTITY bind,
const TPMS_AUTH_COMMAND *authCommand,
- TPM2B_NONCE *nonceCaller,
- TPM2B_ENCRYPTED_SECRET *encryptedSalt,
- TPM_SE sessionType,
- TPMT_SYM_DEF *symmetric,
- TPMI_ALG_HASH authHash,
+ const TPM2B_NONCE *nonceCaller,
+ const TPM2B_ENCRYPTED_SECRET *encryptedSalt,
+ const TPM_SE sessionType,
+ const TPMT_SYM_DEF *symmetric,
+ const TPMI_ALG_HASH authHash,
TPMI_SH_AUTH_SESSION *sessionHandle,
TPM2B_NONCE *nonceTpm,
TPMS_AUTH_RESPONSE *authResponse)
@@ -235,10 +235,10 @@ TPM2_StartAuthSession (TPMI_DH_OBJECT tpmKey,
}
TPM_RC
-TPM2_PolicyPCR (TPMI_SH_POLICY policySessions,
+TPM2_PolicyPCR (const TPMI_SH_POLICY policySessions,
const TPMS_AUTH_COMMAND *authCommand,
- TPM2B_DIGEST *pcrDigest,
- TPML_PCR_SELECTION *pcrs,
+ const TPM2B_DIGEST *pcrDigest,
+ const TPML_PCR_SELECTION *pcrs,
TPMS_AUTH_RESPONSE *authResponse)
{
TPM_RC rc;
@@ -285,7 +285,7 @@ TPM2_PolicyPCR (TPMI_SH_POLICY policySessions,
}
TPM_RC
-TPM2_ReadPublic (TPMI_DH_OBJECT objectHandle,
+TPM2_ReadPublic (const TPMI_DH_OBJECT objectHandle,
const TPMS_AUTH_COMMAND* authCommand,
TPM2B_PUBLIC *outPublic)
{
@@ -322,10 +322,10 @@ TPM2_ReadPublic (TPMI_DH_OBJECT objectHandle,
}
TPM_RC
-TPM2_Load (TPMI_DH_OBJECT parent_handle,
- TPMS_AUTH_COMMAND const *authCommand,
- TPM2B_PRIVATE *inPrivate,
- TPM2B_PUBLIC *inPublic,
+TPM2_Load (const TPMI_DH_OBJECT parent_handle,
+ const TPMS_AUTH_COMMAND *authCommand,
+ const TPM2B_PRIVATE *inPrivate,
+ const TPM2B_PUBLIC *inPublic,
TPM_HANDLE *objectHandle,
TPM2B_NAME *name,
TPMS_AUTH_RESPONSE *authResponse)
@@ -383,7 +383,7 @@ TPM2_Load (TPMI_DH_OBJECT parent_handle,
}
TPM_RC
-TPM2_Unseal (TPMI_DH_OBJECT itemHandle,
+TPM2_Unseal (const TPMI_DH_OBJECT itemHandle,
const TPMS_AUTH_COMMAND *authCommand,
TPM2B_SENSITIVE_DATA *outData,
TPMS_AUTH_RESPONSE *authResponse)
@@ -434,7 +434,7 @@ TPM2_Unseal (TPMI_DH_OBJECT itemHandle,
}
TPM_RC
-TPM2_FlushContext (TPMI_DH_CONTEXT handle)
+TPM2_FlushContext (const TPMI_DH_CONTEXT handle)
{
TPM_RC rc;
struct grub_tpm2_buffer in;
@@ -465,7 +465,7 @@ TPM2_FlushContext (TPMI_DH_CONTEXT handle)
TPM_RC
TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand,
- TPML_PCR_SELECTION *pcrSelectionIn,
+ const TPML_PCR_SELECTION *pcrSelectionIn,
grub_uint32_t *pcrUpdateCounter,
TPML_PCR_SELECTION *pcrSelectionOut,
TPML_DIGEST *pcrValues,
@@ -524,7 +524,7 @@ TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand,
}
TPM_RC
-TPM2_PolicyGetDigest (TPMI_SH_POLICY policySession,
+TPM2_PolicyGetDigest (const TPMI_SH_POLICY policySession,
const TPMS_AUTH_COMMAND *authCommand,
TPM2B_DIGEST *policyDigest,
TPMS_AUTH_RESPONSE *authResponse)
@@ -576,12 +576,12 @@ TPM2_PolicyGetDigest (TPMI_SH_POLICY policySession,
}
TPM_RC
-TPM2_Create (TPMI_DH_OBJECT parentHandle,
+TPM2_Create (const TPMI_DH_OBJECT parentHandle,
const TPMS_AUTH_COMMAND *authCommand,
- TPM2B_SENSITIVE_CREATE *inSensitive,
- TPM2B_PUBLIC *inPublic,
- TPM2B_DATA *outsideInfo,
- TPML_PCR_SELECTION *creationPCR,
+ const TPM2B_SENSITIVE_CREATE *inSensitive,
+ const TPM2B_PUBLIC *inPublic,
+ const TPM2B_DATA *outsideInfo,
+ const TPML_PCR_SELECTION *creationPCR,
TPM2B_PRIVATE *outPrivate,
TPM2B_PUBLIC *outPublic,
TPM2B_CREATION_DATA *creationData,
@@ -660,10 +660,10 @@ TPM2_Create (TPMI_DH_OBJECT parentHandle,
}
TPM_RC
-TPM2_EvictControl (TPMI_RH_PROVISION auth,
- TPMI_DH_OBJECT objectHandle,
+TPM2_EvictControl (const TPMI_RH_PROVISION auth,
+ const TPMI_DH_OBJECT objectHandle,
const TPMS_AUTH_COMMAND *authCommand,
- TPMI_DH_PERSISTENT persistentHandle,
+ const TPMI_DH_PERSISTENT persistentHandle,
TPMS_AUTH_RESPONSE *authResponse)
{
struct grub_tpm2_buffer in;
diff --git a/include/grub/tpm2/internal/functions.h b/include/grub/tpm2/internal/functions.h
index f08b45ed2..8fda8ceab 100644
--- a/include/grub/tpm2/internal/functions.h
+++ b/include/grub/tpm2/internal/functions.h
@@ -22,12 +22,12 @@
#include <grub/tpm2/internal/structs.h>
TPM_RC
-TPM2_CreatePrimary (TPMI_RH_HIERARCHY primaryHandle,
+TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle,
const TPMS_AUTH_COMMAND *authCommand,
- TPM2B_SENSITIVE_CREATE *inSensitive,
- TPM2B_PUBLIC *inPublic,
- TPM2B_DATA *outsideInfo,
- TPML_PCR_SELECTION *creationPCR,
+ const TPM2B_SENSITIVE_CREATE *inSensitive,
+ const TPM2B_PUBLIC *inPublic,
+ const TPM2B_DATA *outsideInfo,
+ const TPML_PCR_SELECTION *creationPCR,
TPM_HANDLE *objectHandle,
TPM2B_PUBLIC *outPublic,
TPM2B_CREATION_DATA *creationData,
@@ -37,69 +37,69 @@ TPM2_CreatePrimary (TPMI_RH_HIERARCHY primaryHandle,
TPMS_AUTH_RESPONSE *authResponse);
TPM_RC
-TPM2_StartAuthSession (TPMI_DH_OBJECT tpmKey,
- TPMI_DH_ENTITY bind,
+TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey,
+ const TPMI_DH_ENTITY bind,
const TPMS_AUTH_COMMAND *authCommand,
- TPM2B_NONCE *nonceCaller,
- TPM2B_ENCRYPTED_SECRET *encryptedSalt,
- TPM_SE sessionType,
- TPMT_SYM_DEF *symmetric,
- TPMI_ALG_HASH authHash,
+ const TPM2B_NONCE *nonceCaller,
+ const TPM2B_ENCRYPTED_SECRET *encryptedSalt,
+ const TPM_SE sessionType,
+ const TPMT_SYM_DEF *symmetric,
+ const TPMI_ALG_HASH authHash,
TPMI_SH_AUTH_SESSION *sessionHandle,
TPM2B_NONCE *nonceTpm,
TPMS_AUTH_RESPONSE *authResponse);
TPM_RC
-TPM2_PolicyPCR (TPMI_SH_POLICY policySession,
+TPM2_PolicyPCR (const TPMI_SH_POLICY policySession,
const TPMS_AUTH_COMMAND *authCommand,
- TPM2B_DIGEST *pcrDigest,
- TPML_PCR_SELECTION *pcrs,
+ const TPM2B_DIGEST *pcrDigest,
+ const TPML_PCR_SELECTION *pcrs,
TPMS_AUTH_RESPONSE *authResponse);
TPM_RC
-TPM2_ReadPublic (TPMI_DH_OBJECT objectHandle,
+TPM2_ReadPublic (const TPMI_DH_OBJECT objectHandle,
const TPMS_AUTH_COMMAND* authCommand,
TPM2B_PUBLIC *outPublic);
TPM_RC
-TPM2_Load (TPMI_DH_OBJECT parent_handle,
- TPMS_AUTH_COMMAND const *authCommand,
- TPM2B_PRIVATE *inPrivate,
- TPM2B_PUBLIC *inPublic,
+TPM2_Load (const TPMI_DH_OBJECT parent_handle,
+ const TPMS_AUTH_COMMAND *authCommand,
+ const TPM2B_PRIVATE *inPrivate,
+ const TPM2B_PUBLIC *inPublic,
TPM_HANDLE *objectHandle,
TPM2B_NAME *name,
TPMS_AUTH_RESPONSE *authResponse);
TPM_RC
-TPM2_Unseal (TPMI_DH_OBJECT item_handle,
+TPM2_Unseal (const TPMI_DH_OBJECT item_handle,
const TPMS_AUTH_COMMAND *authCommand,
TPM2B_SENSITIVE_DATA *outData,
TPMS_AUTH_RESPONSE *authResponse);
TPM_RC
-TPM2_FlushContext (TPMI_DH_CONTEXT handle);
+TPM2_FlushContext (const TPMI_DH_CONTEXT handle);
TPM_RC
TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand,
- TPML_PCR_SELECTION *pcrSelectionIn,
+ const TPML_PCR_SELECTION *pcrSelectionIn,
grub_uint32_t *pcrUpdateCounter,
TPML_PCR_SELECTION *pcrSelectionOut,
TPML_DIGEST *pcrValues,
TPMS_AUTH_RESPONSE *authResponse);
TPM_RC
-TPM2_PolicyGetDigest (TPMI_SH_POLICY policySession,
+TPM2_PolicyGetDigest (const TPMI_SH_POLICY policySession,
const TPMS_AUTH_COMMAND *authCommand,
TPM2B_DIGEST *policyDigest,
TPMS_AUTH_RESPONSE *authResponse);
TPM_RC
-TPM2_Create (TPMI_DH_OBJECT parentHandle,
+TPM2_Create (const TPMI_DH_OBJECT parentHandle,
const TPMS_AUTH_COMMAND *authCommand,
- TPM2B_SENSITIVE_CREATE *inSensitive,
- TPM2B_PUBLIC *inPublic,
- TPM2B_DATA *outsideInfo,
- TPML_PCR_SELECTION *creationPCR,
+ const TPM2B_SENSITIVE_CREATE *inSensitive,
+ const TPM2B_PUBLIC *inPublic,
+ const TPM2B_DATA *outsideInfo,
+ const TPML_PCR_SELECTION *creationPCR,
TPM2B_PRIVATE *outPrivate,
TPM2B_PUBLIC *outPublic,
TPM2B_CREATION_DATA *creationData,
@@ -108,10 +108,10 @@ TPM2_Create (TPMI_DH_OBJECT parentHandle,
TPMS_AUTH_RESPONSE *authResponse);
TPM_RC
-TPM2_EvictControl (TPMI_RH_PROVISION auth,
- TPMI_DH_OBJECT objectHandle,
+TPM2_EvictControl (const TPMI_RH_PROVISION auth,
+ const TPMI_DH_OBJECT objectHandle,
const TPMS_AUTH_COMMAND *authCommand,
- TPMI_DH_PERSISTENT persistentHandle,
+ const TPMI_DH_PERSISTENT persistentHandle,
TPMS_AUTH_RESPONSE *authResponse);
#endif /* ! GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER */
diff --git a/include/grub/tpm2/mu.h b/include/grub/tpm2/mu.h
index 4f4058f9d..1e5065bb4 100644
--- a/include/grub/tpm2/mu.h
+++ b/include/grub/tpm2/mu.h
@@ -28,22 +28,22 @@ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buf,
void
grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buf,
- grub_uint16_t size,
+ const grub_uint16_t size,
const grub_uint8_t* buffer);
void
grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buf,
- TPMI_ALG_SYM_OBJECT algorithm,
- TPMU_SYM_KEY_BITS *p);
+ const TPMI_ALG_SYM_OBJECT algorithm,
+ const TPMU_SYM_KEY_BITS *p);
void
grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buf,
- TPMI_ALG_SYM_OBJECT algorithm,
- TPMU_SYM_MODE *p);
+ const TPMI_ALG_SYM_OBJECT algorithm,
+ const TPMU_SYM_MODE *p);
void
grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buf,
- TPMT_SYM_DEF *p);
+ const TPMT_SYM_DEF *p);
void
grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buf,
@@ -59,92 +59,92 @@ grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buf,
void
grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buf,
- TPMS_SCHEME_XOR *p);
+ const TPMS_SCHEME_XOR *p);
void
grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buf,
- TPMS_SCHEME_HMAC *p);
+ const TPMS_SCHEME_HMAC *p);
void
grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buf,
- TPMI_ALG_KEYEDHASH_SCHEME scheme,
- TPMU_SCHEME_KEYEDHASH *p);
+ const TPMI_ALG_KEYEDHASH_SCHEME scheme,
+ const TPMU_SCHEME_KEYEDHASH *p);
void
grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buf,
- TPMT_KEYEDHASH_SCHEME *p);
+ const TPMT_KEYEDHASH_SCHEME *p);
void
grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buf,
- TPMS_KEYEDHASH_PARMS *p);
+ const TPMS_KEYEDHASH_PARMS *p);
void
grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buf,
- TPMT_SYM_DEF_OBJECT *p);
+ const TPMT_SYM_DEF_OBJECT *p);
void
grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buf,
- TPMI_ALG_RSA_DECRYPT scheme,
- TPMU_ASYM_SCHEME *p);
+ const TPMI_ALG_RSA_DECRYPT scheme,
+ const TPMU_ASYM_SCHEME *p);
void
grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buf,
- TPMT_RSA_SCHEME *p);
+ const TPMT_RSA_SCHEME *p);
void
grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buf,
- TPMS_RSA_PARMS *p);
+ const TPMS_RSA_PARMS *p);
void
grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buf,
- TPMS_SYMCIPHER_PARMS *p);
+ const TPMS_SYMCIPHER_PARMS *p);
void
grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buf,
- TPMT_ECC_SCHEME *p);
+ const TPMT_ECC_SCHEME *p);
void
grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buf,
- TPMI_ALG_KDF scheme,
- TPMU_KDF_SCHEME *p);
+ const TPMI_ALG_KDF scheme,
+ const TPMU_KDF_SCHEME *p);
void
grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buf,
- TPMT_KDF_SCHEME *p);
+ const TPMT_KDF_SCHEME *p);
void
grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buf,
- TPMS_ECC_PARMS *p);
+ const TPMS_ECC_PARMS *p);
void
grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buf,
- grub_uint32_t type,
- TPMU_PUBLIC_PARMS *p);
+ const grub_uint32_t type,
+ const TPMU_PUBLIC_PARMS *p);
void
grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buf,
- TPMS_ECC_POINT *p);
+ const TPMS_ECC_POINT *p);
void
grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buf,
- TPMI_ALG_PUBLIC type,
- TPMU_PUBLIC_ID *p);
+ const TPMI_ALG_PUBLIC type,
+ const TPMU_PUBLIC_ID *p);
void
grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buf,
- TPMT_PUBLIC *p);
+ const TPMT_PUBLIC *p);
void
grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buf,
- TPM2B_PUBLIC *p);
+ const TPM2B_PUBLIC *p);
void
grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buf,
- TPMS_SENSITIVE_CREATE *p);
+ const TPMS_SENSITIVE_CREATE *p);
void
grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buf,
- TPM2B_SENSITIVE_CREATE *sensitiveCreate);
+ const TPM2B_SENSITIVE_CREATE *sensitiveCreate);
void
grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buf,
--
2.35.3

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
From 8f73e30667da46a7716df0f688fbaa41e34fe5ea Mon Sep 17 00:00:00 2001
From a49c4dcbcb04078434f461ed3356c04042be461a Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 8 Feb 2023 10:30:55 +0800
Subject: [PATCH 10/13] tpm2: add TPM2 commands to support authorized policy
Subject: [PATCH 3/4] tpm2: Implement more TPM2 commands
This commit implements a few more TPM2 commands as the preparation for
the authorized policy support.
@ -27,7 +27,7 @@ Signed-off-by: Gary Lin <glin@suse.com>
2 files changed, 481 insertions(+)
diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index a56f7a5e5..2032d6823 100644
index d67699a24..159353b08 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -427,6 +427,73 @@ TPM2_Load (const TPMI_DH_OBJECT parent_handle,
@ -103,7 +103,7 @@ index a56f7a5e5..2032d6823 100644
+
TPM_RC
TPM2_Unseal (const TPMI_DH_OBJECT itemHandle,
const TPMS_AUTH_COMMAND *authCommand,
const TPMS_AUTH_COMMAND *authCommand,
@@ -759,3 +826,360 @@ TPM2_EvictControl (const TPMI_RH_PROVISION auth,
return TPM_RC_SUCCESS;
@ -466,12 +466,12 @@ index a56f7a5e5..2032d6823 100644
+ return TPM_RC_SUCCESS;
+}
diff --git a/include/grub/tpm2/internal/functions.h b/include/grub/tpm2/internal/functions.h
index 8fda8ceab..c8253e4c7 100644
index 9380f26a2..67b78fab8 100644
--- a/include/grub/tpm2/internal/functions.h
+++ b/include/grub/tpm2/internal/functions.h
@@ -70,6 +70,15 @@ TPM2_Load (const TPMI_DH_OBJECT parent_handle,
TPM2B_NAME *name,
TPMS_AUTH_RESPONSE *authResponse);
TPM2B_NAME *name,
TPMS_AUTH_RESPONSE *authResponse);
+TPM_RC
+TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand,
@ -484,10 +484,10 @@ index 8fda8ceab..c8253e4c7 100644
+
TPM_RC
TPM2_Unseal (const TPMI_DH_OBJECT item_handle,
const TPMS_AUTH_COMMAND *authCommand,
const TPMS_AUTH_COMMAND *authCommand,
@@ -114,4 +123,52 @@ TPM2_EvictControl (const TPMI_RH_PROVISION auth,
const TPMI_DH_PERSISTENT persistentHandle,
TPMS_AUTH_RESPONSE *authResponse);
const TPMI_DH_PERSISTENT persistentHandle,
TPMS_AUTH_RESPONSE *authResponse);
+TPM_RC
+TPM2_HashSequenceStart (const TPMS_AUTH_COMMAND *authCommand,

View File

@ -1,68 +0,0 @@
From dcfb996d872a750fc42cb627627a5ac3f6d89a23 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Thu, 9 Feb 2023 14:56:05 +0800
Subject: [PATCH 03/13] tpm2: resend the command on TPM_RC_RETRY
Sometimes TPM may return TPM_RC_RETRY for some reason, and the only
thing we can do is to send the command again. To avoid pending in the
while loop indefinitely, just try to send the command 3 times.
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/tpm2.c | 33 ++++++++++++++++++++++++++++-----
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index 5377ad2c7..083d59d02 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -25,11 +25,11 @@
#include <grub/types.h>
static TPM_RC
-grub_tpm2_submit_command (TPMI_ST_COMMAND_TAG tag,
- TPM_CC commandCode,
- TPM_RC* responseCode,
- const struct grub_tpm2_buffer* in,
- struct grub_tpm2_buffer* out)
+grub_tpm2_submit_command_real (const TPMI_ST_COMMAND_TAG tag,
+ const TPM_CC commandCode,
+ TPM_RC *responseCode,
+ const struct grub_tpm2_buffer *in,
+ struct grub_tpm2_buffer *out)
{
grub_err_t err;
struct grub_tpm2_buffer buf;
@@ -75,6 +75,29 @@ grub_tpm2_submit_command (TPMI_ST_COMMAND_TAG tag,
return TPM_RC_SUCCESS;
}
+static TPM_RC
+grub_tpm2_submit_command (const TPMI_ST_COMMAND_TAG tag,
+ const TPM_CC commandCode,
+ TPM_RC *responseCode,
+ const struct grub_tpm2_buffer *in,
+ struct grub_tpm2_buffer *out)
+{
+ TPM_RC err;
+ int retry_cnt = 0;
+
+ /* Catch TPM_RC_RETRY and send the command again */
+ do {
+ err = grub_tpm2_submit_command_real (tag, commandCode, responseCode,
+ in, out);
+ if (*responseCode != TPM_RC_RETRY)
+ break;
+
+ retry_cnt++;
+ } while (retry_cnt < 3);
+
+ return err;
+}
+
TPM_RC
TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle,
const TPMS_AUTH_COMMAND *authCommand,
--
2.35.3

View File

@ -0,0 +1,142 @@
From d6e2d32d53d9a1aac2383fc6c075f3827111b643 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Thu, 6 Apr 2023 16:00:25 +0800
Subject: [PATCH 4/4] tpm2: Support authorized policy
TPM2_PolicyAuthorize is the key command to support authorized policy
which allows the users to sign TPM policies with their own keys.
Per TPM 2.0 Key File(*), CommandPolicy for TPM2_PolicyAuthorize
comprises 'TPM2B_PUBLIC pubkey', 'TPM2B_DIGEST policy_ref', and
'TPMT_SIGNATURE signature'. This commit unmarshals those data
structures, fetches the current policy digest, hashes the policy digest
with the hash algorithm written in 'signature', and then verifies
'signature' with 'pubkey'. If everything goes well, TPM2_PolicyAuthorize
is invoked to authorize the signed policy.
(*) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/module.c | 98 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 98 insertions(+)
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
index 5274296b7..e5235c2ac 100644
--- a/grub-core/tpm2/module.c
+++ b/grub-core/tpm2/module.c
@@ -454,6 +454,101 @@ grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session,
return GRUB_ERR_NONE;
}
+static grub_err_t
+grub_tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION session,
+ struct grub_tpm2_buffer *cmd_buf)
+{
+ TPM2B_PUBLIC pubkey;
+ TPM2B_DIGEST policy_ref;
+ TPMT_SIGNATURE signature;
+ TPM2B_DIGEST pcr_policy;
+ TPM2B_DIGEST pcr_policy_hash;
+ TPMI_ALG_HASH sig_hash;
+ TPMT_TK_VERIFIED verification_ticket;
+ TPM_HANDLE pubkey_handle = 0;
+ TPM2B_NAME pubname;
+ TPM_RC rc;
+ grub_err_t err;
+
+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey);
+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref);
+ grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature);
+ if (cmd_buf->error != 0)
+ {
+ err = GRUB_ERR_BAD_ARGUMENT;
+ return grub_error (err, N_("Failed to unmarshal the buffer for "
+ "TPM2_PolicyAuthorize"));
+ }
+
+ /* Retrieve Policy Digest */
+ rc = TPM2_PolicyGetDigest (session, NULL, &pcr_policy, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to get policy digest (TPM error: 0x%x)."),
+ rc);
+ return err;
+ }
+
+ /* Calculate the digest of the polcy for VerifySignature */
+ sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature);
+ if (sig_hash == TPM_ALG_NULL)
+ {
+ err = GRUB_ERR_BAD_ARGUMENT;
+ grub_error (err, N_("Failed to get the hash algorithm of the signature"));
+ return err;
+ }
+ rc = TPM2_Hash (NULL, (TPM2B_MAX_BUFFER *)&pcr_policy, sig_hash,
+ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to create PCR policy hash (TPM2_Hash failed "
+ "with TSS/TPM error %u)"), rc);
+ return err;
+ }
+
+ /* Load the public key */
+ rc = TPM2_LoadExternal (NULL, NULL, &pubkey, TPM_RH_OWNER,
+ &pubkey_handle, &pubname, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to load public key (TPM2_LoadExternal failed "
+ "with TSS/TPM error %u)"), rc);
+ return err;
+ }
+
+ /* Verify the signature against the public key and the policy digest */
+ rc = TPM2_VerifySignature (pubkey_handle, NULL, &pcr_policy_hash, &signature,
+ &verification_ticket, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to verify signature (TPM2_VerifySignature "
+ "failed with TSS/TPM error %u)"), rc);
+ goto error;
+ }
+
+ /* Authorize the signed policy with the public key and the verification ticket */
+ rc = TPM2_PolicyAuthorize (session, NULL, &pcr_policy, &policy_ref, &pubname,
+ &verification_ticket, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to authorize PCR policy (TPM2_PolicyAuthorize "
+ "failed with TSS/TPM error: 0x%u).\n"), rc);
+ goto error;
+ }
+
+ err = GRUB_ERR_NONE;
+
+error:
+ TPM2_FlushContext (pubkey_handle);
+
+ return err;
+}
+
static grub_err_t
grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION session)
{
@@ -473,6 +568,9 @@ grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSIO
case TPM_CC_PolicyPCR:
err = grub_tpm2_protector_policypcr (session, &buf);
break;
+ case TPM_CC_PolicyAuthorize:
+ err = grub_tpm2_protector_policyauthorize (session, &buf);
+ break;
default:
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("Unknown TPM Command: 0x%x"), policy->cmd_code);
--
2.35.3

View File

@ -1,86 +0,0 @@
From 4cde0a1bfb8382677c331e0cf4fa482afadbfa1f Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Tue, 7 Feb 2023 18:37:25 +0800
Subject: [PATCH 06/13] tpm2: check the command parameters of TPM2 commands
Some command parameters should not be NULL. Add the conditional check to
avoid the potential NULL pointer reference.
Besides, for TPM2_StartAuthSession, when 'tpmKey' is 'TPM_RH_NULL', the
size of 'encryptedSalt' must be 0 per "TCG TPM2 Part3 Commands".
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/tpm2.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index 1176d968b..8a98fa251 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -127,6 +127,9 @@ TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle,
TPM_RC responseCode;
grub_uint32_t parameterSize;
+ if (!inSensitive || !inPublic || !outsideInfo || !creationPCR)
+ return TPM_RC_VALUE;
+
if (!objectHandle)
objectHandle = &objectHandleTmp;
if (!outPublic)
@@ -210,6 +213,13 @@ TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey,
TPM_RC responseCode;
grub_uint32_t param_size;
+ if (!nonceCaller || !symmetric)
+ return TPM_RC_VALUE;
+
+ if (tpmKey == TPM_RH_NULL &&
+ (encryptedSalt && encryptedSalt->size != 0))
+ return TPM_RC_VALUE;
+
if (!sessionHandle)
sessionHandle = &sessionHandleTmp;
if (!nonceTpm)
@@ -272,6 +282,9 @@ TPM2_PolicyPCR (const TPMI_SH_POLICY policySessions,
TPM_RC responseCode;
grub_uint32_t param_size;
+ if (!pcrs)
+ return TPM_RC_VALUE;
+
if (!authResponse)
authResponse = &authResponseTmp;
@@ -363,6 +376,9 @@ TPM2_Load (const TPMI_DH_OBJECT parent_handle,
TPM_RC responseCode;
grub_uint32_t param_size;
+ if (!inPrivate || !inPublic)
+ return TPM_RC_VALUE;
+
if (!objectHandle)
objectHandle = &objectHandleTmp;
if (!name)
@@ -506,7 +522,7 @@ TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand,
grub_uint32_t parameterSize;
if (!pcrSelectionIn)
- return TPM_RC_FAILURE;
+ return TPM_RC_VALUE;
if (!pcrUpdateCounter)
pcrUpdateCounter = &pcrUpdateCounterTmp;
@@ -625,6 +641,9 @@ TPM2_Create (const TPMI_DH_OBJECT parentHandle,
TPM_RC rc;
grub_uint32_t parameterSize;
+ if (!inSensitive || !inPublic || !outsideInfo || !creationPCR)
+ return TPM_RC_VALUE;
+
if (!outPrivate)
outPrivate = &outPrivateTmp;
if (!outPublic)
--
2.35.3

View File

@ -1,30 +0,0 @@
From 4f00de963f3cf483d4067cdf0e86147248e9456e Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 8 Feb 2023 15:12:10 +0800
Subject: [PATCH 07/13] tpm2: pack the missing authorization command for
TPM2_PCR_Read
When the caller of TPM2_PCR_Read() passes a valid authorization command,
we should pack it into the 'in' buffer before sending the command.
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/tpm2.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index 8a98fa251..8081b8bf3 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -535,6 +535,8 @@ TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand,
/* Marshal */
grub_tpm2_buffer_init (&in);
+ if (authCommand)
+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, pcrSelectionIn);
if (in.error)
return TPM_RC_FAILURE;
--
2.35.3

View File

@ -1,47 +0,0 @@
From 6a280321880fffed8765d65226b92f991443dbc6 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Tue, 7 Feb 2023 22:47:50 +0800
Subject: [PATCH 08/13] tpm2: allow some command parameters to be NULL
There are some parameters of TPM2 commmands allowing to be empty such
as 'encryptedSalt' of 'TPM2_StartAuthSession' and 'pcrDigest' of
'TPM2_PolicyPCR'. Instead of forcing the user of those functions to
declare an empty variable, we can just pack a u16 zero to fabricate an
empty variable when the user passes NULL for them.
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/tpm2.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
index 8081b8bf3..a56f7a5e5 100644
--- a/grub-core/tpm2/tpm2.c
+++ b/grub-core/tpm2/tpm2.c
@@ -238,7 +238,10 @@ TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey,
if (tag == TPM_ST_SESSIONS)
grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
grub_tpm2_mu_TPM2B_Marshal (&in, nonceCaller->size, nonceCaller->buffer);
- grub_tpm2_mu_TPM2B_Marshal (&in, encryptedSalt->size, encryptedSalt->secret);
+ if (encryptedSalt)
+ grub_tpm2_mu_TPM2B_Marshal (&in, encryptedSalt->size, encryptedSalt->secret);
+ else
+ grub_tpm2_buffer_pack_u16 (&in, 0);
grub_tpm2_buffer_pack_u8 (&in, sessionType);
grub_tpm2_mu_TPMT_SYM_DEF_Marshal (&in, symmetric);
grub_tpm2_buffer_pack_u16 (&in, authHash);
@@ -295,7 +298,10 @@ TPM2_PolicyPCR (const TPMI_SH_POLICY policySessions,
grub_tpm2_buffer_pack_u32 (&in, policySessions);
if (tag == TPM_ST_SESSIONS)
grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
- grub_tpm2_mu_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer);
+ if (pcrDigest)
+ grub_tpm2_mu_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer);
+ else
+ grub_tpm2_buffer_pack_u16 (&in, 0);
grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, pcrs);
if (in.error)
return TPM_RC_FAILURE;
--
2.35.3

View File

@ -1,44 +0,0 @@
From ffb0fe8f2dc9256af6df2e3199e3f950e6b8b830 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 8 Feb 2023 10:35:49 +0800
Subject: [PATCH 09/13] tpm2: remove the unnecessary variables
Since the NULL 'encryptedSalt' of 'TPM2_StartAuthSession' is handled as
an empty TPM2B structure, there is no need to declare an empty salt.
As for 'nonceTPM', we don't use in the following TPM2 commands, so we
can safely ignore it.
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/module.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
index 8ede48bbf..3537f223c 100644
--- a/grub-core/tpm2/module.c
+++ b/grub-core/tpm2/module.c
@@ -352,9 +352,7 @@ grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
grub_size_t sealed_key_size;
TPM_HANDLE srk_handle;
TPM2B_NONCE nonceCaller = { 0 };
- TPM2B_ENCRYPTED_SECRET salt = { 0 };
TPMT_SYM_DEF symmetric = { 0 };
- TPM2B_NONCE nonceTPM = { 0 };
TPMI_SH_AUTH_SESSION session;
TPML_PCR_SELECTION pcrSel = {
.count = 1,
@@ -405,9 +403,9 @@ grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
nonceCaller.size = TPM_SHA256_DIGEST_SIZE;
symmetric.algorithm = TPM_ALG_NULL;
- rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonceCaller, &salt,
+ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, NULL, &nonceCaller, NULL,
TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256,
- &session, &nonceTPM, 0);
+ &session, NULL, NULL);
if (rc)
{
grub_error (err, N_("Failed to start auth session (TPM2_StartAuthSession "
--
2.35.3

View File

@ -1,135 +0,0 @@
From e144e2b256ae9771306a8df04f8b9289d435349b Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 8 Feb 2023 11:17:18 +0800
Subject: [PATCH 11/13] tpm2: make the file reading/unmarshal functions generic
Both the key file reading function and the key unmarshal function are
also needed for the authorized policy mode. Slightly modify those
functions so that we can reuse them for the authorized policy mode.
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/module.c | 67 ++++++++++++++++++++---------------------
1 file changed, 33 insertions(+), 34 deletions(-)
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
index 3537f223c..b404d8449 100644
--- a/grub-core/tpm2/module.c
+++ b/grub-core/tpm2/module.c
@@ -144,20 +144,20 @@ static grub_extcmd_t grub_tpm2_protector_clear_cmd;
static struct grub_tpm2_protector_context grub_tpm2_protector_ctx = { 0 };
static grub_err_t
-grub_tpm2_protector_srk_read_keyfile (const char *filepath, void **buffer,
- grub_size_t *buffer_size)
+grub_tpm2_protector_read_file (const char *filepath, void **buffer,
+ grub_size_t *buffer_size)
{
- grub_file_t sealed_key_file;
- grub_off_t sealed_key_size;
- void *sealed_key_buffer;
- grub_off_t sealed_key_read;
+ grub_file_t file;
+ grub_off_t file_size;
+ void *file_buffer;
+ grub_off_t file_read;
/* Using GRUB_FILE_TYPE_SIGNATURE ensures we do not hash the keyfile into PCR9
* otherwise we'll never be able to predict the value of PCR9 at unseal time */
- sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_SIGNATURE);
- if (!sealed_key_file)
+ file = grub_file_open (filepath, GRUB_FILE_TYPE_SIGNATURE);
+ if (!file)
{
- grub_dprintf ("tpm2", "Could not open sealed key file.\n");
+ grub_dprintf ("tpm2", "Could not open file: %s\n", filepath);
/* grub_file_open sets grub_errno on error, and if we do no unset it,
* future calls to grub_file_open will fail (and so will anybody up the
* stack who checks the value, if any). */
@@ -165,44 +165,43 @@ grub_tpm2_protector_srk_read_keyfile (const char *filepath, void **buffer,
return GRUB_ERR_FILE_NOT_FOUND;
}
- sealed_key_size = grub_file_size (sealed_key_file);
- if (!sealed_key_size)
+ file_size = grub_file_size (file);
+ if (!file_size)
{
- grub_dprintf ("tpm2", "Could not read sealed key file size.\n");
- grub_file_close (sealed_key_file);
+ grub_dprintf ("tpm2", "Could not read file size: %s\n", filepath);
+ grub_file_close (file);
return GRUB_ERR_OUT_OF_RANGE;
}
- sealed_key_buffer = grub_malloc (sealed_key_size);
- if (!sealed_key_buffer)
+ file_buffer = grub_malloc (file_size);
+ if (!file_buffer)
{
- grub_dprintf ("tpm2", "Could not allocate buffer for sealed key.\n");
- grub_file_close (sealed_key_file);
+ grub_dprintf ("tpm2", "Could not allocate buffer: %s\n", filepath);
+ grub_file_close (file);
return GRUB_ERR_OUT_OF_MEMORY;
}
- sealed_key_read = grub_file_read (sealed_key_file, sealed_key_buffer,
- sealed_key_size);
- if (sealed_key_read != sealed_key_size)
+ file_read = grub_file_read (file, file_buffer, file_size);
+ if (file_read != file_size)
{
- grub_dprintf ("tpm2", "Could not retrieve sealed key file contents.\n");
- grub_free (sealed_key_buffer);
- grub_file_close (sealed_key_file);
+ grub_dprintf ("tpm2", "Could not retrieve file contents: %s\n", filepath);
+ grub_free (file_buffer);
+ grub_file_close (file);
return GRUB_ERR_FILE_READ_ERROR;
}
- grub_file_close (sealed_key_file);
+ grub_file_close (file);
- *buffer = sealed_key_buffer;
- *buffer_size = sealed_key_size;
+ *buffer = file_buffer;
+ *buffer_size = file_size;
return GRUB_ERR_NONE;
}
static grub_err_t
-grub_tpm2_protector_srk_unmarshal_keyfile (void *sealed_key,
- grub_size_t sealed_key_size,
- TPM2_SEALED_KEY *sk)
+grub_tpm2_protector_unmarshal_keyfile (void *sealed_key,
+ grub_size_t sealed_key_size,
+ TPM2_SEALED_KEY *sk)
{
struct grub_tpm2_buffer buf;
@@ -374,14 +373,14 @@ grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
grub_err_t err;
/* Retrieve Sealed Key */
- err = grub_tpm2_protector_srk_read_keyfile (ctx->keyfile, &sealed_key_bytes,
- &sealed_key_size);
+ err = grub_tpm2_protector_read_file (ctx->keyfile, &sealed_key_bytes,
+ &sealed_key_size);
if (err)
return grub_error (err, N_("Failed to read key file %s"), ctx->keyfile);
- err = grub_tpm2_protector_srk_unmarshal_keyfile (sealed_key_bytes,
- sealed_key_size,
- &sealed_key);
+ err = grub_tpm2_protector_unmarshal_keyfile (sealed_key_bytes,
+ sealed_key_size,
+ &sealed_key);
if (err)
{
grub_error (err, N_("Failed to unmarshal key, ensure the key file is in "
--
2.35.3

View File

@ -1,977 +0,0 @@
From b173db7537920ee5706e1c961fea3086ada6b6dd Mon Sep 17 00:00:00 2001
From: Hernan Gatta <hegatta@linux.microsoft.com>
Date: Tue, 1 Feb 2022 05:02:55 -0800
Subject: [PATCH 12/14] protectors: Add TPM2 Key Protector
The TPM2 key protector is a module that enables the automatic retrieval of a
fully-encrypted disk's unlocking key from a TPM 2.0.
The theory of operation is such that the module accepts various arguments, most
of which are optional and therefore possess reasonable defaults. One of these
arguments is the keyfile parameter, which is mandatory.
The value of this parameter must be a path to a sealed key file (e.g.,
(hd0,gpt1)/boot/grub2/sealed_key). This sealed key file is created via the
grub-protect tool. The tool utilizes the TPM's sealing functionality to seal
(i.e., encrypt) an unlocking key using a Storage Root Key (SRK) to the values of
various Platform Configuration Registers (PCRs). These PCRs reflect the state of
the system as it boots. If the values are as expected, the system may be
considered trustworthy, at which point the TPM allows for a caller to utilize
the private component of the SRK to unseal (i.e., decrypt) the sealed key file.
The caller, in this case, is this key protector.
The TPM2 key protector registers two commands:
- tpm2_key_protector_init: Initializes the state of the TPM2 key protector for
later usage, clearing any previous state, too, if
any.
- tpm2_key_protector_clear: Clears any state set by tpm2_key_protector_init.
The way this is expected to be used requires the user to, either interactively
or, normally, via a boot script, initialize (i.e., configure) the key protector
and then specify that it be used by the cryptomount command (modifications to
this command are in a different patch).
For instance:
tpm2_key_protector_init --keyfile=KEYFILE1
cryptomount DISK1 -k tpm2
tpm2_key_protector_init --keyfile=KEYFILE2 --pcrs=7,11
cryptomount DISK2 -k tpm2
If a user does not initialize the key protector and attempts to use it anyway,
the protector returns an error.
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
---
grub-core/Makefile.core.def | 10 +
grub-core/tpm2/args.c | 129 ++++++
grub-core/tpm2/module.c | 710 ++++++++++++++++++++++++++++++
include/grub/tpm2/internal/args.h | 39 ++
4 files changed, 888 insertions(+)
create mode 100644 grub-core/tpm2/args.c
create mode 100644 grub-core/tpm2/module.c
create mode 100644 include/grub/tpm2/internal/args.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index b0001a33cf..850cee2b13 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2561,6 +2561,16 @@ module = {
enable = efi;
};
+module = {
+ name = tpm2;
+ common = tpm2/args.c;
+ common = tpm2/buffer.c;
+ common = tpm2/module.c;
+ common = tpm2/mu.c;
+ common = tpm2/tpm2.c;
+ efi = tpm2/tcg2.c;
+};
+
module = {
name = tr;
common = commands/tr.c;
diff --git a/grub-core/tpm2/args.c b/grub-core/tpm2/args.c
new file mode 100644
index 0000000000..90c7cd8991
--- /dev/null
+++ b/grub-core/tpm2/args.c
@@ -0,0 +1,129 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Microsoft Corporation
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/tpm2/internal/args.h>
+
+grub_err_t
+grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs,
+ grub_uint8_t *pcr_count)
+{
+ char *current_pcr = value;
+ char *next_pcr;
+ unsigned long pcr;
+ grub_uint8_t i;
+
+ if (grub_strlen (value) == 0)
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ *pcr_count = 0;
+ for (i = 0; i < TPM_MAX_PCRS; i++)
+ {
+ next_pcr = grub_strchr (current_pcr, ',');
+ if (next_pcr == current_pcr)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("Empty entry in PCR list"));
+ if (next_pcr)
+ *next_pcr = '\0';
+
+ grub_errno = GRUB_ERR_NONE;
+ pcr = grub_strtoul (current_pcr, NULL, 10);
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_error (grub_errno,
+ N_("Entry '%s' in PCR list is not a number"),
+ current_pcr);
+
+ if (pcr > TPM_MAX_PCRS)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ N_("Entry %lu in PCR list is too large to be a PCR "
+ "number, PCR numbers range from 0 to %u"),
+ pcr, TPM_MAX_PCRS);
+
+ pcrs[i] = (grub_uint8_t)pcr;
+ *pcr_count += 1;
+
+ if (!next_pcr)
+ break;
+
+ current_pcr = next_pcr + 1;
+ if (*current_pcr == '\0')
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("Trailing comma at the end of PCR list"));
+ }
+
+ if (i == TPM_MAX_PCRS)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ N_("Too many PCRs in PCR list, the maximum number of "
+ "PCRs is %u"), TPM_MAX_PCRS);
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_tpm2_protector_parse_asymmetric (const char *value, TPM_ALG_ID *asymmetric)
+{
+ if (grub_strcasecmp (value, "ECC") == 0)
+ *asymmetric = TPM_ALG_ECC;
+ else if (grub_strcasecmp (value, "RSA") == 0)
+ *asymmetric = TPM_ALG_RSA;
+ else
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ N_("Value '%s' is not a valid asymmetric key type"),
+ value);
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank)
+{
+ if (grub_strcasecmp (value, "SHA1") == 0)
+ *bank = TPM_ALG_SHA1;
+ else if (grub_strcasecmp (value, "SHA256") == 0)
+ *bank = TPM_ALG_SHA256;
+ else if (grub_strcasecmp (value, "SHA384") == 0)
+ *bank = TPM_ALG_SHA384;
+ else
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ N_("Value '%s' is not a valid PCR bank"), value);
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE *handle)
+{
+ unsigned long num;
+
+ grub_errno = GRUB_ERR_NONE;
+ num = grub_strtoul (value, NULL, 0);
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_error (grub_errno, N_("TPM handle value '%s' is not a number"),
+ value);
+
+ if (num > GRUB_UINT_MAX)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ N_("Value %lu is too large to be a TPM handle, TPM "
+ "handles are unsigned 32-bit integers"), num);
+
+ *handle = (TPM_HANDLE)num;
+
+ return GRUB_ERR_NONE;
+}
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
new file mode 100644
index 0000000000..3f2f386f7e
--- /dev/null
+++ b/grub-core/tpm2/module.c
@@ -0,0 +1,710 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Microsoft Corporation
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/extcmd.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/protector.h>
+#include <grub/tpm2/buffer.h>
+#include <grub/tpm2/internal/args.h>
+#include <grub/tpm2/mu.h>
+#include <grub/tpm2/tpm2.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+typedef enum grub_tpm2_protector_mode
+{
+ GRUB_TPM2_PROTECTOR_MODE_UNSET,
+ GRUB_TPM2_PROTECTOR_MODE_SRK,
+ GRUB_TPM2_PROTECTOR_MODE_NV
+} grub_tpm2_protector_mode_t;
+
+struct grub_tpm2_protector_context
+{
+ grub_tpm2_protector_mode_t mode;
+ grub_uint8_t pcrs[TPM_MAX_PCRS];
+ grub_uint8_t pcr_count;
+ TPM_ALG_ID asymmetric;
+ TPM_ALG_ID bank;
+ const char *keyfile;
+ TPM_HANDLE srk;
+ TPM_HANDLE nv;
+};
+
+static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
+ {
+ /* Options for all modes */
+ {
+ .longarg = "mode",
+ .shortarg = 'm',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("Unseal key using SRK ('srk') (default) or retrieve it from an NV "
+ "Index ('nv')."),
+ },
+ {
+ .longarg = "pcrs",
+ .shortarg = 'p',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("Comma-separated list of PCRs used to authorize key release "
+ "(e.g., '7,11', default is 7."),
+ },
+ {
+ .longarg = "bank",
+ .shortarg = 'b',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("Bank of PCRs used to authorize key release: "
+ "SHA1, SHA256 (default), or SHA384."),
+ },
+ /* SRK-mode options */
+ {
+ .longarg = "keyfile",
+ .shortarg = 'k',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("Required in SRK mode, path to the sealed key file to unseal using "
+ "the TPM (e.g., (hd0,gpt1)/boot/grub2/sealed_key)."),
+ },
+ {
+ .longarg = "srk",
+ .shortarg = 's',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("In SRK mode, the SRK handle if the SRK is persistent "
+ "(default is 0x81000001)."),
+ },
+ {
+ .longarg = "asymmetric",
+ .shortarg = 'a',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("In SRK mode, the type of SRK: RSA (default) or ECC."),
+ },
+ /* NV Index-mode options */
+ {
+ .longarg = "nvindex",
+ .shortarg = 'n',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("Required in NV Index mode, the NV handle to read which must "
+ "readily exist on the TPM and which contains the key."),
+ },
+ /* End of list */
+ {0, 0, 0, 0, 0, 0}
+ };
+
+static grub_extcmd_t grub_tpm2_protector_init_cmd;
+static grub_extcmd_t grub_tpm2_protector_clear_cmd;
+static struct grub_tpm2_protector_context grub_tpm2_protector_ctx = { 0 };
+
+static grub_err_t
+grub_tpm2_protector_srk_read_keyfile (const char *filepath, void **buffer,
+ grub_size_t *buffer_size)
+{
+ grub_file_t sealed_key_file;
+ grub_off_t sealed_key_size;
+ void *sealed_key_buffer;
+ grub_off_t sealed_key_read;
+
+ sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_NONE);
+ if (!sealed_key_file)
+ {
+ grub_dprintf ("tpm2", "Could not open sealed key file.\n");
+ /* grub_file_open sets grub_errno on error, and if we do no unset it,
+ * future calls to grub_file_open will fail (and so will anybody up the
+ * stack who checks the value, if any). */
+ grub_errno = GRUB_ERR_NONE;
+ return GRUB_ERR_FILE_NOT_FOUND;
+ }
+
+ sealed_key_size = grub_file_size (sealed_key_file);
+ if (!sealed_key_size)
+ {
+ grub_dprintf ("tpm2", "Could not read sealed key file size.\n");
+ grub_file_close (sealed_key_file);
+ return GRUB_ERR_OUT_OF_RANGE;
+ }
+
+ sealed_key_buffer = grub_malloc (sealed_key_size);
+ if (!sealed_key_buffer)
+ {
+ grub_dprintf ("tpm2", "Could not allocate buffer for sealed key.\n");
+ grub_file_close (sealed_key_file);
+ return GRUB_ERR_OUT_OF_MEMORY;
+ }
+
+ sealed_key_read = grub_file_read (sealed_key_file, sealed_key_buffer,
+ sealed_key_size);
+ if (sealed_key_read != sealed_key_size)
+ {
+ grub_dprintf ("tpm2", "Could not retrieve sealed key file contents.\n");
+ grub_free (sealed_key_buffer);
+ grub_file_close (sealed_key_file);
+ return GRUB_ERR_FILE_READ_ERROR;
+ }
+
+ grub_file_close (sealed_key_file);
+
+ *buffer = sealed_key_buffer;
+ *buffer_size = sealed_key_size;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_tpm2_protector_srk_unmarshal_keyfile (void *sealed_key,
+ grub_size_t sealed_key_size,
+ TPM2_SEALED_KEY *sk)
+{
+ struct grub_tpm2_buffer buf;
+
+ grub_tpm2_buffer_init (&buf);
+ if (sealed_key_size > buf.cap)
+ {
+ grub_dprintf ("tpm2", "Sealed key file is larger than decode buffer "
+ "(%lu vs %lu bytes).\n", sealed_key_size, buf.cap);
+ return GRUB_ERR_BAD_ARGUMENT;
+ }
+
+ grub_memcpy (buf.data, sealed_key, sealed_key_size);
+ buf.size = sealed_key_size;
+
+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public);
+ grub_tpm2_mu_TPM2B_Unmarshal (&buf, (TPM2B *)&sk->private);
+
+ if (buf.error)
+ {
+ grub_dprintf ("tpm2", "Could not unmarshal sealed key file, it is likely "
+ "malformed.\n");
+ return GRUB_ERR_BAD_ARGUMENT;
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_tpm2_protector_srk_get (const struct grub_tpm2_protector_context *ctx,
+ TPM_HANDLE *srk)
+{
+ TPM_RC rc;
+ TPM2B_PUBLIC public;
+ TPMS_AUTH_COMMAND authCommand = { 0 };
+ TPM2B_SENSITIVE_CREATE inSensitive = { 0 };
+ TPM2B_PUBLIC inPublic = { 0 };
+ TPM2B_DATA outsideInfo = { 0 };
+ TPML_PCR_SELECTION creationPcr = { 0 };
+ TPM2B_PUBLIC outPublic = { 0 };
+ TPM2B_CREATION_DATA creationData = { 0 };
+ TPM2B_DIGEST creationHash = { 0 };
+ TPMT_TK_CREATION creationTicket = { 0 };
+ TPM2B_NAME srkName = { 0 };
+ TPM_HANDLE srkHandle;
+
+ /* Find SRK */
+ rc = TPM2_ReadPublic (ctx->srk, NULL, &public);
+ if (rc == TPM_RC_SUCCESS)
+ {
+ *srk = ctx->srk;
+ return GRUB_ERR_NONE;
+ }
+
+ /* The handle exists but its public area could not be read. */
+ if ((rc & ~TPM_RC_N_MASK) != TPM_RC_HANDLE)
+ {
+ grub_dprintf ("tpm2", "The SRK handle (0x%x) exists on the TPM but its "
+ "public area could not be read (TPM2_ReadPublic "
+ "failed with TSS/TPM error %u).\n", ctx->srk, rc);
+ return GRUB_ERR_BAD_DEVICE;
+ }
+
+ /* Create SRK */
+ authCommand.sessionHandle = TPM_RS_PW;
+ inPublic.publicArea.type = ctx->asymmetric;
+ inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
+ inPublic.publicArea.objectAttributes.restricted = 1;
+ inPublic.publicArea.objectAttributes.userWithAuth = 1;
+ inPublic.publicArea.objectAttributes.decrypt = 1;
+ inPublic.publicArea.objectAttributes.fixedTPM = 1;
+ inPublic.publicArea.objectAttributes.fixedParent = 1;
+ inPublic.publicArea.objectAttributes.sensitiveDataOrigin = 1;
+ inPublic.publicArea.objectAttributes.noDA = 1;
+
+ if (ctx->asymmetric == TPM_ALG_RSA)
+ {
+ inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
+ inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
+ inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB;
+ inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
+ inPublic.publicArea.parameters.rsaDetail.keyBits = 2048;
+ inPublic.publicArea.parameters.rsaDetail.exponent = 0;
+ }
+ else if (ctx->asymmetric == TPM_ALG_ECC)
+ {
+ inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES;
+ inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128;
+ inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB;
+ inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_NULL;
+ inPublic.publicArea.parameters.eccDetail.curveID = TPM_ECC_NIST_P256;
+ inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL;
+ }
+ else
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ rc = TPM2_CreatePrimary (TPM_RH_OWNER, &authCommand, &inSensitive, &inPublic,
+ &outsideInfo, &creationPcr, &srkHandle, &outPublic,
+ &creationData, &creationHash, &creationTicket,
+ &srkName, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ grub_dprintf ("tpm2", "Could not create SRK (TPM2_CreatePrimary failed "
+ "with TSS/TPM error %u).\n", rc);
+ return GRUB_ERR_BAD_DEVICE;
+ }
+
+ *srk = srkHandle;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
+ grub_uint8_t **key, grub_size_t *key_size)
+{
+ TPM_RC rc;
+ TPM2_SEALED_KEY sealed_key;
+ void *sealed_key_bytes;
+ grub_size_t sealed_key_size;
+ TPM_HANDLE srk_handle;
+ TPM2B_NONCE nonceCaller = { 0 };
+ TPM2B_ENCRYPTED_SECRET salt = { 0 };
+ TPMT_SYM_DEF symmetric = { 0 };
+ TPM2B_NONCE nonceTPM = { 0 };
+ TPMI_SH_AUTH_SESSION session;
+ TPML_PCR_SELECTION pcrSel = {
+ .count = 1,
+ .pcrSelections = {
+ {
+ .hash = ctx->bank,
+ .sizeOfSelect = 3,
+ .pcrSelect = { 0 }
+ },
+ }
+ };
+ TPMS_AUTH_COMMAND authCmd = { 0 };
+ TPM_HANDLE sealed_key_handle;
+ TPM2B_NAME name;
+ TPMS_AUTH_RESPONSE authResponse;
+ TPM2B_SENSITIVE_DATA data;
+ grub_uint8_t *key_out;
+ grub_uint8_t i;
+ grub_err_t err;
+
+ /* Retrieve Sealed Key */
+ err = grub_tpm2_protector_srk_read_keyfile (ctx->keyfile, &sealed_key_bytes,
+ &sealed_key_size);
+ if (err)
+ return grub_error (err, N_("Failed to read key file %s"), ctx->keyfile);
+
+ err = grub_tpm2_protector_srk_unmarshal_keyfile (sealed_key_bytes,
+ sealed_key_size,
+ &sealed_key);
+ if (err)
+ {
+ grub_error (err, N_("Failed to unmarshal key, ensure the key file is in "
+ "TPM wire format"));
+ goto exit1;
+ }
+
+ /* Get SRK */
+ err = grub_tpm2_protector_srk_get (ctx, &srk_handle);
+ if (err)
+ {
+ grub_error (err, N_("Failed to retrieve the SRK"));
+ goto exit1;
+ }
+
+ err = GRUB_ERR_BAD_DEVICE;
+
+ /* Start Auth Session */
+ nonceCaller.size = TPM_SHA256_DIGEST_SIZE;
+ symmetric.algorithm = TPM_ALG_NULL;
+
+ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonceCaller, &salt,
+ TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256,
+ &session, &nonceTPM, 0);
+ if (rc)
+ {
+ grub_error (err, N_("Failed to start auth session (TPM2_StartAuthSession "
+ "failed with TSS/TPM error %u)"), rc);
+ goto exit2;
+ }
+
+ /* Policy PCR */
+ for (i = 0; i < ctx->pcr_count; i++)
+ pcrSel
+ .pcrSelections[0]
+ .pcrSelect[TPM2_PCR_TO_SELECT(ctx->pcrs[i])]
+ |= TPM2_PCR_TO_BIT(ctx->pcrs[i]);
+
+ rc = TPM2_PolicyPCR (session, NULL, NULL, &pcrSel, NULL);
+ if (rc)
+ {
+ grub_error (err, N_("Failed to submit PCR policy (TPM2_PolicyPCR failed "
+ "with TSS/TPM error %u)"), rc);
+ goto exit3;
+ }
+
+ /* Load Sealed Key */
+ authCmd.sessionHandle = TPM_RS_PW;
+ rc = TPM2_Load (srk_handle, &authCmd, &sealed_key.private, &sealed_key.public,
+ &sealed_key_handle, &name, &authResponse);
+ if (rc)
+ {
+ grub_error (err, N_("Failed to load sealed key (TPM2_Load failed with "
+ "TSS/TPM error %u)"), rc);
+ goto exit3;
+ }
+
+ /* Unseal Sealed Key */
+ authCmd.sessionHandle = session;
+ grub_memset (&authResponse, 0, sizeof (authResponse));
+
+ rc = TPM2_Unseal (sealed_key_handle, &authCmd, &data, &authResponse);
+ if (rc)
+ {
+ grub_error (err, N_("Failed to unseal sealed key (TPM2_Unseal failed "
+ "with TSS/TPM error %u)"), rc);
+ goto exit4;
+ }
+
+ /* Epilogue */
+ key_out = grub_malloc (data.size);
+ if (!key_out)
+ {
+ err = GRUB_ERR_OUT_OF_MEMORY;
+ grub_error (err, N_("No memory left to allocate unlock key buffer"));
+ goto exit4;
+ }
+
+ grub_memcpy (key_out, data.buffer, data.size);
+
+ *key = key_out;
+ *key_size = data.size;
+
+ err = GRUB_ERR_NONE;
+
+exit4:
+ TPM2_FlushContext (sealed_key_handle);
+
+exit3:
+ TPM2_FlushContext (session);
+
+exit2:
+ TPM2_FlushContext (srk_handle);
+
+exit1:
+ grub_free (sealed_key_bytes);
+ return err;
+}
+
+static grub_err_t
+grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *ctx,
+ grub_uint8_t **key, grub_size_t *key_size)
+{
+ (void)ctx;
+ (void)key;
+ (void)key_size;
+
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ N_("NV Index mode is not implemented yet"));
+}
+
+static grub_err_t
+grub_tpm2_protector_recover (const struct grub_tpm2_protector_context *ctx,
+ grub_uint8_t **key, grub_size_t *key_size)
+{
+ switch (ctx->mode)
+ {
+ case GRUB_TPM2_PROTECTOR_MODE_SRK:
+ return grub_tpm2_protector_srk_recover (ctx, key, key_size);
+ case GRUB_TPM2_PROTECTOR_MODE_NV:
+ return grub_tpm2_protector_nv_recover (ctx, key, key_size);
+ default:
+ return GRUB_ERR_BAD_ARGUMENT;
+ }
+}
+
+static grub_err_t
+grub_tpm2_protector_recover_key (grub_uint8_t **key, grub_size_t *key_size)
+{
+ grub_err_t err;
+
+ /* Expect a call to tpm2_protector_init before anybody tries to use us */
+ if (grub_tpm2_protector_ctx.mode == GRUB_TPM2_PROTECTOR_MODE_UNSET)
+ return grub_error (GRUB_ERR_INVALID_COMMAND,
+ N_("Cannot use TPM2 key protector without initializing "
+ "it, call tpm2_protector_init first"));
+
+ if (!key)
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ err = grub_tpm2_protector_recover (&grub_tpm2_protector_ctx, key, key_size);
+ if (err)
+ return err;
+
+ return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx)
+{
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_UNSET)
+ ctx->mode = GRUB_TPM2_PROTECTOR_MODE_SRK;
+
+ /* Checks for SRK mode */
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && !ctx->keyfile)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In SRK mode, a key file must be specified: "
+ "--keyfile or -k"));
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->nv)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In SRK mode, an NV Index cannot be specified"));
+
+ /* Checks for NV mode */
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && !ctx->nv)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In NV Index mode, an NV Index must be specified: "
+ "--nvindex or -n"));
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->keyfile)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In NV Index mode, a keyfile cannot be specified"));
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->srk)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In NV Index mode, an SRK cannot be specified"));
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->asymmetric)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In NV Index mode, an asymmetric key type cannot be "
+ "specified"));
+
+ /* Defaults assignment */
+ if (!ctx->bank)
+ ctx->bank = TPM_ALG_SHA256;
+
+ if (!ctx->pcr_count)
+ {
+ ctx->pcrs[0] = 7;
+ ctx->pcr_count = 1;
+ }
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK)
+ {
+ if (!ctx->srk)
+ ctx->srk = TPM2_SRK_HANDLE;
+
+ if (!ctx->asymmetric)
+ ctx->asymmetric = TPM_ALG_RSA;
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile)
+{
+ if (grub_strlen (value) == 0)
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ *keyfile = grub_strdup (value);
+ if (!*keyfile)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ N_("No memory to duplicate keyfile path"));
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_tpm2_protector_parse_mode (const char *value,
+ grub_tpm2_protector_mode_t *mode)
+{
+ if (grub_strcmp (value, "srk") == 0)
+ *mode = GRUB_TPM2_PROTECTOR_MODE_SRK;
+ else if (grub_strcmp (value, "nv") == 0)
+ *mode = GRUB_TPM2_PROTECTOR_MODE_NV;
+ else
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ N_("Value '%s' is not a valid TPM2 key protector mode"),
+ value);
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_tpm2_protector_init_cmd_handler (grub_extcmd_context_t ctxt, int argc,
+ char **args __attribute__ ((unused)))
+{
+ struct grub_arg_list *state = ctxt->state;
+ grub_err_t err;
+
+ if (argc)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("The TPM2 key protector does not accept any "
+ "non-option arguments (i.e., like -o and/or --option "
+ "only)"));
+
+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx));
+
+ if (state[0].set) /* mode */
+ {
+ err = grub_tpm2_protector_parse_mode (state[0].arg,
+ &grub_tpm2_protector_ctx.mode);
+ if (err)
+ return err;
+ }
+
+ if (state[1].set) /* pcrs */
+ {
+ err = grub_tpm2_protector_parse_pcrs (state[1].arg,
+ grub_tpm2_protector_ctx.pcrs,
+ &grub_tpm2_protector_ctx.pcr_count);
+ if (err)
+ return err;
+ }
+
+ if (state[2].set) /* bank */
+ {
+ err = grub_tpm2_protector_parse_bank (state[2].arg,
+ &grub_tpm2_protector_ctx.bank);
+ if (err)
+ return err;
+ }
+
+ if (state[3].set) /* keyfile */
+ {
+ err = grub_tpm2_protector_parse_keyfile (state[3].arg,
+ &grub_tpm2_protector_ctx.keyfile);
+ if (err)
+ return err;
+ }
+
+ if (state[4].set) /* srk */
+ {
+ err = grub_tpm2_protector_parse_tpm_handle (state[4].arg,
+ &grub_tpm2_protector_ctx.srk);
+ if (err)
+ return err;
+ }
+
+ if (state[5].set) /* asymmetric */
+ {
+ err = grub_tpm2_protector_parse_asymmetric (state[5].arg,
+ &grub_tpm2_protector_ctx.asymmetric);
+ if (err)
+ return err;
+ }
+
+ if (state[6].set) /* nvindex */
+ {
+ err = grub_tpm2_protector_parse_tpm_handle (state[6].arg,
+ &grub_tpm2_protector_ctx.nv);
+ if (err)
+ return err;
+ }
+
+ err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx);
+
+ /* This command only initializes the protector, so nothing else to do. */
+
+ return err;
+}
+
+static grub_err_t
+grub_tpm2_protector_clear_cmd_handler (grub_extcmd_context_t ctxt __attribute__ ((unused)),
+ int argc,
+ char **args __attribute__ ((unused)))
+{
+ if (argc)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("tpm2_key_protector_clear accepts no arguments"));
+
+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx));
+
+ return GRUB_ERR_NONE;
+}
+
+static struct grub_key_protector grub_tpm2_key_protector =
+ {
+ .name = "tpm2",
+ .recover_key = grub_tpm2_protector_recover_key
+ };
+
+GRUB_MOD_INIT (tpm2)
+{
+ grub_tpm2_protector_init_cmd =
+ grub_register_extcmd ("tpm2_key_protector_init",
+ grub_tpm2_protector_init_cmd_handler, 0,
+ N_("[-m mode] "
+ "[-p pcr_list] "
+ "[-b pcr_bank] "
+ "[-k sealed_key_file_path] "
+ "[-s srk_handle] "
+ "[-a asymmetric_key_type] "
+ "[-n nv_index]"),
+ N_("Initialize the TPM2 key protector."),
+ grub_tpm2_protector_init_cmd_options);
+ grub_tpm2_protector_clear_cmd =
+ grub_register_extcmd ("tpm2_key_protector_clear",
+ grub_tpm2_protector_clear_cmd_handler, 0, NULL,
+ N_("Clear the TPM2 key protector if previously initialized."),
+ NULL);
+ grub_key_protector_register (&grub_tpm2_key_protector);
+}
+
+GRUB_MOD_FINI (tpm2)
+{
+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx));
+
+ grub_key_protector_unregister (&grub_tpm2_key_protector);
+ grub_unregister_extcmd (grub_tpm2_protector_clear_cmd);
+ grub_unregister_extcmd (grub_tpm2_protector_init_cmd);
+}
diff --git a/include/grub/tpm2/internal/args.h b/include/grub/tpm2/internal/args.h
new file mode 100644
index 0000000000..6341fce1c5
--- /dev/null
+++ b/include/grub/tpm2/internal/args.h
@@ -0,0 +1,39 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Microsoft Corporation
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TPM2_INTERNAL_ARGS_HEADER
+#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1
+
+#include <grub/err.h>
+#include <grub/tpm2/tpm2.h>
+
+grub_err_t
+grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs,
+ grub_uint8_t *pcr_count);
+
+grub_err_t
+grub_tpm2_protector_parse_asymmetric (const char *value,
+ TPM_ALG_ID *asymmetric);
+
+grub_err_t
+grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank);
+
+grub_err_t
+grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE *handle);
+
+#endif /* ! GRUB_TPM2_INTERNAL_ARGS_HEADER */
--
2.34.1

View File

@ -1,103 +0,0 @@
From 1dcae21faa281496a79ee2caf59772bf36b16b9e Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 8 Feb 2023 11:20:45 +0800
Subject: [PATCH 12/13] tpm2: initialize the PCR selection list early
The PCR selection list will be used in several TPM2 commands for the
authorized policy mode. Declare the PCR selection list in
grub_tpm2_protector_context and initialize the list after checking the
arguments of the tpm2 module so that other functions can use the list
directly.
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/module.c | 39 +++++++++++++++++++++------------------
1 file changed, 21 insertions(+), 18 deletions(-)
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
index b404d8449..c819ef616 100644
--- a/grub-core/tpm2/module.c
+++ b/grub-core/tpm2/module.c
@@ -43,6 +43,7 @@ struct grub_tpm2_protector_context
grub_tpm2_protector_mode_t mode;
grub_uint8_t pcrs[TPM_MAX_PCRS];
grub_uint8_t pcr_count;
+ TPML_PCR_SELECTION pcr_list;
TPM_ALG_ID asymmetric;
TPM_ALG_ID bank;
const char *keyfile;
@@ -353,23 +354,12 @@ grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
TPM2B_NONCE nonceCaller = { 0 };
TPMT_SYM_DEF symmetric = { 0 };
TPMI_SH_AUTH_SESSION session;
- TPML_PCR_SELECTION pcrSel = {
- .count = 1,
- .pcrSelections = {
- {
- .hash = ctx->bank,
- .sizeOfSelect = 3,
- .pcrSelect = { 0 }
- },
- }
- };
TPMS_AUTH_COMMAND authCmd = { 0 };
TPM_HANDLE sealed_key_handle;
TPM2B_NAME name;
TPMS_AUTH_RESPONSE authResponse;
TPM2B_SENSITIVE_DATA data;
grub_uint8_t *key_out;
- grub_uint8_t i;
grub_err_t err;
/* Retrieve Sealed Key */
@@ -413,13 +403,7 @@ grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
}
/* Policy PCR */
- for (i = 0; i < ctx->pcr_count; i++)
- pcrSel
- .pcrSelections[0]
- .pcrSelect[TPM2_PCR_TO_SELECT(ctx->pcrs[i])]
- |= TPM2_PCR_TO_BIT(ctx->pcrs[i]);
-
- rc = TPM2_PolicyPCR (session, NULL, NULL, &pcrSel, NULL);
+ rc = TPM2_PolicyPCR (session, NULL, NULL, &ctx->pcr_list, NULL);
if (rc)
{
grub_error (err, N_("Failed to submit PCR policy (TPM2_PolicyPCR failed "
@@ -538,6 +522,23 @@ grub_tpm2_protector_recover_key (grub_uint8_t **key, grub_size_t *key_size)
return GRUB_ERR_NONE;
}
+static void
+initialize_pcr_list (struct grub_tpm2_protector_context *ctx)
+{
+ TPMS_PCR_SELECTION *pcr_sel;
+ grub_uint8_t i;
+
+ grub_memset (&ctx->pcr_list, 0, sizeof (TPML_PCR_SELECTION));
+
+ ctx->pcr_list.count = 1;
+
+ pcr_sel = &ctx->pcr_list.pcrSelections[0];
+ pcr_sel->hash = ctx->bank;
+ pcr_sel->sizeOfSelect = 3;
+
+ for (i = 0; i < ctx->pcr_count; i++)
+ pcr_sel->pcrSelect[TPM2_PCR_TO_SELECT(ctx->pcrs[i])] |= TPM2_PCR_TO_BIT(ctx->pcrs[i]);
+}
static grub_err_t
grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx)
@@ -593,6 +594,8 @@ grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx)
ctx->asymmetric = TPM_ALG_RSA;
}
+ initialize_pcr_list (ctx);
+
return GRUB_ERR_NONE;
}
--
2.35.3

View File

@ -1,794 +0,0 @@
From 47220d1ce8fffac3654454b8a981385133b7c23a Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 8 Feb 2023 11:26:25 +0800
Subject: [PATCH 13/13] tpm2: support unsealing key with authorized policy
To solve the PCR brittleness, TPM 2.0 allows the administrator to
'authorize' a new PCR policy, i.e. a new set of PCR values, to unseal
the existing key. This commit extends the SRK mode to support the
authorized policy mode to unseal the disk encryption key.
The usage of the authorized policy mode is very similar to the SRK mode
except two additional arguments: "-P" for the publicy key and "-S" for
the signed policy.
Example of the authorized policy mode:
tpm2_key_protector_init -m authpol -b sha256 -p 0,2,4,7 \
-k (hd0,gpt1)/boot/grub2/sealed.key \
-P (hd0,gpt1)/boot/grub2/pub.key \
-S (hd0,gpt1)/boot/grub2/pol.sig
Signed-off-by: Gary Lin <glin@suse.com>
---
grub-core/tpm2/module.c | 614 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 602 insertions(+), 12 deletions(-)
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
index c819ef616..8e1b14146 100644
--- a/grub-core/tpm2/module.c
+++ b/grub-core/tpm2/module.c
@@ -35,7 +35,8 @@ typedef enum grub_tpm2_protector_mode
{
GRUB_TPM2_PROTECTOR_MODE_UNSET,
GRUB_TPM2_PROTECTOR_MODE_SRK,
- GRUB_TPM2_PROTECTOR_MODE_NV
+ GRUB_TPM2_PROTECTOR_MODE_NV,
+ GRUB_TPM2_PROTECTOR_MODE_AUTHPOL
} grub_tpm2_protector_mode_t;
struct grub_tpm2_protector_context
@@ -47,6 +48,8 @@ struct grub_tpm2_protector_context
TPM_ALG_ID asymmetric;
TPM_ALG_ID bank;
const char *keyfile;
+ const char *pkfile;
+ const char *sigfile;
TPM_HANDLE srk;
TPM_HANDLE nv;
const char *efivar;
@@ -62,8 +65,8 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
.arg = NULL,
.type = ARG_TYPE_STRING,
.doc =
- N_("Unseal key using SRK ('srk') (default) or retrieve it from an NV "
- "Index ('nv')."),
+ N_("Unseal key using SRK ('srk') (default), retrieve it from an NV "
+ "Index ('nv'), or unseal key with a authorized policy ('authpol')."),
},
{
.longarg = "pcrs",
@@ -85,7 +88,7 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
N_("Bank of PCRs used to authorize key release: "
"SHA1, SHA256 (default), or SHA384."),
},
- /* SRK-mode options */
+ /* SRK-mode and Authorized Policy-mode options */
{
.longarg = "keyfile",
.shortarg = 'k',
@@ -93,8 +96,9 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
.arg = NULL,
.type = ARG_TYPE_STRING,
.doc =
- N_("Required in SRK mode, path to the sealed key file to unseal using "
- "the TPM (e.g., (hd0,gpt1)/boot/grub2/sealed_key)."),
+ N_("Required in SRK and Authorized Policy mode, path to the sealed "
+ "key file to unseal using the TPM "
+ "(e.g., (hd0,gpt1)/boot/grub2/sealed_key)."),
},
{
.longarg = "srk",
@@ -103,8 +107,8 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
.arg = NULL,
.type = ARG_TYPE_STRING,
.doc =
- N_("In SRK mode, the SRK handle if the SRK is persistent "
- "(default is 0x81000001)."),
+ N_("In SRK and Authorized Policy mode, the SRK handle if the SRK is "
+ "persistent (default is 0x81000001)."),
},
{
.longarg = "asymmetric",
@@ -113,7 +117,8 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
.arg = NULL,
.type = ARG_TYPE_STRING,
.doc =
- N_("In SRK mode, the type of SRK: RSA (default) or ECC."),
+ N_("In SRK and Authorized Policy mode, the type of SRK: RSA "
+ "(default) or ECC."),
},
/* NV Index-mode options */
{
@@ -136,6 +141,26 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
.doc =
N_("Publish the unsealed key to the indicated UEFI variable."),
},
+ /* Authorized Policy-mode options */
+ {
+ .longarg = "pkfile",
+ .shortarg = 'P',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("Public key file to verify the PCR policy signature"
+ "(e.g., (hd0,gpt1)/boot/grub2/pub.key)"),
+ },
+ {
+ .longarg = "sigfile",
+ .shortarg = 'S',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("PCR policy signature file (e.g., (hd0,gpt1)/boot/grub2/pol.sig)"),
+ },
/* End of list */
{0, 0, 0, 0, 0, 0}
};
@@ -199,6 +224,66 @@ grub_tpm2_protector_read_file (const char *filepath, void **buffer,
return GRUB_ERR_NONE;
}
+static grub_err_t
+grub_tpm2_protector_unmarshal_pkfile (void *pub_key,
+ grub_size_t pub_key_size,
+ TPM2B_PUBLIC *pk)
+{
+ struct grub_tpm2_buffer buf;
+
+ grub_tpm2_buffer_init (&buf);
+ if (pub_key_size > buf.cap)
+ {
+ grub_dprintf ("tpm2", "Public key file is larger than decode buffer "
+ "(%" PRIuGRUB_SIZE " vs %" PRIuGRUB_SIZE " bytes).\n", pub_key_size, buf.cap);
+ return GRUB_ERR_BAD_ARGUMENT;
+ }
+
+ grub_memcpy (buf.data, pub_key, pub_key_size);
+ buf.size = pub_key_size;
+
+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&buf, pk);
+
+ if (buf.error)
+ {
+ grub_dprintf ("tpm2", "Could not unmarshal public key file, it is likely "
+ "malformed.\n");
+ return GRUB_ERR_BAD_ARGUMENT;
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_tpm2_protector_unmarshal_sigfile (void *sig,
+ grub_size_t sig_size,
+ TPMT_SIGNATURE *signature)
+{
+ struct grub_tpm2_buffer buf;
+
+ grub_tpm2_buffer_init (&buf);
+ if (sig_size > buf.cap)
+ {
+ grub_dprintf ("tpm2", "Signed PCR policy file is larger than decode buffer "
+ "(%" PRIuGRUB_SIZE " vs %" PRIuGRUB_SIZE " bytes).\n", sig_size, buf.cap);
+ return GRUB_ERR_BAD_ARGUMENT;
+ }
+
+ grub_memcpy (buf.data, sig, sig_size);
+ buf.size = sig_size;
+
+ grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (&buf, signature);
+
+ if (buf.error)
+ {
+ grub_dprintf ("tpm2", "Could not unmarshal public key file, it is likely "
+ "malformed.\n");
+ return GRUB_ERR_BAD_ARGUMENT;
+ }
+
+ return GRUB_ERR_NONE;
+}
+
static grub_err_t
grub_tpm2_protector_unmarshal_keyfile (void *sealed_key,
grub_size_t sealed_key_size,
@@ -486,6 +571,433 @@ grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *ctx,
N_("NV Index mode is not implemented yet"));
}
+static grub_err_t
+get_pcr_digest (const struct grub_tpm2_protector_context *ctx,
+ TPM2B_DIGEST *pcr_digest)
+{
+ TPM_RC rc;
+ TPML_PCR_SELECTION pcr_list_out = { 0 };
+ TPML_DIGEST pcr_values = { 0 };
+ grub_size_t pcr_digest_len;
+ TPM2B_AUTH auth = { 0 };
+ TPMI_DH_OBJECT sequence = 0;
+ TPMS_AUTH_COMMAND authCmd;
+ grub_uint8_t i;
+ TPM2B_DIGEST result_digest;
+ grub_err_t err = GRUB_ERR_INVALID_COMMAND;
+
+ if (!pcr_digest)
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ /* PCR Read */
+ rc = TPM2_PCR_Read (NULL, &ctx->pcr_list, NULL, &pcr_list_out, &pcr_values, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ return grub_error (err, N_("Failed to read PCRs (TPM error: 0x%x)."), rc);
+ }
+
+ if ((pcr_list_out.count != ctx->pcr_list.count) ||
+ (ctx->pcr_list.pcrSelections[0].sizeOfSelect !=
+ pcr_list_out.pcrSelections[0].sizeOfSelect))
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ return grub_error (err, N_("Could not read all the specified PCRs."));
+ }
+
+ /* Check the hash algorithm */
+ switch (ctx->bank)
+ {
+ case TPM_ALG_SHA1:
+ pcr_digest_len = TPM_SHA1_DIGEST_SIZE;
+ break;
+ case TPM_ALG_SHA256:
+ pcr_digest_len = TPM_SHA256_DIGEST_SIZE;
+ break;
+ case TPM_ALG_SHA384:
+ pcr_digest_len = TPM_SHA384_DIGEST_SIZE;
+ break;
+ case TPM_ALG_SHA512:
+ pcr_digest_len = TPM_SHA512_DIGEST_SIZE;
+ break;
+ default:
+ return GRUB_ERR_BAD_ARGUMENT;
+ }
+
+ /* Start the hash sequence with an empty password (auth) */
+ rc = TPM2_HashSequenceStart (NULL, &auth, ctx->bank, &sequence, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ return grub_error (err,
+ N_("Failed to start hash sequence (TPM error: 0x%x)."),
+ rc);
+ }
+
+ /* Set up the password session with an empty password for TPM2_SequenceUpdate */
+ /* and TPM2_SequenceComplete */
+ grub_memset (&authCmd, 0, sizeof (TPMS_AUTH_COMMAND));
+ authCmd.sessionHandle = TPM_RS_PW;
+
+ for (i = 0; i < ctx->pcr_count; i++)
+ {
+ if (pcr_values.digests[i].size != pcr_digest_len)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err,
+ N_("Bad PCR value size: expected %" PRIuGRUB_SIZE " bytes but got %u bytes.\n"),
+ pcr_digest_len, pcr_values.digests[i].size);
+ goto error;
+ }
+
+ rc = TPM2_SequenceUpdate (sequence, &authCmd,
+ (TPM2B_MAX_BUFFER *)&pcr_values.digests[i],
+ NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err,
+ N_("Failed to update hash sequence (TPM error: 0x%x)."),
+ rc);
+ goto error;
+ }
+ }
+
+ rc = TPM2_SequenceComplete (sequence, &authCmd, NULL, TPM_RH_NULL,
+ &result_digest, NULL, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err,
+ N_("Failed to complete hash sequence (TPM error: 0x%x)."),
+ rc);
+ goto error;
+ }
+
+ *pcr_digest = result_digest;
+ sequence = 0;
+ err = GRUB_ERR_NONE;
+
+error:
+
+ /* End the sequence if necessary */
+ if (sequence != 0)
+ {
+ grub_memset (&authCmd, 0, sizeof (TPMS_AUTH_COMMAND));
+ authCmd.sessionHandle = TPM_RS_PW;
+ TPM2_SequenceComplete (sequence, &authCmd, NULL, TPM_RH_NULL,
+ &result_digest, NULL, NULL);
+ }
+
+ return err;
+}
+
+static grub_err_t
+grub_tpm2_protector_authpol_digest (const struct grub_tpm2_protector_context *ctx,
+ TPM2B_DIGEST *digest)
+{
+ TPM_RC rc;
+ TPM2B_DIGEST pcr_digest;
+ TPM2B_NONCE nonce = { 0 };
+ TPMT_SYM_DEF symmetric = { 0 };
+ TPMI_SH_AUTH_SESSION session = 0;
+ TPM2B_DIGEST policy_digest = { 0 };
+ grub_err_t err;
+
+ err = get_pcr_digest (ctx, &pcr_digest);
+ if (err != GRUB_ERR_NONE)
+ return err;
+
+ /* Start Trial Session to calculate the policy digest */
+ nonce.size = TPM_SHA256_DIGEST_SIZE;
+ symmetric.algorithm = TPM_ALG_NULL;
+
+ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, NULL, &nonce, NULL,
+ TPM_SE_TRIAL, &symmetric, TPM_ALG_SHA256,
+ &session, NULL, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err,
+ N_("Failed to start trial policy session (TPM error: 0x%x)."),
+ rc);
+ goto error;
+ }
+
+ /* PCR Policy */
+ rc = TPM2_PolicyPCR (session, NULL, &pcr_digest, &ctx->pcr_list, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, _("Failed to submit PCR policy (TPM error: 0x%x)."),
+ rc);
+ goto error;
+ }
+
+ /* Retrieve Policy Digest */
+ rc = TPM2_PolicyGetDigest (session, NULL, &policy_digest, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, _("Failed to get policy digest (TPM error: 0x%x)."),
+ rc);
+ goto error;
+ }
+
+ /* Epilogue */
+ *digest = policy_digest;
+ err = GRUB_ERR_NONE;
+
+error:
+ TPM2_FlushContext (session);
+
+ return err;
+}
+
+static grub_err_t
+grub_tpm2_protector_authpol_recover (const struct grub_tpm2_protector_context *ctx,
+ grub_uint8_t **key, grub_size_t *key_size)
+{
+ TPM_RC rc;
+ TPM2B_DIGEST pcr_policy;
+ TPM2B_DIGEST pcr_policy_hash;
+ TPM2B_PUBLIC pub_key;
+ void *pub_key_bytes = NULL;
+ grub_size_t pub_key_size;
+ TPM2B_NAME pubname;
+ TPMT_SIGNATURE signature;
+ void *sig_bytes = NULL;
+ grub_size_t sig_size;
+ TPM2_SEALED_KEY sealed_key;
+ void *sealed_key_bytes = NULL;
+ grub_size_t sealed_key_size;
+ TPM_HANDLE pubkey_handle = 0;
+ TPM_HANDLE primary_handle = 0;
+ TPM_HANDLE sealed_key_handle = 0;
+ TPMT_SYM_DEF symmetric = { 0 };
+ TPM2B_NONCE nonceCaller = { 0 };
+ TPMI_SH_AUTH_SESSION session;
+ TPM2B_SENSITIVE_DATA data;
+ TPMS_AUTH_COMMAND authCmd = { 0 };
+ TPMT_TK_VERIFIED verification_ticket;
+ grub_uint8_t *key_out;
+ grub_err_t err;
+
+ /* Retrieve Public Key */
+ err = grub_tpm2_protector_read_file (ctx->pkfile, &pub_key_bytes,
+ &pub_key_size);
+ if (err)
+ return grub_error (err, N_("Failed to read public key file %s"),
+ ctx->pkfile);
+
+ err = grub_tpm2_protector_unmarshal_pkfile (pub_key_bytes,
+ pub_key_size,
+ &pub_key);
+ if (err)
+ {
+ grub_error (err, N_("Failed to unmarshal public key, ensure the public "
+ "key file is in TPM wire format"));
+ goto exit1;
+ }
+
+ /* Retrieve Signed PCR Policy */
+ err = grub_tpm2_protector_read_file (ctx->sigfile, &sig_bytes,
+ &sig_size);
+ if (err)
+ {
+ grub_error (err, N_("Failed to read signed pcr policy file %s"),
+ ctx->sigfile);
+ goto exit1;
+ }
+
+ err = grub_tpm2_protector_unmarshal_sigfile (sig_bytes,
+ sig_size,
+ &signature);
+ if (err)
+ {
+ grub_error (err, N_("Failed to unmarshal signed PCR policy, ensure the signed "
+ "PCR policy file is in TPM wire format"));
+ goto exit1;
+ }
+
+ /* Retrieve Sealed Key */
+ err = grub_tpm2_protector_read_file (ctx->keyfile, &sealed_key_bytes,
+ &sealed_key_size);
+ if (err)
+ {
+ grub_error (err, N_("Failed to read key file %s"), ctx->keyfile);
+ goto exit1;
+ }
+
+ err = grub_tpm2_protector_unmarshal_keyfile (sealed_key_bytes,
+ sealed_key_size,
+ &sealed_key);
+ if (err)
+ {
+ grub_error (err, N_("Failed to unmarshal key, ensure the key file is in "
+ "TPM wire format"));
+ goto exit1;
+ }
+
+ /* Reproduce the policy signed by the public key */
+ err = grub_tpm2_protector_authpol_digest (ctx, &pcr_policy);
+ if (err)
+ {
+ grub_error (err, N_("Failed to get the policy digest"));
+ goto exit1;
+ }
+
+ /* Load the public key */
+ rc = TPM2_LoadExternal (NULL, NULL, &pub_key, TPM_RH_OWNER,
+ &pubkey_handle, &pubname, NULL);
+ if (rc)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to load public key (TPM2_LoadExternal failed "
+ "with TSS/TPM error %u)"), rc);
+ goto exit1;
+ }
+
+ /* Calculate the digest of the polcy for VerifySignature */
+ rc = TPM2_Hash (NULL, (TPM2B_MAX_BUFFER *)&pcr_policy, TPM_ALG_SHA256,
+ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL);
+ if (rc)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to create PCR policy hash (TPM2_Hash failed "
+ "with TSS/TPM error %u)"), rc);
+ goto exit2;
+ }
+
+ /* Verify the signature against the public key and the reproduced policy digest */
+ rc = TPM2_VerifySignature (pubkey_handle, NULL, &pcr_policy_hash, &signature,
+ &verification_ticket, NULL);
+ if (rc)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to verify signature (TPM2_VerifySignature "
+ "failed with TSS/TPM error %u)"), rc);
+ goto exit2;
+ }
+
+ /* Get the handle of the primary storage key */
+ err = grub_tpm2_protector_srk_get (ctx, &primary_handle);
+ if (err)
+ {
+ grub_error (err, N_("Failed to create primary"));
+ goto exit2;
+ }
+
+ /* Load Sealed Key */
+ /* Use the password session with an empty password */
+ grub_memset (&authCmd, 0, sizeof (authCmd));
+ authCmd.sessionHandle = TPM_RS_PW;
+ /* Load the sealed object into TPM */
+ rc = TPM2_Load (primary_handle, &authCmd, &sealed_key.private, &sealed_key.public,
+ &sealed_key_handle, NULL, NULL);
+ if (rc)
+ {
+ grub_error (err, N_("Failed to load sealed key (TPM2_Load failed with "
+ "TSS/TPM error %u)"), rc);
+ goto exit3;
+ }
+
+ /* Start a policy session to authorize the signed policy */
+ symmetric.algorithm = TPM_ALG_AES;
+ symmetric.keyBits.aes = 128;
+ symmetric.mode.aes = TPM_ALG_CFB;
+ nonceCaller.size = TPM_SHA256_DIGEST_SIZE;
+
+ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, NULL, &nonceCaller, NULL,
+ TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256,
+ &session, NULL, NULL);
+ if (rc)
+ {
+ grub_error (err, N_("Failed to start auth session (TPM2_StartAuthSession "
+ "failed with TSS/TPM error %u)"), rc);
+ goto exit4;
+ }
+
+ /* Send the PolicyPCR command to generate the policy digest based on the */
+ /* current PCR values */
+ rc = TPM2_PolicyPCR (session, NULL, NULL, &ctx->pcr_list, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to submit PCR policy (TPM2_PolicyPCR failed "
+ "with TSS/TPM error: 0x%u).\n"), rc);
+ goto exit5;
+ }
+
+ /* Authorize the signed policy with the public key and the verification ticket */
+ rc = TPM2_PolicyAuthorize (session, NULL, &pcr_policy, NULL, &pubname,
+ &verification_ticket, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to authorize PCR policy (TPM2_PolicyAuthorize "
+ "failed with TSS/TPM error: 0x%u).\n"), rc);
+ goto exit5;
+ }
+
+ /* Unseal the key with the policy session that authorizes the signed policy */
+ grub_memset (&authCmd, 0, sizeof (authCmd));
+ authCmd.sessionHandle = session;
+ rc = TPM2_Unseal (sealed_key_handle, &authCmd, &data, NULL);
+ if (rc != TPM_RC_SUCCESS)
+ {
+ err = GRUB_ERR_BAD_DEVICE;
+ grub_error (err, N_("Failed to unseal sealed key (TPM2_Unseal failed"
+ "with TSS/TPM error: 0x%u).\n"), rc);
+ grub_millisleep(500);
+ goto exit5;
+ }
+
+ /* Epilogue */
+ key_out = grub_malloc (data.size);
+ if (!key_out)
+ {
+ err = GRUB_ERR_OUT_OF_MEMORY;
+ grub_error (err, N_("No memory left to allocate unlock key buffer"));
+ goto exit4;
+ }
+
+ grub_printf("TPM2: unsealed %u bytes of key material\n", data.size);
+
+ if (ctx->efivar)
+ {
+ rc = grub_tpm2_protector_publish_key (data.buffer, data.size, ctx->efivar);
+ if (rc)
+ goto exit4;
+ }
+
+ grub_memcpy (key_out, data.buffer, data.size);
+
+ *key = key_out;
+ *key_size = data.size;
+
+ err = GRUB_ERR_NONE;
+
+exit5:
+ TPM2_FlushContext (session);
+
+exit4:
+ TPM2_FlushContext (sealed_key_handle);
+
+exit3:
+ TPM2_FlushContext (primary_handle);
+
+exit2:
+ TPM2_FlushContext (pubkey_handle);
+
+exit1:
+ grub_free (sealed_key_bytes);
+ grub_free (pub_key_bytes);
+ grub_free (sig_bytes);
+
+ return err;
+}
+
static grub_err_t
grub_tpm2_protector_recover (const struct grub_tpm2_protector_context *ctx,
grub_uint8_t **key, grub_size_t *key_size)
@@ -496,6 +1008,8 @@ grub_tpm2_protector_recover (const struct grub_tpm2_protector_context *ctx,
return grub_tpm2_protector_srk_recover (ctx, key, key_size);
case GRUB_TPM2_PROTECTOR_MODE_NV:
return grub_tpm2_protector_nv_recover (ctx, key, key_size);
+ case GRUB_TPM2_PROTECTOR_MODE_AUTHPOL:
+ return grub_tpm2_protector_authpol_recover (ctx, key, key_size);
default:
return GRUB_ERR_BAD_ARGUMENT;
}
@@ -543,7 +1057,10 @@ initialize_pcr_list (struct grub_tpm2_protector_context *ctx)
static grub_err_t
grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx)
{
- if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_UNSET)
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_UNSET && ctx->keyfile &&
+ ctx->pkfile && ctx->sigfile)
+ ctx->mode = GRUB_TPM2_PROTECTOR_MODE_AUTHPOL;
+ else if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_UNSET)
ctx->mode = GRUB_TPM2_PROTECTOR_MODE_SRK;
/* Checks for SRK mode */
@@ -556,6 +1073,14 @@ grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("In SRK mode, an NV Index cannot be specified"));
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->pkfile)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In SRK mode, an a public key cannot be specified"));
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->sigfile)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In SRK mode, an a signed pcr policy cannot be specified"));
+
/* Checks for NV mode */
if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && !ctx->nv)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
@@ -575,6 +1100,34 @@ grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx)
N_("In NV Index mode, an asymmetric key type cannot be "
"specified"));
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->pkfile)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In NV Index mode, an a public key cannot be specified"));
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->sigfile)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In NV Index mode, an a signed pcr policy cannot be specified"));
+
+ /* Checks for Authorized Policy mode */
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_AUTHPOL && !ctx->keyfile)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In Authorized Policy mode, a key file must be specified: "
+ "--keyfile or -k"));
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_AUTHPOL && !ctx->pkfile)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In Authorized Policy mode, a public key file must be specified: "
+ "--pkfile or -P"));
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_AUTHPOL && !ctx->sigfile)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In Authorized Policy mode, a signed pcr file must be specified: "
+ "--sigfile or -S"));
+
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_AUTHPOL && ctx->nv)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("In Authorized Policy mode, an NV Index cannot be specified"));
+
/* Defaults assignment */
if (!ctx->bank)
ctx->bank = TPM_ALG_SHA256;
@@ -585,7 +1138,8 @@ grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx)
ctx->pcr_count = 1;
}
- if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK)
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK ||
+ ctx->mode == GRUB_TPM2_PROTECTOR_MODE_AUTHPOL)
{
if (!ctx->srk)
ctx->srk = TPM2_SRK_HANDLE;
@@ -619,6 +1173,18 @@ grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile)
return grub_tpm2_protector_parse_string (value, keyfile, "keyfile");
}
+static grub_err_t
+grub_tpm2_protector_parse_pkfile (const char *value, const char **pkfile)
+{
+ return grub_tpm2_protector_parse_string (value, pkfile, "pkfile");
+}
+
+static grub_err_t
+grub_tpm2_protector_parse_sigfile (const char *value, const char **sigfile)
+{
+ return grub_tpm2_protector_parse_string (value, sigfile, "sigfile");
+}
+
static grub_err_t
grub_tpm2_protector_parse_efivar (const char *value, const char **efivar)
{
@@ -633,6 +1199,8 @@ grub_tpm2_protector_parse_mode (const char *value,
*mode = GRUB_TPM2_PROTECTOR_MODE_SRK;
else if (grub_strcmp (value, "nv") == 0)
*mode = GRUB_TPM2_PROTECTOR_MODE_NV;
+ else if (grub_strcmp (value, "authpol") == 0)
+ *mode = GRUB_TPM2_PROTECTOR_MODE_AUTHPOL;
else
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("Value '%s' is not a valid TPM2 key protector mode"),
@@ -722,6 +1290,22 @@ grub_tpm2_protector_init_cmd_handler (grub_extcmd_context_t ctxt, int argc,
return err;
}
+ if (state[8].set) /* pkfile */
+ {
+ err = grub_tpm2_protector_parse_pkfile (state[8].arg,
+ &grub_tpm2_protector_ctx.pkfile);
+ if (err)
+ return err;
+ }
+
+ if (state[9].set) /* sigfile */
+ {
+ err = grub_tpm2_protector_parse_sigfile (state[9].arg,
+ &grub_tpm2_protector_ctx.sigfile);
+ if (err)
+ return err;
+ }
+
err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx);
/* This command only initializes the protector, so nothing else to do. */
@@ -739,6 +1323,8 @@ grub_tpm2_protector_clear_cmd_handler (grub_extcmd_context_t ctxt __attribute__
N_("tpm2_key_protector_clear accepts no arguments"));
grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
+ grub_free ((void *) grub_tpm2_protector_ctx.pkfile);
+ grub_free ((void *) grub_tpm2_protector_ctx.sigfile);
grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx));
return GRUB_ERR_NONE;
@@ -761,7 +1347,9 @@ GRUB_MOD_INIT (tpm2)
"[-k sealed_key_file_path] "
"[-s srk_handle] "
"[-a asymmetric_key_type] "
- "[-n nv_index]"),
+ "[-n nv_index] "
+ "[-P public_key_file_path] "
+ "[-S signature_file_path]"),
N_("Initialize the TPM2 key protector."),
grub_tpm2_protector_init_cmd_options);
grub_tpm2_protector_clear_cmd =
@@ -775,6 +1363,8 @@ GRUB_MOD_INIT (tpm2)
GRUB_MOD_FINI (tpm2)
{
grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
+ grub_free ((void *) grub_tpm2_protector_ctx.pkfile);
+ grub_free ((void *) grub_tpm2_protector_ctx.sigfile);
grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx));
grub_key_protector_unregister (&grub_tpm2_key_protector);
--
2.35.3

View File

@ -1,38 +0,0 @@
---
grub-core/Makefile.core.def | 1 +
grub-core/tpm2/module.c | 2 +-
util/grub-protect.c | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2569,6 +2569,7 @@
common = tpm2/mu.c;
common = tpm2/tpm2.c;
efi = tpm2/tcg2.c;
+ enable = efi;
};
module = {
--- a/util/grub-protect.c
+++ b/util/grub-protect.c
@@ -542,7 +542,7 @@
if (pcr_values.digests[i].size != pcr_digest_len)
{
fprintf (stderr,
- _("Bad PCR value size: expected %lu bytes but got %u bytes.\n"),
+ _("Bad PCR value size: expected %" PRIuGRUB_SIZE " bytes but got %u bytes.\n"),
pcr_digest_len, pcr_values.digests[i].size);
goto exit2;
}
--- a/grub-core/tpm2/module.c
+++ b/grub-core/tpm2/module.c
@@ -195,7 +195,7 @@
if (sealed_key_size > buf.cap)
{
grub_dprintf ("tpm2", "Sealed key file is larger than decode buffer "
- "(%lu vs %lu bytes).\n", sealed_key_size, buf.cap);
+ "(%" PRIuGRUB_SIZE " vs %" PRIuGRUB_SIZE " bytes).\n", sealed_key_size, buf.cap);
return GRUB_ERR_BAD_ARGUMENT;
}

View File

@ -42,7 +42,7 @@ Index: grub-2.06/grub-core/commands/efi/tpm.c
+ pcr = &o->pcrSelections[o->count++];
+ pcr->hash = algo;
+ pcr->sizeOfSelect = 3;
+ pcr->pcrSelect[TPM2_PCR_TO_SELECT(pcrIndex)] |= TPM2_PCR_TO_BIT(pcrIndex);
+ TPMS_PCR_SELECTION_SelectPCR (pcr, pcrIndex);
+}
+
+struct grub_tpm_hash_info {

View File

@ -1,41 +0,0 @@
Index: grub-2.06/grub-core/tpm2/module.c
===================================================================
--- grub-2.06.orig/grub-core/tpm2/module.c
+++ grub-2.06/grub-core/tpm2/module.c
@@ -22,6 +22,7 @@
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/protector.h>
+#include <grub/time.h>
#include <grub/tpm2/buffer.h>
#include <grub/tpm2/internal/args.h>
#include <grub/tpm2/mu.h>
@@ -449,6 +450,7 @@ grub_tpm2_protector_srk_recover (const s
{
grub_error (err, N_("Failed to unseal sealed key (TPM2_Unseal failed "
"with TSS/TPM error %u)"), rc);
+ grub_millisleep(500);
goto exit4;
}
@@ -461,6 +463,8 @@ grub_tpm2_protector_srk_recover (const s
goto exit4;
}
+ grub_printf("TPM2: unsealed %u bytes of key material\n", data.size);
+
if (ctx->efivar)
{
rc = grub_tpm2_protector_publish_key (data.buffer, data.size, ctx->efivar);
Index: grub-2.06/grub-core/loader/linux.c
===================================================================
--- grub-2.06.orig/grub-core/loader/linux.c
+++ grub-2.06/grub-core/loader/linux.c
@@ -171,6 +171,7 @@ grub_initrd_component (const char *buf,
struct grub_linux_initrd_component *comp = initrd_ctx->components + initrd_ctx->nfiles;
grub_size_t dir_size, name_len;
+ grub_printf("Creating initrd component \"%s\" with %u bytes\n", newc_name, bufsz);
while (*newc_name == '/')
newc_name++;

View File

@ -1,3 +1,46 @@
-------------------------------------------------------------------
Fri Apr 21 07:53:30 UTC 2023 - Gary Ching-Pang Lin <glin@suse.com>
- Update TPM 2.0 key unsealing patches
* Add the new upstreaming patches
0001-protectors-Add-key-protectors-framework.patch
0002-tpm2-Add-TPM-Software-Stack-TSS.patch
0003-protectors-Add-TPM2-Key-Protector.patch
0004-cryptodisk-Support-key-protectors.patch
0005-util-grub-protect-Add-new-tool.patch
* Add the authorized policy patches based on the upstreaming
patches
0001-tpm2-Add-TPM2-types-structures-and-command-constants.patch
0002-tpm2-Add-more-marshal-unmarshal-functions.patch
0003-tpm2-Implement-more-TPM2-commands.patch
0004-tpm2-Support-authorized-policy.patch
* Drop the old patches
0010-protectors-Add-key-protectors-framework.patch
0011-tpm2-Add-TPM-Software-Stack-TSS.patch
0012-protectors-Add-TPM2-Key-Protector.patch
0013-cryptodisk-Support-key-protectors.patch
0014-util-grub-protect-Add-new-tool.patch
fix-tpm2-build.patch
tpm-protector-dont-measure-sealed-key.patch
tpm-protector-export-secret-key.patch
grub-unseal-debug.patch
0001-tpm2-adjust-the-input-parameters-of-TPM2_EvictContro.patch
0002-tpm2-declare-the-input-arguments-of-TPM2-functions-a.patch
0003-tpm2-resend-the-command-on-TPM_RC_RETRY.patch
0004-tpm2-add-new-TPM2-types-structures-and-command-const.patch
0005-tpm2-add-more-marshal-unmarshal-functions.patch
0006-tpm2-check-the-command-parameters-of-TPM2-commands.patch
0007-tpm2-pack-the-missing-authorization-command-for-TPM2.patch
0008-tpm2-allow-some-command-parameters-to-be-NULL.patch
0009-tpm2-remove-the-unnecessary-variables.patch
0010-tpm2-add-TPM2-commands-to-support-authorized-policy.patch
0011-tpm2-make-the-file-reading-unmarshal-functions-gener.patch
0012-tpm2-initialize-the-PCR-selection-list-early.patch
0013-tpm2-support-unsealing-key-with-authorized-policy.patch
* Refresh grub-read-pcr.patch
* Introduce a new build requirement: libtasn1-devel
- Only package grub2-protect for the architectures with EFI support
-------------------------------------------------------------------
Fri Apr 21 04:53:54 UTC 2023 - Michael Chang <mchang@suse.com>

View File

@ -48,6 +48,7 @@ BuildRequires: dejavu-fonts
BuildRequires: gnu-unifont
%endif
BuildRequires: help2man
BuildRequires: libtasn1-devel
BuildRequires: xz
%if 0%{?suse_version} >= 1210
BuildRequires: makeinfo
@ -413,13 +414,15 @@ Patch890: 0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch
Patch891: 0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch
Patch892: 0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch
Patch893: 0009-cryptodisk-Improve-handling-of-partition-name-in-cry.patch
Patch894: 0010-protectors-Add-key-protectors-framework.patch
Patch895: 0011-tpm2-Add-TPM-Software-Stack-TSS.patch
Patch896: 0012-protectors-Add-TPM2-Key-Protector.patch
Patch897: 0013-cryptodisk-Support-key-protectors.patch
Patch898: 0014-util-grub-protect-Add-new-tool.patch
Patch899: fix-tpm2-build.patch
Patch900: 0001-crytodisk-fix-cryptodisk-module-looking-up.patch
# TPM 2.0 protector
Patch894: 0001-protectors-Add-key-protectors-framework.patch
Patch895: 0002-tpm2-Add-TPM-Software-Stack-TSS.patch
Patch896: 0003-protectors-Add-TPM2-Key-Protector.patch
Patch897: 0004-cryptodisk-Support-key-protectors.patch
Patch898: 0005-util-grub-protect-Add-new-tool.patch
Patch899: 0001-crytodisk-fix-cryptodisk-module-looking-up.patch
# fde
Patch901: 0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch
Patch902: 0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch
@ -434,10 +437,8 @@ Patch910: 0010-templates-import-etc-crypttab-to-grub.cfg.patch
Patch911: grub-read-pcr.patch
Patch912: efi-set-variable-with-attrs.patch
Patch913: tpm-record-pcrs.patch
Patch914: tpm-protector-dont-measure-sealed-key.patch
Patch915: tpm-protector-export-secret-key.patch
Patch916: grub-install-record-pcrs.patch
Patch917: grub-unseal-debug.patch
# efi mm
Patch919: 0001-mm-Allow-dynamically-requesting-additional-memory-re.patch
Patch920: 0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch
@ -480,19 +481,13 @@ Patch953: grub2-increase-crypttab-path-buffer.patch
Patch954: 0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch
Patch955: 0001-grub-core-modify-sector-by-sysfs-as-disk-sector.patch
Patch956: 0001-grub2-Can-t-setup-a-default-boot-device-correctly-on.patch
Patch957: 0001-tpm2-adjust-the-input-parameters-of-TPM2_EvictContro.patch
Patch958: 0002-tpm2-declare-the-input-arguments-of-TPM2-functions-a.patch
Patch959: 0003-tpm2-resend-the-command-on-TPM_RC_RETRY.patch
Patch960: 0004-tpm2-add-new-TPM2-types-structures-and-command-const.patch
Patch961: 0005-tpm2-add-more-marshal-unmarshal-functions.patch
Patch962: 0006-tpm2-check-the-command-parameters-of-TPM2-commands.patch
Patch963: 0007-tpm2-pack-the-missing-authorization-command-for-TPM2.patch
Patch964: 0008-tpm2-allow-some-command-parameters-to-be-NULL.patch
Patch965: 0009-tpm2-remove-the-unnecessary-variables.patch
Patch966: 0010-tpm2-add-TPM2-commands-to-support-authorized-policy.patch
Patch967: 0011-tpm2-make-the-file-reading-unmarshal-functions-gener.patch
Patch968: 0012-tpm2-initialize-the-PCR-selection-list-early.patch
Patch969: 0013-tpm2-support-unsealing-key-with-authorized-policy.patch
# Support TPM 2.0 Authorized Policy
Patch957: 0001-tpm2-Add-TPM2-types-structures-and-command-constants.patch
Patch958: 0002-tpm2-Add-more-marshal-unmarshal-functions.patch
Patch959: 0003-tpm2-Implement-more-TPM2-commands.patch
Patch960: 0004-tpm2-Support-authorized-policy.patch
# Set efi variables LoaderDevicePartUUID & LoaderInfo (needed for UKI)
Patch970: grub2-add-module-for-boot-loader-interface.patch
# Fix out of memory error on lpar installation from virtual cdrom (bsc#1208024)
@ -1415,7 +1410,9 @@ fi
%{_bindir}/%{name}-render-label
%{_bindir}/%{name}-script-check
%{_bindir}/%{name}-syslinux2cfg
%ifarch %{efi}
%{_bindir}/%{name}-protect
%endif
%if 0%{?has_systemd:1}
%{_unitdir}/grub2-once.service
%endif

View File

@ -1,15 +0,0 @@
Index: grub-2.06/grub-core/tpm2/module.c
===================================================================
--- grub-2.06.orig/grub-core/tpm2/module.c
+++ grub-2.06/grub-core/tpm2/module.c
@@ -139,7 +139,9 @@ grub_tpm2_protector_srk_read_keyfile (co
void *sealed_key_buffer;
grub_off_t sealed_key_read;
- sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_NONE);
+ /* Using GRUB_FILE_TYPE_SIGNATURE ensures we do not hash the keyfile into PCR9
+ * otherwise we'll never be able to predict the value of PCR9 at unseal time */
+ sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_SIGNATURE);
if (!sealed_key_file)
{
grub_dprintf ("tpm2", "Could not open sealed key file.\n");

View File

@ -1,138 +0,0 @@
Index: grub-2.06/grub-core/tpm2/module.c
===================================================================
--- grub-2.06.orig/grub-core/tpm2/module.c
+++ grub-2.06/grub-core/tpm2/module.c
@@ -26,6 +26,7 @@
#include <grub/tpm2/internal/args.h>
#include <grub/tpm2/mu.h>
#include <grub/tpm2/tpm2.h>
+#include <grub/efi/efi.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -46,6 +47,7 @@ struct grub_tpm2_protector_context
const char *keyfile;
TPM_HANDLE srk;
TPM_HANDLE nv;
+ const char *efivar;
};
static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
@@ -122,6 +124,16 @@ static const struct grub_arg_option grub
N_("Required in NV Index mode, the NV handle to read which must "
"readily exist on the TPM and which contains the key."),
},
+ /* When publishing the unsealed key to a UEFI variable */
+ {
+ .longarg = "efivar",
+ .shortarg = 'E',
+ .flags = 0,
+ .arg = NULL,
+ .type = ARG_TYPE_STRING,
+ .doc =
+ N_("Publish the unsealed key to the indicated UEFI variable."),
+ },
/* End of list */
{0, 0, 0, 0, 0, 0}
};
@@ -302,6 +314,34 @@ grub_tpm2_protector_srk_get (const struc
}
static grub_err_t
+grub_tpm2_protector_publish_key (grub_uint8_t *key, grub_size_t key_size,
+ const char *var_name)
+{
+ grub_efi_guid_t vendor_guid = { 0x58aca851, 0x8af7, 0x4738, { 0xa5, 0x42, 0x26, 0x6e, 0x21, 0xf5, 0xca, 0xd9 }};
+ grub_uint8_t *tmp_key;
+ grub_err_t err;
+
+ /* It appears that EFI's set_var function overwrites the key. */
+ tmp_key = grub_malloc (key_size);
+ if (!tmp_key)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("No memory left to allocate temporary key buffer"));
+ return GRUB_ERR_OUT_OF_MEMORY;
+ }
+
+ grub_memcpy(tmp_key, key, key_size);
+
+ err = grub_efi_set_variable_with_attributes(var_name, &vendor_guid,
+ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_RUNTIME_ACCESS,
+ tmp_key, key_size);
+ if (err)
+ grub_error (err, N_("Failed to export LUKS key as EFI variable %s"), var_name);
+
+ grub_free (tmp_key);
+ return err;
+}
+
+static grub_err_t
grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
grub_uint8_t **key, grub_size_t *key_size)
{
@@ -421,6 +461,13 @@ grub_tpm2_protector_srk_recover (const s
goto exit4;
}
+ if (ctx->efivar)
+ {
+ rc = grub_tpm2_protector_publish_key (data.buffer, data.size, ctx->efivar);
+ if (rc)
+ goto exit4;
+ }
+
grub_memcpy (key_out, data.buffer, data.size);
*key = key_out;
@@ -549,20 +596,32 @@ grub_tpm2_protector_check_args (struct g
}
static grub_err_t
-grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile)
+grub_tpm2_protector_parse_string (const char *value, const char **var, const char *arg_name)
{
if (grub_strlen (value) == 0)
return GRUB_ERR_BAD_ARGUMENT;
- *keyfile = grub_strdup (value);
- if (!*keyfile)
+ *var = grub_strdup (value);
+ if (!*var)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
- N_("No memory to duplicate keyfile path"));
+ N_("No memory to duplicate %s argument"), arg_name);
return GRUB_ERR_NONE;
}
static grub_err_t
+grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile)
+{
+ return grub_tpm2_protector_parse_string (value, keyfile, "keyfile");
+}
+
+static grub_err_t
+grub_tpm2_protector_parse_efivar (const char *value, const char **efivar)
+{
+ return grub_tpm2_protector_parse_string (value, efivar, "efivar");
+}
+
+static grub_err_t
grub_tpm2_protector_parse_mode (const char *value,
grub_tpm2_protector_mode_t *mode)
{
@@ -650,6 +709,14 @@ grub_tpm2_protector_init_cmd_handler (gr
if (err)
return err;
}
+
+ if (state[7].set) /* efivar */
+ {
+ err = grub_tpm2_protector_parse_efivar (state[7].arg,
+ &grub_tpm2_protector_ctx.efivar);
+ if (err)
+ return err;
+ }
err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx);