Line | Count | Source |
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 __attribute__((noinline)) 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 | 315 | { |
35 | 315 | if(destination == NULL || source == NULL) |
36 | 0 | return; |
37 | 315 | pAssert(size <= dSize); |
38 | 315 | __builtin_memmove(destination, source, size); |
39 | 315 | } |
40 | | // |
41 | | // MemoryEqual() |
42 | | // |
43 | | // This function indicates if two buffers have the same values in the indicated number of bytes. |
44 | | // |
45 | | // Return Value Meaning |
46 | | // |
47 | | // TRUE all octets are the same |
48 | | // FALSE all octets are not the same |
49 | | // |
50 | | LIB_EXPORT BOOL |
51 | | MemoryEqual( |
52 | | const void *buffer1, // IN: compare buffer1 |
53 | | const void *buffer2, // IN: compare buffer2 |
54 | | UINT32 size // IN: size of bytes being compared |
55 | | ) |
56 | 52 | { |
57 | 52 | BOOL diff = FALSE; |
58 | 52 | const BYTE *b1, *b2; |
59 | 52 | b1 = (BYTE *)buffer1; |
60 | 52 | b2 = (BYTE *)buffer2; |
61 | | // Compare all bytes so that there is no leakage of information |
62 | | // due to timing differences. |
63 | 148 | for(; size > 0; size--) |
64 | 96 | diff |= *b1++ ^ *b2++; |
65 | 52 | return !diff; |
66 | 52 | } |
67 | | // |
68 | | // |
69 | | // MemoryCopy2B() |
70 | | // |
71 | | // This function copies a TPM2B. This can be used when the TPM2B types are the same or different. No |
72 | | // size checking is done on the destination so the caller should make sure that the destination is large |
73 | | // enough. |
74 | | // |
75 | | // This function returns the number of octets in the data buffer of the TPM2B. |
76 | | // |
77 | | LIB_EXPORT INT16 |
78 | | MemoryCopy2B( |
79 | | TPM2B *dest, // OUT: receiving TPM2B |
80 | | const TPM2B *source, // IN: source TPM2B |
81 | | UINT16 dSize // IN: size of the receiving buffer |
82 | | ) |
83 | 3 | { |
84 | 3 | if(dest == NULL) |
85 | 0 | return 0; |
86 | 3 | if(source == NULL) |
87 | 0 | dest->size = 0; |
88 | 3 | else |
89 | 3 | { |
90 | 3 | dest->size = source->size; |
91 | 3 | MemoryMove(dest->buffer, source->buffer, dest->size, dSize); |
92 | 3 | } |
93 | 3 | return dest->size; |
94 | 3 | } |
95 | | // |
96 | | // |
97 | | // MemoryConcat2B() |
98 | | // |
99 | | // This function will concatenate the buffer contents of a TPM2B to an the buffer contents of another TPM2B |
100 | | // and adjust the size accordingly (a := (a | b)). |
101 | | // |
102 | | LIB_EXPORT void |
103 | | MemoryConcat2B( |
104 | | TPM2B *aInOut, // IN/OUT: destination 2B |
105 | | TPM2B *bIn, // IN: second 2B |
106 | | UINT16 aSize // IN: The size of aInOut.buffer (max values for |
107 | | // aInOut.size) |
108 | | ) |
109 | 0 | { |
110 | 0 | MemoryMove(&aInOut->buffer[aInOut->size], |
111 | 0 | bIn->buffer, |
112 | 0 | bIn->size, |
113 | 0 | aSize - aInOut->size); |
114 | 0 | aInOut->size = aInOut->size + bIn->size; |
115 | 0 | return; |
116 | 0 | } |
117 | | // |
118 | | // |
119 | | // Memory2BEqual() |
120 | | // |
121 | | // This function will compare two TPM2B structures. To be equal, they need to be the same size and the |
122 | | // buffer contexts need to be the same in all octets. |
123 | | // |
124 | | // Return Value Meaning |
125 | | // |
126 | | // TRUE size and buffer contents are the same |
127 | | // FALSE size or buffer contents are not the same |
128 | | // |
129 | | LIB_EXPORT BOOL |
130 | | Memory2BEqual( |
131 | | const TPM2B *aIn, // IN: compare value |
132 | | const TPM2B *bIn // IN: compare value |
133 | | ) |
134 | 54 | { |
135 | 54 | if(aIn->size != bIn->size) |
136 | 2 | return FALSE; |
137 | 52 | return MemoryEqual(aIn->buffer, bIn->buffer, aIn->size); |
138 | 54 | } |
139 | | // |
140 | | // |
141 | | // MemorySet() |
142 | | // |
143 | | // This function will set all the octets in the specified memory range to the specified octet value. |
144 | | // |
145 | | // NOTE: the dSize parameter forces the caller to know how big the receiving buffer is to make sure that there is no |
146 | | // possibility that the caller will inadvertently run over the end of the buffer. |
147 | | // |
148 | | LIB_EXPORT void |
149 | | MemorySet( |
150 | | void *destination, // OUT: memory destination |
151 | | char value, // IN: fill value |
152 | | UINT32 size // IN: number of octets to fill |
153 | | ) |
154 | 27.1k | { |
155 | 27.1k | char *p = (char *)destination; |
156 | 2.25M | while (size--) |
157 | 2.22M | *p++ = value; |
158 | 27.1k | return; |
159 | 27.1k | } |
160 | | #ifndef EMBEDDED_MODE |
161 | | // |
162 | | // |
163 | | // MemoryGetActionInputBuffer() |
164 | | // |
165 | | // This function returns the address of the buffer into which the command parameters will be unmarshaled in |
166 | | // preparation for calling the command actions. |
167 | | // |
168 | | BYTE * |
169 | | MemoryGetActionInputBuffer( |
170 | | UINT32 size // Size, in bytes, required for the input |
171 | | // unmarshaling |
172 | | ) |
173 | 0 | { |
174 | 0 | BYTE *buf = NULL; |
175 | 0 | if(size > 0) |
176 | 0 | { |
177 | | // In this implementation, a static buffer is set aside for action output. |
178 | | // Other implementations may apply additional optimization based on command |
179 | | // code or other factors. |
180 | 0 | UINT32 *p = s_actionInputBuffer; |
181 | 0 | buf = (BYTE *)p; |
182 | 0 | pAssert(size < sizeof(s_actionInputBuffer)); |
183 | | // size of an element in the buffer |
184 | 0 | #define SZ sizeof(s_actionInputBuffer[0]) |
185 | 0 | for(size = (size + SZ - 1) / SZ; size > 0; size--) |
186 | 0 | *p++ = 0; |
187 | 0 | #undef SZ |
188 | 0 | } |
189 | 0 | return buf; |
190 | 0 | } |
191 | | // |
192 | | // |
193 | | // MemoryGetActionOutputBuffer() |
194 | | // |
195 | | // This function returns the address of the buffer into which the command action code places its output |
196 | | // values. |
197 | | // |
198 | | void * |
199 | | MemoryGetActionOutputBuffer( |
200 | | TPM_CC command // Command that requires the buffer |
201 | | ) |
202 | 0 | { |
203 | | // In this implementation, a static buffer is set aside for action output. |
204 | | // Other implementations may apply additional optimization based on the command |
205 | | // code or other factors. |
206 | 0 | command = 0; // Unreferenced parameter |
207 | 0 | return s_actionOutputBuffer; |
208 | 0 | } |
209 | | #endif // EMBEDDED_MODE ^^^^^ not defined. |
210 | | |
211 | | // |
212 | | // |
213 | | // MemoryGetResponseBuffer() |
214 | | // |
215 | | // This function returns the address into which the command response is marshaled from values in the |
216 | | // action output buffer. |
217 | | // |
218 | | BYTE* |
219 | | MemoryGetResponseBuffer( |
220 | | TPM_CC command // Command that requires the buffer |
221 | | ) |
222 | 1.61k | { |
223 | | // In this implementation, a static buffer is set aside for responses. |
224 | | // Other implementation may apply additional optimization based on the command |
225 | | // code or other factors. |
226 | 1.61k | command = 0; // Unreferenced parameter |
227 | 1.61k | return s_responseBuffer; |
228 | 1.61k | } |
229 | | // |
230 | | // |
231 | | // MemoryRemoveTrailingZeros() |
232 | | // |
233 | | // This function is used to adjust the length of an authorization value. It adjusts the size of the TPM2B so |
234 | | // that it does not include octets at the end of the buffer that contain zero. The function returns the number |
235 | | // of non-zero octets in the buffer. |
236 | | // |
237 | | UINT16 |
238 | | MemoryRemoveTrailingZeros ( |
239 | | TPM2B_AUTH *auth // IN/OUT: value to adjust |
240 | | ) |
241 | 53 | { |
242 | 53 | while (auth->t.size > 0 && !auth->t.buffer[auth->t.size - 1]) |
243 | 0 | auth->t.size--; |
244 | | |
245 | 53 | return auth->t.size; |
246 | 53 | } |