diff --git a/0001-tpm2-adjust-the-input-parameters-of-TPM2_EvictContro.patch b/0001-tpm2-adjust-the-input-parameters-of-TPM2_EvictContro.patch new file mode 100644 index 0000000..af5a93f --- /dev/null +++ b/0001-tpm2-adjust-the-input-parameters-of-TPM2_EvictContro.patch @@ -0,0 +1,73 @@ +From bc5ecda21bb612f786f614623da782d7ad6d8325 Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0002-tpm2-declare-the-input-arguments-of-TPM2-functions-a.patch b/0002-tpm2-declare-the-input-arguments-of-TPM2-functions-a.patch new file mode 100644 index 0000000..cdf295b --- /dev/null +++ b/0002-tpm2-declare-the-input-arguments-of-TPM2-functions-a.patch @@ -0,0 +1,696 @@ +From 2b94a992464aa2d00333ab3f13f065da99196440 Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + + 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 + diff --git a/0003-tpm2-resend-the-command-on-TPM_RC_RETRY.patch b/0003-tpm2-resend-the-command-on-TPM_RC_RETRY.patch new file mode 100644 index 0000000..a2f5f91 --- /dev/null +++ b/0003-tpm2-resend-the-command-on-TPM_RC_RETRY.patch @@ -0,0 +1,68 @@ +From 14a8c03f1a3b09250ea933f1a072dfdfef8c4a48 Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + + 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 + diff --git a/0004-tpm2-add-new-TPM2-types-structures-and-command-const.patch b/0004-tpm2-add-new-TPM2-types-structures-and-command-const.patch new file mode 100644 index 0000000..8938544 --- /dev/null +++ b/0004-tpm2-add-new-TPM2-types-structures-and-command-const.patch @@ -0,0 +1,179 @@ +From 69a5cedcb206ca931ac2c2763c283954751d7072 Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0005-tpm2-add-more-marshal-unmarshal-functions.patch b/0005-tpm2-add-more-marshal-unmarshal-functions.patch new file mode 100644 index 0000000..6d8b6ce --- /dev/null +++ b/0005-tpm2-add-more-marshal-unmarshal-functions.patch @@ -0,0 +1,427 @@ +From ac5c47af318652a25df1788c73884e4e9b6e4ac1 Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0006-tpm2-check-the-command-parameters-of-TPM2-commands.patch b/0006-tpm2-check-the-command-parameters-of-TPM2-commands.patch new file mode 100644 index 0000000..3055503 --- /dev/null +++ b/0006-tpm2-check-the-command-parameters-of-TPM2-commands.patch @@ -0,0 +1,86 @@ +From 4cde0a1bfb8382677c331e0cf4fa482afadbfa1f Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0007-tpm2-pack-the-missing-authorization-command-for-TPM2.patch b/0007-tpm2-pack-the-missing-authorization-command-for-TPM2.patch new file mode 100644 index 0000000..8069a47 --- /dev/null +++ b/0007-tpm2-pack-the-missing-authorization-command-for-TPM2.patch @@ -0,0 +1,30 @@ +From 4f00de963f3cf483d4067cdf0e86147248e9456e Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0008-tpm2-allow-some-command-parameters-to-be-NULL.patch b/0008-tpm2-allow-some-command-parameters-to-be-NULL.patch new file mode 100644 index 0000000..61a5945 --- /dev/null +++ b/0008-tpm2-allow-some-command-parameters-to-be-NULL.patch @@ -0,0 +1,47 @@ +From 6a280321880fffed8765d65226b92f991443dbc6 Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0009-tpm2-remove-the-unnecessary-variables.patch b/0009-tpm2-remove-the-unnecessary-variables.patch new file mode 100644 index 0000000..023a9c3 --- /dev/null +++ b/0009-tpm2-remove-the-unnecessary-variables.patch @@ -0,0 +1,44 @@ +From ffb0fe8f2dc9256af6df2e3199e3f950e6b8b830 Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0010-tpm2-add-TPM2-commands-to-support-authorized-policy.patch b/0010-tpm2-add-TPM2-commands-to-support-authorized-policy.patch new file mode 100644 index 0000000..43e90b1 --- /dev/null +++ b/0010-tpm2-add-TPM2-commands-to-support-authorized-policy.patch @@ -0,0 +1,543 @@ +From 8f73e30667da46a7716df0f688fbaa41e34fe5ea Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0011-tpm2-make-the-file-reading-unmarshal-functions-gener.patch b/0011-tpm2-make-the-file-reading-unmarshal-functions-gener.patch new file mode 100644 index 0000000..ebdee88 --- /dev/null +++ b/0011-tpm2-make-the-file-reading-unmarshal-functions-gener.patch @@ -0,0 +1,135 @@ +From e144e2b256ae9771306a8df04f8b9289d435349b Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0012-tpm2-initialize-the-PCR-selection-list-early.patch b/0012-tpm2-initialize-the-PCR-selection-list-early.patch new file mode 100644 index 0000000..dd96678 --- /dev/null +++ b/0012-tpm2-initialize-the-PCR-selection-list-early.patch @@ -0,0 +1,103 @@ +From 1dcae21faa281496a79ee2caf59772bf36b16b9e Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/0013-tpm2-support-unsealing-key-with-authorized-policy.patch b/0013-tpm2-support-unsealing-key-with-authorized-policy.patch new file mode 100644 index 0000000..d638979 --- /dev/null +++ b/0013-tpm2-support-unsealing-key-with-authorized-policy.patch @@ -0,0 +1,794 @@ +From 47220d1ce8fffac3654454b8a981385133b7c23a Mon Sep 17 00:00:00 2001 +From: Gary Lin +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 +--- + 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 + diff --git a/grub2.changes b/grub2.changes index d6089c4..44bcf9f 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,22 @@ +------------------------------------------------------------------- +Thu Feb 9 08:42:26 UTC 2023 - Gary Ching-Pang Lin + +- 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 + ------------------------------------------------------------------- Wed Feb 8 02:24:16 UTC 2023 - Michael Chang diff --git a/grub2.spec b/grub2.spec index ef8dbf5..0c99d29 100644 --- a/grub2.spec +++ b/grub2.spec @@ -480,6 +480,19 @@ 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 Requires: gettext-runtime %if 0%{?suse_version} >= 1140