blob: 178848e7d82dc10f4015c6f778f9a9762fbfcdc5 [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
Jocelyn Bohra4ed3aa2015-07-30 10:44:16 -07009#include "MemoryLib_fp.h"
Vadim Bendebury56797522015-05-20 10:32:25 -070010//
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//
Vadim Bendebury56797522015-05-20 10:32:25 -070062// 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{
nagendra modadugue760ff52017-05-11 15:17:16 -070078 BOOL diff = FALSE;
Vadim Bendebury56797522015-05-20 10:32:25 -070079 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--)
nagendra modadugue760ff52017-05-11 15:17:16 -070085 diff |= *b1++ ^ *b2++;
86 return !diff;
Vadim Bendebury56797522015-05-20 10:32:25 -070087}
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}
Vadim Bendebury7878aef2015-08-12 12:57:26 -0700181#ifndef EMBEDDED_MODE
Vadim Bendebury56797522015-05-20 10:32:25 -0700182//
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}
Vadim Bendebury7878aef2015-08-12 12:57:26 -0700230#endif // EMBEDDED_MODE ^^^^^ not defined.
231
Vadim Bendebury56797522015-05-20 10:32:25 -0700232//
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//
Jocelyn Bohra4ed3aa2015-07-30 10:44:16 -0700239BYTE*
Vadim Bendebury56797522015-05-20 10:32:25 -0700240MemoryGetResponseBuffer(
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}