[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v19 21/33] tss2: Add TPM2 Software Stack (TSS2) support
From: |
Gary Lin |
Subject: |
[PATCH v19 21/33] tss2: Add TPM2 Software Stack (TSS2) support |
Date: |
Fri, 6 Sep 2024 17:11:13 +0800 |
A Trusted Platform Module (TPM) Software Stack (TSS) provides logic to
compose and submit TPM commands and parse reponses.
A limited number of TPM commands may be accessed via the EFI TCG2
protocol. This protocol exposes functionality that is primarily geared
toward TPM usage within the context of Secure Boot. For all other TPM
commands, however, such as sealing and unsealing, this protocol does not
provide any help, with the exception of passthrough command submission.
The SubmitCommand method allows a caller to send raw commands to the
system's TPM and to receive the corresponding response. These
command/response pairs are formatted using the TPM wire protocol. To
construct commands in this way, and to parse the TPM's response, it is
necessary to, first, possess knowledge of the various TPM structures, and,
second, of the TPM wire protocol itself.
As such, this patch includes implementations of various grub_tpm2_* functions
(inventoried below), and logic to write and read command and response
buffers, respectively, using the TPM wire protocol.
Functions:
* grub_tpm2_create()
* grub_tpm2_createprimary()
* grub_tpm2_evictcontrol()
* grub_tpm2_flushcontext()
* grub_tpm2_load()
* grub_tpm2_pcr_read()
* grub_tpm2_policygetdigest()
* grub_tpm2_policypcr()
* grub_tpm2_readpublic()
* grub_tpm2_startauthsession()
* grub_tpm2_unseal()
* grub_tpm2_loadexternal()
* grub_tpm2_hash()
* grub_tpm2_verifysignature()
* grub_tpm2_policyauthorize()
* grub_tpm2_testparms()
Cc: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/Makefile.core.def | 11 +
grub-core/lib/efi/tcg2.c | 143 +++++
grub-core/lib/tss2/tcg2.h | 35 ++
grub-core/lib/tss2/tpm2_cmd.c | 1043 +++++++++++++++++++++++++++++++++
grub-core/lib/tss2/tpm2_cmd.h | 157 +++++
grub-core/lib/tss2/tss2.c | 21 +
6 files changed, 1410 insertions(+)
create mode 100644 grub-core/lib/efi/tcg2.c
create mode 100644 grub-core/lib/tss2/tcg2.h
create mode 100644 grub-core/lib/tss2/tpm2_cmd.c
create mode 100644 grub-core/lib/tss2/tpm2_cmd.h
create mode 100644 grub-core/lib/tss2/tss2.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 37f131ae2..45b705a34 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2567,6 +2567,17 @@ module = {
enable = efi;
};
+module = {
+ name = tss2;
+ common = lib/tss2/buffer.c;
+ common = lib/tss2/tss2_mu.c;
+ common = lib/tss2/tpm2_cmd.c;
+ common = lib/tss2/tss2.c;
+ efi = lib/efi/tcg2.c;
+ enable = efi;
+ cppflags = '-I$(srcdir)/lib/tss2';
+};
+
module = {
name = tr;
common = commands/tr.c;
diff --git a/grub-core/lib/efi/tcg2.c b/grub-core/lib/efi/tcg2.c
new file mode 100644
index 000000000..841bf50bb
--- /dev/null
+++ b/grub-core/lib/efi/tcg2.c
@@ -0,0 +1,143 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Microsoft Corporation
+ * Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/tpm.h>
+#include <grub/mm.h>
+
+#include <tcg2.h>
+
+static grub_err_t
+tcg2_get_caps (grub_efi_tpm2_protocol_t *protocol, int *tpm2, grub_size_t
*max_output_size)
+{
+ grub_efi_status_t status;
+ static bool has_caps = 0;
+ static EFI_TCG2_BOOT_SERVICE_CAPABILITY caps =
+ {
+ .Size = (grub_uint8_t) sizeof (caps)
+ };
+
+ if (has_caps)
+ goto exit;
+
+ status = protocol->get_capability (protocol, &caps);
+ if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
+ return GRUB_ERR_FILE_NOT_FOUND;
+
+ has_caps = 1;
+
+ exit:
+ if (tpm2 != NULL)
+ *tpm2 = caps.TPMPresentFlag;
+ if (max_output_size != NULL)
+ *max_output_size = caps.MaxResponseSize;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tcg2_get_protocol (grub_efi_tpm2_protocol_t **protocol)
+{
+ static grub_guid_t tpm2_guid = EFI_TPM2_GUID;
+ static grub_efi_tpm2_protocol_t *tpm2_protocol = NULL;
+ int tpm2;
+ grub_efi_handle_t *handles;
+ grub_efi_uintn_t num_handles;
+ grub_efi_handle_t tpm2_handle;
+ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND;
+
+ if (tpm2_protocol != NULL)
+ {
+ *protocol = tpm2_protocol;
+ return GRUB_ERR_NONE;
+ }
+
+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL,
+ &num_handles);
+ if (handles == NULL || num_handles == 0)
+ return err;
+
+ tpm2_handle = handles[0];
+
+ tpm2_protocol = grub_efi_open_protocol (tpm2_handle, &tpm2_guid,
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (tpm2_protocol == NULL)
+ goto exit;
+
+ err = tcg2_get_caps (tpm2_protocol, &tpm2, NULL);
+ if (err != GRUB_ERR_NONE || tpm2 == 0)
+ goto exit;
+
+ *protocol = tpm2_protocol;
+ err = GRUB_ERR_NONE;
+
+ exit:
+ grub_free (handles);
+ return err;
+}
+
+grub_err_t
+grub_tcg2_get_max_output_size (grub_size_t *size)
+{
+ grub_err_t err;
+ grub_size_t max;
+ grub_efi_tpm2_protocol_t *protocol;
+
+ if (size == NULL)
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ err = tcg2_get_protocol (&protocol);
+ if (err != GRUB_ERR_NONE)
+ return err;
+
+ err = tcg2_get_caps (protocol, NULL, &max);
+ if (err != GRUB_ERR_NONE)
+ return err;
+
+ *size = max;
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_tcg2_submit_command (grub_size_t input_size,
+ grub_uint8_t *input,
+ grub_size_t output_size,
+ grub_uint8_t *output)
+{
+ grub_err_t err;
+ grub_efi_status_t status;
+ grub_efi_tpm2_protocol_t *protocol;
+
+ if (input_size == 0 || input == NULL ||
+ output_size == 0 || output == NULL)
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ err = tcg2_get_protocol (&protocol);
+ if (err != GRUB_ERR_NONE)
+ return err;
+
+ status = protocol->submit_command (protocol, input_size, input,
+ output_size, output);
+ if (status != GRUB_EFI_SUCCESS)
+ return GRUB_ERR_INVALID_COMMAND;
+
+ return GRUB_ERR_NONE;
+}
diff --git a/grub-core/lib/tss2/tcg2.h b/grub-core/lib/tss2/tcg2.h
new file mode 100644
index 000000000..3d26373dd
--- /dev/null
+++ b/grub-core/lib/tss2/tcg2.h
@@ -0,0 +1,35 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Microsoft Corporation
+ * Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TPM2_TCG2_HEADER
+#define GRUB_TPM2_TCG2_HEADER 1
+
+#include <grub/err.h>
+#include <grub/types.h>
+
+extern grub_err_t
+grub_tcg2_get_max_output_size (grub_size_t *size);
+
+extern grub_err_t
+grub_tcg2_submit_command (grub_size_t input_size,
+ grub_uint8_t *input,
+ grub_size_t output_size,
+ grub_uint8_t *output);
+
+#endif /* ! GRUB_TPM2_TCG2_HEADER */
diff --git a/grub-core/lib/tss2/tpm2_cmd.c b/grub-core/lib/tss2/tpm2_cmd.c
new file mode 100644
index 000000000..8a86139ed
--- /dev/null
+++ b/grub-core/lib/tss2/tpm2_cmd.c
@@ -0,0 +1,1043 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Microsoft Corporation
+ * Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+
+#include <tss2_buffer.h>
+#include <tss2_mu.h>
+#include <tss2_structs.h>
+#include <tcg2.h>
+#include <tpm2_cmd.h>
+
+static TPM_RC_t
+tpm2_submit_command_real (const TPMI_ST_COMMAND_TAG_t tag,
+ const TPM_CC_t commandCode,
+ TPM_RC_t *responseCode,
+ const struct grub_tpm2_buffer *in,
+ struct grub_tpm2_buffer *out)
+{
+ grub_err_t err;
+ struct grub_tpm2_buffer buf;
+ TPMI_ST_COMMAND_TAG_t tag_out;
+ grub_uint32_t command_size;
+ grub_size_t max_output_size;
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&buf);
+ grub_tpm2_buffer_pack_u16 (&buf, tag);
+ grub_tpm2_buffer_pack_u32 (&buf, 0);
+ grub_tpm2_buffer_pack_u32 (&buf, commandCode);
+ grub_tpm2_buffer_pack (&buf, in->data, in->size);
+
+ if (buf.error != 0)
+ return TPM_RC_FAILURE;
+
+ command_size = grub_swap_bytes32 (buf.size);
+ grub_memcpy (&buf.data[sizeof (grub_uint16_t)], &command_size,
+ sizeof (command_size));
+
+ /* Stay within output block limits */
+ err = grub_tcg2_get_max_output_size (&max_output_size);
+ if (err != GRUB_ERR_NONE || max_output_size > out->cap)
+ max_output_size = out->cap - 1;
+
+ /* Submit */
+ err = grub_tcg2_submit_command (buf.size, buf.data, max_output_size,
out->data);
+ if (err != GRUB_ERR_NONE)
+ return TPM_RC_FAILURE;
+
+ /* Unmarshal */
+ out->size = sizeof (grub_uint16_t) + sizeof (grub_uint32_t) + sizeof
(grub_uint32_t);
+ grub_tpm2_buffer_unpack_u16 (out, &tag_out);
+ grub_tpm2_buffer_unpack_u32 (out, &command_size);
+ grub_tpm2_buffer_unpack_u32 (out, responseCode);
+ out->size = command_size;
+ if (out->error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+static TPM_RC_t
+tpm2_submit_command (const TPMI_ST_COMMAND_TAG_t tag,
+ const TPM_CC_t commandCode,
+ TPM_RC_t *responseCode,
+ const struct grub_tpm2_buffer *in,
+ struct grub_tpm2_buffer *out)
+{
+ TPM_RC_t err;
+ int retry_cnt = 0;
+
+ /* Catch TPM_RC_RETRY and send the command again */
+ do {
+ err = tpm2_submit_command_real (tag, commandCode, responseCode, in, out);
+ if (*responseCode != TPM_RC_RETRY)
+ break;
+
+ retry_cnt++;
+ } while (retry_cnt < 3);
+
+ return err;
+}
+
+TPM_RC_t
+grub_tpm2_createprimary (const TPMI_RH_HIERARCHY_t primaryHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_SENSITIVE_CREATE_t *inSensitive,
+ const TPM2B_PUBLIC_t *inPublic,
+ const TPM2B_DATA_t *outsideInfo,
+ const TPML_PCR_SELECTION_t *creationPCR,
+ TPM_HANDLE_t *objectHandle,
+ TPM2B_PUBLIC_t *outPublic,
+ TPM2B_CREATION_DATA_t *creationData,
+ TPM2B_DIGEST_t *creationHash,
+ TPMT_TK_CREATION_t *creationTicket,
+ TPM2B_NAME_t *name,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPM_HANDLE_t objectHandleTmp;
+ TPM2B_PUBLIC_t outPublicTmp;
+ TPM2B_CREATION_DATA_t creationDataTmp;
+ TPM2B_DIGEST_t creationHashTmp;
+ TPMT_TK_CREATION_t creationTicketTmp;
+ TPM2B_NAME_t nameTmp;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t parameterSize;
+
+ if (inSensitive == NULL || inPublic == NULL || outsideInfo == NULL ||
+ creationPCR == NULL)
+ return TPM_RC_VALUE;
+
+ if (objectHandle == NULL)
+ objectHandle = &objectHandleTmp;
+ if (outPublic == NULL)
+ outPublic = &outPublicTmp;
+ if (creationData == NULL)
+ creationData = &creationDataTmp;
+ if (creationHash == NULL)
+ creationHash = &creationHashTmp;
+ if (creationTicket == NULL)
+ creationTicket = &creationTicketTmp;
+ if (name == NULL)
+ name = &nameTmp;
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+
+ grub_memset (outPublic, 0, sizeof (*outPublic));
+ grub_memset (creationData, 0, sizeof (*creationData));
+ grub_memset (creationHash, 0, sizeof (*creationHash));
+ grub_memset (creationTicket, 0, sizeof (*creationTicket));
+ grub_memset (name, 0, sizeof (*name));
+ grub_memset (authResponse, 0, sizeof (*authResponse));
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, primaryHandle);
+ if (authCommand != NULL)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive);
+ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic);
+ grub_Tss2_MU_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer);
+ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, creationPCR);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_CreatePrimary, &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, ¶meterSize);
+ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&out, outPublic);
+ grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (&out, creationData);
+ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, creationHash);
+ grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (&out, creationTicket);
+ grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, name);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_startauthsession (const TPMI_DH_OBJECT_t tpmKey,
+ const TPMI_DH_ENTITY_t bind,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_NONCE_t *nonceCaller,
+ const TPM2B_ENCRYPTED_SECRET_t *encryptedSalt,
+ const TPM_SE_t sessionType,
+ const TPMT_SYM_DEF_t *symmetric,
+ const TPMI_ALG_HASH_t authHash,
+ TPMI_SH_AUTH_SESSION_t *sessionHandle,
+ TPM2B_NONCE_t *nonceTpm,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPMI_SH_AUTH_SESSION_t sessionHandleTmp;
+ TPM2B_NONCE_t nonceTpmTmp;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t param_size;
+
+ if (nonceCaller == NULL || symmetric == NULL)
+ return TPM_RC_VALUE;
+
+ if (tpmKey == TPM_RH_NULL &&
+ (encryptedSalt && encryptedSalt->size != 0))
+ return TPM_RC_VALUE;
+
+ if (sessionHandle == NULL)
+ sessionHandle = &sessionHandleTmp;
+ if (nonceTpm == NULL)
+ nonceTpm = &nonceTpmTmp;
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+
+ grub_memset (sessionHandle, 0, sizeof (*sessionHandle));
+ grub_memset (nonceTpm, 0, sizeof (*nonceTpm));
+ grub_memset (authResponse, 0, sizeof (*authResponse));
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, tpmKey);
+ grub_tpm2_buffer_pack_u32 (&in, bind);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ grub_Tss2_MU_TPM2B_Marshal (&in, nonceCaller->size, nonceCaller->buffer);
+ if (encryptedSalt != NULL)
+ grub_Tss2_MU_TPM2B_Marshal (&in, encryptedSalt->size,
encryptedSalt->secret);
+ else
+ grub_tpm2_buffer_pack_u16 (&in, 0);
+ grub_tpm2_buffer_pack_u8 (&in, sessionType);
+ grub_Tss2_MU_TPMT_SYM_DEF_Marshal (&in, symmetric);
+ grub_tpm2_buffer_pack_u16 (&in, authHash);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_StartAuthSession, &responseCode,
+ &in, &out);
+ if (rc != TPM_RC_SUCCESS)
+ return rc;
+ if (responseCode != TPM_RC_SUCCESS)
+ return responseCode;
+
+ /* Unmarshal */
+ grub_tpm2_buffer_unpack_u32 (&out, sessionHandle);
+ if (tag == TPM_ST_SESSIONS)
+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size);
+ grub_Tss2_MU_TPM2B_NONCE_Unmarshal (&out, nonceTpm);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_policypcr (const TPMI_SH_POLICY_t policySessions,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_DIGEST_t *pcrDigest,
+ const TPML_PCR_SELECTION_t *pcrs,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t param_size;
+
+ if (pcrs == NULL)
+ return TPM_RC_VALUE;
+
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+
+ grub_memset (authResponse, 0, sizeof (*authResponse));
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, policySessions);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ if (pcrDigest != NULL)
+ grub_Tss2_MU_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer);
+ else
+ grub_tpm2_buffer_pack_u16 (&in, 0);
+ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, pcrs);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_PolicyPCR, &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_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_readpublic (const TPMI_DH_OBJECT_t objectHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ TPM2B_PUBLIC_t *outPublic)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t parameterSize;
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, objectHandle);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_ReadPublic, &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, ¶meterSize);
+ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&out, outPublic);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_load (const TPMI_DH_OBJECT_t parent_handle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_PRIVATE_t *inPrivate,
+ const TPM2B_PUBLIC_t *inPublic,
+ TPM_HANDLE_t *objectHandle,
+ TPM2B_NAME_t *name,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPM_HANDLE_t objectHandleTmp;
+ TPM2B_NAME_t nameTmp;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t param_size;
+
+ if (inPrivate == NULL || inPublic == NULL)
+ return TPM_RC_VALUE;
+
+ if (objectHandle == NULL)
+ objectHandle = &objectHandleTmp;
+ if (name == NULL)
+ name = &nameTmp;
+ if (authResponse == NULL)
+ 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);
+ grub_tpm2_buffer_pack_u32 (&in, parent_handle);
+ if (authCommand)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ grub_Tss2_MU_TPM2B_Marshal (&in, inPrivate->size, inPrivate->buffer);
+ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_Load, &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_Tss2_MU_TPM2B_NAME_Unmarshal (&out, name);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_loadexternal (const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_SENSITIVE_t *inPrivate,
+ const TPM2B_PUBLIC_t *inPublic,
+ const TPMI_RH_HIERARCHY_t hierarchy,
+ TPM_HANDLE_t *objectHandle,
+ TPM2B_NAME_t *name,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPM_HANDLE_t objectHandleTmp;
+ TPM2B_NAME_t nameTmp;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t param_size;
+
+ if (inPublic == NULL)
+ return TPM_RC_VALUE;
+
+ if (objectHandle == NULL)
+ objectHandle = &objectHandleTmp;
+ if (name == NULL)
+ name = &nameTmp;
+ if (authResponse == NULL)
+ 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_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ if (inPrivate)
+ grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (&in, inPrivate);
+ else
+ grub_tpm2_buffer_pack_u16 (&in, 0);
+ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic);
+ grub_tpm2_buffer_pack_u32 (&in, hierarchy);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = 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_Tss2_MU_TPM2B_NAME_Unmarshal (&out, name);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_unseal (const TPMI_DH_OBJECT_t itemHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ TPM2B_SENSITIVE_DATA_t *outData,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPM2B_SENSITIVE_DATA_t outDataTmp;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t param_size;
+
+ if (outData == NULL)
+ outData = &outDataTmp;
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+
+ grub_memset (outData, 0, sizeof (*outData));
+ grub_memset (authResponse, 0, sizeof (*authResponse));
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, itemHandle);
+ if (authCommand != NULL)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_Unseal, &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_Tss2_MU_TPM2B_SENSITIVE_DATA_Unmarshal (&out, outData);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_flushcontext (const TPMI_DH_CONTEXT_t handle)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPM_RC_t responseCode;
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, handle);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (TPM_ST_NO_SESSIONS, TPM_CC_FlushContext,
&responseCode, &in, &out);
+ if (rc != TPM_RC_SUCCESS)
+ return rc;
+ if (responseCode != TPM_RC_SUCCESS)
+ return responseCode;
+
+ /* Unmarshal */
+ if (out.error != 0)
+ 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,
+ grub_uint32_t *pcrUpdateCounter,
+ TPML_PCR_SELECTION_t *pcrSelectionOut,
+ TPML_DIGEST_t *pcrValues,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ grub_uint32_t pcrUpdateCounterTmp;
+ TPML_PCR_SELECTION_t pcrSelectionOutTmp;
+ TPML_DIGEST_t pcrValuesTmp;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t parameterSize;
+
+ if (pcrSelectionIn == NULL)
+ return TPM_RC_VALUE;
+
+ if (pcrUpdateCounter == NULL)
+ pcrUpdateCounter = &pcrUpdateCounterTmp;
+ if (pcrSelectionOut == NULL)
+ pcrSelectionOut = &pcrSelectionOutTmp;
+ if (pcrValues == NULL)
+ pcrValues = &pcrValuesTmp;
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ if (authCommand != NULL)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, pcrSelectionIn);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_PCR_Read, &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, ¶meterSize);
+ grub_tpm2_buffer_unpack_u32 (&out, pcrUpdateCounter);
+ grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (&out, pcrSelectionOut);
+ grub_Tss2_MU_TPML_DIGEST_Unmarshal (&out, pcrValues);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_policygetdigest (const TPMI_SH_POLICY_t policySession,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ TPM2B_DIGEST_t *policyDigest,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPM2B_DIGEST_t policyDigestTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t parameterSize;
+
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+ if (policyDigest == NULL)
+ policyDigest = &policyDigestTmp;
+
+ grub_memset (authResponse, 0, sizeof (*authResponse));
+ grub_memset (policyDigest, 0, sizeof (*policyDigest));
+
+ /* Submit */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, policySession);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_PolicyGetDigest, &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, ¶meterSize);
+ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, policyDigest);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_create (const TPMI_DH_OBJECT_t parentHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_SENSITIVE_CREATE_t *inSensitive,
+ const TPM2B_PUBLIC_t *inPublic,
+ const TPM2B_DATA_t *outsideInfo,
+ const TPML_PCR_SELECTION_t *creationPCR,
+ TPM2B_PRIVATE_t *outPrivate,
+ TPM2B_PUBLIC_t *outPublic,
+ TPM2B_CREATION_DATA_t *creationData,
+ TPM2B_DIGEST_t *creationHash,
+ TPMT_TK_CREATION_t *creationTicket,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPM2B_PUBLIC_t outPublicTmp;
+ TPM2B_PRIVATE_t outPrivateTmp;
+ TPM2B_CREATION_DATA_t creationDataTmp;
+ TPM2B_DIGEST_t creationHashTmp;
+ TPMT_TK_CREATION_t creationTicketTmp;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS:TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ TPM_RC_t rc;
+ grub_uint32_t parameterSize;
+
+ if (inSensitive == NULL || inPublic == NULL || outsideInfo == NULL ||
+ creationPCR == NULL)
+ return TPM_RC_VALUE;
+
+ if (outPrivate == NULL)
+ outPrivate = &outPrivateTmp;
+ if (outPublic == NULL)
+ outPublic = &outPublicTmp;
+ if (creationData == NULL)
+ creationData = &creationDataTmp;
+ if (creationHash == NULL)
+ creationHash = &creationHashTmp;
+ if (creationTicket == NULL)
+ creationTicket = &creationTicketTmp;
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+
+ grub_memset (outPrivate, 0, sizeof (*outPrivate));
+ grub_memset (outPublic, 0, sizeof (*outPublic));
+ grub_memset (creationData, 0, sizeof (*creationData));
+ grub_memset (creationHash, 0, sizeof (*creationHash));
+ grub_memset (creationTicket, 0, sizeof (*creationTicket));
+ grub_memset (authResponse, 0, sizeof (*authResponse));
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, parentHandle);
+ if (authCommand != NULL)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive);
+ grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic);
+ grub_Tss2_MU_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer);
+ grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, creationPCR);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_Create, &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, ¶meterSize);
+ grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (&out, outPrivate);
+ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&out, outPublic);
+ grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (&out, creationData);
+ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, creationHash);
+ grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (&out, creationTicket);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_evictcontrol (const TPMI_RH_PROVISION_t auth,
+ const TPMI_DH_OBJECT_t objectHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPMI_DH_PERSISTENT_t persistentHandle,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ TPM_RC_t rc;
+ grub_uint32_t parameterSize;
+
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+
+ grub_memset (authResponse, 0, sizeof (*authResponse));
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, auth);
+ grub_tpm2_buffer_pack_u32 (&in, objectHandle);
+ if (authCommand != NULL)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ grub_tpm2_buffer_pack_u32 (&in, persistentHandle);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_EvictControl, &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, ¶meterSize);
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse);
+ }
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_hash (const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_MAX_BUFFER_t *data,
+ const TPMI_ALG_HASH_t hashAlg,
+ const TPMI_RH_HIERARCHY_t hierarchy,
+ TPM2B_DIGEST_t *outHash,
+ TPMT_TK_HASHCHECK_t *validation,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPM2B_DIGEST_t outHashTmp;
+ TPMT_TK_HASHCHECK_t validationTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t param_size;
+
+ if (hashAlg == TPM_ALG_NULL)
+ return TPM_RC_VALUE;
+
+ if (outHash == NULL)
+ outHash = &outHashTmp;
+ if (validation == NULL)
+ validation = &validationTmp;
+ if (authResponse == NULL)
+ 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 != NULL)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ if (data != NULL)
+ grub_Tss2_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 != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = 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_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, outHash);
+ grub_Tss2_MU_TPMT_TK_HASHCHECK_Unmarshal (&out, validation);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_verifysignature (const TPMI_DH_OBJECT_t keyHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_DIGEST_t *digest,
+ const TPMT_SIGNATURE_t *signature,
+ TPMT_TK_VERIFIED_t *validation,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPMT_TK_VERIFIED_t validationTmp;
+ TPM_RC_t responseCode;
+ grub_uint32_t param_size;
+
+ if (digest == NULL || signature == NULL)
+ return TPM_RC_VALUE;
+
+ if (validation == NULL)
+ validation = &validationTmp;
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+
+ grub_memset (validation, 0, sizeof (*validation));
+ grub_memset (authResponse, 0, sizeof (*authResponse));
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ if (authCommand != NULL)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ grub_tpm2_buffer_pack_u32 (&in, keyHandle);
+ grub_Tss2_MU_TPM2B_Marshal (&in, digest->size, digest->buffer);
+ grub_Tss2_MU_TPMT_SIGNATURE_Marshal (&in, signature);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = 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_Tss2_MU_TPMT_TK_VERIFIED_Unmarshal (&out, validation);
+ if (tag == TPM_ST_SESSIONS)
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_policyauthorize (const TPMI_SH_POLICY_t policySession,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_DIGEST_t *approvedPolicy,
+ const TPM2B_NONCE_t *policyRef,
+ const TPM2B_NAME_t *keySign,
+ const TPMT_TK_VERIFIED_t *checkTicket,
+ TPMS_AUTH_RESPONSE_t *authResponse)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPMS_AUTH_RESPONSE_t authResponseTmp;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+ grub_uint32_t param_size;
+
+ if (approvedPolicy == NULL || keySign == NULL || checkTicket == NULL)
+ return TPM_RC_VALUE;
+
+ if (authResponse == NULL)
+ authResponse = &authResponseTmp;
+
+ grub_memset (authResponse, 0, sizeof (*authResponse));
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_tpm2_buffer_pack_u32 (&in, policySession);
+ if (authCommand != NULL)
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
+ grub_Tss2_MU_TPM2B_Marshal (&in, approvedPolicy->size,
approvedPolicy->buffer);
+ if (policyRef != NULL)
+ grub_Tss2_MU_TPM2B_Marshal (&in, policyRef->size, policyRef->buffer);
+ else
+ grub_tpm2_buffer_pack_u16 (&in, 0);
+ grub_Tss2_MU_TPM2B_Marshal (&in, keySign->size, keySign->name);
+ grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (&in, checkTicket);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = 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);
+ grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
+ }
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
+
+TPM_RC_t
+grub_tpm2_testparms (const TPMT_PUBLIC_PARMS_t *parms,
+ const TPMS_AUTH_COMMAND_t *authCommand)
+{
+ TPM_RC_t rc;
+ struct grub_tpm2_buffer in;
+ struct grub_tpm2_buffer out;
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS :
TPM_ST_NO_SESSIONS;
+ TPM_RC_t responseCode;
+
+ if (parms == NULL)
+ return TPM_RC_VALUE;
+
+ /* Marshal */
+ grub_tpm2_buffer_init (&in);
+ grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (&in, parms);
+ if (in.error != 0)
+ return TPM_RC_FAILURE;
+
+ /* Submit */
+ grub_tpm2_buffer_init (&out);
+ rc = tpm2_submit_command (tag, TPM_CC_TestParms, &responseCode, &in,
+ &out);
+ if (rc != TPM_RC_SUCCESS)
+ return rc;
+ if (responseCode != TPM_RC_SUCCESS)
+ return responseCode;
+
+ /* Unmarshal */
+ if (out.error != 0)
+ return TPM_RC_FAILURE;
+
+ return TPM_RC_SUCCESS;
+}
diff --git a/grub-core/lib/tss2/tpm2_cmd.h b/grub-core/lib/tss2/tpm2_cmd.h
new file mode 100644
index 000000000..d313cba00
--- /dev/null
+++ b/grub-core/lib/tss2/tpm2_cmd.h
@@ -0,0 +1,157 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Microsoft Corporation
+ * Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TPM2_COMMANDS_HEADER
+#define GRUB_TPM2_COMMANDS_HEADER 1
+
+#include <tss2_structs.h>
+
+extern TPM_RC_t
+grub_tpm2_createprimary (const TPMI_RH_HIERARCHY_t primaryHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_SENSITIVE_CREATE_t *inSensitive,
+ const TPM2B_PUBLIC_t *inPublic,
+ const TPM2B_DATA_t *outsideInfo,
+ const TPML_PCR_SELECTION_t *creationPCR,
+ TPM_HANDLE_t *objectHandle,
+ TPM2B_PUBLIC_t *outPublic,
+ TPM2B_CREATION_DATA_t *creationData,
+ TPM2B_DIGEST_t *creationHash,
+ TPMT_TK_CREATION_t *creationTicket,
+ TPM2B_NAME_t *name,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_startauthsession (const TPMI_DH_OBJECT_t tpmKey,
+ const TPMI_DH_ENTITY_t bind,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_NONCE_t *nonceCaller,
+ const TPM2B_ENCRYPTED_SECRET_t *encryptedSalt,
+ const TPM_SE_t sessionType,
+ const TPMT_SYM_DEF_t *symmetric,
+ const TPMI_ALG_HASH_t authHash,
+ TPMI_SH_AUTH_SESSION_t *sessionHandle,
+ TPM2B_NONCE_t *nonceTpm,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_policypcr (const TPMI_SH_POLICY_t policySession,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_DIGEST_t *pcrDigest,
+ const TPML_PCR_SELECTION_t *pcrs,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_readpublic (const TPMI_DH_OBJECT_t objectHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ TPM2B_PUBLIC_t *outPublic);
+
+extern TPM_RC_t
+grub_tpm2_load (const TPMI_DH_OBJECT_t parent_handle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_PRIVATE_t *inPrivate,
+ const TPM2B_PUBLIC_t *inPublic,
+ TPM_HANDLE_t *objectHandle,
+ TPM2B_NAME_t *name,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_loadexternal (const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_SENSITIVE_t *inPrivate,
+ const TPM2B_PUBLIC_t *inPublic,
+ const TPMI_RH_HIERARCHY_t hierarchy,
+ TPM_HANDLE_t *objectHandle,
+ TPM2B_NAME_t *name,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_unseal (const TPMI_DH_OBJECT_t item_handle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ TPM2B_SENSITIVE_DATA_t *outData,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_flushcontext (const TPMI_DH_CONTEXT_t handle);
+
+extern TPM_RC_t
+grub_tpm2_pcr_read (const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPML_PCR_SELECTION_t *pcrSelectionIn,
+ grub_uint32_t *pcrUpdateCounter,
+ TPML_PCR_SELECTION_t *pcrSelectionOut,
+ TPML_DIGEST_t *pcrValues,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_policygetdigest (const TPMI_SH_POLICY_t policySession,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ TPM2B_DIGEST_t *policyDigest,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_create (const TPMI_DH_OBJECT_t parentHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_SENSITIVE_CREATE_t *inSensitive,
+ const TPM2B_PUBLIC_t *inPublic,
+ const TPM2B_DATA_t *outsideInfo,
+ const TPML_PCR_SELECTION_t *creationPCR,
+ TPM2B_PRIVATE_t *outPrivate,
+ TPM2B_PUBLIC_t *outPublic,
+ TPM2B_CREATION_DATA_t *creationData,
+ TPM2B_DIGEST_t *creationHash,
+ TPMT_TK_CREATION_t *creationTicket,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_evictcontrol (const TPMI_RH_PROVISION_t auth,
+ const TPMI_DH_OBJECT_t objectHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPMI_DH_PERSISTENT_t persistentHandle,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_hash (const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_MAX_BUFFER_t *data,
+ const TPMI_ALG_HASH_t hashAlg,
+ const TPMI_RH_HIERARCHY_t hierarchy,
+ TPM2B_DIGEST_t *outHash,
+ TPMT_TK_HASHCHECK_t *validation,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_verifysignature (const TPMI_DH_OBJECT_t keyHandle,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_DIGEST_t *digest,
+ const TPMT_SIGNATURE_t *signature,
+ TPMT_TK_VERIFIED_t *validation,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_policyauthorize (const TPMI_SH_POLICY_t policySession,
+ const TPMS_AUTH_COMMAND_t *authCommand,
+ const TPM2B_DIGEST_t *approvedPolicy,
+ const TPM2B_NONCE_t *policyRef,
+ const TPM2B_NAME_t *keySign,
+ const TPMT_TK_VERIFIED_t *checkTicket,
+ TPMS_AUTH_RESPONSE_t *authResponse);
+
+extern TPM_RC_t
+grub_tpm2_testparms (const TPMT_PUBLIC_PARMS_t *parms,
+ const TPMS_AUTH_COMMAND_t *authCommand);
+
+#endif /* ! GRUB_TPM2_COMMANDS_HEADER */
diff --git a/grub-core/lib/tss2/tss2.c b/grub-core/lib/tss2/tss2.c
new file mode 100644
index 000000000..48251e9b4
--- /dev/null
+++ b/grub-core/lib/tss2/tss2.c
@@ -0,0 +1,21 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
--
2.35.3
- [PATCH v19 17/33] libtasn1: Add the documentation, (continued)
- [PATCH v19 17/33] libtasn1: Add the documentation, Gary Lin, 2024/09/06
- [PATCH v19 18/33] key_protector: Add key protectors framework, Gary Lin, 2024/09/06
- [PATCH v19 19/33] tss2: Add TPM2 buffer handling functions, Gary Lin, 2024/09/06
- [PATCH v19 20/33] tss2: Add TPM2 types and Marshal/Unmarshal functions, Gary Lin, 2024/09/06
- [PATCH v19 22/33] key_protector: Add TPM2 Key Protector, Gary Lin, 2024/09/06
[PATCH v19 23/33] cryptodisk: Support key protectors, Gary Lin, 2024/09/06
[PATCH v19 21/33] tss2: Add TPM2 Software Stack (TSS2) support,
Gary Lin <=
[PATCH v19 24/33] util/grub-protect: Add new tool, Gary Lin, 2024/09/06
[PATCH v19 25/33] tpm2_key_protector: Support authorized policy, Gary Lin, 2024/09/06
[PATCH v19 26/33] tpm2_key_protector: Implement NV index, Gary Lin, 2024/09/06
[PATCH v19 27/33] cryptodisk: Fallback to passphrase, Gary Lin, 2024/09/06
[PATCH v19 28/33] cryptodisk: wipe out the cached keys from protectors, Gary Lin, 2024/09/06
[PATCH v19 29/33] diskfilter: look up cryptodisk devices first, Gary Lin, 2024/09/06
[PATCH v19 30/33] tpm2_key_protector: Add grub-emu support, Gary Lin, 2024/09/06
[PATCH v19 31/33] tests: Add tpm2_key_protector_test, Gary Lin, 2024/09/06