def __init__(self): if settings.SPEC_VERSION_INT < 138: self.file_path = constants.SRC_PATH + constants.TPM_PATH + "/support/marshal.c" self.file_path_fp = constants.SRC_PATH + constants.TPM_PATH + "/include/prototypes/marshal_fp.h" else: self.file_path = constants.SRC_PATH + constants.TPM_PATH + "/support/Marshal.c" self.file_path_fp = constants.SRC_PATH + constants.TPM_PATH + "/include/prototypes/Marshal_fp.h" self.file = None self.content = u"" self.content_fp = u"" # Create marshallers self.simple_marshaller = SimpleMarshaller() self.advanced_marshaller = AdvancedMarshaller() self.bits_table_marshaller = BitsTableMarshaller() self.interface_table_marshaller = InterfaceTableMarshaller() self.structure_table_marshaller = StructureTableMarshaller() self.union_table_marshaller = UnionTableMarshaller() self.array_marshaller = ArrayMarshaller() # Initialize dictionaries self.array_functions = dict() self.function_prototypes_with_flag = dict()
def __init__(self): self.file_path = constants.SRC_PATH + constants.TPM_PATH + "/support/marshal.c" self.file_path_fp = constants.SRC_PATH + constants.TPM_PATH + "/include/prototypes/marshal_fp.h" self.file = None self.content = u"" self.content_fp = u"" # Create marshallers self.simple_marshaller = SimpleMarshaller() self.advanced_marshaller = AdvancedMarshaller() self.bits_table_marshaller = BitsTableMarshaller() self.interface_table_marshaller = InterfaceTableMarshaller() self.structure_table_marshaller = StructureTableMarshaller() self.union_table_marshaller = UnionTableMarshaller() self.array_marshaller = ArrayMarshaller() # Initialize dictionaries self.array_functions = dict() self.function_prototypes_with_flag = dict()
def __init__(self): SimpleMarshaller.__init__(self)
class Marshaller: # Initialises paths to destination files of marshalling source code, and instantiates all marshalling subclasses def __init__(self): self.file_path = constants.SRC_PATH + constants.TPM_PATH + "/support/marshal.c" self.file_path_fp = constants.SRC_PATH + constants.TPM_PATH + "/include/prototypes/marshal_fp.h" self.file = None self.content = u"" self.content_fp = u"" # Create marshallers self.simple_marshaller = SimpleMarshaller() self.advanced_marshaller = AdvancedMarshaller() self.bits_table_marshaller = BitsTableMarshaller() self.interface_table_marshaller = InterfaceTableMarshaller() self.structure_table_marshaller = StructureTableMarshaller() self.union_table_marshaller = UnionTableMarshaller() self.array_marshaller = ArrayMarshaller() # Initialize dictionaries self.array_functions = dict() self.function_prototypes_with_flag = dict() # Creates header comment for a specific table and adds it to the contents of marshal files # Parameters: # table - internal representation of the table, containing the metainformation about itself to generate comment def create_header_comment(self, table): self.content += "\n// Table 2:" + table.number + " - " + table.short_name + " (" + table.table_type + ")\n" self.content_fp += "\n// Table 2:" + table.number + " - " + table.short_name + " (" + table.table_type + ")\n" # Checks if base type already present in type mapping dictionary # Parameters: # base_type - string containing name of base type # Returns: # base type - string containing name of base type # boolean value - representing the availability of the base type in the dictionary @staticmethod def handle_base_types(base_type): if "int" in base_type: for entry in tpm2_partx_type_mapping.dictionary.iteritems(): if entry[1][0] == base_type or entry[1][0] == "u"+base_type: base_type = entry[0] return base_type, True return base_type, False # Handle marshalling for Typedef tables and BaseType tables by calling required functions from SimpleMarshaller # For every base type that contains an algorithm type, marshaling functions are generated for each algorithm, # (if not already done or already defined) surrounded by define guards (ifdefs) # Parameters: # table - internal representation of the table, based on which marshaling functions are generated # tpm_alg_ids - mapping from algorithm types to list of corresponding algorithm IDs def handle_simple_type_structures_new(self, table, tpm_alg_ids=None): self.create_header_comment(table) for row in table.rows: base_type = row[0] new_type = row[1] types_list = [] # check for !ALG alg_dep = utils.find_alg_constraints(table.short_name) algs = utils.expand_alg_macro(new_type, tpm_alg_ids, alg_dep) for alg in algs: typedef = utils.replace_alg_placeholder(new_type, alg.short_name) types_list.append(typedef) # end of loop - for alg in alg_list: # in case there is no !ALG if not algs: types_list = [new_type] # handle the (list of) typ(es) in the current row for current_type in types_list: if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) # check if type is a C base type and already in mapping dictionary base_type, c_base_type = self.handle_base_types(base_type) already_marshaled = base_type in tpm2_partx_type_mapping.dictionary.keys() unsigned_marshaled = "u"+base_type in tpm2_partx_type_mapping.dictionary.keys() if unsigned_marshaled: base_type = "u"+base_type if c_base_type or already_marshaled or unsigned_marshaled: # if original type was already marshaled somehow # marshalling new type would be redundant - change to define for new type orig_mrshl = tpm2_partx_type_mapping.dictionary[base_type] orig_table_nr = orig_mrshl[1] # recursive exploration of most basic base_type in mapping dictionary base_type = utils.find_basic_base_type(base_type) # add a comment that points to the origin of the type definition self.content += "// " + base_type + " definition used from Table 2:" + orig_table_nr + "\n" self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format(current_type) self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format(current_type) self.content_fp += self.simple_marshaller.create_unmarshal_fp_define(current_type, base_type) self.content_fp += self.simple_marshaller.create_marshal_fp_define(current_type, base_type) else: # handle base types: figure out the size size = utils.find_base_type_size(base_type) if not size: # skip base type without size (i.e. 'int', which is used for 'BOOL') continue self.content += self.simple_marshaller.create_unmarshal_code(current_type, int(size)/8) self.content += self.simple_marshaller.create_marshal_code(current_type, int(size)/8) self.content_fp += self.simple_marshaller.create_unmarshal_fp(current_type) self.content_fp += self.simple_marshaller.create_marshal_fp(current_type) if unsigned_marshaled: base_type = base_type[1:] tpm2_partx_type_mapping.dictionary[current_type] = [base_type, table.number] # done with the new type if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) self.content += "\n" self.content_fp += "\n" # end of loop - for row in table.rows: # end of method - handle_simple_type_structures_new(self, table, tpm_alg_ids): # Handle marshalling for special tables, which are not used to create constant or type definitions, by calling # required functions from SimpleMarshaller, if base type found in table name not already marshaled # Parameters: # table - internal representation of the table, based on which marshaling functions are generated def handle_simple_constants(self, table): self.create_header_comment(table) base_type = utils.find_tpm_base_type_name(table.short_name) current_type = utils.find_tpm_type_name(table.short_name) alg_dep = utils.find_alg_dep(table.short_name) size = utils.find_base_type_size(base_type) if not size: return if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) already_marshaled = base_type in tpm2_partx_type_mapping.dictionary.keys() if already_marshaled: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format(current_type) self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format(current_type) self.content_fp += self.simple_marshaller.create_unmarshal_fp_define(current_type, base_type) self.content_fp += self.simple_marshaller.create_marshal_fp_define(current_type, base_type) else: self.content += self.simple_marshaller.create_unmarshal_code(current_type, int(size)/8) self.content += self.simple_marshaller.create_marshal_code(current_type, int(size)/8) self.content_fp += self.simple_marshaller.create_unmarshal_fp(current_type) self.content_fp += self.simple_marshaller.create_marshal_fp(current_type) tpm2_partx_type_mapping.dictionary[current_type] = [base_type, table.number] if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) # end of method - handle_simple_constants(self, table): # Handle marshalling for Enum tables by calling # required functions from AdvancedMarshaller, based on in/out declarations in table name # Parameters: # table - internal representation of the table, based on which marshaling functions are generated def handle_advanced_type_structures(self, table): self.create_header_comment(table) base_type = utils.find_tpm_base_type_name(table.short_name) current_type = utils.find_tpm_type_name(table.short_name) config = utils.find_config(table.name) size = utils.find_base_type_size(base_type) if not size: return in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) s_declaration = re.search('([S])', config) cases = [] rc_fail = None for row in table.rows: name = row[0] if "#" in name: rc_fail = name.replace("#", "") elif "TPM_CAP_FIRST" in name or "TPM_CAP_LAST" in name: continue # skip else: cases.append(name) # in if in_declaration is None: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format(current_type) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format(current_type) else: if (base_type in tpm2_partx_type_mapping.dictionary.keys() or s_declaration) and not rc_fail: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format(current_type) self.content_fp += self.advanced_marshaller.create_unmarshal_fp_define(current_type, base_type) else: self.content += self.advanced_marshaller.create_unmarshal_code(current_type, base_type, cases,rc_fail) self.content_fp += self.advanced_marshaller.create_unmarshal_fp(current_type) # out if out_declaration is None: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format(current_type) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format(current_type) else: if base_type in tpm2_partx_type_mapping.dictionary.keys() or s_declaration: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format(current_type) self.content_fp += self.advanced_marshaller.create_marshal_fp_define(current_type, base_type) else: self.content += self.advanced_marshaller.create_marshal_code(current_type, size) self.content_fp += self.advanced_marshaller.create_marshal_fp(current_type) tpm2_partx_type_mapping.dictionary[current_type] = [base_type, table.number] # end of method - handle_advanced_type_structures(self, table): # Handle marshalling for Bits tables by calling required functions from BitsTableMarshaller based on the base type # found in table name, if base type not already marshaled # Parameters: # table - internal representation of the table, based on which marshaling functions are generated def handle_bits_table(self, table): self.create_header_comment(table) base_type = utils.find_tpm_base_type_name(table.short_name) current_type = utils.find_tpm_type_name(table.short_name) reserved = 0 i = 0 for row in table.rows: bit_idx = row[0] bit_name = row[1] bits = 1 if ":" in bit_idx and "Reserved" in bit_name: values = bit_idx.split(":") from_value = int(values[1]) to_value = int(values[0]) for b in range(from_value, to_value+1): reserved |= (1 << b) elif "Reserved" in bit_name: reserved |= (1 << i) i += bits # end of loop - for row in table.rows: # generate a bit mask starting with 0x... reserved = "0x%0.2X" % reserved result = re.search("(int|INT)([1368][246]*)", base_type) if result: size = result.group(2) elif base_type in tpm2_partx_type_mapping.dictionary.keys() and tpm2_partx_type_mapping.dictionary[base_type]: size = tpm2_partx_type_mapping.dictionary[base_type][0] else: return # in if base_type in tpm2_partx_type_mapping.dictionary.keys() and reserved == "0x00": self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format(current_type) self.content_fp += self.bits_table_marshaller.create_unmarshal_fp_define(current_type, base_type) else: self.content += self.bits_table_marshaller.create_unmarshal_code(current_type, base_type, reserved, None) self.content_fp += self.bits_table_marshaller.create_unmarshal_fp(current_type) # out if base_type in tpm2_partx_type_mapping.dictionary.keys(): self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format(current_type) self.content_fp += self.bits_table_marshaller.create_marshal_fp_define(current_type, base_type) else: self.content += self.bits_table_marshaller.create_marshal_code(current_type, size) self.content_fp += self.bits_table_marshaller.create_marshal_fp(current_type) tpm2_partx_type_mapping.dictionary[current_type] = [base_type, table.number] # end of method - handle_bits_table(self, table): # Handle marshalling for Interface tables by calling # required functions from InterfaceTableMarshaller based on in/out declarations in table name, # using definition guards (ifdefs) when necessary # It interprets the table as multiple tables, in the case that an algorithm type name is found in the table name # Parameters: # table - internal representation of the table, based on which marshaling functions are generated # tpm_alg_ids - mapping from algorithm types to list of corresponding algorithm IDs def handle_interface_table(self, table, tpm_alg_ids): self.create_header_comment(table) bool_flag = False base_type = utils.find_tpm_base_type_name(table.short_name) current_type = utils.find_tpm_type_name(table.short_name) # config block begin config = re.search('<(.*)>', table.name) if config: config = config.group(1) else: config = "IN/OUT" in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) # s_declaration = re.search('([S])', config) # config block end # distinguish between a normal case, when a simple table needs to be processed # and a case, where a table represents multiple tables (see table 124) alg_dep = None if "!" not in current_type: result = re.search('\{(.*)\}', table.name) if result: alg_dep = result.group(1) cases = [] alg_list = [] checks = [] conditions = None rc_fail = None for row in table.rows: value_name = row[0] if "{" in value_name: values = value_name.split(":") from_value = values[0].replace("{", "") to_value = values[1].replace("}", "") checks.append([from_value.strip(), to_value.strip()]) elif "+TPM" in value_name: conditions = value_name.replace("+", "") self.function_prototypes_with_flag[current_type] = "" bool_flag = True elif "$RSA_KEY_SIZES_BITS" in value_name: cases = constants.RSA_KEY_SIZES_BITS elif "$ECC_CURVES" in value_name: cases = constants.ECC_CURVES elif "#" not in value_name: if "$!ALG" in value_name: alg_list += utils.expand_alg_macro(value_name, tpm_alg_ids, alg_dep) elif "!ALG" in value_name: alg_list += utils.expand_alg_macro(value_name, tpm_alg_ids, alg_dep) else: cases.append(value_name) else: rc_fail = value_name.replace("#", "") # end of loop - for row in table.rows: if "!ALG.S" in current_type: # interpret the table as multiple tables for alg in alg_list: # symmetric algorithm in question alg_name = re.search(r'TPM_ALG_(.*)', alg.name) alg_name = alg_name.group(1) # substitute '!ALG.S' part in the value with the ALG name val = re.sub(r'!ALG\.S', alg_name, current_type) self.content += "// Table 2:" + table.number + " - " \ + table.short_name.replace("{!ALG.S} (TPM_KEY_BITS) ", "").replace("!ALG.S", alg_name) \ + " (" + table.table_type + ")\n" self.content_fp += "// Table 2:" + table.number + " - " \ + table.short_name.replace("{!ALG.S} (TPM_KEY_BITS) ", "").replace("!ALG.S", alg_name) \ + " (" + table.table_type + ")\n" # manually set individual alg_deps self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_name) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_name) # utilize cases for individual sizes of the supported ALG sizes cases = constants.S_KEY_SIZES[alg.name] self.content += self.interface_table_marshaller.create_unmarshal_code( val, base_type, cases, None, checks, conditions, rc_fail) self.content_fp += self.interface_table_marshaller.create_unmarshal_fp(val) # out self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format(val) self.content_fp += self.interface_table_marshaller.create_marshal_fp_define(val, base_type) # manually set individual alg_deps self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_name) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_name) # end of loop - for alg in alg_list: else: if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) # in if in_declaration: self.content += self.interface_table_marshaller.create_unmarshal_code( current_type, base_type, cases, alg_list, checks, conditions, rc_fail) self.content_fp += self.interface_table_marshaller.create_unmarshal_fp(current_type, bool_flag) # out if out_declaration: if base_type in tpm2_partx_type_mapping.dictionary.keys(): self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format(current_type) self.content_fp += self.interface_table_marshaller.create_marshal_fp_define( current_type, base_type) else: self.content += self.interface_table_marshaller.create_marshal_code(current_type, base_type) self.content_fp += self.interface_table_marshaller.create_marshal_fp(current_type) if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) tpm2_partx_type_mapping.dictionary[current_type] = [base_type, table.number] # end of method - handle_interface_table(self, table, tpm_alg_ids): # Handle marshalling for Structures tables by calling required functions from StructureTableMarshaller based on # in/out declarations in table name, using definition guards (ifdefs) when necessary # Parameters: # typedef_name - type of the generated marshaling functions # table - internal representation of the table, based on which marshaling functions are generated def handle_structures_table(self, typedef_name, table): self.create_header_comment(table) bool_flag = False result = re.search('<(.*)>', table.name) if result: config = result.group(1) else: config = "IN/OUT" in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) alg_dep = utils.find_alg_constraints(table.name) for row in table.rows: parameter = row[0] member_type = row[1] if "+TPM" in member_type: self.function_prototypes_with_flag[typedef_name] = "" bool_flag = True if "[count]" in parameter or "[size]" in parameter: self.array_functions[member_type] = [alg_dep, config] # end of loop - for row in table.rows: if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) if in_declaration is None: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format(typedef_name) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format(typedef_name) if len(table.rows) == 1: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format(typedef_name) self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format(typedef_name) only_row = table.rows[0] parameter = only_row[0] member_type = only_row[1] if member_type.endswith("+"): self.content_fp += self.structure_table_marshaller.create_unmarshal_fp_define( typedef_name, member_type.replace("+", ""), parameter, 1) self.content_fp += self.structure_table_marshaller.create_marshal_fp_define( typedef_name, member_type.replace("+", ""), parameter, 1) else: self.content_fp += self.structure_table_marshaller.create_unmarshal_fp_define( typedef_name, member_type, parameter, 0) self.content_fp += self.structure_table_marshaller.create_marshal_fp_define( typedef_name, member_type, parameter, 0) else: # in if in_declaration: self.content += self.structure_table_marshaller.create_unmarshal_code( typedef_name, table, self.function_prototypes_with_flag) self.content_fp += self.structure_table_marshaller.create_unmarshal_fp(typedef_name, bool_flag) # out if out_declaration: self.content += self.structure_table_marshaller.create_marshal_code( typedef_name, table, self.function_prototypes_with_flag) self.content_fp += self.structure_table_marshaller.create_marshal_fp(typedef_name) if out_declaration is None: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format(typedef_name) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format(typedef_name) if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) tpm2_partx_type_mapping.dictionary[typedef_name] = [None, table.number] # end of method - handle_structures_table(self, value, table): # Handle marshalling for empty structures using StructureTableMarshaller for function prototypes # Parameters: # table - internal representation of the table, based on which marshaling functions are generated def handle_structures_table_empty_structure(self, table): self.content += tpm2_partx_marshal_templates.TPMS_EMPTY_UNMARSHAL self.content += tpm2_partx_marshal_templates.TPMS_EMPTY_MARSHAL self.content_fp += self.structure_table_marshaller.create_unmarshal_fp("TPMS_EMPTY") self.content_fp += self.structure_table_marshaller.create_marshal_fp("TPMS_EMPTY") tpm2_partx_type_mapping.dictionary["TPMS_EMPTY"] = [None, table.number] # end of method - handle_structures_table_empty_structure(self): # Handle marshalling for Union tables by calling # required functions from UnionTableMarshaller based on in/out declarations in table name # Parameters: # table - internal representation of the table, based on which marshaling functions are generated # tpm_alg_ids - mapping from algorithm types to list of corresponding algorithm IDs def handle_union_table(self, table, tpm_alg_ids): self.create_header_comment(table) current_type = utils.find_tpm_type_name(table.short_name) alg_dep = re.search('{(.*)}', table.short_name) if alg_dep: alg_dep = alg_dep.group(1) result = re.search('<(.*)>', table.name) if result: config = result.group(1) else: config = "IN/OUT" in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) # in if in_declaration: self.content += self.union_table_marshaller.create_unmarshal_code( current_type, table.rows, tpm_alg_ids, self.function_prototypes_with_flag) self.content_fp += self.union_table_marshaller.create_unmarshal_fp(current_type) else: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format(current_type) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format(current_type) # out if out_declaration: self.content += self.union_table_marshaller.create_marshal_code( current_type, table.rows, tpm_alg_ids, self.function_prototypes_with_flag) self.content_fp += self.union_table_marshaller.create_marshal_fp(current_type) else: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format(current_type) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format(current_type) if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) # end of method - handle_union_table(self, table, tpm_alg_ids): # Handle marshalling for arrays by calling required functions from ArrayMarshaller based on in/out declarations # in the list of array functions, using definition guards (ifdefs) when necessary def handle_arrays(self): for function in self.array_functions: bool_flag = False # add comment for marshalling/unmarshalling of arrays (see Part 4, Section 4) self.content += tpm2_partx_marshal_templates.COMMENT_Array_Un_Marshal_TYPE.format(function) self.content_fp += tpm2_partx_marshal_templates.COMMENT_Array_Un_Marshal_TYPE.format(function) alg_dep = self.array_functions[function][0] config = self.array_functions[function][1] in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format(alg_dep) if function in self.function_prototypes_with_flag.keys(): bool_flag = True # in if in_declaration: self.content += self.array_marshaller.create_unmarshal_code(function, bool_flag) self.content_fp += self.array_marshaller.create_unmarshal_fp(function, bool_flag) else: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Array_Unmarshal_not_req.format(function) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Array_Unmarshal_not_req.format(function) # out if out_declaration: self.content += self.array_marshaller.create_marshal_code(function) self.content_fp += self.array_marshaller.create_marshal_fp(function) else: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Array_Marshal_not_req.format(function) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Array_Marshal_not_req.format(function) if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format(alg_dep) # end of method -handle_arrays(self): # Create marshaling source files with FileHandler at path defined in the constructor, containing marshaling # functions based on the tables def write(self): self.content = u'#include "InternalRoutines.h"\n\n' + self.content # marshal.c FileHandling.write_file(self.file_path, self.content) # marshal_fp.h self.content_fp = u'#ifndef _MARSHAL_FP_H\n\ #define _MARSHAL_FP_H\n\n'\ + self.content_fp self.content_fp += "#endif // _MARSHAL_FP_H" FileHandling.write_file(self.file_path_fp, self.content_fp)
class Marshaller: # Initialises paths to destination files of marshalling source code, and instantiates all marshalling subclasses def __init__(self): if settings.SPEC_VERSION_INT < 138: self.file_path = constants.SRC_PATH + constants.TPM_PATH + "/support/marshal.c" self.file_path_fp = constants.SRC_PATH + constants.TPM_PATH + "/include/prototypes/marshal_fp.h" else: self.file_path = constants.SRC_PATH + constants.TPM_PATH + "/support/Marshal.c" self.file_path_fp = constants.SRC_PATH + constants.TPM_PATH + "/include/prototypes/Marshal_fp.h" self.file = None self.content = u"" self.content_fp = u"" # Create marshallers self.simple_marshaller = SimpleMarshaller() self.advanced_marshaller = AdvancedMarshaller() self.bits_table_marshaller = BitsTableMarshaller() self.interface_table_marshaller = InterfaceTableMarshaller() self.structure_table_marshaller = StructureTableMarshaller() self.union_table_marshaller = UnionTableMarshaller() self.array_marshaller = ArrayMarshaller() # Initialize dictionaries self.array_functions = dict() self.function_prototypes_with_flag = dict() # Creates header comment for a specific table and adds it to the contents of marshal files # Parameters: # table - internal representation of the table, containing the metainformation about itself to generate comment def create_header_comment(self, table): self.content += "\n// Table 2:" + table.number + " - " + table.short_name + " (" + table.table_type + ")\n" self.content_fp += "\n// Table 2:" + table.number + " - " + table.short_name + " (" + table.table_type + ")\n" # Checks if base type already present in type mapping dictionary # Parameters: # base_type - string containing name of base type # Returns: # base type - string containing name of base type # boolean value - representing the availability of the base type in the dictionary @staticmethod def handle_base_types(base_type): if "int" in base_type: for entry in tpm2_partx_type_mapping.dictionary.iteritems(): if entry[1][0] == base_type or entry[1][0] == "u" + base_type: base_type = entry[0] return base_type, True return base_type, False # Handle marshalling for Typedef tables and BaseType tables by calling required functions from SimpleMarshaller # For every base type that contains an algorithm type, marshaling functions are generated for each algorithm, # (if not already done or already defined) surrounded by define guards (ifdefs) # Parameters: # table - internal representation of the table, based on which marshaling functions are generated # tpm_alg_ids - mapping from algorithm types to list of corresponding algorithm IDs def handle_simple_type_structures_new(self, table, tpm_alg_ids=None): self.create_header_comment(table) for row in table.rows: base_type = row[0] new_type = row[1] types_list = [] # check for !ALG alg_dep = utils.find_alg_constraints(table.short_name) algs = utils.expand_alg_macro(new_type, tpm_alg_ids, alg_dep) for alg in algs: typedef = utils.replace_alg_placeholder( new_type, alg.short_name) types_list.append(typedef) # end of loop - for alg in alg_list: # in case there is no !ALG if not algs: types_list = [new_type] # handle the (list of) typ(es) in the current row for current_type in types_list: if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) # check if type is a C base type and already in mapping dictionary base_type, c_base_type = self.handle_base_types(base_type) already_marshaled = base_type in tpm2_partx_type_mapping.dictionary.keys( ) unsigned_marshaled = "u" + base_type in tpm2_partx_type_mapping.dictionary.keys( ) if unsigned_marshaled: base_type = "u" + base_type if c_base_type or already_marshaled or unsigned_marshaled: # if original type was already marshaled somehow # marshalling new type would be redundant - change to define for new type orig_mrshl = tpm2_partx_type_mapping.dictionary[base_type] orig_table_nr = orig_mrshl[1] # recursive exploration of most basic base_type in mapping dictionary base_type = utils.find_basic_base_type(base_type) # add a comment that points to the origin of the type definition self.content += "// " + base_type + " definition used from Table 2:" + orig_table_nr + "\n" self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format( current_type) self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format( current_type) self.content_fp += self.simple_marshaller.create_unmarshal_fp_define( current_type, base_type) self.content_fp += self.simple_marshaller.create_marshal_fp_define( current_type, base_type) else: # handle base types: figure out the size size = utils.find_base_type_size(base_type) if not size: # skip base type without size (i.e. 'int', which is used for 'BOOL') continue self.content += self.simple_marshaller.create_unmarshal_code( current_type, int(size) / 8) self.content += self.simple_marshaller.create_marshal_code( current_type, int(size) / 8) self.content_fp += self.simple_marshaller.create_unmarshal_fp( current_type) self.content_fp += self.simple_marshaller.create_marshal_fp( current_type) if unsigned_marshaled: base_type = base_type[1:] tpm2_partx_type_mapping.dictionary[current_type] = [ base_type, table.number ] # done with the new type if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) self.content += "\n" self.content_fp += "\n" # end of loop - for row in table.rows: # end of method - handle_simple_type_structures_new(self, table, tpm_alg_ids): # Handle marshalling for special tables, which are not used to create constant or type definitions, by calling # required functions from SimpleMarshaller, if base type found in table name not already marshaled # Parameters: # table - internal representation of the table, based on which marshaling functions are generated def handle_simple_constants(self, table): self.create_header_comment(table) base_type = utils.find_tpm_base_type_name(table.short_name) current_type = utils.find_tpm_type_name(table.short_name) alg_dep = utils.find_alg_dep(table.short_name) size = utils.find_base_type_size(base_type) if not size: return if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) already_marshaled = base_type in tpm2_partx_type_mapping.dictionary.keys( ) if already_marshaled: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format( current_type) self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format( current_type) self.content_fp += self.simple_marshaller.create_unmarshal_fp_define( current_type, base_type) self.content_fp += self.simple_marshaller.create_marshal_fp_define( current_type, base_type) else: self.content += self.simple_marshaller.create_unmarshal_code( current_type, int(size) / 8) self.content += self.simple_marshaller.create_marshal_code( current_type, int(size) / 8) self.content_fp += self.simple_marshaller.create_unmarshal_fp( current_type) self.content_fp += self.simple_marshaller.create_marshal_fp( current_type) tpm2_partx_type_mapping.dictionary[current_type] = [ base_type, table.number ] if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) # end of method - handle_simple_constants(self, table): # Handle marshalling for Enum tables by calling # required functions from AdvancedMarshaller, based on in/out declarations in table name # Parameters: # table - internal representation of the table, based on which marshaling functions are generated def handle_advanced_type_structures(self, table): self.create_header_comment(table) base_type = utils.find_tpm_base_type_name(table.short_name) current_type = utils.find_tpm_type_name(table.short_name) config = utils.find_config(table.name) size = utils.find_base_type_size(base_type) if not size: return in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) s_declaration = re.search('([S])', config) cases = [] rc_fail = None for row in table.rows: name = row[0] if "#" in name: rc_fail = name.replace("#", "") elif "TPM_CAP_FIRST" in name or "TPM_CAP_LAST" in name: continue # skip else: cases.append(name) # in if in_declaration is None: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format( current_type) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format( current_type) else: if (base_type in tpm2_partx_type_mapping.dictionary.keys() or s_declaration) and not rc_fail: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format( current_type) self.content_fp += self.advanced_marshaller.create_unmarshal_fp_define( current_type, base_type) else: self.content += self.advanced_marshaller.create_unmarshal_code( current_type, base_type, cases, rc_fail) self.content_fp += self.advanced_marshaller.create_unmarshal_fp( current_type) # out if out_declaration is None: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format( current_type) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format( current_type) else: if base_type in tpm2_partx_type_mapping.dictionary.keys( ) or s_declaration: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format( current_type) self.content_fp += self.advanced_marshaller.create_marshal_fp_define( current_type, base_type) else: self.content += self.advanced_marshaller.create_marshal_code( current_type, size) self.content_fp += self.advanced_marshaller.create_marshal_fp( current_type) tpm2_partx_type_mapping.dictionary[current_type] = [ base_type, table.number ] # end of method - handle_advanced_type_structures(self, table): # Handle marshalling for Bits tables by calling required functions from BitsTableMarshaller based on the base type # found in table name, if base type not already marshaled # Parameters: # table - internal representation of the table, based on which marshaling functions are generated def handle_bits_table(self, table): self.create_header_comment(table) base_type = utils.find_tpm_base_type_name(table.short_name) current_type = utils.find_tpm_type_name(table.short_name) reserved = 0 i = 0 for row in table.rows: bit_idx = row[0] bit_name = row[1] bits = 1 if ":" in bit_idx and "Reserved" in bit_name: values = bit_idx.split(":") from_value = int(values[1]) to_value = int(values[0]) for b in range(from_value, to_value + 1): reserved |= (1 << b) elif "Reserved" in bit_name: reserved |= (1 << i) i += bits # end of loop - for row in table.rows: # generate a bit mask starting with 0x... reserved = "0x%0.2X" % reserved result = re.search("(int|INT)([1368][246]*)", base_type) if result: size = result.group(2) elif base_type in tpm2_partx_type_mapping.dictionary.keys( ) and tpm2_partx_type_mapping.dictionary[base_type]: size = tpm2_partx_type_mapping.dictionary[base_type][0] else: return # in if base_type in tpm2_partx_type_mapping.dictionary.keys( ) and reserved == "0x00": self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format( current_type) self.content_fp += self.bits_table_marshaller.create_unmarshal_fp_define( current_type, base_type) else: self.content += self.bits_table_marshaller.create_unmarshal_code( current_type, base_type, reserved, None) self.content_fp += self.bits_table_marshaller.create_unmarshal_fp( current_type) # out if base_type in tpm2_partx_type_mapping.dictionary.keys(): self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format( current_type) self.content_fp += self.bits_table_marshaller.create_marshal_fp_define( current_type, base_type) else: self.content += self.bits_table_marshaller.create_marshal_code( current_type, size) self.content_fp += self.bits_table_marshaller.create_marshal_fp( current_type) tpm2_partx_type_mapping.dictionary[current_type] = [ base_type, table.number ] # end of method - handle_bits_table(self, table): # Handle marshalling for Interface tables by calling # required functions from InterfaceTableMarshaller based on in/out declarations in table name, # using definition guards (ifdefs) when necessary # It interprets the table as multiple tables, in the case that an algorithm type name is found in the table name # Parameters: # table - internal representation of the table, based on which marshaling functions are generated # tpm_alg_ids - mapping from algorithm types to list of corresponding algorithm IDs def handle_interface_table(self, table, tpm_alg_ids): self.create_header_comment(table) bool_flag = False base_type = utils.find_tpm_base_type_name(table.short_name) current_type = utils.find_tpm_type_name(table.short_name) # config block begin config = re.search('<(.*)>', table.name) if config: config = config.group(1) else: config = "IN/OUT" in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) # s_declaration = re.search('([S])', config) # config block end # distinguish between a normal case, when a simple table needs to be processed # and a case, where a table represents multiple tables (see table 124) alg_dep = None if "!" not in current_type: result = re.search('\{(.*)\}', table.name) if result: alg_dep = result.group(1) cases = [] alg_list = [] checks = [] conditions = None rc_fail = None for row in table.rows: value_name = row[0] if "{" in value_name: values = value_name.split(":") from_value = values[0].replace("{", "") to_value = values[1].replace("}", "") checks.append([from_value.strip(), to_value.strip()]) elif "+TPM" in value_name: conditions = value_name.replace("+", "") self.function_prototypes_with_flag[current_type] = "" bool_flag = True elif "$RSA_KEY_SIZES_BITS" in value_name: cases = constants.RSA_KEY_SIZES_BITS elif "$ECC_CURVES" in value_name: cases = constants.ECC_CURVES elif "#" not in value_name: if "$!ALG" in value_name: alg_list += utils.expand_alg_macro(value_name, tpm_alg_ids, alg_dep) elif "!ALG" in value_name: alg_list += utils.expand_alg_macro(value_name, tpm_alg_ids, alg_dep) else: cases.append(value_name) else: rc_fail = value_name.replace("#", "") # end of loop - for row in table.rows: if "!ALG.S" in current_type: # interpret the table as multiple tables for alg in alg_list: # symmetric algorithm in question alg_name = re.search(r'TPM_ALG_(.*)', alg.name) alg_name = alg_name.group(1) # substitute '!ALG.S' part in the value with the ALG name val = re.sub(r'!ALG\.S', alg_name, current_type) self.content += "// Table 2:" + table.number + " - " \ + table.short_name.replace("{!ALG.S} (TPM_KEY_BITS) ", "").replace("!ALG.S", alg_name) \ + " (" + table.table_type + ")\n" self.content_fp += "// Table 2:" + table.number + " - " \ + table.short_name.replace("{!ALG.S} (TPM_KEY_BITS) ", "").replace("!ALG.S", alg_name) \ + " (" + table.table_type + ")\n" # manually set individual alg_deps self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_name) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_name) # utilize cases for individual sizes of the supported ALG sizes cases = constants.S_KEY_SIZES[alg.name] self.content += self.interface_table_marshaller.create_unmarshal_code( val, base_type, cases, None, checks, conditions, rc_fail) self.content_fp += self.interface_table_marshaller.create_unmarshal_fp( val) # out self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format( val) self.content_fp += self.interface_table_marshaller.create_marshal_fp_define( val, base_type) # manually set individual alg_deps self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_name) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_name) # end of loop - for alg in alg_list: else: if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) # in if in_declaration: self.content += self.interface_table_marshaller.create_unmarshal_code( current_type, base_type, cases, alg_list, checks, conditions, rc_fail) self.content_fp += self.interface_table_marshaller.create_unmarshal_fp( current_type, bool_flag) # out if out_declaration: if base_type in tpm2_partx_type_mapping.dictionary.keys(): self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format( current_type) self.content_fp += self.interface_table_marshaller.create_marshal_fp_define( current_type, base_type) else: self.content += self.interface_table_marshaller.create_marshal_code( current_type, base_type) self.content_fp += self.interface_table_marshaller.create_marshal_fp( current_type) if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) tpm2_partx_type_mapping.dictionary[current_type] = [ base_type, table.number ] # end of method - handle_interface_table(self, table, tpm_alg_ids): # Handle marshalling for Structures tables by calling required functions from StructureTableMarshaller based on # in/out declarations in table name, using definition guards (ifdefs) when necessary # Parameters: # typedef_name - type of the generated marshaling functions # table - internal representation of the table, based on which marshaling functions are generated def handle_structures_table(self, typedef_name, table): self.create_header_comment(table) bool_flag = False result = re.search('<(.*)>', table.name) if result: config = result.group(1) else: config = "IN/OUT" in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) alg_dep = utils.find_alg_constraints(table.name) for row in table.rows: parameter = row[0] member_type = row[1] if "+TPM" in member_type: self.function_prototypes_with_flag[typedef_name] = "" bool_flag = True if "[count]" in parameter or "[size]" in parameter: self.array_functions[member_type] = [alg_dep, config] # end of loop - for row in table.rows: if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) if in_declaration is None: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format( typedef_name) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format( typedef_name) if len(table.rows) == 1: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_defined.format( typedef_name) self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_defined.format( typedef_name) only_row = table.rows[0] parameter = only_row[0] member_type = only_row[1] if member_type.endswith("+"): self.content_fp += self.structure_table_marshaller.create_unmarshal_fp_define( typedef_name, member_type.replace("+", ""), parameter, 1) self.content_fp += self.structure_table_marshaller.create_marshal_fp_define( typedef_name, member_type.replace("+", ""), parameter, 1) else: self.content_fp += self.structure_table_marshaller.create_unmarshal_fp_define( typedef_name, member_type, parameter, 0) self.content_fp += self.structure_table_marshaller.create_marshal_fp_define( typedef_name, member_type, parameter, 0) else: # in if in_declaration: self.content += self.structure_table_marshaller.create_unmarshal_code( typedef_name, table, self.function_prototypes_with_flag) self.content_fp += self.structure_table_marshaller.create_unmarshal_fp( typedef_name, bool_flag) # out if out_declaration: self.content += self.structure_table_marshaller.create_marshal_code( typedef_name, table, self.function_prototypes_with_flag) self.content_fp += self.structure_table_marshaller.create_marshal_fp( typedef_name) if out_declaration is None: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format( typedef_name) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format( typedef_name) if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) tpm2_partx_type_mapping.dictionary[typedef_name] = [None, table.number] # end of method - handle_structures_table(self, value, table): # Handle marshalling for empty structures using StructureTableMarshaller for function prototypes # Parameters: # table - internal representation of the table, based on which marshaling functions are generated def handle_structures_table_empty_structure(self, table): if settings.SPEC_VERSION_INT < 138: self.content += tpm2_partx_marshal_templates.TPMS_EMPTY_UNMARSHAL_pre138 self.content += tpm2_partx_marshal_templates.TPMS_EMPTY_MARSHAL_pre138 else: self.content += tpm2_partx_marshal_templates.TPMS_EMPTY_UNMARSHAL self.content += tpm2_partx_marshal_templates.TPMS_EMPTY_MARSHAL self.content_fp += self.structure_table_marshaller.create_unmarshal_fp( "TPMS_EMPTY") self.content_fp += self.structure_table_marshaller.create_marshal_fp( "TPMS_EMPTY") tpm2_partx_type_mapping.dictionary["TPMS_EMPTY"] = [None, table.number] # end of method - handle_structures_table_empty_structure(self): # Handle marshalling for Union tables by calling # required functions from UnionTableMarshaller based on in/out declarations in table name # Parameters: # table - internal representation of the table, based on which marshaling functions are generated # tpm_alg_ids - mapping from algorithm types to list of corresponding algorithm IDs def handle_union_table(self, table, tpm_alg_ids): self.create_header_comment(table) current_type = utils.find_tpm_type_name(table.short_name) alg_dep = re.search('{(.*)}', table.short_name) if alg_dep: alg_dep = alg_dep.group(1) result = re.search('<(.*)>', table.name) if result: config = result.group(1) else: config = "IN/OUT" in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) # in if in_declaration: self.content += self.union_table_marshaller.create_unmarshal_code( current_type, table.rows, tpm_alg_ids, self.function_prototypes_with_flag) self.content_fp += self.union_table_marshaller.create_unmarshal_fp( current_type) else: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format( current_type) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Unmarshal_not_req.format( current_type) # out if out_declaration: self.content += self.union_table_marshaller.create_marshal_code( current_type, table.rows, tpm_alg_ids, self.function_prototypes_with_flag) self.content_fp += self.union_table_marshaller.create_marshal_fp( current_type) else: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format( current_type) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Marshal_not_req.format( current_type) if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) # end of method - handle_union_table(self, table, tpm_alg_ids): # Handle marshalling for arrays by calling required functions from ArrayMarshaller based on in/out declarations # in the list of array functions, using definition guards (ifdefs) when necessary def handle_arrays(self): for function in self.array_functions: bool_flag = False # add comment for marshalling/unmarshalling of arrays (see Part 4, Section 4) self.content += tpm2_partx_marshal_templates.COMMENT_Array_Un_Marshal_TYPE.format( function) self.content_fp += tpm2_partx_marshal_templates.COMMENT_Array_Un_Marshal_TYPE.format( function) alg_dep = self.array_functions[function][0] config = self.array_functions[function][1] in_declaration = re.search('([iI])', config) out_declaration = re.search('([oO])', config) if alg_dep: self.content += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.IFDEF_ALG.format( alg_dep) if function in self.function_prototypes_with_flag.keys(): bool_flag = True # in if in_declaration: self.content += self.array_marshaller.create_unmarshal_code( function, bool_flag) self.content_fp += self.array_marshaller.create_unmarshal_fp( function, bool_flag) else: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Array_Unmarshal_not_req.format( function) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Array_Unmarshal_not_req.format( function) # out if out_declaration: self.content += self.array_marshaller.create_marshal_code( function) self.content_fp += self.array_marshaller.create_marshal_fp( function) else: self.content += tpm2_partx_marshal_templates.COMMENT_TYPE_Array_Marshal_not_req.format( function) self.content_fp += tpm2_partx_marshal_templates.COMMENT_TYPE_Array_Marshal_not_req.format( function) if alg_dep: self.content += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) self.content_fp += tpm2_partx_marshal_templates.ENDIF_ALG.format( alg_dep) # end of method -handle_arrays(self): # Create marshaling source files with FileHandler at path defined in the constructor, containing marshaling # functions based on the tables def write(self): if settings.SPEC_VERSION_INT < 138: self.content = u'#include "InternalRoutines.h"\n\n' + self.content else: self.content = u'#include "Tpm.h"\n\n' + self.content # marshal.c FileHandling.write_file(self.file_path, self.content) # marshal_fp.h self.content_fp = u'#ifndef _MARSHAL_FP_H\n\ #define _MARSHAL_FP_H\n\n'\ + self.content_fp self.content_fp += "#endif // _MARSHAL_FP_H" FileHandling.write_file(self.file_path_fp, self.content_fp)