• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Microsoft Reference Implementation for TPM 2.0
2  *
3  *  The copyright in this software is being made available under the BSD License,
4  *  included below. This software may be subject to other third party and
5  *  contributor rights, including patent rights, and no such rights are granted
6  *  under this license.
7  *
8  *  Copyright (c) Microsoft Corporation
9  *
10  *  All rights reserved.
11  *
12  *  BSD License
13  *
14  *  Redistribution and use in source and binary forms, with or without modification,
15  *  are permitted provided that the following conditions are met:
16  *
17  *  Redistributions of source code must retain the above copyright notice, this list
18  *  of conditions and the following disclaimer.
19  *
20  *  Redistributions in binary form must reproduce the above copyright notice, this
21  *  list of conditions and the following disclaimer in the documentation and/or
22  *  other materials provided with the distribution.
23  *
24  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28  *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include <assert.h>
37 
38 #include "Tpm.h"
39 #include "Marshal.h"
40 #include "TableMarshal.h"
41 
42 #if TABLE_DRIVEN_MARSHAL
43 
44 extern ArrayMarshal_mst ArrayLookupTable[];
45 
46 extern UINT16 MarshalLookupTable[];
47 
48 typedef struct { int a; } External_Structure_t;
49 
50 extern struct Exernal_Structure_t MarshalData;
51 
52 #define IS_SUCCESS(UNMARSHAL_FUNCTION)                                              \
53     (TPM_RC_SUCCESS == (result = (UNMARSHAL_FUNCTION)))
54 
55 marshalIndex_t IntegerDispatch[] = {
56     UINT8_MARSHAL_REF, UINT16_MARSHAL_REF, UINT32_MARSHAL_REF, UINT64_MARSHAL_REF,
57     INT8_MARSHAL_REF,  INT16_MARSHAL_REF,  INT32_MARSHAL_REF,  INT64_MARSHAL_REF
58 };
59 
60 #if 1
61 #define GetDescriptor(reference)                                                    \
62     ((MarshalHeader_mst *)(((BYTE *)(&MarshalData)) + (reference & NULL_MASK)))
63 #else
GetDescriptor(marshalIndex_t index)64 static const MarshalHeader_mst *GetDescriptor(marshalIndex_t index)
65 {
66     const MarshalHeader_mst    *mst = MarshalLookupTable[index & NULL_MASK];
67     return mst;
68 }
69 #endif
70 
71 #define GetUnionDescriptor(_index_)                                                 \
72     ((UnionMarshal_mst *)GetDescriptor(_index_))
73 #define GetArrayDescriptor(_index_)                                                 \
74     ((ArrayMarshal_mst *))(ArrayLookupTable[_index_ & NULL_MASK])
75 
76 //*** GetUnmarshaledInteger()
77 // Gets the unmarshaled value and normalizes it to a UIN32 for other
78 // processing (comparisons and such).
GetUnmarshaledInteger(marshalIndex_t type,const void * target)79 static UINT32 GetUnmarshaledInteger(
80     marshalIndex_t       type,
81     const void          *target
82 )
83 {
84     int     size = (type & SIZE_MASK);
85 //
86     if(size == FOUR_BYTES)
87         return *((UINT32 *)target);
88     if(type & IS_SIGNED)
89     {
90         if(size == TWO_BYTES)
91             return (UINT32)*((int16_t *)target);
92         return (UINT32)*((int8_t *)target);
93     }
94     if(size == TWO_BYTES)
95         return (UINT32)*((UINT16 *)target);
96     return (UINT32)*((UINT8 *)target);
97 }
98 
GetSelector(void * structure,const UINT16 * values,UINT16 descriptor)99 static UINT32 GetSelector(
100     void                *structure,
101     const UINT16        *values,
102     UINT16               descriptor
103 )
104 {
105     unsigned             sel = GET_ELEMENT_NUMBER(descriptor);
106     // Get the offset of the value in the unmarshaled structure
107     const UINT16        *entry = &values[(sel * 3)];
108 //
109     return GetUnmarshaledInteger(GET_ELEMENT_SIZE(entry[0]),
110                         ((UINT8 *)structure) + entry[2]);
111 }
112 
UnmarshalBytes(UINT8 * target,UINT8 ** buffer,INT32 * size,int count)113 static TPM_RC UnmarshalBytes(
114     UINT8               *target,        // IN/OUT: place to put the bytes
115     UINT8               **buffer,       // IN/OUT: source of the input data
116     INT32               *size,          // IN/OUT: remaining bytes in the input buffer
117     int                  count          // IN: number of bytes to get
118 )
119 {
120     if((*size -= count) >= 0)
121     {
122         memcpy(target, *buffer, count);
123         *buffer += count;
124         return TPM_RC_SUCCESS;
125     }
126     return TPM_RC_INSUFFICIENT;
127 }
128 
129 //*** MarshalBytes()
130 // Marshal an array of bytes.
MarshalBytes(UINT8 * source,UINT8 ** buffer,INT32 * size,int32_t count)131 static UINT16 MarshalBytes(
132     UINT8               *source,
133     UINT8               **buffer,
134     INT32               *size,
135     int32_t              count
136 )
137 {
138     if(buffer != NULL)
139     {
140         if(size != NULL && (size -= count) < 0)
141             return 0;
142         memcpy(*buffer, source, count);
143         *buffer += count;
144     }
145     return (UINT16)count;
146 }
147 
148 //*** ArrayUnmarshal()
149 // Unmarshal an array. The 'index' is of the form: 'type'_ARRAY_MARSHAL_INDEX.
ArrayUnmarshal(UINT16 index,UINT8 * target,UINT8 ** buffer,INT32 * size,UINT32 count)150 static TPM_RC ArrayUnmarshal(
151     UINT16               index,         // IN: the type of the array
152     UINT8               *target,        // IN: target for the data
153     UINT8               **buffer,       // IN/OUT: place to get the data
154     INT32               *size,          // IN/OUT: remaining unmarshal data
155     UINT32               count          // IN: number of values of 'index' to
156                                         //      unmarshal
157 )
158 {
159     marshalIndex_t       which = ArrayLookupTable[index & NULL_MASK].type;
160     UINT16               stride = ArrayLookupTable[index & NULL_MASK].stride;
161     TPM_RC               result;
162 //
163     if(stride == 1) // A byte array
164         result = UnmarshalBytes(target, buffer, size, count);
165     else
166     {
167         which |= index & NULL_FLAG;
168         for(result = TPM_RC_SUCCESS; count > 0; target += stride, count--)
169             if(!IS_SUCCESS(Unmarshal(which, target, buffer, size)))
170                 break;
171     }
172     return result;
173 }
174 
175 //*** ArrayMarshal()
ArrayMarshal(UINT16 index,UINT8 * source,UINT8 ** buffer,INT32 * size,UINT32 count)176 static UINT16 ArrayMarshal(
177     UINT16               index,         // IN: the type of the array
178     UINT8               *source,        // IN: source of the data
179     UINT8               **buffer,       // IN/OUT: place to put the data
180     INT32               *size,          // IN/OUT: amount of space for the data
181     UINT32               count          // IN: number of values of 'index' to marshal
182 )
183 {
184     marshalIndex_t      which = ArrayLookupTable[index & NULL_MASK].type;
185     UINT16              stride = ArrayLookupTable[index & NULL_MASK].stride;
186     UINT16              retVal;
187 //
188     if(stride == 1) // A byte array
189         return MarshalBytes(source, buffer, size, count);
190     which |= index & NULL_FLAG;
191     for(retVal = 0
192         ; count > 0
193         ; source += stride, count--)
194         retVal += Marshal(which, source, buffer, size);
195 
196     return retVal;
197 }
198 
199 //***UnmarshalUnion()
200 TPM_RC
UnmarshalUnion(UINT16 typeIndex,void * target,UINT8 ** buffer,INT32 * size,UINT32 selector)201 UnmarshalUnion(
202     UINT16               typeIndex,         // IN: the thing to unmarshal
203     void                *target,            // IN: were the data goes to
204     UINT8               **buffer,           // IN/OUT: the data source buffer
205     INT32               *size,              // IN/OUT: the remaining size
206     UINT32               selector
207 )
208 {
209     int                  i;
210     UnionMarshal_mst    *ut = GetUnionDescriptor(typeIndex);
211     marshalIndex_t       selected;
212 //
213     for(i = 0; i < ut->countOfselectors; i++)
214     {
215         if(selector == ut->selectors[i])
216         {
217             UINT8           *offset = ((UINT8 *)ut) + ut->offsetOfUnmarshalTypes;
218             // Get the selected thing to unmarshal
219             selected = ((marshalIndex_t *)offset)[i];
220             if(ut->modifiers & IS_ARRAY_UNION)
221                 return UnmarshalBytes(target, buffer, size, selected);
222             else
223             {
224                 // Propagate NULL_FLAG if the null flag was
225                 // propagated to the structure containing the union
226                 selected |= (typeIndex & NULL_FLAG);
227                 return Unmarshal(selected, target, buffer, size);
228             }
229         }
230     }
231     // Didn't find the value.
232     return TPM_RC_SELECTOR;
233 }
234 
235 //*** MarshalUnion()
236 UINT16
MarshalUnion(UINT16 typeIndex,void * source,UINT8 ** buffer,INT32 * size,UINT32 selector)237 MarshalUnion(
238     UINT16               typeIndex,         // IN: the thing to marshal
239     void                *source,            // IN: were the data comes from
240     UINT8               **buffer,           // IN/OUT: the data source buffer
241     INT32               *size,              // IN/OUT: the remaining size
242     UINT32               selector           // IN: the union selector
243 )
244 {
245     int                  i;
246     UnionMarshal_mst    *ut = GetUnionDescriptor(typeIndex);
247     marshalIndex_t       selected;
248 //
249     for(i = 0; i < ut->countOfselectors; i++)
250     {
251         if(selector == ut->selectors[i])
252         {
253             UINT8           *offset = ((UINT8 *)ut) + ut->offsetOfUnmarshalTypes;
254             // Get the selected thing to unmarshal
255             selected = ((marshalIndex_t *)offset)[i];
256             if(ut->modifiers & IS_ARRAY_UNION)
257                 return MarshalBytes(source, buffer, size, selected);
258             else
259                 return Marshal(selected, source, buffer, size);
260         }
261     }
262     if(size != NULL)
263         *size = -1;
264     return 0;
265 }
266 
267 TPM_RC
UnmarshalInteger(int iSize,void * target,UINT8 ** buffer,INT32 * size,UINT32 * value)268 UnmarshalInteger(
269     int                  iSize,             // IN: Number of bytes in the integer
270     void                *target,            // OUT: receives the integer
271     UINT8               **buffer,           // IN/OUT: source of the data
272     INT32               *size,              // IN/OUT: amount of data available
273     UINT32              *value              // OUT: optional copy of 'target'
274 )
275 {
276     // This is just to save typing
277 #define _MB_ (*buffer)
278     // The size is a power of two so convert to regular integer
279     int              bytes = (1 << (iSize & SIZE_MASK));
280 //
281     // Check to see if there is enough data to fulfill the request
282     if((*size -= bytes) >= 0)
283     {
284         // The most comon size
285         if(bytes == 4)
286         {
287             *((UINT32 *)target) = (UINT32)((((((_MB_[0] << 8) | _MB_[1]) << 8)
288                                            | _MB_[2]) << 8) | _MB_[3]);
289             // If a copy is needed, copy it.
290             if(value != NULL)
291                 *value = *((UINT32 *)target);
292         }
293         else if(bytes == 2)
294         {
295             *((UINT16 *)target) = (UINT16)((_MB_[0] << 8) | _MB_[1]);
296             // If a copy is needed, copy with the appropriate sign extension
297             if(value != NULL)
298             {
299                 if(iSize & IS_SIGNED)
300                     *value = (UINT32)(*((INT16 *)target));
301                 else
302                     *value = (UINT32)(*((UINT16 *)target));
303             }
304         }
305         else if(bytes == 1)
306         {
307             *((UINT8*)target) = (UINT8)_MB_[0];
308             // If a copy is needed, copy with the appropriate sign extension
309             if(value != NULL)
310             {
311                 if(iSize & IS_SIGNED)
312                     *value = (UINT32)(*((INT8 *)target));
313                 else
314                     *value = (UINT32)(*((UINT8 *)target));
315             }
316         }
317         else
318         {
319             // There is no input type that is a 64-bit value other than a UINT64. So
320             // there is no reason to do anything other than unmarshal it.
321             *((UINT64 *)target) = BYTE_ARRAY_TO_UINT64(*buffer);
322         }
323         *buffer += bytes;
324         return TPM_RC_SUCCESS;
325 #undef _MB_
326     }
327     return TPM_RC_INSUFFICIENT;
328 }
329 
330 //*** Unmarshal()
331 // This is the function that performs unmarshaling of different numbered types. Each
332 // TPM type has a number. The number is used to lookup the address of the data
333 // structure that describes how to unmarshal that data type.
334 //
335 TPM_RC
Unmarshal(UINT16 typeIndex,void * target,UINT8 ** buffer,INT32 * size)336 Unmarshal(
337     UINT16               typeIndex,         // IN: the thing to marshal
338     void                *target,            // IN: were the data goes from
339     UINT8               **buffer,           // IN/OUT: the data source buffer
340     INT32               *size               // IN/OUT: the remaining size
341 )
342 {
343     const MarshalHeader_mst     *sel;
344     TPM_RC                       result;
345 //
346     sel = GetDescriptor(typeIndex);
347     switch(sel->marshalType)
348     {
349         case UINT_MTYPE:
350         {
351             // A simple signed or unsigned integer value.
352             return UnmarshalInteger(sel->modifiers, target,
353                                       buffer, size, NULL);
354         }
355         case VALUES_MTYPE:
356         {
357             // This is the general-purpose structure that can handle things like
358             // TPMI_DH_PARENT that has multiple ranges, multiple singles and a
359             // 'null' value. When things cover a large range with holes in the range
360             // they can be turned into multiple ranges. There is no option for a bit
361             // field.
362             // The structure is:
363             //  typedef const struct ValuesMarshal_mst
364             //  {
365             //      UINT8           marshalType;        // VALUES_MTYPE
366             //      UINT8           modifiers;
367             //      UINT8           errorCode;
368             //      UINT8           ranges;
369             //      UINT8           singles;
370             //      UINT32          values[1];
371             //  } ValuesMarshal_mst;
372             // Unmarshal the base type
373             UINT32                   val;
374             if(IS_SUCCESS(UnmarshalInteger(sel->modifiers, target,
375                                            buffer, size, &val)))
376             {
377                 ValuesMarshal_mst   *vmt = ((ValuesMarshal_mst *)sel);
378                 const UINT32        *check = vmt->values;
379             //
380                 // if the TAKES_NULL flag is set, then the first entry in the values
381                 // list is the NULL value. Iy is not included in the 'ranges' or
382                 // 'singles' count.
383                 if((vmt->modifiers & TAKES_NULL) && (val == *check++))
384                 {
385                     if((typeIndex & NULL_FLAG) == 0)
386                         result = (TPM_RC)(sel->errorCode);
387                 }
388                 // No NULL value or input is not the NULL value
389                 else
390                 {
391                     int               i;
392                 //
393                     // Check all the min-max ranges.
394                     for(i = vmt->ranges - 1; i >= 0; check = &check[2], i--)
395                         if((UINT32)(val - check[0]) <= check[1])
396                             break;
397                     // if the input is in a selected range, then i >= 0
398                     if(i < 0)
399                     {
400                         // Not in any range, so check sigles
401                         for(i = vmt->singles - 1; i >= 0; i--)
402                             if(val == check[i])
403                                 break;
404                     }
405                     // If input not in range and not in any single so return error
406                     if(i < 0)
407                         result = (TPM_RC)(sel->errorCode);
408                 }
409             }
410             break;
411         }
412         case TABLE_MTYPE:
413         {
414             // This is a table with or without bit checking. The input is checked
415             // against each value in the table. If the value is in the table, and
416             // a bits table is present, then the bit field is checked to see if the
417             // indicated value is implemented. For example, if there is a table of
418             // allowed RSA key sizes and the 2nd entry matches, then the 2nd bit in
419             // the bit field is checked to see if that allowed size is implemented
420             // in this TPM.
421             //  typedef const struct TableMarshal_mst
422             //  {
423             //      UINT8           marshalType;        // TABLE_MTYPE
424             //      UINT8           modifiers;
425             //      UINT8           errorCode;
426             //      UINT8           singles;
427             //      UINT32          values[singles + 1 if TAKES_NULL];
428             //  } TableMarshal_mst;
429 
430             UINT32                  val;
431         //
432             // Unmarshal the base type
433             if(IS_SUCCESS(UnmarshalInteger(sel->modifiers, target,
434                                             buffer, size, &val)))
435             {
436                 TableMarshal_mst    *tmt = ((TableMarshal_mst *)sel);
437                 const UINT32        *check = tmt->values;
438             //
439                 // If this type has a null value, then it is the first value in the
440                 // list of values. It does not count in the count of values
441                 if((tmt->modifiers & TAKES_NULL) && (val == *check++))
442                 {
443                     if((typeIndex & NULL_FLAG) == 0)
444                         result = (TPM_RC)(sel->errorCode);
445                 }
446                 else
447                 {
448                     int               i;
449                 //
450                     // Process the singles
451                     for(i = tmt->singles - 1; i >= 0; i--)
452                     {
453                         // does the input value match the value in the table
454                         if(val == check[i])
455                         {
456                             // If there is an associated bit table, make sure that
457                             // the corresponding bit is SET
458                             if((HAS_BITS & tmt->modifiers)
459                                && (!IS_BIT_SET32(i, &(check[tmt->singles]))))
460                                 // if not SET, then this is a failure.
461                                 i = -1;
462                             break;
463                         }
464                     }
465                     // error if not found or bit not SET
466                     if(i < 0)
467                         result = (TPM_RC)(sel->errorCode);
468                 }
469             }
470             break;
471         }
472         case MIN_MAX_MTYPE:
473         {
474             // A MIN_MAX is a range. It can have a bit field and a NULL value that is
475             // outside of the range. If the input value is in the min-max range then
476             // it is valid unless there is an associated bit field. Otherwise, it
477             // it is only valid if the corresponding value in the bit field is SET.
478             // The min value is 'values[0]' or 'values[1]' if there is a NULL value.
479             // The max value is the value after min. The max value is in the table as
480             // max minus min. This allows 'val' to be subtracted from min and then
481             // checked against max with one unsigned comparison. If present, the bit
482             // field will be the first 'values' after max.
483             //  typedef const struct MinMaxMarshal_mst
484             //  {
485             //      UINT8           marshalType;        // MIN_MAX_MTYPE
486             //      UINT8           modifiers;
487             //      UINT8           errorCode;
488             //      UINT32          values[2 + 1 if TAKES_NULL];
489             //  } MinMaxMarshal_mst;
490             UINT32               val;
491         //
492             // A min-max has a range. It can have a bit-field that is indexed to the
493             // min value (something that matches min has a bit at 0. This is useful
494             // for algorithms. The min-max define a range of algorithms to be checked
495             // and the bit field can check to see if the algorithm in that range is
496             // allowed.
497             if(IS_SUCCESS(UnmarshalInteger(sel->modifiers, target,
498                                            buffer, size, &val)))
499             {
500                 MinMaxMarshal_mst   *mmt = (MinMaxMarshal_mst *)sel;
501                 const UINT32        *check = mmt->values;
502             //
503                 // If this type takes a NULL, see if it matches. This
504                 if((mmt->modifiers & TAKES_NULL) && (val == *check++))
505                 {
506                     if((typeIndex & NULL_FLAG) == 0)
507                         result = (TPM_RC)(mmt->errorCode);
508                 }
509                 else
510                 {
511                     val -= *check;
512                     if((val > check[1])
513                        || ((mmt->modifiers & HAS_BITS) &&
514                            !IS_BIT_SET32(val, &check[2])))
515                         result = (TPM_RC)(mmt->errorCode);
516                 }
517             }
518             break;
519         }
520         case ATTRIBUTES_MTYPE:
521         {
522             //  This is used for TPMA values.
523             UINT32                   mask;
524             AttributesMarshal_mst   *amt = (AttributesMarshal_mst *)sel;
525         //
526             if(IS_SUCCESS(UnmarshalInteger(sel->modifiers, target,
527                                     buffer, size, &mask)))
528             {
529                 if((mask & amt->attributeMask) != 0)
530                     result = TPM_RC_RESERVED_BITS;
531             }
532             break;
533         }
534         case STRUCTURE_MTYPE:
535         {
536             // A structure (not a union). A structure has elements (one defined per
537             // row). Three UINT16 values are used for each row. The first indicates
538             // the type of the entry. They choices are: simple, union, or array. A
539             // simple type can be a simple integer or another structure. It can also
540             // be a specific "interface type." For example, when a structure entry is
541             // a value that is used define the dimension of an array, the entry of
542             // the structure will reference a "synthetic" interface type, most often
543             // a min-max value. If the type of the entry is union or array, then the
544             // first value indicates which of the previous elements provides the union
545             // selector or the array dimension. That previous entry is referenced in
546             // the unmarshaled structure in memory (Not the marshaled buffer). The
547             // previous entry indicates the location in the structure of the value.
548             // The second entry of each structure entry indicated the index of the
549             // type associated with the entry. This is an index into the array of
550             // arrays or the union table (merged with the normal table in this
551             // implementation). The final entry is the offset in the unmarshaled
552             // structure where the value is located. This is the offsetof(STRUcTURE,
553             // element). This value is added to the input 'target' or 'source' value
554             // to determine where the value goes.
555             StructMarshal_mst   *mst = (StructMarshal_mst *)sel;
556             int                  i;
557             const UINT16        *value = mst->values;
558         //
559             for(result = TPM_RC_SUCCESS, i = mst->elements
560                 ; (TPM_RC_SUCCESS == result) && (i > 0)
561                 ; value = &value[3], i--)
562             {
563                 UINT16           descriptor = value[0];
564                 marshalIndex_t   index = value[1];
565                 // The offset of the object in the structure is in the last value in
566                 // the triplet. Add that value to the start of the structure
567                 UINT8           *offset = ((UINT8 *)target) + value[2];
568             //
569                 if ((ELEMENT_PROPAGATE & descriptor)
570                     && (typeIndex & NULL_FLAG))
571                     index |= NULL_FLAG;
572                 switch(GET_ELEMENT_TYPE(descriptor))
573                 {
574                     case SIMPLE_STYPE:
575                     {
576                         result = Unmarshal(index, offset, buffer, size);
577                         break;
578                     }
579                     case UNION_STYPE:
580                     {
581                         UINT32               choice;
582                     //
583                         // Get the selector or array dimension value
584                         choice = GetSelector(target, mst->values, descriptor);
585                         result = UnmarshalUnion(index, offset, buffer, size, choice);
586                         break;
587                     }
588                     case ARRAY_STYPE:
589                     {
590                         UINT32            dimension;
591                     //
592                         dimension = GetSelector(target, mst->values, descriptor);
593                         result = ArrayUnmarshal(index, offset, buffer,
594                                                 size, dimension);
595                         break;
596                     }
597                     default:
598                         result = TPM_RC_FAILURE;
599                         break;
600                 }
601             }
602             break;
603         }
604         case TPM2B_MTYPE:
605         {
606             // A primitive TPM2B. A size and byte buffer. The single value (other than
607             // the tag) references the synthetic 'interface' value for the size
608             // parameter.
609             Tpm2bMarshal_mst        *m2bt = (Tpm2bMarshal_mst *)sel;
610         //
611             if(IS_SUCCESS(Unmarshal(m2bt->sizeIndex, target, buffer, size)))
612                 result = UnmarshalBytes(((TPM2B *)target)->buffer,
613                                buffer, size, *((UINT16 *)target));
614             break;
615         }
616         case TPM2BS_MTYPE:
617         {
618             // This is used when a TPM2B contains a structure.
619             Tpm2bsMarshal_mst   *m2bst = (Tpm2bsMarshal_mst *)sel;
620             INT32          count;
621         //
622             if(IS_SUCCESS(Unmarshal(m2bst->sizeIndex, target, buffer, size)))
623             {
624                 // fetch the size value and convert it to a 32-bit count value
625                 count = (int32_t)*((UINT16 *)target);
626                 if(count == 0)
627                 {
628                     if(m2bst->modifiers & SIZE_EQUAL)
629                         result = TPM_RC_SIZE;
630                 }
631                 else if((*size -= count) >= 0)
632                 {
633                     marshalIndex_t  index = m2bst->dataIndex;
634                 //
635                     // If this type propigates a null (PROPIGATE_NULL), propigate it
636                     if ((m2bst->modifiers & PROPAGATE_NULL)
637                         && (typeIndex & typeIndex))
638                         index |= NULL_FLAG;
639                     // The structure might not start two bytes after the start of the
640                     // size field. The offset to the start of the structure is between
641                     // 2 and 8 bytes. This is encoded into the low 4 bits of the
642                     // modifiers byte byte
643                     if(IS_SUCCESS(Unmarshal(index,
644                         ((UINT8 *)target) + (m2bst->modifiers & OFFSET_MASK),
645                                            buffer, &count)))
646                     {
647                         if(count != 0)
648                             result = TPM_RC_SIZE;
649                     }
650                 }
651                 else
652                     result = TPM_RC_INSUFFICIENT;
653             }
654             break;
655         }
656         case LIST_MTYPE:
657         {
658             // Used for a list. A list is a qualified 32-bit 'count' value followed
659             // by a type indicator.
660             ListMarshal_mst     *mlt = (ListMarshal_mst *)sel;
661             marshalIndex_t      index = mlt->arrayRef;
662         //
663             if(IS_SUCCESS(Unmarshal(mlt->sizeIndex, target, buffer, size)))
664             {
665                 // If this type propigates a null (PROPIGATE_NULL), propigate it
666                 if ((mlt->modifiers & PROPAGATE_NULL)
667                     && (typeIndex & NULL_FLAG))
668                     index |= NULL_FLAG;
669                 result = ArrayUnmarshal(index,
670                     ((UINT8 *)target) +(mlt->modifiers & OFFSET_MASK),
671                                         buffer, size, *((UINT32 *)target));
672             }
673             break;
674         }
675         case NULL_MTYPE:
676         {
677             result = TPM_RC_SUCCESS;
678             break;
679         }
680 #if 0
681         case COMPOSITE_MTYPE:
682         {
683             CompositeMarshal_mst    *mct = (CompositeMarshal_mst *)sel;
684             int                      i;
685             UINT8                   *buf = *buffer;
686             INT32                   sz = *size;
687         //
688             result = TPM_RC_VALUE;
689             for(i = GET_ELEMENT_COUNT(mct->modifiers) - 1; i <= 0; i--)
690             {
691                 marshalIndex_t      index = mct->types[i];
692             //
693                 // This type might take a null so set it in each called value, just
694                 // in case it is needed in that value. Only one value in each
695                 // composite should have the takes null SET.
696                 index |= typeIndex & NULL_MASK;
697                 result = Unmarshal(index, target, buffer, size);
698                 if(result == TPM_RC_SUCCESS)
699                     break;
700                 // Each of the composite values does its own unmarshaling. This
701                 // has some execution overhead if it is unmarshaled multiple times
702                 // but it saves code size in not having to reproduce the various
703                 // unmarshaling types that can be in a composite. So, what this means
704                 // is that the buffer pointer and size have to be reset for each
705                 // unmarshaled value.
706                 *buffer = buf;
707                 *size = sz;
708             }
709             break;
710         }
711 #endif // 0
712         default:
713         {
714             result = TPM_RC_FAILURE;
715             break;
716         }
717     }
718     return result;
719 }
720 
721 //*** Marshal()
722 // This is the function that drives marshaling of output. Because there is no
723 // validation of the output, there is a lot less code.
Marshal(UINT16 typeIndex,void * source,UINT8 ** buffer,INT32 * size)724 UINT16 Marshal(
725     UINT16               typeIndex,         // IN: the thing to marshal
726     void                *source,            // IN: were the data comes from
727     UINT8               **buffer,           // IN/OUT: the data source buffer
728     INT32               *size               // IN/OUT: the remaining size
729 )
730 {
731 #define _source  ((UINT8 *)source)
732 
733     const MarshalHeader_mst     *sel;
734     UINT16                       retVal;
735 //
736     sel = GetDescriptor(typeIndex);
737     switch(sel->marshalType)
738     {
739         case VALUES_MTYPE:
740         case UINT_MTYPE:
741         case TABLE_MTYPE:
742         case MIN_MAX_MTYPE:
743         case ATTRIBUTES_MTYPE:
744         case COMPOSITE_MTYPE:
745         {
746 #if BIG_ENDIAN_TPM
747 #define MM16    0
748 #define MM32    0
749 #define MM64    0
750 #else
751 // These flip the constant index values so that they count in reverse order when doing
752 // little-endian stuff
753 #define MM16    1
754 #define MM32    3
755 #define MM64    7
756 #endif
757 // Just change the name and cast the type of the input parameters for typing purposes
758 #define mb (*buffer)
759 #define _source ((UINT8 *)source)
760             retVal = (1 << (sel->modifiers & SIZE_MASK));
761             if(buffer != NULL)
762             {
763                 if((size == NULL) || ((*size -= retVal) >= 0))
764                 {
765                     if(retVal == 4)
766                     {
767                         mb[0 ^ MM32] = _source[0];
768                         mb[1 ^ MM32] = _source[1];
769                         mb[2 ^ MM32] = _source[2];
770                         mb[3 ^ MM32] = _source[3];
771                     }
772                     else if(retVal == 2)
773                     {
774                         mb[0 ^ MM16] = _source[0];
775                         mb[1 ^ MM16] = _source[1];
776                     }
777                     else if(retVal == 1)
778                         mb[0] = _source[0];
779                     else
780                     {
781                         mb[0 ^ MM64] = _source[0];
782                         mb[1 ^ MM64] = _source[1];
783                         mb[2 ^ MM64] = _source[2];
784                         mb[3 ^ MM64] = _source[3];
785                         mb[4 ^ MM64] = _source[4];
786                         mb[5 ^ MM64] = _source[5];
787                         mb[6 ^ MM64] = _source[6];
788                         mb[7 ^ MM64] = _source[7];
789                     }
790                     *buffer += retVal;
791                 }
792             }
793             break;
794         }
795         case STRUCTURE_MTYPE:
796         {
797 //#define _mst  ((StructMarshal_mst *)sel)
798             StructMarshal_mst *mst = ((StructMarshal_mst *)sel);
799             int              i;
800             const UINT16  *value = mst->values;
801 
802         //
803             for(retVal = 0, i = mst->elements; i > 0; value = &value[3], i--)
804             {
805                 UINT16           des = value[0];
806                 marshalIndex_t   index = value[1];
807                 UINT8           *offset = _source + value[2];
808             //
809                 switch(GET_ELEMENT_TYPE(des))
810                 {
811                     case UNION_STYPE:
812                     {
813                         UINT32           choice;
814                     //
815                         choice = GetSelector(source, mst->values, des);
816                         retVal += MarshalUnion(index, offset, buffer, size, choice);
817                         break;
818                     }
819                     case ARRAY_STYPE:
820                     {
821                         UINT32               count;
822                     //
823                         count = GetSelector(source, mst->values, des);
824                         retVal += ArrayMarshal(index, offset, buffer, size, count);
825                         break;
826                     }
827                     case SIMPLE_STYPE:
828                     default:
829                     {
830                         // This is either another structure or a simple type
831                         retVal += Marshal(index, offset, buffer, size);
832                         break;
833                     }
834                 }
835             }
836             break;
837         }
838         case TPM2B_MTYPE:
839         {
840             // Get the number of bytes being marshaled
841             INT32         val = (int32_t)*((UINT16 *)source);
842         //
843             retVal = Marshal(UINT16_MARSHAL_REF, source, buffer, size);
844 
845             // This is a standard 2B with a byte buffer
846             retVal += MarshalBytes(((TPM2B *)_source)->buffer, buffer, size, val);
847             break;
848         }
849         case TPM2BS_MTYPE: // A structure in a TPM2B
850         {
851             Tpm2bsMarshal_mst       *m2bst = (Tpm2bsMarshal_mst *)sel;
852             UINT8                   *offset;
853             UINT16                   amount;
854             UINT8                   *marshaledSize;
855         //
856             // Save the address of where the size should go
857             marshaledSize = *buffer;
858 
859             // marshal the size (checks the space and advanced the pointer)
860             retVal = Marshal(UINT16_MARSHAL_REF, source, buffer, size);
861 
862             // This gets the 'offsetof' the structure to marshal. It was placed in the
863             // modifiers byte because the offset from the start of the TPM2B to the
864             // start of the structure is going to be less than 8 and the modifiers
865             // byte isn't needed for anything else.
866             offset = _source + (m2bst->modifiers & SIGNED_MASK);
867 
868             // Marshal the structure and get its size
869             amount = Marshal(m2bst->dataIndex, offset, buffer, size);
870 
871             // put the size in the space used when the size was marshaled.
872             if(buffer != NULL)
873                 UINT16_TO_BYTE_ARRAY(amount, marshaledSize);
874             retVal += amount;
875             break;
876         }
877         case LIST_MTYPE:
878         {
879             ListMarshal_mst *    mlt = ((ListMarshal_mst *)sel);
880             UINT8               *offset = _source + (mlt->modifiers & SIGNED_MASK);
881             retVal = Marshal(UINT32_MARSHAL_REF, source, buffer, size);
882             retVal += ArrayMarshal((marshalIndex_t)(mlt->arrayRef), offset,
883                                    buffer, size, *((UINT32 *)source));
884             break;
885         }
886         case NULL_MTYPE:
887             retVal = 0;
888             break;
889        case ERROR_MTYPE:
890        default:
891         {
892             if(size != NULL)
893                *size = -1;
894             retVal = 0;
895             break;
896         }
897     }
898     return retVal;
899 
900 }
901 
902 #endif // TABLE_DRIVEN_MARSHAL
903