Coverage Report

Created: 2025-08-26 06:27

/src/tpm2/MemoryLib.c
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
}