avs_mtk_voice/meta/meta-mediatek-aud/recipes-bsp/lk/files/pbp/pbp.py

273 lines
9.8 KiB
Python
Raw Permalink Normal View History

2022-05-13 08:02:31 +00:00
import sys
import os
import struct
import subprocess
import shutil
script_folder, script_name = os.path.split(os.path.realpath(__file__))
sys.path.append(os.path.join(script_folder, "lib"))
import gfh
import cert
def get_file_sizeb(file_path):
if not os.path.isfile(file_path):
return 0
file_handle = open(file_path, "rb")
file_handle.seek(0, 2)
file_size = file_handle.tell()
file_handle.close()
return file_size
def concatb(file1_path, file2_path):
file1_size = get_file_sizeb(file1_path)
file2_size = get_file_sizeb(file2_path)
file1 = open(file1_path, "ab+")
file2 = open(file2_path, "rb")
file1.write(file2.read(file2_size))
file2.close()
file1.close()
class bootloader:
def __init__(self, out_path, in_bootloader_file_path, out_bootloader_file_path):
self.m_gfh = gfh.image_gfh()
self.m_out_path = out_path
if not os.path.exists(self.m_out_path):
os.makedirs(self.m_out_path)
self.m_in_bootloader_file_path = in_bootloader_file_path
self.m_out_bootloader_file_path = out_bootloader_file_path
self.m_bootloader_is_signed = False
self.m_bootloader_content_offset = 0
#initialize content size to bootloader file size
self.m_bootloader_content_length = get_file_sizeb(self.m_in_bootloader_file_path)
self.m_bootloader_sig_size = 0
#generate file path for bootloader without gfh and signature
bootloader_path = in_bootloader_file_path.split('.')
self.m_bootloader_no_gfh_file_path = bootloader_path[0] + "_plain.bin"
self.m_sig_ver = 0
self.m_sw_ver = 0
self.m_root_prvk_path = ""
self.m_img_prvk_path = ""
self.m_ac_key = 0
self.m_sig_handler = None
def is_signed(self):
if self.m_in_bootloader_file_path:
bootloader_file = open(self.m_in_bootloader_file_path, "rb")
gfh_hdr_obj = gfh.gfh_header()
gfh_hdr_size = gfh_hdr_obj.get_size()
gfh_hdr_buf = bootloader_file.read(gfh_hdr_size)
self.m_bootloader_is_signed = gfh_hdr_obj.is_gfh(gfh_hdr_buf)
bootloader_file.close()
return self.m_bootloader_is_signed
def parse(self):
print "===parse bootloader==="
#image will be decomposed if it's signed
if self.is_signed():
gfh_total_size = self.m_gfh.parse(self.m_in_bootloader_file_path)
self.m_bootloader_content_offset = gfh_total_size
self.m_bootloader_content_length -= gfh_total_size
self.m_bootloader_content_length -= self.m_gfh.get_sig_size()
self.m_bootloader_sig_size = self.m_gfh.get_sig_size()
in_file = open(self.m_in_bootloader_file_path, "rb")
out_file = open(self.m_bootloader_no_gfh_file_path, "wb")
in_file.seek(self.m_bootloader_content_offset)
out_file.write(in_file.read(self.m_bootloader_content_length))
out_file.close()
in_file.close()
else:
shutil.copyfile(self.m_in_bootloader_file_path, self.m_bootloader_no_gfh_file_path)
print "bootloader content size = " + hex(self.m_bootloader_content_length)
def create_gfh(self, gfh_config):
self.parse()
if gfh_config:
if self.is_signed():
del self.m_gfh.gfhs[:]
self.m_gfh.load_ini(gfh_config)
elif not self.is_signed():
print "GFH_CONFIG.ini does not exist!!"
return -1
#self.m_gfh.dump()
return 0
def sign(self, key_ini_path, key_cert_path, content_config_file_path):
self.m_gfh.finalize(self.m_bootloader_content_length, key_ini_path)
#create tbs_bootloader.bin
tbs_bootloader_file_path = os.path.join(self.m_out_path, "tbs_preloader.bin")
tbs_bootloader_file = open(tbs_bootloader_file_path, "wb")
tbs_bootloader_file.write(self.m_gfh.pack())
bootloader_no_gfh_file = open(self.m_bootloader_no_gfh_file_path, "rb")
tbs_bootloader_file.write(bootloader_no_gfh_file.read(self.m_bootloader_content_length))
bootloader_no_gfh_file.close()
tbs_bootloader_file.close()
print "===sign==="
if self.m_gfh.get_sig_type() == "CERT_CHAIN":
self.m_sig_handler = cert.cert_chain_v2()
#create key cert if key cert does not exist
if key_cert_path == "":
key_cert_path = os.path.join(self.m_out_path, "key_cert.bin")
if not os.path.isfile(key_cert_path):
key_cert_folder_name, key_cert_file_name = os.path.split(os.path.abspath(key_cert_path))
self.m_sig_handler.create_key_cert(key_ini_path, self.m_out_path, key_cert_file_name)
key_cert_path = os.path.join(self.m_out_path, key_cert_file_name)
else:
self.m_sig_handler.set_key_cert(key_cert_path)
#create content cert
content_cert_name = "content_cert.bin"
self.m_sig_handler.create_content_cert(content_config_file_path, tbs_bootloader_file_path, self.m_out_path, content_cert_name)
#create final cert chain
sig_name = "preloader.sig"
sig_file_path = os.path.join(self.m_out_path, sig_name)
self.m_sig_handler.output(self.m_out_path, sig_name)
#output final cert chain size
sig_size_name = "sig_size.txt"
sig_size_file_path = os.path.join(self.m_out_path, sig_size_name)
sig_size_file = open(sig_size_file_path, 'w')
sig_size_file.write(hex(get_file_sizeb(sig_file_path)))
sig_size_file.close()
#create final preloader image
if os.path.isfile(self.m_out_bootloader_file_path):
os.remove(self.m_out_bootloader_file_path)
concatb(self.m_out_bootloader_file_path, tbs_bootloader_file_path)
concatb(self.m_out_bootloader_file_path, sig_file_path)
#clean up
os.remove(os.path.join(self.m_out_path, content_cert_name))
elif self.m_gfh.get_sig_type() == "SINGLE_AND_PHASH":
self.m_sig_handler = cert.sig_single_and_phash(self.m_gfh.get_pad_type())
self.m_sig_handler.set_out_path(self.m_out_path)
self.m_sig_handler.create(key_ini_path, tbs_bootloader_file_path)
#signature generation
self.m_sig_handler.sign()
sig_name = "preloader.sig"
sig_file_path = os.path.join(self.m_out_path, sig_name)
self.m_sig_handler.output(self.m_out_path, sig_name)
#output signature size
sig_size_name = "sig_size.txt"
sig_size_file_path = os.path.join(self.m_out_path, sig_size_name)
sig_size_file = open(sig_size_file_path, 'w')
sig_size_file.write(hex(get_file_sizeb(sig_file_path)))
sig_size_file.close()
#create final preloader image
if os.path.isfile(self.m_out_bootloader_file_path):
os.remove(self.m_out_bootloader_file_path)
concatb(self.m_out_bootloader_file_path, tbs_bootloader_file_path)
concatb(self.m_out_bootloader_file_path, sig_file_path)
else:
print "unknown signature type"
#clean up
os.remove(self.m_bootloader_no_gfh_file_path)
os.remove(tbs_bootloader_file_path)
os.remove(sig_file_path)
return
def main():
#parameter parsing
idx = 1
key_ini_path = ""
key_path = ""
gfh_config_ini_path = ""
content_config_ini_path = ""
key_cert_path = ""
in_bootloader_path = ""
function = "sign"
function_out_path = ""
while idx < len(sys.argv):
if sys.argv[idx][0] == '-':
if sys.argv[idx][1] == 'i':
print "key ini: " + sys.argv[idx + 1]
key_ini_path = sys.argv[idx + 1]
idx += 2
if sys.argv[idx][1] == 'j':
print "key(pem): " + sys.argv[idx + 1]
key_path = sys.argv[idx + 1]
idx += 2
elif sys.argv[idx][1] == 'g':
print "gfh config: " + sys.argv[idx + 1]
gfh_config_ini_path = sys.argv[idx + 1]
idx += 2
elif sys.argv[idx][1] == 'c':
print "content config: " + sys.argv[idx + 1]
content_config_ini_path = sys.argv[idx + 1]
idx += 2
elif sys.argv[idx][1] == 'k':
print "key cert: " + sys.argv[idx + 1]
key_cert_path = sys.argv[idx + 1]
idx += 2
elif sys.argv[idx][1:] == 'func':
print "function: " + sys.argv[idx + 1]
function = sys.argv[idx + 1]
idx += 2
elif sys.argv[idx][1] == 'o':
print "function output: " + sys.argv[idx + 1]
function_out_path = sys.argv[idx + 1]
idx += 2
else:
print "unknown input"
idx += 2
else:
in_bootloader_path = sys.argv[idx]
print "bootloader: " + in_bootloader_path
idx += 1
if (function == "sign") and (not in_bootloader_path):
print "bootloader path is not given!"
return -1
if (not function_out_path):
print "function out path is not given!"
return -1
if function == "sign":
if (key_ini_path == "") and (key_cert_path == ""):
print "key path is not given!"
return -1
else:
if (key_path == "" and key_ini_path == ""):
print "key path is not given!"
return -1
out_path = os.path.dirname(os.path.abspath(function_out_path))
if not os.path.exists(out_path):
os.makedirs(out_path)
if function == "sign":
bootloader_obj = bootloader(out_path, in_bootloader_path, function_out_path)
bootloader_obj.create_gfh(gfh_config_ini_path)
bootloader_obj.sign(key_ini_path, key_cert_path, content_config_ini_path)
return 0
elif function == "keybin_pss":
key = cert.ct_key("pss")
key.create(key_path)
key_bin = key.pack()
out_file = open(function_out_path, "wb")
out_file.write(key_bin)
out_file.close()
return 0
elif function == "keybin_legacy":
key = cert.ct_key("legacy")
key.create(key_path)
key_bin = key.pack()
out_file = open(function_out_path, "wb")
out_file.write(key_bin)
out_file.close()
return 0
elif function == "keyhash_pss":
key = cert.ct_key("pss")
key.create(key_path)
key_bin = key.pack()
tmp_key_bin_path = os.path.join(out_path, "tmp_keybin.bin")
out_file = open(tmp_key_bin_path, "wb")
out_file.write(key_bin)
out_file.close()
cert.hash_gen(tmp_key_bin_path, function_out_path)
os.remove(tmp_key_bin_path)
return 0
elif function == "keyhash_legacy":
key = cert.ct_key("legacy")
key.create(key_path)
key_bin = key.pack()
tmp_key_bin_path = os.path.join(out_path, "tmp_keybin.bin")
out_file = open(tmp_key_bin_path, "wb")
out_file.write(key_bin)
out_file.close()
cert.hash_gen(tmp_key_bin_path, function_out_path)
os.remove(tmp_key_bin_path)
return 0
if __name__ == '__main__':
main()