• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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          equal = TRUE;
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           equal = (*b1++ == *b2++) && equal;
86       return equal;
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