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