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 // 27 LIB_EXPORT void 28 MemoryMove( 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 // 71 LIB_EXPORT BOOL 72 MemoryEqual( 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 // 98 LIB_EXPORT INT16 99 MemoryCopy2B( 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 // 123 LIB_EXPORT void 124 MemoryConcat2B( 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 // 150 LIB_EXPORT BOOL 151 Memory2BEqual( 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 // 169 LIB_EXPORT void 170 MemorySet( 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 // 189 BYTE * 190 MemoryGetActionInputBuffer( 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 // 219 void * 220 MemoryGetActionOutputBuffer( 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 // 239 BYTE* 240 MemoryGetResponseBuffer( 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 // 258 UINT16 259 MemoryRemoveTrailingZeros ( 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