Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package grub2 for openSUSE:Factory checked in at 2023-02-10 14:33:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/grub2 (Old) and /work/SRC/openSUSE:Factory/.grub2.new.1848 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "grub2" Fri Feb 10 14:33:37 2023 rev:282 rq:1063963 version:2.06 Changes: -------- --- /work/SRC/openSUSE:Factory/grub2/grub2.changes 2023-02-08 17:19:59.357853663 +0100 +++ /work/SRC/openSUSE:Factory/.grub2.new.1848/grub2.changes 2023-02-10 14:33:38.189316823 +0100 @@ -1,0 +2,19 @@ +Thu Feb 9 08:42:26 UTC 2023 - Gary Ching-Pang Lin <[email protected]> + +- Amend the TPM2 stack and add authorized policy mode to + tpm2_key_protector + * 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 + +------------------------------------------------------------------- New: ---- 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 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ grub2.spec ++++++ --- /var/tmp/diff_new_pack.4U91Pl/_old 2023-02-10 14:33:40.521330758 +0100 +++ /var/tmp/diff_new_pack.4U91Pl/_new 2023-02-10 14:33:40.525330782 +0100 @@ -480,6 +480,19 @@ 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 Requires: gettext-runtime %if 0%{?suse_version} >= 1140 ++++++ 0001-tpm2-adjust-the-input-parameters-of-TPM2_EvictContro.patch ++++++ >From bc5ecda21bb612f786f614623da782d7ad6d8325 Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> 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 <[email protected]> --- 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 ++++++ 0002-tpm2-declare-the-input-arguments-of-TPM2-functions-a.patch ++++++ ++++ 697 lines (skipped) ++++++ 0003-tpm2-resend-the-command-on-TPM_RC_RETRY.patch ++++++ >From 14a8c03f1a3b09250ea933f1a072dfdfef8c4a48 Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> 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 <[email protected]> --- 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..1176d968b 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 (err != 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 ++++++ 0004-tpm2-add-new-TPM2-types-structures-and-command-const.patch ++++++ >From 69a5cedcb206ca931ac2c2763c283954751d7072 Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> Date: Tue, 7 Feb 2023 18:31:12 +0800 Subject: [PATCH 04/13] tpm2: add new TPM2 types, structures, and command constants Add new TPM2 types and structures as the preparation to support the authorized policy. * New types: TPM_ALG_ECDAA, TPM_ALG_ECDSA, TPM_ALG_ECSCHNORR, TPM_ALG_RSASSA, TPM_ALG_RSAPSS, TPM_ALG_SM2, and TPMI_ALG_SIG_SCHEME * New structures: TPMS_EMPTY, TPMS_SIGNATURE_RSA, TPMS_SIGNATURE_ECC, TPMS_SIGNATURE_ECDSA, TPMS_SIGNATURE_ECDAA, TPMS_SIGNATURE_SM2, TPMS_SIGNATURE_ECSCHNORR, TPMU_SIGNATURE, and TPMT_TK_VERIFIED * New command constants: TPM_CC_LoadExternal, TPM_CC_HashSequenceStart, TPM_CC_SequenceUpdate, TPM_CC_SequenceComplete, TPM_CC_VerifySignature, TPM_CC_PolicyAuthorize Signed-off-by: Gary Lin <[email protected]> --- include/grub/tpm2/internal/structs.h | 60 ++++++++++++++++++++++++++++ include/grub/tpm2/internal/types.h | 42 ++++++++++++------- 2 files changed, 88 insertions(+), 14 deletions(-) diff --git a/include/grub/tpm2/internal/structs.h b/include/grub/tpm2/internal/structs.h index 75bf99ec8..50090892c 100644 --- a/include/grub/tpm2/internal/structs.h +++ b/include/grub/tpm2/internal/structs.h @@ -672,4 +672,64 @@ struct TPMT_TK_CREATION }; typedef struct TPMT_TK_CREATION TPMT_TK_CREATION; +/* TPMS_EMPTY Structure */ +struct TPMS_EMPTY { + grub_uint8_t empty[1]; /* a structure with no member */ +}; +typedef struct TPMS_EMPTY TPMS_EMPTY; + +/* TPMS_SIGNATURE_RSA Structure */ +struct TPMS_SIGNATURE_RSA { + TPMI_ALG_HASH hash; + TPM2B_PUBLIC_KEY_RSA sig; +}; +typedef struct TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSA; + +/* Definition of Types for RSA Signature */ +typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSASSA; +typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSAPSS; + +/* TPMS_SIGNATURE_ECC Structure */ +struct TPMS_SIGNATURE_ECC { + TPMI_ALG_HASH hash; + TPM2B_ECC_PARAMETER signatureR; + TPM2B_ECC_PARAMETER signatureS; +}; +typedef struct TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECC; + +/* Definition of Types for ECC TPMS_SIGNATURE_ECC */ +typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDSA; +typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDAA; +typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_SM2; +typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECSCHNORR; + +/* TPMU_SIGNATURE Structure */ +union TPMU_SIGNATURE { + TPMS_SIGNATURE_RSASSA rsassa; + TPMS_SIGNATURE_RSAPSS rsapss; + TPMS_SIGNATURE_ECDSA ecdsa; + TPMS_SIGNATURE_ECDAA ecdaa; + TPMS_SIGNATURE_SM2 sm2; + TPMS_SIGNATURE_ECSCHNORR ecschnorr; + TPMT_HA hmac; + TPMS_SCHEME_HASH any; + TPMS_EMPTY null; +}; +typedef union TPMU_SIGNATURE TPMU_SIGNATURE; + +/* TPMT_SIGNATURE Structure */ +struct TPMT_SIGNATURE { + TPMI_ALG_SIG_SCHEME sigAlg; + TPMU_SIGNATURE signature; +}; +typedef struct TPMT_SIGNATURE TPMT_SIGNATURE; + +/* TPMT_TK_VERIFIED Structure */ +struct TPMT_TK_VERIFIED { + TPM_ST tag; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_DIGEST digest; +}; +typedef struct TPMT_TK_VERIFIED TPMT_TK_VERIFIED; + #endif /* ! GRUB_TPM2_INTERNAL_STRUCTS_HEADER */ diff --git a/include/grub/tpm2/internal/types.h b/include/grub/tpm2/internal/types.h index 9714f75d4..a1902ef0c 100644 --- a/include/grub/tpm2/internal/types.h +++ b/include/grub/tpm2/internal/types.h @@ -181,6 +181,9 @@ typedef grub_uint16_t TPM_ALG_ID; #define TPM_ALG_CFB ((TPM_ALG_ID) 0x0043) #define TPM_ALG_ECB ((TPM_ALG_ID) 0x0044) #define TPM_ALG_ECC ((TPM_ALG_ID) 0x0023) +#define TPM_ALG_ECDAA ((TPM_ALG_ID) 0x001A) +#define TPM_ALG_ECDSA ((TPM_ALG_ID) 0x0018) +#define TPM_ALG_ECSCHNORR ((TPM_ALG_ID) 0x001C) #define TPM_ALG_HMAC ((TPM_ALG_ID) 0x0005) #define TPM_ALG_KDF1_SP800_108 ((TPM_ALG_ID) 0x0022) #define TPM_ALG_KDF1_SP800_56A ((TPM_ALG_ID) 0x0020) @@ -189,10 +192,13 @@ typedef grub_uint16_t TPM_ALG_ID; #define TPM_ALG_MGF1 ((TPM_ALG_ID) 0x0007) #define TPM_ALG_NULL ((TPM_ALG_ID) 0x0010) #define TPM_ALG_RSA ((TPM_ALG_ID) 0x0001) +#define TPM_ALG_RSASSA ((TPM_ALG_ID) 0x0014) +#define TPM_ALG_RSAPSS ((TPM_ALG_ID) 0x0016) #define TPM_ALG_SHA1 ((TPM_ALG_ID) 0x0004) #define TPM_ALG_SHA256 ((TPM_ALG_ID) 0x000B) #define TPM_ALG_SHA384 ((TPM_ALG_ID) 0x000C) #define TPM_ALG_SHA512 ((TPM_ALG_ID) 0x000D) +#define TPM_ALG_SM2 ((TPM_ALG_ID) 0x001B) #define TPM_ALG_SM3_256 ((TPM_ALG_ID) 0x0012) #define TPM_ALG_SM4 ((TPM_ALG_ID) 0x0013) #define TPM_ALG_SYMCIPHER ((TPM_ALG_ID) 0x0025) @@ -299,20 +305,27 @@ typedef grub_uint16_t TPM2_ECC_CURVE; /* TPM_CC Constants */ typedef grub_uint32_t TPM_CC; -#define TPM_CC_EvictControl ((TPM_CC) 0x00000120) -#define TPM_CC_CreatePrimary ((TPM_CC) 0x00000131) -#define TPM_CC_Create ((TPM_CC) 0x00000153) -#define TPM_CC_FlushContext ((TPM_CC) 0x00000165) -#define TPM_CC_ReadPublic ((TPM_CC) 0x00000173) -#define TPM_CC_StartAuthSession ((TPM_CC) 0x00000176) -#define TPM_CC_PolicyPCR ((TPM_CC) 0x0000017f) -#define TPM_CC_NV_Read ((TPM_CC) 0x0000014e) -#define TPM_CC_NV_ReadPublic ((TPM_CC) 0x00000169) -#define TPM_CC_GetCapability ((TPM_CC) 0x0000017a) -#define TPM_CC_PCR_Read ((TPM_CC) 0x0000017e) -#define TPM_CC_Load ((TPM_CC) 0x00000157) -#define TPM_CC_Unseal ((TPM_CC) 0x0000015e) -#define TPM_CC_PolicyGetDigest ((TPM_CC) 0x00000189) +#define TPM_CC_EvictControl ((TPM_CC) 0x00000120) +#define TPM_CC_CreatePrimary ((TPM_CC) 0x00000131) +#define TPM_CC_Create ((TPM_CC) 0x00000153) +#define TPM_CC_FlushContext ((TPM_CC) 0x00000165) +#define TPM_CC_ReadPublic ((TPM_CC) 0x00000173) +#define TPM_CC_StartAuthSession ((TPM_CC) 0x00000176) +#define TPM_CC_PolicyPCR ((TPM_CC) 0x0000017f) +#define TPM_CC_NV_Read ((TPM_CC) 0x0000014e) +#define TPM_CC_NV_ReadPublic ((TPM_CC) 0x00000169) +#define TPM_CC_GetCapability ((TPM_CC) 0x0000017a) +#define TPM_CC_PCR_Read ((TPM_CC) 0x0000017e) +#define TPM_CC_Load ((TPM_CC) 0x00000157) +#define TPM_CC_LoadExternal ((TPM_CC) 0x00000167) +#define TPM_CC_Unseal ((TPM_CC) 0x0000015e) +#define TPM_CC_PolicyGetDigest ((TPM_CC) 0x00000189) +#define TPM_CC_HashSequenceStart ((TPM_CC) 0x00000186) +#define TPM_CC_SequenceUpdate ((TPM_CC) 0x0000015c) +#define TPM_CC_SequenceComplete ((TPM_CC) 0x0000013e) +#define TPM_CC_Hash ((TPM_CC) 0x0000017d) +#define TPM_CC_VerifySignature ((TPM_CC) 0x00000177) +#define TPM_CC_PolicyAuthorize ((TPM_CC) 0x0000016a) /* Hash algorithm sizes */ #define TPM_SHA1_DIGEST_SIZE 20 @@ -354,6 +367,7 @@ typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME; typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME; typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME; typedef TPM_ALG_ID TPMI_ALG_SYM; +typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME; /* TPM_KEY_BITS Type */ typedef grub_uint16_t TPM_KEY_BITS; -- 2.35.3 ++++++ 0005-tpm2-add-more-marshal-unmarshal-functions.patch ++++++ >From ac5c47af318652a25df1788c73884e4e9b6e4ac1 Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> Date: Tue, 7 Feb 2023 18:33:42 +0800 Subject: [PATCH 05/13] tpm2: add more marshal/unmarshal functions Add a few more marshal/unmarshal functions to support authorized policy. * Marshal: grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal() grub_tpm2_mu_TPMT_SENSITIVE_Marshal() grub_tpm2_mu_TPM2B_SENSITIVE_Marshal() grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal() grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal() grub_tpm2_mu_TPMU_HA_Marshal() grub_tpm2_mu_TPMT_HA_Marshal() grub_tpm2_mu_TPMU_SIGNATURE_Marshal() grub_tpm2_mu_TPMT_SIGNATURE_Marshal() grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal() * Unmarshal: grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal() grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal() grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal() grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal() grub_tpm2_mu_TPMU_HA_Unmarshal() grub_tpm2_mu_TPMT_HA_Unmarshal() grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal() grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal() Signed-off-by: Gary Lin <[email protected]> --- grub-core/tpm2/mu.c | 262 +++++++++++++++++++++++++++++++++++++++++ include/grub/tpm2/mu.h | 75 ++++++++++++ 2 files changed, 337 insertions(+) diff --git a/grub-core/tpm2/mu.c b/grub-core/tpm2/mu.c index 6d3294c5b..150a8d37d 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, grub_tpm2_mu_TPM2B_Marshal (buffer, p->data.size, p->data.buffer); } +void +grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer, + const TPMI_ALG_PUBLIC type, + const TPMU_SENSITIVE_COMPOSITE *p) +{ + switch(type) + { + case TPM_ALG_RSA: + grub_tpm2_mu_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer); + break; + case TPM_ALG_ECC: + grub_tpm2_mu_TPM2B_Marshal (buffer, p->ecc.size, p->ecc.buffer); + break; + case TPM_ALG_KEYEDHASH: + grub_tpm2_mu_TPM2B_Marshal (buffer, p->bits.size, p->bits.buffer); + break; + case TPM_ALG_SYMCIPHER: + grub_tpm2_mu_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer); + break; + default: + buffer->error = 1; + } +} + +void +grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, + const TPMT_SENSITIVE *p) +{ + grub_tpm2_buffer_pack_u16 (buffer, p->sensitiveType); + grub_tpm2_mu_TPM2B_Marshal (buffer, p->authValue.size, p->authValue.buffer); + grub_tpm2_mu_TPM2B_Marshal (buffer, p->seedValue.size, p->seedValue.buffer); + grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (buffer, p->sensitiveType, + &p->sensitive); +} + +void +grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, + const TPM2B_SENSITIVE *p) +{ + grub_tpm2_buffer_pack_u16 (buffer, p->size); + grub_tpm2_mu_TPMT_SENSITIVE_Marshal (buffer, &p->sensitiveArea); +} + void grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, 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); } +void +grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer, + const TPMS_SIGNATURE_RSA *p) +{ + grub_tpm2_buffer_pack_u16 (buffer, p->hash); + grub_tpm2_mu_TPM2B_Marshal (buffer, p->sig.size, p->sig.buffer); +} + +void +grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer, + const TPMS_SIGNATURE_ECC *p) +{ + grub_tpm2_buffer_pack_u16 (buffer, p->hash); + grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureR.size, p->signatureR.buffer); + grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureS.size, p->signatureS.buffer); +} + +void +grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer, + const TPMI_ALG_HASH hashAlg, + const TPMU_HA *p) +{ + switch (hashAlg) + { + case TPM_ALG_SHA1: + for (grub_uint16_t i = 0; i < TPM_SHA1_DIGEST_SIZE; i++) + grub_tpm2_buffer_pack_u8 (buffer, p->sha1[i]); + break; + case TPM_ALG_SHA256: + for (grub_uint16_t i = 0; i < TPM_SHA256_DIGEST_SIZE; i++) + grub_tpm2_buffer_pack_u8 (buffer, p->sha256[i]); + break; + case TPM_ALG_SHA384: + for (grub_uint16_t i = 0; i < TPM_SHA384_DIGEST_SIZE; i++) + grub_tpm2_buffer_pack_u8 (buffer, p->sha384[i]); + break; + case TPM_ALG_SHA512: + for (grub_uint16_t i = 0; i < TPM_SHA512_DIGEST_SIZE; i++) + grub_tpm2_buffer_pack_u8 (buffer, p->sha512[i]); + break; + default: + buffer->error = 1; + break; + } +} + +void +grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer, + const TPMT_HA *p) +{ + grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); + grub_tpm2_mu_TPMU_HA_Marshal (buffer, p->hashAlg, &p->digest); +} + +void +grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, + const TPMI_ALG_SIG_SCHEME sigAlg, + const TPMU_SIGNATURE *p) +{ + switch (sigAlg) + { + case TPM_ALG_RSASSA: + grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsassa); + break; + case TPM_ALG_RSAPSS: + grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsapss); + break; + case TPM_ALG_ECDSA: + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdsa); + break; + case TPM_ALG_ECDAA: + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdaa); + break; + case TPM_ALG_SM2: + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->sm2); + break; + case TPM_ALG_ECSCHNORR: + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecschnorr); + break; + case TPM_ALG_HMAC: + grub_tpm2_mu_TPMT_HA_Marshal (buffer, &p->hmac); + break; + case TPM_ALG_NULL: + break; + default: + buffer->error = 1; + break; + } +} + +void +grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, + const TPMT_SIGNATURE *p) +{ + grub_tpm2_buffer_pack_u16 (buffer, p->sigAlg); + grub_tpm2_mu_TPMU_SIGNATURE_Marshal (buffer, p->sigAlg, &p->signature); +} + +void +grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer, + const TPMT_TK_VERIFIED *p) +{ + grub_tpm2_buffer_pack_u16 (buffer, p->tag); + grub_tpm2_buffer_pack_u32 (buffer, p->hierarchy); + grub_tpm2_mu_TPM2B_Marshal (buffer, p->digest.size, p->digest.buffer); +} + void grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buffer, 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); } +void +grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer, + TPMT_TK_HASHCHECK *p) +{ + grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); + grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); + grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest); +} + +void +grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer, + TPMT_TK_VERIFIED *p) +{ + grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); + grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); + grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest); +} + void grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, 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]); } + +void +grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer, + TPMS_SIGNATURE_RSA *rsa) +{ + grub_tpm2_buffer_unpack_u16 (buffer, &rsa->hash); + grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)&rsa->sig); +} + +void +grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer, + TPMS_SIGNATURE_ECC *ecc) +{ + grub_tpm2_buffer_unpack_u16 (buffer, &ecc->hash); + grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)&ecc->signatureR); + grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)&ecc->signatureS); +} + +void +grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer, + TPMI_ALG_HASH hashAlg, + TPMU_HA *p) +{ + switch (hashAlg) + { + case TPM_ALG_SHA1: + grub_tpm2_buffer_unpack (buffer, &p->sha1, TPM_SHA1_DIGEST_SIZE); + break; + case TPM_ALG_SHA256: + grub_tpm2_buffer_unpack (buffer, &p->sha256, TPM_SHA256_DIGEST_SIZE); + break; + case TPM_ALG_SHA384: + grub_tpm2_buffer_unpack (buffer, &p->sha384, TPM_SHA384_DIGEST_SIZE); + break; + case TPM_ALG_SHA512: + grub_tpm2_buffer_unpack (buffer, &p->sha512, TPM_SHA512_DIGEST_SIZE); + break; + default: + buffer->error = 1; + break; + } +} + +void +grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer, + TPMT_HA *p) +{ + grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); + grub_tpm2_mu_TPMU_HA_Unmarshal (buffer, p->hashAlg, &p->digest); +} + +void +grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, + TPMI_ALG_SIG_SCHEME sigAlg, + TPMU_SIGNATURE *p) +{ + switch (sigAlg) + { + case TPM_ALG_RSASSA: + grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsassa); + break; + case TPM_ALG_RSAPSS: + grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsapss); + break; + case TPM_ALG_ECDSA: + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdsa); + break; + case TPM_ALG_ECDAA: + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdaa); + break; + case TPM_ALG_SM2: + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->sm2); + break; + case TPM_ALG_ECSCHNORR: + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecschnorr); + break; + case TPM_ALG_HMAC: + grub_tpm2_mu_TPMT_HA_Unmarshal (buffer, &p->hmac); + break; + case TPM_ALG_NULL: + break; + default: + buffer->error = 1; + break; + } +} + +void +grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, + TPMT_SIGNATURE *p) +{ + grub_tpm2_buffer_unpack_u16 (buffer, &p->sigAlg); + 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 --- 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); void +grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buf, + const TPMI_ALG_PUBLIC type, + const TPMU_SENSITIVE_COMPOSITE *p); +void +grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buf, + const TPMT_SENSITIVE *p); + +void +grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buf, + const TPM2B_SENSITIVE *p); + +void +grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buf, + const TPMS_SIGNATURE_RSA *p); + +void +grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buf, + const TPMS_SIGNATURE_ECC *p); + +void +grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buf, + const TPMI_ALG_HASH hashAlg, + const TPMU_HA *p); + +void +grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buf, + const TPMT_HA *p); + +void +grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buf, + const TPMI_ALG_SIG_SCHEME sigAlg, + const TPMU_SIGNATURE *p); + +void +grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buf, + const TPMT_SIGNATURE *p); + +void +grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buf, + const TPMT_TK_VERIFIED *p); +void grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buf, TPM2B* p); @@ -277,6 +318,14 @@ void grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buf, TPMT_TK_CREATION *p); +void +grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buf, + TPMT_TK_HASHCHECK *p); + +void +grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buf, + TPMT_TK_VERIFIED *p); + void grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, TPMS_PCR_SELECTION* pcrSelection); @@ -289,4 +338,30 @@ void grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf, TPML_DIGEST* digest); +void +grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buf, + TPMS_SIGNATURE_RSA *p); + +void +grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buf, + TPMS_SIGNATURE_ECC *p); + +void +grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buf, + TPMI_ALG_HASH hashAlg, + TPMU_HA *p); + +void +grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buf, + TPMT_HA *p); + +void +grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buf, + TPMI_ALG_SIG_SCHEME sigAlg, + TPMU_SIGNATURE *p); + +void +grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buf, + TPMT_SIGNATURE *p); + #endif /* ! GRUB_TPM2_MU_HEADER */ -- 2.35.3 ++++++ 0006-tpm2-check-the-command-parameters-of-TPM2-commands.patch ++++++ >From 4cde0a1bfb8382677c331e0cf4fa482afadbfa1f Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> 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 <[email protected]> --- 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 ++++++ 0007-tpm2-pack-the-missing-authorization-command-for-TPM2.patch ++++++ >From 4f00de963f3cf483d4067cdf0e86147248e9456e Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> 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 <[email protected]> --- 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 ++++++ 0008-tpm2-allow-some-command-parameters-to-be-NULL.patch ++++++ >From 6a280321880fffed8765d65226b92f991443dbc6 Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> 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 <[email protected]> --- 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 ++++++ 0009-tpm2-remove-the-unnecessary-variables.patch ++++++ >From ffb0fe8f2dc9256af6df2e3199e3f950e6b8b830 Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> 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 <[email protected]> --- 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 ++++++ 0010-tpm2-add-TPM2-commands-to-support-authorized-policy.patch ++++++ >From 8f73e30667da46a7716df0f688fbaa41e34fe5ea Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> Date: Wed, 8 Feb 2023 10:30:55 +0800 Subject: [PATCH 10/13] tpm2: add TPM2 commands to support authorized policy This commit implements a few more TPM2 commands as the preparation for the authorized policy support. * TPM2_LoadExternal This command is added to load the external public key to verify the signed policy digest * TPM2_HashSequenceStart, TPM2_SequenceUpdate, TPM2_SequenceComplete, and TPM2_Hash With those commands, we can use the TPM as a coprocessor to calculate the hash of a given binary blob. * TPM2_VerifySignature This command verifies the given signature with the given public key and returns the validation ticket to authorize the policy. * TPM2_PolicyAuthorize This command approves the given policy digest so that we can unseal the key with the newly authorized policy. Signed-off-by: Gary Lin <[email protected]> --- grub-core/tpm2/tpm2.c | 424 +++++++++++++++++++++++++ include/grub/tpm2/internal/functions.h | 57 ++++ 2 files changed, 481 insertions(+) diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c index a56f7a5e5..2032d6823 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, return TPM_RC_SUCCESS; } +TPM_RC +TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_SENSITIVE *inPrivate, + const TPM2B_PUBLIC *inPublic, + const TPMI_RH_HIERARCHY hierarchy, + TPM_HANDLE *objectHandle, + TPM2B_NAME *name, + TPMS_AUTH_RESPONSE *authResponse) +{ + TPM_RC rc; + struct grub_tpm2_buffer in; + struct grub_tpm2_buffer out; + TPM_HANDLE objectHandleTmp; + TPM2B_NAME nameTmp; + TPMS_AUTH_RESPONSE authResponseTmp; + TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; + TPM_RC responseCode; + grub_uint32_t param_size; + + if (!inPublic) + return TPM_RC_VALUE; + + if (!objectHandle) + objectHandle = &objectHandleTmp; + if (!name) + name = &nameTmp; + if (!authResponse) + authResponse = &authResponseTmp; + + grub_memset (objectHandle, 0, sizeof (*objectHandle)); + grub_memset (name, 0, sizeof (*name)); + grub_memset (authResponse, 0, sizeof (*authResponse)); + + /* Marshal */ + grub_tpm2_buffer_init (&in); + if (authCommand) + grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); + if (inPrivate) + grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (&in, inPrivate); + else + grub_tpm2_buffer_pack_u16 (&in, 0); + grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic); + grub_tpm2_buffer_pack_u32 (&in, hierarchy); + if (in.error) + return TPM_RC_FAILURE; + + /* Submit */ + grub_tpm2_buffer_init (&out); + rc = grub_tpm2_submit_command (tag, TPM_CC_LoadExternal, &responseCode, &in, &out); + if (rc != TPM_RC_SUCCESS) + return rc; + if (responseCode != TPM_RC_SUCCESS) + return responseCode; + + /* Unmarshal*/ + grub_tpm2_buffer_unpack_u32 (&out, objectHandle); + if (tag == TPM_ST_SESSIONS) + grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); + grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)name); + if (tag == TPM_ST_SESSIONS) + grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); + if (out.error) + return TPM_RC_FAILURE; + + return TPM_RC_SUCCESS; +} + TPM_RC TPM2_Unseal (const TPMI_DH_OBJECT itemHandle, const TPMS_AUTH_COMMAND *authCommand, @@ -759,3 +826,360 @@ TPM2_EvictControl (const TPMI_RH_PROVISION auth, return TPM_RC_SUCCESS; } + +TPM_RC +TPM2_HashSequenceStart (const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_AUTH *auth, + const TPMI_ALG_HASH hashAlg, + TPMI_DH_OBJECT *sequenceHandle, + TPMS_AUTH_RESPONSE *authResponse) +{ + struct grub_tpm2_buffer in; + struct grub_tpm2_buffer out; + TPMI_DH_OBJECT sequenceHandleTmp; + TPMS_AUTH_RESPONSE authResponseTmp; + TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; + TPM_RC responseCode; + TPM_RC rc; + grub_uint32_t parameterSize; + + if (!auth) + return TPM_RC_VALUE; + + if (!sequenceHandle) + sequenceHandle = &sequenceHandleTmp; + if (!authResponse) + authResponse = &authResponseTmp; + + grub_memset (sequenceHandle, 0, sizeof (*sequenceHandle)); + grub_memset (authResponse, 0, sizeof (*authResponse)); + + /* Marshal */ + grub_tpm2_buffer_init (&in); + if (authCommand) + grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); + grub_tpm2_mu_TPM2B_Marshal (&in, auth->size, auth->buffer); + grub_tpm2_buffer_pack_u16 (&in, hashAlg); + if (in.error) + return TPM_RC_FAILURE; + + /* Submit */ + grub_tpm2_buffer_init (&out); + rc = grub_tpm2_submit_command (tag, TPM_CC_HashSequenceStart, &responseCode, &in, + &out); + if (rc != TPM_RC_SUCCESS) + return rc; + if (responseCode != TPM_RC_SUCCESS) + return responseCode; + + /* Unmarshal */ + grub_tpm2_buffer_unpack_u32 (&out, sequenceHandle); + if (tag == TPM_ST_SESSIONS) + { + grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); + grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); + } + if (out.error) + return TPM_RC_FAILURE; + + return TPM_RC_SUCCESS; +} + +TPM_RC +TPM2_SequenceUpdate (const TPMI_DH_OBJECT sequenceHandle, + const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_MAX_BUFFER *buffer, + TPMS_AUTH_RESPONSE *authResponse) +{ + struct grub_tpm2_buffer in; + struct grub_tpm2_buffer out; + TPMS_AUTH_RESPONSE authResponseTmp; + TPM_RC responseCode; + TPM_RC rc; + grub_uint32_t parameterSize; + + if (!authCommand) + return TPM_RC_VALUE; + + if (!authResponse) + authResponse = &authResponseTmp; + + grub_memset (authResponse, 0, sizeof (*authResponse)); + + /* Marshal */ + grub_tpm2_buffer_init (&in); + grub_tpm2_buffer_pack_u32 (&in, sequenceHandle); + grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); + if (buffer) + grub_tpm2_mu_TPM2B_Marshal (&in, buffer->size, buffer->buffer); + else + grub_tpm2_buffer_pack_u16 (&in, 0); + if (in.error) + return TPM_RC_FAILURE; + + /* Submit */ + grub_tpm2_buffer_init (&out); + rc = grub_tpm2_submit_command (TPM_ST_SESSIONS, TPM_CC_SequenceUpdate, + &responseCode, &in, &out); + if (rc != TPM_RC_SUCCESS) + return rc; + if (responseCode != TPM_RC_SUCCESS) + return responseCode; + + /* Unmarshal */ + grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); + grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); + if (out.error) + return TPM_RC_FAILURE; + + return TPM_RC_SUCCESS; +} + +TPM_RC +TPM2_SequenceComplete (const TPMI_DH_OBJECT sequenceHandle, + const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_MAX_BUFFER *buffer, + const TPMI_RH_HIERARCHY hierarchy, + TPM2B_DIGEST *result, + TPMT_TK_HASHCHECK *validation, + TPMS_AUTH_RESPONSE *authResponse) +{ + struct grub_tpm2_buffer in; + struct grub_tpm2_buffer out; + TPM2B_DIGEST resultTmp; + TPMT_TK_HASHCHECK validationTmp; + TPMS_AUTH_RESPONSE authResponseTmp; + TPM_RC responseCode; + TPM_RC rc; + grub_uint32_t parameterSize; + + if (!authCommand) + return TPM_RC_VALUE; + + if (!result) + result = &resultTmp; + if (!validation) + validation = &validationTmp; + if (!authResponse) + authResponse = &authResponseTmp; + + grub_memset (result, 0, sizeof (*result)); + grub_memset (validation, 0, sizeof (*validation)); + grub_memset (authResponse, 0, sizeof (*authResponse)); + + /* Marshal */ + grub_tpm2_buffer_init (&in); + grub_tpm2_buffer_pack_u32 (&in, sequenceHandle); + grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); + if (buffer) + grub_tpm2_mu_TPM2B_Marshal (&in, buffer->size, buffer->buffer); + else + grub_tpm2_buffer_pack_u16 (&in, 0); + grub_tpm2_buffer_pack_u32 (&in, hierarchy); + + if (in.error) + return TPM_RC_FAILURE; + + /* Submit */ + grub_tpm2_buffer_init (&out); + rc = grub_tpm2_submit_command (TPM_ST_SESSIONS, TPM_CC_SequenceComplete, + &responseCode, &in, &out); + if (rc != TPM_RC_SUCCESS) + return rc; + if (responseCode != TPM_RC_SUCCESS) + return responseCode; + + /* Unmarshal */ + grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); + grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, result); + grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (&out, validation); + grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); + if (out.error) + return TPM_RC_FAILURE; + + return TPM_RC_SUCCESS; +} + +TPM_RC +TPM2_Hash (const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_MAX_BUFFER *data, + const TPMI_ALG_HASH hashAlg, + const TPMI_RH_HIERARCHY hierarchy, + TPM2B_DIGEST *outHash, + TPMT_TK_HASHCHECK *validation, + TPMS_AUTH_RESPONSE *authResponse) +{ + TPM_RC rc; + struct grub_tpm2_buffer in; + struct grub_tpm2_buffer out; + TPMS_AUTH_RESPONSE authResponseTmp; + TPM2B_DIGEST outHashTmp; + TPMT_TK_HASHCHECK validationTmp; + TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; + TPM_RC responseCode; + grub_uint32_t param_size; + + if (hashAlg == TPM_ALG_NULL) + return TPM_RC_VALUE; + + if (!outHash) + outHash = &outHashTmp; + if (!validation) + validation = &validationTmp; + if (!authResponse) + authResponse = &authResponseTmp; + + grub_memset (outHash, 0, sizeof (*outHash)); + grub_memset (validation, 0, sizeof (*validation)); + grub_memset (authResponse, 0, sizeof (*authResponse)); + + /* Marshal */ + grub_tpm2_buffer_init (&in); + if (authCommand) + grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); + if (data) + grub_tpm2_mu_TPM2B_Marshal (&in, data->size, data->buffer); + else + grub_tpm2_buffer_pack_u16 (&in, 0); + grub_tpm2_buffer_pack_u16 (&in, hashAlg); + grub_tpm2_buffer_pack_u32 (&in, hierarchy); + if (in.error) + return TPM_RC_FAILURE; + + /* Submit */ + grub_tpm2_buffer_init (&out); + rc = grub_tpm2_submit_command (tag, TPM_CC_Hash, &responseCode, &in, &out); + if (rc != TPM_RC_SUCCESS) + return rc; + if (responseCode != TPM_RC_SUCCESS) + return responseCode; + + /* Unmarshal*/ + if (tag == TPM_ST_SESSIONS) + grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); + grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, outHash); + grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (&out, validation); + if (tag == TPM_ST_SESSIONS) + grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); + if (out.error) + return TPM_RC_FAILURE; + + return TPM_RC_SUCCESS; +} + +TPM_RC +TPM2_VerifySignature (const TPMI_DH_OBJECT keyHandle, + const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_DIGEST *digest, + const TPMT_SIGNATURE *signature, + TPMT_TK_VERIFIED *validation, + TPMS_AUTH_RESPONSE *authResponse) +{ + TPM_RC rc; + struct grub_tpm2_buffer in; + struct grub_tpm2_buffer out; + TPMS_AUTH_RESPONSE authResponseTmp; + TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; + TPMT_TK_VERIFIED validationTmp; + TPM_RC responseCode; + grub_uint32_t param_size; + + if (!digest || !signature) + return TPM_RC_VALUE; + + if (!validation) + validation = &validationTmp; + if (!authResponse) + authResponse = &authResponseTmp; + + grub_memset (validation, 0, sizeof (*validation)); + grub_memset (authResponse, 0, sizeof (*authResponse)); + + /* Marshal */ + grub_tpm2_buffer_init (&in); + if (authCommand) + grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); + grub_tpm2_buffer_pack_u32 (&in, keyHandle); + grub_tpm2_mu_TPM2B_Marshal (&in, digest->size, digest->buffer); + grub_tpm2_mu_TPMT_SIGNATURE_Marshal (&in, signature); + if (in.error) + return TPM_RC_FAILURE; + + /* Submit */ + grub_tpm2_buffer_init (&out); + rc = grub_tpm2_submit_command (tag, TPM_CC_VerifySignature, &responseCode, &in, &out); + if (rc != TPM_RC_SUCCESS) + return rc; + if (responseCode != TPM_RC_SUCCESS) + return responseCode; + + /* Unmarshal*/ + if (tag == TPM_ST_SESSIONS) + grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); + grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (&out, validation); + if (tag == TPM_ST_SESSIONS) + grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); + if (out.error) + return TPM_RC_FAILURE; + + return TPM_RC_SUCCESS; +} + +TPM_RC +TPM2_PolicyAuthorize (const TPMI_SH_POLICY policySession, + const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_DIGEST *approvedPolicy, + const TPM2B_NONCE *policyRef, + const TPM2B_NAME *keySign, + const TPMT_TK_VERIFIED *checkTicket, + TPMS_AUTH_RESPONSE *authResponse) +{ + TPM_RC rc; + struct grub_tpm2_buffer in; + struct grub_tpm2_buffer out; + TPMS_AUTH_RESPONSE authResponseTmp; + TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; + TPM_RC responseCode; + grub_uint32_t param_size; + + if (!approvedPolicy || !keySign || !checkTicket) + return TPM_RC_VALUE; + + if (!authResponse) + authResponse = &authResponseTmp; + + grub_memset (authResponse, 0, sizeof (*authResponse)); + + /* Marshal */ + grub_tpm2_buffer_init (&in); + grub_tpm2_buffer_pack_u32 (&in, policySession); + if (authCommand) + grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); + grub_tpm2_mu_TPM2B_Marshal (&in, approvedPolicy->size, approvedPolicy->buffer); + if (policyRef) + grub_tpm2_mu_TPM2B_Marshal (&in, policyRef->size, policyRef->buffer); + else + grub_tpm2_buffer_pack_u16 (&in, 0); + grub_tpm2_mu_TPM2B_Marshal (&in, keySign->size, keySign->name); + grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (&in, checkTicket); + if (in.error) + return TPM_RC_FAILURE; + + /* Submit */ + grub_tpm2_buffer_init (&out); + rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyAuthorize, &responseCode, &in, &out); + if (rc != TPM_RC_SUCCESS) + return rc; + if (responseCode != TPM_RC_SUCCESS) + return responseCode; + + /* Unmarshal*/ + if (tag == TPM_ST_SESSIONS) + grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); + if (tag == TPM_ST_SESSIONS) + grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); + if (out.error) + return TPM_RC_FAILURE; + + return TPM_RC_SUCCESS; +} diff --git a/include/grub/tpm2/internal/functions.h b/include/grub/tpm2/internal/functions.h index 8fda8ceab..c8253e4c7 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); +TPM_RC +TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_SENSITIVE *inPrivate, + const TPM2B_PUBLIC *inPublic, + const TPMI_RH_HIERARCHY hierarchy, + TPM_HANDLE *objectHandle, + TPM2B_NAME *name, + TPMS_AUTH_RESPONSE *authResponse); + TPM_RC TPM2_Unseal (const TPMI_DH_OBJECT item_handle, 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); +TPM_RC +TPM2_HashSequenceStart (const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_AUTH *auth, + const TPMI_ALG_HASH hashAlg, + TPMI_DH_OBJECT *sequenceHandle, + TPMS_AUTH_RESPONSE *authResponse); + +TPM_RC +TPM2_SequenceUpdate (const TPMI_DH_OBJECT sequenceHandle, + const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_MAX_BUFFER *buffer, + TPMS_AUTH_RESPONSE *authResponse); + +TPM_RC +TPM2_SequenceComplete (const TPMI_DH_OBJECT sequenceHandle, + const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_MAX_BUFFER *buffer, + const TPMI_RH_HIERARCHY hierarchy, + TPM2B_DIGEST *result, + TPMT_TK_HASHCHECK *validation, + TPMS_AUTH_RESPONSE *authResponse); + +TPM_RC +TPM2_Hash (const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_MAX_BUFFER *data, + const TPMI_ALG_HASH hashAlg, + const TPMI_RH_HIERARCHY hierarchy, + TPM2B_DIGEST *outHash, + TPMT_TK_HASHCHECK *validation, + TPMS_AUTH_RESPONSE *authResponse); + +TPM_RC +TPM2_VerifySignature (const TPMI_DH_OBJECT keyHandle, + const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_DIGEST *digest, + const TPMT_SIGNATURE *signature, + TPMT_TK_VERIFIED *validation, + TPMS_AUTH_RESPONSE *authResponse); + +TPM_RC +TPM2_PolicyAuthorize (const TPMI_SH_POLICY policySession, + const TPMS_AUTH_COMMAND *authCommand, + const TPM2B_DIGEST *approvedPolicy, + const TPM2B_NONCE *policyRef, + const TPM2B_NAME *keySign, + const TPMT_TK_VERIFIED *checkTicket, + TPMS_AUTH_RESPONSE *authResponse); + #endif /* ! GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER */ -- 2.35.3 ++++++ 0011-tpm2-make-the-file-reading-unmarshal-functions-gener.patch ++++++ >From e144e2b256ae9771306a8df04f8b9289d435349b Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> 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 <[email protected]> --- 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 ++++++ 0012-tpm2-initialize-the-PCR-selection-list-early.patch ++++++ >From 1dcae21faa281496a79ee2caf59772bf36b16b9e Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> 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 <[email protected]> --- 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 ++++++ 0013-tpm2-support-unsealing-key-with-authorized-policy.patch ++++++ ++++ 795 lines (skipped)
