| /** @file | |
| This file connects the platform specific functions of | |
| the TCG TPM reference code to the corresponding functions in PlatformTpmLib. | |
| To use TPM reference code as software based TPM, each Platform should | |
| implements TpmPlatformLib. | |
| For the __plat_XXX interface, Please see the: | |
| - https://github.com/TrustedComputingGroup/TPM/tree/main/TPMCmd/Platform/src | |
| - https://github.com/TrustedComputingGroup/TPM/tree/main/TPMCmd/tpm/include/platform_interface | |
| Copyright (c) 2025, Arm Limited. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #pragma once | |
| #include <Uefi/UefiBaseType.h> | |
| // | |
| // ClockRateAdjust uses predefined signal values and encapsulates the platform | |
| // specifics regarding the number of ticks the underlying clock is running at. | |
| // | |
| // The adjustment must be one of these values. A COARSE adjustment is 1%, MEDIUM | |
| // is 0.1%, and FINE is the smallest amount supported by the platform. The | |
| // total (cumulative) adjustment is limited to ~15% total. Attempts to adjust | |
| // the clock further are silently ignored as are any invalid values. These | |
| // values are defined here to insulate them from spec changes and to avoid | |
| // needing visibility to the doc-generated structure headers. | |
| typedef enum { | |
| TpmClockAdjustCoarseSlower = -3, | |
| TpmClockAdjustMediumSlower = -2, | |
| TpmClockAdjustFineSlower = -1, | |
| TpmClockAdjustFineFaster = 1, | |
| TpmClockAdjustMediumFaster = 2, | |
| TpmClockAdjustCoarseFaster = 3 | |
| } PLATFORM_TPM_CLOCK_ADJUST_STEP; | |
| #define PLATFORM_TPM_TYPE_UNKNOWN 0x00 | |
| #define PLATFORM_TPM_TYPE_DISCRETE_CHIP 0x01 | |
| #define PLATFORM_TPM_TYPE_INTEGRATE_SOC 0x02 | |
| #define PLATFORM_TPM_TYPE_FTPM 0x03 | |
| #define PLATFORM_TPM_TYPE_VTPM 0x04 | |
| // ** From EPS.c | |
| /** | |
| _plat__GetEPS() | |
| This function used to generate Endorsement Seed when | |
| first initailization of TPM. | |
| EPS can be generated, for example, as follows: | |
| EPS = SHA-512(TRNG_output || nonce || optional_mixing || DeviceUnique) | |
| Alternatively, EPS can be generated using DRBG_Generate(), | |
| as done in the TCG TPM 2.0 reference implementation. | |
| This function is not expected to fail; however, | |
| if it does have the potential to fail, | |
| the platform should handle the failure appropriately, | |
| for example by disabling TPM functionality or | |
| retrying the manufacturing process. | |
| @param [in] Size Size of endorsement seed | |
| @param [out] EndorsementSeed Endorsement Seed. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibGetEPS ( | |
| IN UINT16 Size, | |
| OUT UINT8 *EndorsementSeed | |
| ); | |
| // ** From Clock.c | |
| /** | |
| _plat__TimerReset() | |
| This function sets current system clock time as t0 for counting TPM time. | |
| This function is called at a power on event to reset the clock. When the clock | |
| is reset, the indication that the clock was stopped is also set. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibTimerReset ( | |
| VOID | |
| ); | |
| /** | |
| _plat__TimerRestart() | |
| This function should be called in order to simulate the restart of the timer | |
| should it be stopped while power is still applied. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibTimerRestart ( | |
| VOID | |
| ); | |
| /** | |
| _plat__RealTime() | |
| This is another, probably futile, attempt to define a portable function | |
| that will return a 64-bit clock value that has mSec resolution. | |
| @return value realtime | |
| **/ | |
| UINT64 | |
| EFIAPI | |
| PlatformTpmLibRealTime ( | |
| VOID | |
| ); | |
| /** | |
| _plat__TimerRead() | |
| This function provides access to the tick timer of the platform. The TPM code | |
| uses this value to drive the TPM Clock. | |
| The tick timer is supposed to run when power is applied to the device. This timer | |
| should not be reset by time events including _TPM_Init. It should only be reset | |
| when TPM power is re-applied. | |
| If the TPM is run in a protected environment, that environment may provide the | |
| tick time to the TPM as long as the time provided by the environment is not | |
| allowed to go backwards. If the time provided by the system can go backwards | |
| during a power discontinuity, then the _plat__Signal_PowerOn should call | |
| _plat__TimerReset(). | |
| @return value timeval | |
| **/ | |
| UINT64 | |
| EFIAPI | |
| PlatformTpmLibTimerRead ( | |
| VOID | |
| ); | |
| /** | |
| _plat__TimerWasReset() | |
| This function is used to interrogate the flag indicating if the tick timer has | |
| been reset. | |
| If the resetFlag parameter is SET, then the flag will be CLEAR before the | |
| function returns. | |
| @return TRUE Timer was reset. | |
| @return FALSE Timer wasn't reset. | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibTimerWasReset ( | |
| VOID | |
| ); | |
| /** | |
| _plat__TimerWasStopped() | |
| This function is used to interrogate the flag indicating if the tick timer has | |
| been stopped. If so, this is typically a reason to roll the nonce. | |
| This function will CLEAR the s_timerStopped flag before returning. This provides | |
| functionality that is similar to status register that is cleared when read. This | |
| is the model used here because it is the one that has the most impact on the TPM | |
| code as the flag can only be accessed by one entity in the TPM. Any other | |
| implementation of the hardware can be made to look like a read-once register. | |
| @return TRUE timer was stopped | |
| @return FALSE timer wasn't stopped | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| PlatformTpmLibTimerWasStopped ( | |
| VOID | |
| ); | |
| /** | |
| _plat__ClockAdjustRate() | |
| Adjust the clock rate. | |
| @param [in] Adjust The adjust number. It could be positive | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibClockAdjustRate ( | |
| IN INT32 Adjust | |
| ); | |
| /** | |
| _plat__GetEntropy() | |
| This function is used to get available hardware entropy. In a hardware | |
| implementation of this function, there would be no call to the system | |
| to get entropy. | |
| @param [out] Entropy output buffer | |
| @param [in] Amount amount reuqested. | |
| @return < 0 Failed to generate entropy | |
| @return >= 0 The returned amount of entropy (bytes) | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibGetEntropy ( | |
| OUT UINT8 *Entropy, | |
| IN UINT32 Amount | |
| ); | |
| // ** From NVMem.c | |
| /** | |
| _plat__NVEnable() | |
| Enable NV memory. | |
| the NV state would be read in, decrypted and integrity checked if needs. | |
| The recovery from an integrity failure depends on where the error occurred. It | |
| it was in the state that is discarded by TPM Reset, then the error is | |
| recoverable if the TPM is reset. Otherwise, the TPM must go into failure mode. | |
| @param [in] PlatParameter Platform parameter to enable NV storage | |
| @param [in] ParamSize Size of PlatParameter | |
| @return 0 if success | |
| @return > 0 if receive recoverable error | |
| @return < 0 if unrecoverable error | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibNVEnable ( | |
| IN VOID *PlatParameter, | |
| IN UINTN ParamSize | |
| ); | |
| /** | |
| _plat__NVDisable() | |
| Disable NV memory. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibNVDisable ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetNvReadyState() | |
| Check if NV is available. | |
| @return 0 NV is available | |
| @return 1 NV is not available due to write failure | |
| @return 2 NV is not available due to rate limit | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibGetNvReadyState ( | |
| VOID | |
| ); | |
| /** | |
| _plat__NvMemoryRead() | |
| Read a chunk of NV memory. | |
| @param [in] StartOffset Read start offset | |
| @param [in] Size Size to read | |
| @param [out] Data Data buffer | |
| @return 1 Success to read | |
| @return 0 Failed to read | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibNvMemoryRead ( | |
| IN UINT32 StartOffset, | |
| IN UINT32 Size, | |
| OUT VOID *Data | |
| ); | |
| /** | |
| _plat__NvGetChangedStatus() | |
| This function checks to see if the NV is different from the test value | |
| so that NV will not be written if it has not changed. | |
| @param [in] StartOffset Start offset to compare | |
| @param [in] Size Size for compare | |
| @param [in] Data Data to be compared | |
| @return NV_HAS_CHANGED(1) the NV location is different from the test value | |
| @return NV_IS_SAME(0) the NV location is the same as the test value | |
| @return NV_INVALID_LOCATION(-1) the NV location is invalid; also triggers failure mode | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibNvGetChangedStatus ( | |
| IN UINT32 StartOffset, | |
| IN UINT32 Size, | |
| IN VOID *Data | |
| ); | |
| /** | |
| _plat__NvMemoryWrite() | |
| This function is used to update NV memory. The "write" is to a memory copy of | |
| NV. At the end of the current command, any changes are written to | |
| the actual NV memory. | |
| NOTE: A useful optimization would be for this code to compare the current | |
| contents of NV with the local copy and note the blocks that have changed. Then | |
| only write those blocks when _plat__NvCommit() is called. | |
| @param [in] StartOffset Start Offset to write | |
| @param [in] Size Size to wrrite | |
| @param [in] Data Data | |
| @return 0 Failed to write | |
| @return 1 Success to write | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibNvMemoryWrite ( | |
| IN UINT32 StartOffset, | |
| IN UINT32 Size, | |
| IN VOID *Data | |
| ); | |
| /** | |
| _plat__NvMemoryClear() | |
| Function is used to set a range of NV memory bytes to an implementation-dependent | |
| value. The value represents the erase state of the memory. | |
| @param [in] StartOffset Start offset to clear | |
| @param [in] SIze Size to be clear | |
| @return 0 Failed to clear | |
| @return 1 Success | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibNvMemoryClear ( | |
| IN UINT32 StartOffset, | |
| IN UINT32 Size | |
| ); | |
| /** | |
| _plat__NvMemoryMove() | |
| Function: Move a chunk of NV memory from source to destination | |
| This function should ensure that if there overlap, the original data is | |
| copied before it is written. | |
| @param [in] SourceOffset Source offset to move | |
| @param [in] DestOffset Destination offset to move | |
| @param [in] Size Size to be moved | |
| @return 0 Failed to move | |
| @return 1 Success | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibNvMemoryMove ( | |
| IN UINT32 SourceOffset, | |
| IN UINT32 DestOffset, | |
| IN UINT32 Size | |
| ); | |
| /** | |
| _plat__NvCommit() | |
| This function writes the local copy of NV to NV for permanent store. | |
| It will write TPM_NV_MEMORY_SIZE bytes to NV. | |
| @return 0 NV write success | |
| @return non-0 NV write fail | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibNvCommit ( | |
| VOID | |
| ); | |
| /** | |
| _plat__SetNvAvail() | |
| Set the current NV state to available. | |
| This function is for testing purpose only. | |
| It is not part of the platform NV logic | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibSetNvAvail ( | |
| VOID | |
| ); | |
| /** | |
| _plat__ClearNvAvail() | |
| Set the current NV state to unavailable. | |
| This function is for testing purpose only. | |
| It is not part of the platform NV logic. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibClearNvAvail ( | |
| VOID | |
| ); | |
| /** | |
| _plat__NVNeedsManufacture() | |
| This function checks whether TPM's NV state needs to be manufactured. | |
| @return TRUE TPM's NV storage should be manufactured | |
| @return FALSE TPM's NV storage is already manufactured | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| PlatformTpmLibNVNeedsManufacture ( | |
| VOID | |
| ); | |
| // ** From Unique.c | |
| /** | |
| _plat__GetUnique() | |
| This function is used to access the platform-specific unique value. | |
| This function places the unique value in the provided Buffer ('b') | |
| and returns the number of bytes transferred. The function will not | |
| copy more data than 'Size'. | |
| NOTE: If a platform unique value has unequal distribution of uniqueness | |
| and 'Size' is smaller than the size of the unique value, the 'Size' | |
| portion with the most uniqueness should be returned. | |
| @param [in] Which if == 0, Copy unique value from start | |
| otherwise, copy from end | |
| @param [in] Size Size of Buffer | |
| @param [out] Buffer Output Buffer | |
| @return Size of unique value. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| PlatformTpmLibGetUnique ( | |
| IN UINT32 Which, | |
| IN UINT32 Size, | |
| OUT UINT8 *Buffer | |
| ); | |
| /** | |
| _plat__GetManufacturerCapabilityCode() | |
| return the 4 character Manufacturer Capability code. | |
| This should come from the platform library since | |
| that is provided by the manufacturer. | |
| @return Manufacturer capability Code. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| PlatformTpmLibGetManufacturerCapabilityCode ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetVendorCapabilityCode() | |
| return the 4 character VendorStrings for Capabilities. | |
| Index is ONE-BASED, and may be in the range [1,4] inclusive. | |
| Any other index returns all zeros. The return value will be interpreted | |
| as an array of 4 ASCII characters (with no null terminator). | |
| @param[in] Index index | |
| @return Vendor specific capability code. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| PlatformTpmLibGetVendorCapabilityCode ( | |
| IN INT32 Index | |
| ); | |
| /** | |
| _plat__GetTpmFirmwareVersionHigh() | |
| return the most-significant 32-bits of the TPM Firmware Version | |
| @return High 32-bits of TPM Firmware Version. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| PlatformTpmLibGetTpmFirmwareVersionHigh ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetTpmFirmwareVersionLow() | |
| return the least-significant 32-bits of the TPM Firmware Version | |
| @return Low 32-bits of TPM Firmware Version. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| PlatformTpmLibGetTpmFirmwareVersionLow ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetTpmFirmwareSvn() | |
| return the TPM Firmware current SVN. | |
| @return current SVN. | |
| **/ | |
| UINT16 | |
| EFIAPI | |
| PlatformTpmLibGetTpmFirmwareSvn ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetTpmFirmwareMaxSvn() | |
| return the TPM Firmware maximum SVN. | |
| @return Maximum SVN. | |
| **/ | |
| UINT16 | |
| EFIAPI | |
| PlatformTpmLibGetTpmFirmwareMaxSvn ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetTpmFirmwareSvnSecret() | |
| return the TPM Firmware SVN Secret value associated with SVN | |
| @param[in] Svn Svn | |
| @param[in] SecretBufferSize Secret Buffer Size | |
| @param[out] SecretBuffer Secret Buffer | |
| @param[out] SecretSize Secret Svn Size | |
| @return 0 Success | |
| @return < 0 Error | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibGetTpmFirmwareSvnSecret ( | |
| IN UINT16 Svn, | |
| IN UINT16 SecretBufferSize, | |
| OUT UINT8 *SecretBuffer, | |
| OUT UINT16 *SecretSize | |
| ); | |
| /** | |
| _plat__GetTpmFirmwareSecret() | |
| return the TPM Firmware Secret value associated with SVN | |
| @param[in] SecretBufferSize Secret Buffer Size | |
| @param[out] SecretBuffer Secret Buffer | |
| @param[out] SecretSize Secret Svn Size | |
| @return 0 Success | |
| @return < 0 Error | |
| **/ | |
| INT32 | |
| EFIAPI | |
| PlatformTpmLibGetTpmFirmwareSecret ( | |
| IN UINT16 SecretBufferSize, | |
| OUT UINT8 *SecretBuffer, | |
| OUT UINT16 *SecretSize | |
| ); | |
| /** | |
| _plat__GetVendorTpmType() | |
| return the Platform TPM type. | |
| @return TPM type. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| PlatformTpmLibGetVendorTpmType ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetPlatformManufactureData | |
| This function allows the platform to provide a small amount of data to be | |
| stored as part of the TPM's PERSISTENT_DATA structure during manufacture. | |
| Of course the platform can store data separately as well, | |
| but this allows a simple platform implementation to store | |
| a few bytes of data without implementing a multi-layer storage system. | |
| This function is called on manufacture and CLEAR. | |
| The buffer will contain the last value provided | |
| to the Core library. | |
| @param[out] PlatformPersistentData Platform data. | |
| @param[in] Size Size of PlatformPersistentData. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibGetPlatformManufactureData ( | |
| UINT8 *PlatformPersistentData, | |
| UINT32 Size | |
| ); | |
| /** | |
| _plat_internal_resetFailureData() | |
| Reset platform specific failure data. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibInternalResetFailureData ( | |
| VOID | |
| ); | |
| /** | |
| _plat__InFailureMode() | |
| Check whether platform is in the failure mode. | |
| @return whether TPM is in failure mode or not | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| PlatformTpmLibInFailureMode ( | |
| VOID | |
| ); | |
| /** | |
| _plat__Fail() | |
| This is the platform depended failure exit for the TPM. | |
| @param[in] Function Function name where failure happens. | |
| @param[in] Line line number where failure happens. | |
| @param[in] LocationCode Location code where failure happens. | |
| @param[in] FailureCode Fail reson. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformTpmLibFail ( | |
| IN CONST CHAR8 *Function, | |
| IN INT32 Line, | |
| IN UINT64 LocationCode, | |
| IN INT32 FailureCode | |
| ); | |
| /** | |
| _plat__GetFailureCode() | |
| Get last failure code. | |
| @return Last failure code. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| PlatformTpmLibGetFailureCode ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetFailureLocation() | |
| Get last failure location. | |
| @return Last failure location code. | |
| **/ | |
| UINT64 | |
| EFIAPI | |
| PlatformTpmLibGetFailureLocation ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetFailureFunctionName() | |
| Get last function name where failed. | |
| @return Last function name where failed. | |
| **/ | |
| CONST CHAR8 * | |
| EFIAPI | |
| PlatformTpmLibGetFailureFunctionName ( | |
| VOID | |
| ); | |
| /** | |
| _plat__GetFailureLine() | |
| Get last failure line. | |
| @return Last line number where failed. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| PlatformTpmLibGetFailureLine ( | |
| VOID | |
| ); | |
| /** | |
| This function is called in TpmLibConstructor() to | |
| initialise PlatformTpmLib once. | |
| @return EFI_SUCCESS Success | |
| @return Others Errors | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| PlatformTpmLibInit ( | |
| VOID | |
| ); |