Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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 "InternalRoutines.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 | // |
| 63 | // MemoryCopy() |
| 64 | // |
| 65 | // This function moves data from one place in memory to another. No safety checks of any type are |
| 66 | // performed. If the destination and source overlap, then the results are unpredictable. void MemoryCopy( |
| 67 | // |
| 68 | void *destination, // OUT: copy destination |
| 69 | // |
| 70 | void *source, // IN: copy source |
| 71 | UINT32 size, // IN: number of octets being copied |
| 72 | UINT32 dSize // IN: size of the receive buffer |
| 73 | // |
| 74 | // MemoryMove(destination, source, size, dSize); |
| 75 | // |
| 76 | //%#define MemoryCopy(destination, source, size, destSize) \ |
| 77 | //% MemoryMove((destination), (source), (size), (destSize)) |
| 78 | // |
| 79 | // |
| 80 | // MemoryEqual() |
| 81 | // |
| 82 | // This function indicates if two buffers have the same values in the indicated number of bytes. |
| 83 | // |
| 84 | // Return Value Meaning |
| 85 | // |
| 86 | // TRUE all octets are the same |
| 87 | // FALSE all octets are not the same |
| 88 | // |
| 89 | LIB_EXPORT BOOL |
| 90 | MemoryEqual( |
| 91 | const void *buffer1, // IN: compare buffer1 |
| 92 | const void *buffer2, // IN: compare buffer2 |
| 93 | UINT32 size // IN: size of bytes being compared |
| 94 | ) |
| 95 | { |
| 96 | BOOL equal = TRUE; |
| 97 | const BYTE *b1, *b2; |
| 98 | b1 = (BYTE *)buffer1; |
| 99 | b2 = (BYTE *)buffer2; |
| 100 | // Compare all bytes so that there is no leakage of information |
| 101 | // due to timing differences. |
| 102 | for(; size > 0; size--) |
| 103 | equal = (*b1++ == *b2++) && equal; |
| 104 | return equal; |
| 105 | } |
| 106 | // |
| 107 | // |
| 108 | // MemoryCopy2B() |
| 109 | // |
| 110 | // This function copies a TPM2B. This can be used when the TPM2B types are the same or different. No |
| 111 | // size checking is done on the destination so the caller should make sure that the destination is large |
| 112 | // enough. |
| 113 | // |
| 114 | // This function returns the number of octets in the data buffer of the TPM2B. |
| 115 | // |
| 116 | LIB_EXPORT INT16 |
| 117 | MemoryCopy2B( |
| 118 | TPM2B *dest, // OUT: receiving TPM2B |
| 119 | const TPM2B *source, // IN: source TPM2B |
| 120 | UINT16 dSize // IN: size of the receiving buffer |
| 121 | ) |
| 122 | { |
| 123 | if(dest == NULL) |
| 124 | return 0; |
| 125 | if(source == NULL) |
| 126 | dest->size = 0; |
| 127 | else |
| 128 | { |
| 129 | dest->size = source->size; |
| 130 | MemoryMove(dest->buffer, source->buffer, dest->size, dSize); |
| 131 | } |
| 132 | return dest->size; |
| 133 | } |
| 134 | // |
| 135 | // |
| 136 | // MemoryConcat2B() |
| 137 | // |
| 138 | // This function will concatenate the buffer contents of a TPM2B to an the buffer contents of another TPM2B |
| 139 | // and adjust the size accordingly (a := (a | b)). |
| 140 | // |
| 141 | LIB_EXPORT void |
| 142 | MemoryConcat2B( |
| 143 | TPM2B *aInOut, // IN/OUT: destination 2B |
| 144 | TPM2B *bIn, // IN: second 2B |
| 145 | UINT16 aSize // IN: The size of aInOut.buffer (max values for |
| 146 | // aInOut.size) |
| 147 | ) |
| 148 | { |
| 149 | MemoryMove(&aInOut->buffer[aInOut->size], |
| 150 | bIn->buffer, |
| 151 | bIn->size, |
| 152 | aSize - aInOut->size); |
| 153 | aInOut->size = aInOut->size + bIn->size; |
| 154 | return; |
| 155 | } |
| 156 | // |
| 157 | // |
| 158 | // Memory2BEqual() |
| 159 | // |
| 160 | // This function will compare two TPM2B structures. To be equal, they need to be the same size and the |
| 161 | // buffer contexts need to be the same in all octets. |
| 162 | // |
| 163 | // Return Value Meaning |
| 164 | // |
| 165 | // TRUE size and buffer contents are the same |
| 166 | // FALSE size or buffer contents are not the same |
| 167 | // |
| 168 | LIB_EXPORT BOOL |
| 169 | Memory2BEqual( |
| 170 | const TPM2B *aIn, // IN: compare value |
| 171 | const TPM2B *bIn // IN: compare value |
| 172 | ) |
| 173 | { |
| 174 | if(aIn->size != bIn->size) |
| 175 | return FALSE; |
| 176 | return MemoryEqual(aIn->buffer, bIn->buffer, aIn->size); |
| 177 | } |
| 178 | // |
| 179 | // |
| 180 | // MemorySet() |
| 181 | // |
| 182 | // This function will set all the octets in the specified memory range to the specified octet value. |
| 183 | // |
| 184 | // NOTE: the dSize parameter forces the caller to know how big the receiving buffer is to make sure that there is no |
| 185 | // possibility that the caller will inadvertently run over the end of the buffer. |
| 186 | // |
| 187 | LIB_EXPORT void |
| 188 | MemorySet( |
| 189 | void *destination, // OUT: memory destination |
| 190 | char value, // IN: fill value |
| 191 | UINT32 size // IN: number of octets to fill |
| 192 | ) |
| 193 | { |
| 194 | char *p = (char *)destination; |
| 195 | while (size--) |
| 196 | *p++ = value; |
| 197 | return; |
| 198 | } |
| 199 | // |
| 200 | // |
| 201 | // MemoryGetActionInputBuffer() |
| 202 | // |
| 203 | // This function returns the address of the buffer into which the command parameters will be unmarshaled in |
| 204 | // preparation for calling the command actions. |
| 205 | // |
| 206 | BYTE * |
| 207 | MemoryGetActionInputBuffer( |
| 208 | UINT32 size // Size, in bytes, required for the input |
| 209 | // unmarshaling |
| 210 | ) |
| 211 | { |
| 212 | BYTE *buf = NULL; |
| 213 | if(size > 0) |
| 214 | { |
| 215 | // In this implementation, a static buffer is set aside for action output. |
| 216 | // Other implementations may apply additional optimization based on command |
| 217 | // code or other factors. |
| 218 | UINT32 *p = s_actionInputBuffer; |
| 219 | buf = (BYTE *)p; |
| 220 | pAssert(size < sizeof(s_actionInputBuffer)); |
| 221 | // size of an element in the buffer |
| 222 | #define SZ sizeof(s_actionInputBuffer[0]) |
| 223 | for(size = (size + SZ - 1) / SZ; size > 0; size--) |
| 224 | *p++ = 0; |
| 225 | #undef SZ |
| 226 | } |
| 227 | return buf; |
| 228 | } |
| 229 | // |
| 230 | // |
| 231 | // MemoryGetActionOutputBuffer() |
| 232 | // |
| 233 | // This function returns the address of the buffer into which the command action code places its output |
| 234 | // values. |
| 235 | // |
| 236 | void * |
| 237 | MemoryGetActionOutputBuffer( |
| 238 | TPM_CC command // Command that requires the buffer |
| 239 | ) |
| 240 | { |
| 241 | // In this implementation, a static buffer is set aside for action output. |
| 242 | // Other implementations may apply additional optimization based on the command |
| 243 | // code or other factors. |
| 244 | command = 0; // Unreferenced parameter |
| 245 | return s_actionOutputBuffer; |
| 246 | } |
| 247 | // |
| 248 | // |
| 249 | // MemoryGetResponseBuffer() |
| 250 | // |
| 251 | // This function returns the address into which the command response is marshaled from values in the |
| 252 | // action output buffer. |
| 253 | // |
| 254 | BYTE * |
| 255 | MemoryGetResponseBuffer( |
| 256 | TPM_CC command // Command that requires the buffer |
| 257 | ) |
| 258 | { |
| 259 | // In this implementation, a static buffer is set aside for responses. |
| 260 | // Other implementation may apply additional optimization based on the command |
| 261 | // code or other factors. |
| 262 | command = 0; // Unreferenced parameter |
| 263 | return s_responseBuffer; |
| 264 | } |
| 265 | // |
| 266 | // |
| 267 | // MemoryRemoveTrailingZeros() |
| 268 | // |
| 269 | // This function is used to adjust the length of an authorization value. It adjusts the size of the TPM2B so |
| 270 | // that it does not include octets at the end of the buffer that contain zero. The function returns the number |
| 271 | // of non-zero octets in the buffer. |
| 272 | // |
| 273 | UINT16 |
| 274 | MemoryRemoveTrailingZeros ( |
| 275 | TPM2B_AUTH *auth // IN/OUT: value to adjust |
| 276 | ) |
| 277 | { |
| 278 | BYTE *a = &auth->t.buffer[auth->t.size-1]; |
| 279 | for(; auth->t.size > 0; auth->t.size--) |
| 280 | { |
| 281 | if(*a--) |
| 282 | break; |
| 283 | } |
| 284 | return auth->t.size; |
| 285 | } |