Line | Count | Source (jump to first uncovered line) |
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 | 293 | { |
35 | 293 | const BYTE *p = (BYTE *)source; |
36 | 293 | BYTE *q = (BYTE *)destination; |
37 | 293 | if(destination == NULL || source == NULL) |
38 | 0 | return; |
39 | 293 | 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 | 293 | dSize -= size; |
43 | 293 | if (p>q || (p+size <= q)) |
44 | 293 | { |
45 | 2.58k | while(size--) |
46 | 2.29k | *q++ = *p++; |
47 | 293 | } |
48 | | // If the destination buffer has a higher address than the |
49 | | // source, then move bytes from the end to the beginning. |
50 | 0 | else if (p < q) |
51 | 0 | { |
52 | 0 | p += size; |
53 | 0 | q += size; |
54 | | // |
55 | 0 | while (size--) |
56 | 0 | *--q = *--p; |
57 | 0 | } |
58 | | // If the source and destination address are the same, nothing to move. |
59 | 293 | return; |
60 | 293 | } |
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 | 50 | { |
78 | 50 | BOOL diff = FALSE; |
79 | 50 | const BYTE *b1, *b2; |
80 | 50 | b1 = (BYTE *)buffer1; |
81 | 50 | b2 = (BYTE *)buffer2; |
82 | | // Compare all bytes so that there is no leakage of information |
83 | | // due to timing differences. |
84 | 114 | for(; size > 0; size--) |
85 | 64 | diff |= *b1++ ^ *b2++; |
86 | 50 | return !diff; |
87 | 50 | } |
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 | 4 | { |
105 | 4 | if(dest == NULL) |
106 | 0 | return 0; |
107 | 4 | if(source == NULL) |
108 | 0 | dest->size = 0; |
109 | 4 | else |
110 | 4 | { |
111 | 4 | dest->size = source->size; |
112 | 4 | MemoryMove(dest->buffer, source->buffer, dest->size, dSize); |
113 | 4 | } |
114 | 4 | return dest->size; |
115 | 4 | } |
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 | 0 | { |
131 | 0 | MemoryMove(&aInOut->buffer[aInOut->size], |
132 | 0 | bIn->buffer, |
133 | 0 | bIn->size, |
134 | 0 | aSize - aInOut->size); |
135 | 0 | aInOut->size = aInOut->size + bIn->size; |
136 | 0 | return; |
137 | 0 | } |
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 | 51 | { |
156 | 51 | if(aIn->size != bIn->size) |
157 | 1 | return FALSE; |
158 | 50 | return MemoryEqual(aIn->buffer, bIn->buffer, aIn->size); |
159 | 51 | } |
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 | 25.9k | { |
176 | 25.9k | char *p = (char *)destination; |
177 | 2.14M | while (size--) |
178 | 2.11M | *p++ = value; |
179 | 25.9k | return; |
180 | 25.9k | } |
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 | 0 | { |
195 | 0 | BYTE *buf = NULL; |
196 | 0 | if(size > 0) |
197 | 0 | { |
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 | 0 | UINT32 *p = s_actionInputBuffer; |
202 | 0 | buf = (BYTE *)p; |
203 | 0 | pAssert(size < sizeof(s_actionInputBuffer)); |
204 | | // size of an element in the buffer |
205 | 0 | #define SZ sizeof(s_actionInputBuffer[0]) |
206 | 0 | for(size = (size + SZ - 1) / SZ; size > 0; size--) |
207 | 0 | *p++ = 0; |
208 | 0 | #undef SZ |
209 | 0 | } |
210 | 0 | return buf; |
211 | 0 | } |
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 | 0 | { |
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 | 0 | command = 0; // Unreferenced parameter |
228 | 0 | return s_actionOutputBuffer; |
229 | 0 | } |
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 | 1.54k | { |
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 | 1.54k | command = 0; // Unreferenced parameter |
248 | 1.54k | return s_responseBuffer; |
249 | 1.54k | } |
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 | 52 | { |
263 | 52 | while (auth->t.size > 0 && !auth->t.buffer[auth->t.size - 1]) |
264 | 0 | auth->t.size--; |
265 | | |
266 | 52 | return auth->t.size; |
267 | 52 | } |