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:
38
SecurityPkg/Include/Guid/TpmInstance.h
Normal file
38
SecurityPkg/Include/Guid/TpmInstance.h
Normal file
@ -0,0 +1,38 @@
|
||||
/** @file
|
||||
TPM instance guid, used for PcdTpmInstanceGuid.
|
||||
|
||||
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 __TPM_INSTANCE_GUID_H__
|
||||
#define __TPM_INSTANCE_GUID_H__
|
||||
|
||||
#define TPM_DEVICE_INTERFACE_NONE \
|
||||
{ 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
|
||||
|
||||
#define TPM_DEVICE_INTERFACE_TPM12 \
|
||||
{ 0x8b01e5b6, 0x4f19, 0x46e8, { 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc } }
|
||||
|
||||
#define TPM_DEVICE_INTERFACE_TPM20_DTPM \
|
||||
{ 0x286bf25a, 0xc2c3, 0x408c, { 0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17 } }
|
||||
|
||||
extern EFI_GUID gEfiTpmDeviceInstanceNoneGuid;
|
||||
extern EFI_GUID gEfiTpmDeviceInstanceTpm12Guid;
|
||||
extern EFI_GUID gEfiTpmDeviceInstanceTpm20DtpmGuid;
|
||||
|
||||
|
||||
#define TPM_DEVICE_SELECTED_GUID \
|
||||
{ 0x7f4158d3, 0x74d, 0x456d, { 0x8c, 0xb2, 0x1, 0xf9, 0xc8, 0xf7, 0x9d, 0xaa } }
|
||||
|
||||
extern EFI_GUID gEfiTpmDeviceSelectedGuid;
|
||||
|
||||
#endif
|
||||
|
25
SecurityPkg/Include/Guid/TrEEConfigHii.h
Normal file
25
SecurityPkg/Include/Guid/TrEEConfigHii.h
Normal file
@ -0,0 +1,25 @@
|
||||
/** @file
|
||||
GUIDs used as HII FormSet and HII Package list GUID in TrEEConfig driver.
|
||||
|
||||
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 that 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 __TREE_CONFIG_HII_GUID_H__
|
||||
#define __TREE_CONFIG_HII_GUID_H__
|
||||
|
||||
#define TREE_CONFIG_FORM_SET_GUID \
|
||||
{ \
|
||||
0xc54b425f, 0xaa79, 0x48b4, { 0x98, 0x1f, 0x99, 0x8b, 0x3c, 0x4b, 0x64, 0x1c } \
|
||||
}
|
||||
|
||||
extern EFI_GUID gTrEEConfigFormSetGuid;
|
||||
|
||||
#endif
|
62
SecurityPkg/Include/Guid/TrEEPhysicalPresenceData.h
Normal file
62
SecurityPkg/Include/Guid/TrEEPhysicalPresenceData.h
Normal file
@ -0,0 +1,62 @@
|
||||
/** @file
|
||||
Define the variable data structures used for TrEE physical presence.
|
||||
The TPM2 request from firmware or OS is saved to variable. And it is
|
||||
cleared after it is processed in the next boot cycle. The TPM2 response
|
||||
is saved to 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.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __TREE_PHYSICAL_PRESENCE_DATA_GUID_H__
|
||||
#define __TREE_PHYSICAL_PRESENCE_DATA_GUID_H__
|
||||
|
||||
#define EFI_TREE_PHYSICAL_PRESENCE_DATA_GUID \
|
||||
{ \
|
||||
0xf24643c2, 0xc622, 0x494e, { 0x8a, 0xd, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b }\
|
||||
}
|
||||
|
||||
#define TREE_PHYSICAL_PRESENCE_VARIABLE L"TrEEPhysicalPresence"
|
||||
|
||||
typedef struct {
|
||||
UINT8 PPRequest; ///< Physical Presence request command.
|
||||
UINT8 LastPPRequest;
|
||||
UINT32 PPResponse;
|
||||
} EFI_TREE_PHYSICAL_PRESENCE;
|
||||
|
||||
//
|
||||
// The definition bit of the flags
|
||||
//
|
||||
#define TREE_FLAG_NO_PPI_CLEAR BIT1
|
||||
#define TREE_FLAG_RESET_TRACK BIT3
|
||||
|
||||
//
|
||||
// This variable is used to save TPM Management Flags and corresponding operations.
|
||||
// It should be protected from malicious software (e.g. Set it as read-only variable).
|
||||
//
|
||||
#define TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE L"TrEEPhysicalPresenceFlags"
|
||||
|
||||
//
|
||||
// The definition of physical presence operation actions
|
||||
//
|
||||
#define TREE_PHYSICAL_PRESENCE_NO_ACTION 0
|
||||
#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR 5
|
||||
#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2 14
|
||||
#define TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE 17
|
||||
#define TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE 18
|
||||
#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3 21
|
||||
#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4 22
|
||||
|
||||
#define TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX 22
|
||||
|
||||
extern EFI_GUID gEfiTrEEPhysicalPresenceGuid;
|
||||
|
||||
#endif
|
||||
|
169
SecurityPkg/Include/Library/HashLib.h
Normal file
169
SecurityPkg/Include/Library/HashLib.h
Normal file
@ -0,0 +1,169 @@
|
||||
/** @file
|
||||
Ihis library abstract TPM2 hash calculation.
|
||||
The platform can choose multiply hash, while caller just need invoke these API.
|
||||
Then all hash value will be returned and/or extended.
|
||||
|
||||
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_H_
|
||||
#define _HASH_LIB_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Protocol/Hash.h>
|
||||
|
||||
typedef UINTN HASH_HANDLE;
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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 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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *HASH_INIT) (
|
||||
OUT HASH_HANDLE *HashHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Update hash sequence data.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param DataToHash Data to be hashed.
|
||||
@param DataToHashLen Data size.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence updated.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *HASH_UPDATE) (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
IN VOID *DataToHash,
|
||||
IN UINTN DataToHashLen
|
||||
);
|
||||
|
||||
/**
|
||||
Complete hash sequence complete.
|
||||
|
||||
@param HashHandle Hash handle.
|
||||
@param DigestList Digest list.
|
||||
|
||||
@retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *HASH_FINAL) (
|
||||
IN HASH_HANDLE HashHandle,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
);
|
||||
|
||||
#define HASH_ALGORITHM_SHA1_GUID EFI_HASH_ALGORITHM_SHA1_GUID
|
||||
#define HASH_ALGORITHM_SHA256_GUID EFI_HASH_ALGORITHM_SHA256_GUID
|
||||
#define HASH_ALGORITHM_SHA384_GUID EFI_HASH_ALGORITHM_SHA384_GUID
|
||||
#define HASH_ALGORITHM_SHA512_GUID EFI_HASH_ALGORITHM_SHA512_GUID
|
||||
|
||||
typedef struct {
|
||||
EFI_GUID HashGuid;
|
||||
HASH_INIT HashInit;
|
||||
HASH_UPDATE HashUpdate;
|
||||
HASH_FINAL HashFinal;
|
||||
} HASH_INTERFACE;
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
#endif
|
46
SecurityPkg/Include/Library/Tpm12CommandLib.h
Normal file
46
SecurityPkg/Include/Library/Tpm12CommandLib.h
Normal file
@ -0,0 +1,46 @@
|
||||
/** @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.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _TPM12_COMMAND_LIB_H_
|
||||
#define _TPM12_COMMAND_LIB_H_
|
||||
|
||||
#include <IndustryStandard/Tpm12.h>
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
Send ForceClear command to TPM1.2.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR Unexpected device behavior.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm12ForceClear (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif
|
54
SecurityPkg/Include/Library/Tpm12DeviceLib.h
Normal file
54
SecurityPkg/Include/Library/Tpm12DeviceLib.h
Normal file
@ -0,0 +1,54 @@
|
||||
/** @file
|
||||
This library abstract how to access TPM12 hardware device.
|
||||
|
||||
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 _TPM12_DEVICE_LIB_H_
|
||||
#define _TPM12_DEVICE_LIB_H_
|
||||
|
||||
#include <IndustryStandard/Tpm12.h>
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
#endif
|
824
SecurityPkg/Include/Library/Tpm2CommandLib.h
Normal file
824
SecurityPkg/Include/Library/Tpm2CommandLib.h
Normal file
@ -0,0 +1,824 @@
|
||||
/** @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.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _TPM2_COMMAND_LIB_H_
|
||||
#define _TPM2_COMMAND_LIB_H_
|
||||
|
||||
#include <IndustryStandard/Tpm20.h>
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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 LockHandle
|
||||
@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
|
||||
);
|
||||
|
||||
/**
|
||||
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 LockHandle
|
||||
@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
|
||||
);
|
||||
|
||||
/**
|
||||
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.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tpm2NvReadPublic (
|
||||
IN TPMI_RH_NV_INDEX NvIndex,
|
||||
OUT TPM2B_NV_PUBLIC *NvPublic,
|
||||
OUT TPM2B_NAME *NvName
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
//
|
||||
// Help function
|
||||
//
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
Return size of digest.
|
||||
|
||||
@param[in] HashAlgo Hash algorithm
|
||||
|
||||
@return size of digest
|
||||
**/
|
||||
UINT16
|
||||
EFIAPI
|
||||
GetHashSizeFromAlgo (
|
||||
IN TPMI_ALG_HASH HashAlgo
|
||||
);
|
||||
|
||||
#endif
|
109
SecurityPkg/Include/Library/Tpm2DeviceLib.h
Normal file
109
SecurityPkg/Include/Library/Tpm2DeviceLib.h
Normal file
@ -0,0 +1,109 @@
|
||||
/** @file
|
||||
This library abstract how to access TPM2 hardware device.
|
||||
|
||||
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 _TPM2_DEVICE_LIB_H_
|
||||
#define _TPM2_DEVICE_LIB_H_
|
||||
|
||||
#include <Uefi.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
|
||||
Tpm2SubmitCommand (
|
||||
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
|
||||
Tpm2RequestUseTpm (
|
||||
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.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *TPM2_SUBMIT_COMMAND) (
|
||||
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.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *TPM2_REQUEST_USE_TPM) (
|
||||
VOID
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
EFI_GUID ProviderGuid;
|
||||
TPM2_SUBMIT_COMMAND Tpm2SubmitCommand;
|
||||
TPM2_REQUEST_USE_TPM Tpm2RequestUseTpm;
|
||||
} TPM2_DEVICE_INTERFACE;
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
#endif
|
57
SecurityPkg/Include/Library/TrEEPhysicalPresenceLib.h
Normal file
57
SecurityPkg/Include/Library/TrEEPhysicalPresenceLib.h
Normal file
@ -0,0 +1,57 @@
|
||||
/** @file
|
||||
Ihis library is intended to be used by BDS modules.
|
||||
This library will executing TPM2 request.
|
||||
|
||||
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 _TREE_PHYSICAL_PRESENCE_LIB_H_
|
||||
#define _TREE_PHYSICAL_PRESENCE_LIB_H_
|
||||
|
||||
#include <IndustryStandard/Tpm20.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
|
||||
/**
|
||||
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 PlatformAuth platform auth value. NULL means no platform auth change.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
TrEEPhysicalPresenceLibProcessRequest (
|
||||
IN TPM2B_AUTH *PlatformAuth OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
#endif
|
@ -0,0 +1,37 @@
|
||||
/** @file
|
||||
Ihis PPI means a FV does not need to be extended to PCR by TCG modules.
|
||||
|
||||
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 __EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_H__
|
||||
#define __EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_H__
|
||||
|
||||
#define EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI_GUID \
|
||||
{ 0x6e056ff9, 0xc695, 0x4364, { 0x9e, 0x2c, 0x61, 0x26, 0xf5, 0xce, 0xea, 0xae } }
|
||||
|
||||
typedef struct {
|
||||
EFI_PHYSICAL_ADDRESS FvBase;
|
||||
UINT64 FvLength;
|
||||
} EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV;
|
||||
|
||||
//
|
||||
// This PPI means a FV does not need to be extended to PCR by TCG modules.
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Count;
|
||||
EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV Fv[1];
|
||||
} EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI;
|
||||
|
||||
extern EFI_GUID gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid;
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
@ -41,3 +41,4 @@
|
||||
|
||||
[Protocols]
|
||||
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
|
@ -26,6 +26,10 @@
|
||||
## @libraryclass Definitions for common TPM commands as library API for TPM
|
||||
# module use.
|
||||
TpmCommLib|Include/Library/TpmCommLib.h
|
||||
Tpm2CommandLib|Include/Library/Tpm2CommandLib.h
|
||||
Tpm2DeviceLib|Include/Library/Tpm2DeviceLib.h
|
||||
TrEEPhysicalPresenceLib|Include/Library/TrEEPhysicalPresenceLib.h
|
||||
TpmMeasurementLib|Include/Library/TpmMeasurementLib.h
|
||||
|
||||
[Guids]
|
||||
## Security package token space guid
|
||||
@ -74,6 +78,18 @@
|
||||
## Include/Guid/SecureBootConfigHii.h
|
||||
gSecureBootConfigFormSetGuid = { 0x5daf50a5, 0xea81, 0x4de2, {0x8f, 0x9b, 0xca, 0xbd, 0xa9, 0xcf, 0x5c, 0x14}}
|
||||
|
||||
## Include/Guid/TrEEPhysicalPresenceData.h
|
||||
gEfiTrEEPhysicalPresenceGuid = { 0xf24643c2, 0xc622, 0x494e, { 0x8a, 0xd, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b }}
|
||||
|
||||
## Include/Guid/TpmInstance.h
|
||||
gEfiTpmDeviceInstanceNoneGuid = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
|
||||
gEfiTpmDeviceInstanceTpm12Guid = { 0x8b01e5b6, 0x4f19, 0x46e8, { 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc } }
|
||||
gEfiTpmDeviceInstanceTpm20DtpmGuid = { 0x286bf25a, 0xc2c3, 0x408c, { 0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17 } }
|
||||
gEfiTpmDeviceSelectedGuid = { 0x7f4158d3, 0x74d, 0x456d, { 0x8c, 0xb2, 0x1, 0xf9, 0xc8, 0xf7, 0x9d, 0xaa } }
|
||||
|
||||
## Include/Guid/TrEEConfigHii.h
|
||||
gTrEEConfigFormSetGuid = {0xc54b425f, 0xaa79, 0x48b4, { 0x98, 0x1f, 0x99, 0x8b, 0x3c, 0x4b, 0x64, 0x1c }}
|
||||
|
||||
[Ppis]
|
||||
## Include/Ppi/LockPhysicalPresence.h
|
||||
gPeiLockPhysicalPresencePpiGuid = { 0xef9aefe5, 0x2bd3, 0x4031, { 0xaf, 0x7d, 0x5e, 0xfe, 0x5a, 0xbb, 0x9a, 0xd } }
|
||||
@ -81,6 +97,9 @@
|
||||
## Include/Ppi/TpmInitialized.h
|
||||
gPeiTpmInitializedPpiGuid = { 0xe9db0d58, 0xd48d, 0x47f6, { 0x9c, 0x6e, 0x6f, 0x40, 0xe8, 0x6c, 0x7b, 0x41 }}
|
||||
|
||||
## Include/Ppi/FirmwareVolumeInfoMeasurementExcluded.h
|
||||
gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid = { 0x6e056ff9, 0xc695, 0x4364, { 0x9e, 0x2c, 0x61, 0x26, 0xf5, 0xce, 0xea, 0xae } }
|
||||
|
||||
[PcdsFixedAtBuild]
|
||||
## Pcd for OptionRom.
|
||||
# Image verification policy settings:
|
||||
@ -167,3 +186,56 @@
|
||||
## This PCD is used to specify the default value for physicalPresenceHWEnable bit when setting physicalPresenceLifetimeLock bit.
|
||||
## If PcdPhysicalPresenceHwEnable is set to TRUE, physicalPresenceHWEnable bit will be set, else this bit will be cleared.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdPhysicalPresenceHwEnable|TRUE|BOOLEAN|0x00010005
|
||||
|
||||
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
|
||||
## This PCD indicates if debugger exists.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdFirmwareDebuggerInitialized|FALSE|BOOLEAN|0x00010009
|
||||
|
||||
## This PCD indicates the TPM2 initializatin policy.
|
||||
## 0: No initialization needed - most likely used for chipset SRTM sloution, in which TPM is already initialized.
|
||||
## 1: Initialization needed.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy|1|UINT8|0x0001000A
|
||||
|
||||
## This PCD indicates the TPM initializatin policy.
|
||||
## 0: No initialization needed - most likely used for chipset SRTM sloution, in which TPM is already initialized.
|
||||
## 1: Initialization needed.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1|UINT8|0x0001000B
|
||||
|
||||
## This PCD indicates the TPM2 SelfTest policy.
|
||||
## 0: No SelfTest needed - most likely used for fTPM, because it might already be tested.
|
||||
## 1: SelfTest needed.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2SelfTestPolicy|1|UINT8|0x0001000C
|
||||
|
||||
## This PCD indicates the TPM2 SCRTM policy.
|
||||
## 0: No SCRTM needed - In this case, it is already done.
|
||||
## 1: SCRTM done by BIOS.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy|1|UINT8|0x0001000D
|
||||
|
||||
## This PCD indicates the TPM SCRTM policy.
|
||||
## 0: No SCRTM needed - In this case, it is already done.
|
||||
## 1: SCRTM done by BIOS.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1|UINT8|0x0001000E
|
||||
|
||||
## Guid name to identify TPM instance
|
||||
## TPM_DEVICE_INTERFACE_NONE means disable
|
||||
## TPM_DEVICE_INTERFACE_TPM12 means TPM1.2 DTPM
|
||||
## TPM_DEVICE_INTERFACE_DTPM2 means TPM2 DTPM
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid |{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0x0001000F
|
||||
|
||||
## This PCD indicates the TPM2 Hash mask.
|
||||
## BIT0: SHA1
|
||||
## BIT1: SHA256
|
||||
## BIT2: SHA384
|
||||
## BIT3: SHA512
|
||||
## If this bit is set, that means this algorithm is needed to extend to PCR.
|
||||
## If this bit is clear, that means this algorithm is NOT needed to extend to PCR.
|
||||
## 0xFFFFFFFF means extend all.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0xFFFFFFFF|UINT32|0x00010010
|
||||
|
||||
## This PCD indicates if BIOS auto detect TPM1.2 or dTPM2.0.
|
||||
## 0: No auto detection.
|
||||
## 1: Auto detection.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmAutoDetection|TRUE|BOOLEAN|0x00010011
|
||||
|
||||
## This PCD indicates TPM base address.
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0xFED40000|UINT64|0x00010012
|
||||
|
@ -32,6 +32,7 @@
|
||||
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
||||
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
||||
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
|
||||
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
||||
|
||||
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
|
||||
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
|
||||
@ -51,6 +52,9 @@
|
||||
PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
|
||||
TcgPhysicalPresenceLib|SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
|
||||
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
|
||||
Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
|
||||
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
|
||||
TrEEPhysicalPresenceLib|SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.inf
|
||||
|
||||
[LibraryClasses.common.PEIM]
|
||||
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
|
||||
@ -59,31 +63,59 @@
|
||||
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
|
||||
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
|
||||
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
|
||||
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
|
||||
|
||||
[LibraryClasses.common.DXE_DRIVER]
|
||||
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
|
||||
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
|
||||
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
|
||||
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
|
||||
|
||||
[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER,]
|
||||
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
|
||||
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
|
||||
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
|
||||
|
||||
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
|
||||
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
|
||||
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
|
||||
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
|
||||
|
||||
[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
|
||||
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
|
||||
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
|
||||
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
|
||||
|
||||
[LibraryClasses.IPF.DXE_SAL_DRIVER]
|
||||
ExtendedSalLib|MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf
|
||||
BaseCryptLib|CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/BaseCryptLibRuntimeCryptProtocol.inf
|
||||
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
|
||||
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
|
||||
|
||||
[LibraryClasses.common.DXE_SMM_DRIVER]
|
||||
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
|
||||
MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
|
||||
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
|
||||
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
|
||||
|
||||
[PcdsDynamicDefault.common.DEFAULT]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0xb6, 0xe5, 0x01, 0x8b, 0x19, 0x4f, 0xe8, 0x46, 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc}
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy|1
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2SelfTestPolicy|1
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy|1
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1
|
||||
|
||||
[Components]
|
||||
SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf
|
||||
@ -103,10 +135,32 @@
|
||||
#
|
||||
SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
|
||||
SecurityPkg/Library/TpmCommLib/TpmCommLib.inf
|
||||
SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
|
||||
SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
|
||||
SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
|
||||
SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
|
||||
|
||||
SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
|
||||
SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
|
||||
|
||||
#
|
||||
# TPM2
|
||||
#
|
||||
SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
|
||||
SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.inf
|
||||
|
||||
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
|
||||
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
|
||||
|
||||
SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
|
||||
SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
|
||||
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
|
||||
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
|
||||
SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf
|
||||
SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterPei.inf
|
||||
|
||||
SecurityPkg/Library/HashLibTpm2/HashLibTpm2.inf
|
||||
|
||||
[Components.IA32, Components.X64, Components.IPF]
|
||||
SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProviderDxe.inf
|
||||
SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProviderDxe.inf
|
||||
@ -123,10 +177,43 @@
|
||||
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
|
||||
}
|
||||
|
||||
#
|
||||
# TPM2
|
||||
#
|
||||
SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
|
||||
SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
|
||||
|
||||
SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf {
|
||||
<LibraryClasses>
|
||||
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
|
||||
}
|
||||
SecurityPkg/Tcg/TrEEPei/TrEEPei.inf {
|
||||
<LibraryClasses>
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterPei.inf
|
||||
NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
|
||||
NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
|
||||
NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
|
||||
}
|
||||
|
||||
SecurityPkg/Tcg/TrEEDxe/TrEEDxe.inf {
|
||||
<LibraryClasses>
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf
|
||||
NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
|
||||
NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
|
||||
NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
|
||||
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
|
||||
}
|
||||
SecurityPkg/Tcg/TrEEConfig/TrEEConfigDxe.inf {
|
||||
<LibraryClasses>
|
||||
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf
|
||||
}
|
||||
|
||||
[Components.IA32, Components.X64]
|
||||
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
|
||||
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
|
||||
SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
|
||||
SecurityPkg/Tcg/TrEESmm/TrEESmm.inf
|
||||
|
||||
[Components.IPF]
|
||||
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/EsalVariableDxeSal.inf
|
||||
|
@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# Component description file for Memory Overwrite Control driver.
|
||||
#
|
||||
# Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2009 - 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
|
||||
@ -47,5 +47,5 @@
|
||||
[Depex]
|
||||
gEfiVariableArchProtocolGuid AND
|
||||
gEfiVariableWriteArchProtocolGuid AND
|
||||
gEfiTcgProtocolGuid
|
||||
( gEfiTcgProtocolGuid OR gEfiTrEEProtocolGuid )
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
The module entry point for Tcg configuration module.
|
||||
|
||||
Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2011 - 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
|
||||
@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
|
||||
#include "TcgConfigImpl.h"
|
||||
#include <Guid/TpmInstance.h>
|
||||
|
||||
/**
|
||||
The entry point for Tcg configuration driver.
|
||||
@ -37,6 +38,11 @@ TcgConfigDriverEntryPoint (
|
||||
TCG_CONFIG_PRIVATE_DATA *PrivateData;
|
||||
EFI_TCG_PROTOCOL *TcgProtocol;
|
||||
|
||||
if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
|
||||
DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = TisPcRequestUseTpm ((TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "TPM not detected!\n"));
|
||||
|
@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# Component name for Tcg configuration module.
|
||||
#
|
||||
# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2011 - 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
|
||||
@ -56,6 +56,7 @@
|
||||
gEfiPhysicalPresenceGuid
|
||||
gEfiIfrTianoGuid
|
||||
gTcgConfigFormSetGuid
|
||||
gEfiTpmDeviceInstanceTpm12Guid
|
||||
|
||||
[Protocols]
|
||||
gEfiHiiConfigAccessProtocolGuid ## PRODUCES
|
||||
@ -67,6 +68,7 @@
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
|
||||
[Depex]
|
||||
gEfiHiiConfigRoutingProtocolGuid AND
|
||||
|
@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <IndustryStandard/Acpi.h>
|
||||
#include <IndustryStandard/PeImage.h>
|
||||
#include <IndustryStandard/SmBios.h>
|
||||
#include <IndustryStandard/TcpaAcpi.h>
|
||||
|
||||
#include <Guid/GlobalVariable.h>
|
||||
#include <Guid/SmBios.h>
|
||||
@ -31,6 +32,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <Guid/TcgEventHob.h>
|
||||
#include <Guid/EventGroup.h>
|
||||
#include <Guid/EventExitBootServiceFailed.h>
|
||||
#include <Guid/TpmInstance.h>
|
||||
|
||||
#include <Protocol/DevicePath.h>
|
||||
#include <Protocol/TcgService.h>
|
||||
#include <Protocol/AcpiTable.h>
|
||||
@ -53,38 +56,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#define EFI_TCG_LOG_AREA_SIZE 0x10000
|
||||
|
||||
#pragma pack (1)
|
||||
|
||||
typedef struct _EFI_TCG_CLIENT_ACPI_TABLE {
|
||||
EFI_ACPI_DESCRIPTION_HEADER Header;
|
||||
UINT16 PlatformClass;
|
||||
UINT32 Laml;
|
||||
EFI_PHYSICAL_ADDRESS Lasa;
|
||||
} EFI_TCG_CLIENT_ACPI_TABLE;
|
||||
|
||||
typedef struct _EFI_TCG_SERVER_ACPI_TABLE {
|
||||
EFI_ACPI_DESCRIPTION_HEADER Header;
|
||||
UINT16 PlatformClass;
|
||||
UINT16 Reserved0;
|
||||
UINT64 Laml;
|
||||
EFI_PHYSICAL_ADDRESS Lasa;
|
||||
UINT16 SpecRev;
|
||||
UINT8 DeviceFlags;
|
||||
UINT8 InterruptFlags;
|
||||
UINT8 Gpe;
|
||||
UINT8 Reserved1[3];
|
||||
UINT32 GlobalSysInt;
|
||||
EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE BaseAddress;
|
||||
UINT32 Reserved2;
|
||||
EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE ConfigAddress;
|
||||
UINT8 PciSegNum;
|
||||
UINT8 PciBusNum;
|
||||
UINT8 PciDevNum;
|
||||
UINT8 PciFuncNum;
|
||||
} EFI_TCG_SERVER_ACPI_TABLE;
|
||||
|
||||
#pragma pack ()
|
||||
|
||||
#define TCG_DXE_DATA_FROM_THIS(this) \
|
||||
BASE_CR (this, TCG_DXE_DATA, TcgProtocol)
|
||||
|
||||
@ -1344,6 +1315,11 @@ DriverEntry (
|
||||
EFI_EVENT Event;
|
||||
VOID *Registration;
|
||||
|
||||
if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
|
||||
DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
mTcgDxeData.TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
|
||||
Status = TisPcRequestUseTpm (mTcgDxeData.TpmHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -58,6 +58,7 @@
|
||||
gEfiEventReadyToBootGuid
|
||||
gEfiEventExitBootServicesGuid
|
||||
gEventExitBootServicesFailedGuid # ALWAYS_CONSUMED
|
||||
gEfiTpmDeviceInstanceTpm12Guid
|
||||
|
||||
[Protocols]
|
||||
gEfiTcgProtocolGuid ## PRODUCES
|
||||
@ -67,6 +68,7 @@
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
Initialize TPM device and measure FVs before handing off control to DXE.
|
||||
|
||||
Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2005 - 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
|
||||
@ -21,9 +21,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <Ppi/TpmInitialized.h>
|
||||
#include <Ppi/FirmwareVolume.h>
|
||||
#include <Ppi/EndOfPeiPhase.h>
|
||||
#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
|
||||
|
||||
#include <Guid/TcgEventHob.h>
|
||||
#include <Guid/MeasuredFvHob.h>
|
||||
#include <Guid/TpmInstance.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
@ -51,6 +53,8 @@ UINT32 mMeasuredBaseFvIndex = 0;
|
||||
EFI_PLATFORM_FIRMWARE_BLOB mMeasuredChildFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];
|
||||
UINT32 mMeasuredChildFvIndex = 0;
|
||||
|
||||
EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;
|
||||
|
||||
/**
|
||||
Lock physical presence if needed.
|
||||
|
||||
@ -311,6 +315,19 @@ MeasureFvImage (
|
||||
|
||||
TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;
|
||||
|
||||
//
|
||||
// Check if it is in Excluded FV list
|
||||
//
|
||||
if (mMeasurementExcludedFvPpi != NULL) {
|
||||
for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) {
|
||||
if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) {
|
||||
DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase));
|
||||
DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether FV is in the measured FV list.
|
||||
//
|
||||
@ -627,6 +644,14 @@ PeimEntryMP (
|
||||
EFI_STATUS Status;
|
||||
TIS_TPM_HANDLE TpmHandle;
|
||||
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID**)&mMeasurementExcludedFvPpi
|
||||
);
|
||||
// Do not check status, because it is optional
|
||||
|
||||
TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
|
||||
Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -634,8 +659,10 @@ PeimEntryMP (
|
||||
}
|
||||
|
||||
if (IsTpmUsable (PeiServices, TpmHandle)) {
|
||||
if (PcdGet8 (PcdTpmScrtmPolicy) == 1) {
|
||||
Status = MeasureCRTMVersion (PeiServices, TpmHandle);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
Status = MeasureMainBios (PeiServices, TpmHandle);
|
||||
}
|
||||
@ -673,6 +700,11 @@ PeimEntryMA (
|
||||
EFI_BOOT_MODE BootMode;
|
||||
TIS_TPM_HANDLE TpmHandle;
|
||||
|
||||
if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
|
||||
DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
@ -703,10 +735,12 @@ PeimEntryMA (
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {
|
||||
Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);
|
||||
if (EFI_ERROR (Status) ) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TpmSelfTest is optional on S3 path, skip it to save S3 time
|
||||
|
@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# This module will initialize TPM device and measure FVs in PEI phase.
|
||||
#
|
||||
# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2006 - 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
|
||||
@ -52,10 +52,12 @@
|
||||
[Guids]
|
||||
gTcgEventEntryHobGuid
|
||||
gMeasuredFvHobGuid
|
||||
gEfiTpmDeviceInstanceTpm12Guid
|
||||
|
||||
[Ppis]
|
||||
gPeiLockPhysicalPresencePpiGuid
|
||||
gEfiPeiFirmwareVolumeInfoPpiGuid
|
||||
gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid
|
||||
gPeiTpmInitializedPpiGuid
|
||||
gEfiEndOfPeiSignalPpiGuid
|
||||
|
||||
@ -65,6 +67,9 @@
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdPhysicalPresenceCmdEnable
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdPhysicalPresenceHwEnable
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString ## CONSUMES
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy
|
||||
|
||||
[FixedPcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
|
||||
@ -72,4 +77,5 @@
|
||||
|
||||
[Depex]
|
||||
gEfiPeiMasterBootModePpiGuid AND
|
||||
gEfiPeiReadOnlyVariable2PpiGuid
|
||||
gEfiPeiReadOnlyVariable2PpiGuid AND
|
||||
gEfiTpmDeviceSelectedGuid
|
||||
|
@ -386,6 +386,11 @@ InitializeTcgSmm (
|
||||
EFI_SMM_SW_REGISTER_CONTEXT SwContext;
|
||||
EFI_HANDLE SwHandle;
|
||||
|
||||
if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
|
||||
DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = PublishAcpiTable ();
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
|
@ -21,6 +21,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include <Guid/PhysicalPresenceData.h>
|
||||
#include <Guid/MemoryOverwriteControl.h>
|
||||
#include <Guid/TpmInstance.h>
|
||||
|
||||
#include <Protocol/SmmSwDispatch2.h>
|
||||
#include <Protocol/AcpiTable.h>
|
||||
|
@ -50,6 +50,7 @@
|
||||
[Guids]
|
||||
gEfiPhysicalPresenceGuid
|
||||
gEfiMemoryOverwriteControlDataGuid
|
||||
gEfiTpmDeviceInstanceTpm12Guid
|
||||
|
||||
[Protocols]
|
||||
gEfiSmmSwDispatch2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
@ -57,6 +58,7 @@
|
||||
gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
|
||||
|
||||
[Depex]
|
||||
|
107
SecurityPkg/Tcg/TrEEConfig/TpmDetection.c
Normal file
107
SecurityPkg/Tcg/TrEEConfig/TpmDetection.c
Normal file
@ -0,0 +1,107 @@
|
||||
/** @file
|
||||
TPM1.2/dTPM2.0 auto detection.
|
||||
|
||||
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/IoLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/Tpm12DeviceLib.h>
|
||||
#include <Library/Tpm12CommandLib.h>
|
||||
#include <IndustryStandard/Tpm12.h>
|
||||
|
||||
#include "TrEEConfigNvData.h"
|
||||
|
||||
/**
|
||||
This routine return if dTPM (1.2 or 2.0) present.
|
||||
|
||||
@retval TRUE dTPM present
|
||||
@retval FALSE dTPM not present
|
||||
**/
|
||||
BOOLEAN
|
||||
IsDtpmPresent (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT8 RegRead;
|
||||
|
||||
RegRead = MmioRead8 ((UINTN)PcdGet64 (PcdTpmBaseAddress));
|
||||
if (RegRead == 0xFF) {
|
||||
DEBUG ((EFI_D_ERROR, "DetectTpmDevice: Dtpm not present\n"));
|
||||
return FALSE;
|
||||
} else {
|
||||
DEBUG ((EFI_D_ERROR, "DetectTpmDevice: Dtpm present\n"));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration.
|
||||
|
||||
@param SetupTpmDevice TpmDevice configuration in setup driver
|
||||
|
||||
@return TpmDevice configuration
|
||||
**/
|
||||
UINT8
|
||||
DetectTpmDevice (
|
||||
IN UINT8 SetupTpmDevice
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_BOOT_MODE BootMode;
|
||||
|
||||
Status = PeiServicesGetBootMode (&BootMode);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// In S3, we rely on Setup option, because we save to Setup in normal boot.
|
||||
//
|
||||
if (BootMode == BOOT_ON_S3_RESUME) {
|
||||
DEBUG ((EFI_D_ERROR, "DetectTpmDevice: S3 mode\n"));
|
||||
return SetupTpmDevice;
|
||||
}
|
||||
|
||||
if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
|
||||
DEBUG ((EFI_D_ERROR, "DetectTpmDevice: Tpm is hide\n"));
|
||||
return TPM_DEVICE_NULL;
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "DetectTpmDevice:\n"));
|
||||
if ((!IsDtpmPresent ()) || (SetupTpmDevice == TPM_DEVICE_NULL)) {
|
||||
// dTPM not available
|
||||
return TPM_DEVICE_NULL;
|
||||
}
|
||||
|
||||
// dTPM available and not disabled by setup
|
||||
// We need check if it is TPM1.2 or TPM2.0
|
||||
// So try TPM1.2 command at first
|
||||
|
||||
Status = Tpm12RequestUseTpm ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
return TPM_DEVICE_2_0_DTPM;
|
||||
}
|
||||
|
||||
Status = Tpm12Startup (TPM_ST_CLEAR);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return TPM_DEVICE_2_0_DTPM;
|
||||
}
|
||||
|
||||
// NO initialization needed again.
|
||||
PcdSet8 (PcdTpmInitializationPolicy, 0);
|
||||
return TPM_DEVICE_1_2;
|
||||
}
|
67
SecurityPkg/Tcg/TrEEConfig/TrEEConfig.vfr
Normal file
67
SecurityPkg/Tcg/TrEEConfig/TrEEConfig.vfr
Normal file
@ -0,0 +1,67 @@
|
||||
/** @file
|
||||
VFR file used by the TREE configuration component.
|
||||
|
||||
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 "TrEEConfigNvData.h"
|
||||
|
||||
formset
|
||||
guid = TREE_CONFIG_FORM_SET_GUID,
|
||||
title = STRING_TOKEN(STR_TREE_TITLE),
|
||||
help = STRING_TOKEN(STR_TREE_HELP),
|
||||
classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
|
||||
|
||||
varstore TREE_CONFIGURATION,
|
||||
varid = TREE_CONFIGURATION_VARSTORE_ID,
|
||||
name = TREE_CONFIGURATION,
|
||||
guid = TREE_CONFIG_FORM_SET_GUID;
|
||||
|
||||
form formid = TREE_CONFIGURATION_FORM_ID,
|
||||
title = STRING_TOKEN(STR_TREE_TITLE);
|
||||
|
||||
subtitle text = STRING_TOKEN(STR_NULL);
|
||||
|
||||
text
|
||||
help = STRING_TOKEN(STR_TREE_DEVICE_STATE_HELP),
|
||||
text = STRING_TOKEN(STR_TREE_DEVICE_STATE_PROMPT),
|
||||
text = STRING_TOKEN(STR_TREE_DEVICE_STATE_CONTENT);
|
||||
|
||||
oneof varid = TREE_CONFIGURATION.TpmDevice,
|
||||
questionid = KEY_TPM_DEVICE,
|
||||
prompt = STRING_TOKEN(STR_TREE_DEVICE_PROMPT),
|
||||
help = STRING_TOKEN(STR_TREE_DEVICE_HELP),
|
||||
flags = INTERACTIVE,
|
||||
option text = STRING_TOKEN(STR_TREE_TPM_DISABLE), value = TPM_DEVICE_NULL, flags = RESET_REQUIRED;
|
||||
option text = STRING_TOKEN(STR_TREE_TPM_1_2), value = TPM_DEVICE_1_2, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
|
||||
option text = STRING_TOKEN(STR_TREE_TPM_2_0_DTPM), value = TPM_DEVICE_2_0_DTPM, flags = RESET_REQUIRED;
|
||||
endoneof;
|
||||
|
||||
subtitle text = STRING_TOKEN(STR_NULL);
|
||||
|
||||
suppressif ideqvallist TREE_CONFIGURATION.TpmDevice == TPM_DEVICE_NULL TPM_DEVICE_1_2;
|
||||
|
||||
subtitle text = STRING_TOKEN(STR_NULL);
|
||||
subtitle text = STRING_TOKEN(STR_TREE_PP_OPERATION);
|
||||
|
||||
oneof varid = TREE_CONFIGURATION.Tpm2Operation,
|
||||
prompt = STRING_TOKEN(STR_TREE_OPERATION),
|
||||
help = STRING_TOKEN(STR_TREE_OPERATION_HELP),
|
||||
flags = INTERACTIVE,
|
||||
option text = STRING_TOKEN(STR_TREE_NO_ACTION), value = TREE_PHYSICAL_PRESENCE_NO_ACTION, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
|
||||
option text = STRING_TOKEN(STR_TREE_CLEAR), value = TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR, flags = RESET_REQUIRED;
|
||||
endoneof;
|
||||
|
||||
endif;
|
||||
|
||||
endform;
|
||||
|
||||
endformset;
|
171
SecurityPkg/Tcg/TrEEConfig/TrEEConfigDriver.c
Normal file
171
SecurityPkg/Tcg/TrEEConfig/TrEEConfigDriver.c
Normal file
@ -0,0 +1,171 @@
|
||||
/** @file
|
||||
The module entry point for TrEE configuration module.
|
||||
|
||||
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 "TrEEConfigImpl.h"
|
||||
|
||||
extern TPM_INSTANCE_ID mTpmInstanceId[TPM_DEVICE_MAX + 1];
|
||||
|
||||
/**
|
||||
The entry point for TrEE configuration driver.
|
||||
|
||||
@param[in] ImageHandle The image handle of the driver.
|
||||
@param[in] SystemTable The system table.
|
||||
|
||||
@retval EFI_ALREADY_STARTED The driver already exists in system.
|
||||
@retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of resources.
|
||||
@retval EFI_SUCCES All the related protocols are installed on the driver.
|
||||
@retval Others Fail to install protocols as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEEConfigDriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TREE_CONFIG_PRIVATE_DATA *PrivateData;
|
||||
TREE_CONFIGURATION TrEEConfiguration;
|
||||
UINTN Index;
|
||||
UINTN DataSize;
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
ImageHandle,
|
||||
&gEfiCallerIdGuid,
|
||||
NULL,
|
||||
ImageHandle,
|
||||
ImageHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a private data structure.
|
||||
//
|
||||
PrivateData = AllocateCopyPool (sizeof (TREE_CONFIG_PRIVATE_DATA), &mTrEEConfigPrivateDateTemplate);
|
||||
ASSERT (PrivateData != NULL);
|
||||
|
||||
//
|
||||
// Install private GUID.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ImageHandle,
|
||||
&gEfiCallerIdGuid,
|
||||
PrivateData,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
DataSize = sizeof(TrEEConfiguration);
|
||||
Status = gRT->GetVariable (
|
||||
TREE_STORAGE_NAME,
|
||||
&gTrEEConfigFormSetGuid,
|
||||
NULL,
|
||||
&DataSize,
|
||||
&TrEEConfiguration
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
}
|
||||
//
|
||||
// We should always reinit PP request.
|
||||
//
|
||||
TrEEConfiguration.Tpm2Operation = TREE_PHYSICAL_PRESENCE_NO_ACTION;
|
||||
|
||||
//
|
||||
// Sync data from PCD to variable, so that we do not need detect again in S3 phase.
|
||||
//
|
||||
|
||||
//
|
||||
// Get data from PCD to make sure data consistant - platform driver is suppose to construct this PCD accroding to Variable
|
||||
//
|
||||
for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
|
||||
if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {
|
||||
TrEEConfiguration.TpmDevice = mTpmInstanceId[Index].TpmDevice;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Save to variable so platform driver can get it.
|
||||
//
|
||||
Status = gRT->SetVariable (
|
||||
TREE_STORAGE_NAME,
|
||||
&gTrEEConfigFormSetGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(TrEEConfiguration),
|
||||
&TrEEConfiguration
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Install TrEE configuration form
|
||||
//
|
||||
Status = InstallTrEEConfigForm (PrivateData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ErrorExit;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ErrorExit:
|
||||
if (PrivateData != NULL) {
|
||||
UninstallTrEEConfigForm (PrivateData);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Unload the TrEE configuration form.
|
||||
|
||||
@param[in] ImageHandle The driver's image handle.
|
||||
|
||||
@retval EFI_SUCCESS The TrEE configuration form is unloaded.
|
||||
@retval Others Failed to unload the form.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEEConfigDriverUnload (
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TREE_CONFIG_PRIVATE_DATA *PrivateData;
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
ImageHandle,
|
||||
&gEfiCallerIdGuid,
|
||||
(VOID **) &PrivateData
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT (PrivateData->Signature == TREE_CONFIG_PRIVATE_DATA_SIGNATURE);
|
||||
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
&ImageHandle,
|
||||
&gEfiCallerIdGuid,
|
||||
PrivateData,
|
||||
NULL
|
||||
);
|
||||
|
||||
UninstallTrEEConfigForm (PrivateData);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
74
SecurityPkg/Tcg/TrEEConfig/TrEEConfigDxe.inf
Normal file
74
SecurityPkg/Tcg/TrEEConfig/TrEEConfigDxe.inf
Normal file
@ -0,0 +1,74 @@
|
||||
## @file
|
||||
# Component name for TrEE configuration module.
|
||||
# NOTE: This module is only for reference only, each platform should have its own setup page.
|
||||
#
|
||||
# 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 = TrEEConfigDxe
|
||||
FILE_GUID = 3141FD4D-EA02-4a70-9BCE-97EE837319AC
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = TrEEConfigDriverEntryPoint
|
||||
UNLOAD_IMAGE = TrEEConfigDriverUnload
|
||||
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources]
|
||||
TrEEConfigDriver.c
|
||||
TrEEConfigImpl.c
|
||||
TrEEConfigImpl.h
|
||||
TrEEConfig.vfr
|
||||
TrEEConfigStrings.uni
|
||||
TrEEConfigNvData.h
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiRuntimeServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
UefiHiiServicesLib
|
||||
DebugLib
|
||||
HiiLib
|
||||
PcdLib
|
||||
PrintLib
|
||||
Tpm2DeviceLib
|
||||
Tpm12DeviceLib
|
||||
Tpm2CommandLib
|
||||
|
||||
[Guids]
|
||||
gEfiTrEEPhysicalPresenceGuid
|
||||
gTrEEConfigFormSetGuid
|
||||
|
||||
[Protocols]
|
||||
gEfiHiiConfigAccessProtocolGuid ## PRODUCES
|
||||
gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
|
||||
[Depex]
|
||||
gEfiTrEEProtocolGuid AND
|
||||
gEfiHiiConfigRoutingProtocolGuid AND
|
||||
gEfiHiiDatabaseProtocolGuid AND
|
||||
gEfiVariableArchProtocolGuid AND
|
||||
gEfiVariableWriteArchProtocolGuid
|
454
SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.c
Normal file
454
SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.c
Normal file
@ -0,0 +1,454 @@
|
||||
/** @file
|
||||
HII Config Access protocol implementation of TREE configuration module.
|
||||
NOTE: This module is only for reference only, each platform should have its own setup page.
|
||||
|
||||
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 "TrEEConfigImpl.h"
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Guid/TpmInstance.h>
|
||||
|
||||
TPM_INSTANCE_ID mTpmInstanceId[TPM_DEVICE_MAX + 1] = TPM_INSTANCE_ID_LIST;
|
||||
|
||||
TREE_CONFIG_PRIVATE_DATA mTrEEConfigPrivateDateTemplate = {
|
||||
TREE_CONFIG_PRIVATE_DATA_SIGNATURE,
|
||||
{
|
||||
TrEEExtractConfig,
|
||||
TrEERouteConfig,
|
||||
TrEECallback
|
||||
}
|
||||
};
|
||||
|
||||
HII_VENDOR_DEVICE_PATH mTrEEHiiVendorDevicePath = {
|
||||
{
|
||||
{
|
||||
HARDWARE_DEVICE_PATH,
|
||||
HW_VENDOR_DP,
|
||||
{
|
||||
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
|
||||
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
|
||||
}
|
||||
},
|
||||
TREE_CONFIG_FORM_SET_GUID
|
||||
},
|
||||
{
|
||||
END_DEVICE_PATH_TYPE,
|
||||
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
||||
{
|
||||
(UINT8) (END_DEVICE_PATH_LENGTH),
|
||||
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
This function allows a caller to extract the current configuration for one
|
||||
or more named elements from the target driver.
|
||||
|
||||
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
||||
@param[in] Request A null-terminated Unicode string in
|
||||
<ConfigRequest> format.
|
||||
@param[out] Progress On return, points to a character in the Request
|
||||
string. Points to the string's null terminator if
|
||||
request was successful. Points to the most recent
|
||||
'&' before the first failing name/value pair (or
|
||||
the beginning of the string if the failure is in
|
||||
the first name/value pair) if the request was not
|
||||
successful.
|
||||
@param[out] Results A null-terminated Unicode string in
|
||||
<ConfigAltResp> format which has all values filled
|
||||
in for the names in the Request string. String to
|
||||
be allocated by the called function.
|
||||
|
||||
@retval EFI_SUCCESS The Results is filled with the requested values.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
|
||||
@retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
|
||||
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
|
||||
driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEEExtractConfig (
|
||||
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
||||
IN CONST EFI_STRING Request,
|
||||
OUT EFI_STRING *Progress,
|
||||
OUT EFI_STRING *Results
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
TREE_CONFIGURATION Configuration;
|
||||
TREE_CONFIG_PRIVATE_DATA *PrivateData;
|
||||
EFI_STRING ConfigRequestHdr;
|
||||
EFI_STRING ConfigRequest;
|
||||
BOOLEAN AllocatedRequest;
|
||||
UINTN Size;
|
||||
UINTN Index;
|
||||
|
||||
if (Progress == NULL || Results == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*Progress = Request;
|
||||
if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTrEEConfigFormSetGuid, TREE_STORAGE_NAME)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
ConfigRequestHdr = NULL;
|
||||
ConfigRequest = NULL;
|
||||
AllocatedRequest = FALSE;
|
||||
Size = 0;
|
||||
|
||||
PrivateData = TREE_CONFIG_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Convert buffer data to <ConfigResp> by helper function BlockToConfig()
|
||||
//
|
||||
BufferSize = sizeof (Configuration);
|
||||
Status = gRT->GetVariable (
|
||||
TREE_STORAGE_NAME,
|
||||
&gTrEEConfigFormSetGuid,
|
||||
NULL,
|
||||
&BufferSize,
|
||||
&Configuration
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Get data from PCD to make sure data consistant - platform driver is suppose to construct this PCD accroding to Variable
|
||||
//
|
||||
for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
|
||||
if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {
|
||||
Configuration.TpmDevice = mTpmInstanceId[Index].TpmDevice;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BufferSize = sizeof (Configuration);
|
||||
ConfigRequest = Request;
|
||||
if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
|
||||
//
|
||||
// Request has no request element, construct full request string.
|
||||
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template
|
||||
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
|
||||
//
|
||||
ConfigRequestHdr = HiiConstructConfigHdr (&gTrEEConfigFormSetGuid, TREE_STORAGE_NAME, PrivateData->DriverHandle);
|
||||
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
|
||||
ConfigRequest = AllocateZeroPool (Size);
|
||||
ASSERT (ConfigRequest != NULL);
|
||||
AllocatedRequest = TRUE;
|
||||
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64) BufferSize);
|
||||
FreePool (ConfigRequestHdr);
|
||||
}
|
||||
|
||||
Status = gHiiConfigRouting->BlockToConfig (
|
||||
gHiiConfigRouting,
|
||||
ConfigRequest,
|
||||
(UINT8 *) &Configuration,
|
||||
BufferSize,
|
||||
Results,
|
||||
Progress
|
||||
);
|
||||
//
|
||||
// Free the allocated config request string.
|
||||
//
|
||||
if (AllocatedRequest) {
|
||||
FreePool (ConfigRequest);
|
||||
}
|
||||
//
|
||||
// Set Progress string to the original request string.
|
||||
//
|
||||
if (Request == NULL) {
|
||||
*Progress = NULL;
|
||||
} else if (StrStr (Request, L"OFFSET") == NULL) {
|
||||
*Progress = Request + StrLen (Request);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Save TPM request to variable space.
|
||||
|
||||
@param[in] PpRequest Physical Presence request command.
|
||||
|
||||
@retval EFI_SUCCESS The operation is finished successfully.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SaveTrEEPpRequest (
|
||||
IN UINT8 PpRequest
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN DataSize;
|
||||
EFI_TREE_PHYSICAL_PRESENCE PpData;
|
||||
|
||||
//
|
||||
// Save TPM command to variable.
|
||||
//
|
||||
DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
|
||||
Status = gRT->GetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
NULL,
|
||||
&DataSize,
|
||||
&PpData
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
PpData.PPRequest = PpRequest;
|
||||
Status = gRT->SetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
DataSize,
|
||||
&PpData
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function processes the results of changes in configuration.
|
||||
|
||||
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
||||
@param[in] Configuration A null-terminated Unicode string in <ConfigResp>
|
||||
format.
|
||||
@param[out] Progress A pointer to a string filled in with the offset of
|
||||
the most recent '&' before the first failing
|
||||
name/value pair (or the beginning of the string if
|
||||
the failure is in the first name/value pair) or
|
||||
the terminating NULL if all was successful.
|
||||
|
||||
@retval EFI_SUCCESS The Results is processed successfully.
|
||||
@retval EFI_INVALID_PARAMETER Configuration is NULL.
|
||||
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
|
||||
driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEERouteConfig (
|
||||
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
||||
IN CONST EFI_STRING Configuration,
|
||||
OUT EFI_STRING *Progress
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
TREE_CONFIGURATION TrEEConfiguration;
|
||||
|
||||
if (Configuration == NULL || Progress == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*Progress = Configuration;
|
||||
if (!HiiIsConfigHdrMatch (Configuration, &gTrEEConfigFormSetGuid, TREE_STORAGE_NAME)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
BufferSize = sizeof (TrEEConfiguration);
|
||||
Status = gRT->GetVariable (
|
||||
TREE_STORAGE_NAME,
|
||||
&gTrEEConfigFormSetGuid,
|
||||
NULL,
|
||||
&BufferSize,
|
||||
&TrEEConfiguration
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
|
||||
//
|
||||
BufferSize = sizeof (TREE_CONFIGURATION);
|
||||
Status = gHiiConfigRouting->ConfigToBlock (
|
||||
gHiiConfigRouting,
|
||||
Configuration,
|
||||
(UINT8 *) &TrEEConfiguration,
|
||||
&BufferSize,
|
||||
Progress
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Save to variable so platform driver can get it.
|
||||
//
|
||||
Status = gRT->SetVariable (
|
||||
TREE_STORAGE_NAME,
|
||||
&gTrEEConfigFormSetGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(TrEEConfiguration),
|
||||
&TrEEConfiguration
|
||||
);
|
||||
|
||||
SaveTrEEPpRequest (TrEEConfiguration.Tpm2Operation
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function processes the results of changes in configuration.
|
||||
|
||||
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
||||
@param[in] Action Specifies the type of action taken by the browser.
|
||||
@param[in] QuestionId A unique value which is sent to the original
|
||||
exporting driver so that it can identify the type
|
||||
of data to expect.
|
||||
@param[in] Type The type of value for the question.
|
||||
@param[in] Value A pointer to the data being sent to the original
|
||||
exporting driver.
|
||||
@param[out] ActionRequest On return, points to the action requested by the
|
||||
callback function.
|
||||
|
||||
@retval EFI_SUCCESS The callback successfully handled the action.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
|
||||
variable and its data.
|
||||
@retval EFI_DEVICE_ERROR The variable could not be saved.
|
||||
@retval EFI_UNSUPPORTED The specified Action is not supported by the
|
||||
callback.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEECallback (
|
||||
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
||||
IN EFI_BROWSER_ACTION Action,
|
||||
IN EFI_QUESTION_ID QuestionId,
|
||||
IN UINT8 Type,
|
||||
IN EFI_IFR_TYPE_VALUE *Value,
|
||||
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
|
||||
)
|
||||
{
|
||||
if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Action != EFI_BROWSER_ACTION_CHANGED) ||
|
||||
(QuestionId != KEY_TPM_DEVICE)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function publish the TREE configuration Form for TPM device.
|
||||
|
||||
@param[in, out] PrivateData Points to TREE configuration private data.
|
||||
|
||||
@retval EFI_SUCCESS HII Form is installed for this network device.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
InstallTrEEConfigForm (
|
||||
IN OUT TREE_CONFIG_PRIVATE_DATA *PrivateData
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HII_HANDLE HiiHandle;
|
||||
EFI_HANDLE DriverHandle;
|
||||
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
|
||||
|
||||
DriverHandle = NULL;
|
||||
ConfigAccess = &PrivateData->ConfigAccess;
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&DriverHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
&mTrEEHiiVendorDevicePath,
|
||||
&gEfiHiiConfigAccessProtocolGuid,
|
||||
ConfigAccess,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
PrivateData->DriverHandle = DriverHandle;
|
||||
|
||||
//
|
||||
// Publish the HII package list
|
||||
//
|
||||
HiiHandle = HiiAddPackages (
|
||||
&gTrEEConfigFormSetGuid,
|
||||
DriverHandle,
|
||||
TrEEConfigDxeStrings,
|
||||
TrEEConfigBin,
|
||||
NULL
|
||||
);
|
||||
if (HiiHandle == NULL) {
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
DriverHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
&mTrEEHiiVendorDevicePath,
|
||||
&gEfiHiiConfigAccessProtocolGuid,
|
||||
ConfigAccess,
|
||||
NULL
|
||||
);
|
||||
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
PrivateData->HiiHandle = HiiHandle;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function removes TREE configuration Form.
|
||||
|
||||
@param[in, out] PrivateData Points to TREE configuration private data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
UninstallTrEEConfigForm (
|
||||
IN OUT TREE_CONFIG_PRIVATE_DATA *PrivateData
|
||||
)
|
||||
{
|
||||
//
|
||||
// Uninstall HII package list
|
||||
//
|
||||
if (PrivateData->HiiHandle != NULL) {
|
||||
HiiRemovePackages (PrivateData->HiiHandle);
|
||||
PrivateData->HiiHandle = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Uninstall HII Config Access Protocol
|
||||
//
|
||||
if (PrivateData->DriverHandle != NULL) {
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
PrivateData->DriverHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
&mTrEEHiiVendorDevicePath,
|
||||
&gEfiHiiConfigAccessProtocolGuid,
|
||||
&PrivateData->ConfigAccess,
|
||||
NULL
|
||||
);
|
||||
PrivateData->DriverHandle = NULL;
|
||||
}
|
||||
|
||||
FreePool (PrivateData);
|
||||
}
|
191
SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.h
Normal file
191
SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.h
Normal file
@ -0,0 +1,191 @@
|
||||
/** @file
|
||||
The header file of HII Config Access protocol implementation of TREE
|
||||
configuration module.
|
||||
|
||||
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 __TREE_CONFIG_IMPL_H__
|
||||
#define __TREE_CONFIG_IMPL_H__
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Protocol/HiiConfigAccess.h>
|
||||
#include <Protocol/HiiConfigRouting.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiHiiServicesLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/HiiLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
|
||||
#include <Guid/MdeModuleHii.h>
|
||||
|
||||
#include "TrEEConfigNvData.h"
|
||||
|
||||
//
|
||||
// Tool generated IFR binary data and String package data
|
||||
//
|
||||
extern UINT8 TrEEConfigBin[];
|
||||
extern UINT8 TrEEConfigDxeStrings[];
|
||||
|
||||
///
|
||||
/// HII specific Vendor Device Path definition.
|
||||
///
|
||||
typedef struct {
|
||||
VENDOR_DEVICE_PATH VendorDevicePath;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} HII_VENDOR_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
|
||||
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
|
||||
EFI_HII_HANDLE HiiHandle;
|
||||
EFI_HANDLE DriverHandle;
|
||||
|
||||
} TREE_CONFIG_PRIVATE_DATA;
|
||||
|
||||
extern TREE_CONFIG_PRIVATE_DATA mTrEEConfigPrivateDateTemplate;
|
||||
|
||||
#define TREE_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('T', 'r', 'E', 'D')
|
||||
#define TREE_CONFIG_PRIVATE_DATA_FROM_THIS(a) CR (a, TREE_CONFIG_PRIVATE_DATA, ConfigAccess, TREE_CONFIG_PRIVATE_DATA_SIGNATURE)
|
||||
|
||||
|
||||
/**
|
||||
This function publish the TREE configuration Form for TPM device.
|
||||
|
||||
@param[in, out] PrivateData Points to TREE configuration private data.
|
||||
|
||||
@retval EFI_SUCCESS HII Form is installed for this network device.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
InstallTrEEConfigForm (
|
||||
IN OUT TREE_CONFIG_PRIVATE_DATA *PrivateData
|
||||
);
|
||||
|
||||
/**
|
||||
This function removes TREE configuration Form.
|
||||
|
||||
@param[in, out] PrivateData Points to TREE configuration private data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
UninstallTrEEConfigForm (
|
||||
IN OUT TREE_CONFIG_PRIVATE_DATA *PrivateData
|
||||
);
|
||||
|
||||
/**
|
||||
This function allows a caller to extract the current configuration for one
|
||||
or more named elements from the target driver.
|
||||
|
||||
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
||||
@param[in] Request A null-terminated Unicode string in
|
||||
<ConfigRequest> format.
|
||||
@param[out] Progress On return, points to a character in the Request
|
||||
string. Points to the string's null terminator if
|
||||
request was successful. Points to the most recent
|
||||
'&' before the first failing name/value pair (or
|
||||
the beginning of the string if the failure is in
|
||||
the first name/value pair) if the request was not
|
||||
successful.
|
||||
@param[out] Results A null-terminated Unicode string in
|
||||
<ConfigAltResp> format which has all values filled
|
||||
in for the names in the Request string. String to
|
||||
be allocated by the called function.
|
||||
|
||||
@retval EFI_SUCCESS The Results is filled with the requested values.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
|
||||
@retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
|
||||
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
|
||||
driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEEExtractConfig (
|
||||
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
||||
IN CONST EFI_STRING Request,
|
||||
OUT EFI_STRING *Progress,
|
||||
OUT EFI_STRING *Results
|
||||
);
|
||||
|
||||
/**
|
||||
This function processes the results of changes in configuration.
|
||||
|
||||
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
||||
@param[in] Configuration A null-terminated Unicode string in <ConfigResp>
|
||||
format.
|
||||
@param[out] Progress A pointer to a string filled in with the offset of
|
||||
the most recent '&' before the first failing
|
||||
name/value pair (or the beginning of the string if
|
||||
the failure is in the first name/value pair) or
|
||||
the terminating NULL if all was successful.
|
||||
|
||||
@retval EFI_SUCCESS The Results is processed successfully.
|
||||
@retval EFI_INVALID_PARAMETER Configuration is NULL.
|
||||
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
|
||||
driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEERouteConfig (
|
||||
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
||||
IN CONST EFI_STRING Configuration,
|
||||
OUT EFI_STRING *Progress
|
||||
);
|
||||
|
||||
/**
|
||||
This function processes the results of changes in configuration.
|
||||
|
||||
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
||||
@param[in] Action Specifies the type of action taken by the browser.
|
||||
@param[in] QuestionId A unique value which is sent to the original
|
||||
exporting driver so that it can identify the type
|
||||
of data to expect.
|
||||
@param[in] Type The type of value for the question.
|
||||
@param[in] Value A pointer to the data being sent to the original
|
||||
exporting driver.
|
||||
@param[out] ActionRequest On return, points to the action requested by the
|
||||
callback function.
|
||||
|
||||
@retval EFI_SUCCESS The callback successfully handled the action.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
|
||||
variable and its data.
|
||||
@retval EFI_DEVICE_ERROR The variable could not be saved.
|
||||
@retval EFI_UNSUPPORTED The specified Action is not supported by the
|
||||
callback.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEECallback (
|
||||
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
||||
IN EFI_BROWSER_ACTION Action,
|
||||
IN EFI_QUESTION_ID QuestionId,
|
||||
IN UINT8 Type,
|
||||
IN EFI_IFR_TYPE_VALUE *Value,
|
||||
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
|
||||
);
|
||||
|
||||
#endif
|
66
SecurityPkg/Tcg/TrEEConfig/TrEEConfigNvData.h
Normal file
66
SecurityPkg/Tcg/TrEEConfig/TrEEConfigNvData.h
Normal file
@ -0,0 +1,66 @@
|
||||
/** @file
|
||||
Header file for NV data structure 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 __TREE_CONFIG_NV_DATA_H__
|
||||
#define __TREE_CONFIG_NV_DATA_H__
|
||||
|
||||
#include <Guid/HiiPlatformSetupFormset.h>
|
||||
#include <Guid/TrEEPhysicalPresenceData.h>
|
||||
#include <Guid/TrEEConfigHii.h>
|
||||
|
||||
#define TREE_CONFIGURATION_VARSTORE_ID 0x0001
|
||||
#define TREE_CONFIGURATION_FORM_ID 0x0001
|
||||
|
||||
#define KEY_TPM_DEVICE 0x2000
|
||||
|
||||
#define TPM_DEVICE_NULL 0
|
||||
#define TPM_DEVICE_1_2 1
|
||||
#define TPM_DEVICE_2_0_DTPM 2
|
||||
#define TPM_DEVICE_MAX TPM_DEVICE_2_0_DTPM
|
||||
#define TPM_DEVICE_DEFAULT TPM_DEVICE_1_2
|
||||
|
||||
//
|
||||
// Nv Data structure referenced by IFR
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 TpmDevice;
|
||||
UINT8 Tpm2Operation;
|
||||
} TREE_CONFIGURATION;
|
||||
|
||||
#define TREE_STORAGE_NAME L"TREE_CONFIGURATION"
|
||||
|
||||
#define TPM_INSTANCE_ID_LIST { \
|
||||
{TPM_DEVICE_INTERFACE_NONE, TPM_DEVICE_NULL}, \
|
||||
{TPM_DEVICE_INTERFACE_TPM12, TPM_DEVICE_1_2}, \
|
||||
{TPM_DEVICE_INTERFACE_TPM20_DTPM, TPM_DEVICE_2_0_DTPM}, \
|
||||
}
|
||||
|
||||
//
|
||||
// BUGBUG: In order to pass VfrCompiler, we have to redefine GUID here.
|
||||
//
|
||||
#ifndef __BASE_H__
|
||||
typedef struct {
|
||||
UINT32 Data1;
|
||||
UINT16 Data2;
|
||||
UINT16 Data3;
|
||||
UINT8 Data4[8];
|
||||
} GUID;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
GUID TpmInstanceGuid;
|
||||
UINT8 TpmDevice;
|
||||
} TPM_INSTANCE_ID;
|
||||
|
||||
#endif
|
70
SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf
Normal file
70
SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf
Normal file
@ -0,0 +1,70 @@
|
||||
## @file
|
||||
# Component name for TrEE configuration module.
|
||||
# NOTE: This module is only for reference only, each platform should have its own setup page.
|
||||
#
|
||||
# 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 = TrEEConfigPei
|
||||
FILE_GUID = A5C1EF72-9379-4370-B4C7-0F5126CAC38E
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = TrEEConfigPeimEntryPoint
|
||||
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources]
|
||||
TrEEConfigPeim.c
|
||||
TrEEConfigNvData.h
|
||||
TpmDetection.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
PeiServicesLib
|
||||
PeimEntryPoint
|
||||
DebugLib
|
||||
PcdLib
|
||||
TimerLib
|
||||
IoLib
|
||||
Tpm12CommandLib
|
||||
Tpm12DeviceLib
|
||||
|
||||
[Guids]
|
||||
gEfiTrEEPhysicalPresenceGuid
|
||||
gTrEEConfigFormSetGuid
|
||||
gEfiTpmDeviceSelectedGuid
|
||||
|
||||
[Ppis]
|
||||
gEfiPeiReadOnlyVariable2PpiGuid
|
||||
|
||||
[FixedPcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmAutoDetection
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
|
||||
|
||||
[Depex]
|
||||
gEfiPeiMasterBootModePpiGuid AND
|
||||
gEfiPeiReadOnlyVariable2PpiGuid
|
133
SecurityPkg/Tcg/TrEEConfig/TrEEConfigPeim.c
Normal file
133
SecurityPkg/Tcg/TrEEConfig/TrEEConfigPeim.c
Normal file
@ -0,0 +1,133 @@
|
||||
/** @file
|
||||
The module entry point for TrEE configuration module.
|
||||
|
||||
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 <Guid/TpmInstance.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
#include <Ppi/ReadOnlyVariable2.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
|
||||
#include "TrEEConfigNvData.h"
|
||||
|
||||
TPM_INSTANCE_ID mTpmInstanceId[] = TPM_INSTANCE_ID_LIST;
|
||||
|
||||
CONST EFI_PEI_PPI_DESCRIPTOR gTpmSelectedPpi = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiTpmDeviceSelectedGuid,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration.
|
||||
|
||||
@param SetupTpmDevice TpmDevice configuration in setup driver
|
||||
|
||||
@return TpmDevice configuration
|
||||
**/
|
||||
UINT8
|
||||
DetectTpmDevice (
|
||||
IN UINT8 SetupTpmDevice
|
||||
);
|
||||
|
||||
/**
|
||||
The entry point for TrEE configuration driver.
|
||||
|
||||
@param FileHandle Handle of the file being invoked.
|
||||
@param PeiServices Describes the list of possible PEI Services.
|
||||
|
||||
@retval EFI_SUCCES Convert variable to PCD successfully.
|
||||
@retval Others Fail to convert variable to PCD.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TrEEConfigPeimEntryPoint (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
UINTN Size;
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
|
||||
TREE_CONFIGURATION TrEEConfiguration;
|
||||
UINTN Index;
|
||||
UINT8 TpmDevice;
|
||||
|
||||
Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Size = sizeof(TrEEConfiguration);
|
||||
Status = VariablePpi->GetVariable (
|
||||
VariablePpi,
|
||||
TREE_STORAGE_NAME,
|
||||
&gTrEEConfigFormSetGuid,
|
||||
NULL,
|
||||
&Size,
|
||||
&TrEEConfiguration
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Variable not ready, set default value
|
||||
//
|
||||
TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;
|
||||
}
|
||||
|
||||
//
|
||||
// Validation
|
||||
//
|
||||
if (TrEEConfiguration.TpmDevice > TPM_DEVICE_MAX) {
|
||||
TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;
|
||||
}
|
||||
|
||||
//
|
||||
// Although we have SetupVariable info, we still need detect TPM device manually.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "TrEEConfiguration.TpmDevice from Setup: %x\n", TrEEConfiguration.TpmDevice));
|
||||
|
||||
if (PcdGetBool (PcdTpmAutoDetection)) {
|
||||
TpmDevice = DetectTpmDevice (TrEEConfiguration.TpmDevice);
|
||||
DEBUG ((EFI_D_ERROR, "TrEEConfiguration.TpmDevice final: %x\n", TpmDevice));
|
||||
TrEEConfiguration.TpmDevice = TpmDevice;
|
||||
}
|
||||
|
||||
//
|
||||
// Convert variable to PCD.
|
||||
// This is work-around because there is no gurantee DynamicHiiPcd can return correct value in DXE phase.
|
||||
// Using DynamicPcd instead.
|
||||
//
|
||||
for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
|
||||
if (TrEEConfiguration.TpmDevice == mTpmInstanceId[Index].TpmDevice) {
|
||||
Size = sizeof(mTpmInstanceId[Index].TpmInstanceGuid);
|
||||
PcdSetPtr (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[Index].TpmInstanceGuid);
|
||||
DEBUG ((EFI_D_ERROR, "TrEEConfiguration.TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Selection done
|
||||
//
|
||||
Status = PeiServicesInstallPpi (&gTpmSelectedPpi);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
BIN
SecurityPkg/Tcg/TrEEConfig/TrEEConfigStrings.uni
Normal file
BIN
SecurityPkg/Tcg/TrEEConfig/TrEEConfigStrings.uni
Normal file
Binary file not shown.
357
SecurityPkg/Tcg/TrEEDxe/MeasureBootPeCoff.c
Normal file
357
SecurityPkg/Tcg/TrEEDxe/MeasureBootPeCoff.c
Normal file
@ -0,0 +1,357 @@
|
||||
/** @file
|
||||
This module implements measuring PeCoff image for TrEE Protocol.
|
||||
|
||||
Caution: This file requires additional review when modified.
|
||||
This driver will have external input - PE/COFF image.
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#include <PiDxe.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/PeCoffLib.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/HashLib.h>
|
||||
|
||||
/**
|
||||
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] PCRIndex TPM PCR index
|
||||
@param[in] ImageAddress Start address of image buffer.
|
||||
@param[in] ImageSize Image size
|
||||
@param[out] DigestList Digeest list of this image.
|
||||
|
||||
@retval EFI_SUCCESS Successfully measure image.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
|
||||
@retval other error value
|
||||
**/
|
||||
EFI_STATUS
|
||||
MeasurePeImageAndExtend (
|
||||
IN UINT32 PCRIndex,
|
||||
IN EFI_PHYSICAL_ADDRESS ImageAddress,
|
||||
IN UINTN ImageSize,
|
||||
OUT TPML_DIGEST_VALUES *DigestList
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_IMAGE_DOS_HEADER *DosHdr;
|
||||
UINT32 PeCoffHeaderOffset;
|
||||
EFI_IMAGE_SECTION_HEADER *Section;
|
||||
UINT8 *HashBase;
|
||||
UINTN HashSize;
|
||||
UINTN SumOfBytesHashed;
|
||||
EFI_IMAGE_SECTION_HEADER *SectionHeader;
|
||||
UINTN Index;
|
||||
UINTN Pos;
|
||||
UINT16 Magic;
|
||||
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
|
||||
UINT32 NumberOfRvaAndSizes;
|
||||
UINT32 CertSize;
|
||||
HASH_HANDLE HashHandle;
|
||||
|
||||
HashHandle = 0xFFFFFFFF; // Know bad value
|
||||
|
||||
Status = EFI_UNSUPPORTED;
|
||||
SectionHeader = NULL;
|
||||
|
||||
//
|
||||
// Check PE/COFF image
|
||||
//
|
||||
DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress;
|
||||
PeCoffHeaderOffset = 0;
|
||||
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
|
||||
PeCoffHeaderOffset = DosHdr->e_lfanew;
|
||||
}
|
||||
|
||||
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset);
|
||||
if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
//
|
||||
// PE/COFF Image Measurement
|
||||
//
|
||||
// NOTE: The following codes/steps are based upon the authenticode image hashing in
|
||||
// PE/COFF Specification 8.0 Appendix A.
|
||||
//
|
||||
//
|
||||
|
||||
// 1. Load the image header into memory.
|
||||
|
||||
// 2. Initialize a SHA hash context.
|
||||
|
||||
Status = HashStart (&HashHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
//
|
||||
// Measuring PE/COFF Image Header;
|
||||
// But CheckSum field and SECURITY data directory (certificate) are excluded
|
||||
//
|
||||
if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
//
|
||||
// NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
|
||||
// in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
|
||||
// Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
|
||||
// then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
|
||||
//
|
||||
Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
||||
} else {
|
||||
//
|
||||
// Get the magic value from the PE/COFF Optional Header
|
||||
//
|
||||
Magic = Hdr.Pe32->OptionalHeader.Magic;
|
||||
}
|
||||
|
||||
//
|
||||
// 3. Calculate the distance from the base of the image header to the image checksum address.
|
||||
// 4. Hash the image header from its base to beginning of the image checksum.
|
||||
//
|
||||
HashBase = (UINT8 *) (UINTN) ImageAddress;
|
||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
//
|
||||
// Use PE32 offset
|
||||
//
|
||||
NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
|
||||
HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.CheckSum) - HashBase);
|
||||
} else {
|
||||
//
|
||||
// Use PE32+ offset
|
||||
//
|
||||
NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
|
||||
HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - HashBase);
|
||||
}
|
||||
|
||||
Status = HashUpdate (HashHandle, HashBase, HashSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
//
|
||||
// 5. Skip over the image checksum (it occupies a single ULONG).
|
||||
//
|
||||
if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
|
||||
//
|
||||
// 6. Since there is no Cert Directory in optional header, hash everything
|
||||
// from the end of the checksum to the end of image header.
|
||||
//
|
||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
//
|
||||
// Use PE32 offset.
|
||||
//
|
||||
HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
|
||||
HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);
|
||||
} else {
|
||||
//
|
||||
// Use PE32+ offset.
|
||||
//
|
||||
HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
|
||||
HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);
|
||||
}
|
||||
|
||||
if (HashSize != 0) {
|
||||
Status = HashUpdate (HashHandle, HashBase, HashSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Finish;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// 7. Hash everything from the end of the checksum to the start of the Cert Directory.
|
||||
//
|
||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
//
|
||||
// Use PE32 offset
|
||||
//
|
||||
HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
|
||||
HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
|
||||
} else {
|
||||
//
|
||||
// Use PE32+ offset
|
||||
//
|
||||
HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
|
||||
HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
|
||||
}
|
||||
|
||||
if (HashSize != 0) {
|
||||
Status = HashUpdate (HashHandle, HashBase, HashSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Finish;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
|
||||
// 9. Hash everything from the end of the Cert Directory to the end of image header.
|
||||
//
|
||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
//
|
||||
// Use PE32 offset
|
||||
//
|
||||
HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
|
||||
HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);
|
||||
} else {
|
||||
//
|
||||
// Use PE32+ offset
|
||||
//
|
||||
HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
|
||||
HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);
|
||||
}
|
||||
|
||||
if (HashSize != 0) {
|
||||
Status = HashUpdate (HashHandle, HashBase, HashSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 10. Set the SUM_OF_BYTES_HASHED to the size of the header
|
||||
//
|
||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
//
|
||||
// Use PE32 offset
|
||||
//
|
||||
SumOfBytesHashed = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
|
||||
} else {
|
||||
//
|
||||
// Use PE32+ offset
|
||||
//
|
||||
SumOfBytesHashed = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;
|
||||
}
|
||||
|
||||
//
|
||||
// 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
|
||||
// structures in the image. The 'NumberOfSections' field of the image
|
||||
// header indicates how big the table should be. Do not include any
|
||||
// IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
|
||||
//
|
||||
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections);
|
||||
if (SectionHeader == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
//
|
||||
// 12. Using the 'PointerToRawData' in the referenced section headers as
|
||||
// a key, arrange the elements in the table in ascending order. In other
|
||||
// words, sort the section headers according to the disk-file offset of
|
||||
// the section.
|
||||
//
|
||||
Section = (EFI_IMAGE_SECTION_HEADER *) (
|
||||
(UINT8 *) (UINTN) ImageAddress +
|
||||
PeCoffHeaderOffset +
|
||||
sizeof(UINT32) +
|
||||
sizeof(EFI_IMAGE_FILE_HEADER) +
|
||||
Hdr.Pe32->FileHeader.SizeOfOptionalHeader
|
||||
);
|
||||
for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
|
||||
Pos = Index;
|
||||
while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {
|
||||
CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof(EFI_IMAGE_SECTION_HEADER));
|
||||
Pos--;
|
||||
}
|
||||
CopyMem (&SectionHeader[Pos], Section, sizeof(EFI_IMAGE_SECTION_HEADER));
|
||||
Section += 1;
|
||||
}
|
||||
|
||||
//
|
||||
// 13. Walk through the sorted table, bring the corresponding section
|
||||
// into memory, and hash the entire section (using the 'SizeOfRawData'
|
||||
// field in the section header to determine the amount of data to hash).
|
||||
// 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
|
||||
// 15. Repeat steps 13 and 14 for all the sections in the sorted table.
|
||||
//
|
||||
for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
|
||||
Section = (EFI_IMAGE_SECTION_HEADER *) &SectionHeader[Index];
|
||||
if (Section->SizeOfRawData == 0) {
|
||||
continue;
|
||||
}
|
||||
HashBase = (UINT8 *) (UINTN) ImageAddress + Section->PointerToRawData;
|
||||
HashSize = (UINTN) Section->SizeOfRawData;
|
||||
|
||||
Status = HashUpdate (HashHandle, HashBase, HashSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
SumOfBytesHashed += HashSize;
|
||||
}
|
||||
|
||||
//
|
||||
// 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
|
||||
// data in the file that needs to be added to the hash. This data begins
|
||||
// at file offset SUM_OF_BYTES_HASHED and its length is:
|
||||
// FileSize - (CertDirectory->Size)
|
||||
//
|
||||
if (ImageSize > SumOfBytesHashed) {
|
||||
HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed;
|
||||
|
||||
if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
|
||||
CertSize = 0;
|
||||
} else {
|
||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
//
|
||||
// Use PE32 offset.
|
||||
//
|
||||
CertSize = Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
|
||||
} else {
|
||||
//
|
||||
// Use PE32+ offset.
|
||||
//
|
||||
CertSize = Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImageSize > CertSize + SumOfBytesHashed) {
|
||||
HashSize = (UINTN) (ImageSize - CertSize - SumOfBytesHashed);
|
||||
|
||||
Status = HashUpdate (HashHandle, HashBase, HashSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Finish;
|
||||
}
|
||||
} else if (ImageSize < CertSize + SumOfBytesHashed) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto Finish;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 17. Finalize the SHA hash.
|
||||
//
|
||||
Status = HashCompleteAndExtend (HashHandle, PCRIndex, NULL, 0, DigestList);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
Finish:
|
||||
if (SectionHeader != NULL) {
|
||||
FreePool (SectionHeader);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
1977
SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c
Normal file
1977
SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c
Normal file
File diff suppressed because it is too large
Load Diff
91
SecurityPkg/Tcg/TrEEDxe/TrEEDxe.inf
Normal file
91
SecurityPkg/Tcg/TrEEDxe/TrEEDxe.inf
Normal file
@ -0,0 +1,91 @@
|
||||
## @file
|
||||
# Component file for module TrEEDxe.
|
||||
# This module will produce TrEE protocol and measure boot environment.
|
||||
#
|
||||
# Caution: This module requires additional review when modified.
|
||||
# This driver will have external input - PE/COFF image.
|
||||
# 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 = TrEEDxe
|
||||
FILE_GUID = 2A7946E3-1AB2-49a9-ACCB-C6275139C1A5
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = DriverEntry
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF
|
||||
#
|
||||
|
||||
[Sources]
|
||||
TrEEDxe.c
|
||||
MeasureBootPeCoff.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
MemoryAllocationLib
|
||||
BaseLib
|
||||
UefiBootServicesTableLib
|
||||
HobLib
|
||||
UefiDriverEntryPoint
|
||||
UefiRuntimeServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
Tpm2CommandLib
|
||||
PrintLib
|
||||
UefiLib
|
||||
Tpm2DeviceLib
|
||||
HashLib
|
||||
PerformanceLib
|
||||
|
||||
[Guids]
|
||||
gEfiSmbiosTableGuid # ALWAYS_CONSUMED
|
||||
gEfiGlobalVariableGuid # ALWAYS_CONSUMED
|
||||
gTcgEventEntryHobGuid
|
||||
gEfiEventReadyToBootGuid
|
||||
gEfiEventExitBootServicesGuid
|
||||
gEventExitBootServicesFailedGuid # ALWAYS_CONSUMED
|
||||
gEfiImageSecurityDatabaseGuid
|
||||
gEfiTpmDeviceInstanceNoneGuid
|
||||
gEfiTpmDeviceInstanceTpm12Guid
|
||||
|
||||
[Protocols]
|
||||
gEfiTrEEProtocolGuid ## PRODUCES
|
||||
gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiMpServiceProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiVariableWriteArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdFirmwareDebuggerInitialized
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
|
||||
|
||||
[Depex]
|
||||
TRUE
|
||||
|
694
SecurityPkg/Tcg/TrEEPei/TrEEPei.c
Normal file
694
SecurityPkg/Tcg/TrEEPei/TrEEPei.c
Normal file
@ -0,0 +1,694 @@
|
||||
/** @file
|
||||
Initialize TPM2 device and measure FVs before handing off control to DXE.
|
||||
|
||||
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 <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Ppi/FirmwareVolumeInfo.h>
|
||||
#include <Ppi/LockPhysicalPresence.h>
|
||||
#include <Ppi/TpmInitialized.h>
|
||||
#include <Ppi/FirmwareVolume.h>
|
||||
#include <Ppi/EndOfPeiPhase.h>
|
||||
#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
|
||||
|
||||
#include <Guid/TcgEventHob.h>
|
||||
#include <Guid/MeasuredFvHob.h>
|
||||
#include <Guid/TpmInstance.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
#include <Library/PeimEntryPoint.h>
|
||||
#include <Library/Tpm2CommandLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
#include <Library/HashLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/PeiServicesTablePointerLib.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
#include <Library/PerformanceLib.h>
|
||||
|
||||
#define PERF_ID_TREE_PEI 0x3080
|
||||
|
||||
typedef struct {
|
||||
EFI_GUID *EventGuid;
|
||||
TREE_EVENT_LOG_FORMAT LogFormat;
|
||||
UINT32 BootHashAlg;
|
||||
UINT16 DigestAlgID;
|
||||
TPMI_ALG_HASH TpmHashAlgo;
|
||||
} TREE_EVENT_INFO_STRUCT;
|
||||
|
||||
TREE_EVENT_INFO_STRUCT mTreeEventInfo[] = {
|
||||
{&gTcgEventEntryHobGuid, TREE_EVENT_LOG_FORMAT_TCG_1_2, TREE_BOOT_HASH_ALG_SHA1, 0, TPM_ALG_SHA1},
|
||||
};
|
||||
|
||||
BOOLEAN mImageInMemory = FALSE;
|
||||
EFI_PEI_FILE_HANDLE mFileHandle;
|
||||
|
||||
EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
|
||||
&gPeiTpmInitializedPpiGuid,
|
||||
NULL
|
||||
};
|
||||
|
||||
EFI_PLATFORM_FIRMWARE_BLOB mMeasuredBaseFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];
|
||||
UINT32 mMeasuredBaseFvIndex = 0;
|
||||
|
||||
EFI_PLATFORM_FIRMWARE_BLOB mMeasuredChildFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];
|
||||
UINT32 mMeasuredChildFvIndex = 0;
|
||||
|
||||
/**
|
||||
Measure and record the Firmware Volum Information once FvInfoPPI install.
|
||||
|
||||
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
|
||||
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
|
||||
@param[in] Ppi Address of the PPI that was installed.
|
||||
|
||||
@retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
|
||||
@return Others Fail to measure FV.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FirmwareVolmeInfoPpiNotifyCallback (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
);
|
||||
|
||||
/**
|
||||
Record all measured Firmware Volum Information into a Guid Hob
|
||||
|
||||
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
|
||||
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
|
||||
@param[in] Ppi Address of the PPI that was installed.
|
||||
|
||||
@retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
|
||||
@return Others Fail to measure FV.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EndofPeiSignalNotifyCallBack (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
);
|
||||
|
||||
EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
|
||||
&gEfiPeiFirmwareVolumeInfoPpiGuid,
|
||||
FirmwareVolmeInfoPpiNotifyCallback
|
||||
},
|
||||
{
|
||||
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiEndOfPeiSignalPpiGuid,
|
||||
EndofPeiSignalNotifyCallBack
|
||||
}
|
||||
};
|
||||
|
||||
EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;
|
||||
|
||||
/**
|
||||
This function return hash algorithm from event log format.
|
||||
|
||||
@param[in] EventLogFormat Event log format.
|
||||
|
||||
@return hash algorithm.
|
||||
**/
|
||||
TPMI_ALG_HASH
|
||||
TrEEGetHashAlgoFromLogFormat (
|
||||
IN TREE_EVENT_LOG_FORMAT EventLogFormat
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
|
||||
if (mTreeEventInfo[Index].LogFormat == EventLogFormat) {
|
||||
return mTreeEventInfo[Index].TpmHashAlgo;
|
||||
}
|
||||
}
|
||||
return TPM_ALG_SHA1;
|
||||
}
|
||||
|
||||
/**
|
||||
This function get digest from digest list.
|
||||
|
||||
@param HashAlg digest algorithm
|
||||
@param DigestList digest list
|
||||
@param Digest digest
|
||||
|
||||
@retval EFI_SUCCESS Sha1Digest is found and returned.
|
||||
@retval EFI_NOT_FOUND Sha1Digest is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
Tpm2GetDigestFromDigestList (
|
||||
IN TPMI_ALG_HASH HashAlg,
|
||||
IN TPML_DIGEST_VALUES *DigestList,
|
||||
IN VOID *Digest
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINT16 DigestSize;
|
||||
|
||||
DigestSize = GetHashSizeFromAlgo (HashAlg);
|
||||
for (Index = 0; Index < DigestList->count; Index++) {
|
||||
if (DigestList->digests[Index].hashAlg == HashAlg) {
|
||||
CopyMem (
|
||||
Digest,
|
||||
&DigestList->digests[Index].digest,
|
||||
DigestSize
|
||||
);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
Record all measured Firmware Volum Information into a Guid Hob
|
||||
Guid Hob payload layout is
|
||||
|
||||
UINT32 *************************** FIRMWARE_BLOB number
|
||||
EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
|
||||
|
||||
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
|
||||
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
|
||||
@param[in] Ppi Address of the PPI that was installed.
|
||||
|
||||
@retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
|
||||
@return Others Fail to measure FV.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EndofPeiSignalNotifyCallBack (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
{
|
||||
MEASURED_HOB_DATA *MeasuredHobData;
|
||||
|
||||
MeasuredHobData = NULL;
|
||||
|
||||
//
|
||||
// Create a Guid hob to save all measured Fv
|
||||
//
|
||||
MeasuredHobData = BuildGuidHob(
|
||||
&gMeasuredFvHobGuid,
|
||||
sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)
|
||||
);
|
||||
|
||||
if (MeasuredHobData != NULL){
|
||||
//
|
||||
// Save measured FV info enty number
|
||||
//
|
||||
MeasuredHobData->Num = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;
|
||||
|
||||
//
|
||||
// Save measured base Fv info
|
||||
//
|
||||
CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));
|
||||
|
||||
//
|
||||
// Save measured child Fv info
|
||||
//
|
||||
CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Add a new entry to the Event Log.
|
||||
|
||||
@param[in] DigestList A list of digest.
|
||||
@param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
|
||||
@param[in] NewEventData Pointer to the new event data.
|
||||
|
||||
@retval EFI_SUCCESS The new event log entry was added.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
|
||||
**/
|
||||
EFI_STATUS
|
||||
LogHashEvent (
|
||||
IN TPML_DIGEST_VALUES *DigestList,
|
||||
IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
|
||||
IN UINT8 *NewEventData
|
||||
)
|
||||
{
|
||||
VOID *HobData;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_STATUS RetStatus;
|
||||
|
||||
RetStatus = EFI_SUCCESS;
|
||||
for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
|
||||
DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTreeEventInfo[Index].LogFormat));
|
||||
switch (mTreeEventInfo[Index].LogFormat) {
|
||||
case TREE_EVENT_LOG_FORMAT_TCG_1_2:
|
||||
Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
HobData = BuildGuidHob (
|
||||
&gTcgEventEntryHobGuid,
|
||||
sizeof (*NewEventHdr) + NewEventHdr->EventSize
|
||||
);
|
||||
if (HobData == NULL) {
|
||||
RetStatus = EFI_OUT_OF_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));
|
||||
HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));
|
||||
CopyMem (HobData, NewEventData, NewEventHdr->EventSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return RetStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
|
||||
and build a GUIDed HOB recording the event which will be passed to the DXE phase and
|
||||
added into the Event Log.
|
||||
|
||||
@param[in] Flags Bitmap providing additional information.
|
||||
@param[in] HashData Physical address of the start of the data buffer
|
||||
to be hashed, extended, and logged.
|
||||
@param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
|
||||
@param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
|
||||
@param[in] NewEventData Pointer to the new event data.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HashLogExtendEvent (
|
||||
IN UINT64 Flags,
|
||||
IN UINT8 *HashData,
|
||||
IN UINTN HashDataLen,
|
||||
IN TCG_PCR_EVENT_HDR *NewEventHdr,
|
||||
IN UINT8 *NewEventData
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TPML_DIGEST_VALUES DigestList;
|
||||
|
||||
Status = HashAndExtend (
|
||||
NewEventHdr->PCRIndex,
|
||||
HashData,
|
||||
HashDataLen,
|
||||
&DigestList
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
if ((Flags & TREE_EXTEND_ONLY) == 0) {
|
||||
Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData);
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Measure CRTM version.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
MeasureCRTMVersion (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
TCG_PCR_EVENT_HDR TcgEventHdr;
|
||||
|
||||
//
|
||||
// Use FirmwareVersion string to represent CRTM version.
|
||||
// OEMs should get real CRTM version string and measure it.
|
||||
//
|
||||
|
||||
TcgEventHdr.PCRIndex = 0;
|
||||
TcgEventHdr.EventType = EV_S_CRTM_VERSION;
|
||||
TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));
|
||||
|
||||
return HashLogExtendEvent (
|
||||
0,
|
||||
(UINT8*)PcdGetPtr (PcdFirmwareVersionString),
|
||||
TcgEventHdr.EventSize,
|
||||
&TcgEventHdr,
|
||||
(UINT8*)PcdGetPtr (PcdFirmwareVersionString)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Measure FV image.
|
||||
Add it into the measured FV list after the FV is measured successfully.
|
||||
|
||||
@param[in] FvBase Base address of FV image.
|
||||
@param[in] FvLength Length of FV image.
|
||||
|
||||
@retval EFI_SUCCESS Fv image is measured successfully
|
||||
or it has been already measured.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
MeasureFvImage (
|
||||
IN EFI_PHYSICAL_ADDRESS FvBase,
|
||||
IN UINT64 FvLength
|
||||
)
|
||||
{
|
||||
UINT32 Index;
|
||||
EFI_STATUS Status;
|
||||
EFI_PLATFORM_FIRMWARE_BLOB FvBlob;
|
||||
TCG_PCR_EVENT_HDR TcgEventHdr;
|
||||
|
||||
//
|
||||
// Check if it is in Excluded FV list
|
||||
//
|
||||
if (mMeasurementExcludedFvPpi != NULL) {
|
||||
for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) {
|
||||
if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) {
|
||||
DEBUG ((DEBUG_INFO, "The FV which is excluded by TrEEPei starts at: 0x%x\n", FvBase));
|
||||
DEBUG ((DEBUG_INFO, "The FV which is excluded by TrEEPei has the size: 0x%x\n", FvLength));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether FV is in the measured FV list.
|
||||
//
|
||||
for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {
|
||||
if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Measure and record the FV to the TPM
|
||||
//
|
||||
FvBlob.BlobBase = FvBase;
|
||||
FvBlob.BlobLength = FvLength;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "The FV which is measured by TrEEPei starts at: 0x%x\n", FvBlob.BlobBase));
|
||||
DEBUG ((DEBUG_INFO, "The FV which is measured by TrEEPei has the size: 0x%x\n", FvBlob.BlobLength));
|
||||
|
||||
TcgEventHdr.PCRIndex = 0;
|
||||
TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
|
||||
TcgEventHdr.EventSize = sizeof (FvBlob);
|
||||
|
||||
Status = HashLogExtendEvent (
|
||||
0,
|
||||
(UINT8*) (UINTN) FvBlob.BlobBase,
|
||||
(UINTN) FvBlob.BlobLength,
|
||||
&TcgEventHdr,
|
||||
(UINT8*) &FvBlob
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Add new FV into the measured FV list.
|
||||
//
|
||||
ASSERT (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
|
||||
if (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
|
||||
mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase;
|
||||
mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;
|
||||
mMeasuredBaseFvIndex++;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Measure main BIOS.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
MeasureMainBios (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 FvInstances;
|
||||
EFI_PEI_FV_HANDLE VolumeHandle;
|
||||
EFI_FV_INFO VolumeInfo;
|
||||
EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
|
||||
|
||||
PERF_START_EX (mFileHandle, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI);
|
||||
FvInstances = 0;
|
||||
while (TRUE) {
|
||||
//
|
||||
// Traverse all firmware volume instances of Static Core Root of Trust for Measurement
|
||||
// (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
|
||||
// platform for special CRTM TPM measuring.
|
||||
//
|
||||
Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Measure and record the firmware volume that is dispatched by PeiCore
|
||||
//
|
||||
Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
//
|
||||
// Locate the corresponding FV_PPI according to founded FV's format guid
|
||||
//
|
||||
Status = PeiServicesLocatePpi (
|
||||
&VolumeInfo.FvFormat,
|
||||
0,
|
||||
NULL,
|
||||
(VOID**)&FvPpi
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);
|
||||
}
|
||||
|
||||
FvInstances++;
|
||||
}
|
||||
PERF_END_EX (mFileHandle, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI + 1);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Measure and record the Firmware Volum Information once FvInfoPPI install.
|
||||
|
||||
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
|
||||
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
|
||||
@param[in] Ppi Address of the PPI that was installed.
|
||||
|
||||
@retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
|
||||
@return Others Fail to measure FV.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FirmwareVolmeInfoPpiNotifyCallback (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
{
|
||||
EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
|
||||
|
||||
Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;
|
||||
|
||||
//
|
||||
// The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
|
||||
//
|
||||
Status = PeiServicesLocatePpi (
|
||||
&Fv->FvFormat,
|
||||
0,
|
||||
NULL,
|
||||
(VOID**)&FvPpi
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// This is an FV from an FFS file, and the parent FV must have already been measured,
|
||||
// No need to measure twice, so just record the FV and return
|
||||
//
|
||||
if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {
|
||||
|
||||
ASSERT (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
|
||||
if (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
|
||||
mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;
|
||||
mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;
|
||||
mMeasuredChildFvIndex++;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);
|
||||
}
|
||||
|
||||
/**
|
||||
Do measurement after memory is ready.
|
||||
|
||||
@param[in] PeiServices Describes the list of possible PEI Services.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PeimEntryMP (
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID**)&mMeasurementExcludedFvPpi
|
||||
);
|
||||
// Do not check status, because it is optional
|
||||
|
||||
if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) {
|
||||
Status = MeasureCRTMVersion ();
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
Status = MeasureMainBios ();
|
||||
|
||||
//
|
||||
// Post callbacks:
|
||||
// for the FvInfoPpi services to measure and record
|
||||
// the additional Fvs to TPM
|
||||
//
|
||||
Status = PeiServicesNotifyPpi (&mNotifyList[0]);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Entry point of this module.
|
||||
|
||||
@param[in] FileHandle Handle of the file being invoked.
|
||||
@param[in] PeiServices Describes the list of possible PEI Services.
|
||||
|
||||
@return Status.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeimEntryMA (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_BOOT_MODE BootMode;
|
||||
|
||||
if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
|
||||
CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
|
||||
DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Update for Performance optimization
|
||||
//
|
||||
Status = Tpm2RequestUseTpm ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = PeiServicesGetBootMode (&BootMode);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// In S3 path, skip shadow logic. no measurement is required
|
||||
//
|
||||
if (BootMode != BOOT_ON_S3_RESUME) {
|
||||
Status = (**PeiServices).RegisterForShadow(FileHandle);
|
||||
if (Status == EFI_ALREADY_STARTED) {
|
||||
mImageInMemory = TRUE;
|
||||
mFileHandle = FileHandle;
|
||||
} else if (Status == EFI_NOT_FOUND) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mImageInMemory) {
|
||||
//
|
||||
// Initialize TPM device
|
||||
//
|
||||
if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {
|
||||
if (BootMode == BOOT_ON_S3_RESUME) {
|
||||
Status = Tpm2Startup (TPM_SU_STATE);
|
||||
if (EFI_ERROR (Status) ) {
|
||||
Status = Tpm2Startup (TPM_SU_CLEAR);
|
||||
}
|
||||
} else {
|
||||
Status = Tpm2Startup (TPM_SU_CLEAR);
|
||||
}
|
||||
if (EFI_ERROR (Status) ) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TpmSelfTest is optional on S3 path, skip it to save S3 time
|
||||
//
|
||||
if (BootMode != BOOT_ON_S3_RESUME) {
|
||||
if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) {
|
||||
Status = Tpm2SelfTest (NO);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
if (mImageInMemory) {
|
||||
Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
75
SecurityPkg/Tcg/TrEEPei/TrEEPei.inf
Normal file
75
SecurityPkg/Tcg/TrEEPei/TrEEPei.inf
Normal file
@ -0,0 +1,75 @@
|
||||
## @file
|
||||
# This module will initialize TPM2 device and measure FVs in PEI phase.
|
||||
#
|
||||
# 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 = TrEEPei
|
||||
FILE_GUID = CA5A1928-6523-409d-A9FE-5DCC87387222
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = PeimEntryMA
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources]
|
||||
TrEEPei.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
HobLib
|
||||
PeimEntryPoint
|
||||
PeiServicesLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
Tpm2CommandLib
|
||||
PeiServicesTablePointerLib
|
||||
Tpm2DeviceLib
|
||||
HashLib
|
||||
PerformanceLib
|
||||
|
||||
[Guids]
|
||||
gTcgEventEntryHobGuid
|
||||
gMeasuredFvHobGuid
|
||||
gEfiTpmDeviceInstanceNoneGuid
|
||||
gEfiTpmDeviceInstanceTpm12Guid
|
||||
|
||||
[Ppis]
|
||||
gEfiPeiFirmwareVolumeInfoPpiGuid
|
||||
gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid
|
||||
gPeiTpmInitializedPpiGuid
|
||||
gEfiEndOfPeiSignalPpiGuid
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString ## CONSUMES
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2SelfTestPolicy
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy
|
||||
|
||||
[FixedPcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiPeiMasterBootModePpiGuid AND
|
||||
gEfiPeiReadOnlyVariable2PpiGuid AND
|
||||
gEfiTpmDeviceSelectedGuid
|
354
SecurityPkg/Tcg/TrEESmm/Tpm.asl
Normal file
354
SecurityPkg/Tcg/TrEESmm/Tpm.asl
Normal file
@ -0,0 +1,354 @@
|
||||
/** @file
|
||||
The TPM2 definition block in ACPI table for TrEE physical presence
|
||||
and MemoryClear.
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
DefinitionBlock (
|
||||
"Tpm.aml",
|
||||
"SSDT",
|
||||
1,
|
||||
"INTEL ",
|
||||
"Tpm2Tabl",
|
||||
0x1000
|
||||
)
|
||||
{
|
||||
Scope (\_SB)
|
||||
{
|
||||
Device (TPM)
|
||||
{
|
||||
//
|
||||
// TREE
|
||||
//
|
||||
Name (_HID, "MSFT0101")
|
||||
|
||||
//
|
||||
// Readable name of this device, don't know if this way is correct yet
|
||||
//
|
||||
Name (_STR, Unicode ("TPM 2.0 Device"))
|
||||
|
||||
//
|
||||
// Return the resource consumed by TPM device
|
||||
//
|
||||
Name (_CRS, ResourceTemplate () {
|
||||
Memory32Fixed (ReadOnly, 0xfed40000, 0x5000)
|
||||
})
|
||||
|
||||
//
|
||||
// Operational region for Smi port access
|
||||
//
|
||||
OperationRegion (SMIP, SystemIO, 0xB2, 1)
|
||||
Field (SMIP, ByteAcc, NoLock, Preserve)
|
||||
{
|
||||
IOB2, 8
|
||||
}
|
||||
|
||||
//
|
||||
// Operational region for TPM access
|
||||
//
|
||||
OperationRegion (TPMR, SystemMemory, 0xfed40000, 0x5000)
|
||||
Field (TPMR, AnyAcc, NoLock, Preserve)
|
||||
{
|
||||
ACC0, 8,
|
||||
}
|
||||
|
||||
//
|
||||
// Operational region for TPM support, TPM Physical Presence and TPM Memory Clear
|
||||
// Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code.
|
||||
//
|
||||
OperationRegion (TNVS, SystemMemory, 0xFFFF0000, 0xF0)
|
||||
Field (TNVS, AnyAcc, NoLock, Preserve)
|
||||
{
|
||||
PPIN, 8, // Software SMI for Physical Presence Interface
|
||||
PPIP, 32, // Used for save physical presence paramter
|
||||
PPRP, 32, // Physical Presence request operation response
|
||||
PPRQ, 32, // Physical Presence request operation
|
||||
LPPR, 32, // Last Physical Presence request operation
|
||||
FRET, 32, // Physical Presence function return code
|
||||
MCIN, 8, // Software SMI for Memory Clear Interface
|
||||
MCIP, 32, // Used for save the Mor paramter
|
||||
MORD, 32, // Memory Overwrite Request Data
|
||||
MRET, 32 // Memory Overwrite function return code
|
||||
}
|
||||
|
||||
Method (PTS, 1, Serialized)
|
||||
{
|
||||
//
|
||||
// Detect Sx state for MOR, only S4, S5 need to handle
|
||||
//
|
||||
If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3)))
|
||||
{
|
||||
//
|
||||
// Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect.
|
||||
//
|
||||
If (LNot (And (MORD, 0x10)))
|
||||
{
|
||||
//
|
||||
// Triggle the SMI through ACPI _PTS method.
|
||||
//
|
||||
Store (0x02, MCIP)
|
||||
|
||||
//
|
||||
// Triggle the SMI interrupt
|
||||
//
|
||||
Store (MCIN, IOB2)
|
||||
}
|
||||
}
|
||||
Return (0)
|
||||
}
|
||||
|
||||
Method (_STA, 0)
|
||||
{
|
||||
if (LEqual (ACC0, 0xff))
|
||||
{
|
||||
Return (0)
|
||||
}
|
||||
Return (0x0f)
|
||||
}
|
||||
|
||||
//
|
||||
// TCG Hardware Information
|
||||
//
|
||||
Method (HINF, 3, Serialized, 0, {BuffObj, PkgObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj
|
||||
{
|
||||
//
|
||||
// Switch by function index
|
||||
//
|
||||
Switch (ToInteger(Arg1))
|
||||
{
|
||||
Case (0)
|
||||
{
|
||||
//
|
||||
// Standard query
|
||||
//
|
||||
Return (Buffer () {0x03})
|
||||
}
|
||||
Case (1)
|
||||
{
|
||||
//
|
||||
// Return failure if no TPM present
|
||||
//
|
||||
Name(TPMV, Package () {0x01, Package () {0x2, 0x0}})
|
||||
if (LEqual (_STA (), 0x00))
|
||||
{
|
||||
Return (Package () {0x00})
|
||||
}
|
||||
|
||||
//
|
||||
// Return TPM version
|
||||
//
|
||||
Return (TPMV)
|
||||
}
|
||||
Default {BreakPoint}
|
||||
}
|
||||
Return (Buffer () {0})
|
||||
}
|
||||
|
||||
Name(TPM2, Package (0x02){
|
||||
Zero,
|
||||
Zero
|
||||
})
|
||||
|
||||
Name(TPM3, Package (0x03){
|
||||
Zero,
|
||||
Zero,
|
||||
Zero
|
||||
})
|
||||
|
||||
//
|
||||
// TCG Physical Presence Interface
|
||||
//
|
||||
Method (TPPI, 3, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj
|
||||
{
|
||||
//
|
||||
// Switch by function index
|
||||
//
|
||||
Switch (ToInteger(Arg1))
|
||||
{
|
||||
Case (0)
|
||||
{
|
||||
//
|
||||
// Standard query, supports function 1-8
|
||||
//
|
||||
Return (Buffer () {0xFF, 0x01})
|
||||
}
|
||||
Case (1)
|
||||
{
|
||||
//
|
||||
// a) Get Physical Presence Interface Version
|
||||
//
|
||||
Return ("1.2")
|
||||
}
|
||||
Case (2)
|
||||
{
|
||||
//
|
||||
// b) Submit TPM Operation Request to Pre-OS Environment
|
||||
//
|
||||
|
||||
Store (DerefOf (Index (Arg2, 0x00)), PPRQ)
|
||||
Store (0x02, PPIP)
|
||||
|
||||
//
|
||||
// Triggle the SMI interrupt
|
||||
//
|
||||
Store (PPIN, IOB2)
|
||||
Return (FRET)
|
||||
|
||||
|
||||
}
|
||||
Case (3)
|
||||
{
|
||||
//
|
||||
// c) Get Pending TPM Operation Requested By the OS
|
||||
//
|
||||
|
||||
Store (PPRQ, Index (TPM2, 0x01))
|
||||
Return (TPM2)
|
||||
}
|
||||
Case (4)
|
||||
{
|
||||
//
|
||||
// d) Get Platform-Specific Action to Transition to Pre-OS Environment
|
||||
//
|
||||
Return (2)
|
||||
}
|
||||
Case (5)
|
||||
{
|
||||
//
|
||||
// e) Return TPM Operation Response to OS Environment
|
||||
//
|
||||
Store (0x05, PPIP)
|
||||
|
||||
//
|
||||
// Triggle the SMI interrupt
|
||||
//
|
||||
Store (PPIN, IOB2)
|
||||
|
||||
Store (LPPR, Index (TPM3, 0x01))
|
||||
Store (PPRP, Index (TPM3, 0x02))
|
||||
|
||||
Return (TPM3)
|
||||
}
|
||||
Case (6)
|
||||
{
|
||||
|
||||
//
|
||||
// f) Submit preferred user language (Not implemented)
|
||||
//
|
||||
|
||||
Return (3)
|
||||
|
||||
}
|
||||
Case (7)
|
||||
{
|
||||
//
|
||||
// g) Submit TPM Operation Request to Pre-OS Environment 2
|
||||
//
|
||||
Store (7, PPIP)
|
||||
Store (DerefOf (Index (Arg2, 0x00)), PPRQ)
|
||||
|
||||
//
|
||||
// Triggle the SMI interrupt
|
||||
//
|
||||
Store (PPIN, IOB2)
|
||||
Return (FRET)
|
||||
}
|
||||
Case (8)
|
||||
{
|
||||
//
|
||||
// e) Get User Confirmation Status for Operation
|
||||
//
|
||||
Store (8, PPIP)
|
||||
Store (DerefOf (Index (Arg2, 0x00)), PPRQ)
|
||||
|
||||
//
|
||||
// Triggle the SMI interrupt
|
||||
//
|
||||
Store (PPIN, IOB2)
|
||||
|
||||
Return (FRET)
|
||||
}
|
||||
|
||||
Default {BreakPoint}
|
||||
}
|
||||
Return (1)
|
||||
}
|
||||
|
||||
Method (TMCI, 3, Serialized, 0, IntObj, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj
|
||||
{
|
||||
//
|
||||
// Switch by function index
|
||||
//
|
||||
Switch (ToInteger (Arg1))
|
||||
{
|
||||
Case (0)
|
||||
{
|
||||
//
|
||||
// Standard query, supports function 1-1
|
||||
//
|
||||
Return (Buffer () {0x03})
|
||||
}
|
||||
Case (1)
|
||||
{
|
||||
//
|
||||
// Save the Operation Value of the Request to MORD (reserved memory)
|
||||
//
|
||||
Store (DerefOf (Index (Arg2, 0x00)), MORD)
|
||||
|
||||
//
|
||||
// Triggle the SMI through ACPI _DSM method.
|
||||
//
|
||||
Store (0x01, MCIP)
|
||||
|
||||
//
|
||||
// Triggle the SMI interrupt
|
||||
//
|
||||
Store (MCIN, IOB2)
|
||||
Return (MRET)
|
||||
}
|
||||
Default {BreakPoint}
|
||||
}
|
||||
Return (1)
|
||||
}
|
||||
|
||||
Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj})
|
||||
{
|
||||
|
||||
//
|
||||
// TCG Hardware Information
|
||||
//
|
||||
If(LEqual(Arg0, ToUUID ("cf8e16a5-c1e8-4e25-b712-4f54a96702c8")))
|
||||
{
|
||||
Return (HINF (Arg1, Arg2, Arg3))
|
||||
}
|
||||
|
||||
//
|
||||
// TCG Physical Presence Interface
|
||||
//
|
||||
If(LEqual(Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653")))
|
||||
{
|
||||
Return (TPPI (Arg1, Arg2, Arg3))
|
||||
}
|
||||
|
||||
//
|
||||
// TCG Memory Clear Interface
|
||||
//
|
||||
If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d")))
|
||||
{
|
||||
Return (TMCI (Arg1, Arg2, Arg3))
|
||||
}
|
||||
|
||||
Return (Buffer () {0})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
480
SecurityPkg/Tcg/TrEESmm/TrEESmm.c
Normal file
480
SecurityPkg/Tcg/TrEESmm/TrEESmm.c
Normal file
@ -0,0 +1,480 @@
|
||||
/** @file
|
||||
It updates TPM2 items in ACPI table and registers SMI2 callback
|
||||
functions for TrEE physical presence, ClearMemory, and sample
|
||||
for dTPM StartMethod.
|
||||
|
||||
Caution: This module requires additional review when modified.
|
||||
This driver will have external input - variable and ACPINvs data in SMM mode.
|
||||
This external input must be validated carefully to avoid security issue.
|
||||
|
||||
PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.
|
||||
|
||||
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 "TrEESmm.h"
|
||||
|
||||
EFI_TPM2_ACPI_TABLE mTpm2AcpiTemplate = {
|
||||
{
|
||||
EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE,
|
||||
sizeof (mTpm2AcpiTemplate),
|
||||
EFI_TPM2_ACPI_TABLE_REVISION,
|
||||
//
|
||||
// Compiler initializes the remaining bytes to 0
|
||||
// These fields should be filled in in production
|
||||
//
|
||||
},
|
||||
0, // Flags
|
||||
0, // Control Area
|
||||
EFI_TPM2_ACPI_TABLE_START_METHOD_TIS, // StartMethod
|
||||
};
|
||||
|
||||
EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;
|
||||
TCG_NVS *mTcgNvs;
|
||||
|
||||
/**
|
||||
Software SMI callback for TPM physical presence which is called from ACPI method.
|
||||
|
||||
Caution: This function may receive untrusted input.
|
||||
Variable and ACPINvs are external input, so this function will validate
|
||||
its data structure to be valid value.
|
||||
|
||||
@param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
|
||||
@param[in] Context Points to an optional handler context which was specified when the
|
||||
handler was registered.
|
||||
@param[in, out] CommBuffer A pointer to a collection of data in memory that will
|
||||
be conveyed from a non-SMM environment into an SMM environment.
|
||||
@param[in, out] CommBufferSize The size of the CommBuffer.
|
||||
|
||||
@retval EFI_SUCCESS The interrupt was handled successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PhysicalPresenceCallback (
|
||||
IN EFI_HANDLE DispatchHandle,
|
||||
IN CONST VOID *Context,
|
||||
IN OUT VOID *CommBuffer,
|
||||
IN OUT UINTN *CommBufferSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN DataSize;
|
||||
EFI_TREE_PHYSICAL_PRESENCE PpData;
|
||||
UINT8 Flags;
|
||||
BOOLEAN RequestConfirmed;
|
||||
|
||||
//
|
||||
// Get the Physical Presence variable
|
||||
//
|
||||
DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
|
||||
Status = mSmmVariable->SmmGetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
NULL,
|
||||
&DataSize,
|
||||
&PpData
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_INFO, "[TPM2] PP callback, Parameter = %x, Request = %x\n", mTcgNvs->PhysicalPresence.Parameter, mTcgNvs->PhysicalPresence.Request));
|
||||
|
||||
if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) {
|
||||
mTcgNvs->PhysicalPresence.LastRequest = PpData.LastPPRequest;
|
||||
mTcgNvs->PhysicalPresence.Response = PpData.PPResponse;
|
||||
} else if ((mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS)
|
||||
|| (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2)) {
|
||||
if (mTcgNvs->PhysicalPresence.Request > TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
|
||||
//
|
||||
// This command requires UI to prompt user for Auth data.
|
||||
//
|
||||
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_NOT_IMPLEMENTED;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (PpData.PPRequest != mTcgNvs->PhysicalPresence.Request) {
|
||||
PpData.PPRequest = (UINT8) mTcgNvs->PhysicalPresence.Request;
|
||||
DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
|
||||
Status = mSmmVariable->SmmSetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
DataSize,
|
||||
&PpData
|
||||
);
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_GENERAL_FAILURE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_SUCCESS;
|
||||
} else if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {
|
||||
//
|
||||
// Get the Physical Presence flags
|
||||
//
|
||||
DataSize = sizeof (UINT8);
|
||||
Status = mSmmVariable->SmmGetVariable (
|
||||
TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
|
||||
&gEfiTrEEPhysicalPresenceGuid,
|
||||
NULL,
|
||||
&DataSize,
|
||||
&Flags
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_GENERAL_FAILURE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
RequestConfirmed = FALSE;
|
||||
|
||||
switch (mTcgNvs->PhysicalPresence.Request) {
|
||||
|
||||
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:
|
||||
if (mTcgNvs->PhysicalPresence.Request <= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
|
||||
RequestConfirmed = TRUE;
|
||||
} else {
|
||||
mTcgNvs->PhysicalPresence.ReturnCode = PP_REQUEST_NOT_IMPLEMENTED;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (RequestConfirmed) {
|
||||
mTcgNvs->PhysicalPresence.ReturnCode = PP_REQUEST_ALLOWED_AND_PPUSER_NOT_REQUIRED;
|
||||
} else {
|
||||
mTcgNvs->PhysicalPresence.ReturnCode = PP_REQUEST_ALLOWED_AND_PPUSER_REQUIRED;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Software SMI callback for MemoryClear which is called from ACPI method.
|
||||
|
||||
Caution: This function may receive untrusted input.
|
||||
Variable and ACPINvs are external input, so this function will validate
|
||||
its data structure to be valid value.
|
||||
|
||||
@param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
|
||||
@param[in] Context Points to an optional handler context which was specified when the
|
||||
handler was registered.
|
||||
@param[in, out] CommBuffer A pointer to a collection of data in memory that will
|
||||
be conveyed from a non-SMM environment into an SMM environment.
|
||||
@param[in, out] CommBufferSize The size of the CommBuffer.
|
||||
|
||||
@retval EFI_SUCCESS The interrupt was handled successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MemoryClearCallback (
|
||||
IN EFI_HANDLE DispatchHandle,
|
||||
IN CONST VOID *Context,
|
||||
IN OUT VOID *CommBuffer,
|
||||
IN OUT UINTN *CommBufferSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN DataSize;
|
||||
UINT8 MorControl;
|
||||
|
||||
mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS;
|
||||
if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) {
|
||||
MorControl = (UINT8) mTcgNvs->MemoryClear.Request;
|
||||
} else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) {
|
||||
DataSize = sizeof (UINT8);
|
||||
Status = mSmmVariable->SmmGetVariable (
|
||||
MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
|
||||
&gEfiMemoryOverwriteControlDataGuid,
|
||||
NULL,
|
||||
&DataSize,
|
||||
&MorControl
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;
|
||||
}
|
||||
|
||||
DataSize = sizeof (UINT8);
|
||||
Status = mSmmVariable->SmmSetVariable (
|
||||
MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
|
||||
&gEfiMemoryOverwriteControlDataGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
DataSize,
|
||||
&MorControl
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the operation region in TCG ACPI table by given Name and Size,
|
||||
and initialize it if the region is found.
|
||||
|
||||
@param[in, out] Table The TPM item in ACPI table.
|
||||
@param[in] Name The name string to find in TPM table.
|
||||
@param[in] Size The size of the region to find.
|
||||
|
||||
@return The allocated address for the found region.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
AssignOpRegion (
|
||||
EFI_ACPI_DESCRIPTION_HEADER *Table,
|
||||
UINT32 Name,
|
||||
UINT16 Size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
AML_OP_REGION_32_8 *OpRegion;
|
||||
EFI_PHYSICAL_ADDRESS MemoryAddress;
|
||||
|
||||
MemoryAddress = SIZE_4GB - 1;
|
||||
|
||||
//
|
||||
// Patch some pointers for the ASL code before loading the SSDT.
|
||||
//
|
||||
for (OpRegion = (AML_OP_REGION_32_8 *) (Table + 1);
|
||||
OpRegion <= (AML_OP_REGION_32_8 *) ((UINT8 *) Table + Table->Length);
|
||||
OpRegion = (AML_OP_REGION_32_8 *) ((UINT8 *) OpRegion + 1)) {
|
||||
if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) &&
|
||||
(OpRegion->NameString == Name) &&
|
||||
(OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&
|
||||
(OpRegion->BytePrefix == AML_BYTE_PREFIX)) {
|
||||
|
||||
Status = gBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
ZeroMem ((VOID *)(UINTN)MemoryAddress, Size);
|
||||
OpRegion->RegionOffset = (UINT32) (UINTN) MemoryAddress;
|
||||
OpRegion->RegionLen = (UINT8) Size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (VOID *) (UINTN) MemoryAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize and publish TPM items in ACPI table.
|
||||
|
||||
@retval EFI_SUCCESS The TCG ACPI table is published successfully.
|
||||
@retval Others The TCG ACPI table is not published.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PublishAcpiTable (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
|
||||
UINTN TableKey;
|
||||
EFI_ACPI_DESCRIPTION_HEADER *Table;
|
||||
UINTN TableSize;
|
||||
|
||||
Status = GetSectionFromFv (
|
||||
&gEfiCallerIdGuid,
|
||||
EFI_SECTION_RAW,
|
||||
0,
|
||||
(VOID **) &Table,
|
||||
&TableSize
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
|
||||
//
|
||||
// Measure to PCR[0] with event EV_POST_CODE ACPI DATA
|
||||
//
|
||||
TpmMeasureAndLogData(
|
||||
0,
|
||||
EV_POST_CODE,
|
||||
EV_POSTCODE_INFO_ACPI_DATA,
|
||||
ACPI_DATA_LEN,
|
||||
Table,
|
||||
TableSize
|
||||
);
|
||||
|
||||
|
||||
ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l'));
|
||||
CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId) );
|
||||
mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS));
|
||||
ASSERT (mTcgNvs != NULL);
|
||||
|
||||
//
|
||||
// Publish the TPM ACPI table
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
TableKey = 0;
|
||||
Status = AcpiTable->InstallAcpiTable (
|
||||
AcpiTable,
|
||||
Table,
|
||||
TableSize,
|
||||
&TableKey
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Publish TPM2 ACPI table
|
||||
|
||||
@retval EFI_SUCCESS The TPM2 ACPI table is published successfully.
|
||||
@retval Others The TPM2 ACPI table is not published.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PublishTpm2 (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
|
||||
UINTN TableKey;
|
||||
UINT64 OemTableId;
|
||||
|
||||
//
|
||||
// Measure to PCR[0] with event EV_POST_CODE ACPI DATA
|
||||
//
|
||||
TpmMeasureAndLogData(
|
||||
0,
|
||||
EV_POST_CODE,
|
||||
EV_POSTCODE_INFO_ACPI_DATA,
|
||||
ACPI_DATA_LEN,
|
||||
&mTpm2AcpiTemplate,
|
||||
sizeof(mTpm2AcpiTemplate)
|
||||
);
|
||||
|
||||
CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId));
|
||||
OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
|
||||
CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
|
||||
mTpm2AcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
|
||||
mTpm2AcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
|
||||
mTpm2AcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
|
||||
|
||||
//
|
||||
// Construct ACPI table
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = AcpiTable->InstallAcpiTable (
|
||||
AcpiTable,
|
||||
&mTpm2AcpiTemplate,
|
||||
sizeof(mTpm2AcpiTemplate),
|
||||
&TableKey
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
The driver's entry point.
|
||||
|
||||
It install callbacks for TPM physical presence and MemoryClear, and locate
|
||||
SMM variable to be used in the callback function.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The entry point is executed successfully.
|
||||
@retval Others Some error occurs when executing this entry point.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeTcgSmm (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
|
||||
EFI_SMM_SW_REGISTER_CONTEXT SwContext;
|
||||
EFI_HANDLE SwHandle;
|
||||
|
||||
if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid)){
|
||||
DEBUG ((EFI_D_ERROR, "No TPM2 DTPM instance required!\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = PublishAcpiTable ();
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Get the Sw dispatch protocol and register SMI callback functions.
|
||||
//
|
||||
Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID**)&SwDispatch);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
SwContext.SwSmiInputValue = (UINTN) -1;
|
||||
Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;
|
||||
|
||||
SwContext.SwSmiInputValue = (UINTN) -1;
|
||||
Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;
|
||||
|
||||
//
|
||||
// Locate SmmVariableProtocol.
|
||||
//
|
||||
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mSmmVariable);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Set TPM2 ACPI table
|
||||
//
|
||||
Status = PublishTpm2 ();
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
117
SecurityPkg/Tcg/TrEESmm/TrEESmm.h
Normal file
117
SecurityPkg/Tcg/TrEESmm/TrEESmm.h
Normal file
@ -0,0 +1,117 @@
|
||||
/** @file
|
||||
The header file for TrEE SMM driver.
|
||||
|
||||
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 __TREE_SMM_H__
|
||||
#define __TREE_SMM_H__
|
||||
|
||||
#include <PiDxe.h>
|
||||
#include <IndustryStandard/Acpi.h>
|
||||
#include <IndustryStandard/Tpm2Acpi.h>
|
||||
|
||||
#include <Guid/TrEEPhysicalPresenceData.h>
|
||||
#include <Guid/MemoryOverwriteControl.h>
|
||||
#include <Guid/TpmInstance.h>
|
||||
|
||||
#include <Protocol/SmmSwDispatch2.h>
|
||||
#include <Protocol/AcpiTable.h>
|
||||
#include <Protocol/SmmVariable.h>
|
||||
#include <Protocol/TrEEProtocol.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/SmmServicesTableLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/DxeServicesLib.h>
|
||||
#include <Library/TpmMeasurementLib.h>
|
||||
#include <Library/Tpm2DeviceLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
UINT8 SoftwareSmi;
|
||||
UINT32 Parameter;
|
||||
UINT32 Response;
|
||||
UINT32 Request;
|
||||
UINT32 LastRequest;
|
||||
UINT32 ReturnCode;
|
||||
} PHYSICAL_PRESENCE_NVS;
|
||||
|
||||
typedef struct {
|
||||
UINT8 SoftwareSmi;
|
||||
UINT32 Parameter;
|
||||
UINT32 Request;
|
||||
UINT32 ReturnCode;
|
||||
} MEMORY_CLEAR_NVS;
|
||||
|
||||
typedef struct {
|
||||
PHYSICAL_PRESENCE_NVS PhysicalPresence;
|
||||
MEMORY_CLEAR_NVS MemoryClear;
|
||||
} TCG_NVS;
|
||||
|
||||
typedef struct {
|
||||
UINT8 OpRegionOp;
|
||||
UINT32 NameString;
|
||||
UINT8 RegionSpace;
|
||||
UINT8 DWordPrefix;
|
||||
UINT32 RegionOffset;
|
||||
UINT8 BytePrefix;
|
||||
UINT8 RegionLen;
|
||||
} AML_OP_REGION_32_8;
|
||||
#pragma pack()
|
||||
|
||||
//
|
||||
// The definition for TCG physical presence ACPI function
|
||||
//
|
||||
#define ACPI_FUNCTION_GET_PHYSICAL_PRESENCE_INTERFACE_VERSION 1
|
||||
#define ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS 2
|
||||
#define ACPI_FUNCTION_GET_PENDING_REQUEST_BY_OS 3
|
||||
#define ACPI_FUNCTION_GET_PLATFORM_ACTION_TO_TRANSITION_TO_BIOS 4
|
||||
#define ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS 5
|
||||
#define ACPI_FUNCTION_SUBMIT_PREFERRED_USER_LANGUAGE 6
|
||||
#define ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2 7
|
||||
#define ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST 8
|
||||
|
||||
//
|
||||
// The return code for Get User Confirmation Status for Operation
|
||||
//
|
||||
#define PP_REQUEST_NOT_IMPLEMENTED 0
|
||||
#define PP_REQUEST_BIOS_ONLY 1
|
||||
#define PP_REQUEST_BLOCKED 2
|
||||
#define PP_REQUEST_ALLOWED_AND_PPUSER_REQUIRED 3
|
||||
#define PP_REQUEST_ALLOWED_AND_PPUSER_NOT_REQUIRED 4
|
||||
|
||||
//
|
||||
// The return code for Sumbit TPM Request to Pre-OS Environment
|
||||
// and Sumbit TPM Request to Pre-OS Environment 2
|
||||
//
|
||||
#define PP_SUBMIT_REQUEST_SUCCESS 0
|
||||
#define PP_SUBMIT_REQUEST_NOT_IMPLEMENTED 1
|
||||
#define PP_SUBMIT_REQUEST_GENERAL_FAILURE 2
|
||||
#define PP_SUBMIT_REQUEST_BLOCKED_BY_BIOS_SETTINGS 3
|
||||
|
||||
|
||||
//
|
||||
// The definition for TCG MOR
|
||||
//
|
||||
#define ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE 1
|
||||
#define ACPI_FUNCTION_PTS_CLEAR_MOR_BIT 2
|
||||
|
||||
//
|
||||
// The return code for Memory Clear Interface Functions
|
||||
//
|
||||
#define MOR_REQUEST_SUCCESS 0
|
||||
#define MOR_REQUEST_GENERAL_FAILURE 1
|
||||
|
||||
#endif // __TCG_SMM_H__
|
71
SecurityPkg/Tcg/TrEESmm/TrEESmm.inf
Normal file
71
SecurityPkg/Tcg/TrEESmm/TrEESmm.inf
Normal file
@ -0,0 +1,71 @@
|
||||
## @file
|
||||
# This driver implements TPM2 definition block in ACPI table and
|
||||
# registers SMI callback functions for TrEE physical presence and
|
||||
# MemoryClear to handle the requests from ACPI method.
|
||||
#
|
||||
# Caution: This module requires additional review when modified.
|
||||
# This driver will have external input - variable and ACPINvs data in SMM mode.
|
||||
# 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 = TrEESmm
|
||||
FILE_GUID = 114B7105-6CC9-453c-BADC-16DF227BB4EF
|
||||
MODULE_TYPE = DXE_SMM_DRIVER
|
||||
PI_SPECIFICATION_VERSION = 0x0001000A
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = InitializeTcgSmm
|
||||
|
||||
[Sources]
|
||||
TrEESmm.h
|
||||
TrEESmm.c
|
||||
Tpm.asl
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
UefiDriverEntryPoint
|
||||
SmmServicesTableLib
|
||||
UefiBootServicesTableLib
|
||||
DebugLib
|
||||
DxeServicesLib
|
||||
TpmMeasurementLib
|
||||
Tpm2DeviceLib
|
||||
|
||||
[Guids]
|
||||
gEfiTrEEPhysicalPresenceGuid
|
||||
gEfiMemoryOverwriteControlDataGuid
|
||||
gEfiTpmDeviceInstanceTpm20DtpmGuid
|
||||
|
||||
[Protocols]
|
||||
gEfiSmmSwDispatch2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiSmmVariableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
||||
[Pcd]
|
||||
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
|
||||
|
||||
[Depex]
|
||||
gEfiAcpiTableProtocolGuid AND
|
||||
gEfiSmmSwDispatch2ProtocolGuid AND
|
||||
gEfiSmmVariableProtocolGuid
|
255
SecurityPkg/VariableAuthenticated/RuntimeDxe/Measurement.c
Normal file
255
SecurityPkg/VariableAuthenticated/RuntimeDxe/Measurement.c
Normal file
@ -0,0 +1,255 @@
|
||||
/** @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;
|
||||
|
||||
VARIABLE_TYPE mVariableType[] = {
|
||||
{EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid},
|
||||
{EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid},
|
||||
{EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid},
|
||||
{EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},
|
||||
{EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},
|
||||
};
|
||||
|
||||
/**
|
||||
This function will return if this variable is SecureBootPolicy 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 SecureBootPolicy Variable
|
||||
@retval FALSE This is not SecureBootPolicy Variable
|
||||
**/
|
||||
BOOLEAN
|
||||
IsSecureBootPolicyVariable (
|
||||
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;
|
||||
|
||||
ASSERT ((VarSize == 0 && VarData == NULL) || (VarSize != 0 && VarData != NULL));
|
||||
|
||||
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)
|
||||
);
|
||||
if (VarSize != 0) {
|
||||
CopyMem (
|
||||
(CHAR16 *)VarLog->UnicodeName + VarNameLength,
|
||||
VarData,
|
||||
VarSize
|
||||
);
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "AuthVariableDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY));
|
||||
DEBUG ((EFI_D_ERROR, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
7,
|
||||
EV_EFI_VARIABLE_DRIVER_CONFIG,
|
||||
VarLog,
|
||||
VarLogSize,
|
||||
VarLog,
|
||||
VarLogSize
|
||||
);
|
||||
FreePool (VarLog);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the status whether get the variable success. The function retrieves
|
||||
variable through the UEFI Runtime Service GetVariable(). The
|
||||
returned buffer is allocated using AllocatePool(). The caller is responsible
|
||||
for freeing this buffer with FreePool().
|
||||
|
||||
This API is only invoked in boot time. It may NOT be invoked at runtime.
|
||||
|
||||
@param[in] Name The pointer to a Null-terminated Unicode string.
|
||||
@param[in] Guid The pointer to an EFI_GUID structure
|
||||
@param[out] Value The buffer point saved the variable info.
|
||||
@param[out] Size The buffer size of the variable.
|
||||
|
||||
@return EFI_OUT_OF_RESOURCES Allocate buffer failed.
|
||||
@return EFI_SUCCESS Find the specified variable.
|
||||
@return Others Errors Return errors from call to gRT->GetVariable.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
InternalGetVariable (
|
||||
IN CONST CHAR16 *Name,
|
||||
IN CONST EFI_GUID *Guid,
|
||||
OUT VOID **Value,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
|
||||
//
|
||||
// Try to get the variable size.
|
||||
//
|
||||
BufferSize = 0;
|
||||
*Value = NULL;
|
||||
if (Size != NULL) {
|
||||
*Size = 0;
|
||||
}
|
||||
|
||||
Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &BufferSize, *Value);
|
||||
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate buffer to get the variable.
|
||||
//
|
||||
*Value = AllocatePool (BufferSize);
|
||||
ASSERT (*Value != NULL);
|
||||
if (*Value == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the variable data.
|
||||
//
|
||||
Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &BufferSize, *Value);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool(*Value);
|
||||
*Value = NULL;
|
||||
}
|
||||
|
||||
if (Size != NULL) {
|
||||
*Size = BufferSize;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
SecureBoot Hook for SetVariable.
|
||||
|
||||
@param[in] VariableName Name of Variable to be found.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SecureBootHook (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN VariableDataSize;
|
||||
VOID *VariableData;
|
||||
|
||||
if (!IsSecureBootPolicyVariable (VariableName, VendorGuid)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// We should NOT use Data and DataSize here,because it may include signature,
|
||||
// or is just partial with append attributes, or is deleted.
|
||||
// We should GetVariable again, to get full variable content.
|
||||
//
|
||||
Status = InternalGetVariable (
|
||||
VariableName,
|
||||
VendorGuid,
|
||||
&VariableData,
|
||||
&VariableDataSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
VariableData = NULL;
|
||||
VariableDataSize = 0;
|
||||
}
|
||||
|
||||
Status = MeasureVariable (
|
||||
VariableName,
|
||||
VendorGuid,
|
||||
VariableData,
|
||||
VariableDataSize
|
||||
);
|
||||
DEBUG ((EFI_D_ERROR, "MeasureBootPolicyVariable - %r\n", Status));
|
||||
|
||||
if (VariableData != NULL) {
|
||||
FreePool (VariableData);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
@ -104,6 +104,20 @@ GLOBAL_VARIABLE_ENTRY mGlobalVariableList2[] = {
|
||||
{L"Key####", VARIABLE_ATTRIBUTE_NV_BS_RT},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
SecureBoot Hook for auth variable update.
|
||||
|
||||
@param[in] VariableName Name of Variable to be found.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SecureBootHook (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid
|
||||
);
|
||||
|
||||
/**
|
||||
Routine used to track statistical information about variable usage.
|
||||
The data is stored in the EFI system table so it can be accessed later.
|
||||
@ -2981,6 +2995,15 @@ Done:
|
||||
InterlockedDecrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState);
|
||||
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
||||
|
||||
if (!AtRuntime ()) {
|
||||
if (!EFI_ERROR (Status)) {
|
||||
SecureBootHook (
|
||||
VariableName,
|
||||
VendorGuid
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
Variable.h
|
||||
AuthService.c
|
||||
AuthService.h
|
||||
Measurement.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
@ -61,6 +62,7 @@
|
||||
BaseCryptLib
|
||||
PlatformSecureLib
|
||||
HobLib
|
||||
TpmMeasurementLib
|
||||
|
||||
[Protocols]
|
||||
gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
@ -50,6 +50,23 @@ UINTN mVariableBufferPayloadSize;
|
||||
extern BOOLEAN mEndOfDxe;
|
||||
extern BOOLEAN mEnableLocking;
|
||||
|
||||
/**
|
||||
SecureBoot Hook for SetVariable.
|
||||
|
||||
@param[in] VariableName Name of Variable to be found.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SecureBootHook (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid
|
||||
)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
This code sets variable in storage blocks (Volatile or Non-Volatile).
|
||||
|
@ -57,6 +57,20 @@ UINTN mVariableBufferPayloadSize;
|
||||
EFI_LOCK mVariableServicesLock;
|
||||
EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock;
|
||||
|
||||
/**
|
||||
SecureBoot Hook for SetVariable.
|
||||
|
||||
@param[in] VariableName Name of Variable to be found.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SecureBootHook (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid
|
||||
);
|
||||
|
||||
/**
|
||||
Acquires lock only at boot time. Simply returns at runtime.
|
||||
|
||||
@ -545,6 +559,15 @@ RuntimeServiceSetVariable (
|
||||
|
||||
Done:
|
||||
ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
|
||||
|
||||
if (!EfiAtRuntime ()) {
|
||||
if (!EFI_ERROR (Status)) {
|
||||
SecureBootHook (
|
||||
VariableName,
|
||||
VendorGuid
|
||||
);
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
[Sources]
|
||||
VariableSmmRuntimeDxe.c
|
||||
Measurement.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
@ -53,6 +54,7 @@
|
||||
DxeServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
PcdLib
|
||||
TpmMeasurementLib
|
||||
|
||||
[Protocols]
|
||||
gEfiVariableWriteArchProtocolGuid ## ALWAYS_PRODUCES
|
||||
@ -64,6 +66,7 @@
|
||||
[Guids]
|
||||
gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event
|
||||
gSmmVariableWriteGuid
|
||||
gEfiImageSecurityDatabaseGuid
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize
|
||||
|
Reference in New Issue
Block a user