Sync: Introduce platform functions for accessing NV indices

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2025-08-08 06:24:12 -04:00
parent f96d435823
commit 2e6d3f2902
12 changed files with 440 additions and 180 deletions

View File

@ -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 \

View File

@ -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:

View File

@ -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"

70
src/tpm2/NVVirtual.c Normal file
View File

@ -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;
}

71
src/tpm2/NV_Read.c Normal file
View File

@ -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

42
src/tpm2/NV_ReadPublic.c Normal file
View File

@ -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

48
src/tpm2/NV_ReadPublic2.c Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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_

View File

@ -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_