def export(self, padding8: Optional[bytes] = None, dbg_info: DebugInfo = DebugInfo.disabled()) -> bytes: """Serialization to binary form. :param padding8: 8 padding bytes used for in the header, None to use random bytes This value shall be used only for regression testing to generate same results :param dbg_info: class allowing to debug output from the export :return: Serialize object into bytes """ major_version, minor_version = [int(v) for v in self.version.split('.')] product_version_words = [swap16(n) for n in self.product_version.nums] component_version_words = [swap16(n) for n in self.component_version.nums] signature2 = crypto_backend().random_bytes(4) padding = padding8 if padding8 else crypto_backend().random_bytes(8) if (major_version > 1) or ((major_version == 1) and (minor_version >= 2)): signature2 = self._SIGNATURE2 dbg_info.append_section('SB-file-Header') result = pack( self._FORMAT, self.digest, self._SIGNATURE1, # header version major_version, minor_version, self.flags, self.image_blocks, self.first_boot_tag_block, self.first_boot_section_id, self.key_count, self.key_dictionary_block, self.header_blocks, self.section_count, self.section_header_size, padding[0:2], signature2, pack_timestamp(self.timestamp), # product version product_version_words[0], 0, product_version_words[1], 0, product_version_words[2], 0, # component version component_version_words[0], 0, component_version_words[1], 0, component_version_words[2], 0, self.drive_tag, padding[2:] ) result = result[len(self.digest):] self.digest = crypto_backend().hash(result, 'sha1') dbg_info.append_binary_section('digest', self.digest) dbg_info.append_binary_section('attrs', result) return self.digest + result
def _log_test_output(dbg_info: DebugInfo) -> None: """Uses all methods of DebugInfo class to append data in different format :param dbg_info: instance used for logging """ dbg_info.append_section("SECTION") dbg_info.append("-test-line-") dbg_info.append_binary_section("bin", b"\x00\x11\x22\xFF") dbg_info.append_binary_data("data", b"\x00\x11\x22") dbg_info.append_hex_data(b"\x00\x11\x22\x00\x11\x22\x00\x11\x22\x00\x11\x22")
def _log_test_output(dbg_info: DebugInfo) -> None: """Uses all methods of DebugInfo class to append data in different format :param dbg_info: instance used for logging """ dbg_info.append_section('SECTION') dbg_info.append('-test-line-') dbg_info.append_binary_section('bin', b'\x00\x11\x22\xFF') dbg_info.append_binary_data('data', b'\x00\x11\x22') dbg_info.append_hex_data( b'\x00\x11\x22\x00\x11\x22\x00\x11\x22\x00\x11\x22')
def export(self, dbg_info: DebugInfo = DebugInfo.disabled()) -> bytes: """Return binary representation of the class (serialization).""" self.update() dbg_info.append_section('Section') data = self._header.export() dbg_info.append_binary_data('Section-header', data) dbg_info.append_section('Commands') for cmd in self._commands: cmd_data = cmd.export(dbg_info) data += cmd_data return data
def export( self, header_padding8: Optional[bytes] = None, auth_padding: Optional[bytes] = None, dbg_info: DebugInfo = DebugInfo.disabled(), ) -> bytes: """Serialization to binary form. :param header_padding8: optional header padding, 8-bytes; recommended to use None to apply random value :param auth_padding: optional padding used after authentication; recommended to use None to apply random value :param dbg_info: instance allowing to debug generated output :return: serialize the instance into binary data :raises SPSDKError: Invalid section data :raises SPSDKError: Invalid padding length """ self.update() self.validate() dbg_info.append_section("SB-FILE-1.x") data = self._header.export(padding8=header_padding8, dbg_info=dbg_info) # header table dbg_info.append_section("Sections-Header-Table") for sect_hdr in self._sections_hdr_table: sect_hdr_data = sect_hdr.export() dbg_info.append_binary_data("Section-Header-Item", sect_hdr_data) data += sect_hdr_data # sections dbg_info.append_section("Sections") for sect in self._sections: sect_data = sect.export(dbg_info) if len(sect_data) != sect.size: raise SPSDKError("Invalid section data") data += sect_data # authentication: SHA1 auth_code = crypto_backend().hash(data, "sha1") dbg_info.append_binary_section("SHA1", auth_code) data += auth_code # padding padding_len = align(len(auth_code), SecBootBlckSize.BLOCK_SIZE) - len(auth_code) if auth_padding is None: auth_padding = crypto_backend().random_bytes(padding_len) if padding_len != len(auth_padding): raise SPSDKError("Invalid padding length") data += auth_padding dbg_info.append_binary_section("padding", auth_padding) return data
def export( self, header_padding8: Optional[bytes] = None, auth_padding: Optional[bytes] = None, dbg_info: DebugInfo = DebugInfo.disabled() ) -> bytes: """Serialization to binary form. :param header_padding8: optional header padding, 8-bytes; recommended to use None to apply random value :param auth_padding: optional padding used after authentication; recommended to use None to apply random value :param dbg_info: instance allowing to debug generated output :return: serialize the instance into binary data """ self.update() self.validate() dbg_info.append_section('SB-FILE-1.x') data = self._header.export(padding8=header_padding8, dbg_info=dbg_info) # header table dbg_info.append_section('Sections-Header-Table') for sect_hdr in self._sections_hdr_table: sect_hdr_data = sect_hdr.export() dbg_info.append_binary_data('Section-Header-Item', sect_hdr_data) data += sect_hdr_data # sections dbg_info.append_section('Sections') for sect in self._sections: sect_data = sect.export(dbg_info) assert len(sect_data) == sect.size data += sect_data # authentication: SHA1 auth_code = crypto_backend().hash(data, 'sha1') dbg_info.append_binary_section('SHA1', auth_code) data += auth_code # padding padding_len = align(len(auth_code), SecBootBlckSize.BLOCK_SIZE) - len(auth_code) if auth_padding is None: auth_padding = crypto_backend().random_bytes(padding_len) assert padding_len == len(auth_padding) data += auth_padding dbg_info.append_binary_section('padding', auth_padding) return data
def export(self, dbg_info: DebugInfo = DebugInfo.disabled()) -> bytes: """Return object serialized into bytes.""" dbg_info.append_section("Command:" + EnumCmdTag.name(self.header.tag)) cmd_data = self._header.export() # default implementation dbg_info.append_binary_data("cmd-header", cmd_data) return cmd_data