]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
tss2: Add TPM2_PCR_Event command
authorGary Lin <glin@suse.com>
Fri, 3 Oct 2025 03:22:02 +0000 (11:22 +0800)
committerDaniel Kiper <daniel.kiper@oracle.com>
Sat, 11 Oct 2025 13:43:58 +0000 (15:43 +0200)
The TPM2_PCR_Event command is introduced to tss2 to allow the user to
extend a specific PCR. The related data structure and unmarshal function
are also introduced.

However, simply invoking TPM2_PCR_Event does not automatically record
the event into the TPM event log. The TPM event log is primarily
maintained by the system firmware (e.g., BIOS/UEFI). Therefore, for most
standard use cases, the recommended method for extending PCRs and
ensuring proper event logging is to utilize the system firmware
functions.

There are specific scenarios where direct use of TPM2_PCR_Event becomes
necessary. For instance, in environments lacking system firmware support
for PCR extension, such as the grub-emu, TPM2_PCR_Event serves as the
only available method to extend PCRs.

Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/lib/tss2/tpm2_cmd.c
grub-core/lib/tss2/tpm2_cmd.h
grub-core/lib/tss2/tss2_mu.c
grub-core/lib/tss2/tss2_mu.h
grub-core/lib/tss2/tss2_structs.h
grub-core/lib/tss2/tss2_types.h

index 6d25db1ab766c5e5a05422d2069dbc1c44006b1a..b682eb43156e77f7eeae753be6db139d0058489e 100644 (file)
@@ -575,6 +575,57 @@ grub_tpm2_flushcontext (const TPMI_DH_CONTEXT_t handle)
   return TPM_RC_SUCCESS;
 }
 
+TPM_RC_t
+grub_tpm2_pcr_event (const TPMI_DH_PCR_t pcrHandle,
+                    const TPMS_AUTH_COMMAND_t *authCommand,
+                    const TPM2B_EVENT_t *eventData,
+                    TPML_DIGEST_VALUES_t *digests,
+                    TPMS_AUTH_RESPONSE_t *authResponse)
+{
+  TPM_RC_t rc;
+  struct grub_tpm2_buffer in;
+  struct grub_tpm2_buffer out;
+  TPML_DIGEST_VALUES_t digestsTmp;
+  TPMS_AUTH_RESPONSE_t authResponseTmp;
+  TPM_RC_t responseCode;
+  grub_uint32_t parameterSize;
+
+  if (eventData == NULL)
+    return TPM_RC_VALUE;
+  if (authCommand == NULL)
+    return TPM_RC_VALUE;
+
+  if (digests == NULL)
+    digests = &digestsTmp;
+  if (authResponse == NULL)
+    authResponse = &authResponseTmp;
+
+  /* Marshal */
+  grub_tpm2_buffer_init (&in);
+  grub_tpm2_buffer_pack_u32 (&in, pcrHandle);
+  grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+  grub_Tss2_MU_TPM2B_Marshal (&in, eventData->size, eventData->buffer);
+  if (in.error == true)
+    return TPM_RC_FAILURE;
+
+  /* Submit */
+  grub_tpm2_buffer_init (&out);
+  rc = tpm2_submit_command (TPM_ST_SESSIONS, TPM_CC_PCR_Event, &responseCode, &in, &out);
+  if (rc != TPM_RC_SUCCESS)
+    return rc;
+  if (responseCode != TPM_RC_SUCCESS)
+    return responseCode;
+
+  /* Unmarshal */
+  grub_tpm2_buffer_unpack_u32 (&out, &parameterSize);
+  grub_Tss2_MU_TPML_DIGEST_VALUE_Unmarshal (&out, digests);
+  grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+  if (out.error == true)
+    return TPM_RC_FAILURE;
+
+  return TPM_RC_SUCCESS;
+}
+
 TPM_RC_t
 grub_tpm2_pcr_read (const TPMS_AUTH_COMMAND_t *authCommand,
                    const TPML_PCR_SELECTION_t *pcrSelectionIn,
index 90b42efecd23986deef47155530f8c13e91f3787..d7ad962abee7a622e0b8597d222d9d18183fdafa 100644 (file)
@@ -89,6 +89,13 @@ grub_tpm2_unseal (const TPMI_DH_OBJECT_t item_handle,
 extern TPM_RC_t
 grub_tpm2_flushcontext (const TPMI_DH_CONTEXT_t handle);
 
+extern TPM_RC_t
+grub_tpm2_pcr_event (const TPMI_DH_PCR_t pcrHandle,
+                    const TPMS_AUTH_COMMAND_t *authCommand,
+                    const TPM2B_EVENT_t *eventData,
+                    TPML_DIGEST_VALUES_t *digests,
+                    TPMS_AUTH_RESPONSE_t *authResponse);
+
 extern TPM_RC_t
 grub_tpm2_pcr_read (const TPMS_AUTH_COMMAND_t *authCommand,
                    const TPML_PCR_SELECTION_t *pcrSelectionIn,
index 816e5b37f2a81ae3b7fd5ee7515042254af8bb29..e544e62f976abc577cce3d23739df6639ccf64e2 100644 (file)
@@ -1118,6 +1118,24 @@ grub_Tss2_MU_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
     grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &digest->digests[i]);
 }
 
+void
+grub_Tss2_MU_TPML_DIGEST_VALUE_Unmarshal (grub_tpm2_buffer_t buffer,
+                                         TPML_DIGEST_VALUES_t *digests)
+{
+  grub_uint32_t i;
+
+  grub_tpm2_buffer_unpack_u32 (buffer, &digests->count);
+
+  if (digests->count > TPM_NUM_PCR_BANKS)
+    {
+      buffer->error = true;
+      return;
+    }
+
+  for (i = 0; i < digests->count; i++)
+    grub_Tss2_MU_TPMT_HA_Unmarshal (buffer, &digests->digests[i]);
+}
+
 void
 grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
                                            TPMS_SIGNATURE_RSA_t *rsa)
index 6440de57cf753a337311d7e7e38b55bd168f2867..76eebc9948a7d1fe84cdfbf66729cba755eff5bb 100644 (file)
@@ -380,6 +380,10 @@ extern void
 grub_Tss2_MU_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
                                    TPML_DIGEST_t *digest);
 
+extern void
+grub_Tss2_MU_TPML_DIGEST_VALUE_Unmarshal (grub_tpm2_buffer_t buffer,
+                                         TPML_DIGEST_VALUES_t *digests);
+
 extern void
 grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
                                            TPMS_SIGNATURE_RSA_t *p);
index 2eefba87cf48e581d5146b39b62795f1c224eae1..0ac09f50f46ef069577f5bc75a798ad9f1bf3a6b 100644 (file)
@@ -144,6 +144,13 @@ typedef struct TPML_DIGEST TPML_DIGEST_t;
 /* TPM2B_NONCE Type */
 typedef TPM2B_DIGEST_t TPM2B_NONCE_t;
 
+/* TPM2B_EVENT Structure */
+struct TPM2B_EVENT {
+    grub_uint16_t size;
+    grub_uint8_t buffer[1024];
+};
+typedef struct TPM2B_EVENT TPM2B_EVENT_t;
+
 /* TPMA_SESSION Structure */
 struct TPMA_SESSION
 {
index bddde71919e4ff611676a34ad15310a9e9b14572..52d304b90ed9008900844ea9200688a801e8453e 100644 (file)
@@ -343,6 +343,7 @@ typedef grub_uint32_t TPM_CC_t;
 #define TPM_CC_NV_Write         ((TPM_CC_t) 0x00000137)
 #define TPM_CC_NV_UndefineSpace ((TPM_CC_t) 0x00000122)
 #define TPM_CC_GetCapability    ((TPM_CC_t) 0x0000017a)
+#define TPM_CC_PCR_Event        ((TPM_CC_t) 0x0000013c)
 #define TPM_CC_PCR_Read         ((TPM_CC_t) 0x0000017e)
 #define TPM_CC_Load             ((TPM_CC_t) 0x00000157)
 #define TPM_CC_LoadExternal     ((TPM_CC_t) 0x00000167)