Home | History | Annotate | Download | only in tpm2
      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 {
     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
     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
     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
    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
    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
    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 *
    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 *
    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*
    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
    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