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
MemoryMove(void * destination,const void * source,UINT32 size,UINT32 dSize)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
MemoryEqual(const void * buffer1,const void * buffer2,UINT32 size)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 diff = FALSE;
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 diff |= *b1++ ^ *b2++;
86 return !diff;
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
MemoryCopy2B(TPM2B * dest,const TPM2B * source,UINT16 dSize)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
MemoryConcat2B(TPM2B * aInOut,TPM2B * bIn,UINT16 aSize)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
Memory2BEqual(const TPM2B * aIn,const TPM2B * bIn)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
MemorySet(void * destination,char value,UINT32 size)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 *
MemoryGetActionInputBuffer(UINT32 size)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 *
MemoryGetActionOutputBuffer(TPM_CC command)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*
MemoryGetResponseBuffer(TPM_CC command)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
MemoryRemoveTrailingZeros(TPM2B_AUTH * auth)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