/********************************************************************************/
/*										*/
/*		NV read and write access methods     				*/
/*			     Written by Ken Goldman				*/
/*		       IBM Thomas J. Watson Research Center			*/
/*										*/
/*  Licenses and Notices							*/
/*										*/
/*  1. Copyright Licenses:							*/
/*										*/
/*  - Trusted Computing Group (TCG) grants to the user of the source code in	*/
/*    this specification (the "Source Code") a worldwide, irrevocable, 		*/
/*    nonexclusive, royalty free, copyright license to reproduce, create 	*/
/*    derivative works, distribute, display and perform the Source Code and	*/
/*    derivative works thereof, and to grant others the rights granted herein.	*/
/*										*/
/*  - The TCG grants to the user of the other parts of the specification 	*/
/*    (other than the Source Code) the rights to reproduce, distribute, 	*/
/*    display, and perform the specification solely for the purpose of 		*/
/*    developing products based on such documents.				*/
/*										*/
/*  2. Source Code Distribution Conditions:					*/
/*										*/
/*  - Redistributions of Source Code must retain the above copyright licenses, 	*/
/*    this list of conditions and the following disclaimers.			*/
/*										*/
/*  - Redistributions in binary form must reproduce the above copyright 	*/
/*    licenses, this list of conditions	and the following disclaimers in the 	*/
/*    documentation and/or other materials provided with the distribution.	*/
/*										*/
/*  3. Disclaimers:								*/
/*										*/
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF	*/
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH	*/
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES)	*/
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.		*/
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for 		*/
/*  information on specification licensing rights available through TCG 	*/
/*  membership agreements.							*/
/*										*/
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED 	*/
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR 	*/
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR 		*/
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY 		*/
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.		*/
/*										*/
/*  - Without limitation, TCG and its members and licensors disclaim all 	*/
/*    liability, including liability for infringement of any proprietary 	*/
/*    rights, relating to use of information in this specification and to the	*/
/*    implementation of this specification, and TCG disclaims all liability for	*/
/*    cost of procurement of substitute goods or services, lost profits, loss 	*/
/*    of use, loss of data or any incidental, consequential, direct, indirect, 	*/
/*    or special damages, whether under contract, tort, warranty or otherwise, 	*/
/*    arising in any way out of use or reliance upon this specification or any 	*/
/*    information herein.							*/
/*										*/
/*  (c) Copyright IBM Corp. and others, 2023					*/
/*										*/
/********************************************************************************/

// This file represents the functional interface that all platform libraries must
// provide because they are called by the Core TPM library.
#ifndef _TPM_TO_PLATFORM_INTERFACE_H_
#define _TPM_TO_PLATFORM_INTERFACE_H_

// need to read configuration for ACT_SUPPORT flag check below
#include "TpmBuildSwitches.h"
#include "TpmProfile.h"
#include <stddef.h>

//** From Cancel.c

//***_plat__IsCanceled()
// Check if the cancel flag is set
//  Return Type: int
//      TRUE(1)         if cancel flag is set
//      FALSE(0)        if cancel flag is not set
LIB_EXPORT int _plat__IsCanceled(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().
LIB_EXPORT uint64_t _plat__TimerRead(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.
LIB_EXPORT int _plat__TimerWasReset(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.
LIB_EXPORT int _plat__TimerWasStopped(void);

//***_plat__ClockRateAdjust()
// Adjust the clock rate
// the old function name is ClockAdjustRate, and took a value which was an absolute
// number of ticks.
//
// 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 _plat__ClockAdjustStep
    {
	PLAT_TPM_CLOCK_ADJUST_COARSE_SLOWER = -3,
	PLAT_TPM_CLOCK_ADJUST_MEDIUM_SLOWER = -2,
	PLAT_TPM_CLOCK_ADJUST_FINE_SLOWER   = -1,
	PLAT_TPM_CLOCK_ADJUST_FINE_FASTER   = 1,
	PLAT_TPM_CLOCK_ADJUST_MEDIUM_FASTER = 2,
	PLAT_TPM_CLOCK_ADJUST_COARSE_FASTER = 3
    } _plat__ClockAdjustStep;
LIB_EXPORT void _plat__ClockRateAdjust(_plat__ClockAdjustStep adjustment);

					// libtpms: added begin
#include <time.h>
void ClockAdjustPostResume(UINT64 backthen, BOOL timesAreRealtime);
uint64_t ClockGetTime(clockid_t clk_id);
					// libtpms: added end

//** From DebugHelpers.c
	
#if CERTIFYX509_DEBUG

#if 0					// libtpms: added
//*** DebugFileInit()
// This function opens the file used to hold the debug data.
//  Return Type: int
//   0        success
//  != 0          error
int DebugFileInit(void);

//*** DebugDumpBuffer()
void DebugDumpBuffer(int size, unsigned char* buf, const char* identifier);
#endif					// libtpms: added
#endif  // CERTIFYX509_DEBUG

	//** From Entropy.c

	//*** _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.
	//  Return Type: int32_t
	//  < 0        hardware failure of the entropy generator, this is sticky
	// >= 0        the returned amount of entropy (bytes)
	//
LIB_EXPORT int32_t _plat__GetEntropy(unsigned char* entropy,  // output buffer
				     uint32_t       amount    // amount requested
				     );

//** From LocalityPlat.c

//***_plat__LocalityGet()
// Get the most recent command locality in locality value form.
// This is an integer value for locality and not a locality structure
// The locality can be 0-4 or 32-255. 5-31 is not allowed.
LIB_EXPORT unsigned char _plat__LocalityGet(void);

//***_plat__NVEnable()
// Enable NV memory.
//
// This version just pulls in data from a file. In a real TPM, with NV on chip,
// this function would verify the integrity of the saved context. If the NV
// memory was not on chip but was in something like RPMB, the NV state would be
// read in, decrypted and integrity checked.
//
// 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.
//
//  Return Type: int
//      0           if success
//      >0          if recoverable error
//      <0          if unrecoverable error
LIB_EXPORT int _plat__NVEnable(
			       void*  platParameter,  // platform specific parameter
			       size_t paramSize       // size of parameter. If size == 0, then
			       // parameter is a sizeof(void*) scalar and should
			       // be cast to an integer (intptr_t), not dereferenced.
			       );

					// libtpms: added begin
LIB_EXPORT int
_plat__NVEnable_NVChipFile(
		void            *platParameter  // IN: platform specific parameters
		);
					// libtpms: added end

//***_plat__GetNvReadyState()
// Check if NV is available
//  Return Type: int
//      0               NV is available
//      1               NV is not available due to write failure
//      2               NV is not available due to rate limit
#define NV_READY        0
#define NV_WRITEFAILURE 1
#define NV_RATE_LIMIT   2
LIB_EXPORT int _plat__GetNvReadyState(void);

//***_plat__NvMemoryRead()
// Function: Read a chunk of NV memory
//  Return Type: int
//      TRUE(1)         offset and size is within available NV size
//      FALSE(0)        otherwise; also trigger failure mode
LIB_EXPORT int _plat__NvMemoryRead(unsigned int startOffset,  // IN: read start
				   unsigned int size,  // IN: size of bytes to read
				   void*        data   // OUT: data buffer
				   );

//*** _plat__NvGetChangedStatus()
// This function checks to see if the NV is different from the test value. This is
// so that NV will not be written if it has not changed.
//  Return Type: int
//      NV_HAS_CHANGED(1)       the NV location is different from the test value
//      NV_IS_SAME(0)           the NV location is the same as the test value
//      NV_INVALID_LOCATION(-1) the NV location is invalid; also triggers failure mode
#define NV_HAS_CHANGED      (1)
#define NV_IS_SAME          (0)
#define NV_INVALID_LOCATION (-1)
LIB_EXPORT int _plat__NvGetChangedStatus(
					 unsigned int startOffset,  // IN: read start
					 unsigned int size,         // IN: size of bytes to read
					 void*        data          // IN: data buffer
					 );

//***_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.
//  Return Type: int
//      TRUE(1)         offset and size is within available NV size
//      FALSE(0)        otherwise; also trigger failure mode
LIB_EXPORT int _plat__NvMemoryWrite(unsigned int startOffset,  // IN: write start
				    unsigned int size,  // IN: size of bytes to write
				    void*        data   // OUT: data buffer
				    );

//***_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.
LIB_EXPORT int _plat__NvMemoryClear(unsigned int startOffset,  // IN: clear start
				    unsigned int size  // IN: number of bytes to clear
				    );

//***_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
LIB_EXPORT int _plat__NvMemoryMove(unsigned int sourceOffset,  // IN: source offset
				   unsigned int destOffset,  // IN: destination offset
				   unsigned int size  // IN: size of data being moved
				   );

//***_plat__NvCommit()
// This function writes the local copy of NV to NV for permanent store. It will write
// NV_MEMORY_SIZE bytes to NV. If a file is use, the entire file is written.
//  Return Type: int
//  0       NV write success
//  non-0   NV write fail
LIB_EXPORT int _plat__NvCommit(void);

//***_plat__TearDown
// notify platform that TPM_TearDown was called so platform can cleanup or
// zeroize anything in the Platform.  This should zeroize NV as well.
#if 0					// libtpms: added begin
LIB_EXPORT void _plat__TearDown(void);
#endif					// libtpms: added end

//** From PlatformACT.c

#if ACT_SUPPORT
//*** _plat__ACT_GetImplemented()
// This function tests to see if an ACT is implemented. It is a belt and suspenders
// function because the TPM should not be calling to manipulate an ACT that is not
// implemented. However, this could help the simulator code which doesn't necessarily
// know if an ACT is implemented or not.
LIB_EXPORT int _plat__ACT_GetImplemented(uint32_t act);

//*** _plat__ACT_GetRemaining()
// This function returns the remaining time. If an update is pending, 'newValue' is
// returned. Otherwise, the current counter value is returned. Note that since the
// timers keep running, the returned value can get stale immediately. The actual count
// value will be no greater than the returned value.
LIB_EXPORT uint32_t _plat__ACT_GetRemaining(uint32_t act  //IN: the ACT selector
					    );

//*** _plat__ACT_GetSignaled()
LIB_EXPORT int _plat__ACT_GetSignaled(uint32_t act  //IN: number of ACT to check
				      );

//*** _plat__ACT_SetSignaled()
LIB_EXPORT void _plat__ACT_SetSignaled(uint32_t act, int on);

//*** _plat__ACT_UpdateCounter()
// This function is used to write the newValue for the counter. If an update is
// pending, then no update occurs and the function returns FALSE. If 'setSignaled'
// is TRUE, then the ACT signaled state is SET and if 'newValue' is 0, nothing
// is posted.
LIB_EXPORT int _plat__ACT_UpdateCounter(uint32_t act,      // IN: ACT to update
					uint32_t newValue  // IN: the value to post
					);

//***_plat__ACT_EnableTicks()
// This enables and disables the processing of the once-per-second ticks. This should
// be turned off ('enable' = FALSE) by _TPM_Init and turned on ('enable' = TRUE) by
// TPM2_Startup() after all the initializations have completed.
LIB_EXPORT void _plat__ACT_EnableTicks(int enable);

//***_plat__ACT_Initialize()
// This function initializes the ACT hardware and data structures
LIB_EXPORT int _plat__ACT_Initialize(void);

#endif  // ACT_SUPPORT

	//** From PowerPlat.c

	//*** _plat__WasPowerLost()
	// Test whether power was lost before a _TPM_Init.
	//
	// This function will clear the "hardware" indication of power loss before return.
	// This means that there can only be one spot in the TPM code where this value
	// gets read. This method is used here as it is the most difficult to manage in the
	// TPM code and, if the hardware actually works this way, it is hard to make it
	// look like anything else. So, the burden is placed on the TPM code rather than the
	// platform code
	//  Return Type: int
	//      TRUE(1)         power was lost
	//      FALSE(0)        power was not lost
LIB_EXPORT int _plat__WasPowerLost(void);

//** From PPPlat.c

//***_plat__PhysicalPresenceAsserted()
// Check if physical presence is signaled
//  Return Type: int
//      TRUE(1)         if physical presence is signaled
//      FALSE(0)        if physical presence is not signaled
LIB_EXPORT int _plat__PhysicalPresenceAsserted(void);

//***_plat__Fail()
// This is the platform depended failure exit for the TPM.
LIB_EXPORT NORETURN void _plat__Fail(void);

//** From Unique.c

#if VENDOR_PERMANENT_AUTH_ENABLED == YES
//** _plat__GetUnique()
// This function is used to access the platform-specific unique values.
// 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 'bSize'.
// zero indicates value does not exist or an error occurred.
//
// 'which' indicates the unique value to return:
// 0 = RESERVED, do not use
// 1 = the VENDOR_PERMANENT_AUTH_HANDLE authorization value for this device
LIB_EXPORT uint32_t _plat__GetUnique(uint32_t       which,
				     uint32_t       bSize,  // size of the buffer
				     unsigned char* b       // output buffer
				     );
#endif

//** _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.
LIB_EXPORT void _plat__GetPlatformManufactureData(uint8_t* pPlatformPersistentData,
						  uint32_t bufferSize);

// return the 4 character Manufacturer Capability code.  This
// should come from the platform library since that is provided by the manufacturer
LIB_EXPORT uint32_t _plat__GetManufacturerCapabilityCode(void);

// 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)
LIB_EXPORT uint32_t _plat__GetVendorCapabilityCode(int index);

// return the most-significant 32-bits of the TPM Firmware Version reported by
// getCapability.
LIB_EXPORT uint32_t _plat__GetTpmFirmwareVersionHigh(void);

// return the least-significant 32-bits of the TPM Firmware Version reported by
// getCapability.
LIB_EXPORT uint32_t _plat__GetTpmFirmwareVersionLow(void);

// return the TPM Firmware's current SVN.
LIB_EXPORT uint16_t _plat__GetTpmFirmwareSvn(void);

// return the maximum value that the TPM Firmware SVN may take.
LIB_EXPORT uint16_t _plat__GetTpmFirmwareMaxSvn(void);

#if SVN_LIMITED_SUPPORT
//***_plat__GetTpmFirmwareSvnSecret()
// Function: Obtain a Firmware SVN Secret bound to the given SVN. Fails if the
// given SVN is greater than the firmware's current SVN.
// size must equal PRIMARY_SEED_SIZE.
// Return Type: int
//  0           success
//  != 0        error
LIB_EXPORT int _plat__GetTpmFirmwareSvnSecret(
					      uint16_t  svn,              // IN: specified SVN
					      uint16_t  secret_buf_size,  // IN: size of secret buffer
					      uint8_t*  secret_buf,       // OUT: secret buffer
					      uint16_t* secret_size       // OUT: secret buffer
					      );
#endif  // SVN_LIMITED_SUPPORT

#if FW_LIMITED_SUPPORT
//***_plat__GetTpmFirmwareSecret()
// Function: Obtain a Firmware Secret bound to the current firmware image.
// Return Type: int
//  0           success
//  != 0        error
LIB_EXPORT int _plat__GetTpmFirmwareSecret(
					   uint16_t  secret_buf_size,  // IN: size of secret buffer
					   uint8_t*  secret_buf,       // OUT: secret buffer
					   uint16_t* secret_size       // OUT: secret buffer
					   );
#endif  // FW_LIMITED_SUPPORT

	// return the TPM Type returned by TPM_PT_VENDOR_TPM_TYPE
LIB_EXPORT uint32_t _plat__GetTpmType(void);

// platform PCR initialization functions
#include "platform_pcr_fp.h"

#endif  // _TPM_TO_PLATFORM_INTERFACE_H_
