270 lines
8.9 KiB
C
270 lines
8.9 KiB
C
// This file was extracted from the TCG Published
|
|
// Trusted Platform Module Library
|
|
// Part 4: Supporting Routines
|
|
// Family "2.0"
|
|
// Level 00 Revision 01.16
|
|
// October 30, 2014
|
|
|
|
#define MEMORY_LIB_C
|
|
#include "MemoryLib_fp.h"
|
|
//
|
|
// These buffers are set aside to hold command and response values. In this implementation, it is not
|
|
// guaranteed that the code will stop accessing the s_actionInputBuffer before starting to put values in the
|
|
// s_actionOutputBuffer so different buffers are required. However, the s_actionInputBuffer and
|
|
// s_responseBuffer are not needed at the same time and they could be the same buffer.
|
|
//
|
|
// Functions on BYTE Arrays
|
|
//
|
|
// MemoryMove()
|
|
//
|
|
// This function moves data from one place in memory to another. No safety checks of any type are
|
|
// performed. If source and data buffer overlap, then the move is done as if an intermediate buffer were
|
|
// used.
|
|
//
|
|
// NOTE: This function is used by MemoryCopy(), MemoryCopy2B(), and MemoryConcat2b() and requires that the caller
|
|
// know the maximum size of the destination buffer so that there is no possibility of buffer overrun.
|
|
//
|
|
LIB_EXPORT void
|
|
MemoryMove(
|
|
void *destination, // OUT: move destination
|
|
const void *source, // IN: move source
|
|
UINT32 size, // IN: number of octets to moved
|
|
UINT32 dSize // IN: size of the receive buffer
|
|
)
|
|
{
|
|
const BYTE *p = (BYTE *)source;
|
|
BYTE *q = (BYTE *)destination;
|
|
if(destination == NULL || source == NULL)
|
|
return;
|
|
pAssert(size <= dSize);
|
|
// if the destination buffer has a lower address than the
|
|
// source, then moving bytes in ascending order is safe.
|
|
dSize -= size;
|
|
if (p>q || (p+size <= q))
|
|
{
|
|
while(size--)
|
|
*q++ = *p++;
|
|
}
|
|
// If the destination buffer has a higher address than the
|
|
// source, then move bytes from the end to the beginning.
|
|
else if (p < q)
|
|
{
|
|
p += size;
|
|
q += size;
|
|
//
|
|
while (size--)
|
|
*--q = *--p;
|
|
}
|
|
// If the source and destination address are the same, nothing to move.
|
|
return;
|
|
}
|
|
//
|
|
// MemoryEqual()
|
|
//
|
|
// This function indicates if two buffers have the same values in the indicated number of bytes.
|
|
//
|
|
// Return Value Meaning
|
|
//
|
|
// TRUE all octets are the same
|
|
// FALSE all octets are not the same
|
|
//
|
|
LIB_EXPORT BOOL
|
|
MemoryEqual(
|
|
const void *buffer1, // IN: compare buffer1
|
|
const void *buffer2, // IN: compare buffer2
|
|
UINT32 size // IN: size of bytes being compared
|
|
)
|
|
{
|
|
BOOL diff = FALSE;
|
|
const BYTE *b1, *b2;
|
|
b1 = (BYTE *)buffer1;
|
|
b2 = (BYTE *)buffer2;
|
|
// Compare all bytes so that there is no leakage of information
|
|
// due to timing differences.
|
|
for(; size > 0; size--)
|
|
diff |= *b1++ ^ *b2++;
|
|
return !diff;
|
|
}
|
|
//
|
|
//
|
|
// MemoryCopy2B()
|
|
//
|
|
// This function copies a TPM2B. This can be used when the TPM2B types are the same or different. No
|
|
// size checking is done on the destination so the caller should make sure that the destination is large
|
|
// enough.
|
|
//
|
|
// This function returns the number of octets in the data buffer of the TPM2B.
|
|
//
|
|
LIB_EXPORT INT16
|
|
MemoryCopy2B(
|
|
TPM2B *dest, // OUT: receiving TPM2B
|
|
const TPM2B *source, // IN: source TPM2B
|
|
UINT16 dSize // IN: size of the receiving buffer
|
|
)
|
|
{
|
|
if(dest == NULL)
|
|
return 0;
|
|
if(source == NULL)
|
|
dest->size = 0;
|
|
else
|
|
{
|
|
dest->size = source->size;
|
|
MemoryMove(dest->buffer, source->buffer, dest->size, dSize);
|
|
}
|
|
return dest->size;
|
|
}
|
|
//
|
|
//
|
|
// MemoryConcat2B()
|
|
//
|
|
// This function will concatenate the buffer contents of a TPM2B to an the buffer contents of another TPM2B
|
|
// and adjust the size accordingly (a := (a | b)).
|
|
//
|
|
LIB_EXPORT void
|
|
MemoryConcat2B(
|
|
TPM2B *aInOut, // IN/OUT: destination 2B
|
|
TPM2B *bIn, // IN: second 2B
|
|
UINT16 aSize // IN: The size of aInOut.buffer (max values for
|
|
// aInOut.size)
|
|
)
|
|
{
|
|
MemoryMove(&aInOut->buffer[aInOut->size],
|
|
bIn->buffer,
|
|
bIn->size,
|
|
aSize - aInOut->size);
|
|
aInOut->size = aInOut->size + bIn->size;
|
|
return;
|
|
}
|
|
//
|
|
//
|
|
// Memory2BEqual()
|
|
//
|
|
// This function will compare two TPM2B structures. To be equal, they need to be the same size and the
|
|
// buffer contexts need to be the same in all octets.
|
|
//
|
|
// Return Value Meaning
|
|
//
|
|
// TRUE size and buffer contents are the same
|
|
// FALSE size or buffer contents are not the same
|
|
//
|
|
LIB_EXPORT BOOL
|
|
Memory2BEqual(
|
|
const TPM2B *aIn, // IN: compare value
|
|
const TPM2B *bIn // IN: compare value
|
|
)
|
|
{
|
|
if(aIn->size != bIn->size)
|
|
return FALSE;
|
|
return MemoryEqual(aIn->buffer, bIn->buffer, aIn->size);
|
|
}
|
|
//
|
|
//
|
|
// MemorySet()
|
|
//
|
|
// This function will set all the octets in the specified memory range to the specified octet value.
|
|
//
|
|
// NOTE: the dSize parameter forces the caller to know how big the receiving buffer is to make sure that there is no
|
|
// possibility that the caller will inadvertently run over the end of the buffer.
|
|
//
|
|
LIB_EXPORT void
|
|
MemorySet(
|
|
void *destination, // OUT: memory destination
|
|
char value, // IN: fill value
|
|
UINT32 size // IN: number of octets to fill
|
|
)
|
|
{
|
|
char *p = (char *)destination;
|
|
while (size--)
|
|
*p++ = value;
|
|
return;
|
|
}
|
|
#ifndef EMBEDDED_MODE
|
|
//
|
|
//
|
|
// MemoryGetActionInputBuffer()
|
|
//
|
|
// This function returns the address of the buffer into which the command parameters will be unmarshaled in
|
|
// preparation for calling the command actions.
|
|
//
|
|
BYTE *
|
|
MemoryGetActionInputBuffer(
|
|
UINT32 size // Size, in bytes, required for the input
|
|
// unmarshaling
|
|
)
|
|
{
|
|
BYTE *buf = NULL;
|
|
if(size > 0)
|
|
{
|
|
// In this implementation, a static buffer is set aside for action output.
|
|
// Other implementations may apply additional optimization based on command
|
|
// code or other factors.
|
|
UINT32 *p = s_actionInputBuffer;
|
|
buf = (BYTE *)p;
|
|
pAssert(size < sizeof(s_actionInputBuffer));
|
|
// size of an element in the buffer
|
|
#define SZ sizeof(s_actionInputBuffer[0])
|
|
for(size = (size + SZ - 1) / SZ; size > 0; size--)
|
|
*p++ = 0;
|
|
#undef SZ
|
|
}
|
|
return buf;
|
|
}
|
|
//
|
|
//
|
|
// MemoryGetActionOutputBuffer()
|
|
//
|
|
// This function returns the address of the buffer into which the command action code places its output
|
|
// values.
|
|
//
|
|
void *
|
|
MemoryGetActionOutputBuffer(
|
|
TPM_CC command // Command that requires the buffer
|
|
)
|
|
{
|
|
// In this implementation, a static buffer is set aside for action output.
|
|
// Other implementations may apply additional optimization based on the command
|
|
// code or other factors.
|
|
command = 0; // Unreferenced parameter
|
|
return s_actionOutputBuffer;
|
|
}
|
|
#endif // EMBEDDED_MODE ^^^^^ not defined.
|
|
|
|
//
|
|
//
|
|
// MemoryGetResponseBuffer()
|
|
//
|
|
// This function returns the address into which the command response is marshaled from values in the
|
|
// action output buffer.
|
|
//
|
|
BYTE*
|
|
MemoryGetResponseBuffer(
|
|
TPM_CC command // Command that requires the buffer
|
|
)
|
|
{
|
|
// In this implementation, a static buffer is set aside for responses.
|
|
// Other implementation may apply additional optimization based on the command
|
|
// code or other factors.
|
|
command = 0; // Unreferenced parameter
|
|
return s_responseBuffer;
|
|
}
|
|
//
|
|
//
|
|
// MemoryRemoveTrailingZeros()
|
|
//
|
|
// This function is used to adjust the length of an authorization value. It adjusts the size of the TPM2B so
|
|
// that it does not include octets at the end of the buffer that contain zero. The function returns the number
|
|
// of non-zero octets in the buffer.
|
|
//
|
|
UINT16
|
|
MemoryRemoveTrailingZeros (
|
|
TPM2B_AUTH *auth // IN/OUT: value to adjust
|
|
)
|
|
{
|
|
BYTE *a = &auth->t.buffer[auth->t.size-1];
|
|
for(; auth->t.size > 0; auth->t.size--)
|
|
{
|
|
if(*a--)
|
|
break;
|
|
}
|
|
return auth->t.size;
|
|
}
|