예제 #1
0
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
예제 #2
0
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
예제 #3
0
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)