Home | History | Annotate | Download | only in generator
      1 # Copyright 2015 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """A code generator for TPM 2.0 structures.
      6 
      7 The structure generator provides classes to create various objects
      8 (structures, unions, constants, etc.) and then convert the set of generated
      9 objects into valid C files named tpm_generated.{h,c}.
     10 
     11 """
     12 
     13 from __future__ import print_function
     14 
     15 import datetime
     16 import re
     17 
     18 from subprocess import call
     19 
     20 _BASIC_TYPES = ['uint8_t', 'int8_t', 'uint16_t', 'int16_t', 'uint32_t',
     21                 'int32_t', 'uint64_t', 'int64_t']
     22 _OUTPUT_FILE_H = 'tpm_generated.h'
     23 _OUTPUT_FILE_CC = 'tpm_generated.c'
     24 COPYRIGHT_HEADER = (
     25     '// Copyright %d The Chromium OS Authors. All rights reserved.\n'
     26     '// Use of this source code is governed by a BSD-style license that can '
     27     'be\n'
     28     '// found in the LICENSE file.\n'
     29     '\n'
     30     '// THIS CODE IS GENERATED - DO NOT MODIFY!\n' %
     31     datetime.datetime.now().year)
     32 HEADER_FILE_GUARD_HEADER = """
     33 #ifndef %(name)s
     34 #define %(name)s
     35 """
     36 HEADER_FILE_GUARD_FOOTER = """
     37 #endif  // %(name)s
     38 """
     39 _HEADER_FILE_INCLUDES = """
     40 #include <endian.h>
     41 #include <string.h>
     42 
     43 #include "TPM_Types.h"
     44 #include "Tpm.h"
     45 """
     46 _IMPLEMENTATION_FILE_INCLUDES = """
     47 #include "tpm_generated.h"
     48 """
     49 # Function signatures for generated marshaling code are specified in TCG TPM2.0
     50 # Library Specification, Part 4: Supporting Routines, sections 4.2.2 and 4.2.3.
     51 _MARSHAL_BASIC_TYPE = """
     52 UINT16 %(type)s_Marshal(%(type)s *source, BYTE **buffer, INT32 *size) {
     53   %(type)s value_net = *source;
     54   if (!size || *size < sizeof(%(type)s)) {
     55     return 0;  // Nothing has been marshaled.
     56   }
     57   switch (sizeof(%(type)s)) {
     58     case 2:
     59       value_net = htobe16(*source);
     60       break;
     61     case 4:
     62       value_net = htobe32(*source);
     63       break;
     64     case 8:
     65       value_net = htobe64(*source);
     66       break;
     67     default:
     68       break;
     69   }
     70   memcpy(*buffer, &value_net, sizeof(%(type)s));
     71   *buffer += sizeof(%(type)s);
     72   *size -= sizeof(%(type)s);
     73   return sizeof(%(type)s);
     74 }
     75 
     76 TPM_RC %(type)s_Unmarshal(%(type)s *target, BYTE **buffer, INT32 *size) {
     77   %(type)s value_net = 0;
     78   if (!size || *size < sizeof(%(type)s)) {
     79     return TPM_RC_INSUFFICIENT;
     80   }
     81   memcpy(&value_net, *buffer, sizeof(%(type)s));
     82   switch (sizeof(%(type)s)) {
     83     case 2:
     84       *target = be16toh(value_net);
     85       break;
     86     case 4:
     87       *target = be32toh(value_net);
     88       break;
     89     case 8:
     90       *target = be64toh(value_net);
     91       break;
     92     default:
     93       *target = value_net;
     94   }
     95   *buffer += sizeof(%(type)s);
     96   *size -= sizeof(%(type)s);
     97   return TPM_RC_SUCCESS;
     98 }
     99 """
    100 _STANDARD_MARSHAL_DECLARATION = """
    101 UINT16 %(type)s_Marshal(
    102     %(type)s *source,
    103     BYTE **buffer,
    104     INT32 *size);
    105 
    106 TPM_RC %(type)s_Unmarshal(
    107     %(type)s *target,
    108     BYTE **buffer,
    109     INT32 *size);
    110 """
    111 
    112 
    113 def _IsTPM2B(name):
    114   return name.startswith('TPM2B_')
    115 
    116 
    117 class Field(object):
    118   """Represents a field in TPM structure or union.
    119 
    120   This object is used in several not fully overlapping cases, not all
    121   attributes apply to all use cases.
    122 
    123   The 'array_size' and 'run_time_size' attributes below are related to the
    124   following code example:
    125 
    126   struct {
    127     int size;
    128     byte array[MAX_SIZE]
    129   } object.
    130 
    131   In this structure the actual number of bytes in the array could be anything
    132   from zero to MAX_SIZE. The field 'size' denotes the actual number of
    133   elements at run time. So, when this object is constructed, array_size is
    134   'MAX_SIZE' and run_time_size is 'size'.
    135 
    136   The 'selector_value' attribute is used to associate union fields with
    137   certain object types. For instance
    138 
    139   typedef union {
    140     TPM2B_PUBLIC_KEY_RSA  rsa;
    141     TPMS_ECC_POINT        ecc;
    142   } TPMU_PUBLIC_ID;
    143 
    144   the field named 'rsa' will have its 'selector_value' set to 'TPM_ALG_RSA'.
    145 
    146   Attributes:
    147     field_type: a string, the type of field.
    148     field_name: a string, the name of the field.
    149     array_size: a string, see example above
    150     run_time_size: a string, see example above
    151     selector_value: a string, see example above
    152     conditional_value: a string, necessary for validation when unmarshaling.
    153                        Some types have a value that is allowed for some
    154                        commands but not others. E.g. 'TPM_RS_PW' is a
    155                        conditional value for the 'TPMI_SH_AUTH_SESSION' type
    156                        and TPM_ALG_NULL is a conditional value for the
    157                        TPMI_ALG_HASH type.
    158   """
    159   _MARSHAL_FIELD_ARRAY = """
    160   for (i = 0; i < source->%(array_length)s; ++i) {
    161     total_size += %(type)s_Marshal(&source->%(name)s[i], buffer, size);
    162   }"""
    163   _UNMARSHAL_FIELD_ARRAY = """
    164   for (i = 0; i < target->%(array_length)s; ++i) {
    165     result = %(type)s_Unmarshal(&target->%(name)s[i], buffer, size);
    166     if (result != TPM_RC_SUCCESS) {
    167       return result;
    168     }
    169   }"""
    170 
    171   def __init__(self, field_type, field_name,
    172                selector=None, array_size='',
    173                conditional_value='FALSE',
    174                run_time_size=None):
    175     """Initializes a Field instance.
    176 
    177     Args:
    178       field_type: Initial value for the field type attribute.
    179       field_name: Initial value for the field name attribute.
    180       selector: Initial value for the selector attribute.
    181       array_size: Initial value for the array_size attribute.
    182       conditional_value: Initial value of the conditional_value attribute.
    183       run_time_size: Initial value of the run_time_size attribute
    184     """
    185     if not field_type:
    186       # Some tables include rows without data type, for instance 'Table 70 -
    187       # Definition of TPMU_HA Union' in part 2. These rows are supposed to
    188       # cause another case added to the switch in the marshaling function
    189       # (processing of TPM_ALG_NULL in this example). Setting field name to ''
    190       # makes sure that the actual generated structure/union does not have an
    191       # entry for this field, setting type of such field to some value
    192       # simplifies functions generating the marshaling code.
    193       self.field_type = 'BYTE'
    194       self.field_name = ''
    195     else:
    196       self.field_type = field_type
    197       self.field_name = field_name
    198     self.array_size = array_size
    199     self.selector_value = selector
    200     self.conditional_value = conditional_value
    201     self.run_time_size = run_time_size
    202 
    203   def OutputMarshal(self, out_file, typemap):
    204     """Write a call to marshal the field this instance represents.
    205 
    206     Args:
    207       out_file: The output file.
    208       typemap: A dict mapping type names to the corresponding object.
    209     """
    210     if self.array_size:
    211       if self.run_time_size:
    212         real_size = self.run_time_size
    213       else:
    214         real_size = self.array_size
    215       out_file.write(
    216           self._MARSHAL_FIELD_ARRAY % {'type': self.field_type,
    217                                        'name': self.field_name,
    218                                        'array_length': real_size})
    219     else:
    220       typemap[self.field_type].OutputMarshalCall(out_file, self)
    221 
    222   def OutputUnmarshal(self, out_file, typemap):
    223     """Write a call to unmarshal the field this instance represents.
    224 
    225     Args:
    226       out_file: The output file.
    227       typemap: A dict mapping type names to the corresponding object.
    228     """
    229     if self.array_size:
    230       if self.run_time_size:
    231         real_size = self.run_time_size
    232       else:
    233         real_size = self.array_size
    234       out_file.write(
    235           self._UNMARSHAL_FIELD_ARRAY % {'type': self.field_type,
    236                                          'name': self.field_name,
    237                                          'array_length': real_size})
    238     else:
    239       typemap[self.field_type].OutputUnmarshalCall(out_file, self)
    240 
    241 
    242 class TPMType(object):
    243   """Base type for all TPMTypes.
    244 
    245      Contains functions and string literals common to all TPM types.
    246 
    247      Attributes:
    248       _base_type: a string, when set - the very basic type this type is
    249                   derived from (should be used for marshaling/unmarshaling to
    250                   shortcut multiple nested invocations).
    251   """
    252   # A function to marshal a TPM typedef.
    253   _TYPEDEF_MARSHAL_FUNCTION = """
    254 UINT16 %(new_type)s_Marshal(
    255     %(new_type)s *source,
    256     BYTE **buffer,
    257     INT32 *size) {
    258   return %(old_type)s_Marshal(source, buffer, size);
    259 }
    260 """
    261   # The function signature and unmarshaling call to the base type of a TPM
    262   # typedef. After the value is unmarshaled, additional validation code is
    263   # generated based on tables in TCG TPM2.0 Library Specification, Part 2:
    264   # Structures.
    265   _TYPEDEF_UNMARSHAL_START = """
    266 TPM_RC %(new_type)s_Unmarshal(
    267     %(new_type)s *target,
    268     BYTE **buffer,
    269     INT32 *size) {
    270   TPM_RC result;
    271   result = %(old_type)s_Unmarshal(target, buffer, size);
    272   if (result != TPM_RC_SUCCESS) {
    273     return result;
    274   }"""
    275   _UNMARSHAL_END = '\n  return TPM_RC_SUCCESS;\n}\n'
    276   # Snippets of code for value validation.
    277   _VALUE_START_SWITCH = '\n  switch (%(name)s) {'
    278   _VALUE_CASE = '\n    case %(value)s:'
    279   _VALUE_CASE_IFDEF = '\n#ifdef %(value)s\n    case %(value)s:\n#endif'
    280   _VALUE_END_SWITCH = """
    281       break;
    282     default:
    283       return %(error_code)s;
    284   }"""
    285   # A declaration for marshaling and unmarshaling functions for a TPM type.
    286   _MARSHAL_DECLARATION = _STANDARD_MARSHAL_DECLARATION
    287   # Snippets of code which make calls to marshaling functions. Marshals a value
    288   # of type 'type' into a field 'name' within a structure. This is used in
    289   # generation of structure and command marshaling code.
    290   _MARSHAL_CALL = """
    291   total_size += %(type)s_Marshal(
    292       &source->%(name)s, buffer, size);"""
    293   _UNMARSHAL_CALL = """
    294   result = %(type)s_Unmarshal(
    295       &target->%(name)s, buffer, size);
    296   if (result != TPM_RC_SUCCESS) {
    297     return result;
    298   }"""
    299 
    300   def __init__(self):
    301     self._base_type = None
    302 
    303   def SetBaseType(self, base_type):
    304     self._base_type = base_type
    305 
    306   def _GetBaseType(self, out_file, marshalled_types, typemap):
    307     '''Return base type for this object.
    308 
    309     The base type is used for shortcutting marshaling/unmarshaling code.
    310 
    311     If _base_type is not set, return the old_type value as the base type.
    312 
    313     If the base type's marshaling/unmarshaling code has not been generated
    314     yet, issue it before continuing processing.
    315 
    316     Args:
    317       out_file: The output file.
    318       marshalled_types: A set of types for which marshal and unmarshal functions
    319           have already been generated.
    320       typemap: A dict mapping type names to the corresponding object.
    321 
    322     Returns:
    323       A string, the name of the type to use for marshaling/unmarshaling.
    324 
    325     '''
    326     if self._base_type:
    327       base_type = self._base_type
    328     else:
    329       base_type = self.old_type
    330     if base_type not in marshalled_types:
    331       typemap[base_type].OutputMarshalImpl(
    332         out_file, marshalled_types, typemap)
    333     return base_type
    334 
    335   def HasConditional(self):
    336     """Returns true if TPMType has a conditional value."""
    337     return False
    338 
    339   def OutputMarshalCall(self, out_file, field):
    340     """Write a call to Marshal function for TPMType to |out_file|.
    341 
    342        Accumulates a variable 'total_size' with the result of marshaling
    343        field |field_name| in structure 'source'.
    344 
    345     Args:
    346       out_file: The output file.
    347       field: A Field object describing this type.
    348     """
    349     out_file.write(self._MARSHAL_CALL % {'type': field.field_type,
    350                                          'name': field.field_name})
    351 
    352   def OutputUnmarshalCall(self, out_file, field):
    353     """Write a call to Unmarshal function for TPMType to |out_file|.
    354 
    355        Assigns result of unmarshaling field |field_name| in structure 'source'
    356        to variable 'result'. Returns if the unmarshalling was unsuccessful.
    357 
    358     Args:
    359       out_file: The output file.
    360       field: A Field object describing this type.
    361     """
    362     obj_type = field.field_type
    363     if obj_type == 'TPM_CC':
    364       obj_type = 'UINT32'
    365     out_file.write(self._UNMARSHAL_CALL % {'type': obj_type,
    366                                            'name': field.field_name})
    367 
    368   def _OutputTypedefMarshalDecl(self, out_file, declared_types, typemap):
    369     """Write marshal declarations for TPM typedefs to |out_file|.
    370 
    371        Can only be called on Typedef, ConstantType, AttributeStruct, and
    372        Interface objects.
    373 
    374     Args:
    375       out_file: The output file.
    376       declared_types: A set of types for which marshal and unmarshal function
    377           declarations have already been generated.
    378       typemap: A dict mapping type names to the corresponding object.
    379     """
    380     if self.new_type in declared_types:
    381       return
    382     if self.old_type not in declared_types and self.old_type in typemap:
    383       typemap[self.old_type].OutputMarshalDecl(
    384           out_file, declared_types, typemap)
    385     out_file.write(self._MARSHAL_DECLARATION % {'type': self.new_type})
    386     declared_types.add(self.new_type)
    387 
    388   def _OutputStructOrUnionMarshalDecl(self, out_file, declared_types):
    389     """Write marshal declarations for a TPM Structure or Union.
    390 
    391        Can only be called on Structure and Union objects.
    392 
    393     Args:
    394       out_file: The output file.
    395       declared_types: A set of types for which marshal and unmarshal function
    396         declarations have already been generated.
    397     """
    398     # TPMU_NAME and TPMU_ENCRYPTED_SECRET type are never used across the
    399     # interface.
    400     if (self.name in declared_types or
    401         self.name == 'TPMU_NAME' or
    402         self.name == 'TPMU_ENCRYPTED_SECRET'):
    403       return
    404     out_file.write(self._MARSHAL_DECLARATION % {'type': self.name})
    405     declared_types.add(self.name)
    406 
    407 
    408 class Typedef(TPMType):
    409   """Represents a TPM typedef.
    410 
    411   Attributes:
    412     old_type: The existing type in a typedef statement.
    413     new_type: The new type in a typedef statement.
    414   """
    415   # A function to unmarshal a TPM typedef with no extra validation.
    416   _TYPEDEF_UNMARSHAL_FUNCTION = """
    417 TPM_RC %(new_type)s_Unmarshal(
    418     %(new_type)s *target,
    419     BYTE **buffer,
    420     INT32 *size) {
    421   return %(old_type)s_Unmarshal(target, buffer, size);
    422 }
    423 """
    424 
    425   def __init__(self, old_type, new_type):
    426     """Initializes a Typedef instance.
    427 
    428     Args:
    429       old_type: The base type of the attribute structure.
    430       new_type: The name of the type.
    431     """
    432     super(Typedef, self).__init__()
    433     self.old_type = old_type
    434     self.new_type = new_type
    435 
    436   def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
    437     """Writes marshal implementations for Typedef to |out_file|.
    438 
    439     Args:
    440       out_file: The output file.
    441       marshalled_types: A set of types for which marshal and unmarshal functions
    442           have already been generated.
    443       typemap: A dict mapping type names to the corresponding object.
    444     """
    445     if self.new_type in marshalled_types:
    446       return
    447     base_type = self._GetBaseType(out_file, marshalled_types, typemap)
    448     out_file.write(self._TYPEDEF_MARSHAL_FUNCTION % {'old_type': base_type,
    449                                                      'new_type': self.new_type})
    450     out_file.write(
    451         self._TYPEDEF_UNMARSHAL_FUNCTION % {'old_type': base_type,
    452                                             'new_type': self.new_type})
    453     marshalled_types.add(self.new_type)
    454 
    455   def OutputMarshalDecl(self, out_file, declared_types, typemap):
    456     """Writes marshal declarations for Typedef to |out_file|.
    457 
    458     Args:
    459       out_file: The output file.
    460       declared_types: A set of types for which marshal and unmarshal function
    461           declarations have already been generated.
    462       typemap: A dict mapping type names to the corresponding object.
    463     """
    464     self._OutputTypedefMarshalDecl(out_file, declared_types, typemap)
    465 
    466 
    467 class ConstantType(TPMType):
    468   """Represents a TPM Constant type definition.
    469 
    470   Attributes:
    471      old_type: The base type of the constant (e.g. 'int').
    472      new_type: The name of the type (e.g. 'TPM_RC').
    473      valid_values: The list of valid values this type can take (e.g.
    474          'TPM_RC_SUCCESS').
    475      error_code: Error to be returned when unmarshalling is unsuccessful.
    476   """
    477   _CHECK_VALUE = """
    478   if (*target == %(value)s) {
    479     return TPM_RC_SUCCESS;
    480   }"""
    481   _CHECK_VALUE_IFDEF = """
    482 #ifdef %(value)s
    483   if (*target == %(value)s) {
    484     return TPM_RC_SUCCESS;
    485   }
    486 #endif"""
    487   _UNMARSHAL_END = """
    488   return %(error_code)s;
    489 }
    490 """
    491   _IFDEF_TYPE_RE = re.compile(r'^TPM_(ALG|CC).*')
    492 
    493   def __init__(self, old_type, new_type):
    494     """Initializes a ConstantType instance.
    495 
    496     Values are added to valid_values attribute during parsing.
    497 
    498     Args:
    499       old_type: The base type of the constant type.
    500       new_type: The name of the type.
    501     """
    502     super(ConstantType, self).__init__()
    503     self.old_type = old_type
    504     self.new_type = new_type
    505     self.valid_values = []
    506     self.error_code = 'TPM_RC_VALUE'
    507 
    508   def _NeedsIfdef(self):
    509     """Returns True if new_type is a type which needs ifdef enclosing."""
    510     return self._IFDEF_TYPE_RE.search(self.new_type)
    511 
    512   def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
    513     """Writes marshal implementations for ConstantType to |out_file|.
    514 
    515     Args:
    516       out_file: The output file.
    517       marshalled_types: A set of types for which marshal and unmarshal functions
    518           have already been generated.
    519       typemap: A dict mapping type names to the corresponding object.
    520     """
    521     if self.new_type in marshalled_types:
    522       return
    523     base_type = self._GetBaseType(out_file, marshalled_types, typemap)
    524     out_file.write(self._TYPEDEF_MARSHAL_FUNCTION % {'old_type': base_type,
    525                                                      'new_type': self.new_type})
    526     out_file.write(self._TYPEDEF_UNMARSHAL_START % {'old_type': base_type,
    527                                                     'new_type': self.new_type})
    528     for value in self.valid_values:
    529       if self._NeedsIfdef():
    530         out_file.write(self._CHECK_VALUE_IFDEF % {'value': value})
    531       else:
    532         out_file.write(self._CHECK_VALUE % {'value': value})
    533     out_file.write(self._UNMARSHAL_END % {'error_code': self.error_code})
    534     marshalled_types.add(self.new_type)
    535 
    536   def OutputMarshalDecl(self, out_file, declared_types, typemap):
    537     """Writes marshal declarations for ConstantType to |out_file|.
    538 
    539     Args:
    540       out_file: The output file.
    541       declared_types: A set of types for which marshal and unmarshal function
    542           declarations have already been generated.
    543       typemap: A dict mapping type names to the corresponding object.
    544     """
    545     self._OutputTypedefMarshalDecl(out_file, declared_types, typemap)
    546 
    547 
    548 class AttributeStructure(TPMType):
    549   """Represents a TPM attribute structure type definition.
    550 
    551   Attributes:
    552      old_type: The base type of the constant (e.g. 'int').
    553      new_type: The name of the type (e.g. 'TPMA_OBJECT').
    554      reserved: The list of bit bounds where bits must be 0 (e.g. ['10_2','3']).
    555   """
    556   # Attribute structures need an explicit cast to the base type.
    557   _ATTRIBUTE_MARSHAL_FUNCTION = """
    558 UINT16 %(new_type)s_Marshal(
    559     %(new_type)s *source,
    560     BYTE **buffer,
    561     INT32 *size) {
    562   return %(old_type)s_Marshal((%(old_type)s*)source, buffer, size);
    563 }
    564 """
    565   _ATTRIBUTE_UNMARSHAL_START = """
    566 TPM_RC %(new_type)s_Unmarshal(
    567     %(new_type)s *target,
    568     BYTE **buffer,
    569     INT32 *size) {
    570   TPM_RC result;
    571   result = %(old_type)s_Unmarshal((%(old_type)s*)target, buffer, size);
    572   if (result != TPM_RC_SUCCESS) {
    573     return result;
    574   }"""
    575   _CHECK_RESERVED = """
    576   if (target->reserved%(bits)s != 0) {
    577     return TPM_RC_RESERVED_BITS;
    578   }"""
    579 
    580   def __init__(self, old_type, new_type):
    581     """Initializes an AttributeStructure instance.
    582 
    583     Values may be added to reserved attribute during parsing.
    584 
    585     Args:
    586       old_type: The base type of the attribute structure.
    587       new_type: The name of the type.
    588     """
    589     super(AttributeStructure, self).__init__()
    590     self.old_type = old_type
    591     self.new_type = new_type
    592     self.reserved = []
    593 
    594   def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
    595     """Writes marshal implementations for AttributStructure to |out_file|.
    596 
    597     Args:
    598       out_file: The output file.
    599       marshalled_types: A set of types for which marshal and unmarshal functions
    600           have already been generated.
    601       typemap: A dict mapping type names to the corresponding object.
    602     """
    603     if self.new_type in marshalled_types:
    604       return
    605     base_type = self._GetBaseType(out_file, marshalled_types, typemap)
    606     out_file.write(self._ATTRIBUTE_MARSHAL_FUNCTION %
    607                    {'old_type': base_type,
    608                     'new_type': self.new_type})
    609     out_file.write(self._ATTRIBUTE_UNMARSHAL_START %
    610                    {'old_type': base_type,
    611                     'new_type': self.new_type})
    612     for bits in self.reserved:
    613       out_file.write(self._CHECK_RESERVED % {'bits': bits})
    614     out_file.write(self._UNMARSHAL_END)
    615     marshalled_types.add(self.new_type)
    616 
    617   def OutputMarshalDecl(self, out_file, declared_types, typemap):
    618     """Writes marshal declarations for AttributeStructure to |out_file|.
    619 
    620     Args:
    621       out_file: The output file.
    622       declared_types: A set of types for which marshal and unmarshal function
    623           declarations have already been generated.
    624       typemap: A dict mapping type names to the corresponding object.
    625     """
    626     self._OutputTypedefMarshalDecl(out_file, declared_types, typemap)
    627 
    628 
    629 class Interface(TPMType):
    630   """Represents a TPM interface type definition.
    631 
    632   Attributes:
    633      old_type: The base type of the interface (e.g. 'TPM_HANDLE').
    634      new_type: The name of the type (e.g. 'TPMI_DH_OBJECT').
    635      valid_values: List of valid values for new_type. If this is not empty,
    636          valid values for new_type is explicitly defined in the spec.
    637      bounds: List of pairs representing bounds. If nonempty, target must fall
    638          between one of these bounds.
    639      conditional_value: Name of conditionally allowed value. If there is no
    640          such value, this variable will be None.
    641      supported_values: String literal indicating the name of a list of supported
    642          values to be substituted at compile time (e.g. 'AES_KEY_SIZES_BITS').
    643          If this is not None, valid values for new_type depends on the
    644          implementation.
    645      error_code: Return code when an unmarshalling error occurs.
    646   """
    647   _INTERFACE_CONDITIONAL_UNMARSHAL_START = """
    648 TPM_RC %(new_type)s_Unmarshal(
    649     %(new_type)s *target,
    650     BYTE **buffer,
    651     INT32 *size,
    652     BOOL allow_conditional_value) {
    653   TPM_RC result;"""
    654   _INTERFACE_UNMARSHAL_START = """
    655 TPM_RC %(new_type)s_Unmarshal(
    656     %(new_type)s *target,
    657     BYTE **buffer,
    658     INT32 *size) {
    659   TPM_RC result;"""
    660   _UNMARSHAL_VALUE = """
    661   result = %(old_type)s_Unmarshal(target, buffer, size);
    662   if (result != TPM_RC_SUCCESS) {
    663     return result;
    664   }"""
    665   _UNMARSHAL_VALUE_ALLOW_RC_VALUE = """
    666   result = %(old_type)s_Unmarshal(target, buffer, size);
    667   if ((result != TPM_RC_VALUE) && (result != TPM_RC_SUCCESS)) {
    668     return result;
    669   }"""
    670   _SETUP_CHECK_SUPPORTED_VALUES = """
    671   uint16_t supported_values[] = %(supported_values)s;
    672   size_t length = sizeof(supported_values)/sizeof(supported_values[0]);
    673   size_t i;
    674   BOOL is_supported_value = FALSE;"""
    675   _CHECK_SUPPORTED_VALUES = """
    676   for (i = 0; i < length; ++i) {
    677     if (*target == supported_values[i]) {
    678       is_supported_value = TRUE;
    679       break;
    680     }
    681   }
    682   if (!is_supported_value) {
    683     return %(error_code)s;
    684   }"""
    685   _CHECK_CONDITIONAL = """
    686   if (*target == %(name)s) {
    687     return allow_conditional_value ? TPM_RC_SUCCESS : %(error_code)s;
    688   }"""
    689   _SETUP_CHECK_VALUES = '\n  BOOL has_valid_value = FALSE;'
    690   _VALUE_END_SWITCH = """
    691       has_valid_value = TRUE;
    692       break;
    693   }"""
    694   _CHECK_BOUND = """
    695   if((*target >= %(lower)s) && (*target <= %(upper)s)) {
    696     has_valid_value = TRUE;
    697   }"""
    698   _CHECK_VALUES_END = """
    699   if (!has_valid_value) {
    700     return %(error_code)s;
    701   }"""
    702   _CONDITIONAL_MARSHAL_DECLARATION = """
    703 UINT16 %(type)s_Marshal(
    704     %(type)s *source,
    705     BYTE **buffer,
    706     INT32 *size);
    707 
    708 TPM_RC %(type)s_Unmarshal(
    709     %(type)s *target,
    710     BYTE **buffer,
    711     INT32 *size,
    712     BOOL allow_conditioanl_value);
    713 """
    714   _CONDITIONAL_UNMARSHAL_CALL = """
    715   result = %(type)s_Unmarshal(
    716       &target->%(name)s, buffer, size, %(flag)s);
    717   if (result != TPM_RC_SUCCESS) {
    718     return result;
    719   }"""
    720   _IFDEF_TYPE_RE = re.compile(r'^TPMI_(ALG|ECC)_.*')
    721 
    722   def __init__(self, old_type, new_type):
    723     """Initializes an Interface instance.
    724 
    725     Values may be added/assigned to valid_values, bounds, conditional_value,
    726     supported_values, and error_code attributes new values during parsing.
    727 
    728     Args:
    729       old_type: The base type of the interface.
    730       new_type: The name of the type.
    731     """
    732     super(Interface, self).__init__()
    733     self.old_type = old_type
    734     self.new_type = new_type
    735     self.valid_values = []
    736     self.bounds = []
    737     self.conditional_value = None
    738     self.supported_values = None
    739     self.error_code = 'TPM_RC_VALUE'
    740 
    741   def HasConditional(self):
    742     """Returns true if Interface has a valid conditional_value."""
    743     return self.conditional_value is not None
    744 
    745   def _NeedsIfdef(self):
    746     """Returns True if new_type is a type which needs ifdef enclosing."""
    747     return self._IFDEF_TYPE_RE.search(self.new_type)
    748 
    749   def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
    750     """Writes marshal implementation for Interface to |out_file|.
    751 
    752     Args:
    753       out_file: The output file.
    754       marshalled_types: A set of types for which marshal and unmarshal functions
    755           have already been generated.
    756       typemap: A dict mapping type names to the corresponding object.
    757     """
    758     if self.new_type in marshalled_types:
    759       return
    760     base_type = self._GetBaseType(out_file, marshalled_types, typemap)
    761     out_file.write(self._TYPEDEF_MARSHAL_FUNCTION % {'old_type': base_type,
    762                                                      'new_type': self.new_type})
    763     if self.conditional_value:
    764       out_file.write(self._INTERFACE_CONDITIONAL_UNMARSHAL_START %
    765                      {'old_type': base_type,
    766                       'new_type': self.new_type})
    767     else:
    768       out_file.write(
    769           self._INTERFACE_UNMARSHAL_START % {'old_type': base_type,
    770                                              'new_type': self.new_type})
    771     # Creating necessary local variables.
    772     if self.supported_values:
    773       out_file.write(self._SETUP_CHECK_SUPPORTED_VALUES %
    774                      {'supported_values': self.supported_values})
    775     if len(self.valid_values)+len(self.bounds) > 0:
    776       out_file.write(self._SETUP_CHECK_VALUES)
    777       out_file.write(self._UNMARSHAL_VALUE_ALLOW_RC_VALUE %
    778                      {'old_type': base_type})
    779     else:
    780       out_file.write(self._UNMARSHAL_VALUE % {'old_type': base_type})
    781 
    782     if self.supported_values:
    783       out_file.write(self._CHECK_SUPPORTED_VALUES %
    784                      {'supported_values': self.supported_values,
    785                       'error_code': self.error_code})
    786     if self.conditional_value:
    787       out_file.write(
    788           self._CHECK_CONDITIONAL % {'name': self.conditional_value,
    789                                      'error_code': self.error_code})
    790     # Checking for valid values.
    791     if len(self.valid_values)+len(self.bounds) > 0:
    792       if self.valid_values:
    793         out_file.write(self._VALUE_START_SWITCH % {'name': '*target'})
    794         for value in self.valid_values:
    795           if self._NeedsIfdef():
    796             out_file.write(self._VALUE_CASE_IFDEF % {'value': value})
    797           else:
    798             out_file.write(self._VALUE_CASE % {'value': value})
    799         out_file.write(self._VALUE_END_SWITCH)
    800       for (lower, upper) in self.bounds:
    801         out_file.write(
    802             self._CHECK_BOUND % {'lower': lower, 'upper': upper})
    803       out_file.write(self._CHECK_VALUES_END % {'error_code': self.error_code})
    804 
    805     out_file.write(self._UNMARSHAL_END)
    806     marshalled_types.add(self.new_type)
    807 
    808   def OutputMarshalDecl(self, out_file, declared_types, typemap):
    809     """Writes marshal declarations for Interface to |out_file|.
    810 
    811        Outputted declaration depends on whether Interface type has a
    812        conditionally valid value.
    813 
    814     Args:
    815       out_file: The output file.
    816       declared_types: A set of types for which marshal and unmarshal function
    817           declarations have already been generated.
    818       typemap: A dict mapping type names to the corresponding object.
    819     """
    820     if self.new_type in declared_types:
    821       return
    822     if self.old_type not in declared_types:
    823       typemap[self.old_type].OutputMarshalDecl(
    824           out_file, declared_types, typemap)
    825     if self.HasConditional():
    826       out_file.write(
    827           self._CONDITIONAL_MARSHAL_DECLARATION % {'type': self.new_type})
    828     else:
    829       out_file.write(self._MARSHAL_DECLARATION % {'type': self.new_type})
    830     declared_types.add(self.new_type)
    831 
    832   def OutputUnmarshalCall(
    833       self, out_file, field):
    834     """Write a call to Unmarshal function for Interface type to |out_file|.
    835 
    836        Override TPMType OutputUnmarshalCall because when an Interface type has
    837        a conditionally valid value, a BOOL value (|conditional_valid|) is passed
    838        as a parameter.
    839 
    840     Args:
    841       out_file: The output file.
    842       field: A Field object representing an element of this interface.
    843     """
    844     if self.conditional_value:
    845       out_file.write(
    846           self._CONDITIONAL_UNMARSHAL_CALL % {'type': field.field_type,
    847                                               'name': field.field_name,
    848                                               'flag': field.conditional_value})
    849     else:
    850       out_file.write(self._UNMARSHAL_CALL % {'type': field.field_type,
    851                                              'name': field.field_name})
    852 
    853 
    854 class Structure(TPMType):
    855   """Represents a TPM structure.
    856 
    857   Attributes:
    858     name: The name of the structure.
    859     fields: A list of Field objects representing struct fields.
    860     upper_bounds: A dictionary of (name, val) tuples mapping name to max val.
    861     lower_bounds: A dictionary of (name, val) tuples mapping name to min val.
    862     size_check: Set if TPM2B structure must be size checked (triggered by size=)
    863     valid_tag_values: A list of values field tag is allowed to take.
    864     error_code: The return code to be returned if an error occurs
    865   """
    866   _STRUCTURE_MARSHAL_START = """
    867 UINT16 %(name)s_Marshal(
    868     %(name)s *source,
    869     BYTE **buffer,
    870     INT32 *size) {
    871   UINT16 total_size = 0;"""
    872   _STRUCTURE_UNMARSHAL_START = """
    873 TPM_RC %(name)s_Unmarshal(
    874     %(name)s *target,
    875     BYTE **buffer,
    876     INT32 *size) {
    877   TPM_RC result;"""
    878   _MARSHAL_END = '\n  return total_size;\n}\n'
    879   _SETUP_ARRAY_FIELD = '\n  INT32 i;'
    880   _CHECK_SIZE_START = """
    881   UINT32 start_size = *size;
    882   UINT32 struct_size;"""
    883   _CHECK_SIZE_END = """
    884   struct_size = start_size - *size - sizeof(target->t.size);
    885   if (struct_size != target->t.size) {
    886     return TPM_RC_SIZE;
    887   }"""
    888   _TPM2B_ZERO_SIZE = """
    889   if (target->t.size == 0) {
    890     return %(return_value)s;
    891   }"""
    892   _CHECK_BOUND = """
    893   if (target->%(name)s %(operator)s %(bound_value)s) {
    894     return %(error_code)s;
    895   }"""
    896   _FIX_SIZE_FIELD = """
    897   {
    898     BYTE *size_location = *buffer - total_size;
    899     INT32 size_field_size = sizeof(%(size_field_type)s);
    900     UINT16 payload_size = total_size - (UINT16)size_field_size;
    901     %(size_field_type)s_Marshal(&payload_size,
    902       &size_location, &size_field_size);
    903   }"""
    904 
    905   def __init__(self, name):
    906     """Initializes a Structure instance.
    907 
    908     Initially the instance will have no fields, upper_bounds, lower_bounds, or
    909     valid_tag_values. Those can be added with AddField(), AddUpperBound(),
    910     AddLowerBound(), and AddTagVal() methods.
    911 
    912     Args:
    913       name: The name of the structure.
    914     """
    915     super(Structure, self).__init__()
    916     self.name = name
    917     self.fields = []
    918     self.upper_bounds = {}
    919     self.lower_bounds = {}
    920     self.size_check = False
    921     self.valid_tag_values = []
    922     self.error_code = 'TPM_RC_VALUE'
    923 
    924   def AddField(self, field):
    925     """Adds a field to fields attribute in Structure.
    926 
    927     Args:
    928       field: Instance of Field
    929     """
    930     self.fields.append(field)
    931 
    932   def AddUpperBound(self, field_name, value):
    933     """Adds an upper bound for a field.
    934 
    935     Args:
    936        field_name: Name of field with bound.
    937        value: Value of upper bound.
    938     """
    939     if _IsTPM2B(self.name):
    940       field_name = 't.' + field_name
    941     self.upper_bounds[field_name] = value
    942 
    943   def AddLowerBound(self, field_name, value):
    944     """Adds a lower bound for a field.
    945 
    946     Args:
    947        field_name: Name of field with bound.
    948        value: Value of lower bound.
    949     """
    950     if _IsTPM2B(self.name):
    951       field_name = 't.' + field_name
    952     self.lower_bounds[field_name] = value
    953 
    954   def _AddTagValue(self, value):
    955     """Adds a valid value for tag field.
    956 
    957     Args:
    958        value: Valid value for tag field.
    959     """
    960     self.valid_tag_values.append(value)
    961 
    962   def _GetFieldTypes(self):
    963     """Creates a set which holds all current field types.
    964 
    965     Returns:
    966       A set of field types.
    967     """
    968     return set([field.field_type for field in self.fields])
    969 
    970   def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
    971     """Writes marshal implementations for Structure to |out_file|.
    972 
    973     Args:
    974       out_file: The output file.
    975       marshalled_types: A set of types for which marshal and unmarshal functions
    976           have already been generated.
    977       typemap: A dict mapping type names to the corresponding object.
    978     """
    979     if self.name in marshalled_types:
    980       return
    981 
    982     # Make sure any dependencies already have marshal functions defined.
    983     for field_type in self._GetFieldTypes():
    984       if field_type not in marshalled_types:
    985         typemap[field_type].OutputMarshalImpl(
    986             out_file, marshalled_types, typemap)
    987         marshalled_types.add(field_type)
    988 
    989     out_file.write(self._STRUCTURE_MARSHAL_START % {'name': self.name})
    990     # If any field is an array, create local variable INT32 i.
    991     for field in self.fields:
    992       if field.array_size:
    993         out_file.write(self._SETUP_ARRAY_FIELD)
    994         break
    995     for field in self.fields:
    996       # Each TPM2B is a union of two sized buffers, one which is type specific
    997       # (the 't' element) and the other is a generic value (the 'b' element).
    998       # For this reason a 't.' is prepended for fields in a TPM2B type. See
    999       # section 9.11.6 in TCG TPM2.0 Library Specification, Part 2: Structures
   1000       # for more details.
   1001       if _IsTPM2B(self.name):
   1002         field.field_name = 't.' + field.field_name
   1003         if field.run_time_size:
   1004           field.run_time_size = 't.' + field.run_time_size
   1005       field.OutputMarshal(out_file, typemap)
   1006     if self.size_check:
   1007       out_file.write(self._FIX_SIZE_FIELD % {'size_field_type': self.fields[0].field_type})
   1008     out_file.write(self._MARSHAL_END)
   1009 
   1010     out_file.write(self._STRUCTURE_UNMARSHAL_START % {'name': self.name})
   1011     if self.size_check:
   1012       out_file.write(self._CHECK_SIZE_START)
   1013     # If any field is an array, create local variable INT32 i.
   1014     for field in self.fields:
   1015       if field.array_size:
   1016         out_file.write(self._SETUP_ARRAY_FIELD)
   1017         break
   1018     for field in self.fields:
   1019       field.OutputUnmarshal(out_file, typemap)
   1020       return_value = self.error_code
   1021       if field.field_name == 't.size' and self.size_check:
   1022         out_file.write(self._TPM2B_ZERO_SIZE % {'return_value': 'TPM_RC_SIZE'})
   1023       if field.field_name == 't.size' and not self.size_check:
   1024         out_file.write(
   1025             self._TPM2B_ZERO_SIZE % {'return_value': 'TPM_RC_SUCCESS'})
   1026       if field.field_name in self.upper_bounds:
   1027         if (field.field_name == 'count' or
   1028             field.field_name == 't.size' or
   1029             field.field_name == 'size'):
   1030           return_value = 'TPM_RC_SIZE'
   1031         out_file.write(self._CHECK_BOUND %
   1032                        {'name': field.field_name,
   1033                         'operator': '>',
   1034                         'bound_value': self.upper_bounds[field.field_name],
   1035                         'error_code': return_value})
   1036       if field.field_name in self.lower_bounds:
   1037         if (field.field_name == 'count' or
   1038             field.field_name == 't.size' or
   1039             field.field_name == 'size'):
   1040           return_value = 'TPM_RC_SIZE'
   1041         out_file.write(self._CHECK_BOUND %
   1042                        {'name': field.field_name,
   1043                         'operator': '<',
   1044                         'bound_value': self.lower_bounds[field.field_name],
   1045                         'error_code': return_value})
   1046       if field.field_name == 'tag' and self.valid_tag_values:
   1047         out_file.write(self._VALUE_START_SWITCH % {'name': 'target->tag'})
   1048         for value in self.valid_tag_values:
   1049           out_file.write(self._VALUE_CASE % {'value': value})
   1050         out_file.write(self._VALUE_END_SWITCH % {'error_code': 'TPM_RC_TAG'})
   1051     if self.size_check:
   1052       out_file.write(self._CHECK_SIZE_END)
   1053     if not self.fields:
   1054       # The spec includes a definition of an empty structure, as a side effect
   1055       # the marshaling/unmarshaling functions become empty, the compiler
   1056       # warning is suppressed by the below statement.
   1057       out_file.write('  (void)result;\n')
   1058     out_file.write(self._UNMARSHAL_END)
   1059 
   1060     marshalled_types.add(self.name)
   1061 
   1062   def OutputMarshalDecl(self, out_file, declared_types, _):
   1063     """Writes marshal declarations for Structure to |out_file|.
   1064 
   1065     Args:
   1066       out_file: The output file.
   1067       declared_types: A set of types for which marshal and unmarshal function
   1068           declarations have already been generated.
   1069     """
   1070     self._OutputStructOrUnionMarshalDecl(out_file, declared_types)
   1071 
   1072 
   1073 class Union(TPMType):
   1074   """Represents a TPM union.
   1075 
   1076   Attributes:
   1077     name: The name of the union.
   1078     fields: A list of Field objects representing union fields.
   1079   """
   1080 
   1081   _UNION_MARSHAL_START = """
   1082 UINT16 %(name)s_Marshal(
   1083     %(name)s *source,
   1084     BYTE **buffer,
   1085     INT32 *size,
   1086     UINT32 selector) {
   1087   %(array_extras)s
   1088   switch(selector) {"""
   1089   _UNION_UNMARSHAL_START = """
   1090 TPM_RC %(name)s_Unmarshal(
   1091     %(name)s *target,
   1092     BYTE **buffer,
   1093     INT32 *size,
   1094     UINT32 selector) {
   1095   switch(selector) {"""
   1096   _MARSHAL_END = '\n  }\n  return 0;\n}\n'
   1097   _UNMARSHAL_END = '\n  }\n  return TPM_RC_SELECTOR;\n}\n'
   1098   _MARSHAL_DECLARATION = """
   1099 UINT16 %(type)s_Marshal(
   1100     %(type)s *source,
   1101     BYTE **buffer,
   1102     INT32 *size,
   1103     UINT32 selector);
   1104 
   1105 TPM_RC %(type)s_Unmarshal(
   1106     %(type)s *target,
   1107     BYTE **buffer,
   1108     INT32 *size,
   1109     UINT32 selector);
   1110 """
   1111   _CASE_SELECTOR = """
   1112     case %(selector)s:"""
   1113   _MARSHAL_EMPTY = """
   1114       return 0;"""
   1115   _UNMARSHAL_EMPTY = """
   1116       return TPM_RC_SUCCESS;"""
   1117   _MARSHAL_FIELD = """
   1118       return %(type)s_Marshal(
   1119           (%(type)s*)&source->%(name)s, buffer, size);"""
   1120   _UNMARSHAL_FIELD = """
   1121       return %(type)s_Unmarshal(
   1122           (%(type)s*)&target->%(name)s, buffer, size);"""
   1123   _SETUP_MARSHAL_FIELD_ARRAY = """
   1124     INT32 i;
   1125     UINT16 total_size = 0;"""
   1126   _SETUP_UNMARSHAL_FIELD_ARRAY = """
   1127     INT32 i;
   1128     TPM_RC result = TPM_RC_SUCCESS;"""
   1129   _MARSHAL_FIELD_ARRAY = """
   1130     for (i = 0; i < %(array_length)s; ++i) {
   1131       total_size += %(type)s_Marshal(
   1132           &source->%(name)s[i], buffer, size);
   1133     }
   1134     return total_size;"""
   1135   _UNMARSHAL_FIELD_ARRAY = """
   1136     for (i = 0; i < %(array_length)s; ++i) {
   1137       result = %(type)s_Unmarshal(
   1138           &target->%(name)s[i], buffer, size);
   1139       if (result != TPM_RC_SUCCESS) {
   1140         return result;
   1141       }
   1142     }
   1143     return TPM_RC_SUCCESS;"""
   1144   _UNMARSHAL_FIELD_CONDITIONAL = """
   1145     return %(type)s_Unmarshal(
   1146         &target->%(name)s, buffer, size, FALSE);"""
   1147   _UNION_MARSHAL_CALL = """
   1148   total_size += %(type)s_Marshal(
   1149       &source->%(name)s, buffer, size, source->%(selector)s);"""
   1150   _UNION_UNMARSHAL_CALL = """
   1151   result = %(type)s_Unmarshal(
   1152       &target->%(name)s, buffer, size, target->%(selector)s);
   1153   if (result != TPM_RC_SUCCESS) {
   1154     return result;
   1155   }"""
   1156   _IFDEF = '\n#ifdef %(type)s'
   1157   _ENDIF = '\n#endif'
   1158   _IFDEF_TYPE_RE = re.compile(r'^TPM_(ALG|CC).*')
   1159 
   1160   def __init__(self, name):
   1161     """Initializes a Union instance.
   1162 
   1163     Initially the instance will have no fields. Fields are added with the
   1164     AddField() method.
   1165 
   1166     Args:
   1167       name: The name of the structure.
   1168     """
   1169     super(Union, self).__init__()
   1170     self.name = name
   1171     self.fields = []
   1172 
   1173   def _NeedsIfdef(self, selector):
   1174     """Returns True if selector is a type which needs ifdef enclosing."""
   1175     return self._IFDEF_TYPE_RE.search(selector)
   1176 
   1177   def AddField(self, field):
   1178     """Adds a field to fields attribute in Union.
   1179 
   1180     Args:
   1181       field: instance of Field
   1182     """
   1183     # xor is a C++ keyword and must be fixed.
   1184     if field.field_name == 'xor':
   1185       field.field_name = 'xor_'
   1186     self.fields.append(field)
   1187 
   1188   def _OutputMarshalField(
   1189       self, out_file, field_type, field_name, array_length):
   1190     """Write a call to marshal a field in this union.
   1191 
   1192     Args:
   1193       out_file: The output file.
   1194       field_type: The type of field.
   1195       field_name: The name of the field.
   1196       array_length: Variable indicating length of array, None if field is not
   1197           an array.
   1198     """
   1199     if array_length:
   1200       out_file.write(self._MARSHAL_FIELD_ARRAY % {'type': field_type,
   1201                                                   'name': field_name,
   1202                                                   'array_length': array_length})
   1203     else:
   1204       out_file.write(self._MARSHAL_FIELD % {'type': field_type,
   1205                                             'name': field_name})
   1206 
   1207   def _OutputUnmarshalField(
   1208       self, out_file, field_type, field_name, array_length, typemap):
   1209     """Write a call to unmarshal a field in this union.
   1210 
   1211     Args:
   1212       out_file: The output file object.
   1213       field_type: The type of field.
   1214       field_name: The name of the field.
   1215       array_length: Variable indicating length of array, None if field is not
   1216           an array.
   1217       typemap: A dict mapping type names to the corresponding object.
   1218     """
   1219     if array_length:
   1220       out_file.write(
   1221           self._UNMARSHAL_FIELD_ARRAY % {'type': field_type,
   1222                                          'name': field_name,
   1223                                          'array_length': array_length})
   1224     elif typemap[field_type].HasConditional():
   1225       out_file.write(
   1226           self._UNMARSHAL_FIELD_CONDITIONAL % {'type': field_type,
   1227                                                'name': field_name})
   1228     else:
   1229       out_file.write(self._UNMARSHAL_FIELD % {'type': field_type,
   1230                                               'name': field_name})
   1231 
   1232   def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
   1233     """Writes marshal implementations for Union to |out_file|.
   1234 
   1235     Args:
   1236       out_file: The output file.
   1237       marshalled_types: A set of types for which marshal and unmarshal functions
   1238           have already been generated.
   1239       typemap: A dict mapping type names to the corresponding object.
   1240     """
   1241     if (self.name in marshalled_types or
   1242         self.name == 'TPMU_NAME' or
   1243         self.name == 'TPMU_ENCRYPTED_SECRET' or
   1244         not self.fields):
   1245       return
   1246 
   1247     field_types = {f.field_name: f.field_type for f in self.fields}
   1248     array_lengths = {}
   1249     for f in self.fields:
   1250       if f.array_size:
   1251         array_lengths[f.field_name] = f.array_size
   1252       else:
   1253         array_lengths[f.field_name] = None
   1254 
   1255     # Make sure any dependencies already have marshal functions defined.
   1256     for field_type in field_types.itervalues():
   1257       if field_type not in marshalled_types:
   1258         typemap[field_type].OutputMarshalImpl(
   1259             out_file, marshalled_types, typemap)
   1260         marshalled_types.add(field_type)
   1261     if self.fields[0].array_size:
   1262       array_extras = self._SETUP_MARSHAL_FIELD_ARRAY
   1263     else:
   1264       array_extras = ''
   1265     out_file.write(self._UNION_MARSHAL_START % {'name': self.name,
   1266                                                 'array_extras': array_extras})
   1267     # Set up variables if Union is an array type.
   1268     for field in self.fields:
   1269       selector = field.selector_value
   1270       if not selector:
   1271         continue
   1272       field_name = field.field_name
   1273       if self._NeedsIfdef(selector):
   1274         out_file.write(self._IFDEF % {'type': selector})
   1275       out_file.write(self._CASE_SELECTOR % {'selector': selector})
   1276       # Selector is not associated with a name, so no marshaling occurs.
   1277       if not field_name:
   1278         out_file.write(self._MARSHAL_EMPTY)
   1279         if self._NeedsIfdef(selector):
   1280           out_file.write(self._ENDIF)
   1281         continue
   1282       field_type = field_types[field_name]
   1283       array_length = array_lengths[field_name]
   1284       self._OutputMarshalField(out_file, field_type, field_name, array_length)
   1285       if self._NeedsIfdef(selector):
   1286         out_file.write(self._ENDIF)
   1287     out_file.write(self._MARSHAL_END)
   1288     out_file.write(self._UNION_UNMARSHAL_START % {'name': self.name})
   1289     # Set up variables if Union is an array type.
   1290     if self.fields[0].array_size:
   1291       out_file.write(self._SETUP_UNMARSHAL_FIELD_ARRAY)
   1292     for field in self.fields:
   1293       selector = field.selector_value
   1294       if not selector:
   1295         continue
   1296       field_name = field.field_name
   1297       if self._NeedsIfdef(selector):
   1298         out_file.write(self._IFDEF % {'type': selector})
   1299       out_file.write(self._CASE_SELECTOR % {'selector': selector})
   1300       # Selector is not associated with a name, so no unmarshaling occurs.
   1301       if not field_name:
   1302         out_file.write(self._UNMARSHAL_EMPTY)
   1303         if self._NeedsIfdef(selector):
   1304           out_file.write(self._ENDIF)
   1305         continue
   1306       field_type = field_types[field_name]
   1307       array_length = array_lengths[field_name]
   1308       self._OutputUnmarshalField(
   1309           out_file, field_type, field_name, array_length, typemap)
   1310       if self._NeedsIfdef(selector):
   1311         out_file.write(self._ENDIF)
   1312     out_file.write(self._UNMARSHAL_END)
   1313     marshalled_types.add(self.name)
   1314 
   1315   def OutputMarshalDecl(self, out_file, declared_types, _):
   1316     """Writes marshal declarations for Union to |out_file|.
   1317 
   1318     Args:
   1319       out_file: The output file.
   1320       declared_types: A set of types for which marshal and unmarshal function
   1321           declarations have already been generated.
   1322     """
   1323     self._OutputStructOrUnionMarshalDecl(out_file, declared_types)
   1324 
   1325   def OutputMarshalCall(self, out_file, field):
   1326     """Write a call to marshal function for Union type to |out_file|.
   1327 
   1328        Override TPMType OutputMarshalCall to pass in selector value.
   1329 
   1330     Args:
   1331       out_file: The output file.
   1332       field: A Field object representing a member of this union
   1333     """
   1334     out_file.write(self._UNION_MARSHAL_CALL %
   1335                    {'type': field.field_type,
   1336                     'name': field.field_name,
   1337                     'selector': field.selector_value})
   1338 
   1339   def OutputUnmarshalCall(self, out_file, field):
   1340     """Write a call to unmarshal function for Union type to |out_file|.
   1341 
   1342        Override TPMType OutputUnmashalCall to pass in selector value.
   1343 
   1344     Args:
   1345       out_file: The output file.
   1346       field: A Field object representing a member of this union
   1347     """
   1348     out_file.write(self._UNION_UNMARSHAL_CALL %
   1349                    {'type': field.field_type,
   1350                     'name': field.field_name,
   1351                     'selector': field.selector_value})
   1352 
   1353 
   1354 def GenerateHeader(typemap):
   1355   """Generates a header file with declarations for all given generator objects.
   1356 
   1357   Args:
   1358     typemap: A dict mapping type names to the corresponding object.
   1359   """
   1360   out_file = open(_OUTPUT_FILE_H, 'w')
   1361   out_file.write(COPYRIGHT_HEADER)
   1362   guard_name = 'TPM2_%s_' % _OUTPUT_FILE_H.upper().replace('.', '_')
   1363   out_file.write(HEADER_FILE_GUARD_HEADER % {'name': guard_name})
   1364   out_file.write(_HEADER_FILE_INCLUDES)
   1365   # These types are built-in or defined by <stdint.h>; they serve as base cases
   1366   # when defining type dependencies.
   1367   declared_types = set(_BASIC_TYPES)
   1368   # Generate serialize / parse function declarations.
   1369   for basic_type in _BASIC_TYPES:
   1370     out_file.write(_STANDARD_MARSHAL_DECLARATION % {'type': basic_type})
   1371   for tpm_type in [typemap[x] for x in sorted(typemap.keys())]:
   1372     tpm_type.OutputMarshalDecl(out_file, declared_types, typemap)
   1373   out_file.write(HEADER_FILE_GUARD_FOOTER % {'name': guard_name})
   1374   out_file.close()
   1375   call(['clang-format', '-i', '-style=Chromium', 'tpm_generated.h'])
   1376 
   1377 
   1378 def GenerateImplementation(typemap):
   1379   """Generates implementation code for each type.
   1380 
   1381   Args:
   1382     typemap: A dict mapping string type names to the corresponding object.
   1383   """
   1384   out_file = open(_OUTPUT_FILE_CC, 'w')
   1385   out_file.write(COPYRIGHT_HEADER)
   1386   out_file.write(_IMPLEMENTATION_FILE_INCLUDES)
   1387   marshalled_types = set(_BASIC_TYPES)
   1388   for basic_type in _BASIC_TYPES:
   1389     out_file.write(_MARSHAL_BASIC_TYPE % {'type': basic_type})
   1390   for tpm_type in [typemap[x] for x in sorted(typemap.keys())]:
   1391     tpm_type.OutputMarshalImpl(out_file, marshalled_types, typemap)
   1392   out_file.close()
   1393   call(['clang-format', '-i', '-style=Chromium', 'tpm_generated.c'])
   1394