From 2e6d3f2902edb73399d5a64eabaa757133ae9dcf Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Fri, 8 Aug 2025 06:24:12 -0400 Subject: [PATCH] Sync: Introduce platform functions for accessing NV indices Signed-off-by: Stefan Berger --- src/Makefile.am | 5 ++ src/tpm2/Entity.c | 71 +++++++++++++++++--- src/tpm2/NVCommands.c | 98 ---------------------------- src/tpm2/NVVirtual.c | 70 ++++++++++++++++++++ src/tpm2/NV_Read.c | 71 ++++++++++++++++++++ src/tpm2/NV_ReadPublic.c | 42 ++++++++++++ src/tpm2/NV_ReadPublic2.c | 48 ++++++++++++++ src/tpm2/NvDynamic.c | 49 ++++++++++++-- src/tpm2/NvDynamic_fp.h | 64 +----------------- src/tpm2/SessionProcess.c | 49 ++++++++++++-- src/tpm2/platform_virtual_nv_fp.h | 50 ++++++++++++++ src/tpm2/tpm_to_platform_interface.h | 3 + 12 files changed, 440 insertions(+), 180 deletions(-) create mode 100644 src/tpm2/NVVirtual.c create mode 100644 src/tpm2/NV_Read.c create mode 100644 src/tpm2/NV_ReadPublic.c create mode 100644 src/tpm2/NV_ReadPublic2.c create mode 100644 src/tpm2/platform_virtual_nv_fp.h diff --git a/src/Makefile.am b/src/Makefile.am index 085555ee..2c64640e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -248,6 +248,10 @@ libtpms_tpm2_la_SOURCES = \ tpm2/NvDynamic.c \ tpm2/NVMem.c \ tpm2/NvReserved.c \ + tpm2/NVVirtual.c \ + tpm2/NV_Read.c \ + tpm2/NV_ReadPublic.c \ + tpm2/NV_ReadPublic2.c \ tpm2/NV_spt.c \ tpm2/Object.c \ tpm2/ObjectChangeAuth.c \ @@ -485,6 +489,7 @@ noinst_HEADERS += \ tpm2/PlatformInternal.h \ tpm2/platform_failure_mode_fp.h \ tpm2/platform_init_fp.h \ + tpm2/platform_virtual_nv_fp.h \ tpm2/platform_public_interface.h \ tpm2/platform_pcr_fp.h \ tpm2/platform_to_tpm_interface.h \ diff --git a/src/tpm2/Entity.c b/src/tpm2/Entity.c index e0660692..bdc05843 100644 --- a/src/tpm2/Entity.c +++ b/src/tpm2/Entity.c @@ -8,6 +8,7 @@ //** Includes #include "Tpm.h" +#include "platform_virtual_nv_fp.h" //** Functions //*** EntityGetLoadStatus() @@ -116,10 +117,14 @@ EntityGetLoadStatus(COMMAND* command // IN/OUT: command parsing structure result = TPM_RC_REFERENCE_H0; break; case TPM_HT_NV_INDEX: - // For an NV Index, use the TPM-specific routine + { + // For an NV Index, use the platform-specific routine // to search the IN Index space. - result = NvIndexIsAccessible(handle); + BOOL commandAcceptsVirtualHandles = + _plat__NvOperationAcceptsVirtualHandles(command->index); + result = NvIndexIsAccessible(handle, commandAcceptsVirtualHandles); break; + } case TPM_HT_PCR: // Any PCR handle that is unmarshaled successfully referenced // a PCR that is defined. @@ -167,9 +172,11 @@ EntityGetAuthValue(TPMI_DH_ENTITY handle, // IN: handle of entity TPM2B_AUTH* auth // OUT: authValue of the entity ) { - TPM2B_AUTH* pAuth = NULL; + TPM2B_AUTH* pAuth = NULL; + NV_INDEX* nvIndex = NULL; + NV_INDEX tempIndex = {0}; - auth->t.size = 0; + auth->t.size = 0; switch(HandleGetType(handle)) { @@ -240,8 +247,18 @@ EntityGetAuthValue(TPMI_DH_ENTITY handle, // IN: handle of entity case TPM_HT_NV_INDEX: // authValue for an NV index { - NV_INDEX* nvIndex = NvGetIndexInfo(handle, NULL); - pAssert(nvIndex != NULL); + if(_plat__IsNvVirtualIndex(handle)) + { + _plat__NvVirtual_PopulateNvIndexInfo( + handle, &tempIndex.publicArea, &tempIndex.authValue); + nvIndex = &tempIndex; + } + else + { + nvIndex = NvGetIndexInfo(handle, NULL); + } + pAssert_ZERO(nvIndex != NULL); + pAuth = &nvIndex->authValue; } break; @@ -328,8 +345,23 @@ EntityGetAuthPolicy(TPMI_DH_ENTITY handle, // IN: handle of entity case TPM_HT_NV_INDEX: // authPolicy for a NV index { - NV_INDEX* nvIndex = NvGetIndexInfo(handle, NULL); - pAssert(nvIndex != 0); + NV_INDEX* nvIndex = NvGetIndexInfo(handle, NULL); + NV_INDEX tempNvIndex = {0}; + if(nvIndex == NULL) + { + if(!_plat__IsNvVirtualIndex(handle)) + { + FAIL_IMMEDIATE(FATAL_ERROR_INTERNAL, TPM_ALG_NULL); + } + else + { + _plat__NvVirtual_PopulateNvIndexInfo( + handle, &tempNvIndex.publicArea, &tempNvIndex.authValue); + nvIndex = &tempNvIndex; + } + } + // nvIndex guaranteed non-null at this point. + *authPolicy = nvIndex->publicArea.authPolicy; hashAlg = nvIndex->publicArea.nameAlg; } @@ -429,16 +461,35 @@ EntityGetHierarchy(TPMI_DH_ENTITY handle // IN :handle of entity // hierarchy for NV index { NV_INDEX* nvIndex = NvGetIndexInfo(handle, NULL); - pAssert(nvIndex != NULL); + if(nvIndex == NULL) + { + if(!_plat__IsNvVirtualIndex(handle)) + { + FAIL_IMMEDIATE(FATAL_ERROR_INTERNAL, TPM_RH_NULL); + } + else + { + NV_INDEX tempNvIndex = {0}; + _plat__NvVirtual_PopulateNvIndexInfo( + handle, &tempNvIndex.publicArea, &tempNvIndex.authValue); + nvIndex = &tempNvIndex; + } + } + // nvIndex guaranteed non-null at this point. // If only the platform can delete the index, then it is // considered to be in the platform hierarchy, otherwise it // is in the owner hierarchy. - if(IS_ATTRIBUTE( + if(nvIndex != NULL + && IS_ATTRIBUTE( nvIndex->publicArea.attributes, TPMA_NV, PLATFORMCREATE)) + { hierarchy = TPM_RH_PLATFORM; + } else + { hierarchy = TPM_RH_OWNER; + } } break; case TPM_HT_TRANSIENT: diff --git a/src/tpm2/NVCommands.c b/src/tpm2/NVCommands.c index bd5690b8..720c4852 100644 --- a/src/tpm2/NVCommands.c +++ b/src/tpm2/NVCommands.c @@ -152,24 +152,6 @@ TPM2_NV_UndefineSpaceSpecial( } #endif // CC_NV_UndefineSpaceSpecial #include "Tpm.h" -#include "NV_ReadPublic_fp.h" -#if CC_NV_ReadPublic // Conditional expansion of this file -TPM_RC -TPM2_NV_ReadPublic( - NV_ReadPublic_In *in, // IN: input parameter list - NV_ReadPublic_Out *out // OUT: output parameter list - ) -{ - NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, NULL); - // Command Output - // Copy index public data to output - out->nvPublic.nvPublic = nvIndex->publicArea; - // Compute NV name - NvGetIndexName(nvIndex, &out->nvName); - return TPM_RC_SUCCESS; -} -#endif // CC_NV_ReadPublic -#include "Tpm.h" #include "NV_Write_fp.h" #if CC_NV_Write // Conditional expansion of this file TPM_RC @@ -431,49 +413,6 @@ TPM2_NV_GlobalWriteLock( } #endif // CC_NV_GlobalWriteLock #include "Tpm.h" -#include "NV_Read_fp.h" -#if CC_NV_Read // Conditional expansion of this file -/* TPM_RC_NV_AUTHORIZATION the authorization was valid but the authorizing entity (authHandle) is - not allowed to read from the Index referenced by nvIndex */ -/* TPM_RC_NV_LOCKED the Index referenced by nvIndex is read locked */ -/* TPM_RC_NV_RANGE read range defined by size and offset is outside the range of the Index - referenced by nvIndex */ -/* TPM_RC_NV_UNINITIALIZED the Index referenced by nvIndex has not been initialized (written) */ -/* TPM_RC_VALUE the read size is larger than the MAX_NV_BUFFER_SIZE */ -TPM_RC -TPM2_NV_Read( - NV_Read_In *in, // IN: input parameter list - NV_Read_Out *out // OUT: output parameter list - ) -{ - NV_REF locator; - NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator); - TPM_RC result; - // Input Validation - // Common read access checks. NvReadAccessChecks() may return - // TPM_RC_NV_AUTHORIZATION, TPM_RC_NV_LOCKED, or TPM_RC_NV_UNINITIALIZED - result = NvReadAccessChecks(in->authHandle, in->nvIndex, - nvIndex->publicArea.attributes); - if(result != TPM_RC_SUCCESS) - return result; - // Make sure the data will fit the return buffer - if(in->size > MAX_NV_BUFFER_SIZE) - return TPM_RCS_VALUE + RC_NV_Read_size; - // Verify that the offset is not too large - if(in->offset > nvIndex->publicArea.dataSize) - return TPM_RCS_VALUE + RC_NV_Read_offset; - // Make sure that the selection is within the range of the Index - if(in->size > (nvIndex->publicArea.dataSize - in->offset)) - return TPM_RC_NV_RANGE; - // Command Output - // Set the return size - out->data.t.size = in->size; - // Perform the read - NvGetIndexData(nvIndex, locator, in->offset, in->size, out->data.t.buffer); - return TPM_RC_SUCCESS; -} -#endif // CC_NV_Read -#include "Tpm.h" #include "NV_ReadLock_fp.h" #if CC_NV_ReadLock // Conditional expansion of this file TPM_RC @@ -622,43 +561,6 @@ TPM2_NV_Certify( } #endif // CC_NV_Certify -#include "Tpm.h" -#include "NV_ReadPublic2_fp.h" - -#if CC_NV_ReadPublic2 // Conditional expansion of this file - -/*(See part 3 specification) -// Read the public information of a NV index -*/ -TPM_RC -TPM2_NV_ReadPublic2(NV_ReadPublic2_In* in, // IN: input parameter list - NV_ReadPublic2_Out* out // OUT: output parameter list - ) -{ - TPM_RC result; - NV_INDEX* nvIndex; - - nvIndex = NvGetIndexInfo(in->nvIndex, NULL); - - // Command Output - - // The reference code stores its NV indices in the legacy form, because - // it doesn't support any extended attributes. - // Translate the legacy form to the general form. - result = NvPublic2FromNvPublic(&nvIndex->publicArea, &out->nvPublic.nvPublic2); - if(result != TPM_RC_SUCCESS) - { - return RcSafeAddToResult(result, RC_NV_ReadPublic2_nvIndex); - } - - // Compute NV name - NvGetIndexName(nvIndex, &out->nvName); - - return TPM_RC_SUCCESS; -} - -#endif // CC_NV_ReadPublic2 - #include "Tpm.h" #include "NV_DefineSpace2_fp.h" diff --git a/src/tpm2/NVVirtual.c b/src/tpm2/NVVirtual.c new file mode 100644 index 00000000..cde23aaf --- /dev/null +++ b/src/tpm2/NVVirtual.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: BSD-2-Clause + +#include "Platform.h" +#include "TpmAlgorithmDefines.h" +#include "TpmTypes.h" +#include "platform_virtual_nv_fp.h" + +// NV Index handles for EKICA and EK Certificates. +#define RSA_2048_EK_CERT_HANDLE (0x01c00002) +#define ECC_P256_EK_CERT_HANDLE (0x01c0000a) +#define ECC_EK_ICA_HANDLE (0x01c00100) + +LIB_EXPORT TPM_RC _plat__NvVirtual_PopulateNvIndexInfo( + TPM_HANDLE handle, // IN: handle for the index + TPMS_NV_PUBLIC* publicArea, // INOUT: The public area structure to be modified. + TPM2B_AUTH* authValue // INOUT: The auth value structure to be modified. +) +{ + NOT_REFERENCED(handle); + NOT_REFERENCED(publicArea); + NOT_REFERENCED(authValue); + return TPM_RC_NO_RESULT; +} + +LIB_EXPORT TPM_RC _plat__NvVirtual_Read( + NV_Read_In* in, // IN: input parameter list + NV_Read_Out* out // OUT: output parameter list +) +{ + NOT_REFERENCED(in); + NOT_REFERENCED(out); + return TPM_RC_NO_RESULT; +} + +LIB_EXPORT TPM_RC _plat__NvVirtual_ReadPublic( + NV_ReadPublic_In* in, // IN: input parameter list + NV_ReadPublic_Out* out // OUT: output parameter list +) +{ + NOT_REFERENCED(in); + NOT_REFERENCED(out); + return TPM_RC_NO_RESULT; +} + +LIB_EXPORT TPMI_YES_NO _plat__NvVirtual_CapGetIndex( + TPMI_DH_OBJECT handle, // IN: start handle + UINT32 count, // IN: max number of returned handles + TPML_HANDLE* handleList // OUT: list of handle +) +{ + NOT_REFERENCED(handle); + NOT_REFERENCED(count); + NOT_REFERENCED(handleList); + return NO; +} + +LIB_EXPORT BOOL _plat__NvOperationAcceptsVirtualHandles(TPM_CC commandCode) +{ + NOT_REFERENCED(commandCode); + return FALSE; +} + +LIB_EXPORT BOOL _plat__IsNvVirtualIndex(TPM_HANDLE handle) +{ + NOT_REFERENCED(handle); + // might be something like this: + // (handle == ECC_P256_EK_CERT_HANDLE || handle == RSA_2048_EK_CERT_HANDLE + // || handle == ECC_EK_ICA_HANDLE); + return FALSE; +} diff --git a/src/tpm2/NV_Read.c b/src/tpm2/NV_Read.c new file mode 100644 index 00000000..e72c8ea8 --- /dev/null +++ b/src/tpm2/NV_Read.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: BSD-2-Clause + +#include "Tpm.h" +#include "NV_Read_fp.h" +#include "platform_virtual_nv_fp.h" + +#if CC_NV_Read // Conditional expansion of this file + +/*(See part 3 specification) +// Read of an NV index +*/ +// Return Type: TPM_RC +// TPM_RC_NV_AUTHORIZATION the authorization was valid but the +// authorizing entity ('authHandle') +// is not allowed to read from the Index +// referenced by 'nvIndex' +// TPM_RC_NV_LOCKED the Index referenced by 'nvIndex' is +// read locked +// TPM_RC_NV_RANGE read range defined by 'size' and 'offset' +// is outside the range of the Index referenced +// by 'nvIndex' +// TPM_RC_NV_UNINITIALIZED the Index referenced by 'nvIndex' has +// not been initialized (written) +// TPM_RC_VALUE the read size is larger than the +// MAX_NV_BUFFER_SIZE +TPM_RC +TPM2_NV_Read(NV_Read_In* in, // IN: input parameter list + NV_Read_Out* out // OUT: output parameter list +) +{ + // Handle special cases for EK cert and EKICA cert. + if(_plat__IsNvVirtualIndex(in->nvIndex)) + { + return _plat__NvVirtual_Read(in, out); + } + + NV_REF locator; + NV_INDEX* nvIndex = NvGetIndexInfo(in->nvIndex, &locator); + TPM_RC result; + + // Input Validation + // Common read access checks. NvReadAccessChecks() may return + // TPM_RC_NV_AUTHORIZATION, TPM_RC_NV_LOCKED, or TPM_RC_NV_UNINITIALIZED + result = NvReadAccessChecks( + in->authHandle, in->nvIndex, nvIndex->publicArea.attributes); + if(result != TPM_RC_SUCCESS) + return result; + + // Make sure the data will fit the return buffer + if(in->size > MAX_NV_BUFFER_SIZE) + return TPM_RCS_VALUE + RC_NV_Read_size; + + // Verify that the offset is not too large + if(in->offset > nvIndex->publicArea.dataSize) + return TPM_RCS_VALUE + RC_NV_Read_offset; + + // Make sure that the selection is within the range of the Index + if(in->size > (nvIndex->publicArea.dataSize - in->offset)) + return TPM_RC_NV_RANGE; + + // Command Output + // Set the return size + out->data.t.size = in->size; + + // Perform the read + NvGetIndexData(nvIndex, locator, in->offset, in->size, out->data.t.buffer); + + return TPM_RC_SUCCESS; +} + +#endif // CC_NV_Read diff --git a/src/tpm2/NV_ReadPublic.c b/src/tpm2/NV_ReadPublic.c new file mode 100644 index 00000000..48e15e9a --- /dev/null +++ b/src/tpm2/NV_ReadPublic.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: BSD-2-Clause + +#include "Tpm.h" +#include "NV_ReadPublic_fp.h" +#include "platform_virtual_nv_fp.h" + +#if CC_NV_ReadPublic // Conditional expansion of this file + +/*(See part 3 specification) +// Read the public information of a NV index +*/ +TPM_RC +TPM2_NV_ReadPublic(NV_ReadPublic_In* in, // IN: input parameter list + NV_ReadPublic_Out* out // OUT: output parameter list +) +{ + // This command only supports TPM_HT_NV_INDEX-typed NV indices. + if(HandleGetType(in->nvIndex) != TPM_HT_NV_INDEX) + { + return TPM_RCS_HANDLE + RC_NV_ReadPublic_nvIndex; + } + + // Handle special cases for EK cert and special indexes + if(_plat__IsNvVirtualIndex(in->nvIndex)) + { + return _plat__NvVirtual_ReadPublic(in, out); + } + + NV_INDEX* nvIndex = NvGetIndexInfo(in->nvIndex, NULL); + + // Command Output + + // Copy index public data to output + out->nvPublic.nvPublic = nvIndex->publicArea; + + // Compute NV name + NvGetIndexName(nvIndex, &out->nvName); + + return TPM_RC_SUCCESS; +} + +#endif // CC_NV_ReadPublic diff --git a/src/tpm2/NV_ReadPublic2.c b/src/tpm2/NV_ReadPublic2.c new file mode 100644 index 00000000..b6de7efd --- /dev/null +++ b/src/tpm2/NV_ReadPublic2.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: BSD-2-Clause + +#include "Tpm.h" +#include "NV_ReadPublic2_fp.h" +#include "NV_DefineSpace_fp.h" // for the RC modifiers +#include "platform_virtual_nv_fp.h" + +#if CC_NV_ReadPublic2 // Conditional expansion of this file + +/*(See part 3 specification) +// Read the public information of a NV index +*/ +TPM_RC +TPM2_NV_ReadPublic2(NV_ReadPublic2_In* in, // IN: input parameter list + NV_ReadPublic2_Out* out // OUT: output parameter list +) +{ + TPM_RC result; + NV_INDEX* nvIndex; + + // Handle special cases for EK cert and special indexes + if(_plat__IsNvVirtualIndex(in->nvIndex)) + { + // currently NV_ReadPublic2 doesn't know how to handle virtual indexes. + return TPM_RCS_HANDLE + RC_NV_DefineSpace_publicInfo; + } + + nvIndex = NvGetIndexInfo(in->nvIndex, NULL); + + // Command Output + + // The reference code stores its NV indices in the legacy form, because + // it doesn't support any extended attributes. + // Translate the legacy form to the general form. + result = NvPublic2FromNvPublic(&nvIndex->publicArea, &out->nvPublic.nvPublic2); + if(result != TPM_RC_SUCCESS) + { + return RcSafeAddToResult(result, RC_NV_ReadPublic2_nvIndex); + } + + // Compute NV name + NvGetIndexName(nvIndex, &out->nvName); + + return TPM_RC_SUCCESS; +} + +#endif // CC_NV_ReadPublic2 + diff --git a/src/tpm2/NvDynamic.c b/src/tpm2/NvDynamic.c index a73513b6..0b851a92 100644 --- a/src/tpm2/NvDynamic.c +++ b/src/tpm2/NvDynamic.c @@ -41,6 +41,7 @@ #define NV_C #include "Tpm.h" #include "Marshal.h" +#include "platform_virtual_nv_fp.h" // libtpms changed #include "tpm_library_intern.h" // libtpms added #include "BackwardsCompatibilityObject.h" // libtpms added @@ -795,9 +796,17 @@ BOOL NvIsOwnerPersistentHandle(TPM_HANDLE handle // IN: handle // TPM_RC_NV_WRITELOCKED Index is present but locked for writing and command // writes to the index TPM_RC -NvIndexIsAccessible(TPMI_RH_NV_INDEX handle // IN: handle -) +NvIndexIsAccessible(TPMI_RH_NV_INDEX handle, // IN: handle + BOOL commandAcceptsVirtualHandles) { + // For virtual indexes nothing is actually stored in the NV + // so if it exists, it's considered "accessible", though the relevant + // virtual API may return a locked result later. + if(_plat__IsNvVirtualIndex(handle)) + { + return commandAcceptsVirtualHandles ? TPM_RC_SUCCESS : TPM_RC_NV_LOCKED; + } + NV_INDEX* nvIndex = NvGetIndexInfo(handle, NULL); // if(nvIndex == NULL) @@ -908,9 +917,14 @@ void NvGetIndexData(NV_INDEX* nvIndex, // IN: the in RAM index descriptor { // Get data from RAM buffer NV_RAM_REF ramAddr = NvRamGetIndex(nvIndex->publicArea.nvIndex); - pAssert(ramAddr != 0 - && (size <= ((NV_RAM_HEADER*)ramAddr)->size - sizeof(NV_RAM_HEADER) - - offset)); + + // Copy the contents of ramAddr into a local NV_RAM_HEADER variable before + // performing the boundary check to avoid potential alignment issues + NV_RAM_HEADER nvRamHeader; + MemoryCopy(&nvRamHeader, ramAddr, sizeof(NV_RAM_HEADER)); + pAssert_VOID_OK( + ramAddr != 0 + && (size <= (nvRamHeader.size - sizeof(NV_RAM_HEADER) - offset))); MemoryCopy(data, ramAddr + sizeof(NV_RAM_HEADER) + offset, size); } else @@ -1191,8 +1205,25 @@ TPM2B_NAME* NvGetNameByIndexHandle( TPM2B_NAME* name // OUT: name of the index ) { - NV_INDEX* nvIndex = NvGetIndexInfo(handle, NULL); - // + NV_INDEX* nvIndex = NULL; + NV_INDEX tempIndex = {0}; + + if(_plat__IsNvVirtualIndex(handle)) + { + _plat__NvVirtual_PopulateNvIndexInfo( + handle, &tempIndex.publicArea, &tempIndex.authValue); + nvIndex = &tempIndex; + } + else + { + nvIndex = NvGetIndexInfo(handle, NULL); + if(nvIndex == NULL) + { + name->b.size = 0; // set to empty reply. + return name; + } + } + return NvGetIndexName(nvIndex, name); } @@ -1624,6 +1655,10 @@ NvCapGetIndex(TPMI_DH_OBJECT handle, // IN: start handle // used here. InsertSort(handleList, count, nvHandle); } + + // Check virtual indices as well. + more |= _plat__NvVirtual_CapGetIndex(handle, count, handleList); + return more; } diff --git a/src/tpm2/NvDynamic_fp.h b/src/tpm2/NvDynamic_fp.h index e960f515..d679bd13 100644 --- a/src/tpm2/NvDynamic_fp.h +++ b/src/tpm2/NvDynamic_fp.h @@ -1,62 +1,4 @@ -/********************************************************************************/ -/* */ -/* Dynamic space for user defined NV */ -/* 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, 2016 - 2023 */ -/* */ -/********************************************************************************/ +// SPDX-License-Identifier: BSD-2-Clause /*(Auto-generated) * Created by TpmPrototypes; Version 3.0 July 18, 2017 @@ -136,8 +78,8 @@ BOOL NvIsOwnerPersistentHandle(TPM_HANDLE handle // IN: handle // TPM_RC_NV_WRITELOCKED Index is present but locked for writing and command // writes to the index TPM_RC -NvIndexIsAccessible(TPMI_RH_NV_INDEX handle // IN: handle -); +NvIndexIsAccessible(TPMI_RH_NV_INDEX handle, // IN: handle + BOOL commandAcceptsVirtualHandles); //*** NvGetEvictObject() // This function is used to dereference an evict object handle and get a pointer diff --git a/src/tpm2/SessionProcess.c b/src/tpm2/SessionProcess.c index 4f61b633..a90891c4 100644 --- a/src/tpm2/SessionProcess.c +++ b/src/tpm2/SessionProcess.c @@ -13,6 +13,7 @@ #include "Tpm.h" #include "ACT.h" #include "Marshal.h" +#include "platform_virtual_nv_fp.h" #if SEC_CHANNEL_SUPPORT # include "SecChannel_fp.h" #endif // SEC_CHANNEL_SUPPORT @@ -54,7 +55,18 @@ BOOL IsDAExempted(TPM_HANDLE handle // IN: entity handle } case TPM_HT_NV_INDEX: { - NV_INDEX* nvIndex = NvGetIndexInfo(handle, NULL); + NV_INDEX* nvIndex = NULL; + NV_INDEX ekIndex = {0}; + if(_plat__IsNvVirtualIndex(handle)) + { + _plat__NvVirtual_PopulateNvIndexInfo( + handle, &ekIndex.publicArea, &ekIndex.authValue); + nvIndex = &ekIndex; + } + else + { + nvIndex = NvGetIndexInfo(handle, NULL); + } result = IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, NO_DA); break; } @@ -327,10 +339,24 @@ static BOOL IsAuthValueAvailable(TPM_HANDLE handle, // IN: handle of e // NV Index. { NV_REF locator; - NV_INDEX* nvIndex = NvGetIndexInfo(handle, &locator); + NV_INDEX* nvIndex = NULL; TPMA_NV nvAttributes; // - pAssert(nvIndex != 0); + + if(_plat__IsNvVirtualIndex(handle)) + { + NV_INDEX tempIndex = {0}; + _plat__NvVirtual_PopulateNvIndexInfo( + handle, &tempIndex.publicArea, &tempIndex.authValue); + nvIndex = &tempIndex; + + locator = (NV_REF)0; + } + else + { + nvIndex = NvGetIndexInfo(handle, &locator); + } + pAssert_BOOL(nvIndex != 0); nvAttributes = nvIndex->publicArea.attributes; @@ -1502,9 +1528,24 @@ static TPM_RC CheckAuthSession( if((TPM_HT_NV_INDEX == HandleGetType(associatedHandle)) && authUsed) { NV_REF locator; - NV_INDEX* nvIndex = NvGetIndexInfo(associatedHandle, &locator); + NV_INDEX* nvIndex = NULL; NV_PIN pinData; TPMA_NV nvAttributes; + NV_INDEX tempIndex = {0}; + + if(_plat__IsNvVirtualIndex(associatedHandle)) + { + _plat__NvVirtual_PopulateNvIndexInfo( + associatedHandle, &tempIndex.publicArea, &tempIndex.authValue); + nvIndex = &tempIndex; + + locator = (NV_REF)0; + } + else + { + nvIndex = NvGetIndexInfo(associatedHandle, &locator); + } + // pAssert_RC(nvIndex != NULL); nvAttributes = nvIndex->publicArea.attributes; diff --git a/src/tpm2/platform_virtual_nv_fp.h b/src/tpm2/platform_virtual_nv_fp.h new file mode 100644 index 00000000..e16388b4 --- /dev/null +++ b/src/tpm2/platform_virtual_nv_fp.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: BSD-2-Clause + +#ifndef _PLATFORM_VIRTUAL_FP_H_ +#define _PLATFORM_VIRTUAL_FP_H_ + +#include "NV_Read_fp.h" +#include "NV_ReadPublic_fp.h" + +// The ECC EK Cert and EK ICA Cert NV indexes are not populated like normal. +// Data is generated on the fly and returned when NV_Read or NV_ReadPublic is +// called for them. This function populates the given NV_VIRTUAL_INDEX structure with +// attributes for the EK cert and EKICA cert scenarios. If the NV index is not virtual, +// the function should return TPM_RC_NO_RESULT. +LIB_EXPORT TPM_RC _plat__NvVirtual_PopulateNvIndexInfo( + TPM_HANDLE handle, // IN: handle for the index + TPMS_NV_PUBLIC* publicArea, // INOUT: The public area structure to be modified. + TPM2B_AUTH* authValue // INOUT: The auth value structure to be modified. +); + +// Performs NV Read call to handle EK/EKICA cert scenarios. +LIB_EXPORT TPM_RC _plat__NvVirtual_Read( + NV_Read_In* dataIn, // IN: input parameter list + NV_Read_Out* dataOut // OUT: output parameter list +); + +// Performs NV Read Public call to handle EK/EKICA cert scenarios. +LIB_EXPORT TPM_RC _plat__NvVirtual_ReadPublic( + NV_ReadPublic_In* dataIn, // IN: input parameter list + NV_ReadPublic_Out* dataOut // OUT: output parameter list +); + +// Returns a list of handles of virtual NV indices, starting from 'handle'. +// 'Handle' must be in the range of NV indices, but does not have to reference +// an existing virtual NV Index. +LIB_EXPORT TPMI_YES_NO _plat__NvVirtual_CapGetIndex( + TPMI_DH_OBJECT handle, // IN: start handle + UINT32 count, // IN: max number of returned handles + TPML_HANDLE* handleList // OUT: list of handle +); + +// Does this NV operation accept virtual NV handles? +// If the operation is not an NV operation, returns false. +LIB_EXPORT BOOL _plat__NvOperationAcceptsVirtualHandles(TPM_CC commandCode); + +// Checks if the given handle belongs to one of the virtual indices. +// Currently only used with the ECC EK Certificate and EKICA Certificate +// indices. +LIB_EXPORT BOOL _plat__IsNvVirtualIndex(TPM_HANDLE handle); + +#endif // _PLATFORM_VIRTUAL_FP_H_ diff --git a/src/tpm2/tpm_to_platform_interface.h b/src/tpm2/tpm_to_platform_interface.h index 350a5832..e97fcbff 100644 --- a/src/tpm2/tpm_to_platform_interface.h +++ b/src/tpm2/tpm_to_platform_interface.h @@ -434,4 +434,7 @@ LIB_EXPORT size_t _plat_debug_snprintf( // platform failure mode functions #include "platform_failure_mode_fp.h" +// platform virtual NV functions +#include "platform_virtual_nv_fp.h" + #endif // _TPM_TO_PLATFORM_INTERFACE_H_