/*
* 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 .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
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;
/* Convert the command size to big endian to fill the u32 buffer below 'tag' */
command_size = grub_cpu_to_be32 (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 {
grub_tpm2_buffer_init (out);
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 */
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 */
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 */
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 (authCommand != NULL)
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
if (in.error != 0)
return TPM_RC_FAILURE;
/* Submit */
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 != NULL)
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 */
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 != NULL)
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
if (inPrivate != NULL)
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 */
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 */
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 */
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_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 */
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, ¶meterSize);
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,
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 (authCommand != NULL)
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
if (in.error != 0)
return TPM_RC_FAILURE;
/* Submit */
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;
}
TPM_RC_t
grub_tpm2_nv_definespace (const TPMI_RH_PROVISION_t authHandle,
const TPMS_AUTH_COMMAND_t *authCommand,
const TPM2B_AUTH_t *auth,
const TPM2B_NV_PUBLIC_t *publicInfo)
{
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 (publicInfo == NULL)
return TPM_RC_VALUE;
/* Marshal */
grub_tpm2_buffer_init (&in);
grub_tpm2_buffer_pack_u32 (&in, authHandle);
if (authCommand != NULL)
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
if (auth != NULL)
grub_Tss2_MU_TPM2B_Marshal (&in, auth->size, auth->buffer);
else
grub_tpm2_buffer_pack_u16 (&in, 0);
grub_Tss2_MU_TPM2B_NV_PUBLIC_Marshal (&in, publicInfo);
if (in.error != 0)
return TPM_RC_FAILURE;
/* Submit */
rc = tpm2_submit_command (tag, TPM_CC_NV_DefineSpace, &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_nv_undefinespace (const TPMI_RH_PROVISION_t authHandle,
const TPMI_RH_NV_INDEX_t nvIndex,
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;
/* Marshal */
grub_tpm2_buffer_init (&in);
grub_tpm2_buffer_pack_u32 (&in, authHandle);
grub_tpm2_buffer_pack_u32 (&in, nvIndex);
if (authCommand != NULL)
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
if (in.error != 0)
return TPM_RC_FAILURE;
/* Submit */
rc = tpm2_submit_command (tag, TPM_CC_NV_UndefineSpace, &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_nv_readpublic (const TPMI_RH_NV_INDEX_t nvIndex,
const TPMS_AUTH_COMMAND_t *authCommand,
TPM2B_NV_PUBLIC_t *nvPublic,
TPM2B_NAME_t *nvName)
{
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 param_size;
/* Marshal */
grub_tpm2_buffer_init (&in);
grub_tpm2_buffer_pack_u32 (&in, nvIndex);
if (authCommand != NULL)
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
if (in.error != 0)
return TPM_RC_FAILURE;
/* Submit */
rc = tpm2_submit_command (tag, TPM_CC_NV_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, ¶m_size);
grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (&out, nvPublic);
grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, nvName);
if (out.error != 0)
return TPM_RC_FAILURE;
return TPM_RC_SUCCESS;
}
TPM_RC_t
grub_tpm2_nv_read (const TPMI_RH_NV_AUTH_t authHandle,
const TPMI_RH_NV_INDEX_t nvIndex,
const TPMS_AUTH_COMMAND_t *authCommand,
const grub_uint16_t size,
const grub_uint16_t offset,
TPM2B_MAX_NV_BUFFER_t *data)
{
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 param_size;
/* Marshal */
grub_tpm2_buffer_init (&in);
grub_tpm2_buffer_pack_u32 (&in, authHandle);
grub_tpm2_buffer_pack_u32 (&in, nvIndex);
if (authCommand != NULL)
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
grub_tpm2_buffer_pack_u16 (&in, size);
grub_tpm2_buffer_pack_u16 (&in, offset);
if (in.error != 0)
return TPM_RC_FAILURE;
/* Submit */
rc = tpm2_submit_command (tag, TPM_CC_NV_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, ¶m_size);
grub_Tss2_MU_TPM2B_NAX_NV_BUFFER_Unmarshal (&out, data);
if (out.error != 0)
return TPM_RC_FAILURE;
return TPM_RC_SUCCESS;
}
TPM_RC_t
grub_tpm2_nv_write (const TPMI_RH_NV_AUTH_t authHandle,
const TPMI_RH_NV_INDEX_t nvIndex,
const TPMS_AUTH_COMMAND_t *authCommand,
const TPM2B_MAX_NV_BUFFER_t *data,
const grub_uint16_t offset)
{
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;
/* Marshal */
grub_tpm2_buffer_init (&in);
grub_tpm2_buffer_pack_u32 (&in, authHandle);
grub_tpm2_buffer_pack_u32 (&in, nvIndex);
if (authCommand != NULL)
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
grub_Tss2_MU_TPM2B_Marshal (&in, data->size, data->buffer);
grub_tpm2_buffer_pack_u16 (&in, offset);
if (in.error != 0)
return TPM_RC_FAILURE;
/* Submit */
rc = tpm2_submit_command (tag, TPM_CC_NV_Write, &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;
}