79 lines
2.5 KiB
Python
79 lines
2.5 KiB
Python
|
#! /usr/bin/env python
|
||
|
|
||
|
import os
|
||
|
import sys
|
||
|
import struct
|
||
|
import tempfile
|
||
|
import commands
|
||
|
|
||
|
VERSION = 0
|
||
|
MAGIC_NUMBER = 0xb001b001
|
||
|
BLOCK_SIZE = 4096
|
||
|
METADATA_SIZE = BLOCK_SIZE * 8
|
||
|
|
||
|
def run(cmd):
|
||
|
status, output = commands.getstatusoutput(cmd)
|
||
|
print output
|
||
|
if status:
|
||
|
exit(-1)
|
||
|
|
||
|
def get_verity_metadata_size(data_size):
|
||
|
return METADATA_SIZE
|
||
|
|
||
|
def build_metadata_block(verity_table, signature):
|
||
|
table_len = len(verity_table)
|
||
|
block = struct.pack("II256sI", MAGIC_NUMBER, VERSION, signature, table_len)
|
||
|
block += verity_table
|
||
|
block = block.ljust(METADATA_SIZE, '\x00')
|
||
|
return block
|
||
|
|
||
|
def sign_verity_table(table, signer_path, key_path):
|
||
|
with tempfile.NamedTemporaryFile(suffix='.table') as table_file:
|
||
|
with tempfile.NamedTemporaryFile(suffix='.sig') as signature_file:
|
||
|
table_file.write(table)
|
||
|
table_file.flush()
|
||
|
cmd = " ".join((signer_path, table_file.name, key_path, signature_file.name))
|
||
|
print cmd
|
||
|
run(cmd)
|
||
|
return signature_file.read()
|
||
|
|
||
|
def build_verity_table(block_device, data_blocks, root_hash, salt):
|
||
|
table = "1 %s %s %s %s %s %s sha256 %s %s"
|
||
|
table %= ( block_device,
|
||
|
block_device,
|
||
|
BLOCK_SIZE,
|
||
|
BLOCK_SIZE,
|
||
|
data_blocks,
|
||
|
data_blocks + (METADATA_SIZE / BLOCK_SIZE),
|
||
|
root_hash,
|
||
|
salt)
|
||
|
return table
|
||
|
|
||
|
def build_verity_metadata(data_blocks, metadata_image, root_hash,
|
||
|
salt, block_device, signer_path, signing_key):
|
||
|
# build the verity table
|
||
|
verity_table = build_verity_table(block_device, data_blocks, root_hash, salt)
|
||
|
# build the verity table signature
|
||
|
signature = sign_verity_table(verity_table, signer_path, signing_key)
|
||
|
# build the metadata block
|
||
|
metadata_block = build_metadata_block(verity_table, signature)
|
||
|
# write it to the outfile
|
||
|
with open(metadata_image, "wb") as f:
|
||
|
f.write(metadata_block)
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
if len(sys.argv) == 3 and sys.argv[1] == "-s":
|
||
|
print get_verity_metadata_size(int(sys.argv[2]))
|
||
|
elif len(sys.argv) == 8:
|
||
|
data_image_blocks = int(sys.argv[1]) / 4096
|
||
|
metadata_image = sys.argv[2]
|
||
|
root_hash = sys.argv[3]
|
||
|
salt = sys.argv[4]
|
||
|
block_device = sys.argv[5]
|
||
|
signer_path = sys.argv[6]
|
||
|
signing_key = sys.argv[7]
|
||
|
build_verity_metadata(data_image_blocks, metadata_image, root_hash,
|
||
|
salt, block_device, signer_path, signing_key)
|
||
|
else:
|
||
|
exit(-1)
|