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:
@@ -71,6 +71,25 @@ HASH_TABLE mHash[] = {
|
||||
{ L"SHA512", 64, &mHashOidValue[32], 9, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
SecureBoot Hook for processing image verification.
|
||||
|
||||
@param[in] VariableName Name of Variable to be found.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
@param[in] DataSize Size of Data found. If size is less than the
|
||||
data, this value contains the required size.
|
||||
@param[in] Data Data pointer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SecureBootHook (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN UINTN DataSize,
|
||||
IN VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Reads contents of a PE/COFF image in memory buffer.
|
||||
|
||||
@@ -846,6 +865,7 @@ IsSignatureFoundInDatabase (
|
||||
// Find the signature in database.
|
||||
//
|
||||
IsFound = TRUE;
|
||||
SecureBootHook (VariableName, &gEfiImageSecurityDatabaseGuid, CertList->SignatureSize, Cert);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -948,6 +968,7 @@ IsPkcsSignedDataVerifiedBySignatureList (
|
||||
mImageDigestSize
|
||||
);
|
||||
if (VerifyStatus) {
|
||||
SecureBootHook (VariableName, VendorGuid, CertList->SignatureSize, Cert);
|
||||
goto Done;
|
||||
}
|
||||
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
|
||||
|
@@ -35,6 +35,7 @@
|
||||
[Sources]
|
||||
DxeImageVerificationLib.c
|
||||
DxeImageVerificationLib.h
|
||||
Measurement.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
@@ -54,6 +55,7 @@
|
||||
BaseCryptLib
|
||||
SecurityManagementLib
|
||||
PeCoffLib
|
||||
TpmMeasurementLib
|
||||
|
||||
[Protocols]
|
||||
gEfiFirmwareVolume2ProtocolGuid
|
||||
|
322
SecurityPkg/Library/DxeImageVerificationLib/Measurement.c
Normal file
322
SecurityPkg/Library/DxeImageVerificationLib/Measurement.c
Normal file
@@ -0,0 +1,322 @@
|
||||
/** @file
|
||||
Measure TrEE required variable.
|
||||
|
||||
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 <PiDxe.h>
|
||||
#include <Guid/ImageAuthentication.h>
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/TpmMeasurementLib.h>
|
||||
|
||||
typedef struct {
|
||||
CHAR16 *VariableName;
|
||||
EFI_GUID *VendorGuid;
|
||||
} VARIABLE_TYPE;
|
||||
|
||||
typedef struct {
|
||||
CHAR16 *VariableName;
|
||||
EFI_GUID *VendorGuid;
|
||||
VOID *Data;
|
||||
UINTN Size;
|
||||
} VARIABLE_RECORD;
|
||||
|
||||
#define MEASURED_AUTHORITY_COUNT_MAX 0x100
|
||||
|
||||
UINTN mMeasuredAuthorityCount = 0;
|
||||
UINTN mMeasuredAuthorityCountMax = 0;
|
||||
VARIABLE_RECORD *mMeasuredAuthorityList = NULL;
|
||||
|
||||
VARIABLE_TYPE mVariableType[] = {
|
||||
{EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},
|
||||
};
|
||||
|
||||
/**
|
||||
This function will check if VarName should be recorded and return the address of VarName if it is needed.
|
||||
|
||||
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
|
||||
|
||||
@return the address of VarName.
|
||||
**/
|
||||
CHAR16 *
|
||||
AssignVarName (
|
||||
IN CHAR16 *VarName
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
|
||||
if (StrCmp (VarName, mVariableType[Index].VariableName) == 0) {
|
||||
return mVariableType[Index].VariableName;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
This function will check if VendorGuid should be recorded and return the address of VendorGuid if it is needed.
|
||||
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
|
||||
@return the address of VendorGuid.
|
||||
**/
|
||||
EFI_GUID *
|
||||
AssignVendorGuid (
|
||||
IN EFI_GUID *VendorGuid
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
|
||||
if (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid)) {
|
||||
return mVariableType[Index].VendorGuid;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
This function will add variable information to MeasuredAuthorityList.
|
||||
|
||||
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
@param[in] VarData The content of the variable data.
|
||||
@param[in] VarSize The size of the variable data.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
**/
|
||||
EFI_STATUS
|
||||
AddDataMeasured (
|
||||
IN CHAR16 *VarName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN VOID *Data,
|
||||
IN UINTN Size
|
||||
)
|
||||
{
|
||||
VARIABLE_RECORD *NewMeasuredAuthorityList;
|
||||
|
||||
ASSERT (mMeasuredAuthorityCount <= mMeasuredAuthorityCountMax);
|
||||
if (mMeasuredAuthorityCount == mMeasuredAuthorityCountMax) {
|
||||
//
|
||||
// Need enlarge
|
||||
//
|
||||
NewMeasuredAuthorityList = AllocateZeroPool (sizeof(VARIABLE_RECORD) * (mMeasuredAuthorityCountMax + MEASURED_AUTHORITY_COUNT_MAX));
|
||||
if (NewMeasuredAuthorityList == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
if (mMeasuredAuthorityList != NULL) {
|
||||
CopyMem (NewMeasuredAuthorityList, mMeasuredAuthorityList, sizeof(VARIABLE_RECORD) * mMeasuredAuthorityCount);
|
||||
FreePool (mMeasuredAuthorityList);
|
||||
}
|
||||
mMeasuredAuthorityList = NewMeasuredAuthorityList;
|
||||
mMeasuredAuthorityCountMax += MEASURED_AUTHORITY_COUNT_MAX;
|
||||
}
|
||||
|
||||
//
|
||||
// Add new entry
|
||||
//
|
||||
mMeasuredAuthorityList[mMeasuredAuthorityCount].VariableName = AssignVarName (VarName);
|
||||
mMeasuredAuthorityList[mMeasuredAuthorityCount].VendorGuid = AssignVendorGuid (VendorGuid);
|
||||
mMeasuredAuthorityList[mMeasuredAuthorityCount].Size = Size;
|
||||
mMeasuredAuthorityList[mMeasuredAuthorityCount].Data = AllocatePool (Size);
|
||||
if (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
CopyMem (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data, Data, Size);
|
||||
mMeasuredAuthorityCount++;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function will return if this variable is already measured.
|
||||
|
||||
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
@param[in] VarData The content of the variable data.
|
||||
@param[in] VarSize The size of the variable data.
|
||||
|
||||
@retval TRUE The data is already measured.
|
||||
@retval FALSE The data is not measured yet.
|
||||
**/
|
||||
BOOLEAN
|
||||
IsDataMeasured (
|
||||
IN CHAR16 *VarName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN VOID *Data,
|
||||
IN UINTN Size
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < mMeasuredAuthorityCount; Index++) {
|
||||
if ((StrCmp (VarName, mMeasuredAuthorityList[Index].VariableName) == 0) &&
|
||||
(CompareGuid (VendorGuid, mMeasuredAuthorityList[Index].VendorGuid)) &&
|
||||
(CompareMem (Data, mMeasuredAuthorityList[Index].Data, Size) == 0) &&
|
||||
(Size == mMeasuredAuthorityList[Index].Size)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
This function will return if this variable is SecureAuthority Variable.
|
||||
|
||||
@param[in] VariableName A Null-terminated string that is the name of the vendor's variable.
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
|
||||
@retval TRUE This is SecureAuthority Variable
|
||||
@retval FALSE This is not SecureAuthority Variable
|
||||
**/
|
||||
BOOLEAN
|
||||
IsSecureAuthorityVariable (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
|
||||
if ((StrCmp (VariableName, mVariableType[Index].VariableName) == 0) &&
|
||||
(CompareGuid (VendorGuid, mVariableType[Index].VendorGuid))) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Measure and log an EFI variable, and extend the measurement result into a specific PCR.
|
||||
|
||||
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
@param[in] VarData The content of the variable data.
|
||||
@param[in] VarSize The size of the variable data.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MeasureVariable (
|
||||
IN CHAR16 *VarName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN VOID *VarData,
|
||||
IN UINTN VarSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN VarNameLength;
|
||||
EFI_VARIABLE_DATA_TREE *VarLog;
|
||||
UINT32 VarLogSize;
|
||||
|
||||
//
|
||||
// The EFI_VARIABLE_DATA_TREE.VariableData value shall be the EFI_SIGNATURE_DATA value
|
||||
// from the EFI_SIGNATURE_LIST that contained the authority that was used to validate the image
|
||||
//
|
||||
VarNameLength = StrLen (VarName);
|
||||
VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
|
||||
- sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
|
||||
|
||||
VarLog = (EFI_VARIABLE_DATA_TREE *) AllocateZeroPool (VarLogSize);
|
||||
if (VarLog == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
CopyMem (&VarLog->VariableName, VendorGuid, sizeof(VarLog->VariableName));
|
||||
VarLog->UnicodeNameLength = VarNameLength;
|
||||
VarLog->VariableDataLength = VarSize;
|
||||
CopyMem (
|
||||
VarLog->UnicodeName,
|
||||
VarName,
|
||||
VarNameLength * sizeof (*VarName)
|
||||
);
|
||||
CopyMem (
|
||||
(CHAR16 *)VarLog->UnicodeName + VarNameLength,
|
||||
VarData,
|
||||
VarSize
|
||||
);
|
||||
|
||||
DEBUG ((EFI_D_INFO, "DxeImageVerification: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY));
|
||||
DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
7,
|
||||
EV_EFI_VARIABLE_AUTHORITY,
|
||||
VarLog,
|
||||
VarLogSize,
|
||||
VarLog,
|
||||
VarLogSize
|
||||
);
|
||||
FreePool (VarLog);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
SecureBoot Hook for processing image verification.
|
||||
|
||||
@param[in] VariableName Name of Variable to be found.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
@param[in] DataSize Size of Data found. If size is less than the
|
||||
data, this value contains the required size.
|
||||
@param[in] Data Data pointer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SecureBootHook (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN UINTN DataSize,
|
||||
IN VOID *Data
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (!IsSecureAuthorityVariable (VariableName, VendorGuid)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (IsDataMeasured (VariableName, VendorGuid, Data, DataSize)) {
|
||||
DEBUG ((EFI_D_ERROR, "MeasureSecureAuthorityVariable - IsDataMeasured\n"));
|
||||
return ;
|
||||
}
|
||||
|
||||
Status = MeasureVariable (
|
||||
VariableName,
|
||||
VendorGuid,
|
||||
Data,
|
||||
DataSize
|
||||
);
|
||||
DEBUG ((EFI_D_ERROR, "MeasureBootPolicyVariable - %r\n", Status));
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
AddDataMeasured (VariableName, VendorGuid, Data, DataSize);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
@@ -0,0 +1,700 @@
|
||||
/** @file
|
||||
The library instance provides security service of TPM2 measure boot.
|
||||
|
||||
Caution: This file requires additional review when modified.
|
||||
This library will have external input - PE/COFF image and GPT partition.
|
||||
This external input must be validated carefully to avoid security issue like
|
||||
buffer overflow, integer overflow.
|
||||
|
||||
DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content
|
||||
read is within the image buffer.
|
||||
|
||||
TrEEMeasurePeImage() function will accept untrusted PE/COFF image and validate its
|
||||
data structure within this image buffer before use.
|
||||
|
||||
TrEEMeasureGptTable() function will receive untrusted GPT partition table, and parse
|
||||
partition data carefully.
|
||||
|
||||
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 <PiDxe.h>
|
||||
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
#include <Protocol/BlockIo.h>
|
||||
#include <Protocol/DiskIo.h>
|
||||
#include <Protocol/DevicePathToText.h>
|
||||
#include <Protocol/FirmwareVolumeBlock.h>
|
||||
|
||||
#include <Guid/MeasuredFvHob.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/BaseCryptLib.h>
|
||||
#include <Library/PeCoffLib.h>
|
||||
#include <Library/SecurityManagementLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
|
||||
//
|
||||
// Flag to check GPT partition. It only need be measured once.
|
||||
//
|
||||
BOOLEAN mTrEEMeasureGptTableFlag = FALSE;
|
||||
EFI_GUID mTrEEZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
UINTN mTrEEMeasureGptCount = 0;
|
||||
VOID *mTrEEFileBuffer;
|
||||
UINTN mTrEEImageSize;
|
||||
//
|
||||
// Measured FV handle cache
|
||||
//
|
||||
EFI_HANDLE mTrEECacheMeasuredHandle = NULL;
|
||||
MEASURED_HOB_DATA *mTrEEMeasuredHobData = NULL;
|
||||
|
||||
/**
|
||||
Reads contents of a PE/COFF image in memory buffer.
|
||||
|
||||
Caution: This function may receive untrusted input.
|
||||
PE/COFF image is external input, so this function will make sure the PE/COFF image content
|
||||
read is within the image buffer.
|
||||
|
||||
@param FileHandle Pointer to the file handle to read the PE/COFF image.
|
||||
@param FileOffset Offset into the PE/COFF image to begin the read operation.
|
||||
@param ReadSize On input, the size in bytes of the requested read operation.
|
||||
On output, the number of bytes actually read.
|
||||
@param Buffer Output buffer that contains the data read from the PE/COFF image.
|
||||
|
||||
@retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DxeTpm2MeasureBootLibImageRead (
|
||||
IN VOID *FileHandle,
|
||||
IN UINTN FileOffset,
|
||||
IN OUT UINTN *ReadSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
UINTN EndPosition;
|
||||
|
||||
if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (MAX_ADDRESS - FileOffset < *ReadSize) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EndPosition = FileOffset + *ReadSize;
|
||||
if (EndPosition > mTrEEImageSize) {
|
||||
*ReadSize = (UINT32)(mTrEEImageSize - FileOffset);
|
||||
}
|
||||
|
||||
if (FileOffset >= mTrEEImageSize) {
|
||||
*ReadSize = 0;
|
||||
}
|
||||
|
||||
CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Measure GPT table data into TPM log.
|
||||
|
||||
Caution: This function may receive untrusted input.
|
||||
The GPT partition table is external input, so this function should parse partition data carefully.
|
||||
|
||||
@param TreeProtocol Pointer to the located TREE protocol instance.
|
||||
@param GptHandle Handle that GPT partition was installed.
|
||||
|
||||
@retval EFI_SUCCESS Successfully measure GPT table.
|
||||
@retval EFI_UNSUPPORTED Not support GPT table on the given handle.
|
||||
@retval EFI_DEVICE_ERROR Can't get GPT table because device error.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to measure GPT table.
|
||||
@retval other error value
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEEMeasureGptTable (
|
||||
IN EFI_TREE_PROTOCOL *TreeProtocol,
|
||||
IN EFI_HANDLE GptHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
||||
EFI_DISK_IO_PROTOCOL *DiskIo;
|
||||
EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
|
||||
EFI_PARTITION_ENTRY *PartitionEntry;
|
||||
UINT8 *EntryPtr;
|
||||
UINTN NumberOfPartition;
|
||||
UINT32 Index;
|
||||
TrEE_EVENT *TreeEvent;
|
||||
EFI_GPT_DATA *GptData;
|
||||
UINT32 EventSize;
|
||||
|
||||
if (mTrEEMeasureGptCount > 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = gBS->HandleProtocol (GptHandle, &gEfiBlockIoProtocolGuid, (VOID**)&BlockIo);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
Status = gBS->HandleProtocol (GptHandle, &gEfiDiskIoProtocolGuid, (VOID**)&DiskIo);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Read the EFI Partition Table Header
|
||||
//
|
||||
PrimaryHeader = (EFI_PARTITION_TABLE_HEADER *) AllocatePool (BlockIo->Media->BlockSize);
|
||||
if (PrimaryHeader == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
Status = DiskIo->ReadDisk (
|
||||
DiskIo,
|
||||
BlockIo->Media->MediaId,
|
||||
1 * BlockIo->Media->BlockSize,
|
||||
BlockIo->Media->BlockSize,
|
||||
(UINT8 *)PrimaryHeader
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "Failed to Read Partition Table Header!\n"));
|
||||
FreePool (PrimaryHeader);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Read the partition entry.
|
||||
//
|
||||
EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry);
|
||||
if (EntryPtr == NULL) {
|
||||
FreePool (PrimaryHeader);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
Status = DiskIo->ReadDisk (
|
||||
DiskIo,
|
||||
BlockIo->Media->MediaId,
|
||||
MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
|
||||
PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry,
|
||||
EntryPtr
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (PrimaryHeader);
|
||||
FreePool (EntryPtr);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Count the valid partition
|
||||
//
|
||||
PartitionEntry = (EFI_PARTITION_ENTRY *)EntryPtr;
|
||||
NumberOfPartition = 0;
|
||||
for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
|
||||
if (!CompareGuid (&PartitionEntry->PartitionTypeGUID, &mTrEEZeroGuid)) {
|
||||
NumberOfPartition++;
|
||||
}
|
||||
PartitionEntry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry);
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Data for Measurement
|
||||
//
|
||||
EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions)
|
||||
+ NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry);
|
||||
TreeEvent = (TrEE_EVENT *) AllocateZeroPool (EventSize + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event));
|
||||
if (TreeEvent == NULL) {
|
||||
FreePool (PrimaryHeader);
|
||||
FreePool (EntryPtr);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
TreeEvent->Size = EventSize + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event);
|
||||
TreeEvent->Header.HeaderSize = sizeof(TrEE_EVENT_HEADER);
|
||||
TreeEvent->Header.HeaderVersion = TREE_EVENT_HEADER_VERSION;
|
||||
TreeEvent->Header.PCRIndex = 5;
|
||||
TreeEvent->Header.EventType = EV_EFI_GPT_EVENT;
|
||||
GptData = (EFI_GPT_DATA *) TreeEvent->Event;
|
||||
|
||||
//
|
||||
// Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition
|
||||
//
|
||||
CopyMem ((UINT8 *)GptData, (UINT8*)PrimaryHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
|
||||
GptData->NumberOfPartitions = NumberOfPartition;
|
||||
//
|
||||
// Copy the valid partition entry
|
||||
//
|
||||
PartitionEntry = (EFI_PARTITION_ENTRY*)EntryPtr;
|
||||
NumberOfPartition = 0;
|
||||
for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
|
||||
if (!CompareGuid (&PartitionEntry->PartitionTypeGUID, &mTrEEZeroGuid)) {
|
||||
CopyMem (
|
||||
(UINT8 *)&GptData->Partitions + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry,
|
||||
(UINT8 *)PartitionEntry,
|
||||
PrimaryHeader->SizeOfPartitionEntry
|
||||
);
|
||||
NumberOfPartition++;
|
||||
}
|
||||
PartitionEntry =(EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry);
|
||||
}
|
||||
|
||||
//
|
||||
// Measure the GPT data
|
||||
//
|
||||
Status = TreeProtocol->HashLogExtendEvent (
|
||||
TreeProtocol,
|
||||
0,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) GptData,
|
||||
(UINT64) EventSize,
|
||||
TreeEvent
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
mTrEEMeasureGptCount++;
|
||||
}
|
||||
|
||||
FreePool (PrimaryHeader);
|
||||
FreePool (EntryPtr);
|
||||
FreePool (TreeEvent);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Measure PE image into TPM log based on the authenticode image hashing in
|
||||
PE/COFF Specification 8.0 Appendix A.
|
||||
|
||||
Caution: This function may receive untrusted input.
|
||||
PE/COFF image is external input, so this function will validate its data structure
|
||||
within this image buffer before use.
|
||||
|
||||
@param[in] TreeProtocol Pointer to the located TREE protocol instance.
|
||||
@param[in] ImageAddress Start address of image buffer.
|
||||
@param[in] ImageSize Image size
|
||||
@param[in] LinkTimeBase Address that the image is loaded into memory.
|
||||
@param[in] ImageType Image subsystem type.
|
||||
@param[in] FilePath File path is corresponding to the input image.
|
||||
|
||||
@retval EFI_SUCCESS Successfully measure image.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
|
||||
@retval EFI_UNSUPPORTED ImageType is unsupported or PE image is mal-format.
|
||||
@retval other error value
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEEMeasurePeImage (
|
||||
IN EFI_TREE_PROTOCOL *TreeProtocol,
|
||||
IN EFI_PHYSICAL_ADDRESS ImageAddress,
|
||||
IN UINTN ImageSize,
|
||||
IN UINTN LinkTimeBase,
|
||||
IN UINT16 ImageType,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *FilePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TrEE_EVENT *TreeEvent;
|
||||
EFI_IMAGE_LOAD_EVENT *ImageLoad;
|
||||
UINT32 FilePathSize;
|
||||
UINT32 EventSize;
|
||||
|
||||
Status = EFI_UNSUPPORTED;
|
||||
ImageLoad = NULL;
|
||||
FilePathSize = (UINT32) GetDevicePathSize (FilePath);
|
||||
|
||||
//
|
||||
// Determine destination PCR by BootPolicy
|
||||
//
|
||||
EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize;
|
||||
TreeEvent = AllocateZeroPool (EventSize + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event));
|
||||
if (TreeEvent == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
TreeEvent->Size = EventSize + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event);
|
||||
TreeEvent->Header.HeaderSize = sizeof(TrEE_EVENT_HEADER);
|
||||
TreeEvent->Header.HeaderVersion = TREE_EVENT_HEADER_VERSION;
|
||||
ImageLoad = (EFI_IMAGE_LOAD_EVENT *) TreeEvent->Event;
|
||||
|
||||
switch (ImageType) {
|
||||
case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
|
||||
TreeEvent->Header.EventType = EV_EFI_BOOT_SERVICES_APPLICATION;
|
||||
TreeEvent->Header.PCRIndex = 4;
|
||||
break;
|
||||
case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
|
||||
TreeEvent->Header.EventType = EV_EFI_BOOT_SERVICES_DRIVER;
|
||||
TreeEvent->Header.PCRIndex = 2;
|
||||
break;
|
||||
case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
|
||||
TreeEvent->Header.EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;
|
||||
TreeEvent->Header.PCRIndex = 2;
|
||||
break;
|
||||
default:
|
||||
DEBUG ((
|
||||
EFI_D_ERROR,
|
||||
"TrEEMeasurePeImage: Unknown subsystem type %d",
|
||||
ImageType
|
||||
));
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
ImageLoad->ImageLocationInMemory = ImageAddress;
|
||||
ImageLoad->ImageLengthInMemory = ImageSize;
|
||||
ImageLoad->ImageLinkTimeAddress = LinkTimeBase;
|
||||
ImageLoad->LengthOfDevicePath = FilePathSize;
|
||||
CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);
|
||||
|
||||
//
|
||||
// Log the PE data
|
||||
//
|
||||
Status = TreeProtocol->HashLogExtendEvent (
|
||||
TreeProtocol,
|
||||
PE_COFF_IMAGE,
|
||||
ImageAddress,
|
||||
ImageSize,
|
||||
TreeEvent
|
||||
);
|
||||
if (Status == EFI_VOLUME_FULL) {
|
||||
//
|
||||
// Volume full here means the image is hashed and its result is extended to PCR.
|
||||
// But the event log cann't be saved since log area is full.
|
||||
// Just return EFI_SUCCESS in order not to block the image load.
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Finish:
|
||||
FreePool (TreeEvent);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
The security handler is used to abstract platform-specific policy
|
||||
from the DXE core response to an attempt to use a file that returns a
|
||||
given status for the authentication check from the section extraction protocol.
|
||||
|
||||
The possible responses in a given SAP implementation may include locking
|
||||
flash upon failure to authenticate, attestation logging for all signed drivers,
|
||||
and other exception operations. The File parameter allows for possible logging
|
||||
within the SAP of the driver.
|
||||
|
||||
If File is NULL, then EFI_INVALID_PARAMETER is returned.
|
||||
|
||||
If the file specified by File with an authentication status specified by
|
||||
AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned.
|
||||
|
||||
If the file specified by File with an authentication status specified by
|
||||
AuthenticationStatus is not safe for the DXE Core to use under any circumstances,
|
||||
then EFI_ACCESS_DENIED is returned.
|
||||
|
||||
If the file specified by File with an authentication status specified by
|
||||
AuthenticationStatus is not safe for the DXE Core to use right now, but it
|
||||
might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is
|
||||
returned.
|
||||
|
||||
@param[in] AuthenticationStatus This is the authentication status returned
|
||||
from the securitymeasurement services for the
|
||||
input file.
|
||||
@param[in] File This is a pointer to the device path of the file that is
|
||||
being dispatched. This will optionally be used for logging.
|
||||
@param[in] FileBuffer File buffer matches the input file device path.
|
||||
@param[in] FileSize Size of File buffer matches the input file device path.
|
||||
@param[in] BootPolicy A boot policy that was used to call LoadImage() UEFI service.
|
||||
|
||||
@retval EFI_SUCCESS The file specified by DevicePath and non-NULL
|
||||
FileBuffer did authenticate, and the platform policy dictates
|
||||
that the DXE Foundation may use the file.
|
||||
@retval other error value
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DxeTpm2MeasureBootHandler (
|
||||
IN UINT32 AuthenticationStatus,
|
||||
IN CONST EFI_DEVICE_PATH_PROTOCOL *File,
|
||||
IN VOID *FileBuffer,
|
||||
IN UINTN FileSize,
|
||||
IN BOOLEAN BootPolicy
|
||||
)
|
||||
{
|
||||
EFI_TREE_PROTOCOL *TreeProtocol;
|
||||
EFI_STATUS Status;
|
||||
TREE_BOOT_SERVICE_CAPABILITY ProtocolCapability;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
|
||||
EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_HANDLE TempHandle;
|
||||
BOOLEAN ApplicationRequired;
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;
|
||||
EFI_PHYSICAL_ADDRESS FvAddress;
|
||||
UINT32 Index;
|
||||
|
||||
Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// TrEE protocol is not installed. So, TPM2 is not present.
|
||||
// Don't do any measurement, and directly return EFI_SUCCESS.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler - TrEE - %r\n", Status));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
ProtocolCapability.Size = (UINT8) sizeof (ProtocolCapability);
|
||||
Status = TreeProtocol->GetCapability (
|
||||
TreeProtocol,
|
||||
&ProtocolCapability
|
||||
);
|
||||
if (EFI_ERROR (Status) || !ProtocolCapability.TrEEPresentFlag) {
|
||||
//
|
||||
// TPM device doesn't work or activate.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler (%r) - TrEEPresentFlag - %x\n", Status, ProtocolCapability.TrEEPresentFlag));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy File Device Path
|
||||
//
|
||||
OrigDevicePathNode = DuplicateDevicePath (File);
|
||||
|
||||
//
|
||||
// 1. Check whether this device path support BlockIo protocol.
|
||||
// Is so, this device path may be a GPT device path.
|
||||
//
|
||||
DevicePathNode = OrigDevicePathNode;
|
||||
Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle);
|
||||
if (!EFI_ERROR (Status) && !mTrEEMeasureGptTableFlag) {
|
||||
//
|
||||
// Find the gpt partion on the given devicepath
|
||||
//
|
||||
DevicePathNode = OrigDevicePathNode;
|
||||
ASSERT (DevicePathNode != NULL);
|
||||
while (!IsDevicePathEnd (DevicePathNode)) {
|
||||
//
|
||||
// Find the Gpt partition
|
||||
//
|
||||
if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH &&
|
||||
DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP) {
|
||||
//
|
||||
// Check whether it is a gpt partition or not
|
||||
//
|
||||
if (((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER &&
|
||||
((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->SignatureType == SIGNATURE_TYPE_GUID) {
|
||||
|
||||
//
|
||||
// Change the partition device path to its parent device path (disk) and get the handle.
|
||||
//
|
||||
DevicePathNode->Type = END_DEVICE_PATH_TYPE;
|
||||
DevicePathNode->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
DevicePathNode = OrigDevicePathNode;
|
||||
Status = gBS->LocateDevicePath (
|
||||
&gEfiDiskIoProtocolGuid,
|
||||
&DevicePathNode,
|
||||
&Handle
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Measure GPT disk.
|
||||
//
|
||||
Status = TrEEMeasureGptTable (TreeProtocol, Handle);
|
||||
DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler - TrEEMeasureGptTable - %r\n", Status));
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// GPT disk check done.
|
||||
//
|
||||
mTrEEMeasureGptTableFlag = TRUE;
|
||||
}
|
||||
}
|
||||
FreePool (OrigDevicePathNode);
|
||||
OrigDevicePathNode = DuplicateDevicePath (File);
|
||||
ASSERT (OrigDevicePathNode != NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DevicePathNode = NextDevicePathNode (DevicePathNode);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 2. Measure PE image.
|
||||
//
|
||||
ApplicationRequired = FALSE;
|
||||
|
||||
//
|
||||
// Check whether this device path support FVB protocol.
|
||||
//
|
||||
DevicePathNode = OrigDevicePathNode;
|
||||
Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Don't check FV image, and directly return EFI_SUCCESS.
|
||||
// It can be extended to the specific FV authentication according to the different requirement.
|
||||
//
|
||||
if (IsDevicePathEnd (DevicePathNode)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
//
|
||||
// The PE image from unmeasured Firmware volume need be measured
|
||||
// The PE image from measured Firmware volume will be mearsured according to policy below.
|
||||
// If it is driver, do not measure
|
||||
// If it is application, still measure.
|
||||
//
|
||||
ApplicationRequired = TRUE;
|
||||
|
||||
if (mTrEECacheMeasuredHandle != Handle && mTrEEMeasuredHobData != NULL) {
|
||||
//
|
||||
// Search for Root FV of this PE image
|
||||
//
|
||||
TempHandle = Handle;
|
||||
do {
|
||||
Status = gBS->HandleProtocol(
|
||||
TempHandle,
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
(VOID**)&FvbProtocol
|
||||
);
|
||||
TempHandle = FvbProtocol->ParentHandle;
|
||||
} while (!EFI_ERROR(Status) && FvbProtocol->ParentHandle != NULL);
|
||||
|
||||
//
|
||||
// Search in measured FV Hob
|
||||
//
|
||||
Status = FvbProtocol->GetPhysicalAddress(FvbProtocol, &FvAddress);
|
||||
if (EFI_ERROR(Status)){
|
||||
return Status;
|
||||
}
|
||||
|
||||
ApplicationRequired = FALSE;
|
||||
|
||||
for (Index = 0; Index < mTrEEMeasuredHobData->Num; Index++) {
|
||||
if(mTrEEMeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) {
|
||||
//
|
||||
// Cache measured FV for next measurement
|
||||
//
|
||||
mTrEECacheMeasuredHandle = Handle;
|
||||
ApplicationRequired = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// File is not found.
|
||||
//
|
||||
if (FileBuffer == NULL) {
|
||||
Status = EFI_SECURITY_VIOLATION;
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
mTrEEImageSize = FileSize;
|
||||
mTrEEFileBuffer = FileBuffer;
|
||||
|
||||
//
|
||||
// Measure PE Image
|
||||
//
|
||||
DevicePathNode = OrigDevicePathNode;
|
||||
ZeroMem (&ImageContext, sizeof (ImageContext));
|
||||
ImageContext.Handle = (VOID *) FileBuffer;
|
||||
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) DxeTpm2MeasureBootLibImageRead;
|
||||
|
||||
//
|
||||
// Get information about the image being loaded
|
||||
//
|
||||
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// The information can't be got from the invalid PeImage
|
||||
//
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
//
|
||||
// Measure only application if Application flag is set
|
||||
// Measure drivers and applications if Application flag is not set
|
||||
//
|
||||
if ((!ApplicationRequired) ||
|
||||
(ApplicationRequired && ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) {
|
||||
//
|
||||
// Print the image path to be measured.
|
||||
//
|
||||
DEBUG_CODE_BEGIN ();
|
||||
CHAR16 *ToText;
|
||||
ToText = ConvertDevicePathToText (
|
||||
DevicePathNode,
|
||||
FALSE,
|
||||
TRUE
|
||||
);
|
||||
if (ToText != NULL) {
|
||||
DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText));
|
||||
FreePool (ToText);
|
||||
}
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
//
|
||||
// Measure PE image into TPM log.
|
||||
//
|
||||
Status = TrEEMeasurePeImage (
|
||||
TreeProtocol,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) FileBuffer,
|
||||
FileSize,
|
||||
(UINTN) ImageContext.ImageAddress,
|
||||
ImageContext.ImageType,
|
||||
DevicePathNode
|
||||
);
|
||||
DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler - TrEEMeasurePeImage - %r\n", Status));
|
||||
}
|
||||
|
||||
//
|
||||
// Done, free the allocated resource.
|
||||
//
|
||||
Finish:
|
||||
if (OrigDevicePathNode != NULL) {
|
||||
FreePool (OrigDevicePathNode);
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler - %r\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Register the security handler to provide TPM measure boot service.
|
||||
|
||||
@param ImageHandle ImageHandle of the loaded driver.
|
||||
@param SystemTable Pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS Register successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough memory to register this handler.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DxeTpm2MeasureBootLibConstructor (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
|
||||
GuidHob = NULL;
|
||||
|
||||
GuidHob = GetFirstGuidHob (&gMeasuredFvHobGuid);
|
||||
|
||||
if (GuidHob != NULL) {
|
||||
mTrEEMeasuredHobData = GET_GUID_HOB_DATA (GuidHob);
|
||||
}
|
||||
|
||||
return RegisterSecurity2Handler (
|
||||
DxeTpm2MeasureBootHandler,
|
||||
EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED
|
||||
);
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
## @file
|
||||
# The library instance provides security service of TPM2 measure boot.
|
||||
#
|
||||
# Caution: This module requires additional review when modified.
|
||||
# This library will have external input - PE/COFF image and GPT partition.
|
||||
# This external input must be validated carefully to avoid security issue like
|
||||
# buffer overflow, integer overflow.
|
||||
#
|
||||
# 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 = DxeTpm2MeasureBootLib
|
||||
FILE_GUID = 778CE4F4-36BD-4ae7-B8F0-10B420B0D174
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = NULL|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
|
||||
CONSTRUCTOR = DxeTpm2MeasureBootLibConstructor
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources]
|
||||
DxeTpm2MeasureBootLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
MemoryAllocationLib
|
||||
DevicePathLib
|
||||
UefiBootServicesTableLib
|
||||
BaseCryptLib
|
||||
PeCoffLib
|
||||
BaseLib
|
||||
SecurityManagementLib
|
||||
HobLib
|
||||
|
||||
[Guids]
|
||||
gMeasuredFvHobGuid
|
||||
|
||||
[Protocols]
|
||||
gEfiTrEEProtocolGuid ## CONSUMES
|
||||
gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES
|
||||
gEfiBlockIoProtocolGuid ## CONSUMES
|
||||
gEfiDiskIoProtocolGuid ## CONSUMES
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
This library is used by other modules to measure data to TPM.
|
||||
|
||||
Copyright (c) 2012, Intel Corporation. All rights reserved. <BR>
|
||||
Copyright (c) 2012 - 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
|
||||
@@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/TcgService.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
@@ -93,6 +94,67 @@ Tpm12MeasureAndLogData (
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Tpm20 measure and log data, and extend the measurement result into a specific PCR.
|
||||
|
||||
@param[in] PcrIndex PCR Index.
|
||||
@param[in] EventType Event type.
|
||||
@param[in] EventLog Measurement event log.
|
||||
@param[in] LogLen Event log length in bytes.
|
||||
@param[in] HashData The start of the data buffer to be hashed, extended.
|
||||
@param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_UNSUPPORTED TPM device not available.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
**/
|
||||
EFI_STATUS
|
||||
Tpm20MeasureAndLogData (
|
||||
IN UINT32 PcrIndex,
|
||||
IN UINT32 EventType,
|
||||
IN VOID *EventLog,
|
||||
IN UINT32 LogLen,
|
||||
IN VOID *HashData,
|
||||
IN UINT64 HashDataLen
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_TREE_PROTOCOL *TreeProtocol;
|
||||
TrEE_EVENT *TreeEvent;
|
||||
|
||||
//
|
||||
// TrEEPresentFlag is checked in HashLogExtendEvent
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
TreeEvent = (TrEE_EVENT *) AllocateZeroPool (LogLen + sizeof (TrEE_EVENT));
|
||||
if(TreeEvent == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
TreeEvent->Size = (UINT32)LogLen + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event);
|
||||
TreeEvent->Header.HeaderSize = sizeof(TrEE_EVENT_HEADER);
|
||||
TreeEvent->Header.HeaderVersion = TREE_EVENT_HEADER_VERSION;
|
||||
TreeEvent->Header.PCRIndex = PcrIndex;
|
||||
TreeEvent->Header.EventType = EventType;
|
||||
CopyMem (&TreeEvent->Event[0], EventLog, LogLen);
|
||||
|
||||
Status = TreeProtocol->HashLogExtendEvent (
|
||||
TreeProtocol,
|
||||
0,
|
||||
(EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
|
||||
HashDataLen,
|
||||
TreeEvent
|
||||
);
|
||||
FreePool (TreeEvent);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Tpm measure and log data, and extend the measurement result into a specific PCR.
|
||||
|
||||
@@ -132,6 +194,19 @@ TpmMeasureAndLogData (
|
||||
HashData,
|
||||
HashDataLen
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Try to measure using Tpm20 protocol
|
||||
//
|
||||
Status = Tpm20MeasureAndLogData(
|
||||
PcrIndex,
|
||||
EventType,
|
||||
EventLog,
|
||||
LogLen,
|
||||
HashData,
|
||||
HashDataLen
|
||||
);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# This library is used by other modules to measure data to TPM 1.2.
|
||||
# This library is used by other modules to measure data to TPM 1.2 or TPM 2.0.
|
||||
#
|
||||
# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2012 - 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
|
||||
@@ -40,4 +40,5 @@
|
||||
UefiBootServicesTableLib
|
||||
|
||||
[Protocols]
|
||||
gEfiTcgProtocolGuid
|
||||
gEfiTcgProtocolGuid
|
||||
gEfiTrEEProtocolGuid
|
||||
|
@@ -0,0 +1,716 @@
|
||||
/** @file
|
||||
Execute pending TPM2 requests from OS or BIOS.
|
||||
|
||||
Caution: This module requires additional review when modified.
|
||||
This driver will have external input - variable.
|
||||
This external input must be validated carefully to avoid security issue.
|
||||
|
||||
TrEEExecutePendingTpmRequest() will receive untrusted input and do validation.
|
||||
|
||||
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 <PiDxe.h>
|
||||
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
#include <Protocol/VariableLock.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/HiiLib.h>
|
||||
#include <Guid/EventGroup.h>
|
||||
#include <Guid/TrEEPhysicalPresenceData.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
|
||||
#define TPM_PP_SUCCESS 0
|
||||
#define TPM_PP_USER_ABORT ((TPM_RESULT)(-0x10))
|
||||
#define TPM_PP_BIOS_FAILURE ((TPM_RESULT)(-0x0f))
|
||||
|
||||
#define CONFIRM_BUFFER_SIZE 4096
|
||||
|
||||
EFI_HII_HANDLE mTrEEPpStringPackHandle;
|
||||
|
||||
/**
|
||||
Get string by string id from HII Interface.
|
||||
|
||||
@param[in] Id String ID.
|
||||
|
||||
@retval CHAR16 * String from ID.
|
||||
@retval NULL If error occurs.
|
||||
|
||||
**/
|
||||
CHAR16 *
|
||||
TrEEPhysicalPresenceGetStringById (
|
||||
IN EFI_STRING_ID Id
|
||||
)
|
||||
{
|
||||
return HiiGetString (mTrEEPpStringPackHandle, Id, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
Send ClearControl and Clear command to TPM.
|
||||
|
||||
@param[in] PlatformAuth platform auth value. NULL means no platform auth change.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_TIMEOUT The register can't run into the expected status in time.
|
||||
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TpmCommandClear (
|
||||
IN TPM2B_AUTH *PlatformAuth OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPMS_AUTH_COMMAND *AuthSession;
|
||||
TPMS_AUTH_COMMAND LocalAuthSession;
|
||||
|
||||
if (PlatformAuth == NULL) {
|
||||
AuthSession = NULL;
|
||||
} else {
|
||||
AuthSession = &LocalAuthSession;
|
||||
ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession));
|
||||
LocalAuthSession.sessionHandle = TPM_RS_PW;
|
||||
LocalAuthSession.hmac.size = PlatformAuth->size;
|
||||
CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2ClearControl ... \n"));
|
||||
Status = Tpm2ClearControl (TPM_RH_PLATFORM, AuthSession, NO);
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2ClearControl - %r\n", Status));
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2Clear ... \n"));
|
||||
Status = Tpm2Clear (TPM_RH_PLATFORM, AuthSession);
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2Clear - %r\n", Status));
|
||||
|
||||
Done:
|
||||
ZeroMem (&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac));
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Execute physical presence operation requested by the OS.
|
||||
|
||||
@param[in] PlatformAuth platform auth value. NULL means no platform auth change.
|
||||
@param[in] CommandCode Physical presence operation value.
|
||||
@param[in, out] PpiFlags The physical presence interface flags.
|
||||
|
||||
@retval TPM_PP_BIOS_FAILURE Unknown physical presence operation.
|
||||
@retval TPM_PP_BIOS_FAILURE Error occurred during sending command to TPM or
|
||||
receiving response from TPM.
|
||||
@retval Others Return code from the TPM device after command execution.
|
||||
**/
|
||||
TPM_RESULT
|
||||
TrEEExecutePhysicalPresence (
|
||||
IN TPM2B_AUTH *PlatformAuth, OPTIONAL
|
||||
IN UINT8 CommandCode,
|
||||
IN OUT UINT8 *PpiFlags
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
switch (CommandCode) {
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:
|
||||
Status = TpmCommandClear (PlatformAuth);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return TPM_PP_BIOS_FAILURE;
|
||||
} else {
|
||||
return TPM_PP_SUCCESS;
|
||||
}
|
||||
|
||||
case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:
|
||||
*PpiFlags &= ~TREE_FLAG_NO_PPI_CLEAR;
|
||||
return TPM_PP_SUCCESS;
|
||||
|
||||
case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
|
||||
*PpiFlags |= TREE_FLAG_NO_PPI_CLEAR;
|
||||
return TPM_PP_SUCCESS;
|
||||
|
||||
default:
|
||||
if (CommandCode <= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
|
||||
return TPM_PP_SUCCESS;
|
||||
} else {
|
||||
return TPM_PP_BIOS_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Read the specified key for user confirmation.
|
||||
|
||||
@param[in] CautionKey If true, F12 is used as confirm key;
|
||||
If false, F10 is used as confirm key.
|
||||
|
||||
@retval TRUE User confirmed the changes by input.
|
||||
@retval FALSE User discarded the changes.
|
||||
**/
|
||||
BOOLEAN
|
||||
TrEEReadUserKey (
|
||||
IN BOOLEAN CautionKey
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_INPUT_KEY Key;
|
||||
UINT16 InputKey;
|
||||
|
||||
InputKey = 0;
|
||||
do {
|
||||
Status = gBS->CheckEvent (gST->ConIn->WaitForKey);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
||||
if (Key.ScanCode == SCAN_ESC) {
|
||||
InputKey = Key.ScanCode;
|
||||
}
|
||||
if ((Key.ScanCode == SCAN_F10) && !CautionKey) {
|
||||
InputKey = Key.ScanCode;
|
||||
}
|
||||
if ((Key.ScanCode == SCAN_F12) && CautionKey) {
|
||||
InputKey = Key.ScanCode;
|
||||
}
|
||||
}
|
||||
} while (InputKey == 0);
|
||||
|
||||
if (InputKey != SCAN_ESC) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
The constructor function register UNI strings into imageHandle.
|
||||
|
||||
It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
|
||||
|
||||
@param ImageHandle The firmware allocated handle for the EFI image.
|
||||
@param SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The constructor successfully added string package.
|
||||
@retval Other value The constructor can't add string package.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEEPhysicalPresenceLibConstructor (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
mTrEEPpStringPackHandle = HiiAddPackages (&gEfiTrEEPhysicalPresenceGuid, ImageHandle, DxeTrEEPhysicalPresenceLibStrings, NULL);
|
||||
ASSERT (mTrEEPpStringPackHandle != NULL);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Display the confirm text and get user confirmation.
|
||||
|
||||
@param[in] TpmPpCommand The requested TPM physical presence command.
|
||||
|
||||
@retval TRUE The user has confirmed the changes.
|
||||
@retval FALSE The user doesn't confirm the changes.
|
||||
**/
|
||||
BOOLEAN
|
||||
TrEEUserConfirm (
|
||||
IN UINT8 TpmPpCommand
|
||||
)
|
||||
{
|
||||
CHAR16 *ConfirmText;
|
||||
CHAR16 *TmpStr1;
|
||||
CHAR16 *TmpStr2;
|
||||
UINTN BufSize;
|
||||
BOOLEAN CautionKey;
|
||||
UINT16 Index;
|
||||
CHAR16 DstStr[81];
|
||||
|
||||
TmpStr2 = NULL;
|
||||
CautionKey = FALSE;
|
||||
BufSize = CONFIRM_BUFFER_SIZE;
|
||||
ConfirmText = AllocateZeroPool (BufSize);
|
||||
ASSERT (ConfirmText != NULL);
|
||||
|
||||
switch (TpmPpCommand) {
|
||||
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:
|
||||
CautionKey = TRUE;
|
||||
TmpStr2 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
|
||||
|
||||
TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
|
||||
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
|
||||
FreePool (TmpStr1);
|
||||
|
||||
TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
|
||||
StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
|
||||
StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
|
||||
FreePool (TmpStr1);
|
||||
|
||||
TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
|
||||
StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
|
||||
FreePool (TmpStr1);
|
||||
break;
|
||||
|
||||
case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
|
||||
CautionKey = TRUE;
|
||||
TmpStr2 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
|
||||
|
||||
TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
|
||||
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
|
||||
FreePool (TmpStr1);
|
||||
|
||||
TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));
|
||||
StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
|
||||
FreePool (TmpStr1);
|
||||
|
||||
TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
|
||||
StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
|
||||
StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
|
||||
FreePool (TmpStr1);
|
||||
|
||||
TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
|
||||
StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
|
||||
FreePool (TmpStr1);
|
||||
|
||||
TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
|
||||
StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
|
||||
FreePool (TmpStr1);
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if (TmpStr2 == NULL) {
|
||||
FreePool (ConfirmText);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));
|
||||
BufSize -= StrSize (ConfirmText);
|
||||
UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);
|
||||
|
||||
DstStr[80] = L'\0';
|
||||
for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {
|
||||
StrnCpy(DstStr, ConfirmText + Index, 80);
|
||||
Print (DstStr);
|
||||
}
|
||||
|
||||
FreePool (TmpStr1);
|
||||
FreePool (TmpStr2);
|
||||
FreePool (ConfirmText);
|
||||
|
||||
if (TrEEReadUserKey (CautionKey)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Check if there is a valid physical presence command request. Also updates parameter value
|
||||
to whether the requested physical presence command already confirmed by user
|
||||
|
||||
@param[in] TcgPpData EFI TrEE Physical Presence request data.
|
||||
@param[in] Flags The physical presence interface flags.
|
||||
@param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
|
||||
True, it indicates the command doesn't require user confirm, or already confirmed
|
||||
in last boot cycle by user.
|
||||
False, it indicates the command need user confirm from UI.
|
||||
|
||||
@retval TRUE Physical Presence operation command is valid.
|
||||
@retval FALSE Physical Presence operation command is invalid.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
TrEEHaveValidTpmRequest (
|
||||
IN EFI_TREE_PHYSICAL_PRESENCE *TcgPpData,
|
||||
IN UINT8 Flags,
|
||||
OUT BOOLEAN *RequestConfirmed
|
||||
)
|
||||
{
|
||||
*RequestConfirmed = FALSE;
|
||||
|
||||
switch (TcgPpData->PPRequest) {
|
||||
case TREE_PHYSICAL_PRESENCE_NO_ACTION:
|
||||
*RequestConfirmed = TRUE;
|
||||
return TRUE;
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:
|
||||
if ((Flags & TREE_FLAG_NO_PPI_CLEAR) != 0) {
|
||||
*RequestConfirmed = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:
|
||||
*RequestConfirmed = TRUE;
|
||||
break;
|
||||
|
||||
case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Wrong Physical Presence command
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((Flags & TREE_FLAG_RESET_TRACK) != 0) {
|
||||
//
|
||||
// It had been confirmed in last boot, it doesn't need confirm again.
|
||||
//
|
||||
*RequestConfirmed = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Physical Presence command is correct
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Check and execute the requested physical presence command.
|
||||
|
||||
Caution: This function may receive untrusted input.
|
||||
TcgPpData variable is external input, so this function will validate
|
||||
its data structure to be valid value.
|
||||
|
||||
@param[in] PlatformAuth platform auth value. NULL means no platform auth change.
|
||||
@param[in] TcgPpData Point to the physical presence NV variable.
|
||||
@param[in] Flags The physical presence interface flags.
|
||||
**/
|
||||
VOID
|
||||
TrEEExecutePendingTpmRequest (
|
||||
IN TPM2B_AUTH *PlatformAuth, OPTIONAL
|
||||
IN EFI_TREE_PHYSICAL_PRESENCE *TcgPpData,
|
||||
IN UINT8 Flags
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN DataSize;
|
||||
BOOLEAN RequestConfirmed;
|
||||
UINT8 NewFlags;
|
||||
|
||||
if (TcgPpData->PPRequest == TREE_PHYSICAL_PRESENCE_NO_ACTION) {
|
||||
//
|
||||
// No operation request
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TrEEHaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {
|
||||
//
|
||||
// Invalid operation request.
|
||||
//
|
||||
if (TcgPpData->PPRequest <= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
|
||||
TcgPpData->PPResponse = TPM_PP_SUCCESS;
|
||||
} else {
|
||||
TcgPpData->PPResponse = TPM_PP_BIOS_FAILURE;
|
||||
}
|
||||
TcgPpData->LastPPRequest = TcgPpData->PPRequest;
|
||||
TcgPpData->PPRequest = TREE_PHYSICAL_PRESENCE_NO_ACTION;
|
||||
DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
|
||||
Status = gRT->SetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
DataSize,
|
||||
TcgPpData
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RequestConfirmed) {
|
||||
//
|
||||
// Print confirm text and wait for approval.
|
||||
//
|
||||
RequestConfirmed = TrEEUserConfirm (TcgPpData->PPRequest
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Execute requested physical presence command
|
||||
//
|
||||
TcgPpData->PPResponse = TPM_PP_USER_ABORT;
|
||||
NewFlags = Flags;
|
||||
if (RequestConfirmed) {
|
||||
TcgPpData->PPResponse = TrEEExecutePhysicalPresence (PlatformAuth, TcgPpData->PPRequest,
|
||||
&NewFlags);
|
||||
}
|
||||
|
||||
//
|
||||
// Save the flags if it is updated.
|
||||
//
|
||||
if (Flags != NewFlags) {
|
||||
Status = gRT->SetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof (UINT8),
|
||||
&NewFlags
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Clear request
|
||||
//
|
||||
if ((NewFlags & TREE_FLAG_RESET_TRACK) == 0) {
|
||||
TcgPpData->LastPPRequest = TcgPpData->PPRequest;
|
||||
TcgPpData->PPRequest = TREE_PHYSICAL_PRESENCE_NO_ACTION;
|
||||
}
|
||||
|
||||
//
|
||||
// Save changes
|
||||
//
|
||||
DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
|
||||
Status = gRT->SetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
DataSize,
|
||||
TcgPpData
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TcgPpData->PPResponse == TPM_PP_USER_ABORT) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reset system to make new TPM settings in effect
|
||||
//
|
||||
switch (TcgPpData->LastPPRequest) {
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:
|
||||
case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:
|
||||
break;
|
||||
default:
|
||||
if (TcgPpData->PPRequest != TREE_PHYSICAL_PRESENCE_NO_ACTION) {
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Print (L"Rebooting system to make TPM2 settings in effect\n");
|
||||
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
Check and execute the pending TPM request.
|
||||
|
||||
The TPM request may come from OS or BIOS. This API will display request information and wait
|
||||
for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
|
||||
the TPM request is confirmed, and one or more reset may be required to make TPM request to
|
||||
take effect.
|
||||
|
||||
This API should be invoked after console in and console out are all ready as they are required
|
||||
to display request information and get user input to confirm the request.
|
||||
|
||||
@param[in] PlatformAuth platform auth value. NULL means no platform auth change.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
TrEEPhysicalPresenceLibProcessRequest (
|
||||
IN TPM2B_AUTH *PlatformAuth OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN DataSize;
|
||||
EFI_TREE_PHYSICAL_PRESENCE TcgPpData;
|
||||
EFI_TREE_PROTOCOL *TreeProtocol;
|
||||
EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
|
||||
UINT8 PpiFlags;
|
||||
|
||||
Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize physical presence flags.
|
||||
//
|
||||
DataSize = sizeof (UINT8);
|
||||
Status = gRT->GetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
NULL,
|
||||
&DataSize,
|
||||
&PpiFlags
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
PpiFlags = 0;
|
||||
Status = gRT->SetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof (UINT8),
|
||||
&PpiFlags
|
||||
);
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
DEBUG ((EFI_D_ERROR, "[TPM2] PpiFlags = %x, Status = %r\n", PpiFlags, Status));
|
||||
|
||||
//
|
||||
// This flags variable controls whether physical presence is required for TPM command.
|
||||
// It should be protected from malicious software. We set it as read-only variable here.
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = VariableLockProtocol->RequestToLock (
|
||||
VariableLockProtocol,
|
||||
TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "[TPM2] Error when lock variable %s, Status = %r\n", TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize physical presence variable.
|
||||
//
|
||||
DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
|
||||
Status = gRT->GetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
NULL,
|
||||
&DataSize,
|
||||
&TcgPpData
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
|
||||
DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
|
||||
Status = gRT->SetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
DataSize,
|
||||
&TcgPpData
|
||||
);
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));
|
||||
|
||||
//
|
||||
// Execute pending TPM request.
|
||||
//
|
||||
TrEEExecutePendingTpmRequest (PlatformAuth, &TcgPpData, PpiFlags);
|
||||
DEBUG ((EFI_D_ERROR, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Check if the pending TPM request needs user input to confirm.
|
||||
|
||||
The TPM request may come from OS. This API will check if TPM request exists and need user
|
||||
input to confirmation.
|
||||
|
||||
@retval TRUE TPM needs input to confirm user physical presence.
|
||||
@retval FALSE TPM doesn't need input to confirm user physical presence.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
TrEEPhysicalPresenceLibNeedUserConfirm(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_TREE_PHYSICAL_PRESENCE TcgPpData;
|
||||
UINTN DataSize;
|
||||
BOOLEAN RequestConfirmed;
|
||||
EFI_TREE_PROTOCOL *TreeProtocol;
|
||||
UINT8 PpiFlags;
|
||||
|
||||
Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Tpm requests
|
||||
//
|
||||
DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
|
||||
Status = gRT->GetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
NULL,
|
||||
&DataSize,
|
||||
&TcgPpData
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DataSize = sizeof (UINT8);
|
||||
Status = gRT->GetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
NULL,
|
||||
&DataSize,
|
||||
&PpiFlags
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (TcgPpData.PPRequest == TREE_PHYSICAL_PRESENCE_NO_ACTION) {
|
||||
//
|
||||
// No operation request
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!TrEEHaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {
|
||||
//
|
||||
// Invalid operation request.
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!RequestConfirmed) {
|
||||
//
|
||||
// Need UI to confirm
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@@ -0,0 +1,59 @@
|
||||
## @file
|
||||
# TrEE physical presence library instance. This library will execute TPM2 request.
|
||||
#
|
||||
# Caution: This module requires additional review when modified.
|
||||
# This driver will have external input - variable.
|
||||
# This external input must be validated carefully to avoid security issue.
|
||||
#
|
||||
# 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 = DxeTrEEPhysicalPresenceLib
|
||||
FILE_GUID = 601ECB06-7874-489e-A280-805780F6C861
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = TrEEPhysicalPresenceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_APPLICATION UEFI_DRIVER
|
||||
CONSTRUCTOR = TrEEPhysicalPresenceLibConstructor
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources]
|
||||
DxeTrEEPhysicalPresenceLib.c
|
||||
PhysicalPresenceStrings.uni
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
MemoryAllocationLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
UefiRuntimeServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
PrintLib
|
||||
HiiLib
|
||||
Tpm2CommandLib
|
||||
|
||||
[Protocols]
|
||||
gEfiTrEEProtocolGuid
|
||||
gEdkiiVariableLockProtocolGuid
|
||||
|
||||
[Guids]
|
||||
gEfiTrEEPhysicalPresenceGuid
|
Binary file not shown.
155
SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.c
Normal file
155
SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/** @file
|
||||
Ihis library is BaseCrypto SHA1 hash instance.
|
||||
It can be registered to BaseCrypto router, to serve as hash engine.
|
||||
|
||||
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 <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseCryptLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/HashLib.h>
|
||||
|
||||
/**
|
||||
The function set SHA1 to digest list.
|
||||
|
||||
@param DigestList digest list
|
||||
@param Sha1Digest SHA1 digest
|
||||
**/
|
||||
VOID
|
||||
Tpm2SetSha1ToDigestList (
|
||||
IN TPML_DIGEST_VALUES *DigestList,
|
||||
IN UINT8 *Sha1Digest
|
||||
)
|
||||
{
|
||||
DigestList->count = 1;
|
||||
DigestList->digests[0].hashAlg = TPM_ALG_SHA1;
|
||||
CopyMem (
|
||||
DigestList->digests[0].digest.sha1,
|
||||
Sha1Digest,
|
||||
SHA1_DIGEST_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Start hash sequence.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Sha1HashInit (
|
||||
OUT HASH_HANDLE *HashHandle
|
||||
)
|
||||
{
|
||||
VOID *Sha1Ctx;
|
||||
UINTN CtxSize;
|
||||
|
||||
CtxSize = Sha1GetContextSize ();
|
||||
Sha1Ctx = AllocatePool (CtxSize);
|
||||
ASSERT (Sha1Ctx != NULL);
|
||||
|
||||
Sha1Init (Sha1Ctx);
|
||||
|
||||
*HashHandle = (HASH_HANDLE)Sha1Ctx;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Update hash sequence data.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence updated.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Sha1HashUpdate (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen
|
||||
)
|
||||
{
|
||||
VOID *Sha1Ctx;
|
||||
|
||||
Sha1Ctx = (VOID *)HashHandle;
|
||||
Sha1Update (Sha1Ctx, DataToHash, DataToHashLen);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Complete hash sequence complete.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param DigestList Digest list.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Sha1HashFinal (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
)
|
||||
{
|
||||
UINT8 Digest[SHA1_DIGEST_SIZE];
|
||||
VOID *Sha1Ctx;
|
||||
|
||||
Sha1Ctx = (VOID *)HashHandle;
|
||||
Sha1Final (Sha1Ctx, Digest);
|
||||
|
||||
FreePool (Sha1Ctx);
|
||||
|
||||
Tpm2SetSha1ToDigestList (DigestList, Digest);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
HASH_INTERFACE mSha1InternalHashInstance = {
|
||||
HASH_ALGORITHM_SHA1_GUID,
|
||||
Sha1HashInit,
|
||||
Sha1HashUpdate,
|
||||
Sha1HashFinal,
|
||||
};
|
||||
|
||||
/**
|
||||
The function register SHA1 instance.
|
||||
|
||||
@retval EFI_SUCCESS SHA1 instance is registered, or system dose not surpport registr SHA1 instance
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashInstanceLibSha1Constructor (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = RegisterHashInterfaceLib (&mSha1InternalHashInstance);
|
||||
if ((Status == EFI_SUCCESS) || (Status == EFI_UNSUPPORTED)) {
|
||||
//
|
||||
// Unsupported means platform policy does not need this instance enabled.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
## @file
|
||||
# Ihis library is BaseCrypto SHA1 hash instance.
|
||||
# It can be registered to BaseCrypto router, to serve as hash engine.
|
||||
#
|
||||
# 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 = HashInstanceLibSha1
|
||||
FILE_GUID = 9A7A6AB4-9DA6-4aa4-90CB-6D4B79EDA7B9
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = NULL
|
||||
CONSTRUCTOR = HashInstanceLibSha1Constructor
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
HashInstanceLibSha1.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
Tpm2CommandLib
|
||||
MemoryAllocationLib
|
||||
BaseCryptLib
|
@@ -0,0 +1,155 @@
|
||||
/** @file
|
||||
Ihis library is BaseCrypto SHA256 hash instance.
|
||||
It can be registered to BaseCrypto router, to serve as hash engine.
|
||||
|
||||
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 <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseCryptLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/HashLib.h>
|
||||
|
||||
/**
|
||||
The function set SHA256 to digest list.
|
||||
|
||||
@param DigestList digest list
|
||||
@param Sha256Digest SHA256 digest
|
||||
**/
|
||||
VOID
|
||||
Tpm2SetSha256ToDigestList (
|
||||
IN TPML_DIGEST_VALUES *DigestList,
|
||||
IN UINT8 *Sha256Digest
|
||||
)
|
||||
{
|
||||
DigestList->count = 1;
|
||||
DigestList->digests[0].hashAlg = TPM_ALG_SHA256;
|
||||
CopyMem (
|
||||
DigestList->digests[0].digest.sha256,
|
||||
Sha256Digest,
|
||||
SHA256_DIGEST_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Start hash sequence.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Sha256HashInit (
|
||||
OUT HASH_HANDLE *HashHandle
|
||||
)
|
||||
{
|
||||
VOID *Sha256Ctx;
|
||||
UINTN CtxSize;
|
||||
|
||||
CtxSize = Sha256GetContextSize ();
|
||||
Sha256Ctx = AllocatePool (CtxSize);
|
||||
ASSERT (Sha256Ctx != NULL);
|
||||
|
||||
Sha256Init (Sha256Ctx);
|
||||
|
||||
*HashHandle = (HASH_HANDLE)Sha256Ctx;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Update hash sequence data.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence updated.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Sha256HashUpdate (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen
|
||||
)
|
||||
{
|
||||
VOID *Sha256Ctx;
|
||||
|
||||
Sha256Ctx = (VOID *)HashHandle;
|
||||
Sha256Update (Sha256Ctx, DataToHash, DataToHashLen);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Complete hash sequence complete.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param DigestList Digest list.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Sha256HashFinal (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
)
|
||||
{
|
||||
UINT8 Digest[SHA256_DIGEST_SIZE];
|
||||
VOID *Sha256Ctx;
|
||||
|
||||
Sha256Ctx = (VOID *)HashHandle;
|
||||
Sha256Final (Sha256Ctx, Digest);
|
||||
|
||||
FreePool (Sha256Ctx);
|
||||
|
||||
Tpm2SetSha256ToDigestList (DigestList, Digest);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
HASH_INTERFACE mSha256InternalHashInstance = {
|
||||
HASH_ALGORITHM_SHA256_GUID,
|
||||
Sha256HashInit,
|
||||
Sha256HashUpdate,
|
||||
Sha256HashFinal,
|
||||
};
|
||||
|
||||
/**
|
||||
The function register SHA256 instance.
|
||||
|
||||
@retval EFI_SUCCESS SHA256 instance is registered, or system dose not surpport registr SHA256 instance
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashInstanceLibSha256Constructor (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = RegisterHashInterfaceLib (&mSha256InternalHashInstance);
|
||||
if ((Status == EFI_SUCCESS) || (Status == EFI_UNSUPPORTED)) {
|
||||
//
|
||||
// Unsupported means platform policy does not need this instance enabled.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
## @file
|
||||
# Ihis library is BaseCrypto SHA256 hash instance.
|
||||
# It can be registered to BaseCrypto router, to serve as hash engine.
|
||||
#
|
||||
# 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 = HashInstanceLibSha256
|
||||
FILE_GUID = 5810798A-ED30-4080-8DD7-B9667A748C02
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = NULL
|
||||
CONSTRUCTOR = HashInstanceLibSha256Constructor
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
HashInstanceLibSha256.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
Tpm2CommandLib
|
||||
MemoryAllocationLib
|
||||
BaseCryptLib
|
@@ -0,0 +1,77 @@
|
||||
/** @file
|
||||
Ihis is BaseCrypto router support function.
|
||||
|
||||
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 <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/HashLib.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
|
||||
typedef struct {
|
||||
EFI_GUID Guid;
|
||||
UINT32 Mask;
|
||||
} TPM2_HASH_MASK;
|
||||
|
||||
TPM2_HASH_MASK mTpm2HashMask[] = {
|
||||
{HASH_ALGORITHM_SHA1_GUID, TREE_BOOT_HASH_ALG_SHA1},
|
||||
{HASH_ALGORITHM_SHA256_GUID, TREE_BOOT_HASH_ALG_SHA256},
|
||||
{HASH_ALGORITHM_SHA384_GUID, TREE_BOOT_HASH_ALG_SHA384},
|
||||
{HASH_ALGORITHM_SHA512_GUID, TREE_BOOT_HASH_ALG_SHA512},
|
||||
};
|
||||
|
||||
/**
|
||||
The function get hash mask info from algorithm.
|
||||
|
||||
@param HashGuid Hash Guid
|
||||
|
||||
@return HashMask
|
||||
**/
|
||||
UINT32
|
||||
EFIAPI
|
||||
Tpm2GetHashMaskFromAlgo (
|
||||
IN EFI_GUID *HashGuid
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
for (Index = 0; Index < sizeof(mTpm2HashMask)/sizeof(mTpm2HashMask[0]); Index++) {
|
||||
if (CompareGuid (HashGuid, &mTpm2HashMask[Index].Guid)) {
|
||||
return mTpm2HashMask[Index].Mask;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
The function set digest to digest list.
|
||||
|
||||
@param DigestList digest list
|
||||
@param Digest digest data
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
Tpm2SetHashToDigestList (
|
||||
IN OUT TPML_DIGEST_VALUES *DigestList,
|
||||
IN TPML_DIGEST_VALUES *Digest
|
||||
)
|
||||
{
|
||||
CopyMem (
|
||||
&DigestList->digests[DigestList->count],
|
||||
&Digest->digests[0],
|
||||
sizeof(Digest->digests[0])
|
||||
);
|
||||
DigestList->count ++;
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
/** @file
|
||||
Ihis is BaseCrypto router support function definition.
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _HASH_LIB_BASE_CRYPTO_ROUTER_COMMON_H_
|
||||
#define _HASH_LIB_BASE_CRYPTO_ROUTER_COMMON_H_
|
||||
|
||||
/**
|
||||
The function get hash mask info from algorithm.
|
||||
|
||||
@param HashGuid Hash Guid
|
||||
|
||||
@return HashMask
|
||||
**/
|
||||
UINT32
|
||||
EFIAPI
|
||||
Tpm2GetHashMaskFromAlgo (
|
||||
IN EFI_GUID *HashGuid
|
||||
);
|
||||
|
||||
/**
|
||||
The function set digest to digest list.
|
||||
|
||||
@param DigestList digest list
|
||||
@param Digest digest data
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
Tpm2SetHashToDigestList (
|
||||
IN OUT TPML_DIGEST_VALUES *DigestList,
|
||||
IN TPML_DIGEST_VALUES *Digest
|
||||
);
|
||||
|
||||
#endif
|
@@ -0,0 +1,221 @@
|
||||
/** @file
|
||||
Ihis library is BaseCrypto router. It will redirect hash request to each individual
|
||||
hash handler registerd, such as SHA1, SHA256.
|
||||
Platform can use PcdTpm2HashMask to mask some hash engines.
|
||||
|
||||
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 <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/HashLib.h>
|
||||
|
||||
#include "HashLibBaseCryptoRouterCommon.h"
|
||||
|
||||
HASH_INTERFACE mHashInterface[HASH_COUNT] = {0};
|
||||
UINTN mHashInterfaceCount = 0;
|
||||
|
||||
/**
|
||||
Start hash sequence.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashStart (
|
||||
OUT HASH_HANDLE *HashHandle
|
||||
)
|
||||
{
|
||||
HASH_HANDLE *HashCtx;
|
||||
UINTN Index;
|
||||
|
||||
if (mHashInterfaceCount == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HashCtx = AllocatePool (sizeof(*HashCtx) * mHashInterfaceCount);
|
||||
ASSERT (HashCtx != NULL);
|
||||
|
||||
for (Index = 0; Index < mHashInterfaceCount; Index++) {
|
||||
mHashInterface[Index].HashInit (&HashCtx[Index]);
|
||||
}
|
||||
|
||||
*HashHandle = (HASH_HANDLE)HashCtx;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Update hash sequence data.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence updated.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashUpdate (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen
|
||||
)
|
||||
{
|
||||
HASH_HANDLE *HashCtx;
|
||||
UINTN Index;
|
||||
|
||||
if (mHashInterfaceCount == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HashCtx = (HASH_HANDLE *)HashHandle;
|
||||
|
||||
for (Index = 0; Index < mHashInterfaceCount; Index++) {
|
||||
mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Hash sequence complete and extend to PCR.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param PcrIndex PCR to be extended.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
@param DigestList Digest list.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashCompleteAndExtend (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
IN TPMI_DH_PCR PcrIndex,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
)
|
||||
{
|
||||
TPML_DIGEST_VALUES Digest;
|
||||
HASH_HANDLE *HashCtx;
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (mHashInterfaceCount == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HashCtx = (HASH_HANDLE *)HashHandle;
|
||||
ZeroMem (DigestList, sizeof(*DigestList));
|
||||
|
||||
for (Index = 0; Index < mHashInterfaceCount; Index++) {
|
||||
mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
|
||||
mHashInterface[Index].HashFinal (HashCtx[Index], &Digest);
|
||||
Tpm2SetHashToDigestList (DigestList, &Digest);
|
||||
}
|
||||
|
||||
FreePool (HashCtx);
|
||||
|
||||
Status = Tpm2PcrExtend (
|
||||
PcrIndex,
|
||||
DigestList
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Hash data and extend to PCR.
|
||||
|
||||
@param PcrIndex PCR to be extended.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
@param DigestList Digest list.
|
||||
|
||||
@retval EFI_SUCCESS Hash data and DigestList is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashAndExtend (
|
||||
IN TPMI_DH_PCR PcrIndex,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
)
|
||||
{
|
||||
HASH_HANDLE HashHandle;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (mHashInterfaceCount == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HashStart (&HashHandle);
|
||||
HashUpdate (HashHandle, DataToHash, DataToHashLen);
|
||||
Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This service register Hash.
|
||||
|
||||
@param HashInterface Hash interface
|
||||
|
||||
@retval EFI_SUCCESS This hash interface is registered successfully.
|
||||
@retval EFI_UNSUPPORTED System does not support register this interface.
|
||||
@retval EFI_ALREADY_STARTED System already register this interface.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RegisterHashInterfaceLib (
|
||||
IN HASH_INTERFACE *HashInterface
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINT32 HashMask;
|
||||
|
||||
//
|
||||
// Check allow
|
||||
//
|
||||
HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
|
||||
if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Check duplication
|
||||
//
|
||||
for (Index = 0; Index < mHashInterfaceCount; Index++) {
|
||||
if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
}
|
||||
|
||||
CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface));
|
||||
mHashInterfaceCount ++;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
## @file
|
||||
# Ihis library is BaseCrypto router. It will redirect hash request to each individual
|
||||
# hash handler registerd, such as SHA1, SHA256.
|
||||
# Platform can use PcdTpm2HashMask to mask some hash engines.
|
||||
#
|
||||
# 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 = HashLibBaseCryptoRouterDxe
|
||||
FILE_GUID = 158DC712-F15A-44dc-93BB-1675045BE066
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = HashLibBaseCrypto|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
HashLibBaseCryptoRouterCommon.h
|
||||
HashLibBaseCryptoRouterCommon.c
|
||||
HashLibBaseCryptoRouterDxe.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
Tpm2CommandLib
|
||||
MemoryAllocationLib
|
||||
PcdLib
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask
|
||||
|
@@ -0,0 +1,288 @@
|
||||
/** @file
|
||||
Ihis library is BaseCrypto router. It will redirect hash request to each individual
|
||||
hash handler registerd, such as SHA1, SHA256.
|
||||
Platform can use PcdTpm2HashMask to mask some hash engines.
|
||||
|
||||
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 <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/HashLib.h>
|
||||
|
||||
#include "HashLibBaseCryptoRouterCommon.h"
|
||||
|
||||
#define HASH_LIB_PEI_ROUTER_GUID \
|
||||
{ 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }
|
||||
|
||||
EFI_GUID mHashLibPeiRouterGuid = HASH_LIB_PEI_ROUTER_GUID;
|
||||
|
||||
typedef struct {
|
||||
UINTN HashInterfaceCount;
|
||||
HASH_INTERFACE HashInterface[HASH_COUNT];
|
||||
} HASH_INTERFACE_HOB;
|
||||
|
||||
/**
|
||||
This function get hash interface.
|
||||
|
||||
@retval hash interface.
|
||||
**/
|
||||
HASH_INTERFACE_HOB *
|
||||
InternalGetHashInterface (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_HOB_GUID_TYPE *Hob;
|
||||
|
||||
Hob = GetFirstGuidHob (&mHashLibPeiRouterGuid);
|
||||
if (Hob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return (HASH_INTERFACE_HOB *)(Hob + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
Start hash sequence.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashStart (
|
||||
OUT HASH_HANDLE *HashHandle
|
||||
)
|
||||
{
|
||||
HASH_INTERFACE_HOB *HashInterfaceHob;
|
||||
HASH_HANDLE *HashCtx;
|
||||
UINTN Index;
|
||||
|
||||
HashInterfaceHob = InternalGetHashInterface ();
|
||||
if (HashInterfaceHob == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (HashInterfaceHob->HashInterfaceCount == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HashCtx = AllocatePool (sizeof(*HashCtx) * HashInterfaceHob->HashInterfaceCount);
|
||||
ASSERT (HashCtx != NULL);
|
||||
|
||||
for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
|
||||
HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);
|
||||
}
|
||||
|
||||
*HashHandle = (HASH_HANDLE)HashCtx;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Update hash sequence data.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence updated.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashUpdate (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen
|
||||
)
|
||||
{
|
||||
HASH_INTERFACE_HOB *HashInterfaceHob;
|
||||
HASH_HANDLE *HashCtx;
|
||||
UINTN Index;
|
||||
|
||||
HashInterfaceHob = InternalGetHashInterface ();
|
||||
if (HashInterfaceHob == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (HashInterfaceHob->HashInterfaceCount == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HashCtx = (HASH_HANDLE *)HashHandle;
|
||||
|
||||
for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
|
||||
HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Hash sequence complete and extend to PCR.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param PcrIndex PCR to be extended.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
@param DigestList Digest list.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashCompleteAndExtend (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
IN TPMI_DH_PCR PcrIndex,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
)
|
||||
{
|
||||
TPML_DIGEST_VALUES Digest;
|
||||
HASH_INTERFACE_HOB *HashInterfaceHob;
|
||||
HASH_HANDLE *HashCtx;
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
|
||||
HashInterfaceHob = InternalGetHashInterface ();
|
||||
if (HashInterfaceHob == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (HashInterfaceHob->HashInterfaceCount == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HashCtx = (HASH_HANDLE *)HashHandle;
|
||||
ZeroMem (DigestList, sizeof(*DigestList));
|
||||
|
||||
for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
|
||||
HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
|
||||
HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest);
|
||||
Tpm2SetHashToDigestList (DigestList, &Digest);
|
||||
}
|
||||
|
||||
FreePool (HashCtx);
|
||||
|
||||
Status = Tpm2PcrExtend (
|
||||
PcrIndex,
|
||||
DigestList
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Hash data and extend to PCR.
|
||||
|
||||
@param PcrIndex PCR to be extended.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
@param DigestList Digest list.
|
||||
|
||||
@retval EFI_SUCCESS Hash data and DigestList is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashAndExtend (
|
||||
IN TPMI_DH_PCR PcrIndex,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
)
|
||||
{
|
||||
HASH_INTERFACE_HOB *HashInterfaceHob;
|
||||
HASH_HANDLE HashHandle;
|
||||
EFI_STATUS Status;
|
||||
|
||||
HashInterfaceHob = InternalGetHashInterface ();
|
||||
if (HashInterfaceHob == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (HashInterfaceHob->HashInterfaceCount == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HashStart (&HashHandle);
|
||||
HashUpdate (HashHandle, DataToHash, DataToHashLen);
|
||||
Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This service register Hash.
|
||||
|
||||
@param HashInterface Hash interface
|
||||
|
||||
@retval EFI_SUCCESS This hash interface is registered successfully.
|
||||
@retval EFI_UNSUPPORTED System does not support register this interface.
|
||||
@retval EFI_ALREADY_STARTED System already register this interface.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RegisterHashInterfaceLib (
|
||||
IN HASH_INTERFACE *HashInterface
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
HASH_INTERFACE_HOB *HashInterfaceHob;
|
||||
HASH_INTERFACE_HOB LocalHashInterfaceHob;
|
||||
UINT32 HashMask;
|
||||
|
||||
//
|
||||
// Check allow
|
||||
//
|
||||
HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
|
||||
if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HashInterfaceHob = InternalGetHashInterface ();
|
||||
if (HashInterfaceHob == NULL) {
|
||||
ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
|
||||
HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
|
||||
if (HashInterfaceHob == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Check duplication
|
||||
//
|
||||
for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
|
||||
if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
|
||||
//
|
||||
// In PEI phase, there will be shadow driver dispatched again.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "RegisterHashInterfaceLib - Override\n"));
|
||||
CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));
|
||||
HashInterfaceHob->HashInterfaceCount ++;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
## @file
|
||||
# Ihis library is BaseCrypto router. It will redirect hash request to each individual
|
||||
# hash handler registerd, such as SHA1, SHA256.
|
||||
# Platform can use PcdTpm2HashMask to mask some hash engines.
|
||||
#
|
||||
# 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 = HashLibBaseCryptoRouterPei
|
||||
FILE_GUID = DDCBCFBA-8EEB-488a-96D6-097831A6E50B
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = HashLibBaseCrypto|PEIM
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
HashLibBaseCryptoRouterCommon.h
|
||||
HashLibBaseCryptoRouterCommon.c
|
||||
HashLibBaseCryptoRouterPei.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
Tpm2CommandLib
|
||||
MemoryAllocationLib
|
||||
PcdLib
|
||||
HobLib
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask
|
||||
|
342
SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c
Normal file
342
SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c
Normal file
@@ -0,0 +1,342 @@
|
||||
/** @file
|
||||
Ihis library uses TPM2 device to calculation hash.
|
||||
|
||||
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 <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/HashLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
|
||||
typedef struct {
|
||||
TPM_ALG_ID AlgoId;
|
||||
UINT32 Mask;
|
||||
} TPM2_HASH_MASK;
|
||||
|
||||
TPM2_HASH_MASK mTpm2HashMask[] = {
|
||||
{TPM_ALG_SHA1, TREE_BOOT_HASH_ALG_SHA1},
|
||||
{TPM_ALG_SHA256, TREE_BOOT_HASH_ALG_SHA256},
|
||||
{TPM_ALG_SHA384, TREE_BOOT_HASH_ALG_SHA384},
|
||||
{TPM_ALG_SHA512, TREE_BOOT_HASH_ALG_SHA512},
|
||||
};
|
||||
|
||||
/**
|
||||
The function get algorith from hash mask info.
|
||||
|
||||
@return Hash algorithm
|
||||
**/
|
||||
TPM_ALG_ID
|
||||
Tpm2GetAlgoFromHashMask (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 HashMask;
|
||||
UINTN Index;
|
||||
|
||||
HashMask = PcdGet32 (PcdTpm2HashMask);
|
||||
for (Index = 0; Index < sizeof(mTpm2HashMask)/sizeof(mTpm2HashMask[0]); Index++) {
|
||||
if (mTpm2HashMask[Index].Mask == HashMask) {
|
||||
return mTpm2HashMask[Index].AlgoId;
|
||||
}
|
||||
}
|
||||
|
||||
return TPM_ALG_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Start hash sequence.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashStart (
|
||||
OUT HASH_HANDLE *HashHandle
|
||||
)
|
||||
{
|
||||
TPMI_DH_OBJECT SequenceHandle;
|
||||
EFI_STATUS Status;
|
||||
TPM_ALG_ID AlgoId;
|
||||
|
||||
AlgoId = Tpm2GetAlgoFromHashMask ();
|
||||
|
||||
Status = Tpm2HashSequenceStart (AlgoId, &SequenceHandle);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
*HashHandle = (HASH_HANDLE)SequenceHandle;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Update hash sequence data.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence updated.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashUpdate (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen
|
||||
)
|
||||
{
|
||||
UINT8 *Buffer;
|
||||
UINT64 HashLen;
|
||||
TPM2B_MAX_BUFFER HashBuffer;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Buffer = (UINT8 *)(UINTN)DataToHash;
|
||||
for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {
|
||||
|
||||
HashBuffer.size = sizeof(HashBuffer.buffer);
|
||||
CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));
|
||||
Buffer += sizeof(HashBuffer.buffer);
|
||||
|
||||
Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Last one
|
||||
//
|
||||
HashBuffer.size = (UINT16)HashLen;
|
||||
CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);
|
||||
Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Hash sequence complete and extend to PCR.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param PcrIndex PCR to be extended.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
@param DigestList Digest list.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashCompleteAndExtend (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
IN TPMI_DH_PCR PcrIndex,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
)
|
||||
{
|
||||
UINT8 *Buffer;
|
||||
UINT64 HashLen;
|
||||
TPM2B_MAX_BUFFER HashBuffer;
|
||||
EFI_STATUS Status;
|
||||
TPM_ALG_ID AlgoId;
|
||||
TPM2B_DIGEST Result;
|
||||
|
||||
AlgoId = Tpm2GetAlgoFromHashMask ();
|
||||
|
||||
Buffer = (UINT8 *)(UINTN)DataToHash;
|
||||
for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {
|
||||
|
||||
HashBuffer.size = sizeof(HashBuffer.buffer);
|
||||
CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));
|
||||
Buffer += sizeof(HashBuffer.buffer);
|
||||
|
||||
Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Last one
|
||||
//
|
||||
HashBuffer.size = (UINT16)HashLen;
|
||||
CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);
|
||||
|
||||
ZeroMem(DigestList, sizeof(*DigestList));
|
||||
DigestList->count = HASH_COUNT;
|
||||
|
||||
if (AlgoId == TPM_ALG_NULL) {
|
||||
Status = Tpm2EventSequenceComplete (
|
||||
PcrIndex,
|
||||
(TPMI_DH_OBJECT)HashHandle,
|
||||
&HashBuffer,
|
||||
DigestList
|
||||
);
|
||||
} else {
|
||||
Status = Tpm2SequenceComplete (
|
||||
(TPMI_DH_OBJECT)HashHandle,
|
||||
&HashBuffer,
|
||||
&Result
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
DigestList->count = 1;
|
||||
DigestList->digests[0].hashAlg = AlgoId;
|
||||
CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);
|
||||
Status = Tpm2PcrExtend (
|
||||
PcrIndex,
|
||||
DigestList
|
||||
);
|
||||
}
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Hash data and extend to PCR.
|
||||
|
||||
@param PcrIndex PCR to be extended.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
@param DigestList Digest list.
|
||||
|
||||
@retval EFI_SUCCESS Hash data and DigestList is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HashAndExtend (
|
||||
IN TPMI_DH_PCR PcrIndex,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 *Buffer;
|
||||
UINT64 HashLen;
|
||||
TPMI_DH_OBJECT SequenceHandle;
|
||||
TPM2B_MAX_BUFFER HashBuffer;
|
||||
TPM_ALG_ID AlgoId;
|
||||
TPM2B_EVENT EventData;
|
||||
TPM2B_DIGEST Result;
|
||||
|
||||
DEBUG((EFI_D_INFO, "\n HashAndExtend Entry \n"));
|
||||
|
||||
SequenceHandle = 0xFFFFFFFF; // Know bad value
|
||||
|
||||
AlgoId = Tpm2GetAlgoFromHashMask ();
|
||||
|
||||
if ((AlgoId == TPM_ALG_NULL) && (DataToHashLen <= sizeof(EventData.buffer))) {
|
||||
EventData.size = (UINT16)DataToHashLen;
|
||||
CopyMem (EventData.buffer, DataToHash, DataToHashLen);
|
||||
Status = Tpm2PcrEvent (PcrIndex, &EventData, DigestList);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = Tpm2HashSequenceStart(AlgoId, &SequenceHandle);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
DEBUG((EFI_D_INFO, "\n Tpm2HashSequenceStart Success \n"));
|
||||
|
||||
Buffer = (UINT8 *)(UINTN)DataToHash;
|
||||
for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {
|
||||
|
||||
HashBuffer.size = sizeof(HashBuffer.buffer);
|
||||
CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));
|
||||
Buffer += sizeof(HashBuffer.buffer);
|
||||
|
||||
Status = Tpm2SequenceUpdate(SequenceHandle, &HashBuffer);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
DEBUG((EFI_D_INFO, "\n Tpm2SequenceUpdate Success \n"));
|
||||
|
||||
HashBuffer.size = (UINT16)HashLen;
|
||||
CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);
|
||||
|
||||
ZeroMem(DigestList, sizeof(*DigestList));
|
||||
DigestList->count = HASH_COUNT;
|
||||
|
||||
if (AlgoId == TPM_ALG_NULL) {
|
||||
Status = Tpm2EventSequenceComplete (
|
||||
PcrIndex,
|
||||
SequenceHandle,
|
||||
&HashBuffer,
|
||||
DigestList
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
DEBUG((EFI_D_INFO, "\n Tpm2EventSequenceComplete Success \n"));
|
||||
} else {
|
||||
Status = Tpm2SequenceComplete (
|
||||
SequenceHandle,
|
||||
&HashBuffer,
|
||||
&Result
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
DEBUG((EFI_D_INFO, "\n Tpm2SequenceComplete Success \n"));
|
||||
|
||||
DigestList->count = 1;
|
||||
DigestList->digests[0].hashAlg = AlgoId;
|
||||
CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);
|
||||
Status = Tpm2PcrExtend (
|
||||
PcrIndex,
|
||||
DigestList
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
DEBUG((EFI_D_INFO, "\n Tpm2PcrExtend Success \n"));
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This service register Hash.
|
||||
|
||||
@param HashInterface Hash interface
|
||||
|
||||
@retval EFI_SUCCESS This hash interface is registered successfully.
|
||||
@retval EFI_UNSUPPORTED System does not support register this interface.
|
||||
@retval EFI_ALREADY_STARTED System already register this interface.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RegisterHashInterfaceLib (
|
||||
IN HASH_INTERFACE *HashInterface
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
45
SecurityPkg/Library/HashLibTpm2/HashLibTpm2.inf
Normal file
45
SecurityPkg/Library/HashLibTpm2/HashLibTpm2.inf
Normal file
@@ -0,0 +1,45 @@
|
||||
## @file
|
||||
# Ihis library uses TPM2 device to calculation hash.
|
||||
#
|
||||
# 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 = HashLibTpm2
|
||||
FILE_GUID = 1317F0D5-7842-475c-B1CA-6EDC20DCBE7D
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = HashLibTpm2
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
HashLibTpm2.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
Tpm2CommandLib
|
||||
MemoryAllocationLib
|
||||
PcdLib
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask
|
43
SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
Normal file
43
SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
Normal file
@@ -0,0 +1,43 @@
|
||||
## @file
|
||||
# This library is used by other modules to send TPM12 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 = Tpm12CommandLib
|
||||
FILE_GUID = C595047C-70B3-4731-99CC-A014E956D7A7
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = Tpm12CommandLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Tpm12Startup.c
|
||||
Tpm12Ownership.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
IoLib
|
||||
TimerLib
|
||||
DebugLib
|
||||
Tpm12DeviceLib
|
||||
|
72
SecurityPkg/Library/Tpm12CommandLib/Tpm12Ownership.c
Normal file
72
SecurityPkg/Library/Tpm12CommandLib/Tpm12Ownership.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/** @file
|
||||
Implement TPM1.2 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 <Uefi.h>
|
||||
#include <IndustryStandard/Tpm12.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/Tpm12DeviceLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM_RQU_COMMAND_HDR Hdr;
|
||||
} TPM_CMD_FORCE_CLEAR;
|
||||
|
||||
typedef struct {
|
||||
TPM_RSP_COMMAND_HDR Hdr;
|
||||
} TPM_RSP_FORCE_CLEAR;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
Send ForceClear command to TPM1.2.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12ForceClear (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 TpmRecvSize;
|
||||
UINT32 TpmSendSize;
|
||||
TPM_CMD_FORCE_CLEAR SendBuffer;
|
||||
TPM_RSP_FORCE_CLEAR RecvBuffer;
|
||||
UINT32 ReturnCode;
|
||||
|
||||
//
|
||||
// send Tpm command TPM_ORD_ForceClear
|
||||
//
|
||||
TpmRecvSize = sizeof (TPM_RSP_FORCE_CLEAR);
|
||||
TpmSendSize = sizeof (TPM_CMD_FORCE_CLEAR);
|
||||
SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
|
||||
SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
|
||||
SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_ForceClear);
|
||||
|
||||
Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);
|
||||
switch (ReturnCode) {
|
||||
case TPM_SUCCESS:
|
||||
return EFI_SUCCESS;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
78
SecurityPkg/Library/Tpm12CommandLib/Tpm12Startup.c
Normal file
78
SecurityPkg/Library/Tpm12CommandLib/Tpm12Startup.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/** @file
|
||||
Implement TPM1.2 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 <Uefi.h>
|
||||
#include <IndustryStandard/Tpm12.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/Tpm12DeviceLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
TPM_RQU_COMMAND_HDR Hdr;
|
||||
TPM_STARTUP_TYPE TpmSt;
|
||||
} TPM_CMD_START_UP;
|
||||
|
||||
typedef struct {
|
||||
TPM_RSP_COMMAND_HDR Hdr;
|
||||
} TPM_RSP_START_UP;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
Send Startup command to TPM1.2.
|
||||
|
||||
@param TpmSt Startup Type.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12Startup (
|
||||
IN TPM_STARTUP_TYPE TpmSt
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 TpmRecvSize;
|
||||
UINT32 TpmSendSize;
|
||||
TPM_CMD_START_UP SendBuffer;
|
||||
TPM_RSP_START_UP RecvBuffer;
|
||||
UINT32 ReturnCode;
|
||||
|
||||
//
|
||||
// send Tpm command TPM_ORD_Startup
|
||||
//
|
||||
TpmRecvSize = sizeof (TPM_RSP_START_UP);
|
||||
TpmSendSize = sizeof (TPM_CMD_START_UP);
|
||||
SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
|
||||
SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
|
||||
SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_Startup);
|
||||
SendBuffer.TpmSt = SwapBytes16 (TpmSt);
|
||||
|
||||
Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);
|
||||
switch (ReturnCode) {
|
||||
case TPM_SUCCESS:
|
||||
case TPM_INVALID_POSTINIT:
|
||||
// In warm reset, TPM may response TPM_INVALID_POSTINIT
|
||||
return EFI_SUCCESS;
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
## @file
|
||||
# Ihis library is TPM2 DTPM device lib.
|
||||
# Choosing this library means platform uses and only uses DTPM device as TPM2 engine.
|
||||
#
|
||||
# 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 = Tpm12DeviceLibDTpm
|
||||
FILE_GUID = BC2B7672-A48B-4d58-B39E-AEE3707B5A23
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = Tpm12DeviceLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Tpm12Tis.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
IoLib
|
||||
TimerLib
|
||||
DebugLib
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
|
572
SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12Tis.c
Normal file
572
SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12Tis.c
Normal file
@@ -0,0 +1,572 @@
|
||||
/** @file
|
||||
TIS (TPM Interface Specification) functions used by TPM1.2.
|
||||
|
||||
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 <Uefi.h>
|
||||
#include <IndustryStandard/Tpm12.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/Tpm12CommandLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
//
|
||||
// Set structure alignment to 1-byte
|
||||
//
|
||||
#pragma pack (1)
|
||||
|
||||
//
|
||||
// Register set map as specified in TIS specification Chapter 10
|
||||
//
|
||||
typedef struct {
|
||||
///
|
||||
/// Used to gain ownership for this particular port.
|
||||
///
|
||||
UINT8 Access; // 0
|
||||
UINT8 Reserved1[7]; // 1
|
||||
///
|
||||
/// Controls interrupts.
|
||||
///
|
||||
UINT32 IntEnable; // 8
|
||||
///
|
||||
/// SIRQ vector to be used by the TPM.
|
||||
///
|
||||
UINT8 IntVector; // 0ch
|
||||
UINT8 Reserved2[3]; // 0dh
|
||||
///
|
||||
/// What caused interrupt.
|
||||
///
|
||||
UINT32 IntSts; // 10h
|
||||
///
|
||||
/// Shows which interrupts are supported by that particular TPM.
|
||||
///
|
||||
UINT32 IntfCapability; // 14h
|
||||
///
|
||||
/// Status Register. Provides status of the TPM.
|
||||
///
|
||||
UINT8 Status; // 18h
|
||||
///
|
||||
/// Number of consecutive writes that can be done to the TPM.
|
||||
///
|
||||
UINT16 BurstCount; // 19h
|
||||
UINT8 Reserved3[9];
|
||||
///
|
||||
/// Read or write FIFO, depending on transaction.
|
||||
///
|
||||
UINT32 DataFifo; // 24h
|
||||
UINT8 Reserved4[0xed8]; // 28h
|
||||
///
|
||||
/// Vendor ID
|
||||
///
|
||||
UINT16 Vid; // 0f00h
|
||||
///
|
||||
/// Device ID
|
||||
///
|
||||
UINT16 Did; // 0f02h
|
||||
///
|
||||
/// Revision ID
|
||||
///
|
||||
UINT8 Rid; // 0f04h
|
||||
///
|
||||
/// TCG defined configuration registers.
|
||||
///
|
||||
UINT8 TcgDefined[0x7b]; // 0f05h
|
||||
///
|
||||
/// Alias to I/O legacy space.
|
||||
///
|
||||
UINT32 LegacyAddress1; // 0f80h
|
||||
///
|
||||
/// Additional 8 bits for I/O legacy space extension.
|
||||
///
|
||||
UINT32 LegacyAddress1Ex; // 0f84h
|
||||
///
|
||||
/// Alias to second I/O legacy space.
|
||||
///
|
||||
UINT32 LegacyAddress2; // 0f88h
|
||||
///
|
||||
/// Additional 8 bits for second I/O legacy space extension.
|
||||
///
|
||||
UINT32 LegacyAddress2Ex; // 0f8ch
|
||||
///
|
||||
/// Vendor-defined configuration registers.
|
||||
///
|
||||
UINT8 VendorDefined[0x70];// 0f90h
|
||||
} TIS_PC_REGISTERS;
|
||||
|
||||
//
|
||||
// Restore original structure alignment
|
||||
//
|
||||
#pragma pack ()
|
||||
|
||||
//
|
||||
// Define pointer types used to access TIS registers on PC
|
||||
//
|
||||
typedef TIS_PC_REGISTERS *TIS_PC_REGISTERS_PTR;
|
||||
|
||||
//
|
||||
// Define bits of ACCESS and STATUS registers
|
||||
//
|
||||
|
||||
///
|
||||
/// This bit is a 1 to indicate that the other bits in this register are valid.
|
||||
///
|
||||
#define TIS_PC_VALID BIT7
|
||||
///
|
||||
/// Indicate that this locality is active.
|
||||
///
|
||||
#define TIS_PC_ACC_ACTIVE BIT5
|
||||
///
|
||||
/// Set to 1 to indicate that this locality had the TPM taken away while
|
||||
/// this locality had the TIS_PC_ACC_ACTIVE bit set.
|
||||
///
|
||||
#define TIS_PC_ACC_SEIZED BIT4
|
||||
///
|
||||
/// Set to 1 to indicate that TPM MUST reset the
|
||||
/// TIS_PC_ACC_ACTIVE bit and remove ownership for localities less than the
|
||||
/// locality that is writing this bit.
|
||||
///
|
||||
#define TIS_PC_ACC_SEIZE BIT3
|
||||
///
|
||||
/// When this bit is 1, another locality is requesting usage of the TPM.
|
||||
///
|
||||
#define TIS_PC_ACC_PENDIND BIT2
|
||||
///
|
||||
/// Set to 1 to indicate that this locality is requesting to use TPM.
|
||||
///
|
||||
#define TIS_PC_ACC_RQUUSE BIT1
|
||||
///
|
||||
/// A value of 1 indicates that a T/OS has not been established on the platform
|
||||
///
|
||||
#define TIS_PC_ACC_ESTABLISH BIT0
|
||||
|
||||
///
|
||||
/// When this bit is 1, TPM is in the Ready state,
|
||||
/// indicating it is ready to receive a new command.
|
||||
///
|
||||
#define TIS_PC_STS_READY BIT6
|
||||
///
|
||||
/// Write a 1 to this bit to cause the TPM to execute that command.
|
||||
///
|
||||
#define TIS_PC_STS_GO BIT5
|
||||
///
|
||||
/// This bit indicates that the TPM has data available as a response.
|
||||
///
|
||||
#define TIS_PC_STS_DATA BIT4
|
||||
///
|
||||
/// The TPM sets this bit to a value of 1 when it expects another byte of data for a command.
|
||||
///
|
||||
#define TIS_PC_STS_EXPECT BIT3
|
||||
///
|
||||
/// Writes a 1 to this bit to force the TPM to re-send the response.
|
||||
///
|
||||
#define TIS_PC_STS_RETRY BIT1
|
||||
|
||||
//
|
||||
// Default TimeOut value
|
||||
//
|
||||
#define TIS_TIMEOUT_A (750 * 1000) // 750ms
|
||||
#define TIS_TIMEOUT_B (2000 * 1000) // 2s
|
||||
#define TIS_TIMEOUT_C (750 * 1000) // 750ms
|
||||
#define TIS_TIMEOUT_D (750 * 1000) // 750ms
|
||||
|
||||
//
|
||||
// Max TPM command/reponse length
|
||||
//
|
||||
#define TPMCMDBUFLENGTH 1024
|
||||
|
||||
/**
|
||||
Check whether TPM chip exist.
|
||||
|
||||
@param[in] TisReg Pointer to TIS register.
|
||||
|
||||
@retval TRUE TPM chip exists.
|
||||
@retval FALSE TPM chip is not found.
|
||||
**/
|
||||
BOOLEAN
|
||||
Tpm12TisPcPresenceCheck (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg
|
||||
)
|
||||
{
|
||||
UINT8 RegRead;
|
||||
|
||||
RegRead = MmioRead8 ((UINTN)&TisReg->Access);
|
||||
return (BOOLEAN)(RegRead != (UINT8)-1);
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the value of a TPM chip register satisfies the input BIT setting.
|
||||
|
||||
@param[in] Register Address port of register to be checked.
|
||||
@param[in] BitSet Check these data bits are set.
|
||||
@param[in] BitClear Check these data bits are clear.
|
||||
@param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
|
||||
|
||||
@retval EFI_SUCCESS The register satisfies the check bit.
|
||||
@retval EFI_TIMEOUT The register can't run into the expected status in time.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12TisPcWaitRegisterBits (
|
||||
IN UINT8 *Register,
|
||||
IN UINT8 BitSet,
|
||||
IN UINT8 BitClear,
|
||||
IN UINT32 TimeOut
|
||||
)
|
||||
{
|
||||
UINT8 RegRead;
|
||||
UINT32 WaitTime;
|
||||
|
||||
for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){
|
||||
RegRead = MmioRead8 ((UINTN)Register);
|
||||
if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0)
|
||||
return EFI_SUCCESS;
|
||||
MicroSecondDelay (30);
|
||||
}
|
||||
return EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
Get BurstCount by reading the burstCount field of a TIS regiger
|
||||
in the time of default TIS_TIMEOUT_D.
|
||||
|
||||
@param[in] TisReg Pointer to TIS register.
|
||||
@param[out] BurstCount Pointer to a buffer to store the got BurstConut.
|
||||
|
||||
@retval EFI_SUCCESS Get BurstCount.
|
||||
@retval EFI_INVALID_PARAMETER TisReg is NULL or BurstCount is NULL.
|
||||
@retval EFI_TIMEOUT BurstCount can't be got in time.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12TisPcReadBurstCount (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg,
|
||||
OUT UINT16 *BurstCount
|
||||
)
|
||||
{
|
||||
UINT32 WaitTime;
|
||||
UINT8 DataByte0;
|
||||
UINT8 DataByte1;
|
||||
|
||||
if (BurstCount == NULL || TisReg == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
WaitTime = 0;
|
||||
do {
|
||||
//
|
||||
// TIS_PC_REGISTERS_PTR->burstCount is UINT16, but it is not 2bytes aligned,
|
||||
// so it needs to use MmioRead8 to read two times
|
||||
//
|
||||
DataByte0 = MmioRead8 ((UINTN)&TisReg->BurstCount);
|
||||
DataByte1 = MmioRead8 ((UINTN)&TisReg->BurstCount + 1);
|
||||
*BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);
|
||||
if (*BurstCount != 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
MicroSecondDelay (30);
|
||||
WaitTime += 30;
|
||||
} while (WaitTime < TIS_TIMEOUT_D);
|
||||
|
||||
return EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
Set TPM chip to ready state by sending ready command TIS_PC_STS_READY
|
||||
to Status Register in time.
|
||||
|
||||
@param[in] TisReg Pointer to TIS register.
|
||||
|
||||
@retval EFI_SUCCESS TPM chip enters into ready state.
|
||||
@retval EFI_INVALID_PARAMETER TisReg is NULL.
|
||||
@retval EFI_TIMEOUT TPM chip can't be set to ready state in time.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12TisPcPrepareCommand (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (TisReg == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
|
||||
Status = Tpm12TisPcWaitRegisterBits (
|
||||
&TisReg->Status,
|
||||
TIS_PC_STS_READY,
|
||||
0,
|
||||
TIS_TIMEOUT_B
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE
|
||||
to ACCESS Register in the time of default TIS_TIMEOUT_A.
|
||||
|
||||
@param[in] TisReg Pointer to TIS register.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM chip.
|
||||
@retval EFI_INVALID_PARAMETER TisReg is NULL.
|
||||
@retval EFI_NOT_FOUND TPM chip doesn't exit.
|
||||
@retval EFI_TIMEOUT Can't get the TPM control in time.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12TisPcRequestUseTpm (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (TisReg == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!Tpm12TisPcPresenceCheck (TisReg)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
MmioWrite8((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);
|
||||
Status = Tpm12TisPcWaitRegisterBits (
|
||||
&TisReg->Access,
|
||||
(UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
|
||||
0,
|
||||
TIS_TIMEOUT_A
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Send a command to TPM for execution and return response data.
|
||||
|
||||
@param[in] TisReg TPM register space base address.
|
||||
@param[in] BufferIn Buffer for command data.
|
||||
@param[in] SizeIn Size of command data.
|
||||
@param[in, out] BufferOut Buffer for response data.
|
||||
@param[in, out] SizeOut Size of response data.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_TIMEOUT The register can't run into the expected status in time.
|
||||
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
@retval EFI_UNSUPPORTED Unsupported TPM version
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Tpm12TisTpmCommand (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg,
|
||||
IN UINT8 *BufferIn,
|
||||
IN UINT32 SizeIn,
|
||||
IN OUT UINT8 *BufferOut,
|
||||
IN OUT UINT32 *SizeOut
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT16 BurstCount;
|
||||
UINT32 Index;
|
||||
UINT32 TpmOutSize;
|
||||
UINT16 Data16;
|
||||
UINT32 Data32;
|
||||
|
||||
DEBUG_CODE (
|
||||
UINTN DebugSize;
|
||||
|
||||
DEBUG ((EFI_D_INFO, "Tpm12TisTpmCommand Send - "));
|
||||
if (SizeIn > 0x100) {
|
||||
DebugSize = 0x40;
|
||||
} else {
|
||||
DebugSize = SizeIn;
|
||||
}
|
||||
for (Index = 0; Index < DebugSize; Index++) {
|
||||
DEBUG ((EFI_D_INFO, "%02x ", BufferIn[Index]));
|
||||
}
|
||||
if (DebugSize != SizeIn) {
|
||||
DEBUG ((EFI_D_INFO, "...... "));
|
||||
for (Index = SizeIn - 0x20; Index < SizeIn; Index++) {
|
||||
DEBUG ((EFI_D_INFO, "%02x ", BufferIn[Index]));
|
||||
}
|
||||
}
|
||||
DEBUG ((EFI_D_INFO, "\n"));
|
||||
);
|
||||
TpmOutSize = 0;
|
||||
|
||||
Status = Tpm12TisPcPrepareCommand (TisReg);
|
||||
if (EFI_ERROR (Status)){
|
||||
DEBUG ((DEBUG_ERROR, "Tpm12 is not ready for command!\n"));
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Send the command data to Tpm
|
||||
//
|
||||
Index = 0;
|
||||
while (Index < SizeIn) {
|
||||
Status = Tpm12TisPcReadBurstCount (TisReg, &BurstCount);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_TIMEOUT;
|
||||
goto Exit;
|
||||
}
|
||||
for (; BurstCount > 0 && Index < SizeIn; BurstCount--) {
|
||||
MmioWrite8((UINTN)&TisReg->DataFifo, *(BufferIn + Index));
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Check the Tpm status STS_EXPECT change from 1 to 0
|
||||
//
|
||||
Status = Tpm12TisPcWaitRegisterBits (
|
||||
&TisReg->Status,
|
||||
(UINT8) TIS_PC_VALID,
|
||||
TIS_PC_STS_EXPECT,
|
||||
TIS_TIMEOUT_C
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Tpm12 The send buffer too small!\n"));
|
||||
Status = EFI_BUFFER_TOO_SMALL;
|
||||
goto Exit;
|
||||
}
|
||||
//
|
||||
// Executed the TPM command and waiting for the response data ready
|
||||
//
|
||||
MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_GO);
|
||||
Status = Tpm12TisPcWaitRegisterBits (
|
||||
&TisReg->Status,
|
||||
(UINT8) (TIS_PC_VALID | TIS_PC_STS_DATA),
|
||||
0,
|
||||
TIS_TIMEOUT_B
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Wait for Tpm12 response data time out!!\n"));
|
||||
Status = EFI_TIMEOUT;
|
||||
goto Exit;
|
||||
}
|
||||
//
|
||||
// Get response data header
|
||||
//
|
||||
Index = 0;
|
||||
BurstCount = 0;
|
||||
while (Index < sizeof (TPM_RSP_COMMAND_HDR)) {
|
||||
Status = Tpm12TisPcReadBurstCount (TisReg, &BurstCount);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_TIMEOUT;
|
||||
goto Exit;
|
||||
}
|
||||
for (; BurstCount > 0; BurstCount--) {
|
||||
*(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
|
||||
Index++;
|
||||
if (Index == sizeof (TPM_RSP_COMMAND_HDR)) break;
|
||||
}
|
||||
}
|
||||
DEBUG_CODE (
|
||||
DEBUG ((EFI_D_INFO, "Tpm12TisTpmCommand ReceiveHeader - "));
|
||||
for (Index = 0; Index < sizeof (TPM_RSP_COMMAND_HDR); Index++) {
|
||||
DEBUG ((EFI_D_INFO, "%02x ", BufferOut[Index]));
|
||||
}
|
||||
DEBUG ((EFI_D_INFO, "\n"));
|
||||
);
|
||||
//
|
||||
// Check the reponse data header (tag,parasize and returncode )
|
||||
//
|
||||
CopyMem (&Data16, BufferOut, sizeof (UINT16));
|
||||
if (SwapBytes16 (Data16) != TPM_TAG_RSP_COMMAND) {
|
||||
DEBUG ((EFI_D_ERROR, "TPM12: TPM_ST_RSP error - %x\n", TPM_TAG_RSP_COMMAND));
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
CopyMem (&Data32, (BufferOut + 2), sizeof (UINT32));
|
||||
TpmOutSize = SwapBytes32 (Data32);
|
||||
if (*SizeOut < TpmOutSize) {
|
||||
Status = EFI_BUFFER_TOO_SMALL;
|
||||
goto Exit;
|
||||
}
|
||||
*SizeOut = TpmOutSize;
|
||||
//
|
||||
// Continue reading the remaining data
|
||||
//
|
||||
while ( Index < TpmOutSize ) {
|
||||
for (; BurstCount > 0; BurstCount--) {
|
||||
*(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
|
||||
Index++;
|
||||
if (Index == TpmOutSize) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
Status = Tpm12TisPcReadBurstCount (TisReg, &BurstCount);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_TIMEOUT;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
Exit:
|
||||
DEBUG_CODE (
|
||||
DEBUG ((EFI_D_INFO, "Tpm12TisTpmCommand Receive - "));
|
||||
for (Index = 0; Index < TpmOutSize; Index++) {
|
||||
DEBUG ((EFI_D_INFO, "%02x ", BufferOut[Index]));
|
||||
}
|
||||
DEBUG ((EFI_D_INFO, "\n"));
|
||||
);
|
||||
MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM12.
|
||||
|
||||
@param[in] InputParameterBlockSize Size of the TPM12 input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM12 input parameter block.
|
||||
@param[in,out] OutputParameterBlockSize Size of the TPM12 output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM12 output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12SubmitCommand (
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
IN OUT UINT32 *OutputParameterBlockSize,
|
||||
IN UINT8 *OutputParameterBlock
|
||||
)
|
||||
{
|
||||
return Tpm12TisTpmCommand (
|
||||
(TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress),
|
||||
InputParameterBlock,
|
||||
InputParameterBlockSize,
|
||||
OutputParameterBlock,
|
||||
OutputParameterBlockSize
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This service requests use TPM12.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM12 chip.
|
||||
@retval EFI_NOT_FOUND TPM12 not found.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12RequestUseTpm (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return Tpm12TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress));
|
||||
}
|
108
SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.c
Normal file
108
SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/** @file
|
||||
Ihis library is TPM12 TCG protocol lib.
|
||||
|
||||
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 <Uefi.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/Tpm12DeviceLib.h>
|
||||
#include <Protocol/TcgService.h>
|
||||
#include <IndustryStandard/Tpm12.h>
|
||||
|
||||
EFI_TCG_PROTOCOL *mTcgProtocol = NULL;
|
||||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM12.
|
||||
|
||||
@param[in] InputParameterBlockSize Size of the TPM12 input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM12 input parameter block.
|
||||
@param[in,out] OutputParameterBlockSize Size of the TPM12 output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM12 output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12SubmitCommand (
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
IN OUT UINT32 *OutputParameterBlockSize,
|
||||
IN UINT8 *OutputParameterBlock
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM_RSP_COMMAND_HDR *Header;
|
||||
|
||||
if (mTcgProtocol == NULL) {
|
||||
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &mTcgProtocol);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// TCG protocol is not installed. So, TPM12 is not present.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "Tpm12SubmitCommand - TCG - %r\n", Status));
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Assume when TCG Protocol is ready, RequestUseTpm already done.
|
||||
//
|
||||
Status = mTcgProtocol->PassThroughToTpm (
|
||||
mTcgProtocol,
|
||||
InputParameterBlockSize,
|
||||
InputParameterBlock,
|
||||
*OutputParameterBlockSize,
|
||||
OutputParameterBlock
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
Header = (TPM_RSP_COMMAND_HDR *)OutputParameterBlock;
|
||||
*OutputParameterBlockSize = SwapBytes32 (Header->paramSize);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This service requests use TPM12.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM12 chip.
|
||||
@retval EFI_NOT_FOUND TPM12 not found.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12RequestUseTpm (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (mTcgProtocol == NULL) {
|
||||
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &mTcgProtocol);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// TCG protocol is not installed. So, TPM12 is not present.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "Tpm12RequestUseTpm - TCG - %r\n", Status));
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Assume when TCG Protocol is ready, RequestUseTpm already done.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
42
SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
Normal file
42
SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
Normal file
@@ -0,0 +1,42 @@
|
||||
## @file
|
||||
# Ihis library is TPM12 TCG protocol lib.
|
||||
#
|
||||
# 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 = Tpm12DeviceLibTcg
|
||||
FILE_GUID = 4D8B77D9-E923-48f8-B070-4053D78B7E56
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = Tpm12DeviceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_APPLICATION UEFI_DRIVER
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Tpm12DeviceLibTcg.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
UefiBootServicesTableLib
|
||||
|
||||
[Protocols]
|
||||
gEfiTcgProtocolGuid ## CONSUMES
|
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;
|
||||
}
|
116
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.c
Normal file
116
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/** @file
|
||||
Ihis library is TPM2 DTPM device lib.
|
||||
Choosing this library means platform uses and only uses DTPM device as TPM2 engine.
|
||||
|
||||
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 <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM2.
|
||||
|
||||
@param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
|
||||
@param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DTpm2SubmitCommand (
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
IN OUT UINT32 *OutputParameterBlockSize,
|
||||
IN UINT8 *OutputParameterBlock
|
||||
);
|
||||
|
||||
/**
|
||||
This service requests use TPM2.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM2 chip.
|
||||
@retval EFI_NOT_FOUND TPM2 not found.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DTpm2RequestUseTpm (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM2.
|
||||
|
||||
@param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
|
||||
@param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2SubmitCommand (
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
IN OUT UINT32 *OutputParameterBlockSize,
|
||||
IN UINT8 *OutputParameterBlock
|
||||
)
|
||||
{
|
||||
return DTpm2SubmitCommand (
|
||||
InputParameterBlockSize,
|
||||
InputParameterBlock,
|
||||
OutputParameterBlockSize,
|
||||
OutputParameterBlock
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This service requests use TPM2.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM2 chip.
|
||||
@retval EFI_NOT_FOUND TPM2 not found.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2RequestUseTpm (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return DTpm2RequestUseTpm ();
|
||||
}
|
||||
|
||||
/**
|
||||
This service register TPM2 device.
|
||||
|
||||
@param Tpm2Device TPM2 device
|
||||
|
||||
@retval EFI_SUCCESS This TPM2 device is registered successfully.
|
||||
@retval EFI_UNSUPPORTED System does not support register this TPM2 device.
|
||||
@retval EFI_ALREADY_STARTED System already register this TPM2 device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2RegisterTpm2DeviceLib (
|
||||
IN TPM2_DEVICE_INTERFACE *Tpm2Device
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
45
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
Normal file
45
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
Normal file
@@ -0,0 +1,45 @@
|
||||
## @file
|
||||
# Ihis library is TPM2 DTPM device lib.
|
||||
# Choosing this library means platform uses and only uses DTPM device as TPM2 engine.
|
||||
#
|
||||
# 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 = Tpm2DeviceLibDTpm
|
||||
FILE_GUID = E54A3327-A345-4068-8842-70AC0D519855
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = Tpm2DeviceLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Tpm2Tis.c
|
||||
Tpm2DeviceLibDTpm.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
IoLib
|
||||
TimerLib
|
||||
DebugLib
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
|
85
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.c
Normal file
85
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/** @file
|
||||
Ihis library is TPM2 DTPM instance.
|
||||
It can be registered to Tpm2 Device router, to be active TPM2 engine,
|
||||
based on platform setting.
|
||||
|
||||
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 <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
|
||||
#include <Guid/TpmInstance.h>
|
||||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM2.
|
||||
|
||||
@param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
|
||||
@param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DTpm2SubmitCommand (
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
IN OUT UINT32 *OutputParameterBlockSize,
|
||||
IN UINT8 *OutputParameterBlock
|
||||
);
|
||||
|
||||
/**
|
||||
This service requests use TPM2.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM2 chip.
|
||||
@retval EFI_NOT_FOUND TPM2 not found.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DTpm2RequestUseTpm (
|
||||
VOID
|
||||
);
|
||||
|
||||
TPM2_DEVICE_INTERFACE mDTpm2InternalTpm2Device = {
|
||||
TPM_DEVICE_INTERFACE_TPM20_DTPM,
|
||||
DTpm2SubmitCommand,
|
||||
DTpm2RequestUseTpm,
|
||||
};
|
||||
|
||||
/**
|
||||
The function register DTPM2.0 instance.
|
||||
|
||||
@retval EFI_SUCCESS DTPM2.0 instance is registered, or system dose not surpport registr DTPM2.0 instance
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2InstanceLibDTpmConstructor (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = Tpm2RegisterTpm2DeviceLib (&mDTpm2InternalTpm2Device);
|
||||
if ((Status == EFI_SUCCESS) || (Status == EFI_UNSUPPORTED)) {
|
||||
//
|
||||
// Unsupported means platform policy does not need this instance enabled.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
## @file
|
||||
# Ihis library is TPM2 DTPM instance.
|
||||
# It can be registered to Tpm2 Device router, to be active TPM2 engine,
|
||||
# based on platform setting.
|
||||
#
|
||||
# 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 = Tpm2InstanceLibDTpm
|
||||
FILE_GUID = 286BF25A-C2C3-408c-B3B4-25E6758B7317
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = NULL
|
||||
CONSTRUCTOR = Tpm2InstanceLibDTpmConstructor
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Tpm2Tis.c
|
||||
Tpm2InstanceLibDTpm.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
IoLib
|
||||
TimerLib
|
||||
DebugLib
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
|
583
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Tis.c
Normal file
583
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Tis.c
Normal file
@@ -0,0 +1,583 @@
|
||||
/** @file
|
||||
TIS (TPM Interface Specification) functions used by dTPM2.0 library.
|
||||
|
||||
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/Tpm20.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
//
|
||||
// Set structure alignment to 1-byte
|
||||
//
|
||||
#pragma pack (1)
|
||||
|
||||
//
|
||||
// Register set map as specified in TIS specification Chapter 10
|
||||
//
|
||||
typedef struct {
|
||||
///
|
||||
/// Used to gain ownership for this particular port.
|
||||
///
|
||||
UINT8 Access; // 0
|
||||
UINT8 Reserved1[7]; // 1
|
||||
///
|
||||
/// Controls interrupts.
|
||||
///
|
||||
UINT32 IntEnable; // 8
|
||||
///
|
||||
/// SIRQ vector to be used by the TPM.
|
||||
///
|
||||
UINT8 IntVector; // 0ch
|
||||
UINT8 Reserved2[3]; // 0dh
|
||||
///
|
||||
/// What caused interrupt.
|
||||
///
|
||||
UINT32 IntSts; // 10h
|
||||
///
|
||||
/// Shows which interrupts are supported by that particular TPM.
|
||||
///
|
||||
UINT32 IntfCapability; // 14h
|
||||
///
|
||||
/// Status Register. Provides status of the TPM.
|
||||
///
|
||||
UINT8 Status; // 18h
|
||||
///
|
||||
/// Number of consecutive writes that can be done to the TPM.
|
||||
///
|
||||
UINT16 BurstCount; // 19h
|
||||
///
|
||||
/// TPM2 support CANCEL at BIT[24] of STATUS register (WO)
|
||||
///
|
||||
UINT8 StatusEx; // 1Bh
|
||||
UINT8 Reserved3[8];
|
||||
///
|
||||
/// Read or write FIFO, depending on transaction.
|
||||
///
|
||||
UINT32 DataFifo; // 24h
|
||||
UINT8 Reserved4[0xed8]; // 28h
|
||||
///
|
||||
/// Vendor ID
|
||||
///
|
||||
UINT16 Vid; // 0f00h
|
||||
///
|
||||
/// Device ID
|
||||
///
|
||||
UINT16 Did; // 0f02h
|
||||
///
|
||||
/// Revision ID
|
||||
///
|
||||
UINT8 Rid; // 0f04h
|
||||
///
|
||||
/// TCG defined configuration registers.
|
||||
///
|
||||
UINT8 TcgDefined[0x7b]; // 0f05h
|
||||
///
|
||||
/// Alias to I/O legacy space.
|
||||
///
|
||||
UINT32 LegacyAddress1; // 0f80h
|
||||
///
|
||||
/// Additional 8 bits for I/O legacy space extension.
|
||||
///
|
||||
UINT32 LegacyAddress1Ex; // 0f84h
|
||||
///
|
||||
/// Alias to second I/O legacy space.
|
||||
///
|
||||
UINT32 LegacyAddress2; // 0f88h
|
||||
///
|
||||
/// Additional 8 bits for second I/O legacy space extension.
|
||||
///
|
||||
UINT32 LegacyAddress2Ex; // 0f8ch
|
||||
///
|
||||
/// Vendor-defined configuration registers.
|
||||
///
|
||||
UINT8 VendorDefined[0x70];// 0f90h
|
||||
} TIS_PC_REGISTERS;
|
||||
|
||||
//
|
||||
// Restore original structure alignment
|
||||
//
|
||||
#pragma pack ()
|
||||
|
||||
//
|
||||
// Define pointer types used to access TIS registers on PC
|
||||
//
|
||||
typedef TIS_PC_REGISTERS *TIS_PC_REGISTERS_PTR;
|
||||
|
||||
//
|
||||
// Define bits of ACCESS and STATUS registers
|
||||
//
|
||||
|
||||
///
|
||||
/// This bit is a 1 to indicate that the other bits in this register are valid.
|
||||
///
|
||||
#define TIS_PC_VALID BIT7
|
||||
///
|
||||
/// Indicate that this locality is active.
|
||||
///
|
||||
#define TIS_PC_ACC_ACTIVE BIT5
|
||||
///
|
||||
/// Set to 1 to indicate that this locality had the TPM taken away while
|
||||
/// this locality had the TIS_PC_ACC_ACTIVE bit set.
|
||||
///
|
||||
#define TIS_PC_ACC_SEIZED BIT4
|
||||
///
|
||||
/// Set to 1 to indicate that TPM MUST reset the
|
||||
/// TIS_PC_ACC_ACTIVE bit and remove ownership for localities less than the
|
||||
/// locality that is writing this bit.
|
||||
///
|
||||
#define TIS_PC_ACC_SEIZE BIT3
|
||||
///
|
||||
/// When this bit is 1, another locality is requesting usage of the TPM.
|
||||
///
|
||||
#define TIS_PC_ACC_PENDIND BIT2
|
||||
///
|
||||
/// Set to 1 to indicate that this locality is requesting to use TPM.
|
||||
///
|
||||
#define TIS_PC_ACC_RQUUSE BIT1
|
||||
///
|
||||
/// A value of 1 indicates that a T/OS has not been established on the platform
|
||||
///
|
||||
#define TIS_PC_ACC_ESTABLISH BIT0
|
||||
|
||||
///
|
||||
/// When this bit is 1, TPM is in the Ready state,
|
||||
/// indicating it is ready to receive a new command.
|
||||
///
|
||||
#define TIS_PC_STS_READY BIT6
|
||||
///
|
||||
/// Write a 1 to this bit to cause the TPM to execute that command.
|
||||
///
|
||||
#define TIS_PC_STS_GO BIT5
|
||||
///
|
||||
/// This bit indicates that the TPM has data available as a response.
|
||||
///
|
||||
#define TIS_PC_STS_DATA BIT4
|
||||
///
|
||||
/// The TPM sets this bit to a value of 1 when it expects another byte of data for a command.
|
||||
///
|
||||
#define TIS_PC_STS_EXPECT BIT3
|
||||
///
|
||||
/// Writes a 1 to this bit to force the TPM to re-send the response.
|
||||
///
|
||||
#define TIS_PC_STS_RETRY BIT1
|
||||
|
||||
//
|
||||
// Default TimeOut value
|
||||
//
|
||||
#define TIS_TIMEOUT_A (1000 * 1000) // 1s
|
||||
#define TIS_TIMEOUT_B (2000 * 1000) // 2s
|
||||
#define TIS_TIMEOUT_C (1000 * 1000) // 1s
|
||||
#define TIS_TIMEOUT_D (1000 * 1000) // 1s
|
||||
|
||||
#define TIS_TIMEOUT_MAX (90000 * 1000) // 90s
|
||||
|
||||
//
|
||||
// Max TPM command/reponse length
|
||||
//
|
||||
#define TPMCMDBUFLENGTH 0x500
|
||||
|
||||
/**
|
||||
Check whether TPM chip exist.
|
||||
|
||||
@param[in] TisReg Pointer to TIS register.
|
||||
|
||||
@retval TRUE TPM chip exists.
|
||||
@retval FALSE TPM chip is not found.
|
||||
**/
|
||||
BOOLEAN
|
||||
TisPcPresenceCheck (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg
|
||||
)
|
||||
{
|
||||
UINT8 RegRead;
|
||||
|
||||
RegRead = MmioRead8 ((UINTN)&TisReg->Access);
|
||||
return (BOOLEAN)(RegRead != (UINT8)-1);
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the value of a TPM chip register satisfies the input BIT setting.
|
||||
|
||||
@param[in] Register Address port of register to be checked.
|
||||
@param[in] BitSet Check these data bits are set.
|
||||
@param[in] BitClear Check these data bits are clear.
|
||||
@param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
|
||||
|
||||
@retval EFI_SUCCESS The register satisfies the check bit.
|
||||
@retval EFI_TIMEOUT The register can't run into the expected status in time.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TisPcWaitRegisterBits (
|
||||
IN UINT8 *Register,
|
||||
IN UINT8 BitSet,
|
||||
IN UINT8 BitClear,
|
||||
IN UINT32 TimeOut
|
||||
)
|
||||
{
|
||||
UINT8 RegRead;
|
||||
UINT32 WaitTime;
|
||||
|
||||
for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){
|
||||
RegRead = MmioRead8 ((UINTN)Register);
|
||||
if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0)
|
||||
return EFI_SUCCESS;
|
||||
MicroSecondDelay (30);
|
||||
}
|
||||
return EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
Get BurstCount by reading the burstCount field of a TIS regiger
|
||||
in the time of default TIS_TIMEOUT_D.
|
||||
|
||||
@param[in] TisReg Pointer to TIS register.
|
||||
@param[out] BurstCount Pointer to a buffer to store the got BurstConut.
|
||||
|
||||
@retval EFI_SUCCESS Get BurstCount.
|
||||
@retval EFI_INVALID_PARAMETER TisReg is NULL or BurstCount is NULL.
|
||||
@retval EFI_TIMEOUT BurstCount can't be got in time.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TisPcReadBurstCount (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg,
|
||||
OUT UINT16 *BurstCount
|
||||
)
|
||||
{
|
||||
UINT32 WaitTime;
|
||||
UINT8 DataByte0;
|
||||
UINT8 DataByte1;
|
||||
|
||||
if (BurstCount == NULL || TisReg == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
WaitTime = 0;
|
||||
do {
|
||||
//
|
||||
// TIS_PC_REGISTERS_PTR->burstCount is UINT16, but it is not 2bytes aligned,
|
||||
// so it needs to use MmioRead8 to read two times
|
||||
//
|
||||
DataByte0 = MmioRead8 ((UINTN)&TisReg->BurstCount);
|
||||
DataByte1 = MmioRead8 ((UINTN)&TisReg->BurstCount + 1);
|
||||
*BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);
|
||||
if (*BurstCount != 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
MicroSecondDelay (30);
|
||||
WaitTime += 30;
|
||||
} while (WaitTime < TIS_TIMEOUT_D);
|
||||
|
||||
return EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
Set TPM chip to ready state by sending ready command TIS_PC_STS_READY
|
||||
to Status Register in time.
|
||||
|
||||
@param[in] TisReg Pointer to TIS register.
|
||||
|
||||
@retval EFI_SUCCESS TPM chip enters into ready state.
|
||||
@retval EFI_INVALID_PARAMETER TisReg is NULL.
|
||||
@retval EFI_TIMEOUT TPM chip can't be set to ready state in time.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TisPcPrepareCommand (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (TisReg == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
|
||||
Status = TisPcWaitRegisterBits (
|
||||
&TisReg->Status,
|
||||
TIS_PC_STS_READY,
|
||||
0,
|
||||
TIS_TIMEOUT_B
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE
|
||||
to ACCESS Register in the time of default TIS_TIMEOUT_A.
|
||||
|
||||
@param[in] TisReg Pointer to TIS register.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM chip.
|
||||
@retval EFI_INVALID_PARAMETER TisReg is NULL.
|
||||
@retval EFI_NOT_FOUND TPM chip doesn't exit.
|
||||
@retval EFI_TIMEOUT Can't get the TPM control in time.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TisPcRequestUseTpm (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (TisReg == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!TisPcPresenceCheck (TisReg)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
MmioWrite8((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);
|
||||
Status = TisPcWaitRegisterBits (
|
||||
&TisReg->Access,
|
||||
(UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
|
||||
0,
|
||||
TIS_TIMEOUT_A
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Send a command to TPM for execution and return response data.
|
||||
|
||||
@param[in] TisReg TPM register space base address.
|
||||
@param[in] BufferIn Buffer for command data.
|
||||
@param[in] SizeIn Size of command data.
|
||||
@param[in, out] BufferOut Buffer for response data.
|
||||
@param[in, out] SizeOut Size of response data.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_TIMEOUT The register can't run into the expected status in time.
|
||||
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
@retval EFI_UNSUPPORTED Unsupported TPM version
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
TisTpmCommand (
|
||||
IN TIS_PC_REGISTERS_PTR TisReg,
|
||||
IN UINT8 *BufferIn,
|
||||
IN UINT32 SizeIn,
|
||||
IN OUT UINT8 *BufferOut,
|
||||
IN OUT UINT32 *SizeOut
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT16 BurstCount;
|
||||
UINT32 Index;
|
||||
UINT32 TpmOutSize;
|
||||
UINT16 Data16;
|
||||
UINT32 Data32;
|
||||
|
||||
DEBUG_CODE (
|
||||
UINTN DebugSize;
|
||||
|
||||
DEBUG ((EFI_D_INFO, "TisTpmCommand Send - "));
|
||||
if (SizeIn > 0x100) {
|
||||
DebugSize = 0x40;
|
||||
} else {
|
||||
DebugSize = SizeIn;
|
||||
}
|
||||
for (Index = 0; Index < DebugSize; Index++) {
|
||||
DEBUG ((EFI_D_INFO, "%02x ", BufferIn[Index]));
|
||||
}
|
||||
if (DebugSize != SizeIn) {
|
||||
DEBUG ((EFI_D_INFO, "...... "));
|
||||
for (Index = SizeIn - 0x20; Index < SizeIn; Index++) {
|
||||
DEBUG ((EFI_D_INFO, "%02x ", BufferIn[Index]));
|
||||
}
|
||||
}
|
||||
DEBUG ((EFI_D_INFO, "\n"));
|
||||
);
|
||||
TpmOutSize = 0;
|
||||
|
||||
Status = TisPcPrepareCommand (TisReg);
|
||||
if (EFI_ERROR (Status)){
|
||||
DEBUG ((DEBUG_ERROR, "Tpm is not ready for command!\n"));
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Send the command data to Tpm
|
||||
//
|
||||
Index = 0;
|
||||
while (Index < SizeIn) {
|
||||
Status = TisPcReadBurstCount (TisReg, &BurstCount);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_TIMEOUT;
|
||||
goto Exit;
|
||||
}
|
||||
for (; BurstCount > 0 && Index < SizeIn; BurstCount--) {
|
||||
MmioWrite8((UINTN)&TisReg->DataFifo, *(BufferIn + Index));
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Check the Tpm status STS_EXPECT change from 1 to 0
|
||||
//
|
||||
Status = TisPcWaitRegisterBits (
|
||||
&TisReg->Status,
|
||||
(UINT8) TIS_PC_VALID,
|
||||
TIS_PC_STS_EXPECT,
|
||||
TIS_TIMEOUT_C
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "The send buffer too small!\n"));
|
||||
Status = EFI_BUFFER_TOO_SMALL;
|
||||
goto Exit;
|
||||
}
|
||||
//
|
||||
// Executed the TPM command and waiting for the response data ready
|
||||
//
|
||||
MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_GO);
|
||||
|
||||
//
|
||||
// NOTE: That may take many seconds to minutes for certain commands, such as key generation.
|
||||
//
|
||||
Status = TisPcWaitRegisterBits (
|
||||
&TisReg->Status,
|
||||
(UINT8) (TIS_PC_VALID | TIS_PC_STS_DATA),
|
||||
0,
|
||||
TIS_TIMEOUT_MAX
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Wait for Tpm response data time out!!\n"));
|
||||
Status = EFI_TIMEOUT;
|
||||
goto Exit;
|
||||
}
|
||||
//
|
||||
// Get response data header
|
||||
//
|
||||
Index = 0;
|
||||
BurstCount = 0;
|
||||
while (Index < sizeof (TPM2_RESPONSE_HEADER)) {
|
||||
Status = TisPcReadBurstCount (TisReg, &BurstCount);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_TIMEOUT;
|
||||
goto Exit;
|
||||
}
|
||||
for (; BurstCount > 0; BurstCount--) {
|
||||
*(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
|
||||
Index++;
|
||||
if (Index == sizeof (TPM2_RESPONSE_HEADER)) break;
|
||||
}
|
||||
}
|
||||
DEBUG_CODE (
|
||||
DEBUG ((EFI_D_INFO, "TisTpmCommand ReceiveHeader - "));
|
||||
for (Index = 0; Index < sizeof (TPM2_RESPONSE_HEADER); Index++) {
|
||||
DEBUG ((EFI_D_INFO, "%02x ", BufferOut[Index]));
|
||||
}
|
||||
DEBUG ((EFI_D_INFO, "\n"));
|
||||
);
|
||||
//
|
||||
// Check the reponse data header (tag,parasize and returncode )
|
||||
//
|
||||
CopyMem (&Data16, BufferOut, sizeof (UINT16));
|
||||
// TPM2 should not use this RSP_COMMAND
|
||||
if (SwapBytes16 (Data16) == TPM_ST_RSP_COMMAND) {
|
||||
DEBUG ((EFI_D_ERROR, "TPM_ST_RSP error - %x\n", TPM_ST_RSP_COMMAND));
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
CopyMem (&Data32, (BufferOut + 2), sizeof (UINT32));
|
||||
TpmOutSize = SwapBytes32 (Data32);
|
||||
if (*SizeOut < TpmOutSize) {
|
||||
Status = EFI_BUFFER_TOO_SMALL;
|
||||
goto Exit;
|
||||
}
|
||||
*SizeOut = TpmOutSize;
|
||||
//
|
||||
// Continue reading the remaining data
|
||||
//
|
||||
while ( Index < TpmOutSize ) {
|
||||
for (; BurstCount > 0; BurstCount--) {
|
||||
*(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
|
||||
Index++;
|
||||
if (Index == TpmOutSize) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
Status = TisPcReadBurstCount (TisReg, &BurstCount);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_TIMEOUT;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
Exit:
|
||||
DEBUG_CODE (
|
||||
DEBUG ((EFI_D_INFO, "TisTpmCommand Receive - "));
|
||||
for (Index = 0; Index < TpmOutSize; Index++) {
|
||||
DEBUG ((EFI_D_INFO, "%02x ", BufferOut[Index]));
|
||||
}
|
||||
DEBUG ((EFI_D_INFO, "\n"));
|
||||
);
|
||||
MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM2.
|
||||
|
||||
@param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
|
||||
@param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DTpm2SubmitCommand (
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
IN OUT UINT32 *OutputParameterBlockSize,
|
||||
IN UINT8 *OutputParameterBlock
|
||||
)
|
||||
{
|
||||
return TisTpmCommand (
|
||||
(TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress),
|
||||
InputParameterBlock,
|
||||
InputParameterBlockSize,
|
||||
OutputParameterBlock,
|
||||
OutputParameterBlockSize
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This service requests use TPM2.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM2 chip.
|
||||
@retval EFI_NOT_FOUND TPM2 not found.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DTpm2RequestUseTpm (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress));
|
||||
}
|
@@ -0,0 +1,98 @@
|
||||
/** @file
|
||||
Ihis library is TPM2 device router. Platform can register multi TPM2 instance to it
|
||||
via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
|
||||
At most one TPM2 instance can be finally registered, and other will return unsupported.
|
||||
|
||||
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 <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
|
||||
TPM2_DEVICE_INTERFACE mInternalTpm2DeviceInterface;
|
||||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM2.
|
||||
|
||||
@param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
|
||||
@param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2SubmitCommand (
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
IN OUT UINT32 *OutputParameterBlockSize,
|
||||
IN UINT8 *OutputParameterBlock
|
||||
)
|
||||
{
|
||||
if (mInternalTpm2DeviceInterface.Tpm2SubmitCommand == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
return mInternalTpm2DeviceInterface.Tpm2SubmitCommand (
|
||||
InputParameterBlockSize,
|
||||
InputParameterBlock,
|
||||
OutputParameterBlockSize,
|
||||
OutputParameterBlock
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This service requests use TPM2.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM2 chip.
|
||||
@retval EFI_NOT_FOUND TPM2 not found.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2RequestUseTpm (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
if (mInternalTpm2DeviceInterface.Tpm2RequestUseTpm == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
return mInternalTpm2DeviceInterface.Tpm2RequestUseTpm ();
|
||||
}
|
||||
|
||||
/**
|
||||
This service register TPM2 device.
|
||||
|
||||
@param Tpm2Device TPM2 device
|
||||
|
||||
@retval EFI_SUCCESS This TPM2 device is registered successfully.
|
||||
@retval EFI_UNSUPPORTED System does not support register this TPM2 device.
|
||||
@retval EFI_ALREADY_STARTED System already register this TPM2 device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2RegisterTpm2DeviceLib (
|
||||
IN TPM2_DEVICE_INTERFACE *Tpm2Device
|
||||
)
|
||||
{
|
||||
if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &Tpm2Device->ProviderGuid)){
|
||||
DEBUG ((EFI_D_ERROR, "WARNING: Tpm2RegisterTpm2DeviceLib - does not support %g registration\n", &Tpm2Device->ProviderGuid));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
CopyMem (&mInternalTpm2DeviceInterface, Tpm2Device, sizeof(mInternalTpm2DeviceInterface));
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
## @file
|
||||
# Ihis library is TPM2 device router. Platform can register multi TPM2 instance to it
|
||||
# via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
|
||||
# At most one TPM2 instance can be finally registered, and other will return unsupported.
|
||||
#
|
||||
# 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 = Tpm2DeviceLibRouterDxe
|
||||
FILE_GUID = C3D69D87-5200-4aab-A6DB-2569BA1A92FC
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = Tpm2DeviceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Tpm2DeviceLibRouterDxe.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
PcdLib
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
143
SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterPei.c
Normal file
143
SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterPei.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/** @file
|
||||
Ihis library is TPM2 device router. Platform can register multi TPM2 instance to it
|
||||
via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
|
||||
At most one TPM2 instance can be finally registered, and other will return unsupported.
|
||||
|
||||
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 <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
|
||||
EFI_GUID mInternalTpm2DeviceInterfaceGuid = {
|
||||
0x349cf818, 0xc0ba, 0x4c43, 0x92, 0x9a, 0xc8, 0xa1, 0xb1, 0xb3, 0xd2, 0x55
|
||||
};
|
||||
|
||||
/**
|
||||
This function get TPM2.0 interface.
|
||||
|
||||
@retval TPM2.0 interface.
|
||||
**/
|
||||
TPM2_DEVICE_INTERFACE *
|
||||
InternalGetTpm2DeviceInterface (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_HOB_GUID_TYPE *Hob;
|
||||
|
||||
Hob = GetFirstGuidHob (&mInternalTpm2DeviceInterfaceGuid);
|
||||
if (Hob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return (TPM2_DEVICE_INTERFACE *)(Hob + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM2.
|
||||
|
||||
@param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
|
||||
@param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2SubmitCommand (
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
IN OUT UINT32 *OutputParameterBlockSize,
|
||||
IN UINT8 *OutputParameterBlock
|
||||
)
|
||||
{
|
||||
TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;
|
||||
|
||||
Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
|
||||
if (Tpm2DeviceInterface == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return Tpm2DeviceInterface->Tpm2SubmitCommand (
|
||||
InputParameterBlockSize,
|
||||
InputParameterBlock,
|
||||
OutputParameterBlockSize,
|
||||
OutputParameterBlock
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
This service requests use TPM2.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM2 chip.
|
||||
@retval EFI_NOT_FOUND TPM2 not found.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2RequestUseTpm (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;
|
||||
|
||||
Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
|
||||
if (Tpm2DeviceInterface == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
return Tpm2DeviceInterface->Tpm2RequestUseTpm ();
|
||||
}
|
||||
|
||||
/**
|
||||
This service register TPM2 device.
|
||||
|
||||
@param Tpm2Device TPM2 device
|
||||
|
||||
@retval EFI_SUCCESS This TPM2 device is registered successfully.
|
||||
@retval EFI_UNSUPPORTED System does not support register this TPM2 device.
|
||||
@retval EFI_ALREADY_STARTED System already register this TPM2 device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2RegisterTpm2DeviceLib (
|
||||
IN TPM2_DEVICE_INTERFACE *Tpm2Device
|
||||
)
|
||||
{
|
||||
TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;
|
||||
|
||||
if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &Tpm2Device->ProviderGuid)){
|
||||
DEBUG ((EFI_D_ERROR, "WARNING: Tpm2RegisterTpm2DeviceLib - does not support %g registration\n", &Tpm2Device->ProviderGuid));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
|
||||
if (Tpm2DeviceInterface != NULL) {
|
||||
//
|
||||
// In PEI phase, there will be shadow driver dispatched again.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2RegisterTpm2DeviceLib - Override\n"));
|
||||
CopyMem (Tpm2DeviceInterface, Tpm2Device, sizeof(*Tpm2Device));
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
Tpm2Device = BuildGuidDataHob (&mInternalTpm2DeviceInterfaceGuid, Tpm2Device, sizeof(*Tpm2Device));
|
||||
if (Tpm2Device != NULL) {
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
## @file
|
||||
# Ihis library is TPM2 device router. Platform can register multi TPM2 instance to it
|
||||
# via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
|
||||
# At most one TPM2 instance can be finally registered, and other will return unsupported.
|
||||
#
|
||||
# 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 = Tpm2DeviceLibRouterPei
|
||||
FILE_GUID = 97CDCF04-4C8E-42fe-8015-11CC8A6E9D81
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = Tpm2DeviceLib|PEIM
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Tpm2DeviceLibRouterPei.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
HobLib
|
||||
PcdLib
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
|
125
SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.c
Normal file
125
SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/** @file
|
||||
Ihis library is TPM2 TREE protocol lib.
|
||||
|
||||
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 <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
#include <IndustryStandard/Tpm20.h>
|
||||
|
||||
EFI_TREE_PROTOCOL *mTreeProtocol = NULL;
|
||||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM2.
|
||||
|
||||
@param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
|
||||
@param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2SubmitCommand (
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
IN OUT UINT32 *OutputParameterBlockSize,
|
||||
IN UINT8 *OutputParameterBlock
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPM2_RESPONSE_HEADER *Header;
|
||||
|
||||
if (mTreeProtocol == NULL) {
|
||||
Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &mTreeProtocol);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// TrEE protocol is not installed. So, TPM2 is not present.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2SubmitCommand - TrEE - %r\n", Status));
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Assume when TrEE Protocol is ready, RequestUseTpm already done.
|
||||
//
|
||||
Status = mTreeProtocol->SubmitCommand (
|
||||
mTreeProtocol,
|
||||
InputParameterBlockSize,
|
||||
InputParameterBlock,
|
||||
*OutputParameterBlockSize,
|
||||
OutputParameterBlock
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
Header = (TPM2_RESPONSE_HEADER *)OutputParameterBlock;
|
||||
*OutputParameterBlockSize = SwapBytes32 (Header->paramSize);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This service requests use TPM2.
|
||||
|
||||
@retval EFI_SUCCESS Get the control of TPM2 chip.
|
||||
@retval EFI_NOT_FOUND TPM2 not found.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2RequestUseTpm (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (mTreeProtocol == NULL) {
|
||||
Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &mTreeProtocol);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// TrEE protocol is not installed. So, TPM2 is not present.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "Tpm2RequestUseTpm - TrEE - %r\n", Status));
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Assume when TrEE Protocol is ready, RequestUseTpm already done.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This service register TPM2 device.
|
||||
|
||||
@param Tpm2Device TPM2 device
|
||||
|
||||
@retval EFI_SUCCESS This TPM2 device is registered successfully.
|
||||
@retval EFI_UNSUPPORTED System does not support register this TPM2 device.
|
||||
@retval EFI_ALREADY_STARTED System already register this TPM2 device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2RegisterTpm2DeviceLib (
|
||||
IN TPM2_DEVICE_INTERFACE *Tpm2Device
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
42
SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
Normal file
42
SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
Normal file
@@ -0,0 +1,42 @@
|
||||
## @file
|
||||
# Ihis library is TPM2 TREE protocol lib.
|
||||
#
|
||||
# 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 = Tpm2DeviceLibTrEE
|
||||
FILE_GUID = BBCB6F85-303C-4eb9-8182-AF98D4B3020C
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = Tpm2DeviceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Tpm2DeviceLibTrEE.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
UefiBootServicesTableLib
|
||||
|
||||
[Protocols]
|
||||
gEfiTrEEProtocolGuid ## CONSUMES
|
Reference in New Issue
Block a user