You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
8.9 KiB
270 lines
8.9 KiB
// 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; |
|
}
|
|
|