def test_save_chunk_doctest(tmppath): path = str(tmppath / 'bytes.mot') data = bytes(range(256)) save_chunk(path, data, 0x12345678) ans_out = load_blocks(path) ans_ref = [(0x12345678, data)] assert ans_out == ans_ref
def test_save_blocks(tmppath): path = str(tmppath / 'bytes.hex') blocks = [(offset, bytes(range(offset, offset + 16))) for offset in range(0, 256, 16)] save_blocks(path, blocks, IntelRecord) ans_out = load_blocks(path) ans_ref = merge(blocks) assert ans_out == ans_ref
def test_load_blocks_doctest(tmppath): path = str(tmppath / 'bytes.mot') blocks = [(offset, bytes(range(offset, offset + 16))) for offset in range(0, 256, 16)] save_blocks(path, blocks) ans_out = load_blocks(path) ans_ref = merge(blocks) assert ans_out == ans_ref
def pattern_fill_hex(hex, firm): blocks = hr.load_blocks(hex) if ('boot' == firm): blocks = hb.delete(blocks, start=app_start, endex=0xFFFFFFFF) elif ('app' == firm): blocks = hb.delete(blocks, start=signature_start, endex=0xFFFFFFFF) blocks.sort() length = len(blocks) hex_start, hex_length = blocks[length - 1] flooded_block = hb.flood(blocks, endex=(hex_start + len(hex_length)), pattern=b'\xFF') merged_block = hb.merge(flooded_block) return merged_block
def combine_sign_hex(boot_data, app_data): with open(boot_hex, 'wb') as f: f.write(boot_data.data[0]) f.close() with open(app_hex, 'wb') as f: f.write(app_data.data[0]) f.close() merged_boot_hex = pattern_fill_hex(boot_hex, 'boot') hr.save_blocks("firm_valid.hex", merged_boot_hex) hex_boot_start, hex_boot_length = merged_boot_hex[0] print("Firmware validation binary size:", len(hex_boot_length)) merged_app_hex = pattern_fill_hex(app_hex, 'app') hr.save_blocks("app.hex", merged_app_hex) hex_app_start, hex_app_length = merged_app_hex[0] print("Application binary size:", len(hex_app_length)) #Merge boot hex and app hex into single hex blocks_boot = hr.load_blocks("firm_valid.hex") blocks_app = hr.load_blocks("app.hex") merged = blocks_boot + blocks_app merged.sort() flooded = hb.flood(merged, pattern=b'\xFF') flooded = hb.merge(flooded) hr.save_blocks("combined_image.hex", flooded) memory = hr.load_memory("combined_image.hex") #a, data = data_blocks[0] data = memory[boot_start:(app_start + len(hex_app_length)):b'\xFF'] # Setup cryptography crypto_be = cryptography.hazmat.backends.default_backend() with open(key_file, 'rb') as f: # Loading the private key from key_file private_key = serialization.load_pem_private_key(data=f.read(), password=None, backend=crypto_be) # Hashing the Application binary file bin_file chosen_hash = hashes.SHA256() hasher = hashes.Hash(chosen_hash, crypto_be) hasher.update(data) digest = hasher.finalize() print("\nApplication digest:") print(pretty_print_hex(digest, indent=' ')) # Signing the digest of the Application binary file bin_file sign = private_key.sign(digest, ec.ECDSA(utils.Prehashed(chosen_hash))) # Extract actual Signature bytes r_offset = (sign[3] - 32) + 4 sign_r = sign[r_offset:r_offset + 32] s_offset = (sign[r_offset + 32 + 1] - 32) + (r_offset + 32 + 2) sign_s = sign[s_offset:s_offset + 32] calc_sign = sign_r + sign_s print("\nSuccessfully Signed the firmware digest") print("Calculated signature:") print(str(convert_to_hex_bytes(calc_sign))) memory.write(0x3FC00, calc_sign) memory.write(0x3FD00, len(hex_app_length).to_bytes(4, byteorder='little')) hr.save_memory('combined_image.hex', memory)