[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/dev_info/dtb-transfer-array.py b/meta/meta-mediatek/recipes-bsp/lk/files/dev_info/dtb-transfer-array.py
new file mode 100644
index 0000000..c6b3583
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/dev_info/dtb-transfer-array.py
@@ -0,0 +1,41 @@
+import os
+import sys
+
+def read_dtb(filename, raw_data):
+ fin = open(filename, 'rb')
+ fin.seek(0, 0)
+ while True:
+ t_byte = fin.read(1)
+ if len(t_byte) == 0:
+ break
+ else :
+ raw_data.append("0x%.2X" % ord(t_byte))
+
+def write_blob_head_file(filename, raw_data, length):
+ fout = open(filename, 'w+')
+ fout.write('#define CHECK_RSA 1 \n')
+ fout.write('#define CHECK_HASH 1 \n')
+ fout.write('const unsigned char blob[] __attribute__((aligned(4))) = \n')
+ fout.write('{\n ')
+
+ i = 0
+ for data in raw_data:
+ i += 1
+ if i != length:
+ fout.write(data + ', ')
+ else:
+ fout.write(data)
+ if i % 16 == 0:
+ fout.write('\n ')
+ if i == length:
+ break;
+ fout.write('\n};')
+ fout.close()
+
+if __name__ == "__main__":
+ raw_data = []
+ in_path = str(sys.argv[1]);
+ out_path = str(sys.argv[2]);
+ length = int(sys.argv[3],16);
+ read_dtb(in_path, raw_data)
+ write_blob_head_file(out_path, raw_data, length)
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/dummy_img/fitImage b/meta/meta-mediatek/recipes-bsp/lk/files/dummy_img/fitImage
new file mode 100644
index 0000000..036ed1b
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/dummy_img/fitImage
Binary files differ
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/fit-lk/extract_region b/meta/meta-mediatek/recipes-bsp/lk/files/fit-lk/extract_region
new file mode 100755
index 0000000..261ba30
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/fit-lk/extract_region
Binary files differ
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/key/lk_key.ini b/meta/meta-mediatek/recipes-bsp/lk/files/key/lk_key.ini
new file mode 100755
index 0000000..d6d089a
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/key/lk_key.ini
@@ -0,0 +1,4 @@
+[KEY]
+sw_ver = "1"
+rootkey = "root_prvk.pem"
+ac_key = "0x112233445566778899aabbccddeeff"
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/key/root_prvk.pem b/meta/meta-mediatek/recipes-bsp/lk/files/key/root_prvk.pem
new file mode 100644
index 0000000..fd987a3
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/key/root_prvk.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA0mlxI+3vrVlX8wH23CeTPDIH3c4DhEQNIGQltziYX7DOAHyf
+t/5s9TXAOmqIY0cyrQsjw837aiN3QGXONeQorP4+G5wlzWESJeJyAGlZ11hSijVp
+QQFwCT+++k4L8SEoMIgJUMNVd9pESqCYf08nhJXc/qgn++YiG8tMvHz9IA/Ef4OK
+XNj/+1+XyrtYRgYpfOwsoCgbe01NEpV3vM61fW0g3EtCQXW7MOD5VIWMkvTt+ob4
+qTF5/HpRlIJ5nth/8ZktkCx51Lu6yhQ1fw3KKPZ7A3ZmBtxSJ8I1xe1v/yWN+eD9
+Z9l7ZTkFVe8Avej6NnudkH1f6uTNmEETXOXHWwIDAQABAoIBAAdKjhgfo6GPKgQK
+umIwoOKCHVGrVOXdcdMAhWoO9QDD4K+Vofc/QslQfoPHs0g1bGUgsLGVTrQD3JsH
+rBij+mDcQoy0YX73cSiM60RmYi2bKukNJsOQ6C/53IVR9Qn7Cyh7Xk9FJY4Mqzcm
+z4IB3S2z/793VkNdWys5ZURW1HKq6R7s5Z937wlinPdJhwi7kI148NFnHFO793+z
+MGRC4n45CP13dHG3jktc46UYksP3sQ4CFcjFhKS6BPKDsyjmbCx1HUYjjcaLTy2d
+CJhYDlEvvkjU6CmQfe+cFpKYXnW5zZTwwx1uUDFiWOgSZupaieWZtyPCX7hqQ4ea
+Q6u7RxkCgYEA6+WjIwTB+D3PKP1x82RY2BMpWQRxHuVJs7T0H4zA+IicfJYc/+Sh
+0Esqzfj9ak/sEuNR1fIj4XCKODEVL3/n+qjBz8lbsNDjUrjG8jv3TiGkeaOeOyFR
+8jv0cvedzFk+1lQElFwSHrWAOfeoZRMHOoxK1MNkELjo2wFa67o6rxcCgYEA5FfR
+PJRyu2OmCVwqzycMbSOz6gB/5O5bnI9DxZf0oMNE1n5ElsZWynEFE5L33E+bvB/8
+AdC4cPPL1pg46KiDDkJ/BQhw+mC4wwvBHwjZFlKdQMYtgGb9ErFL4WPnllXy+ETD
+8U9Az1zOvj6thy3RYA7JGyZus4t9ecM5M+xItF0CgYBm+u7G4NLUzhbbrBjMyifG
+3EaWp8vCUxJjs0FHbKjpVqoJ8XZjd6n0Rnw/Qs1OVemXLUmSfoyPZBPTCApZnBrn
+YDiLvzmZ7PbwK94d7XO+1gz5VSZEZf1iJC5I6jQm+2blJfSB19fJNC7wH1+SEEZ9
+lrUsQMg0TKTKxsKsWbY4rQKBgEjP//aTV6qNcgqWC0iXKQ08T0iU9DNqFmhr/q5p
+cCY7Xh4PkYuKn25ab8X4HXVxJTXt9QwXJFlQRHWfgLYf1fqcFajjMjOE2CXJ/8EH
+r0HBAkf/ac8CCD0HsCylENoNejbUpq6yGPaGn55mmir630MEM/imXrJ+DnrfV8RI
+2j45AoGBAN/fhfcjGu5ix88+T9sEmV1lfoHyETQIZD4r5c9NufMXPcztE33XTqjI
+DpBfOCVQ8ZNuHuScQdQC55K8XT7wR9sQRhNvRua1K0IsfcL73ghCJin9i0yxMEzp
+s00NbHgvb2kfhxCC8eyoiCmpRk9A9xg2V22hx7Hkcwv+A62e9tN4
+-----END RSA PRIVATE KEY-----
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/lk_dts/lk.dts b/meta/meta-mediatek/recipes-bsp/lk/files/lk_dts/lk.dts
new file mode 100644
index 0000000..7b1b06f
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/lk_dts/lk.dts
@@ -0,0 +1,12 @@
+/dts-v1/;
+/ {
+ model = "Keys";
+ compatible = "mediatek,auto2701evb2-ivi";
+ signature {
+ key-dev {
+ required = "conf";
+ algo = "sha256,rsa2048";
+ key-name-hint = "dev";
+ };
+ };
+};
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/lk_dts/tmp_blob.txt b/meta/meta-mediatek/recipes-bsp/lk/files/lk_dts/tmp_blob.txt
new file mode 100644
index 0000000..23a0ee1
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/lk_dts/tmp_blob.txt
@@ -0,0 +1,7 @@
+#define CHECK_RSA 0
+#define CHECK_HASH 0
+
+const unsigned char blob[] __attribute__((aligned(4))) =
+{
+0
+};
\ No newline at end of file
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/hsm.py b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/hsm.py
new file mode 100755
index 0000000..afad840
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/hsm.py
@@ -0,0 +1,89 @@
+"""
+This module is used to delegate signature generation to HSM(Hardware Security Module)
+If public key is given for signing instead of private key, we'll know that
+we're trying to delegate signature to HSM. Then we look up key table created
+here to find HSM parameters. Here public key is used only as id for HSM
+parameters and won't act as a public key.
+"""
+import filecmp
+import os
+import lib.cert
+
+class HsmParam(object):
+ """
+ Parameter for HSM
+ """
+ def __init__(self):
+ # you can add parameter required by your HSM here
+ self.m_prvk = None
+
+def create_key_table():
+ """
+ create key table for public key to private key mapping
+ """
+ prvk_list = []
+ pubk_list = []
+ key_database_path = os.path.join(os.path.dirname(__file__), 'hsm_test_keys')
+ keys = os.listdir(key_database_path)
+ key_table = {}
+
+ for key in keys:
+ key_path = os.path.join(key_database_path, key)
+ if lib.cert.is_prvk(key_path):
+ prvk_list.append(key_path)
+ elif lib.cert.is_pubk(key_path):
+ pubk_list.append(key_path)
+
+ for pubk in pubk_list:
+ for prvk in prvk_list:
+ tmp_pubk = os.path.join(os.path.dirname(__file__), 'tmp_pubk.pem')
+ lib.cert.prvk_to_pubk(prvk, tmp_pubk)
+ if filecmp.cmp(pubk, tmp_pubk, False) is True:
+ key_table[pubk] = os.path.join(key_database_path, prvk)
+ os.remove(tmp_pubk)
+ break
+ os.remove(tmp_pubk)
+
+ return key_table
+
+def query_key_table(key_table, key):
+ """
+ get private key from public key.
+ In your implementation, you should convert input public
+ key to parameter passed to HSM, so HSM knows how to sign
+ message. Here as an example, we search public keys in a folder
+ as public key data base, and use corresponding private key
+ to sign message.
+ """
+ for pubk in key_table.keys():
+ if filecmp.cmp(key, pubk, False) is True:
+ return key_table[pubk]
+
+ return None
+
+
+def hsm_rsa_sign(data, key, padding, sig):
+ """
+ sign data with HSM
+ """
+ # note that key is pubk actually, use it as index for
+ # HSM parameters such as key selection
+ hsm_param_obj = HsmParam()
+ key_table = create_key_table()
+ hsm_param_obj.m_prvk = query_key_table(key_table, key)
+ if hsm_param_obj.m_prvk is None:
+ print 'not valid HSM parameter'
+ return -1
+
+ print "========================"
+ print "HSM parameter:"
+ print " m_prvk = " + hsm_param_obj.m_prvk
+ print "========================"
+
+ # place hsm request here -- start
+ # we re-direct it to signing with private key to mimic HSM
+ # data is not hashed here, you can hash data here to reduce
+ # network usage
+ lib.cert.sig_gen(data, hsm_param_obj.m_prvk, padding, sig)
+ # place hsm request here -- end
+ return 0
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/sctrlcert/root_prvk.pem b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/sctrlcert/root_prvk.pem
new file mode 100644
index 0000000..715ecca
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/sctrlcert/root_prvk.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA0WQDRmxTDvm7U8HoqWphpOMy4X3A9Vu0bSB6wwW66TVOqsLL
+MHezN0DSdQNrgi2yaCAN4X2j23JmsnaGuJcLhXNwUPCE+NV2kE50zWxTsx8LsM1g
+aGv2fGDaDsIPVj7qcVzr2/dtHFwQ6YKrKVXYM95VPJza/X6iOIwCgjz+fdmsg/oq
+jrBoWr2rVqkt8aeAXorAvRDA89yxdwqea7w0GMX4Ski3yyMWssj2SXLzkbEWpYyT
+lanOnnQ1aaNnCG13cdOf7I67uj3StRl4Wnap9YnTbWN6+IRUP9ZbrHW+gjwMUKoW
+1YGHuXIjYlxUxmtaXk266re+iaTjQKLiQbCbLwIDAQABAoIBAAmXZTcCm0NiWRxb
+E4c/Ij3lUl1V31Ld4oPlKvpn9snb8UCNL7WGpiTvyTQm9fO+mB+A6GHd2XWh5eZi
+24T1FkgEo65xdgXX8Vhm357RSXw4/dYZckMWPvIvlY17gixXMXID6aHn0Y2tAfFQ
+VPrNvduSYaEnJjjaZh/k+fBxTs8A5lQcxDWvsf11on00sXrUAOlHS6hQ2vziZnmc
+r/MqBY/3Hkwtqsr4unCenKTch1hKf/6KqaChYO0GnDlwt9rjmH3tcb0LyCQ1aYe9
+dDY9RmgscZE8PtvbKpEfcB8jruP43ZgYC1oTj9WtdHQ2gtLS0bs9knhnECSPMW3Y
+ORF46oECgYEA8qz+H+tuqxCKAA1p6EXmegpEcqhkwapviqgMZMQAejfW//bf8LYd
+9CsyTtWER1uxJ+PjvhW/K0NYXn+tbWzrsW1UK/AaYwvaB9+JsjU07aZh9kmADZJi
+3KkPsKp4Unqlno59XkLm3XE9REoHursnIkiuzHZnqh/+50ck+GJGQQ8CgYEA3OMr
+xNfLkuTs5NyBDBCYSOf0s2wfLgpfu4eaUYuYMGoAAL4trvrLtW5tcW63ObMy51V5
+EJJAH3vk/EK9EgevMYGwbiVB7pkb11tcnLoxelorTAbpDCzSorbW71mruX11496w
+GBJw4yQcIUxET5GxU14qTEK4wLQQ7AZQIKVtw+ECgYEAv/YJuzQfwZ9+mhYCPaL1
+cnomtM/xi6SHQRY3X4oPmp4LK0Sc1ispPJji3atWTKACXbyNzTIkm1NVVsMGa7Wq
+JxqFZ5AxP0IDwRCZOmeOK6LegNSZP6MZItV0vNnL/epYkjjCgMrJFkfaH+ezf4lF
+pn/6DXBoBhHzL/1+CCCs1A8CgYBPk1+fSIbEYsidInszF39lNHtJcDhDY+VdL9r+
+aaXoOyfJHLpkgWGF+URgSxyjItXB1V8KA0YqkX3LC1gF+NK6qRggdjesd2g6S2Wv
+6LwOchGLECpBApzXlbsU+18MMhCYiQ8zfOFCUy33KPyrFbemaxQd6SOZ+MTn4tZX
+DIHgwQKBgFLvSmrc8eLKRDDDxdvZYiu8JMm/DS4TdbK3P2u67hhxd3Y4whdQboF5
+zHbkkTBIuKoFbbQj3bB91KmCIcxNkT66Xe3qmoAfDrUMp7cxBLcnpoDpJIXTlKnG
+bHThVsqvJvuwQByr2oUGUJd8eerqzUCAgx/mi+/9aTe+ztB/KmBF
+-----END RSA PRIVATE KEY-----
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/toolauth/da_prvk.pem b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/toolauth/da_prvk.pem
new file mode 100644
index 0000000..715ecca
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/toolauth/da_prvk.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA0WQDRmxTDvm7U8HoqWphpOMy4X3A9Vu0bSB6wwW66TVOqsLL
+MHezN0DSdQNrgi2yaCAN4X2j23JmsnaGuJcLhXNwUPCE+NV2kE50zWxTsx8LsM1g
+aGv2fGDaDsIPVj7qcVzr2/dtHFwQ6YKrKVXYM95VPJza/X6iOIwCgjz+fdmsg/oq
+jrBoWr2rVqkt8aeAXorAvRDA89yxdwqea7w0GMX4Ski3yyMWssj2SXLzkbEWpYyT
+lanOnnQ1aaNnCG13cdOf7I67uj3StRl4Wnap9YnTbWN6+IRUP9ZbrHW+gjwMUKoW
+1YGHuXIjYlxUxmtaXk266re+iaTjQKLiQbCbLwIDAQABAoIBAAmXZTcCm0NiWRxb
+E4c/Ij3lUl1V31Ld4oPlKvpn9snb8UCNL7WGpiTvyTQm9fO+mB+A6GHd2XWh5eZi
+24T1FkgEo65xdgXX8Vhm357RSXw4/dYZckMWPvIvlY17gixXMXID6aHn0Y2tAfFQ
+VPrNvduSYaEnJjjaZh/k+fBxTs8A5lQcxDWvsf11on00sXrUAOlHS6hQ2vziZnmc
+r/MqBY/3Hkwtqsr4unCenKTch1hKf/6KqaChYO0GnDlwt9rjmH3tcb0LyCQ1aYe9
+dDY9RmgscZE8PtvbKpEfcB8jruP43ZgYC1oTj9WtdHQ2gtLS0bs9knhnECSPMW3Y
+ORF46oECgYEA8qz+H+tuqxCKAA1p6EXmegpEcqhkwapviqgMZMQAejfW//bf8LYd
+9CsyTtWER1uxJ+PjvhW/K0NYXn+tbWzrsW1UK/AaYwvaB9+JsjU07aZh9kmADZJi
+3KkPsKp4Unqlno59XkLm3XE9REoHursnIkiuzHZnqh/+50ck+GJGQQ8CgYEA3OMr
+xNfLkuTs5NyBDBCYSOf0s2wfLgpfu4eaUYuYMGoAAL4trvrLtW5tcW63ObMy51V5
+EJJAH3vk/EK9EgevMYGwbiVB7pkb11tcnLoxelorTAbpDCzSorbW71mruX11496w
+GBJw4yQcIUxET5GxU14qTEK4wLQQ7AZQIKVtw+ECgYEAv/YJuzQfwZ9+mhYCPaL1
+cnomtM/xi6SHQRY3X4oPmp4LK0Sc1ispPJji3atWTKACXbyNzTIkm1NVVsMGa7Wq
+JxqFZ5AxP0IDwRCZOmeOK6LegNSZP6MZItV0vNnL/epYkjjCgMrJFkfaH+ezf4lF
+pn/6DXBoBhHzL/1+CCCs1A8CgYBPk1+fSIbEYsidInszF39lNHtJcDhDY+VdL9r+
+aaXoOyfJHLpkgWGF+URgSxyjItXB1V8KA0YqkX3LC1gF+NK6qRggdjesd2g6S2Wv
+6LwOchGLECpBApzXlbsU+18MMhCYiQ8zfOFCUy33KPyrFbemaxQd6SOZ+MTn4tZX
+DIHgwQKBgFLvSmrc8eLKRDDDxdvZYiu8JMm/DS4TdbK3P2u67hhxd3Y4whdQboF5
+zHbkkTBIuKoFbbQj3bB91KmCIcxNkT66Xe3qmoAfDrUMp7cxBLcnpoDpJIXTlKnG
+bHThVsqvJvuwQByr2oUGUJd8eerqzUCAgx/mi+/9aTe+ztB/KmBF
+-----END RSA PRIVATE KEY-----
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/toolauth/root_prvk.pem b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/toolauth/root_prvk.pem
new file mode 100644
index 0000000..715ecca
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/toolauth/root_prvk.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA0WQDRmxTDvm7U8HoqWphpOMy4X3A9Vu0bSB6wwW66TVOqsLL
+MHezN0DSdQNrgi2yaCAN4X2j23JmsnaGuJcLhXNwUPCE+NV2kE50zWxTsx8LsM1g
+aGv2fGDaDsIPVj7qcVzr2/dtHFwQ6YKrKVXYM95VPJza/X6iOIwCgjz+fdmsg/oq
+jrBoWr2rVqkt8aeAXorAvRDA89yxdwqea7w0GMX4Ski3yyMWssj2SXLzkbEWpYyT
+lanOnnQ1aaNnCG13cdOf7I67uj3StRl4Wnap9YnTbWN6+IRUP9ZbrHW+gjwMUKoW
+1YGHuXIjYlxUxmtaXk266re+iaTjQKLiQbCbLwIDAQABAoIBAAmXZTcCm0NiWRxb
+E4c/Ij3lUl1V31Ld4oPlKvpn9snb8UCNL7WGpiTvyTQm9fO+mB+A6GHd2XWh5eZi
+24T1FkgEo65xdgXX8Vhm357RSXw4/dYZckMWPvIvlY17gixXMXID6aHn0Y2tAfFQ
+VPrNvduSYaEnJjjaZh/k+fBxTs8A5lQcxDWvsf11on00sXrUAOlHS6hQ2vziZnmc
+r/MqBY/3Hkwtqsr4unCenKTch1hKf/6KqaChYO0GnDlwt9rjmH3tcb0LyCQ1aYe9
+dDY9RmgscZE8PtvbKpEfcB8jruP43ZgYC1oTj9WtdHQ2gtLS0bs9knhnECSPMW3Y
+ORF46oECgYEA8qz+H+tuqxCKAA1p6EXmegpEcqhkwapviqgMZMQAejfW//bf8LYd
+9CsyTtWER1uxJ+PjvhW/K0NYXn+tbWzrsW1UK/AaYwvaB9+JsjU07aZh9kmADZJi
+3KkPsKp4Unqlno59XkLm3XE9REoHursnIkiuzHZnqh/+50ck+GJGQQ8CgYEA3OMr
+xNfLkuTs5NyBDBCYSOf0s2wfLgpfu4eaUYuYMGoAAL4trvrLtW5tcW63ObMy51V5
+EJJAH3vk/EK9EgevMYGwbiVB7pkb11tcnLoxelorTAbpDCzSorbW71mruX11496w
+GBJw4yQcIUxET5GxU14qTEK4wLQQ7AZQIKVtw+ECgYEAv/YJuzQfwZ9+mhYCPaL1
+cnomtM/xi6SHQRY3X4oPmp4LK0Sc1ispPJji3atWTKACXbyNzTIkm1NVVsMGa7Wq
+JxqFZ5AxP0IDwRCZOmeOK6LegNSZP6MZItV0vNnL/epYkjjCgMrJFkfaH+ezf4lF
+pn/6DXBoBhHzL/1+CCCs1A8CgYBPk1+fSIbEYsidInszF39lNHtJcDhDY+VdL9r+
+aaXoOyfJHLpkgWGF+URgSxyjItXB1V8KA0YqkX3LC1gF+NK6qRggdjesd2g6S2Wv
+6LwOchGLECpBApzXlbsU+18MMhCYiQ8zfOFCUy33KPyrFbemaxQd6SOZ+MTn4tZX
+DIHgwQKBgFLvSmrc8eLKRDDDxdvZYiu8JMm/DS4TdbK3P2u67hhxd3Y4whdQboF5
+zHbkkTBIuKoFbbQj3bB91KmCIcxNkT66Xe3qmoAfDrUMp7cxBLcnpoDpJIXTlKnG
+bHThVsqvJvuwQByr2oUGUJd8eerqzUCAgx/mi+/9aTe+ztB/KmBF
+-----END RSA PRIVATE KEY-----
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/toolauth/sla_prvk.pem b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/toolauth/sla_prvk.pem
new file mode 100644
index 0000000..715ecca
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/keys/toolauth/sla_prvk.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA0WQDRmxTDvm7U8HoqWphpOMy4X3A9Vu0bSB6wwW66TVOqsLL
+MHezN0DSdQNrgi2yaCAN4X2j23JmsnaGuJcLhXNwUPCE+NV2kE50zWxTsx8LsM1g
+aGv2fGDaDsIPVj7qcVzr2/dtHFwQ6YKrKVXYM95VPJza/X6iOIwCgjz+fdmsg/oq
+jrBoWr2rVqkt8aeAXorAvRDA89yxdwqea7w0GMX4Ski3yyMWssj2SXLzkbEWpYyT
+lanOnnQ1aaNnCG13cdOf7I67uj3StRl4Wnap9YnTbWN6+IRUP9ZbrHW+gjwMUKoW
+1YGHuXIjYlxUxmtaXk266re+iaTjQKLiQbCbLwIDAQABAoIBAAmXZTcCm0NiWRxb
+E4c/Ij3lUl1V31Ld4oPlKvpn9snb8UCNL7WGpiTvyTQm9fO+mB+A6GHd2XWh5eZi
+24T1FkgEo65xdgXX8Vhm357RSXw4/dYZckMWPvIvlY17gixXMXID6aHn0Y2tAfFQ
+VPrNvduSYaEnJjjaZh/k+fBxTs8A5lQcxDWvsf11on00sXrUAOlHS6hQ2vziZnmc
+r/MqBY/3Hkwtqsr4unCenKTch1hKf/6KqaChYO0GnDlwt9rjmH3tcb0LyCQ1aYe9
+dDY9RmgscZE8PtvbKpEfcB8jruP43ZgYC1oTj9WtdHQ2gtLS0bs9knhnECSPMW3Y
+ORF46oECgYEA8qz+H+tuqxCKAA1p6EXmegpEcqhkwapviqgMZMQAejfW//bf8LYd
+9CsyTtWER1uxJ+PjvhW/K0NYXn+tbWzrsW1UK/AaYwvaB9+JsjU07aZh9kmADZJi
+3KkPsKp4Unqlno59XkLm3XE9REoHursnIkiuzHZnqh/+50ck+GJGQQ8CgYEA3OMr
+xNfLkuTs5NyBDBCYSOf0s2wfLgpfu4eaUYuYMGoAAL4trvrLtW5tcW63ObMy51V5
+EJJAH3vk/EK9EgevMYGwbiVB7pkb11tcnLoxelorTAbpDCzSorbW71mruX11496w
+GBJw4yQcIUxET5GxU14qTEK4wLQQ7AZQIKVtw+ECgYEAv/YJuzQfwZ9+mhYCPaL1
+cnomtM/xi6SHQRY3X4oPmp4LK0Sc1ispPJji3atWTKACXbyNzTIkm1NVVsMGa7Wq
+JxqFZ5AxP0IDwRCZOmeOK6LegNSZP6MZItV0vNnL/epYkjjCgMrJFkfaH+ezf4lF
+pn/6DXBoBhHzL/1+CCCs1A8CgYBPk1+fSIbEYsidInszF39lNHtJcDhDY+VdL9r+
+aaXoOyfJHLpkgWGF+URgSxyjItXB1V8KA0YqkX3LC1gF+NK6qRggdjesd2g6S2Wv
+6LwOchGLECpBApzXlbsU+18MMhCYiQ8zfOFCUy33KPyrFbemaxQd6SOZ+MTn4tZX
+DIHgwQKBgFLvSmrc8eLKRDDDxdvZYiu8JMm/DS4TdbK3P2u67hhxd3Y4whdQboF5
+zHbkkTBIuKoFbbQj3bB91KmCIcxNkT66Xe3qmoAfDrUMp7cxBLcnpoDpJIXTlKnG
+bHThVsqvJvuwQByr2oUGUJd8eerqzUCAgx/mi+/9aTe+ztB/KmBF
+-----END RSA PRIVATE KEY-----
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/__init__.pyc b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/__init__.pyc
new file mode 100644
index 0000000..efe7800
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/__init__.pyc
Binary files differ
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/asn1_gen.pyc b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/asn1_gen.pyc
new file mode 100755
index 0000000..9a44921
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/asn1_gen.pyc
Binary files differ
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/cert.pyc b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/cert.pyc
new file mode 100644
index 0000000..d7941ef
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/cert.pyc
Binary files differ
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/dainfo.pyc b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/dainfo.pyc
new file mode 100644
index 0000000..292f62e
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/dainfo.pyc
Binary files differ
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/gfh.pyc b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/gfh.pyc
new file mode 100644
index 0000000..a653ad6
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/gfh.pyc
Binary files differ
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/hsm_hook.pyc b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/hsm_hook.pyc
new file mode 100644
index 0000000..93a084f
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/lib/hsm_hook.pyc
Binary files differ
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/pbp.py b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/pbp.py
new file mode 100755
index 0000000..6ca7326
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/pbp.py
@@ -0,0 +1,367 @@
+"""
+pbp is a tool that signs/re-signs bootloader and generate data for root public key authentication.
+"""
+import os
+import shutil
+import argparse
+from lib import gfh
+from lib import cert
+
+
+def get_file_sizeb(file_path):
+ """
+ Get size of binary file
+ """
+ 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):
+ """
+ Concatenate binary files
+ """
+ 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 Bl(object):
+ """
+ Bl, which stands for preloader in Mediatek solution.
+ Mediatek preloader is loaded/verified by BootROM and its format is determined by BootROM
+ and is different from other images due to several reasons.
+ It has basic format as follows:
+ =======================
+ GFH
+ =======================
+ Preloader_NO_GFH.bin
+ =======================
+ Sig
+ =======================
+ Where Preloader_NO_GFH.bin is converted from preloader.elf.
+ """
+ def __init__(self, out_path, in_bootloader_file_path, out_bootloader_file_path):
+ self.m_gfh = gfh.ImageGFH()
+ self.m_out_path = out_path
+ if not os.path.exists(self.m_out_path):
+ os.makedirs(self.m_out_path)
+ self.m_in_bl_file_path = in_bootloader_file_path
+ self.m_out_bl_file_path = out_bootloader_file_path
+ self.m_bl_is_signed = False
+ self.m_bl_content_offset = 0
+ # initialize content size to bl file size
+ self.m_bl_content_length = get_file_sizeb(self.m_in_bl_file_path)
+ self.m_bl_sig_size = 0
+ # generate file path for bl without gfh and signature
+ bl_path = os.path.splitext(in_bootloader_file_path)
+ self.m_bl_no_gfh_file_path = bl_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):
+ """
+ GFH and signature are added after bootloader image has been processed by pbp.
+ We use this fact to determine whether bootloader image is signed.
+ """
+ if self.m_in_bl_file_path:
+ bl_file = open(self.m_in_bl_file_path, "rb")
+ gfh_hdr_obj = gfh.GFHHeader()
+ gfh_hdr_size = gfh_hdr_obj.get_size()
+ gfh_hdr_buf = bl_file.read(gfh_hdr_size)
+ self.m_bl_is_signed = gfh_hdr_obj.is_gfh(gfh_hdr_buf)
+ bl_file.close()
+ return self.m_bl_is_signed
+
+ def parse(self):
+ """
+ If image is signed, we remove GFH and signature. Removed GFH is parsed and
+ stored. Stored GFH will be used later if GFH ini file is not given.
+ """
+ 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_bl_file_path)
+ self.m_bl_content_offset = gfh_total_size
+ self.m_bl_content_length -= gfh_total_size
+ self.m_bl_content_length -= self.m_gfh.get_sig_size()
+ self.m_bl_sig_size = self.m_gfh.get_sig_size()
+ in_file = open(self.m_in_bl_file_path, "rb")
+ out_file = open(self.m_bl_no_gfh_file_path, "wb")
+ in_file.seek(self.m_bl_content_offset)
+ out_file.write(in_file.read(self.m_bl_content_length))
+ out_file.close()
+ in_file.close()
+ else:
+ shutil.copyfile(self.m_in_bl_file_path, self.m_bl_no_gfh_file_path)
+ print "bootloader content size = " + hex(self.m_bl_content_length)
+
+ def create_gfh(self, gfh_config):
+ """
+ GFH creation. GFH may be created from parsed/stored GFH config or from GFH config file
+ provided by user.
+ """
+ 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):
+ """
+ Sign bootloader according to its signature type, which is stored in GFH.
+ """
+ self.m_gfh.finalize(self.m_bl_content_length, key_ini_path)
+ # create tbs_bootloader.bin
+ tbs_bl_file_path = os.path.join(self.m_out_path, "tbs_preloader.bin")
+ tbs_bl_file = open(tbs_bl_file_path, "wb")
+ tbs_bl_file.write(self.m_gfh.pack())
+ bl_no_gfh_file = open(self.m_bl_no_gfh_file_path, "rb")
+ tbs_bl_file.write(bl_no_gfh_file.read(self.m_bl_content_length))
+ bl_no_gfh_file.close()
+ tbs_bl_file.close()
+ print "===sign==="
+ if self.m_gfh.get_sig_type() == "CERT_CHAIN":
+ self.m_sig_handler = cert.CertChainV2()
+ # 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_file_name = os.path.basename(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_bl_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_bl_file_path):
+ os.remove(self.m_out_bl_file_path)
+ concatb(self.m_out_bl_file_path, tbs_bl_file_path)
+ concatb(self.m_out_bl_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.SigSingleAndPhash(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_bl_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_bl_file_path):
+ os.remove(self.m_out_bl_file_path)
+ concatb(self.m_out_bl_file_path, tbs_bl_file_path)
+ concatb(self.m_out_bl_file_path, sig_file_path)
+ else:
+ print "unknown signature type"
+ # clean up
+ os.remove(self.m_bl_no_gfh_file_path)
+ os.remove(tbs_bl_file_path)
+ os.remove(sig_file_path)
+ return
+
+class PbpArgs(object):
+ """
+ PbpArgs is used to pass parameter to pbp.
+ This structure is both used when user executes this python script directly or imports
+ this module and use exported method.
+ """
+ def __init__(self):
+ self.op = None
+ self.padding = None
+ self.key_ini_path = None
+ self.key_path = None
+ self.gfh_cfg_ini_path = None
+ self.cnt_cfg_ini_path = None
+ self.key_cert_path = None
+ self.input_bl_path = None
+ self.tmp_output_path = None
+ self.output_path = None
+ def reset(self):
+ self.__init__()
+ def dump(self):
+ """
+ dump parameters.
+ """
+ f = lambda arg: 'Not Set' if arg is None else arg
+ print "op = " + f(self.op)
+ print "padding = " + f(self.padding)
+ print "key_ini_path = " + f(self.key_ini_path)
+ print "key_path = " + f(self.key_path)
+ print "gfh_cfg_ini_path = " + f(self.gfh_cfg_ini_path)
+ print "cnt_cfg_ini_path = " + f(self.cnt_cfg_ini_path)
+ print "key_cert_path = " + f(self.key_cert_path)
+ print "input_bl_path = " + f(self.input_bl_path)
+ print "tmp_output_path = " + f(self.tmp_output_path)
+ print "output_path = " + f(self.output_path)
+
+def _op_sign(args):
+ """
+ Sign/re-sign operation
+ """
+ bl_obj = Bl(args.tmp_output_path, args.input_bl_path, args.output_path)
+ bl_obj.create_gfh(args.gfh_cfg_ini_path)
+ bl_obj.sign(args.key_ini_path, args.key_cert_path, args.cnt_cfg_ini_path)
+ return 0
+
+def _op_keybin(args):
+ """
+ Generate root key data structure for root public key authentication.
+ """
+ key = cert.CtKey(args.padding)
+ key.create(args.key_path)
+ key_bin = key.pack()
+ out_file = open(args.output_path, "wb")
+ out_file.write(key_bin)
+ out_file.close()
+ return 0
+
+def _op_keybin_pss(args):
+ """
+ Root key data structures are different for different padding. Here we handles pss padding.
+ """
+ args.padding = 'pss'
+ return _op_keybin(args)
+
+def _op_keybin_legacy(args):
+ """
+ Root key data structures are different for different padding. Here we handles legacy padding.
+ """
+ args.padding = 'legacy'
+ return _op_keybin(args)
+
+def _op_keyhash(args):
+ """
+ Generate hash of root key data structure, which is dependent on padding used.
+ """
+ key = cert.CtKey(args.padding)
+ key.create(args.key_path)
+ key_bin = key.pack()
+ tmp_key_bin_path = os.path.join(args.tmp_output_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, args.output_path)
+ os.remove(tmp_key_bin_path)
+ return 0
+
+def _op_keyhash_pss(args):
+ """
+ Root key data struture hash for pss padding.
+ """
+ args.padding = 'pss'
+ return _op_keyhash(args)
+
+def _op_keyhash_legacy(args):
+ """
+ Root key data struture hash for legacy padding.
+ """
+ args.padding = 'legacy'
+ return _op_keyhash(args)
+
+def pbp_op(args):
+ """
+ Handles and dispatches all operations supported by pbp.
+ """
+ supported_ops = {
+ 'sign': _op_sign,
+ 'keybin_pss': _op_keybin_pss,
+ 'keybin_legacy': _op_keybin_legacy,
+ 'keyhash_pss': _op_keyhash_pss,
+ 'keyhash_legacy': _op_keyhash_legacy
+ }
+
+ if args.output_path is None:
+ print "output path is not given!"
+ return -1
+
+ if args.op is None:
+ print "op is not given!"
+ return -1
+
+ if args.op == 'sign':
+ if not args.input_bl_path:
+ print "bootloader path is not given!"
+ return -1
+ if (args.key_ini_path is None) and (args.key_cert_path is None):
+ print "key path is not given!"
+ return -1
+ else:
+ if (args.key_ini_path is None) and (args.key_path is None):
+ print "key path is not given!"
+ return -1
+
+ args.tmp_output_path = os.path.dirname(os.path.abspath(args.output_path))
+ if not os.path.exists(args.tmp_output_path):
+ os.makedirs(args.tmp_output_path)
+
+ op_f = supported_ops.get(args.op)
+ return op_f(args)
+
+
+def main():
+ """
+ Main function for pbp, which is used when pbp.py is executed directly.
+ Note that we changed input bootloader parameter to -in_bl $BL_PATH.
+ Please remember to add -in_bl if you're migrating from previous version.
+ """
+ parser = argparse.ArgumentParser(description='pbp tool for preloader gfh \
+creation/replacement and signing/re-signing')
+ parser.add_argument('-i', dest='key_ini_path', help='key configuartion path')
+ parser.add_argument('-j', dest='key_path', help='key path (with pem format)')
+ parser.add_argument('-g', dest='gfh_cfg_ini_path', help='gfh(generaic file header) \
+configuration path')
+ parser.add_argument('-c', dest='cnt_cfg_ini_path', help='content certificate \
+configuration path')
+ parser.add_argument('-k', dest='key_cert_path', help='key certificate path')
+ parser.add_argument('-func', dest='op', help='operation to be performed', required=True)
+ parser.add_argument('-o', dest='output_path', help='output file path')
+ parser.add_argument('input_bl_path', nargs='?', help='input file path')
+
+ pbp_args = parser.parse_args()
+ return pbp_op(pbp_args)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/prebuilt/toolauth/MTK_AllInOne_DA.bin b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/prebuilt/toolauth/MTK_AllInOne_DA.bin
new file mode 100644
index 0000000..3f5aea7
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/prebuilt/toolauth/MTK_AllInOne_DA.bin
Binary files differ
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/sctrlcert.py b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/sctrlcert.py
new file mode 100755
index 0000000..e8cfff4
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/sctrlcert.py
@@ -0,0 +1,202 @@
+"""
+This module is for debug control certificate generation
+"""
+import os
+import sys
+from lib import gfh
+from lib import cert
+
+
+def get_file_sizeb(file_path):
+ """
+ get binary file size
+ """
+ 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):
+ """
+ concatenate two binary files
+ """
+ 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 SctrlCert(object):
+ """
+ class for debug control certificate
+ """
+ def __init__(self, out_path, sctrl_cert_path):
+ self.m_out_path = out_path
+ if not os.path.exists(self.m_out_path):
+ os.makedirs(self.m_out_path)
+ self.m_sctrl_cert_path = sctrl_cert_path
+ self.m_gfh = gfh.ImageGFH()
+ self.m_key_path = ""
+ self.m_out_path = out_path
+ self.m_sig_handler = None
+
+ def create_gfh(self, gfh_config):
+ """
+ create GFH(generic file header) for debug control certificate
+ """
+ self.m_gfh.load_ini(gfh_config)
+ self.m_gfh.dump()
+ return
+
+ def sign(self, key_ini_path, key_cert_path, primary_dbg_config_ini_path, primary_dbg_path,
+ secondary_config_file_path):
+ """
+ generate signature for debug control certificate
+ """
+ # tool auth contains only gfh and signature, no extra content
+ self.m_gfh.finalize(0, key_ini_path)
+ # create tbs_sctrl_cert.bin
+ tbs_sctrl_cert_file_path = os.path.join(self.m_out_path, "tbs_sctrl_cert.bin")
+ tbs_sctrl_cert_file = open(tbs_sctrl_cert_file_path, "wb")
+ tbs_sctrl_cert_file.write(self.m_gfh.pack())
+ tbs_sctrl_cert_file.close()
+ print "===sctrl_cert sign==="
+ if self.m_gfh.get_sig_type() == "CERT_CHAIN":
+ self.m_sig_handler = cert.CertChainV5()
+ # create key cert
+ if key_cert_path == "":
+ key_cert_path = os.path.join(self.m_out_path, "key_cert.bin")
+ if os.path.isfile(key_ini_path):
+ key_cert_file_name = os.path.basename(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 primary debug cert
+ if primary_dbg_path == "":
+ primary_dbg_path = "primary_dbg_cert.bin"
+ if os.path.isfile(primary_dbg_config_ini_path):
+ primary_dbg_cert_file_name = os.path.basename(os.path.abspath(primary_dbg_path))
+ self.m_sig_handler.create_primary_dbg_cert(primary_dbg_config_ini_path,
+ tbs_sctrl_cert_file_path,
+ self.m_out_path,
+ primary_dbg_cert_file_name)
+ else:
+ self.m_sig_handler.set_primary_dbg_cert(primary_dbg_path)
+ # create secondary debug cert
+ secondary_dbg_cert_file_name = "secondary_dbg_cert.bin"
+ secondary_dbg_cert_file_path = os.path.join(self.m_out_path,
+ secondary_dbg_cert_file_name)
+ self.m_sig_handler.create_secondary_dbg_cert(secondary_config_file_path,
+ self.m_out_path,
+ secondary_dbg_cert_file_name)
+ # create final cert chain
+ sig_name = "sctrl_cert.sig"
+ sig_file_path = os.path.join(self.m_out_path, sig_name)
+ self.m_sig_handler.output(self.m_out_path, sig_name)
+ # create final sctrl cert
+ if os.path.isfile(self.m_sctrl_cert_path):
+ os.remove(self.m_sctrl_cert_path)
+ concatb(self.m_sctrl_cert_path, tbs_sctrl_cert_file_path)
+ concatb(self.m_sctrl_cert_path, sig_file_path)
+ os.remove(secondary_dbg_cert_file_path)
+ elif self.m_gfh.get_sig_type() == "SINGLE":
+ self.m_sig_handler = cert.SigSingle(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_sctrl_cert_file_path)
+ self.m_sig_handler.sign()
+ sig_name = "sctrl_cert.sig"
+ sig_file_path = os.path.join(self.m_out_path, sig_name)
+ self.m_sig_handler.output(self.m_out_path, sig_name)
+ # create final toolauth file
+ if os.path.isfile(self.m_sctrl_cert_path):
+ os.remove(self.m_sctrl_cert_path)
+ concatb(self.m_sctrl_cert_path, tbs_sctrl_cert_file_path)
+ concatb(self.m_sctrl_cert_path, sig_file_path)
+ else:
+ print "unknown signature type"
+
+ # clean up
+ os.remove(tbs_sctrl_cert_file_path)
+ os.remove(sig_file_path)
+ return
+
+
+def main():
+ """
+ entry point if this module is executed from cmdline.
+ """
+ # parameter parsing
+ idx = 1
+ key_ini_path = ""
+ key_cert_path = ""
+ gfh_config_ini_path = ""
+ primary_dbg_path = ""
+ primary_dbg_config_ini_path = ""
+ secondary_dbg_config_ini_path = ""
+ sctrl_cert_path = ""
+
+ while idx < len(sys.argv):
+ if sys.argv[idx][0] == '-':
+ if sys.argv[idx][1] == 'i':
+ print "key: " + sys.argv[idx + 1]
+ key_ini_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] == 'p':
+ print "primary dbg cert: " + sys.argv[idx + 1]
+ primary_dbg_path = sys.argv[idx + 1]
+ idx += 2
+ elif sys.argv[idx][1] == 'q':
+ print "primary dbg cert config: " + sys.argv[idx + 1]
+ primary_dbg_config_ini_path = sys.argv[idx + 1]
+ idx += 2
+ elif sys.argv[idx][1] == 's':
+ print "secondary dbg cert config: " + sys.argv[idx + 1]
+ secondary_dbg_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
+ else:
+ print "unknown input"
+ idx += 2
+ else:
+ sctrl_cert_path = sys.argv[idx]
+ print "sctrl_cert_path: " + sctrl_cert_path
+ idx += 1
+
+ if not key_cert_path and not key_ini_path:
+ print "key path is not given!"
+ return -1
+ if not gfh_config_ini_path:
+ print "sctrl_cert_config_path is not given!"
+ return -1
+ if not sctrl_cert_path:
+ print "sctrl_cert is not given!"
+ return -1
+
+ out_path = os.path.dirname(os.path.abspath(sctrl_cert_path))
+
+ sctrl_cert_obj = SctrlCert(out_path, sctrl_cert_path)
+ sctrl_cert_obj.create_gfh(gfh_config_ini_path)
+ sctrl_cert_obj.sign(key_ini_path, key_cert_path, primary_dbg_config_ini_path, primary_dbg_path,
+ secondary_dbg_config_ini_path)
+
+ return 0
+
+
+if __name__ == '__main__':
+ main()
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/sctrlcert/scc_gfh_config.ini b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/sctrlcert/scc_gfh_config.ini
new file mode 100644
index 0000000..394d1bd
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/sctrlcert/scc_gfh_config.ini
@@ -0,0 +1,43 @@
+[CHIP]
+version = "mt8167"
+[GFH_FILE_INFO]
+version = "1"
+file_type = "4"
+start_addr = "0x00201000"
+flash_dev = "emmc"
+sig_type = "SINGLE"
+pad_type = "pss"
+max_size = "0x00040000"
+sig_ver = "1"
+attr = "0"
+[GFH_SCTRL_CERT]
+version = "1"
+cust_name = "MTK"
+me_id = "9398c055df4d402b8be0ac030d609210"
+sla_dis = "1"
+daa_dis = "1"
+sbc_dis = "1"
+jtag_enable = "1"
+secure_world_debug_enable = "1"
+
+[CHIP]
+version = "mt8518"
+[GFH_FILE_INFO]
+version = "1"
+file_type = "4"
+start_addr = "0x00201000"
+flash_dev = "nand"
+sig_type = "SINGLE"
+pad_type = "pss"
+max_size = "0x00040000"
+sig_ver = "1"
+attr = "0"
+[GFH_SCTRL_CERT]
+version = "1"
+cust_name = "MTK"
+me_id = "9398c055df4d402b8be0ac030d609210"
+sla_dis = "1"
+daa_dis = "1"
+sbc_dis = "1"
+jtag_enable = "1"
+secure_world_debug_enable = "1"
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/sctrlcert/scc_key.ini b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/sctrlcert/scc_key.ini
new file mode 100644
index 0000000..2aac06f
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/sctrlcert/scc_key.ini
@@ -0,0 +1,3 @@
+[KEY]
+sw_ver = "1"
+rootkey = "keys/sctrlcert/root_prvk.pem"
\ No newline at end of file
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth.py b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth.py
new file mode 100755
index 0000000..5319605
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth.py
@@ -0,0 +1,135 @@
+"""
+This module generates tool auth, which combines public certificate and other functions
+such as DA binding.
+"""
+import os
+import sys
+from lib import gfh
+from lib import cert
+
+
+def get_file_sizeb(file_path):
+ """
+ get binary file size
+ """
+ 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):
+ """
+ concatenate two binary files
+ """
+ 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 ToolAuth(object):
+ """
+ class for tool auth, which is a public key certificate for DAA/SLA.
+ """
+ def __init__(self, out_path, tool_auth_path):
+ self.m_out_path = out_path
+ if not os.path.exists(self.m_out_path):
+ os.makedirs(self.m_out_path)
+ self.m_tool_auth_path = tool_auth_path
+ self.m_gfh = gfh.ImageGFH()
+ self.m_sig_handler = None
+
+ def create_gfh(self, gfh_config):
+ """
+ create GFH(generic file header) for tool auth.
+ """
+ self.m_gfh.load_ini(gfh_config)
+ return
+
+ def sign(self, key_ini_path):
+ """
+ generate signature for tool auth.
+ """
+ # tool auth contains only gfh and signature, no extra content
+ self.m_gfh.finalize(0, key_ini_path)
+ # write tbs_tool_auth
+ tbs_toolauth_file_path = os.path.join(self.m_out_path,
+ "tbs_toolauth.bin")
+ tbs_tool_auth_file = open(tbs_toolauth_file_path, "wb")
+ tbs_tool_auth_file.write(self.m_gfh.pack())
+ tbs_tool_auth_file.close()
+ print "===tool_auth signing==="
+ if self.m_gfh.get_sig_type() == "SINGLE":
+ self.m_sig_handler = cert.SigSingle(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_toolauth_file_path)
+ self.m_sig_handler.sign()
+ sig_name = "toolauth.sig"
+ sig_file_path = os.path.join(self.m_out_path, sig_name)
+ self.m_sig_handler.output(self.m_out_path, sig_name)
+ # create final toolauth file
+ if os.path.isfile(self.m_tool_auth_path):
+ os.remove(self.m_tool_auth_path)
+ concatb(self.m_tool_auth_path, tbs_toolauth_file_path)
+ concatb(self.m_tool_auth_path, sig_file_path)
+ else:
+ print "unknown signature type"
+ # clean up
+ os.remove(tbs_toolauth_file_path)
+ os.remove(sig_file_path)
+ return
+
+
+def main():
+ """
+ entry point if this module is executed from cmdline.
+ """
+ # parameter parsing
+ idx = 1
+ key_ini_path = ""
+ gfh_config_ini_path = ""
+ while idx < len(sys.argv):
+ if sys.argv[idx][0] == '-':
+ if sys.argv[idx][1] == 'i':
+ print "key: " + sys.argv[idx + 1]
+ key_ini_path = sys.argv[idx + 1]
+ idx += 2
+ elif sys.argv[idx][1] == 'g':
+ print "gfh: " + sys.argv[idx + 1]
+ gfh_config_ini_path = sys.argv[idx + 1]
+ idx += 2
+ else:
+ print "unknown input"
+ idx += 2
+ else:
+ tool_auth_path = sys.argv[idx]
+ print "tool_auth_path: " + tool_auth_path
+ idx += 1
+
+ if not key_ini_path:
+ print "key path is not given!"
+ return -1
+ if not gfh_config_ini_path:
+ print "gfh config path is not given!"
+ return -1
+ if not tool_auth_path:
+ print "tool_auth path is not given!"
+ return -1
+
+ out_path = os.path.dirname(os.path.abspath(tool_auth_path))
+
+ tool_auth_obj = ToolAuth(out_path, tool_auth_path)
+ tool_auth_obj.create_gfh(gfh_config_ini_path)
+ tool_auth_obj.sign(key_ini_path)
+
+ return 0
+
+
+if __name__ == '__main__':
+ main()
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth/bbchips.ini b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth/bbchips.ini
new file mode 100644
index 0000000..9cba1be
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth/bbchips.ini
@@ -0,0 +1,25 @@
+[MT8521p]
+hw_code = 0x8521
+hw_sub_code = 0x0
+hw_ver = 0xca00
+sw_ver = 0x0
+load_region0_sigtype = epp
+load_region0_key = keys/resignda/epp_prvk.pem
+load_region1_sigtype = da
+load_region1_key = keys/resignda/da_prvk.pem
+load_region2_sigtype = da
+load_region2_key = keys/resignda/da_prvk.pem
+[MT8518]
+hw_code = 0x8518
+hw_sub_code = 0x8a00
+hw_ver = 0xcb00
+sw_ver = 0x0
+load_region0_sigtype = epp
+load_region0_sigpad = pss
+load_region0_key = keys/resignda/epp_prvk.pem
+load_region1_sigtype = da
+load_region1_sigpad = pss
+load_region1_key = keys/resignda/da_prvk.pem
+load_region2_sigtype = da
+load_region2_sigpad = pss
+load_region2_key = keys/resignda/da_prvk.pem
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth/toolauth_gfh_config.ini b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth/toolauth_gfh_config.ini
new file mode 100644
index 0000000..6948f1b
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth/toolauth_gfh_config.ini
@@ -0,0 +1,19 @@
+[CHIP]
+version = "mt8518"
+[GFH_FILE_INFO]
+version = "1"
+file_type = "5"
+start_addr = "0x00201000"
+flash_dev = "nand"
+sig_type = "SINGLE"
+pad_type = "pss"
+max_size = "0x00040000"
+[GFH_TOOL_AUTH]
+version = "1"
+cust_name = "MTK"
+attr = "0x0"
+sla_public_key = "keys/toolauth/sla_prvk.pem"
+sla_pad_type = "pss"
+daa_public_key = "keys/toolauth/da_prvk.pem"
+daa_pad_type = "pss"
+ar_version_v2 = "0"
diff --git a/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth/toolauth_key.ini b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth/toolauth_key.ini
new file mode 100644
index 0000000..e760e20
--- /dev/null
+++ b/meta/meta-mediatek/recipes-bsp/lk/files/pbp/toolauth/toolauth_key.ini
@@ -0,0 +1,3 @@
+[KEY]
+sw_ver = "1"
+rootkey = "keys/toolauth/root_prvk.pem"
\ No newline at end of file