123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /********************************************************************************/
- /* */
- /* ACT Command Support */
- /* Written by Ken Goldman */
- /* IBM Thomas J. Watson Research Center */
- /* $Id: Object_spt.c 1490 2019-07-26 21:13:22Z kgoldman $ */
- /* */
- /* 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, 2016 - 2020 */
- /* */
- /********************************************************************************/
- /* 7.8 ACT Support (ACT_spt.c) */
- /* 7.8.1 Introduction */
- /* This code implements the ACT update code. It does not use a mutex. This code uses a platform
- service (_plat__ACT_UpdateCounter()) that returns false if the update is not accepted. If this
- occurs, then TPM_RC_RETRY should be sent to the caller so that they can retry the operation
- later. The implementation of this is platform dependent but the reference uses a simple flag to
- indicate that an update is pending and the only process that can clear that flag is the process
- that does the actual update. */
- /* 7.8.2 Includes */
- #include "Tpm.h"
- #include "ACT_spt_fp.h"
- #include "Platform_fp.h"
- #include "PlatformACT_fp.h" /* added kgold */
- /* 7.8.3 Functions */
- /* 7.8.3.1 _ActResume() */
- /* This function does the resume processing for an ACT. It updates the saved count and turns
- signaling back on if necessary. */
- static void
- _ActResume(
- UINT32 act, //IN: the act number
- ACT_STATE *actData //IN: pointer to the saved ACT data
- )
- {
- // If the act was non-zero, then restore the counter value.
- if(actData->remaining > 0)
- _plat__ACT_UpdateCounter(act, actData->remaining);
- // if the counter was zero and the ACT signaling, enable the signaling.
- else if(go.signaledACT & (1 << act))
- _plat__ACT_SetSignaled(act, TRUE);
- }
- /* 7.8.3.2 ActStartup() */
- /* This function is called by TPM2_Startup() to initialize the ACT counter values. */
- BOOL
- ActStartup(
- STARTUP_TYPE type
- )
- {
- // Reset all the ACT hardware
- _plat__ACT_Initialize();
- // If this not a cold start, copy all the current 'signaled' settings to
- // 'preservedSignaled'.
- if (g_powerWasLost)
- go.preservedSignaled = 0;
- else
- go.preservedSignaled |= go.signaledACT;
-
- // For TPM_RESET or TPM_RESTART, the ACTs will all be disabled and the output
- // de-asserted.
- if(type != SU_RESUME)
- {
- go.signaledACT = 0;
- #define CLEAR_ACT_POLICY(N) \
- go.ACT_##N.hashAlg = TPM_ALG_NULL; \
- go.ACT_##N.authPolicy.b.size = 0;
-
- FOR_EACH_ACT(CLEAR_ACT_POLICY)
-
- }
- else
- {
- // Resume each of the implemented ACT
- #define RESUME_ACT(N) _ActResume(0x##N, &go.ACT_##N);
-
- FOR_EACH_ACT(RESUME_ACT)
- }
- // set no ACT updated since last startup. This is to enable the halving of the
- // timeout value
- s_ActUpdated = 0;
- _plat__ACT_EnableTicks(TRUE);
- return TRUE;
- }
- /* 7.8.3.3 _ActSaveState() */
- /* Get the counter state and the signaled state for an ACT. If the ACT has not been updated since
- the last time it was saved, then divide the count by 2. */
- static void
- _ActSaveState(
- UINT32 act,
- P_ACT_STATE actData
- )
- {
- actData->remaining = _plat__ACT_GetRemaining(act);
- // If the ACT hasn't been updated since the last startup, then it should be
- // be halved.
- if((s_ActUpdated & (1 << act)) == 0)
- {
- // Don't halve if the count is set to max or if halving would make it zero
- if((actData->remaining != UINT32_MAX) && (actData->remaining > 1))
- actData->remaining /= 2;
- }
- if(_plat__ACT_GetSignaled(act))
- go.signaledACT |= (1 << act);
- }
- /* 7.8.3.4 ActGetSignaled() */
- /* This function returns the state of the signaled flag associated with an ACT. */
- BOOL
- ActGetSignaled(
- TPM_RH actHandle
- )
- {
- UINT32 act = actHandle - TPM_RH_ACT_0;
- //
- return _plat__ACT_GetSignaled(act);
- }
- /* 7.8.3.5 ActShutdown() */
- /* This function saves the current state of the counters */
- BOOL
- ActShutdown(
- TPM_SU state //IN: the type of the shutdown.
- )
- {
- // if this is not shutdown state, then the only type of startup is TPM_RESTART
- // so the timer values will be cleared. If this is shutdown state, get the current
- // countdown and signaled values. Plus, if the counter has not been updated
- // since the last restart, divide the time by 2 so that there is no attack on the
- // countdown by saving the countdown state early and then not using the TPM.
- if(state == TPM_SU_STATE)
- {
- // This will be populated as each of the ACT is queried
- go.signaledACT = 0;
- // Get the current count and the signaled state
- #define SAVE_ACT_STATE(N) _ActSaveState(0x##N, &go.ACT_##N);
-
- FOR_EACH_ACT(SAVE_ACT_STATE);
- }
- return TRUE;
- }
- /* 7.8.3.6 ActIsImplemented() */
- /* This function determines if an ACT is implemented in both the TPM and the platform code. */
- BOOL
- ActIsImplemented(
- UINT32 act
- )
- {
- #define CASE_ACT_
- // This switch accounts for the TPM implemented values.
- switch(act)
- {
- FOR_EACH_ACT(CASE_ACT_NUMBER)
- // This ensures that the platorm implemented the values implemented by
- // the TPM
- return _plat__ACT_GetImplemented(act);
- default:
- break;
- }
- return FALSE;
- }
- /* 7.8.3.7 ActCounterUpdate() */
- /* This function updates the ACT counter. If the counter already has a pending update, it returns
- TPM_RC_RETRY so that the update can be tried again later. */
- TPM_RC
- ActCounterUpdate(
- TPM_RH handle, //IN: the handle of the act
- UINT32 newValue //IN: the value to set in the ACT
- )
- {
- UINT32 act;
- TPM_RC result;
- //
- act = handle - TPM_RH_ACT_0;
- // This should never fail, but...
- if(!_plat__ACT_GetImplemented(act))
- result = TPM_RC_VALUE;
- else
- {
- // Will need to clear orderly so fail if we are orderly and NV is not available
- if(NV_IS_ORDERLY)
- RETURN_IF_NV_IS_NOT_AVAILABLE;
- // if the attempt to update the counter fails, it means that there is an
- // update pending so wait until it has occurred and then do an update.
- if(!_plat__ACT_UpdateCounter(act, newValue))
- result = TPM_RC_RETRY;
- else
- {
- // Indicate that the ACT has been updated since last TPM2_Startup().
- s_ActUpdated |= (UINT16)(1 << act);
- // Clear the preservedSignaled attribute.
- go.preservedSignaled &= ~((UINT16)(1 << act));
-
- // Need to clear the orderly flag
- g_clearOrderly = TRUE;
-
- result = TPM_RC_SUCCESS;
- }
- }
- return result;
- }
- /* 7.8.3.8 ActGetCapabilityData() */
- /* This function returns the list of ACT data */
- /* Return Value Meaning */
- /* YES if more ACT data is available */
- /* NO if no more ACT data to */
- TPMI_YES_NO
- ActGetCapabilityData(
- TPM_HANDLE actHandle, // IN: the handle for the starting ACT
- UINT32 maxCount, // IN: maximum allowed return values
- TPML_ACT_DATA *actList // OUT: ACT data list
- )
- {
- // Initialize output property list
- actList->count = 0;
-
- // Make sure that the starting handle value is in range (again)
- if((actHandle < TPM_RH_ACT_0) || (actHandle > TPM_RH_ACT_F))
- return FALSE;
- // The maximum count of curves we may return is MAX_ECC_CURVES
- if(maxCount > MAX_ACT_DATA)
- maxCount = MAX_ACT_DATA;
- // Scan the ACT data from the starting ACT
- for(; actHandle <= TPM_RH_ACT_F; actHandle++)
- {
- UINT32 act = actHandle - TPM_RH_ACT_0;
- if(actList->count < maxCount)
- {
- if(ActIsImplemented(act))
- {
- TPMS_ACT_DATA *actData = &actList->actData[actList->count];
- //
- memset(&actData->attributes, 0, sizeof(actData->attributes));
- actData->handle = actHandle;
- actData->timeout = _plat__ACT_GetRemaining(act);
- if (_plat__ACT_GetSignaled(act))
- SET_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
- else
- CLEAR_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
- actList->count++;
- }
- }
- else
- {
- if(_plat__ACT_GetImplemented(act))
- return YES;
- }
- }
- // If we get here, either all of the ACT values were put in the list, or the list
- // was filled and there are no more ACT values to return
- return NO;
- }
|