Add TPM2 implementation.
signed off by: jiewen.yao@intel.com reviewed by: guo.dong@intel.com git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14687 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
741
SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c
Normal file
741
SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c
Normal file
@@ -0,0 +1,741 @@
|
||||
/** @file
|
||||
Implement TPM2 Capability related command.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPM_CAP Capability;
|
||||
UINT32 Property;
|
||||
UINT32 PropertyCount;
|
||||
} TPM2_GET_CAPABILITY_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
TPMI_YES_NO MoreData;
|
||||
TPMS_CAPABILITY_DATA CapabilityData;
|
||||
} TPM2_GET_CAPABILITY_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMT_PUBLIC_PARMS Parameters;
|
||||
} TPM2_TEST_PARMS_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
} TPM2_TEST_PARMS_RESPONSE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
This command returns various information regarding the TPM and its current state.
|
||||
|
||||
The capability parameter determines the category of data returned. The property parameter
|
||||
selects the first value of the selected category to be returned. If there is no property
|
||||
that corresponds to the value of property, the next higher value is returned, if it exists.
|
||||
The moreData parameter will have a value of YES if there are more values of the requested
|
||||
type that were not returned.
|
||||
If no next capability exists, the TPM will return a zero-length list and moreData will have
|
||||
a value of NO.
|
||||
|
||||
NOTE:
|
||||
To simplify this function, leave returned CapabilityData for caller to unpack since there are
|
||||
many capability categories and only few categories will be used in firmware. It means the caller
|
||||
need swap the byte order for the feilds in CapabilityData.
|
||||
|
||||
@param[in] Capability Group selection; determines the format of the response.
|
||||
@param[in] Property Further definition of information.
|
||||
@param[in] PropertyCount Number of properties of the indicated type to return.
|
||||
@param[out] MoreData Flag to indicate if there are more values of this type.
|
||||
@param[out] CapabilityData The capability data.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapability (
|
||||
IN TPM_CAP Capability,
|
||||
IN UINT32 Property,
|
||||
IN UINT32 PropertyCount,
|
||||
OUT TPMI_YES_NO *MoreData,
|
||||
OUT TPMS_CAPABILITY_DATA *CapabilityData
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_GET_CAPABILITY_COMMAND SendBuffer;
|
||||
TPM2_GET_CAPABILITY_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_GetCapability);
|
||||
|
||||
SendBuffer.Capability = SwapBytes32 (Capability);
|
||||
SendBuffer.Property = SwapBytes32 (Property);
|
||||
SendBuffer.PropertyCount = SwapBytes32 (PropertyCount);
|
||||
|
||||
SendBufferSize = (UINT32) sizeof (SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer );
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize <= sizeof (TPM2_RESPONSE_HEADER) + sizeof (UINT8)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the response
|
||||
//
|
||||
*MoreData = RecvBuffer.MoreData;
|
||||
//
|
||||
// Does not unpack all possiable property here, the caller should unpack it and note the byte order.
|
||||
//
|
||||
CopyMem (CapabilityData, &RecvBuffer.CapabilityData, RecvBufferSize - sizeof (TPM2_RESPONSE_HEADER) - sizeof (UINT8));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the information of TPM Family.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the Family.
|
||||
|
||||
@param[out] Family The Family of TPM. (a 4-octet character string)
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilityFamily (
|
||||
OUT CHAR8 *Family
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_FAMILY_INDICATOR,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
CopyMem (Family, &TpmCap.data.tpmProperties.tpmProperty->value, 4);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the information of TPM manufacture ID.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the TPM manufacture ID.
|
||||
|
||||
@param[out] ManufactureId The manufacture ID of TPM.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilityManufactureID (
|
||||
OUT UINT32 *ManufactureId
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_MANUFACTURER,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
*ManufactureId = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the information of TPM FirmwareVersion.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the TPM FirmwareVersion.
|
||||
|
||||
@param[out] FirmwareVersion1 The FirmwareVersion1.
|
||||
@param[out] FirmwareVersion2 The FirmwareVersion2.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilityFirmwareVersion (
|
||||
OUT UINT32 *FirmwareVersion1,
|
||||
OUT UINT32 *FirmwareVersion2
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_FIRMWARE_VERSION_1,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
*FirmwareVersion1 = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_FIRMWARE_VERSION_2,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
*FirmwareVersion2 = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the information of the maximum value for commandSize and responseSize in a command.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the max command size and response size
|
||||
|
||||
@param[out] MaxCommandSize The maximum value for commandSize in a command.
|
||||
@param[out] MaxResponseSize The maximum value for responseSize in a command.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilityMaxCommandResponseSize (
|
||||
OUT UINT32 *MaxCommandSize,
|
||||
OUT UINT32 *MaxResponseSize
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_MAX_COMMAND_SIZE,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
*MaxCommandSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_MAX_RESPONSE_SIZE,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
*MaxResponseSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns Returns a list of TPMS_ALG_PROPERTIES. Each entry is an
|
||||
algorithm ID and a set of properties of the algorithm.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the list.
|
||||
|
||||
@param[out] AlgList List of algorithm.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilitySupportedAlg (
|
||||
OUT TPML_ALG_PROPERTY *AlgList
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_ALGS,
|
||||
1,
|
||||
MAX_CAP_ALGS,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
CopyMem (AlgList, &TpmCap.data.algorithms, sizeof (TPML_ALG_PROPERTY));
|
||||
|
||||
AlgList->count = SwapBytes32 (AlgList->count);
|
||||
for (Index = 0; Index < AlgList->count; Index++) {
|
||||
AlgList->algProperties[Index].alg = SwapBytes16 (AlgList->algProperties[Index].alg);
|
||||
WriteUnaligned32 ((UINT32 *)&AlgList->algProperties[Index].algProperties, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&AlgList->algProperties[Index].algProperties)));
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the information of TPM LockoutCounter.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the LockoutCounter.
|
||||
|
||||
@param[out] LockoutCounter The LockoutCounter of TPM.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilityLockoutCounter (
|
||||
OUT UINT32 *LockoutCounter
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_LOCKOUT_COUNTER,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
*LockoutCounter = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the information of TPM LockoutInterval.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the LockoutInterval.
|
||||
|
||||
@param[out] LockoutInterval The LockoutInterval of TPM.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilityLockoutInterval (
|
||||
OUT UINT32 *LockoutInterval
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_LOCKOUT_INTERVAL,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
*LockoutInterval = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the information of TPM InputBufferSize.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the InputBufferSize.
|
||||
|
||||
@param[out] InputBufferSize The InputBufferSize of TPM.
|
||||
the maximum size of a parameter (typically, a TPM2B_MAX_BUFFER)
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilityInputBufferSize (
|
||||
OUT UINT32 *InputBufferSize
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_INPUT_BUFFER,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
*InputBufferSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the information of TPM PCRs.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the PcrSelection.
|
||||
|
||||
@param[out] Pcrs The Pcr Selection
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilityPcrs (
|
||||
OUT TPML_PCR_SELECTION *Pcrs
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_PCRS,
|
||||
0,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Pcrs->count = SwapBytes32 (TpmCap.data.assignedPCR.count);
|
||||
for (Index = 0; Index < Pcrs->count; Index++) {
|
||||
Pcrs->pcrSelections[Index].hash = SwapBytes16 (TpmCap.data.assignedPCR.pcrSelections[Index].hash);
|
||||
Pcrs->pcrSelections[Index].sizeofSelect = TpmCap.data.assignedPCR.pcrSelections[Index].sizeofSelect;
|
||||
CopyMem (Pcrs->pcrSelections[Index].pcrSelect, TpmCap.data.assignedPCR.pcrSelections[Index].pcrSelect, Pcrs->pcrSelections[Index].sizeofSelect);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the information of TPM AlgorithmSet.
|
||||
|
||||
This function parse the value got from TPM2_GetCapability and return the AlgorithmSet.
|
||||
|
||||
@param[out] AlgorithmSet The AlgorithmSet of TPM.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2GetCapabilityAlgorithmSet (
|
||||
OUT UINT32 *AlgorithmSet
|
||||
)
|
||||
{
|
||||
TPMS_CAPABILITY_DATA TpmCap;
|
||||
TPMI_YES_NO MoreData;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2GetCapability (
|
||||
TPM_CAP_TPM_PROPERTIES,
|
||||
TPM_PT_ALGORITHM_SET,
|
||||
1,
|
||||
&MoreData,
|
||||
&TpmCap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
*AlgorithmSet = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command is used to check to see if specific combinations of algorithm parameters are supported.
|
||||
|
||||
@param[in] Parameters Algorithm parameters to be validated
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2TestParms (
|
||||
IN TPMT_PUBLIC_PARMS *Parameters
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_TEST_PARMS_COMMAND SendBuffer;
|
||||
TPM2_TEST_PARMS_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_TestParms);
|
||||
|
||||
Buffer = (UINT8 *)&SendBuffer.Parameters;
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->type));
|
||||
Buffer += sizeof(UINT16);
|
||||
switch (Parameters->type) {
|
||||
case TPM_ALG_KEYEDHASH:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.scheme));
|
||||
Buffer += sizeof(UINT16);
|
||||
switch (Parameters->parameters.keyedHashDetail.scheme.scheme) {
|
||||
case TPM_ALG_HMAC:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.details.hmac.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_XOR:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.details.xor.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.details.xor.kdf));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
case TPM_ALG_SYMCIPHER:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.algorithm));
|
||||
Buffer += sizeof(UINT16);
|
||||
switch (Parameters->parameters.symDetail.algorithm) {
|
||||
case TPM_ALG_AES:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.aes));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.mode.aes));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_SM4:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.SM4));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.mode.SM4));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_XOR:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.xor));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
case TPM_ALG_RSA:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.algorithm));
|
||||
Buffer += sizeof(UINT16);
|
||||
switch (Parameters->parameters.rsaDetail.symmetric.algorithm) {
|
||||
case TPM_ALG_AES:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.keyBits.aes));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.mode.aes));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_SM4:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.keyBits.SM4));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.mode.SM4));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.scheme));
|
||||
Buffer += sizeof(UINT16);
|
||||
switch (Parameters->parameters.rsaDetail.scheme.scheme) {
|
||||
case TPM_ALG_RSASSA:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.rsassa.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_RSAPSS:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.rsapss.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_RSAES:
|
||||
break;
|
||||
case TPM_ALG_OAEP:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.oaep.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.keyBits));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Parameters->parameters.rsaDetail.exponent));
|
||||
Buffer += sizeof(UINT32);
|
||||
break;
|
||||
case TPM_ALG_ECC:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.algorithm));
|
||||
Buffer += sizeof(UINT16);
|
||||
switch (Parameters->parameters.eccDetail.symmetric.algorithm) {
|
||||
case TPM_ALG_AES:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.keyBits.aes));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.mode.aes));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_SM4:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.keyBits.SM4));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.mode.SM4));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.scheme));
|
||||
Buffer += sizeof(UINT16);
|
||||
switch (Parameters->parameters.eccDetail.scheme.scheme) {
|
||||
case TPM_ALG_ECDSA:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecdsa.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_ECDAA:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecdaa.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_ECSCHNORR:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecSchnorr.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_ECDH:
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.curveID));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.scheme));
|
||||
Buffer += sizeof(UINT16);
|
||||
switch (Parameters->parameters.eccDetail.kdf.scheme) {
|
||||
case TPM_ALG_MGF1:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.mgf1.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_KDF1_SP800_108:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf1_sp800_108.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_KDF1_SP800_56a:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf1_SP800_56a.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_KDF2:
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf2.hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2TestParms - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2TestParms - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
48
SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
Normal file
48
SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
Normal file
@@ -0,0 +1,48 @@
|
||||
## @file
|
||||
# This library is used by other modules to send TPM2 command.
|
||||
#
|
||||
# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Tpm2CommandLib
|
||||
FILE_GUID = 2F572F32-8BE5-4868-BD1D-7438AD97DC27
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = Tpm2CommandLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Tpm2Capability.c
|
||||
Tpm2Sequences.c
|
||||
Tpm2Integrity.c
|
||||
Tpm2Hierarchy.c
|
||||
Tpm2NVStorage.c
|
||||
Tpm2Startup.c
|
||||
Tpm2Test.c
|
||||
Tpm2DictionaryAttack.c
|
||||
Tpm2Miscellaneous.c
|
||||
Tpm2Help.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
Tpm2DeviceLib
|
203
SecurityPkg/Library/Tpm2CommandLib/Tpm2DictionaryAttack.c
Normal file
203
SecurityPkg/Library/Tpm2CommandLib/Tpm2DictionaryAttack.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/** @file
|
||||
Implement TPM2 DictionaryAttack related command.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_LOCKOUT LockHandle;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
} TPM2_DICTIONARY_ATTACK_LOCK_RESET_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_DICTIONARY_ATTACK_LOCK_RESET_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_LOCKOUT LockHandle;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
UINT32 NewMaxTries;
|
||||
UINT32 NewRecoveryTime;
|
||||
UINT32 LockoutRecovery;
|
||||
} TPM2_DICTIONARY_ATTACK_PARAMETERS_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_DICTIONARY_ATTACK_PARAMETERS_RESPONSE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
This command cancels the effect of a TPM lockout due to a number of successive authorization failures.
|
||||
If this command is properly authorized, the lockout counter is set to zero.
|
||||
|
||||
@param[in] LockHandle TPM_RH_LOCKOUT
|
||||
@param[in] AuthSession Auth Session context
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2DictionaryAttackLockReset (
|
||||
IN TPMI_RH_LOCKOUT LockHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_DICTIONARY_ATTACK_LOCK_RESET_COMMAND SendBuffer;
|
||||
TPM2_DICTIONARY_ATTACK_LOCK_RESET_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_DictionaryAttackLockReset);
|
||||
|
||||
SendBuffer.LockHandle = SwapBytes32 (LockHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackLockReset - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackLockReset - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command cancels the effect of a TPM lockout due to a number of successive authorization failures.
|
||||
If this command is properly authorized, the lockout counter is set to zero.
|
||||
|
||||
@param[in] LockHandle TPM_RH_LOCKOUT
|
||||
@param[in] AuthSession Auth Session context
|
||||
@param[in] NewMaxTries Count of authorization failures before the lockout is imposed
|
||||
@param[in] NewRecoveryTime Time in seconds before the authorization failure count is automatically decremented
|
||||
@param[in] LockoutRecovery Time in seconds after a lockoutAuth failure before use of lockoutAuth is allowed
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2DictionaryAttackParameters (
|
||||
IN TPMI_RH_LOCKOUT LockHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession,
|
||||
IN UINT32 NewMaxTries,
|
||||
IN UINT32 NewRecoveryTime,
|
||||
IN UINT32 LockoutRecovery
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_DICTIONARY_ATTACK_PARAMETERS_COMMAND SendBuffer;
|
||||
TPM2_DICTIONARY_ATTACK_PARAMETERS_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_DictionaryAttackParameters);
|
||||
|
||||
SendBuffer.LockHandle = SwapBytes32 (LockHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
//
|
||||
// Real data
|
||||
//
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(NewMaxTries));
|
||||
Buffer += sizeof(UINT32);
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(NewRecoveryTime));
|
||||
Buffer += sizeof(UINT32);
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(LockoutRecovery));
|
||||
Buffer += sizeof(UINT32);
|
||||
|
||||
SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackParameters - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackParameters - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
166
SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c
Normal file
166
SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/** @file
|
||||
Implement TPM2 help.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
typedef struct {
|
||||
TPMI_ALG_HASH HashAlgo;
|
||||
UINT16 HashSize;
|
||||
} INTERNAL_HASH_INFO;
|
||||
|
||||
STATIC INTERNAL_HASH_INFO mHashInfo[] = {
|
||||
{TPM_ALG_SHA1, SHA1_DIGEST_SIZE},
|
||||
{TPM_ALG_SHA256, SHA256_DIGEST_SIZE},
|
||||
{TPM_ALG_SM3_256, SM3_256_DIGEST_SIZE},
|
||||
{TPM_ALG_SHA384, SHA384_DIGEST_SIZE},
|
||||
{TPM_ALG_SHA512, SHA512_DIGEST_SIZE},
|
||||
};
|
||||
|
||||
/**
|
||||
Return size of digest.
|
||||
|
||||
@param[in] HashAlgo Hash algorithm
|
||||
|
||||
@return size of digest
|
||||
**/
|
||||
UINT16
|
||||
EFIAPI
|
||||
GetHashSizeFromAlgo (
|
||||
IN TPMI_ALG_HASH HashAlgo
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < sizeof(mHashInfo)/sizeof(mHashInfo[0]); Index++) {
|
||||
if (mHashInfo[Index].HashAlgo == HashAlgo) {
|
||||
return mHashInfo[Index].HashSize;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Copy AuthSessionIn to TPM2 command buffer.
|
||||
|
||||
@param [in] AuthSessionIn Input AuthSession data
|
||||
@param [out] AuthSessionOut Output AuthSession data in TPM2 command buffer
|
||||
|
||||
@return AuthSession size
|
||||
**/
|
||||
UINT32
|
||||
EFIAPI
|
||||
CopyAuthSessionCommand (
|
||||
IN TPMS_AUTH_COMMAND *AuthSessionIn, OPTIONAL
|
||||
OUT UINT8 *AuthSessionOut
|
||||
)
|
||||
{
|
||||
UINT8 *Buffer;
|
||||
|
||||
Buffer = (UINT8 *)AuthSessionOut;
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
if (AuthSessionIn != NULL) {
|
||||
// sessionHandle
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(AuthSessionIn->sessionHandle));
|
||||
Buffer += sizeof(UINT32);
|
||||
|
||||
// nonce
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->nonce.size));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
CopyMem (Buffer, AuthSessionIn->nonce.buffer, AuthSessionIn->nonce.size);
|
||||
Buffer += AuthSessionIn->nonce.size;
|
||||
|
||||
// sessionAttributes
|
||||
*(UINT8 *)Buffer = *(UINT8 *)&AuthSessionIn->sessionAttributes;
|
||||
Buffer += sizeof(UINT8);
|
||||
|
||||
// hmac
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->hmac.size));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
CopyMem (Buffer, AuthSessionIn->hmac.buffer, AuthSessionIn->hmac.size);
|
||||
Buffer += AuthSessionIn->hmac.size;
|
||||
} else {
|
||||
// sessionHandle
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(TPM_RS_PW));
|
||||
Buffer += sizeof(UINT32);
|
||||
|
||||
// nonce = nullNonce
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(0));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
// sessionAttributes = 0
|
||||
*(UINT8 *)Buffer = 0x00;
|
||||
Buffer += sizeof(UINT8);
|
||||
|
||||
// hmac = nullAuth
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(0));
|
||||
Buffer += sizeof(UINT16);
|
||||
}
|
||||
|
||||
return (UINT32)(UINTN)(Buffer - (UINT8 *)AuthSessionOut);
|
||||
}
|
||||
|
||||
/**
|
||||
Copy AuthSessionIn from TPM2 response buffer.
|
||||
|
||||
@param [in] AuthSessionIn Input AuthSession data in TPM2 response buffer
|
||||
@param [out] AuthSessionOut Output AuthSession data
|
||||
|
||||
@return AuthSession size
|
||||
**/
|
||||
UINT32
|
||||
EFIAPI
|
||||
CopyAuthSessionResponse (
|
||||
IN UINT8 *AuthSessionIn,
|
||||
OUT TPMS_AUTH_RESPONSE *AuthSessionOut OPTIONAL
|
||||
)
|
||||
{
|
||||
UINT8 *Buffer;
|
||||
TPMS_AUTH_RESPONSE LocalAuthSessionOut;
|
||||
|
||||
if (AuthSessionOut == NULL) {
|
||||
AuthSessionOut = &LocalAuthSessionOut;
|
||||
}
|
||||
|
||||
Buffer = (UINT8 *)AuthSessionIn;
|
||||
|
||||
// nonce
|
||||
AuthSessionOut->nonce.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
CopyMem (AuthSessionOut->nonce.buffer, Buffer, AuthSessionOut->nonce.size);
|
||||
Buffer += AuthSessionOut->nonce.size;
|
||||
|
||||
// sessionAttributes
|
||||
*(UINT8 *)&AuthSessionOut->sessionAttributes = *(UINT8 *)Buffer;
|
||||
Buffer += sizeof(UINT8);
|
||||
|
||||
// hmac
|
||||
AuthSessionOut->hmac.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
CopyMem (AuthSessionOut->hmac.buffer, Buffer, AuthSessionOut->hmac.size);
|
||||
Buffer += AuthSessionOut->hmac.size;
|
||||
|
||||
return (UINT32)(UINTN)(Buffer - (UINT8 *)AuthSessionIn);
|
||||
}
|
635
SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
Normal file
635
SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
Normal file
@@ -0,0 +1,635 @@
|
||||
/** @file
|
||||
Implement TPM2 Hierarchy related command.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_CLEAR AuthHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
} TPM2_CLEAR_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_CLEAR_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_CLEAR AuthHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
TPMI_YES_NO Disable;
|
||||
} TPM2_CLEAR_CONTROL_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_CLEAR_CONTROL_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_HIERARCHY_AUTH AuthHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
TPM2B_AUTH NewAuth;
|
||||
} TPM2_HIERARCHY_CHANGE_AUTH_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_PLATFORM AuthHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
} TPM2_CHANGE_EPS_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_CHANGE_EPS_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_PLATFORM AuthHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
} TPM2_CHANGE_PPS_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_CHANGE_PPS_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_HIERARCHY AuthHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
TPMI_RH_HIERARCHY Hierarchy;
|
||||
TPMI_YES_NO State;
|
||||
} TPM2_HIERARCHY_CONTROL_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_HIERARCHY_CONTROL_RESPONSE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
This command removes all TPM context associated with a specific Owner.
|
||||
|
||||
@param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
|
||||
@param[in] AuthSession Auth Session context
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2Clear (
|
||||
IN TPMI_RH_CLEAR AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_CLEAR_COMMAND Cmd;
|
||||
TPM2_CLEAR_RESPONSE Res;
|
||||
UINT32 ResultBufSize;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_Clear);
|
||||
Cmd.AuthHandle = SwapBytes32(AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&Cmd.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "Clear: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "Clear: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Clear: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Unmarshal the response
|
||||
//
|
||||
|
||||
// None
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Disables and enables the execution of TPM2_Clear().
|
||||
|
||||
@param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
|
||||
@param[in] AuthSession Auth Session context
|
||||
@param[in] Disable YES if the disableOwnerClear flag is to be SET,
|
||||
NO if the flag is to be CLEAR.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2ClearControl (
|
||||
IN TPMI_RH_CLEAR AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
|
||||
IN TPMI_YES_NO Disable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_CLEAR_CONTROL_COMMAND Cmd;
|
||||
TPM2_CLEAR_CONTROL_RESPONSE Res;
|
||||
UINT32 ResultBufSize;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_ClearControl);
|
||||
Cmd.AuthHandle = SwapBytes32(AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&Cmd.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
// disable
|
||||
*(UINT8 *)Buffer = Disable;
|
||||
Buffer += sizeof(UINT8);
|
||||
|
||||
CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "ClearControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "ClearControl: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "ClearControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Unmarshal the response
|
||||
//
|
||||
|
||||
// None
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command allows the authorization secret for a hierarchy or lockout to be changed using the current
|
||||
authorization value as the command authorization.
|
||||
|
||||
@param[in] AuthHandle TPM_RH_LOCKOUT, TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
|
||||
@param[in] AuthSession Auth Session context
|
||||
@param[in] NewAuth New authorization secret
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2HierarchyChangeAuth (
|
||||
IN TPMI_RH_HIERARCHY_AUTH AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession,
|
||||
IN TPM2B_AUTH *NewAuth
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_HIERARCHY_CHANGE_AUTH_COMMAND Cmd;
|
||||
TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT8 *ResultBuf;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyChangeAuth);
|
||||
Cmd.AuthHandle = SwapBytes32(AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&Cmd.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
// New Authorization size
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NewAuth->size));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
// New Authorizeation
|
||||
CopyMem(Buffer, NewAuth->buffer, NewAuth->size);
|
||||
Buffer += NewAuth->size;
|
||||
|
||||
CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
ResultBuf = (UINT8 *) &Res;
|
||||
ResultBufSize = sizeof(Res);
|
||||
|
||||
//
|
||||
// Call the TPM
|
||||
//
|
||||
Status = Tpm2SubmitCommand (
|
||||
CmdSize,
|
||||
(UINT8 *)&Cmd,
|
||||
&ResultBufSize,
|
||||
ResultBuf
|
||||
);
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG((EFI_D_ERROR,"HierarchyChangeAuth: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This replaces the current EPS with a value from the RNG and sets the Endorsement hierarchy controls to
|
||||
their default initialization values.
|
||||
|
||||
@param[in] AuthHandle TPM_RH_PLATFORM+{PP}
|
||||
@param[in] AuthSession Auth Session context
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2ChangeEPS (
|
||||
IN TPMI_RH_PLATFORM AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_CHANGE_EPS_COMMAND Cmd;
|
||||
TPM2_CHANGE_EPS_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT8 *ResultBuf;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangeEPS);
|
||||
Cmd.AuthHandle = SwapBytes32(AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&Cmd.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
ResultBuf = (UINT8 *) &Res;
|
||||
ResultBufSize = sizeof(Res);
|
||||
|
||||
//
|
||||
// Call the TPM
|
||||
//
|
||||
Status = Tpm2SubmitCommand (
|
||||
CmdSize,
|
||||
(UINT8 *)&Cmd,
|
||||
&ResultBufSize,
|
||||
ResultBuf
|
||||
);
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "ChangeEPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "ChangeEPS: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG((EFI_D_ERROR,"ChangeEPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This replaces the current PPS with a value from the RNG and sets platformPolicy to the default
|
||||
initialization value (the Empty Buffer).
|
||||
|
||||
@param[in] AuthHandle TPM_RH_PLATFORM+{PP}
|
||||
@param[in] AuthSession Auth Session context
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2ChangePPS (
|
||||
IN TPMI_RH_PLATFORM AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_CHANGE_PPS_COMMAND Cmd;
|
||||
TPM2_CHANGE_PPS_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT8 *ResultBuf;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangePPS);
|
||||
Cmd.AuthHandle = SwapBytes32(AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&Cmd.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
ResultBuf = (UINT8 *) &Res;
|
||||
ResultBufSize = sizeof(Res);
|
||||
|
||||
//
|
||||
// Call the TPM
|
||||
//
|
||||
Status = Tpm2SubmitCommand (
|
||||
CmdSize,
|
||||
(UINT8 *)&Cmd,
|
||||
&ResultBufSize,
|
||||
ResultBuf
|
||||
);
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "ChangePPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "ChangePPS: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG((EFI_D_ERROR,"ChangePPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command enables and disables use of a hierarchy.
|
||||
|
||||
@param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
|
||||
@param[in] AuthSession Auth Session context
|
||||
@param[in] Hierarchy Hierarchy of the enable being modified
|
||||
@param[in] State YES if the enable should be SET,
|
||||
NO if the enable should be CLEAR
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2HierarchyControl (
|
||||
IN TPMI_RH_HIERARCHY AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession,
|
||||
IN TPMI_RH_HIERARCHY Hierarchy,
|
||||
IN TPMI_YES_NO State
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_HIERARCHY_CONTROL_COMMAND Cmd;
|
||||
TPM2_HIERARCHY_CONTROL_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT8 *ResultBuf;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyControl);
|
||||
Cmd.AuthHandle = SwapBytes32(AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&Cmd.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Hierarchy));
|
||||
Buffer += sizeof(UINT32);
|
||||
|
||||
*(UINT8 *)Buffer = State;
|
||||
Buffer += sizeof(UINT8);
|
||||
|
||||
CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
ResultBuf = (UINT8 *) &Res;
|
||||
ResultBufSize = sizeof(Res);
|
||||
|
||||
//
|
||||
// Call the TPM
|
||||
//
|
||||
Status = Tpm2SubmitCommand (
|
||||
CmdSize,
|
||||
(UINT8 *)&Cmd,
|
||||
&ResultBufSize,
|
||||
ResultBuf
|
||||
);
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "HierarchyControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "HierarchyControl: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG((EFI_D_ERROR,"HierarchyControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
525
SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
Normal file
525
SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
Normal file
@@ -0,0 +1,525 @@
|
||||
/** @file
|
||||
Implement TPM2 Integrity related command.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_DH_PCR PcrHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSessionPcr;
|
||||
TPML_DIGEST_VALUES DigestValues;
|
||||
} TPM2_PCR_EXTEND_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPMS_AUTH_RESPONSE AuthSessionPcr;
|
||||
} TPM2_PCR_EXTEND_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_DH_PCR PcrHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSessionPcr;
|
||||
TPM2B_EVENT EventData;
|
||||
} TPM2_PCR_EVENT_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPML_DIGEST_VALUES Digests;
|
||||
TPMS_AUTH_RESPONSE AuthSessionPcr;
|
||||
} TPM2_PCR_EVENT_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPML_PCR_SELECTION PcrSelectionIn;
|
||||
} TPM2_PCR_READ_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 PcrUpdateCounter;
|
||||
TPML_PCR_SELECTION PcrSelectionOut;
|
||||
TPML_DIGEST PcrValues;
|
||||
} TPM2_PCR_READ_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_PLATFORM AuthHandle;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
TPML_PCR_SELECTION PcrAllocation;
|
||||
} TPM2_PCR_ALLOCATE_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMI_YES_NO AllocationSuccess;
|
||||
UINT32 MaxPCR;
|
||||
UINT32 SizeNeeded;
|
||||
UINT32 SizeAvailable;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_PCR_ALLOCATE_RESPONSE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
This command is used to cause an update to the indicated PCR.
|
||||
The digests parameter contains one or more tagged digest value identified by an algorithm ID.
|
||||
For each digest, the PCR associated with pcrHandle is Extended into the bank identified by the tag (hashAlg).
|
||||
|
||||
@param[in] PcrHandle Handle of the PCR
|
||||
@param[in] Digests List of tagged digest values to be extended
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2PcrExtend (
|
||||
IN TPMI_DH_PCR PcrHandle,
|
||||
IN TPML_DIGEST_VALUES *Digests
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_PCR_EXTEND_COMMAND Cmd;
|
||||
TPM2_PCR_EXTEND_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT32 ResultBufSize;
|
||||
UINT8 *Buffer;
|
||||
UINTN Index;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT16 DigestSize;
|
||||
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Extend);
|
||||
Cmd.PcrHandle = SwapBytes32(PcrHandle);
|
||||
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&Cmd.AuthSessionPcr;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
//Digest Count
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Digests->count));
|
||||
Buffer += sizeof(UINT32);
|
||||
|
||||
//Digest
|
||||
for (Index = 0; Index < Digests->count; Index++) {
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Digests->digests[Index].hashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
|
||||
if (DigestSize == 0) {
|
||||
DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
CopyMem(
|
||||
Buffer,
|
||||
&Digests->digests[Index].digest,
|
||||
DigestSize
|
||||
);
|
||||
Buffer += DigestSize;
|
||||
}
|
||||
|
||||
CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Unmarshal the response
|
||||
//
|
||||
|
||||
// None
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command is used to cause an update to the indicated PCR.
|
||||
The data in eventData is hashed using the hash algorithm associated with each bank in which the
|
||||
indicated PCR has been allocated. After the data is hashed, the digests list is returned. If the pcrHandle
|
||||
references an implemented PCR and not TPM_ALG_NULL, digests list is processed as in
|
||||
TPM2_PCR_Extend().
|
||||
A TPM shall support an Event.size of zero through 1,024 inclusive.
|
||||
|
||||
@param[in] PcrHandle Handle of the PCR
|
||||
@param[in] EventData Event data in sized buffer
|
||||
@param[out] Digests List of digest
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2PcrEvent (
|
||||
IN TPMI_DH_PCR PcrHandle,
|
||||
IN TPM2B_EVENT *EventData,
|
||||
OUT TPML_DIGEST_VALUES *Digests
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_PCR_EVENT_COMMAND Cmd;
|
||||
TPM2_PCR_EVENT_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT32 ResultBufSize;
|
||||
UINT8 *Buffer;
|
||||
UINTN Index;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT16 DigestSize;
|
||||
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Event);
|
||||
Cmd.PcrHandle = SwapBytes32(PcrHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&Cmd.AuthSessionPcr;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
// Event
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(EventData->size));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
CopyMem (Buffer, EventData->buffer, EventData->size);
|
||||
Buffer += EventData->size;
|
||||
|
||||
CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Unmarshal the response
|
||||
//
|
||||
Buffer = (UINT8 *)&Res.Digests;
|
||||
|
||||
Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));
|
||||
Buffer += sizeof(UINT32);
|
||||
for (Index = 0; Index < Digests->count; Index++) {
|
||||
Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
|
||||
Buffer += sizeof(UINT16);
|
||||
DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
|
||||
if (DigestSize == 0) {
|
||||
DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
CopyMem(
|
||||
&Digests->digests[Index].digest,
|
||||
Buffer,
|
||||
DigestSize
|
||||
);
|
||||
Buffer += DigestSize;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command returns the values of all PCR specified in pcrSelect.
|
||||
|
||||
@param[in] PcrSelectionIn The selection of PCR to read.
|
||||
@param[out] PcrUpdateCounter The current value of the PCR update counter.
|
||||
@param[out] PcrSelectionOut The PCR in the returned list.
|
||||
@param[out] PcrValues The contents of the PCR indicated in pcrSelect.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2PcrRead (
|
||||
IN TPML_PCR_SELECTION *PcrSelectionIn,
|
||||
OUT UINT32 *PcrUpdateCounter,
|
||||
OUT TPML_PCR_SELECTION *PcrSelectionOut,
|
||||
OUT TPML_DIGEST *PcrValues
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_PCR_READ_COMMAND SendBuffer;
|
||||
TPM2_PCR_READ_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINTN Index;
|
||||
TPML_DIGEST *PcrValuesOut;
|
||||
TPM2B_DIGEST *Digests;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PCR_Read);
|
||||
|
||||
SendBuffer.PcrSelectionIn.count = SwapBytes32(PcrSelectionIn->count);
|
||||
for (Index = 0; Index < PcrSelectionIn->count; Index++) {
|
||||
SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16(PcrSelectionIn->pcrSelections[Index].hash);
|
||||
SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;
|
||||
CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);
|
||||
}
|
||||
|
||||
SendBufferSize = sizeof(SendBuffer.Header) + sizeof(SendBuffer.PcrSelectionIn.count) + sizeof(SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the response
|
||||
//
|
||||
|
||||
//
|
||||
// PcrUpdateCounter
|
||||
//
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
*PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);
|
||||
|
||||
//
|
||||
// PcrSelectionOut
|
||||
//
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
for (Index = 0; Index < PcrSelectionOut->count; Index++) {
|
||||
PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16(RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);
|
||||
PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;
|
||||
CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);
|
||||
}
|
||||
|
||||
//
|
||||
// PcrValues
|
||||
//
|
||||
PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);
|
||||
PcrValues->count = SwapBytes32(PcrValuesOut->count);
|
||||
Digests = PcrValuesOut->digests;
|
||||
for (Index = 0; Index < PcrValues->count; Index++) {
|
||||
PcrValues->digests[Index].size = SwapBytes16(Digests->size);
|
||||
CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);
|
||||
Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof(Digests->size) + PcrValues->digests[Index].size);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command is used to set the desired PCR allocation of PCR and algorithms.
|
||||
|
||||
@param[in] AuthHandle TPM_RH_PLATFORM+{PP}
|
||||
@param[in] AuthSession Auth Session context
|
||||
@param[in] PcrAllocation The requested allocation
|
||||
@param[out] AllocationSuccess YES if the allocation succeeded
|
||||
@param[out] MaxPCR maximum number of PCR that may be in a bank
|
||||
@param[out] SizeNeeded number of octets required to satisfy the request
|
||||
@param[out] SizeAvailable Number of octets available. Computed before the allocation
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2PcrAllocate (
|
||||
IN TPMI_RH_PLATFORM AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession,
|
||||
IN TPML_PCR_SELECTION *PcrAllocation,
|
||||
OUT TPMI_YES_NO *AllocationSuccess,
|
||||
OUT UINT32 *MaxPCR,
|
||||
OUT UINT32 *SizeNeeded,
|
||||
OUT UINT32 *SizeAvailable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_PCR_ALLOCATE_COMMAND Cmd;
|
||||
TPM2_PCR_ALLOCATE_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT8 *ResultBuf;
|
||||
UINT32 ResultBufSize;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Allocate);
|
||||
Cmd.AuthHandle = SwapBytes32(AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&Cmd.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
Cmd.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
// Count
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(PcrAllocation->count));
|
||||
Buffer += sizeof(UINT32);
|
||||
for (Index = 0; Index < PcrAllocation->count; Index++) {
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PcrAllocation->pcrSelections[Index].hash));
|
||||
Buffer += sizeof(UINT16);
|
||||
*(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;
|
||||
Buffer += sizeof(UINT8);
|
||||
CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);
|
||||
Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;
|
||||
}
|
||||
|
||||
CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
ResultBuf = (UINT8 *) &Res;
|
||||
ResultBufSize = sizeof(Res);
|
||||
|
||||
//
|
||||
// Call the TPM
|
||||
//
|
||||
Status = Tpm2SubmitCommand (
|
||||
CmdSize,
|
||||
(UINT8 *)&Cmd,
|
||||
&ResultBufSize,
|
||||
ResultBuf
|
||||
);
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the response
|
||||
//
|
||||
*AllocationSuccess = Res.AllocationSuccess;
|
||||
*MaxPCR = SwapBytes32(Res.MaxPCR);
|
||||
*SizeNeeded = SwapBytes32(Res.SizeNeeded);
|
||||
*SizeAvailable = SwapBytes32(Res.SizeAvailable);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
114
SecurityPkg/Library/Tpm2CommandLib/Tpm2Miscellaneous.c
Normal file
114
SecurityPkg/Library/Tpm2CommandLib/Tpm2Miscellaneous.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/** @file
|
||||
Implement TPM2 Miscellanenous related command.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_HIERARCHY_AUTH AuthHandle;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
UINT32 AlgorithmSet;
|
||||
} TPM2_SET_ALGORITHM_SET_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_SET_ALGORITHM_SET_RESPONSE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
This command allows the platform to change the set of algorithms that are used by the TPM.
|
||||
The algorithmSet setting is a vendor-dependent value.
|
||||
|
||||
@param[in] AuthHandle TPM_RH_PLATFORM
|
||||
@param[in] AuthSession Auth Session context
|
||||
@param[in] AlgorithmSet A TPM vendor-dependent value indicating the
|
||||
algorithm set selection
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2SetAlgorithmSet (
|
||||
IN TPMI_RH_PLATFORM AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession,
|
||||
IN UINT32 AlgorithmSet
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_SET_ALGORITHM_SET_COMMAND SendBuffer;
|
||||
TPM2_SET_ALGORITHM_SET_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_SetAlgorithmSet);
|
||||
|
||||
SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
//
|
||||
// Real data
|
||||
//
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(AlgorithmSet));
|
||||
Buffer += sizeof(UINT32);
|
||||
|
||||
SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2SetAlgorithmSet - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2SetAlgorithmSet - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
938
SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
Normal file
938
SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
Normal file
@@ -0,0 +1,938 @@
|
||||
/** @file
|
||||
Implement TPM2 NVStorage related command.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define RC_NV_ReadPublic_nvIndex (TPM_RC_H + TPM_RC_1)
|
||||
|
||||
#define RC_NV_DefineSpace_authHandle (TPM_RC_H + TPM_RC_1)
|
||||
#define RC_NV_DefineSpace_auth (TPM_RC_P + TPM_RC_1)
|
||||
#define RC_NV_DefineSpace_publicInfo (TPM_RC_P + TPM_RC_2)
|
||||
|
||||
#define RC_NV_UndefineSpace_authHandle (TPM_RC_H + TPM_RC_1)
|
||||
#define RC_NV_UndefineSpace_nvIndex (TPM_RC_H + TPM_RC_2)
|
||||
|
||||
#define RC_NV_Read_authHandle (TPM_RC_H + TPM_RC_1)
|
||||
#define RC_NV_Read_nvIndex (TPM_RC_H + TPM_RC_2)
|
||||
#define RC_NV_Read_size (TPM_RC_P + TPM_RC_1)
|
||||
#define RC_NV_Read_offset (TPM_RC_P + TPM_RC_2)
|
||||
|
||||
#define RC_NV_Write_authHandle (TPM_RC_H + TPM_RC_1)
|
||||
#define RC_NV_Write_nvIndex (TPM_RC_H + TPM_RC_2)
|
||||
#define RC_NV_Write_data (TPM_RC_P + TPM_RC_1)
|
||||
#define RC_NV_Write_offset (TPM_RC_P + TPM_RC_2)
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_NV_INDEX NvIndex;
|
||||
} TPM2_NV_READPUBLIC_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
TPM2B_NV_PUBLIC NvPublic;
|
||||
TPM2B_NAME NvName;
|
||||
} TPM2_NV_READPUBLIC_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_PROVISION AuthHandle;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
TPM2B_AUTH Auth;
|
||||
TPM2B_NV_PUBLIC NvPublic;
|
||||
} TPM2_NV_DEFINESPACE_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_NV_DEFINESPACE_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_PROVISION AuthHandle;
|
||||
TPMI_RH_NV_INDEX NvIndex;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
} TPM2_NV_UNDEFINESPACE_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_NV_UNDEFINESPACE_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_NV_AUTH AuthHandle;
|
||||
TPMI_RH_NV_INDEX NvIndex;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
UINT16 Size;
|
||||
UINT16 Offset;
|
||||
} TPM2_NV_READ_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPM2B_MAX_BUFFER Data;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_NV_READ_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_NV_AUTH AuthHandle;
|
||||
TPMI_RH_NV_INDEX NvIndex;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
TPM2B_MAX_BUFFER Data;
|
||||
UINT16 Offset;
|
||||
} TPM2_NV_WRITE_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_NV_WRITE_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_NV_AUTH AuthHandle;
|
||||
TPMI_RH_NV_INDEX NvIndex;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
} TPM2_NV_READLOCK_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_NV_READLOCK_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_NV_AUTH AuthHandle;
|
||||
TPMI_RH_NV_INDEX NvIndex;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
} TPM2_NV_WRITELOCK_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_NV_WRITELOCK_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_RH_PROVISION AuthHandle;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_COMMAND AuthSession;
|
||||
} TPM2_NV_GLOBALWRITELOCK_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 AuthSessionSize;
|
||||
TPMS_AUTH_RESPONSE AuthSession;
|
||||
} TPM2_NV_GLOBALWRITELOCK_RESPONSE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
This command is used to read the public area and Name of an NV Index.
|
||||
|
||||
@param[in] NvIndex The NV Index.
|
||||
@param[out] NvPublic The public area of the index.
|
||||
@param[out] NvName The Name of the nvIndex.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2NvReadPublic (
|
||||
IN TPMI_RH_NV_INDEX NvIndex,
|
||||
OUT TPM2B_NV_PUBLIC *NvPublic,
|
||||
OUT TPM2B_NAME *NvName
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_NV_READPUBLIC_COMMAND SendBuffer;
|
||||
TPM2_NV_READPUBLIC_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT16 NvPublicSize;
|
||||
UINT16 NvNameSize;
|
||||
UINT8 *Buffer;
|
||||
TPM_RC ResponseCode;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_ReadPublic);
|
||||
|
||||
SendBuffer.NvIndex = SwapBytes32 (NvIndex);
|
||||
|
||||
SendBufferSize = (UINT32) sizeof (SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
|
||||
if (ResponseCode != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
}
|
||||
switch (ResponseCode) {
|
||||
case TPM_RC_SUCCESS:
|
||||
// return data
|
||||
break;
|
||||
case TPM_RC_HANDLE + RC_NV_ReadPublic_nvIndex: // TPM_RC_NV_DEFINED:
|
||||
return EFI_NOT_FOUND;
|
||||
case TPM_RC_VALUE + RC_NV_ReadPublic_nvIndex:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (RecvBufferSize <= sizeof (TPM2_RESPONSE_HEADER) + sizeof (UINT16) + sizeof(UINT16)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Basic check
|
||||
//
|
||||
NvPublicSize = SwapBytes16 (RecvBuffer.NvPublic.size);
|
||||
NvNameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize)));
|
||||
|
||||
if (RecvBufferSize != sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize + sizeof(UINT16) + NvNameSize) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - RecvBufferSize Error - NvPublicSize %x, NvNameSize %x\n", RecvBufferSize, NvNameSize));
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the response
|
||||
//
|
||||
CopyMem (NvPublic, &RecvBuffer.NvPublic, sizeof(UINT16) + NvPublicSize);
|
||||
NvPublic->size = NvPublicSize;
|
||||
NvPublic->nvPublic.nvIndex = SwapBytes32 (NvPublic->nvPublic.nvIndex);
|
||||
NvPublic->nvPublic.nameAlg = SwapBytes16 (NvPublic->nvPublic.nameAlg);
|
||||
WriteUnaligned32 ((UINT32 *)&NvPublic->nvPublic.attributes, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&NvPublic->nvPublic.attributes)));
|
||||
NvPublic->nvPublic.authPolicy.size = SwapBytes16 (NvPublic->nvPublic.authPolicy.size);
|
||||
Buffer = (UINT8 *)&NvPublic->nvPublic.authPolicy;
|
||||
Buffer += sizeof(UINT16) + NvPublic->nvPublic.authPolicy.size;
|
||||
NvPublic->nvPublic.dataSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
|
||||
|
||||
CopyMem (NvName, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize, NvNameSize);
|
||||
NvName->size = NvNameSize;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command defines the attributes of an NV Index and causes the TPM to
|
||||
reserve space to hold the data associated with the index.
|
||||
If a definition already exists at the index, the TPM will return TPM_RC_NV_DEFINED.
|
||||
|
||||
@param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
|
||||
@param[in] AuthSession Auth Session context
|
||||
@param[in] Auth The authorization data.
|
||||
@param[in] NvPublic The public area of the index.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
@retval EFI_ALREADY_STARTED The command was returned successfully, but NvIndex is already defined.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2NvDefineSpace (
|
||||
IN TPMI_RH_PROVISION AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
|
||||
IN TPM2B_AUTH *Auth,
|
||||
IN TPM2B_NV_PUBLIC *NvPublic
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_NV_DEFINESPACE_COMMAND SendBuffer;
|
||||
TPM2_NV_DEFINESPACE_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT16 NvPublicSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
TPM_RC ResponseCode;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_DefineSpace);
|
||||
SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
//
|
||||
// IndexAuth
|
||||
//
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Auth->size));
|
||||
Buffer += sizeof(UINT16);
|
||||
CopyMem(Buffer, Auth->buffer, Auth->size);
|
||||
Buffer += Auth->size;
|
||||
|
||||
//
|
||||
// NvPublic
|
||||
//
|
||||
NvPublicSize = NvPublic->size;
|
||||
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublicSize));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (NvPublic->nvPublic.nvIndex));
|
||||
Buffer += sizeof(UINT32);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublic->nvPublic.nameAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&NvPublic->nvPublic.attributes)));
|
||||
Buffer += sizeof(UINT32);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublic->nvPublic.authPolicy.size));
|
||||
Buffer += sizeof(UINT16);
|
||||
CopyMem (Buffer, NvPublic->nvPublic.authPolicy.buffer, NvPublic->nvPublic.authPolicy.size);
|
||||
Buffer += NvPublic->nvPublic.authPolicy.size;
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublic->nvPublic.dataSize));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvDefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
|
||||
if (ResponseCode != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvDefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
}
|
||||
switch (ResponseCode) {
|
||||
case TPM_RC_SUCCESS:
|
||||
// return data
|
||||
break;
|
||||
case TPM_RC_SIZE + RC_NV_DefineSpace_publicInfo:
|
||||
case TPM_RC_SIZE + RC_NV_DefineSpace_auth:
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
case TPM_RC_ATTRIBUTES:
|
||||
case TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo:
|
||||
return EFI_UNSUPPORTED;
|
||||
case TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_authHandle:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_NV_DEFINED:
|
||||
return EFI_ALREADY_STARTED;
|
||||
case TPM_RC_VALUE + RC_NV_DefineSpace_publicInfo:
|
||||
case TPM_RC_VALUE + RC_NV_DefineSpace_authHandle:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_NV_SPACE:
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command removes an index from the TPM.
|
||||
|
||||
@param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
|
||||
@param[in] NvIndex The NV Index.
|
||||
@param[in] AuthSession Auth Session context
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2NvUndefineSpace (
|
||||
IN TPMI_RH_PROVISION AuthHandle,
|
||||
IN TPMI_RH_NV_INDEX NvIndex,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_NV_UNDEFINESPACE_COMMAND SendBuffer;
|
||||
TPM2_NV_UNDEFINESPACE_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
TPM_RC ResponseCode;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_UndefineSpace);
|
||||
|
||||
SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
|
||||
SendBuffer.NvIndex = SwapBytes32 (NvIndex);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvUndefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
|
||||
if (ResponseCode != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvUndefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
}
|
||||
switch (ResponseCode) {
|
||||
case TPM_RC_SUCCESS:
|
||||
// return data
|
||||
break;
|
||||
case TPM_RC_ATTRIBUTES:
|
||||
case TPM_RC_ATTRIBUTES + RC_NV_UndefineSpace_nvIndex:
|
||||
return EFI_UNSUPPORTED;
|
||||
case TPM_RC_NV_AUTHORIZATION:
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
case TPM_RC_HANDLE + RC_NV_UndefineSpace_nvIndex: // TPM_RC_NV_DEFINED:
|
||||
return EFI_NOT_FOUND;
|
||||
case TPM_RC_HANDLE + RC_NV_UndefineSpace_authHandle: // TPM_RC_NV_DEFINED:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_VALUE + RC_NV_UndefineSpace_authHandle:
|
||||
case TPM_RC_VALUE + RC_NV_UndefineSpace_nvIndex:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command reads a value from an area in NV memory previously defined by TPM2_NV_DefineSpace().
|
||||
|
||||
@param[in] AuthHandle the handle indicating the source of the authorization value.
|
||||
@param[in] NvIndex The index to be read.
|
||||
@param[in] AuthSession Auth Session context
|
||||
@param[in] Size Number of bytes to read.
|
||||
@param[in] Offset Byte offset into the area.
|
||||
@param[in,out] OutData The data read.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2NvRead (
|
||||
IN TPMI_RH_NV_AUTH AuthHandle,
|
||||
IN TPMI_RH_NV_INDEX NvIndex,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
|
||||
IN UINT16 Size,
|
||||
IN UINT16 Offset,
|
||||
IN OUT TPM2B_MAX_BUFFER *OutData
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_NV_READ_COMMAND SendBuffer;
|
||||
TPM2_NV_READ_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
TPM_RC ResponseCode;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_Read);
|
||||
|
||||
SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
|
||||
SendBuffer.NvIndex = SwapBytes32 (NvIndex);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Size));
|
||||
Buffer += sizeof(UINT16);
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Offset));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvRead - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
|
||||
if (ResponseCode != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvRead - responseCode - %x\n", ResponseCode));
|
||||
}
|
||||
switch (ResponseCode) {
|
||||
case TPM_RC_SUCCESS:
|
||||
// return data
|
||||
break;
|
||||
case TPM_RC_NV_AUTHORIZATION:
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
case TPM_RC_NV_LOCKED:
|
||||
return EFI_ACCESS_DENIED;
|
||||
case TPM_RC_NV_RANGE:
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
case TPM_RC_NV_UNINITIALIZED:
|
||||
return EFI_NOT_READY;
|
||||
case TPM_RC_HANDLE + RC_NV_Read_nvIndex: // TPM_RC_NV_DEFINED:
|
||||
return EFI_NOT_FOUND;
|
||||
case TPM_RC_HANDLE + RC_NV_Read_authHandle: // TPM_RC_NV_DEFINED:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_VALUE + RC_NV_Read_nvIndex:
|
||||
case TPM_RC_VALUE + RC_NV_Read_authHandle:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_BAD_AUTH + RC_NV_Read_authHandle + TPM_RC_S:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_AUTH_UNAVAILABLE:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_AUTH_FAIL + RC_NV_Read_authHandle + TPM_RC_S:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
case TPM_RC_ATTRIBUTES + RC_NV_Read_authHandle + TPM_RC_S:
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the response
|
||||
//
|
||||
OutData->size = SwapBytes16 (RecvBuffer.Data.size);
|
||||
CopyMem (OutData->buffer, &RecvBuffer.Data.buffer, OutData->size);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command writes a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().
|
||||
|
||||
@param[in] AuthHandle the handle indicating the source of the authorization value.
|
||||
@param[in] NvIndex The NV Index of the area to write.
|
||||
@param[in] AuthSession Auth Session context
|
||||
@param[in] InData The data to write.
|
||||
@param[in] Offset The offset into the NV Area.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2NvWrite (
|
||||
IN TPMI_RH_NV_AUTH AuthHandle,
|
||||
IN TPMI_RH_NV_INDEX NvIndex,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
|
||||
IN TPM2B_MAX_BUFFER *InData,
|
||||
IN UINT16 Offset
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_NV_WRITE_COMMAND SendBuffer;
|
||||
TPM2_NV_WRITE_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
TPM_RC ResponseCode;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_Write);
|
||||
|
||||
SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
|
||||
SendBuffer.NvIndex = SwapBytes32 (NvIndex);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (InData->size));
|
||||
Buffer += sizeof(UINT16);
|
||||
CopyMem (Buffer, InData->buffer, InData->size);
|
||||
Buffer += InData->size;
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Offset));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
SendBufferSize = (UINT32) (Buffer - (UINT8 *)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvWrite - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
|
||||
if (ResponseCode != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvWrite - responseCode - %x\n", ResponseCode));
|
||||
}
|
||||
switch (ResponseCode) {
|
||||
case TPM_RC_SUCCESS:
|
||||
return EFI_SUCCESS;
|
||||
case TPM_RC_ATTRIBUTES:
|
||||
return EFI_UNSUPPORTED;
|
||||
case TPM_RC_NV_AUTHORIZATION:
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
case TPM_RC_NV_LOCKED:
|
||||
return EFI_ACCESS_DENIED;
|
||||
case TPM_RC_NV_RANGE:
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
case TPM_RC_HANDLE + RC_NV_Write_nvIndex: // TPM_RC_NV_DEFINED:
|
||||
return EFI_NOT_FOUND;
|
||||
case TPM_RC_HANDLE + RC_NV_Write_authHandle: // TPM_RC_NV_DEFINED:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_VALUE + RC_NV_Write_nvIndex:
|
||||
case TPM_RC_VALUE + RC_NV_Write_authHandle:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_BAD_AUTH + RC_NV_Write_authHandle + TPM_RC_S:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_AUTH_UNAVAILABLE:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
case TPM_RC_AUTH_FAIL + RC_NV_Write_authHandle + TPM_RC_S:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
case TPM_RC_ATTRIBUTES + RC_NV_Write_authHandle + TPM_RC_S:
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This command may be used to prevent further reads of the Index until the next TPM2_Startup (TPM_SU_CLEAR).
|
||||
|
||||
@param[in] AuthHandle the handle indicating the source of the authorization value.
|
||||
@param[in] NvIndex The NV Index of the area to lock.
|
||||
@param[in] AuthSession Auth Session context
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2NvReadLock (
|
||||
IN TPMI_RH_NV_AUTH AuthHandle,
|
||||
IN TPMI_RH_NV_INDEX NvIndex,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_NV_READLOCK_COMMAND SendBuffer;
|
||||
TPM2_NV_READLOCK_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
TPM_RC ResponseCode;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_ReadLock);
|
||||
|
||||
SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
|
||||
SendBuffer.NvIndex = SwapBytes32 (NvIndex);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvReadLock - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
|
||||
if (ResponseCode != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvReadLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
}
|
||||
switch (ResponseCode) {
|
||||
case TPM_RC_SUCCESS:
|
||||
// return data
|
||||
break;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command may be used to inhibit further writes of the Index.
|
||||
|
||||
@param[in] AuthHandle the handle indicating the source of the authorization value.
|
||||
@param[in] NvIndex The NV Index of the area to lock.
|
||||
@param[in] AuthSession Auth Session context
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2NvWriteLock (
|
||||
IN TPMI_RH_NV_AUTH AuthHandle,
|
||||
IN TPMI_RH_NV_INDEX NvIndex,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_NV_WRITELOCK_COMMAND SendBuffer;
|
||||
TPM2_NV_WRITELOCK_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
TPM_RC ResponseCode;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_WriteLock);
|
||||
|
||||
SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
|
||||
SendBuffer.NvIndex = SwapBytes32 (NvIndex);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
|
||||
if (ResponseCode != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
}
|
||||
switch (ResponseCode) {
|
||||
case TPM_RC_SUCCESS:
|
||||
// return data
|
||||
break;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
The command will SET TPMA_NV_WRITELOCKED for all indexes that have their TPMA_NV_GLOBALLOCK attribute SET.
|
||||
|
||||
@param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
|
||||
@param[in] AuthSession Auth Session context
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
@retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2NvGlobalWriteLock (
|
||||
IN TPMI_RH_PROVISION AuthHandle,
|
||||
IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_NV_GLOBALWRITELOCK_COMMAND SendBuffer;
|
||||
TPM2_NV_GLOBALWRITELOCK_RESPONSE RecvBuffer;
|
||||
UINT32 SendBufferSize;
|
||||
UINT32 RecvBufferSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 SessionInfoSize;
|
||||
TPM_RC ResponseCode;
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_GlobalWriteLock);
|
||||
|
||||
SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
Buffer = (UINT8 *)&SendBuffer.AuthSession;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
|
||||
Buffer += SessionInfoSize;
|
||||
SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
|
||||
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
|
||||
|
||||
//
|
||||
// send Tpm command
|
||||
//
|
||||
RecvBufferSize = sizeof (RecvBuffer);
|
||||
Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvGlobalWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);
|
||||
if (ResponseCode != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2NvGlobalWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
|
||||
}
|
||||
switch (ResponseCode) {
|
||||
case TPM_RC_SUCCESS:
|
||||
// return data
|
||||
break;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
508
SecurityPkg/Library/Tpm2CommandLib/Tpm2Sequences.c
Normal file
508
SecurityPkg/Library/Tpm2CommandLib/Tpm2Sequences.c
Normal file
@@ -0,0 +1,508 @@
|
||||
/** @file
|
||||
Implement TPM2 Sequences related command.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPM2B_AUTH Auth;
|
||||
TPMI_ALG_HASH HashAlg;
|
||||
} TPM2_HASH_SEQUENCE_START_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
TPMI_DH_OBJECT SequenceHandle;
|
||||
} TPM2_HASH_SEQUENCE_START_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_DH_OBJECT SequenceHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSessionSeq;
|
||||
TPM2B_MAX_BUFFER Buffer;
|
||||
} TPM2_SEQUENCE_UPDATE_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPMS_AUTH_RESPONSE AuthSessionSeq;
|
||||
} TPM2_SEQUENCE_UPDATE_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_DH_PCR PcrHandle;
|
||||
TPMI_DH_OBJECT SequenceHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSessionPcr;
|
||||
TPMS_AUTH_COMMAND AuthSessionSeq;
|
||||
TPM2B_MAX_BUFFER Buffer;
|
||||
} TPM2_EVENT_SEQUENCE_COMPLETE_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPML_DIGEST_VALUES Results;
|
||||
TPMS_AUTH_RESPONSE AuthSessionPcr;
|
||||
TPMS_AUTH_RESPONSE AuthSessionSeq;
|
||||
} TPM2_EVENT_SEQUENCE_COMPLETE_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_DH_OBJECT SequenceHandle;
|
||||
UINT32 AuthorizationSize;
|
||||
TPMS_AUTH_COMMAND AuthSessionSeq;
|
||||
TPM2B_MAX_BUFFER Buffer;
|
||||
TPMI_RH_HIERARCHY Hierarchy;
|
||||
} TPM2_SEQUENCE_COMPLETE_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
UINT32 ParameterSize;
|
||||
TPM2B_DIGEST Digest;
|
||||
TPMS_AUTH_RESPONSE AuthSessionSeq;
|
||||
} TPM2_SEQUENCE_COMPLETE_RESPONSE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
This command starts a hash or an Event sequence.
|
||||
If hashAlg is an implemented hash, then a hash sequence is started.
|
||||
If hashAlg is TPM_ALG_NULL, then an Event sequence is started.
|
||||
|
||||
@param[in] HashAlg The hash algorithm to use for the hash sequence
|
||||
An Event sequence starts if this is TPM_ALG_NULL.
|
||||
@param[out] SequenceHandle A handle to reference the sequence
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2HashSequenceStart (
|
||||
IN TPMI_ALG_HASH HashAlg,
|
||||
OUT TPMI_DH_OBJECT *SequenceHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_HASH_SEQUENCE_START_COMMAND Cmd;
|
||||
TPM2_HASH_SEQUENCE_START_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *Buffer;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
ZeroMem(&Cmd, sizeof(Cmd));
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_HashSequenceStart);
|
||||
|
||||
Buffer = (UINT8 *)&Cmd.Auth;
|
||||
|
||||
// auth = nullAuth
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(0));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
// hashAlg
|
||||
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(HashAlg));
|
||||
Buffer += sizeof(UINT16);
|
||||
|
||||
CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
//
|
||||
// Call the TPM
|
||||
//
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "HashSequenceStart: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "HashSequenceStart: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "HashSequenceStart: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Unmarshal the response
|
||||
//
|
||||
|
||||
// sequenceHandle
|
||||
*SequenceHandle = SwapBytes32(Res.SequenceHandle);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command is used to add data to a hash or HMAC sequence.
|
||||
The amount of data in buffer may be any size up to the limits of the TPM.
|
||||
NOTE: In all TPM, a buffer size of 1,024 octets is allowed.
|
||||
|
||||
@param[in] SequenceHandle Handle for the sequence object
|
||||
@param[in] Buffer Data to be added to hash
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2SequenceUpdate (
|
||||
IN TPMI_DH_OBJECT SequenceHandle,
|
||||
IN TPM2B_MAX_BUFFER *Buffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_SEQUENCE_UPDATE_COMMAND Cmd;
|
||||
TPM2_SEQUENCE_UPDATE_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *BufferPtr;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
ZeroMem(&Cmd, sizeof(Cmd));
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_SequenceUpdate);
|
||||
Cmd.SequenceHandle = SwapBytes32(SequenceHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
BufferPtr = (UINT8 *)&Cmd.AuthSessionSeq;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (NULL, BufferPtr);
|
||||
BufferPtr += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
// buffer.size
|
||||
WriteUnaligned16 ((UINT16 *)BufferPtr, SwapBytes16(Buffer->size));
|
||||
BufferPtr += sizeof(UINT16);
|
||||
|
||||
CopyMem(BufferPtr, &Buffer->buffer, Buffer->size);
|
||||
BufferPtr += Buffer->size;
|
||||
|
||||
CmdSize = (UINT32)(BufferPtr - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
//
|
||||
// Call the TPM
|
||||
//
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd,&ResultBufSize, (UINT8 *)&Res);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "SequenceUpdate: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "SequenceUpdate: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "SequenceUpdate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Unmarshal the response
|
||||
//
|
||||
|
||||
// None
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command adds the last part of data, if any, to an Event sequence and returns the result in a digest list.
|
||||
If pcrHandle references a PCR and not TPM_RH_NULL, then the returned digest list is processed in
|
||||
the same manner as the digest list input parameter to TPM2_PCR_Extend() with the pcrHandle in each
|
||||
bank extended with the associated digest value.
|
||||
|
||||
@param[in] PcrHandle PCR to be extended with the Event data
|
||||
@param[in] SequenceHandle Authorization for the sequence
|
||||
@param[in] Buffer Data to be added to the Event
|
||||
@param[out] Results List of digests computed for the PCR
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2EventSequenceComplete (
|
||||
IN TPMI_DH_PCR PcrHandle,
|
||||
IN TPMI_DH_OBJECT SequenceHandle,
|
||||
IN TPM2B_MAX_BUFFER *Buffer,
|
||||
OUT TPML_DIGEST_VALUES *Results
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_EVENT_SEQUENCE_COMPLETE_COMMAND Cmd;
|
||||
TPM2_EVENT_SEQUENCE_COMPLETE_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *BufferPtr;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT32 SessionInfoSize2;
|
||||
UINT32 Index;
|
||||
UINT32 ResultBufSize;
|
||||
UINT16 DigestSize;
|
||||
|
||||
ZeroMem(&Cmd, sizeof(Cmd));
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_EventSequenceComplete);
|
||||
Cmd.PcrHandle = SwapBytes32(PcrHandle);
|
||||
Cmd.SequenceHandle = SwapBytes32(SequenceHandle);
|
||||
|
||||
//
|
||||
// Add in pcrHandle Auth session
|
||||
//
|
||||
BufferPtr = (UINT8 *)&Cmd.AuthSessionPcr;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (NULL, BufferPtr);
|
||||
BufferPtr += SessionInfoSize;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize2 = CopyAuthSessionCommand (NULL, BufferPtr);
|
||||
BufferPtr += SessionInfoSize2;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize + SessionInfoSize2);
|
||||
|
||||
// buffer.size
|
||||
WriteUnaligned16 ((UINT16 *)BufferPtr, SwapBytes16(Buffer->size));
|
||||
BufferPtr += sizeof(UINT16);
|
||||
|
||||
CopyMem(BufferPtr, &Buffer->buffer[0], Buffer->size);
|
||||
BufferPtr += Buffer->size;
|
||||
|
||||
CmdSize = (UINT32)(BufferPtr - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
//
|
||||
// Call the TPM
|
||||
//
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "EventSequenceComplete: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "EventSequenceComplete: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "EventSequenceComplete: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Unmarshal the response
|
||||
//
|
||||
|
||||
BufferPtr = (UINT8 *)&Res.Results;
|
||||
|
||||
// count
|
||||
Results->count = SwapBytes32(ReadUnaligned32 ((UINT32 *)BufferPtr));
|
||||
BufferPtr += sizeof(UINT32);
|
||||
|
||||
for (Index = 0; Index < Results->count; Index++) {
|
||||
Results->digests[Index].hashAlg = SwapBytes16(ReadUnaligned16 ((UINT16 *)BufferPtr));
|
||||
BufferPtr += sizeof(UINT16);
|
||||
|
||||
DigestSize = GetHashSizeFromAlgo (Results->digests[Index].hashAlg);
|
||||
if (DigestSize == 0) {
|
||||
DEBUG ((EFI_D_ERROR, "EventSequenceComplete: Unknown hash algorithm %d\r\n", Results->digests[Index].hashAlg));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
CopyMem(
|
||||
&Results->digests[Index].digest,
|
||||
BufferPtr,
|
||||
DigestSize
|
||||
);
|
||||
BufferPtr += DigestSize;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This command adds the last part of data, if any, to a hash/HMAC sequence and returns the result.
|
||||
|
||||
@param[in] SequenceHandle Authorization for the sequence
|
||||
@param[in] Buffer Data to be added to the hash/HMAC
|
||||
@param[out] Result The returned HMAC or digest in a sized buffer
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2SequenceComplete (
|
||||
IN TPMI_DH_OBJECT SequenceHandle,
|
||||
IN TPM2B_MAX_BUFFER *Buffer,
|
||||
OUT TPM2B_DIGEST *Result
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_SEQUENCE_COMPLETE_COMMAND Cmd;
|
||||
TPM2_SEQUENCE_COMPLETE_RESPONSE Res;
|
||||
UINT32 CmdSize;
|
||||
UINT32 RespSize;
|
||||
UINT8 *BufferPtr;
|
||||
UINT32 SessionInfoSize;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
ZeroMem(&Cmd, sizeof(Cmd));
|
||||
|
||||
//
|
||||
// Construct command
|
||||
//
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_SequenceComplete);
|
||||
Cmd.SequenceHandle = SwapBytes32(SequenceHandle);
|
||||
|
||||
//
|
||||
// Add in Auth session
|
||||
//
|
||||
BufferPtr = (UINT8 *)&Cmd.AuthSessionSeq;
|
||||
|
||||
// sessionInfoSize
|
||||
SessionInfoSize = CopyAuthSessionCommand (NULL, BufferPtr);
|
||||
BufferPtr += SessionInfoSize;
|
||||
Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
|
||||
|
||||
// buffer.size
|
||||
WriteUnaligned16 ((UINT16 *)BufferPtr, SwapBytes16(Buffer->size));
|
||||
BufferPtr += sizeof(UINT16);
|
||||
|
||||
CopyMem(BufferPtr, &Buffer->buffer[0], Buffer->size);
|
||||
BufferPtr += Buffer->size;
|
||||
|
||||
// Hierarchy
|
||||
WriteUnaligned32 ((UINT32 *)BufferPtr, SwapBytes32 (TPM_RH_NULL));
|
||||
BufferPtr += sizeof (UINT32);
|
||||
|
||||
CmdSize = (UINT32)(BufferPtr - (UINT8 *)&Cmd);
|
||||
Cmd.Header.paramSize = SwapBytes32(CmdSize);
|
||||
|
||||
//
|
||||
// Call the TPM
|
||||
//
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ResultBufSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "SequenceComplete: Failed ExecuteCommand: Buffer Too Small\r\n"));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate response headers
|
||||
//
|
||||
RespSize = SwapBytes32(Res.Header.paramSize);
|
||||
if (RespSize > sizeof(Res)) {
|
||||
DEBUG ((EFI_D_ERROR, "SequenceComplete: Response size too large! %d\r\n", RespSize));
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Fail if command failed
|
||||
//
|
||||
if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
|
||||
DEBUG ((EFI_D_ERROR, "SequenceComplete: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Unmarshal the response
|
||||
//
|
||||
|
||||
BufferPtr = (UINT8 *)&Res.Digest;
|
||||
|
||||
// digestSize
|
||||
Result->size = SwapBytes16(ReadUnaligned16 ((UINT16 *)BufferPtr));
|
||||
BufferPtr += sizeof(UINT16);
|
||||
|
||||
CopyMem(
|
||||
Result->buffer,
|
||||
BufferPtr,
|
||||
Result->size
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
102
SecurityPkg/Library/Tpm2CommandLib/Tpm2Startup.c
Normal file
102
SecurityPkg/Library/Tpm2CommandLib/Tpm2Startup.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/** @file
|
||||
Implement TPM2 Startup related command.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPM_SU StartupType;
|
||||
} TPM2_STARTUP_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
} TPM2_STARTUP_RESPONSE;
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPM_SU ShutdownType;
|
||||
} TPM2_SHUTDOWN_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
} TPM2_SHUTDOWN_RESPONSE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
Send Startup command to TPM2.
|
||||
|
||||
@param[in] StartupType TPM_SU_CLEAR or TPM_SU_STATE
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2Startup (
|
||||
IN TPM_SU StartupType
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_STARTUP_COMMAND Cmd;
|
||||
TPM2_STARTUP_RESPONSE Res;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
|
||||
Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_Startup);
|
||||
Cmd.StartupType = SwapBytes16(StartupType);
|
||||
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (sizeof(Cmd), (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Send Shutdown command to TPM2.
|
||||
|
||||
@param[in] ShutdownType TPM_SU_CLEAR or TPM_SU_STATE.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2Shutdown (
|
||||
IN TPM_SU ShutdownType
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_SHUTDOWN_COMMAND Cmd;
|
||||
TPM2_SHUTDOWN_RESPONSE Res;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
|
||||
Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_Shutdown);
|
||||
Cmd.ShutdownType = SwapBytes16(ShutdownType);
|
||||
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (sizeof(Cmd), (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
|
||||
return Status;
|
||||
}
|
66
SecurityPkg/Library/Tpm2CommandLib/Tpm2Test.c
Normal file
66
SecurityPkg/Library/Tpm2CommandLib/Tpm2Test.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/** @file
|
||||
Implement TPM2 Test related command.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM2_COMMAND_HEADER Header;
|
||||
TPMI_YES_NO FullTest;
|
||||
} TPM2_SELF_TEST_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
TPM2_RESPONSE_HEADER Header;
|
||||
} TPM2_SELF_TEST_RESPONSE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
This command causes the TPM to perform a test of its capabilities.
|
||||
If the fullTest is YES, the TPM will test all functions.
|
||||
If fullTest = NO, the TPM will only test those functions that have not previously been tested.
|
||||
|
||||
@param[in] FullTest YES if full test to be performed
|
||||
NO if only test of untested functions required
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2SelfTest (
|
||||
IN TPMI_YES_NO FullTest
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_SELF_TEST_COMMAND Cmd;
|
||||
TPM2_SELF_TEST_RESPONSE Res;
|
||||
UINT32 ResultBufSize;
|
||||
|
||||
Cmd.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
|
||||
Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
|
||||
Cmd.Header.commandCode = SwapBytes32(TPM_CC_SelfTest);
|
||||
Cmd.FullTest = FullTest;
|
||||
|
||||
ResultBufSize = sizeof(Res);
|
||||
Status = Tpm2SubmitCommand (sizeof(Cmd), (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
|
||||
|
||||
return Status;
|
||||
}
|
Reference in New Issue
Block a user