tpm2: Add functions to write state in big endian format

Add functions to marshal the volatile state of the TPM. We write it in
big endian format.

Add functions to write the data structure in big endian format
into NVRAM.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
Stefan Berger 2017-03-15 21:52:23 -04:00
parent a6d8f3f3c1
commit fad1e91698
18 changed files with 2717 additions and 57 deletions

View File

@ -262,7 +262,11 @@ libtpms_tpm2_la_SOURCES = \
tpm2/Unmarshal.c \
tpm2/Vendor_TCG_Test.c \
tpm_tpm2_interface.c \
tpm_tpm2_tis.c
tpm_tpm2_tis.c \
\
tpm2/NVMarshal.c \
tpm2/StateMarshal.c \
tpm2/Volatile.c
noinst_HEADERS += \
tpm2/crypto/CryptDes_fp.h \
@ -469,7 +473,11 @@ noinst_HEADERS += \
tpm2/VendorString.h \
tpm2/Vendor_TCG_Test_fp.h \
tpm2/VerifySignature_fp.h \
tpm2/ZGen_2Phase_fp.h
tpm2/ZGen_2Phase_fp.h \
\
tpm2/NVMarshal.h \
tpm2/StateMarshal.h \
tpm2/Volatile.h
if LIBTPMS_USE_OPENSSL
@ -513,7 +521,7 @@ endif # LIBTPMS_USE_OPENSSL
# we do not want to loose these modifications
check:
n=`grep "TPM_LIBTPMS_CALLBACK" $(libtpms_tpm2_la_SOURCES) | wc -l`; \
exp=16; \
exp=18; \
if test $$n -ne $$exp; then \
echo "TPM_LIBTPMS_CALLBACK occurrence has changed to $$n from $$exp"; \
exit 1; \

View File

@ -115,7 +115,7 @@ TPMA_SESSION s_attributes[MAX_SESSION_NUM];
TPM_HANDLE s_associatedHandles[MAX_SESSION_NUM];
TPM2B_NONCE s_nonceCaller[MAX_SESSION_NUM];
TPM2B_AUTH s_inputAuthValues[MAX_SESSION_NUM];
SESSION *s_usedSessions[MAX_SESSION_NUM];
//SESSION *s_usedSessions[MAX_SESSION_NUM];
UINT32 s_encryptSessionIndex;
UINT32 s_decryptSessionIndex;
UINT32 s_auditSessionIndex;

View File

@ -356,7 +356,7 @@ typedef struct PCR_SAVE
typedef struct PCR_POLICY
{
TPMI_ALG_HASH hashAlg[NUM_POLICY_PCR_GROUP];
TPM2B_DIGEST a;
// TPM2B_DIGEST a;
TPM2B_DIGEST policy[NUM_POLICY_PCR_GROUP];
} PCR_POLICY;
#endif
@ -848,6 +848,8 @@ extern STATE_RESET_DATA gr;
/* 5.10.13 Global Macro Definitions */
/* The NV_READ_PERSISTENT and NV_WRITE_PERSISTENT macros are used to access members of the
PERSISTENT_DATA structure in NV. */
#if 0
#define NV_READ_PERSISTENT(to, from) \
NvRead(&to, offsetof(PERSISTENT_DATA, from), sizeof(to))
#define NV_WRITE_PERSISTENT(to, from) \
@ -855,6 +857,20 @@ extern STATE_RESET_DATA gr;
#define CLEAR_PERSISTENT(item) \
NvClearPersistent(offsetof(PERSISTENT_DATA, item), sizeof(gp.item))
#define NV_SYNC_PERSISTENT(item) NV_WRITE_PERSISTENT(item, gp.item)
#else
#define NV_WRITE_PERSISTENT(to, from) \
do { \
PERSISTENT_DATA mgp; \
NvRead_PERSISTENT_DATA(&mgp, NV_PERSISTENT_DATA, sizeof(mgp)); \
memcpy(&mgp.to, &from, sizeof(mgp.to)); \
NvWrite_PERSISTENT_DATA(NV_PERSISTENT_DATA, sizeof(mgp), &mgp); \
} while (0)
#define NV_SYNC_PERSISTENT(item) NV_WRITE_PERSISTENT(item, gp.item)
#endif
/* At the start of command processing, the index of the command is determined. This index value is
used to access the various data tables that contain per-command information. There are multiple
options for how the per-command tables can be implemented. This is resolved in

View File

@ -407,14 +407,14 @@ TPM2_Clear(
// Reset clock
go.clock = 0;
go.clockSafe = YES;
NvWrite(NV_ORDERLY_DATA, sizeof(ORDERLY_DATA), &go);
NvWrite_ORDERLY_DATA(NV_ORDERLY_DATA, sizeof(ORDERLY_DATA), &go);
// Reset counters
gp.resetCount = gr.restartCount = gr.clearCount = 0;
gp.auditCounter = 0;
// Save persistent data changes to NV
// Note: since there are so many changes to the persistent data structure, the
// entire PERSISTENT_DATA structure is written as a unit
NvWrite(NV_PERSISTENT_DATA, sizeof(PERSISTENT_DATA), &gp);
NvWrite_PERSISTENT_DATA(NV_PERSISTENT_DATA, sizeof(PERSISTENT_DATA), &gp);
// Reset the PCR authValues (this does not change the PCRs)
PCR_ClearAuth();
// Bump the PCR counter

View File

@ -127,7 +127,7 @@ TPM_Manufacture(
// initialize the clock stuff
go.clock = 0;
go.clockSafe = YES;
NvWrite(NV_ORDERLY_DATA, sizeof(ORDERLY_DATA), &go);
NvWrite_ORDERLY_DATA(NV_ORDERLY_DATA, sizeof(ORDERLY_DATA), &go);
// Commit NV writes. Manufacture process is an artificial process existing
// only in simulator environment and it is not defined in the specification
// that what should be the expected behavior if the NV write fails at this

View File

@ -91,7 +91,7 @@ NvNext(
// Step over the size field and point to the handle
currentAddr = *iter + sizeof(UINT32);
// read the header of the next entry
NvRead(&header, *iter, sizeof(NV_ENTRY_HEADER));
NvRead_NV_ENTRY_HEADER(&header, *iter, sizeof(NV_ENTRY_HEADER));
// 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
@ -233,8 +233,7 @@ NvWriteNvListEnd(
// Copy the maxCount value to the marker buffer
listEndMarker.maxCount = maxCount;
pAssert(end + sizeof(NV_LIST_TERMINATOR) <= s_evictNvEnd);
// Write it to memory
NvWrite(end, sizeof(NV_LIST_TERMINATOR), &listEndMarker);
NvWrite_NV_LIST_TERMINATOR(end, sizeof(NV_LIST_TERMINATOR), (NV_LIST_TERMINATOR *)&listEndMarker);
return end + sizeof(NV_LIST_TERMINATOR);
}
/* 8.4.3.9 NvAdd() */
@ -265,18 +264,18 @@ NvAdd(
// so that the handle in the nvIndex is used instead of writing this value
if(handle != TPM_RH_UNASSIGNED)
{
NvWrite((UINT32)nextAddr, sizeof(TPM_HANDLE), &handle);
NvWrite_TPM_HANDLE((UINT32)nextAddr, sizeof(TPM_HANDLE), &handle);
nextAddr += sizeof(TPM_HANDLE);
}
// Write entity data
NvWrite((UINT32)nextAddr, bufferSize, entity);
NvWrite_Array((UINT32)nextAddr, bufferSize, entity);
// Advance the pointer by the amount of the total
nextAddr += totalSize;
// Finish by writing the link value
// Write the next offset (relative addressing)
totalSize = nextAddr - newAddr;
// Write link value
NvWrite((UINT32)newAddr, sizeof(UINT32), &totalSize);
NvWrite_UINT32((UINT32)newAddr, sizeof(UINT32), &totalSize);
// Write the list terminator
NvWriteNvListEnd(nextAddr);
return TPM_RC_SUCCESS;
@ -296,7 +295,7 @@ NvDelete(
RETURN_IF_NV_IS_NOT_AVAILABLE;
// Get the offset of the next entry. That is, back up and point to the size
// field of the entry
NvRead(&entrySize, entryRef, sizeof(UINT32));
NvRead_UINT32(&entrySize, entryRef, sizeof(UINT32));
// The next entry after the one being deleted is at a relative offset
// from the current entry
nextAddr = entryRef + entrySize;
@ -419,7 +418,7 @@ NvUpdateIndexOrderlyData(
)
{
// Write reserved RAM space to NV
NvWrite(NV_INDEX_RAM_DATA, sizeof(s_indexOrderlyRam), s_indexOrderlyRam);
NvWrite_Array(NV_INDEX_RAM_DATA, sizeof(s_indexOrderlyRam), s_indexOrderlyRam);
}
/* 8.4.4.6 NvAddRAM() */
/* This function adds a new data area to RAM. */
@ -493,8 +492,7 @@ NvReadNvIndexInfo(
)
{
pAssert(nvIndex != NULL);
NvRead(nvIndex, ref, sizeof(NV_INDEX));
return;
NvRead_NV_INDEX(nvIndex, ref, sizeof(NV_INDEX));
}
/* 8.4.4.9 NvReadObject() */
/* This function is used to read a persistent object. This is used so that the object information
@ -505,8 +503,7 @@ NvReadObject(
OBJECT *object // OUT: place to receive the object data
)
{
NvRead(object, (ref + sizeof(TPM_HANDLE)), sizeof(OBJECT));
return;
NvRead_OBJECT(object, (ref + sizeof(TPM_HANDLE)), sizeof(OBJECT));
}
/* 8.4.4.10 NvFindEvict() */
/* This function will return the NV offset of an evict object */
@ -552,7 +549,7 @@ NvConditionallyWrite(
// Write the data if NV is available
if(g_NvStatus == TPM_RC_SUCCESS)
{
NvWrite(entryAddr, size, data);
NvWrite_Array(entryAddr, size, data);
}
return g_NvStatus;
}
@ -566,7 +563,7 @@ NvReadNvIndexAttributes(
)
{
TPMA_NV attributes;
NvRead(&attributes,
NvRead_TPMA_NV(&attributes,
locator + offsetof(NV_INDEX, publicArea.attributes),
sizeof(TPMA_NV));
return attributes;
@ -595,10 +592,13 @@ NvWriteNvIndexAttributes(
TPMA_NV attributes // IN: attributes to write
)
{
TPMA_NV be_attributes;
TPMA_NV_SWAP(&be_attributes, &attributes);
return NvConditionallyWrite(
locator + offsetof(NV_INDEX, publicArea.attributes),
sizeof(TPMA_NV),
&attributes);
&be_attributes);
}
/* 8.4.4.16 NvWriteRamIndexAttributes() */
/* This function is used to write the index attributes into an unaligned structure */
@ -820,23 +820,24 @@ NvWriteIndexAuth(
TPM2B_AUTH *authValue // IN: the authValue to write
)
{
TPM_RC result;
TPM2B_AUTH be_authValue;
TPM2B_SWAP(&be_authValue.b, &authValue->b, sizeof(authValue->t.buffer));
//
// If the locator is pointing to the cached index value...
if(locator == s_cachedNvRef)
{
TPM_RC result;
//
// If the locator is pointing to the cached index value...
if(locator == s_cachedNvRef)
{
// copy the authValue to the cached index so it will be there if we
// look for it. This is a safety thing.
MemoryCopy2B(&s_cachedNvIndex.authValue.b, &authValue->b,
sizeof(s_cachedNvIndex.authValue.t.buffer));
}
result = NvConditionallyWrite(
locator + offsetof(NV_INDEX, authValue),
sizeof(UINT16) + authValue->t.size,
authValue);
return result;
// copy the authValue to the cached index so it will be there if we
// look for it. This is a safety thing.
MemoryCopy2B(&s_cachedNvIndex.authValue.b, &authValue->b,
sizeof(s_cachedNvIndex.authValue.t.buffer));
}
result = NvConditionallyWrite(
locator + offsetof(NV_INDEX, authValue),
sizeof(UINT16) + authValue->t.size,
&be_authValue);
return result;
}
/* 8.4.5.10 NvGetIndexInfo() */
/* This function loads the nvIndex Info into the NV cache and returns a pointer to the NV_INDEX. If
@ -1027,6 +1028,7 @@ NvDefineIndex(
// The buffer to be written to NV memory
NV_INDEX nvIndex; // the index data
NV_INDEX be_nvIndex;
UINT16 entrySize; // size of entry
TPM_RC result;
//
@ -1051,8 +1053,8 @@ NvDefineIndex(
// Copy the authValue
nvIndex.authValue = *authValue;
// Add index to NV memory
result = NvAdd(entrySize, sizeof(NV_INDEX), TPM_RH_UNASSIGNED,
(BYTE *)&nvIndex);
NV_INDEX_SWAP(&be_nvIndex, &nvIndex);
result = NvAdd(entrySize, sizeof(NV_INDEX), TPM_RH_UNASSIGNED, (BYTE *)&be_nvIndex);
if(result == TPM_RC_SUCCESS)
{
// If the data of NV Index is RAM backed, add the data area in RAM as well
@ -1074,6 +1076,7 @@ NvAddEvictObject(
{
TPM_HANDLE temp = object->evictHandle;
TPM_RC result;
OBJECT be_object;
// Check if we have enough space to add the evict object
// An evict object needs 8 bytes in index table + sizeof OBJECT
// In this implementation, the only resource limitation is the available NV
@ -1085,7 +1088,8 @@ NvAddEvictObject(
object->attributes.evict = SET;
object->evictHandle = evictHandle;
// Now put this in NV
result = NvAdd(sizeof(OBJECT), sizeof(OBJECT), evictHandle, (BYTE *)object);
OBJECT_SWAP(&be_object, object, FALSE);
result = NvAdd(sizeof(OBJECT), sizeof(OBJECT), evictHandle, (BYTE *)&be_object);
// Put things back the way they were
object->attributes.evict = CLEAR;
object->evictHandle = temp;
@ -1179,7 +1183,7 @@ NvFlushHierarchy(
{
OBJECT_ATTRIBUTES attributes;
//
NvRead(&attributes,
NvRead_OBJECT_ATTRIBUTES(&attributes,
(UINT32)(currentAddr
+ sizeof(TPM_HANDLE)
+ offsetof(OBJECT, attributes)),
@ -1638,6 +1642,6 @@ NvGetMaxCount(
while((currentAddr = NvNext(&iter, NULL )) != 0);
// 'iter' should be pointing at the end of list marker so read in the current
// value of the s_maxCounter.
NvRead(&maxCount, iter + sizeof(UINT32), sizeof(maxCount));
NvRead_UINT64(&maxCount, iter + sizeof(UINT32), sizeof(maxCount));
return maxCount;
}

2178
src/tpm2/NVMarshal.c Normal file

File diff suppressed because it is too large Load Diff

107
src/tpm2/NVMarshal.h Normal file
View File

@ -0,0 +1,107 @@
/********************************************************************************/
/* */
/* Marshalling and unmarshalling of state */
/* Written by Stefan Berger */
/* 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, 2012-2015 */
/* */
/********************************************************************************/
#ifndef NVMARSHAL_H
#define NVMARSHAL_H
#include <stdbool.h>
#include "Tpm.h"
#include "TpmTypes.h"
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
UINT16 VolatileState_Marshal(BYTE **buffer, INT32 *size);
TPM_RC VolatileState_Unmarshal(BYTE **buffer, INT32 *size);
void NvWrite_ORDERLY_DATA(UINT32 nvOffset, UINT32 size, ORDERLY_DATA *data);
void NvWrite_STATE_RESET_DATA(UINT32 nvOffset, UINT32 size, STATE_RESET_DATA *data);
void NvWrite_STATE_CLEAR_DATA(UINT32 nvOffset, UINT32 size, STATE_CLEAR_DATA *data);
void NvWrite_PERSISTENT_DATA(UINT32 nvOffset, UINT32 size, PERSISTENT_DATA *data);
void NvWrite_NV_LIST_TERMINATOR(UINT32 nvOffset, UINT32 size, NV_LIST_TERMINATOR *data);
void NvWrite_UINT32(UINT32 nvOffset, UINT32 size, UINT32 *data);
void NvWrite_TPM_HANDLE(UINT32 nvOffset, UINT32 size, UINT32 *data);
void NvWrite_Array(UINT32 nvOffset, UINT32 size, BYTE *data);
void NvRead_UINT32(UINT32 *data, UINT32 nvOffset, UINT32 size);
void NvRead_UINT64(UINT64 *data, UINT32 nvOffset, UINT32 size);
void NvRead_ORDERLY_DATA(ORDERLY_DATA *data, UINT32 nvOffset, UINT32 size);
void NvRead_STATE_RESET_DATA(STATE_RESET_DATA *data, UINT32 nvOffset, UINT32 size);
void NvRead_STATE_CLEAR_DATA(STATE_CLEAR_DATA *data, UINT32 nvOffset, UINT32 size);
void NvRead_PERSISTENT_DATA(PERSISTENT_DATA *data, UINT32 nvOffset, UINT32 size);
void NvRead_OBJECT_ATTRIBUTES(OBJECT_ATTRIBUTES *data, UINT32 nvOffset, UINT32 size);
void NvRead_OBJECT(OBJECT *data, UINT32 nvOffset, UINT32 size);
void NvRead_TPMA_NV(TPMA_NV *data, UINT32 nvOffset, UINT32 size);
void NvRead_NV_INDEX(NV_INDEX *data, UINT32 nvOffset, UINT32 size);
void NvRead_NV_ENTRY_HEADER(NV_ENTRY_HEADER *data, UINT32 nvOffset, UINT32 size);
void TPMA_NV_SWAP(TPMA_NV *t, TPMA_NV *s);
void OBJECT_SWAP(OBJECT *t, OBJECT *s, bool to_native);
void NV_INDEX_SWAP(NV_INDEX *t, NV_INDEX *s);
static inline void TPM2B_SWAP(TPM2B *t, TPM2B *s, size_t bufsize)
{
t->size = htobe16(s->size);
memcpy(t->buffer, s->buffer, bufsize);
}
#endif /* NVMARSHAL_H */

View File

@ -198,7 +198,7 @@ NvUpdatePersistent(
{
pAssert(offset + size <= sizeof(gp));
MemoryCopy(&gp + offset, buffer, size);
NvWrite(offset, size, buffer);
NvWrite_PERSISTENT_DATA(NV_PERSISTENT_DATA, sizeof(PERSISTENT_DATA), &gp);
}
/* 8.5.3.8 NvClearPersistent() */
/* This function is used to clear a persistent data entry and commit it to NV */
@ -210,7 +210,7 @@ NvClearPersistent(
)
{
MemorySet((&gp) + offset, 0, size);
NvWrite(offset, size, (&gp) + offset);
NvWrite_PERSISTENT_DATA(NV_PERSISTENT_DATA, sizeof(PERSISTENT_DATA), &gp);
}
/* 8.5.3.9 NvReadPersistent() */
/* This function reads persistent data to the RAM copy of the gp structure. */
@ -219,6 +219,6 @@ NvReadPersistent(
void
)
{
NvRead(&gp, NV_PERSISTENT_DATA, sizeof(gp));
NvRead_PERSISTENT_DATA(&gp, NV_PERSISTENT_DATA, sizeof(gp));
return;
}

View File

@ -62,6 +62,8 @@
#ifndef NVRESERVED_FP_H
#define NVRESERVED_FP_H
#include "NVMarshal.h"
void
NvCheckState(
void

View File

@ -62,6 +62,7 @@
/* 9.2 _TPM_Init */
#include "Tpm.h"
#include "_TPM_Init_fp.h"
#include "StateMarshal.h"
// This function is used to process a _TPM_Init indication.
LIB_EXPORT void
_TPM_Init(
@ -100,9 +101,11 @@ _TPM_Init(
NvReadPersistent();
// Load the orderly data (clock and DRBG state).
// If this is not done here, things break
NvRead(&go, NV_ORDERLY_DATA, sizeof(go));
NvRead_ORDERLY_DATA(&go, NV_ORDERLY_DATA, sizeof(go));
// Start clock. Need to do this after NV has been restored.
TimePowerOn();
VolatileLoad();
}
return;
}
@ -174,13 +177,13 @@ TPM2_Startup(
{
// Always read the data that is only cleared on a Reset because this is not
// a reset
NvRead(&gr, NV_STATE_RESET_DATA, sizeof(gr));
NvRead_STATE_RESET_DATA(&gr, NV_STATE_RESET_DATA, sizeof(gr));
if(in->startupType == TPM_SU_STATE)
{
// If this is a startup STATE (a Resume) need to read the data
// that is cleared on a startup CLEAR because this is not a Reset
// or Restart.
NvRead(&gc, NV_STATE_CLEAR_DATA, sizeof(gc));
NvRead_STATE_CLEAR_DATA(&gc, NV_STATE_CLEAR_DATA, sizeof(gc));
startup = SU_RESUME;
}
else
@ -294,12 +297,12 @@ TPM2_Shutdown(
go.time = g_time;
#endif
// Save all orderly data
NvWrite(NV_ORDERLY_DATA, sizeof(ORDERLY_DATA), &go);
NvWrite_ORDERLY_DATA(NV_ORDERLY_DATA, sizeof(ORDERLY_DATA), &go);
if(in->shutdownType == TPM_SU_STATE)
{
// Save STATE_RESET and STATE_CLEAR data
NvWrite(NV_STATE_CLEAR_DATA, sizeof(STATE_CLEAR_DATA), &gc);
NvWrite(NV_STATE_RESET_DATA, sizeof(STATE_RESET_DATA), &gr);
NvWrite_STATE_CLEAR_DATA(NV_STATE_CLEAR_DATA, sizeof(STATE_CLEAR_DATA), &gc);
NvWrite_STATE_RESET_DATA(NV_STATE_RESET_DATA, sizeof(STATE_RESET_DATA), &gr);
// Save the startup flags for resume
if(g_DrtmPreStartup)
gp.orderlyState = TPM_SU_STATE | PRE_STARTUP_FLAG;
@ -309,7 +312,7 @@ TPM2_Shutdown(
else if(in->shutdownType == TPM_SU_CLEAR)
{
// Save STATE_RESET data
NvWrite(NV_STATE_RESET_DATA, sizeof(STATE_RESET_DATA), &gr);
NvWrite_STATE_RESET_DATA(NV_STATE_RESET_DATA, sizeof(STATE_RESET_DATA), &gr);
}
else
FAIL(FATAL_ERROR_INTERNAL);

41
src/tpm2/StateMarshal.c Normal file
View File

@ -0,0 +1,41 @@
#include <stdlib.h>
#include "config.h"
#include "tpm_library_intern.h"
#include "tpm_nvfilename.h"
#include "tpm_error.h"
#include "StateMarshal.h"
#include "Volatile.h"
UINT16
VolatileSave(BYTE **buffer, INT32 *size)
{
return VolatileState_Save(buffer, size);
}
void
VolatileLoad(void)
{
#ifdef TPM_LIBTPMS_CALLBACKS
struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks();
if (cbs->tpm_nvram_loaddata) {
unsigned char *data = NULL;
uint32_t length = 0;
uint32_t tpm_number = 0;
const char *name = TPM_VOLATILESTATE_NAME;
TPM_RESULT ret;
ret = cbs->tpm_nvram_loaddata(&data, &length, tpm_number, name);
if (ret == TPM_SUCCESS) {
VolatileState_Load(&data, (INT32 *)&length);
/*
* if this failed, VolatileState_Load will have started
* failure mode.
*/
}
}
#endif /* TPM_LIBTPMS_CALLBACKS */
}

74
src/tpm2/StateMarshal.h Normal file
View File

@ -0,0 +1,74 @@
/********************************************************************************/
/* */
/* Marshalling and unmarshalling of state */
/* Written by Stefan Berger */
/* 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, 2012-2015 */
/* */
/********************************************************************************/
#ifndef STATE_MARSHAL_H
#define STATE_MARSHAL_H
#include "BaseTypes.h"
/*
* we keep these in a separate file to avoid symbol clashes when
* included from the interface code.
*/
void VolatileLoad(void);
UINT16 VolatileSave(BYTE **buffer, INT32 *size);
#endif /* STATE_MARSHAL_H */

View File

@ -136,7 +136,7 @@ TimeClockUpdate(
go.clockSafe = YES;
// update the time
go.clock = newTime;
NvWrite(NV_ORDERLY_DATA, sizeof(go), &go);
NvWrite_ORDERLY_DATA(NV_ORDERLY_DATA, sizeof(go), &go);
}
else
// No NV update needed so just update

View File

@ -1792,10 +1792,12 @@ typedef union {
} TPM2B_ID_OBJECT;
/* Table 2:202 - Definition of TPM_NV_INDEX Bits */
#ifndef NO_BIT_FIELD_STRUCTURES
#if 0
typedef struct TPM_NV_INDEX{
unsigned index : 24;
unsigned RH_NV : 8 ;
} TPM_NV_INDEX;
#endif
/* This is the initializer for a TPMA_NV_INDEX structure. */
#define TPM_NV_INDEX_INITIALIZER(tpm_nv_index_index, tpm_nv_index_RH_NV) \
{tpm_nv_index_index, tpm_nv_index_RH_NV}

133
src/tpm2/Volatile.c Normal file
View File

@ -0,0 +1,133 @@
/********************************************************************************/
/* */
/* Marshalling and unmarshalling of state */
/* Written by Stefan Berger */
/* 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, 2012-2015 */
/* */
/********************************************************************************/
#include <endian.h>
#include <string.h>
#include "config.h"
#include "assert.h"
#include "NVMarshal.h"
#include "Volatile.h"
#include "tpm_library_intern.h"
TPM_RC
VolatileState_Load(BYTE **buffer, INT32 *size)
{
TPM_RC rc = TPM_RC_SUCCESS;
BYTE hash[SHA1_DIGEST_SIZE], acthash[SHA1_DIGEST_SIZE];
UINT16 hashAlg = TPM_ALG_SHA1;
if (rc == TPM_RC_SUCCESS) {
CryptHashBlock(hashAlg, *size - sizeof(hash), *buffer,
sizeof(acthash), acthash);
rc = VolatileState_Unmarshal(buffer, size);
if (rc != TPM_RC_SUCCESS)
TPMLIB_LogTPM2Error("Error unmarshalling volatile state: 0x%02x",
rc);
}
if (rc == TPM_RC_SUCCESS) {
/*
* advance pointer towards hash if we have a later version of
* the state that has extra data we didn't read
*/
if (*size > 0 && (UINT32)*size > sizeof(hash)) {
*buffer += *size - sizeof(hash);
*size = sizeof(hash);
}
rc = Array_Unmarshal(hash, sizeof(hash), buffer, size);
if (rc != TPM_RC_SUCCESS)
TPMLIB_LogTPM2Error("Error unmarshalling volatile state hash: "
"0x%02x", rc);
}
if (rc == TPM_RC_SUCCESS) {
if (memcmp(acthash, hash, sizeof(hash))) {
rc = TPM_RC_HASH;
TPMLIB_LogTPM2Error("Volatile state checksum error: 0x%02x\n",
rc);
}
}
if (rc != TPM_RC_SUCCESS)
g_inFailureMode = TRUE;
return rc;
}
UINT16
VolatileState_Save(BYTE **buffer, INT32 *size)
{
UINT16 written;
const BYTE *start;
BYTE hash[SHA1_DIGEST_SIZE];
TPM_ALG_ID hashAlg = TPM_ALG_SHA1;
start = *buffer;
written = VolatileState_Marshal(buffer, size);
/* append the checksum */
CryptHashBlock(hashAlg, written, start, sizeof(hash), hash);
written += Array_Marshal(hash, sizeof(hash), buffer, size);
return written;
}

70
src/tpm2/Volatile.h Normal file
View File

@ -0,0 +1,70 @@
/********************************************************************************/
/* */
/* Marshalling and unmarshalling of state */
/* Written by Stefan Berger */
/* 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, 2012-2015 */
/* */
/********************************************************************************/
#ifndef VOLATILE_H
#define VOLATILE_H
#include "BaseTypes.h"
typedef UINT32 TPM_RC;
TPM_RC VolatileState_Load(BYTE **buffer, INT32 *size);
UINT16 VolatileState_Save(BYTE **buffer, INT32 *size);
#endif /* VOLATILE_H */

View File

@ -60,6 +60,7 @@
#include "tpm2/Simulator_fp.h"
#include "tpm2/_TPM_Hash_Data_fp.h"
#include "tpm2/_TPM_Init_fp.h"
#include "tpm2/StateMarshal.h"
extern BOOL g_inFailureMode;
@ -157,7 +158,7 @@ TPM_RESULT TPM2_Process(unsigned char **respbuffer, uint32_t *resp_size,
req.Buffer = command;
/* have the TPM 2 write directly into the response buffer */
if (*respbufsize < TPM_BUFFER_MAX) {
if (*respbufsize < TPM_BUFFER_MAX || !*respbuffer) {
res = TPM_Realloc(respbuffer, TPM_BUFFER_MAX);
if (res)
return res;
@ -181,8 +182,29 @@ TPM_RESULT TPM2_Process(unsigned char **respbuffer, uint32_t *resp_size,
TPM_RESULT TPM2_VolatileAllStore(unsigned char **buffer,
uint32_t *buflen)
{
// FIXME: Is there a function for this?
return TPM_FAIL;
TPM_RESULT rc;
INT32 size = NV_MEMORY_SIZE;
UINT16 written;
unsigned char *statebuffer = NULL;
*buffer = NULL;
rc = TPM_Realloc(&statebuffer, size);
if (rc)
return rc;
/* statebuffer will change */
*buffer = statebuffer;
written = VolatileSave(&statebuffer, &size);
if (written >= size) {
TPM_Free(*buffer);
*buffer = NULL;
rc = TPM_FAIL;
} else {
*buflen = written;
}
return rc;
}
TPM_RESULT TPM2_CancelCommand(void)