Sync: Rework some NVRAM functions to return TPM_RC and adjust pAsserts

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2025-07-23 19:39:45 -04:00
parent f17c7d8511
commit fb53a5cbe0
2 changed files with 74 additions and 153 deletions

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
//** Introduction
@ -277,7 +219,17 @@ NvWriteNvListEnd(NV_REF end)
// Copy the maxCount value to the marker buffer
MemoryCopy(&listEndMarker[sizeof(UINT32)], &maxCount, sizeof(UINT64));
pAssert(end + sizeof(NV_LIST_TERMINATOR) <= s_evictNvEnd);
// was a pAssert that (end + sizeof(NV_LIST_TERMINATOR) <= s_evictNvEnd);
if(end + sizeof(NV_LIST_TERMINATOR) > s_evictNvEnd)
{
// enter failure mode, but don't return yet.
FAIL_NORET(FATAL_ERROR_ASSERT);
// write NV_REF at last valid space.
// This will truncate the last entry, but
// better than writing past buffer or leaving buffer unterminated.
end = s_evictNvEnd - sizeof(NV_LIST_TERMINATOR);
}
// Write it to memory
NvWrite(end, sizeof(NV_LIST_TERMINATOR), &listEndMarker);
@ -364,7 +316,7 @@ static TPM_RC NvDelete(NV_REF entityRef // IN: reference to entity to be delete
// If this is not the last entry, move everything up
if(nextAddr < endRef)
{
pAssert(nextAddr > entryRef);
pAssert_RC(nextAddr > entryRef);
_plat__NvMemoryMove(nextAddr, entryRef, (endRef - nextAddr));
}
// The end of the used space is now moved up by the amount of space we just
@ -397,7 +349,9 @@ static TPM_RC NvDelete(NV_REF entityRef // IN: reference to entity to be delete
//*** NvRamNext()
// This function is used to iterate trough the list of Ram Index values. *iter needs
// to be initialized by calling
// to be initialized to NV_RAM_REF_INIT before starting iteration.
// returns the handle and REF of the current item and advances iterator.
// return 0 when at the end of the list.
static NV_RAM_REF NvRamNext(NV_RAM_REF* iter, // IN/OUT: the list iterator
TPM_HANDLE* handle // OUT: the handle of the next item.
)
@ -418,19 +372,33 @@ static NV_RAM_REF NvRamNext(NV_RAM_REF* iter, // IN/OUT: the list iterator
// that we are at the end of the list. The end of the list occurs when
// we don't have space for a size and a handle
if(currentAddr + sizeof(NV_RAM_HEADER) > RAM_ORDERLY_END)
{
return NULL;
}
// read the header of the next entry
memcpy(&header, currentAddr, sizeof(NV_RAM_HEADER)); // libtpms: do not use MemoryCopy to avoid gcc warning
// if the size field is zero, then we have hit the end of the list
if(header.size == 0)
{
// leave the *iter pointing at the end of the list
return NULL;
// advance the header by the size of the entry
*iter = currentAddr + header.size;
}
if(*iter + header.size > RAM_ORDERLY_END)
{
// enter failure mode and stop iteration.
FAIL_IMMEDIATE(FATAL_ERROR_INTERNAL, 0);
}
// advance the header by the size of the entry
*iter += header.size;
// pAssert(*iter <= RAM_ORDERLY_END);
if(handle != NULL)
{
*handle = header.handle;
}
return currentAddr;
}
@ -502,7 +470,7 @@ void NvUpdateIndexOrderlyData(void)
// This function should be called after the NV Index space has been updated
// and the index removed. This insures that NV is available so that checking
// for NV availability is not required during this function.
static void NvAddRAM(TPMS_NV_PUBLIC* index // IN: the index descriptor
static TPM_RC NvAddRAM(TPMS_NV_PUBLIC* index // IN: the index descriptor
)
{
NV_RAM_HEADER header;
@ -512,7 +480,7 @@ static void NvAddRAM(TPMS_NV_PUBLIC* index // IN: the index descriptor
header.handle = index->nvIndex;
MemoryCopy(&header.attributes, &index->attributes, sizeof(TPMA_NV));
pAssert(ORDERLY_RAM_ADDRESS_OK(end, header.size));
pAssert_RC(ORDERLY_RAM_ADDRESS_OK(end, header.size));
// Copy the header to the memory
MemoryCopy(end, &header, sizeof(NV_RAM_HEADER));
@ -529,7 +497,7 @@ static void NvAddRAM(TPMS_NV_PUBLIC* index // IN: the index descriptor
// Write reserved RAM space to NV to reflect the newly added NV Index
SET_NV_UPDATE(UT_ORDERLY);
return;
return TPM_RC_SUCCESS;
}
//*** NvDeleteRAM()
@ -542,7 +510,7 @@ static void NvAddRAM(TPMS_NV_PUBLIC* index // IN: the index descriptor
// This function should be called after the NV Index space has been updated
// and the index removed. This insures that NV is available so that checking
// for NV availability is not required during this function.
static void NvDeleteRAM(TPMI_RH_NV_INDEX handle // IN: NV handle
static TPM_RC NvDeleteRAM(TPMI_RH_NV_INDEX handle // IN: NV handle
)
{
NV_RAM_REF nodeAddress;
@ -552,7 +520,7 @@ static void NvDeleteRAM(TPMI_RH_NV_INDEX handle // IN: NV handle
//
nodeAddress = NvRamGetIndex(handle);
pAssert(nodeAddress != 0);
pAssert_RC(nodeAddress != 0);
// Get node size
MemoryCopy(&size, nodeAddress, sizeof(size));
@ -569,7 +537,7 @@ static void NvDeleteRAM(TPMI_RH_NV_INDEX handle // IN: NV handle
// Write reserved RAM space to NV to reflect the newly delete NV Index
SET_NV_UPDATE(UT_ORDERLY);
return;
return TPM_RC_SUCCESS;
}
//*** NvReadIndex()
@ -581,7 +549,10 @@ void NvReadNvIndexInfo(NV_REF ref, // IN: points to NV where index is loc
NV_INDEX* nvIndex // OUT: place to receive index data
)
{
pAssert(nvIndex != NULL);
// internal function that should have validated parameters. enter failure
// mode and return without reading. currently existing callers pass private
// buffers so are all guaranteed non-null
pAssert_VOID_OK(nvIndex != NULL);
NvRead(nvIndex, ref, sizeof(NV_INDEX));
return;
}
@ -923,12 +894,15 @@ void NvGetIndexData(NV_INDEX* nvIndex, // IN: the in RAM index descriptor
)
{
TPMA_NV nvAttributes;
//
pAssert(nvIndex != NULL);
// early exit/fail to read is an appropriate response if input data is invalid.
// these should have been checked by NvReadAccessChecks before getting here, so
// failure mode is appropriate
pAssert_VOID_OK(nvIndex != NULL);
nvAttributes = nvIndex->publicArea.attributes;
pAssert(IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN));
pAssert_VOID_OK(IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN));
if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, ORDERLY))
{
@ -942,8 +916,8 @@ void NvGetIndexData(NV_INDEX* nvIndex, // IN: the in RAM index descriptor
else
{
// Validate that read falls within range of the index
pAssert(offset <= nvIndex->publicArea.dataSize
&& size <= (nvIndex->publicArea.dataSize - offset));
pAssert_VOID_OK(offset <= nvIndex->publicArea.dataSize
&& size <= (nvIndex->publicArea.dataSize - offset));
NvRead(data, locator + sizeof(NV_INDEX) + offset, size);
}
return;
@ -1112,15 +1086,15 @@ NvWriteIndexData(NV_INDEX* nvIndex, // IN: the description of the index
{
TPM_RC result = TPM_RC_SUCCESS;
//
pAssert(nvIndex != NULL);
pAssert_RC(nvIndex != NULL);
// Make sure that this is dealing with the 'default' index.
// Note: it is tempting to change the calling sequence so that the 'default' is
// presumed.
pAssert(nvIndex->publicArea.nvIndex == s_cachedNvIndex.publicArea.nvIndex);
pAssert_RC(nvIndex->publicArea.nvIndex == s_cachedNvIndex.publicArea.nvIndex);
// Validate that write falls within range of the index
pAssert(offset <= nvIndex->publicArea.dataSize
&& size <= (nvIndex->publicArea.dataSize - offset));
pAssert_RC(offset <= nvIndex->publicArea.dataSize
&& size <= (nvIndex->publicArea.dataSize - offset));
// Update TPMA_NV_WRITTEN bit if necessary
if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
@ -1267,7 +1241,9 @@ NvDefineIndex(TPMS_NV_PUBLIC* publicArea, // IN: A template for an area to crea
{
// If the data of NV Index is RAM backed, add the data area in RAM as well
if(IS_ATTRIBUTE(publicArea->attributes, TPMA_NV, ORDERLY))
NvAddRAM(publicArea);
{
result = NvAddRAM(publicArea);
}
}
return result;
}
@ -1348,7 +1324,13 @@ NvDeleteIndex(NV_INDEX* nvIndex, // IN: an in RAM index descriptor
return result;
// If the NV Index is RAM backed, delete the RAM data as well
if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, ORDERLY))
NvDeleteRAM(nvIndex->publicArea.nvIndex);
{
result = NvDeleteRAM(nvIndex->publicArea.nvIndex);
}
if(result != TPM_RC_SUCCESS)
return result;
NvIndexCacheInit();
}
return TPM_RC_SUCCESS;
@ -1547,7 +1529,7 @@ NvCapGetPersistent(TPMI_DH_OBJECT handle, // IN: start handle
NV_REF currentAddr;
TPM_HANDLE entityHandle;
//
pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
VERIFY(HandleGetType(handle) == TPM_HT_PERSISTENT, FATAL_ERROR_INTERNAL, NO);
// Initialize output handle list
handleList->count = 0;
@ -1586,7 +1568,7 @@ BOOL NvCapGetOnePersistent(TPMI_DH_OBJECT handle) // IN: handle
NV_REF currentAddr;
TPM_HANDLE entityHandle;
pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
pAssert_BOOL(HandleGetType(handle) == TPM_HT_PERSISTENT);
while((currentAddr = NvNextEvict(&entityHandle, &iter)) != 0)
{
@ -1616,7 +1598,7 @@ NvCapGetIndex(TPMI_DH_OBJECT handle, // IN: start handle
NV_REF currentAddr;
TPM_HANDLE nvHandle;
//
pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
VERIFY(HandleGetType(handle) == TPM_HT_NV_INDEX, FATAL_ERROR_INTERNAL, NO);
// Initialize output handle list
handleList->count = 0;
@ -1653,7 +1635,7 @@ BOOL NvCapGetOneIndex(TPMI_DH_OBJECT handle) // IN: handle
NV_REF currentAddr;
TPM_HANDLE nvHandle;
pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
pAssert_BOOL(HandleGetType(handle) == TPM_HT_NV_INDEX);
while((currentAddr = NvNextIndex(&nvHandle, &iter)) != 0)
{

View File

@ -1,62 +1,4 @@
/********************************************************************************/
/* */
/* NV TPM persistent and state save data */
/* 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
//** Introduction
@ -228,13 +170,10 @@ BOOL NvWrite(UINT32 nvOffset, // IN: location in NV to receive data
)
{
// Input type should be valid
if(nvOffset + size <= NV_MEMORY_SIZE)
{
// Set the flag that a NV write happened
SET_NV_UPDATE(UT_NV);
return _plat__NvMemoryWrite(nvOffset, size, inBuffer);
}
return FALSE;
pAssert_BOOL(nvOffset + size <= NV_MEMORY_SIZE);
// Set the flag that a NV write happened
SET_NV_UPDATE(UT_NV);
return _plat__NvMemoryWrite(nvOffset, size, inBuffer);
}
#if 0 // libtpms added begin (for Coverity)