blob: 730e4d3024d5ab3ed33582daaa708bdcfb2e67b5 [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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//
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//
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//
89LIB_EXPORT BOOL
90MemoryEqual(
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//
116LIB_EXPORT INT16
117MemoryCopy2B(
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//
141LIB_EXPORT void
142MemoryConcat2B(
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//
168LIB_EXPORT BOOL
169Memory2BEqual(
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//
187LIB_EXPORT void
188MemorySet(
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//
206BYTE *
207MemoryGetActionInputBuffer(
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//
236void *
237MemoryGetActionOutputBuffer(
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//
254BYTE *
255MemoryGetResponseBuffer(
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//
273UINT16
274MemoryRemoveTrailingZeros (
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}