1// This file was extracted from the TCG Published 2// Trusted Platform Module Library 3// Part 4: Supporting Routines 4// Family "2.0" 5// Level 00 Revision 01.16 6// October 30, 2014 7 8#define MEMORY_LIB_C 9#include "MemoryLib_fp.h" 10// 11// These buffers are set aside to hold command and response values. In this implementation, it is not 12// guaranteed that the code will stop accessing the s_actionInputBuffer before starting to put values in the 13// s_actionOutputBuffer so different buffers are required. However, the s_actionInputBuffer and 14// s_responseBuffer are not needed at the same time and they could be the same buffer. 15// 16// Functions on BYTE Arrays 17// 18// MemoryMove() 19// 20// This function moves data from one place in memory to another. No safety checks of any type are 21// performed. If source and data buffer overlap, then the move is done as if an intermediate buffer were 22// used. 23// 24// NOTE: This function is used by MemoryCopy(), MemoryCopy2B(), and MemoryConcat2b() and requires that the caller 25// know the maximum size of the destination buffer so that there is no possibility of buffer overrun. 26// 27LIB_EXPORT void 28MemoryMove( 29 void *destination, // OUT: move destination 30 const void *source, // IN: move source 31 UINT32 size, // IN: number of octets to moved 32 UINT32 dSize // IN: size of the receive buffer 33 ) 34{ 35 const BYTE *p = (BYTE *)source; 36 BYTE *q = (BYTE *)destination; 37 if(destination == NULL || source == NULL) 38 return; 39 pAssert(size <= dSize); 40 // if the destination buffer has a lower address than the 41 // source, then moving bytes in ascending order is safe. 42 dSize -= size; 43 if (p>q || (p+size <= q)) 44 { 45 while(size--) 46 *q++ = *p++; 47 } 48 // If the destination buffer has a higher address than the 49 // source, then move bytes from the end to the beginning. 50 else if (p < q) 51 { 52 p += size; 53 q += size; 54// 55 while (size--) 56 *--q = *--p; 57 } 58 // If the source and destination address are the same, nothing to move. 59 return; 60} 61// 62// MemoryEqual() 63// 64// This function indicates if two buffers have the same values in the indicated number of bytes. 65// 66// Return Value Meaning 67// 68// TRUE all octets are the same 69// FALSE all octets are not the same 70// 71LIB_EXPORT BOOL 72MemoryEqual( 73 const void *buffer1, // IN: compare buffer1 74 const void *buffer2, // IN: compare buffer2 75 UINT32 size // IN: size of bytes being compared 76 ) 77{ 78 BOOL equal = TRUE; 79 const BYTE *b1, *b2; 80 b1 = (BYTE *)buffer1; 81 b2 = (BYTE *)buffer2; 82 // Compare all bytes so that there is no leakage of information 83 // due to timing differences. 84 for(; size > 0; size--) 85 equal = (*b1++ == *b2++) && equal; 86 return equal; 87} 88// 89// 90// MemoryCopy2B() 91// 92// This function copies a TPM2B. This can be used when the TPM2B types are the same or different. No 93// size checking is done on the destination so the caller should make sure that the destination is large 94// enough. 95// 96// This function returns the number of octets in the data buffer of the TPM2B. 97// 98LIB_EXPORT INT16 99MemoryCopy2B( 100 TPM2B *dest, // OUT: receiving TPM2B 101 const TPM2B *source, // IN: source TPM2B 102 UINT16 dSize // IN: size of the receiving buffer 103 ) 104{ 105 if(dest == NULL) 106 return 0; 107 if(source == NULL) 108 dest->size = 0; 109 else 110 { 111 dest->size = source->size; 112 MemoryMove(dest->buffer, source->buffer, dest->size, dSize); 113 } 114 return dest->size; 115} 116// 117// 118// MemoryConcat2B() 119// 120// This function will concatenate the buffer contents of a TPM2B to an the buffer contents of another TPM2B 121// and adjust the size accordingly (a := (a | b)). 122// 123LIB_EXPORT void 124MemoryConcat2B( 125 TPM2B *aInOut, // IN/OUT: destination 2B 126 TPM2B *bIn, // IN: second 2B 127 UINT16 aSize // IN: The size of aInOut.buffer (max values for 128 // aInOut.size) 129 ) 130{ 131 MemoryMove(&aInOut->buffer[aInOut->size], 132 bIn->buffer, 133 bIn->size, 134 aSize - aInOut->size); 135 aInOut->size = aInOut->size + bIn->size; 136 return; 137} 138// 139// 140// Memory2BEqual() 141// 142// This function will compare two TPM2B structures. To be equal, they need to be the same size and the 143// buffer contexts need to be the same in all octets. 144// 145// Return Value Meaning 146// 147// TRUE size and buffer contents are the same 148// FALSE size or buffer contents are not the same 149// 150LIB_EXPORT BOOL 151Memory2BEqual( 152 const TPM2B *aIn, // IN: compare value 153 const TPM2B *bIn // IN: compare value 154 ) 155{ 156 if(aIn->size != bIn->size) 157 return FALSE; 158 return MemoryEqual(aIn->buffer, bIn->buffer, aIn->size); 159} 160// 161// 162// MemorySet() 163// 164// This function will set all the octets in the specified memory range to the specified octet value. 165// 166// NOTE: the dSize parameter forces the caller to know how big the receiving buffer is to make sure that there is no 167// possibility that the caller will inadvertently run over the end of the buffer. 168// 169LIB_EXPORT void 170MemorySet( 171 void *destination, // OUT: memory destination 172 char value, // IN: fill value 173 UINT32 size // IN: number of octets to fill 174 ) 175{ 176 char *p = (char *)destination; 177 while (size--) 178 *p++ = value; 179 return; 180} 181#ifndef EMBEDDED_MODE 182// 183// 184// MemoryGetActionInputBuffer() 185// 186// This function returns the address of the buffer into which the command parameters will be unmarshaled in 187// preparation for calling the command actions. 188// 189BYTE * 190MemoryGetActionInputBuffer( 191 UINT32 size // Size, in bytes, required for the input 192 // unmarshaling 193 ) 194{ 195 BYTE *buf = NULL; 196 if(size > 0) 197 { 198 // In this implementation, a static buffer is set aside for action output. 199 // Other implementations may apply additional optimization based on command 200 // code or other factors. 201 UINT32 *p = s_actionInputBuffer; 202 buf = (BYTE *)p; 203 pAssert(size < sizeof(s_actionInputBuffer)); 204 // size of an element in the buffer 205#define SZ sizeof(s_actionInputBuffer[0]) 206 for(size = (size + SZ - 1) / SZ; size > 0; size--) 207 *p++ = 0; 208#undef SZ 209 } 210 return buf; 211} 212// 213// 214// MemoryGetActionOutputBuffer() 215// 216// This function returns the address of the buffer into which the command action code places its output 217// values. 218// 219void * 220MemoryGetActionOutputBuffer( 221 TPM_CC command // Command that requires the buffer 222 ) 223{ 224 // In this implementation, a static buffer is set aside for action output. 225 // Other implementations may apply additional optimization based on the command 226 // code or other factors. 227 command = 0; // Unreferenced parameter 228 return s_actionOutputBuffer; 229} 230#endif // EMBEDDED_MODE ^^^^^ not defined. 231 232// 233// 234// MemoryGetResponseBuffer() 235// 236// This function returns the address into which the command response is marshaled from values in the 237// action output buffer. 238// 239BYTE* 240MemoryGetResponseBuffer( 241 TPM_CC command // Command that requires the buffer 242 ) 243{ 244 // In this implementation, a static buffer is set aside for responses. 245 // Other implementation may apply additional optimization based on the command 246 // code or other factors. 247 command = 0; // Unreferenced parameter 248 return s_responseBuffer; 249} 250// 251// 252// MemoryRemoveTrailingZeros() 253// 254// This function is used to adjust the length of an authorization value. It adjusts the size of the TPM2B so 255// that it does not include octets at the end of the buffer that contain zero. The function returns the number 256// of non-zero octets in the buffer. 257// 258UINT16 259MemoryRemoveTrailingZeros ( 260 TPM2B_AUTH *auth // IN/OUT: value to adjust 261 ) 262{ 263 BYTE *a = &auth->t.buffer[auth->t.size-1]; 264 for(; auth->t.size > 0; auth->t.size--) 265 { 266 if(*a--) 267 break; 268 } 269 return auth->t.size; 270} 271