efuse_bingen.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. import binascii
  2. import os.path
  3. import sys
  4. from xml.dom import minidom
  5. import argparse
  6. import re
  7. import base64
  8. import subprocess
  9. import os
  10. import hashlib
  11. import logging
  12. log_file_path = ""
  13. def convert_to_int_value(val, tag_name, attr_name=None) :
  14. if (val == "") or (val == 0) or (val == "0") :
  15. return 0
  16. if (val == 1) or (val == "1") :
  17. return 1
  18. if isinstance(val, basestring) : #check if "val" is string type (only string has lower() method)
  19. if val.lower() == "true" :
  20. return 1
  21. if val.lower() == "false" :
  22. return 0
  23. if attr_name : #has Atribute
  24. PrintError_RaiseException_StopBuild("Attribute Name: " + attr_name + " => I got value: \"" + str(val) + "\". The value should be: \"1\" or \"0\" or \"true\" or \"false\" or empty(=false)")
  25. else :
  26. PrintError_RaiseException_StopBuild("Tag Name: " + tag_name + " => I got value: \"" + str(val) + "\". The value should be: \"1\" or \"0\" or \"true\" or \"false\" or empty(=false)")
  27. def writeBitValueAndOneHexStringToFile(fstream, lstBitValue, hexString) :
  28. """
  29. Notice: The priority of bit input(lstBitValue) is higher than hex input(hexString) if hexString overlaps lstBitValue
  30. """
  31. result = 0;
  32. priority_mask = 0xFFFFFFFF
  33. for bit_number, value in lstBitValue :
  34. if value == 1 :
  35. result = result + (2 ** bit_number) #transform bit to decimal
  36. priority_mask = priority_mask & ~(2 ** bit_number)
  37. hexString2Decimal = int(hexString, 16) #transform hex to decimal
  38. result = (hexString2Decimal & priority_mask) | result #merge
  39. plain_hex_string = str(hex(result))[2:] #result is decimal, transform to hex
  40. plain_hex_string = plain_hex_string.zfill(8) #padding 0 at right to 8 digits
  41. lstHexArr = re.findall('..', plain_hex_string)
  42. fstream.write(chr(int(lstHexArr[3], 16)))
  43. fstream.write(chr(int(lstHexArr[2], 16)))
  44. fstream.write(chr(int(lstHexArr[1], 16)))
  45. fstream.write(chr(int(lstHexArr[0], 16)))
  46. def getBitValueAndOneHexString(lstBitValue, hexString) :
  47. """
  48. Notice: The priority of bit input(lstBitValue) is higher than hex input(hexString) if hexString overlaps lstBitValue
  49. This function is the same as function "writeBitValueAndOneHexStringToFile" except it return the merged value rather than writing to file
  50. """
  51. result = 0;
  52. priority_mask = 0xFFFFFFFF
  53. for bit_number, value in lstBitValue :
  54. if value == 1 :
  55. result = result + (2 ** bit_number) #transform bit to decimal
  56. priority_mask = priority_mask & ~(2 ** bit_number)
  57. hexString2Decimal = int(hexString, 16) #transform hex to decimal
  58. result = (hexString2Decimal & priority_mask) | result #merge
  59. plain_hex_string = str(hex(result))[2:] #result is decimal, transform to hex
  60. plain_hex_string = plain_hex_string.zfill(len(hexString)) #padding 0 at right to 8 digits
  61. return plain_hex_string.upper()
  62. def writeBitValueToFile(fstream, lstBitValue) :
  63. result = 0;
  64. for bit_number, value in lstBitValue :
  65. if value == 1 :
  66. result = result + (2 ** bit_number)
  67. plain_hex_string = str(hex(result))[2:] #result is decimal
  68. plain_hex_string = plain_hex_string.zfill(8)
  69. lstHexArr = re.findall('..', plain_hex_string)
  70. fstream.write(chr(int(lstHexArr[3], 16)))
  71. fstream.write(chr(int(lstHexArr[2], 16)))
  72. fstream.write(chr(int(lstHexArr[1], 16)))
  73. fstream.write(chr(int(lstHexArr[0], 16)))
  74. def get_file_sha256hexdigest(file_name):
  75. hash_result = ""
  76. with open(file_name) as f:
  77. m = hashlib.sha256()
  78. m.update(f.read())
  79. hash_result = m.hexdigest()
  80. return hash_result.upper()
  81. def writeHexStringToFile(fstream, hexString) :
  82. plain_hex_string = hexString.ljust(8, '0') #padding 0 at right to 8 digits
  83. lstHexArr = re.findall('..', plain_hex_string)
  84. fstream.write(chr(int(lstHexArr[0], 16)))
  85. fstream.write(chr(int(lstHexArr[1], 16)))
  86. fstream.write(chr(int(lstHexArr[2], 16)))
  87. fstream.write(chr(int(lstHexArr[3], 16)))
  88. def parseXmlTagAndAttribute(xml_file, tag_name, attr_name, inputValueLengthLimit=1, inputIsStringType=False) :
  89. if inputIsStringType :
  90. retVal = '0' * inputValueLengthLimit
  91. else :
  92. retVal = 0
  93. try:
  94. if not xml_file.getElementsByTagName(tag_name) :
  95. raise KeyError
  96. tag_number = len(xml_file.getElementsByTagName(tag_name))
  97. if tag_number > 1 :
  98. raise ValueError("Duplicated tag name. It appears " + str(tag_number) + " times!!")
  99. tmp_parse_value = xml_file.getElementsByTagName(tag_name)[0].attributes[attr_name].value
  100. if inputIsStringType :
  101. if (tmp_parse_value == "") :
  102. return retVal
  103. if (inputValueLengthLimit <> len(tmp_parse_value)) :
  104. raise ValueError("Wrong value length. The length of value should be: " + str(inputValueLengthLimit))
  105. if isinstance(tmp_parse_value, basestring) : #check if "tmp_parse_value" is string type (only string has upper() method)
  106. if not isValidHexString(tmp_parse_value) : #only string can be processed by regex
  107. raise ValueError("Wrong hex value type! The value should be within [0-9|A-F]")
  108. return tmp_parse_value.upper()
  109. return tmp_parse_value
  110. else : #not string
  111. return convert_to_int_value(tmp_parse_value, tag_name, attr_name)
  112. except IndexError:
  113. #Tag or Attribute not exist
  114. #printAndLog("[Warning][Not Exist] Tag Name: " + tag_name + ", Attribute Name: " + attr_name + " => Set to default value: " + str(retVal))
  115. return retVal
  116. except KeyError:
  117. #Tag or Attribute not exist
  118. #printAndLog("[Warning][Not Exist] Tag Name: " + tag_name + ", Attribute Name: " + attr_name + " => Set to default value: " + str(retVal))
  119. return retVal
  120. except ValueError as err:
  121. PrintError_RaiseException_StopBuild("Tag Name: " + tag_name + ", Attribute Name: " + attr_name + " (" + str(err) + ")")
  122. def parseXmlTagInnerValue(xml_file, tag_name, inputValueLengthLimit=1, inputIsStringType=False) :
  123. if inputIsStringType :
  124. retVal = '0' * inputValueLengthLimit
  125. else :
  126. retVal = 0
  127. try:
  128. if not xml_file.getElementsByTagName(tag_name) :
  129. raise KeyError
  130. tag_number = len(xml_file.getElementsByTagName(tag_name))
  131. if tag_number > 1 :
  132. raise ValueError("Duplicated tag name. It appears " + str(tag_number) + " times!!")
  133. tmp_parse_value = xml_file.getElementsByTagName(tag_name)[0].childNodes[0].data
  134. if inputIsStringType :
  135. if (tmp_parse_value == "") :
  136. return retVal
  137. if (inputValueLengthLimit <> len(tmp_parse_value)) :
  138. raise ValueError("Wrong value length. The length of value should be: " + str(inputValueLengthLimit))
  139. if isinstance(tmp_parse_value, basestring) : #check if "tmp_parse_value" is string type (only string has upper() method)
  140. if not isValidHexString(tmp_parse_value) : #only string can be processed by regex
  141. raise ValueError("Wrong hex value type! The value should be within [0-9|A-F]")
  142. return tmp_parse_value.upper()
  143. return tmp_parse_value
  144. else : #not string
  145. return convert_to_int_value(tmp_parse_value, tag_name)
  146. except IndexError:
  147. #Tag or Attribute not exist
  148. #printAndLog("[Warning][Not Exist] Tag Name: " + tag_name + " => Set to default value: " + str(retVal))
  149. return retVal
  150. except KeyError:
  151. #Tag or Attribute not exist
  152. #printAndLog("[Warning][Not Exist] Tag Name: " + tag_name + " => Set to default value: " + str(retVal))
  153. return retVal
  154. except ValueError as err:
  155. PrintError_RaiseException_StopBuild("Tag Name: " + tag_name + " (" + str(err) + ")")
  156. def isValidHexString(hex_input) :
  157. if re.match(r"^[0-9A-F]*$", hex_input, re.IGNORECASE) :
  158. return True
  159. return False
  160. def printAndLog(msg, criticalLevel=False):
  161. print(msg)
  162. global log_file_path
  163. if (log_file_path) :
  164. logging.basicConfig(format='[%(asctime)s] %(message)s', filename=log_file_path, level=logging.DEBUG)
  165. if criticalLevel :
  166. logging.critical(msg)
  167. else :
  168. logging.info(msg)
  169. def PrintError_RaiseException_StopBuild(err) :
  170. printAndLog("[Error] " + err, criticalLevel=True)
  171. raise Exception("[Error] " + err)
  172. def main():
  173. parser = argparse.ArgumentParser(description='MediaTek EFUSE XML Parser')
  174. parser.add_argument('--file', '-f',
  175. required=True,
  176. help='Provide the xml file')
  177. parser.add_argument('--output_bin_name', '-o',
  178. required=False,
  179. default='xml_output.bin',
  180. help='Provide output file name')
  181. parser.add_argument('--key_hash', '-k',
  182. required=False,
  183. help='Provide the file name path of key hash')
  184. parser.add_argument('--log_output_file', '-l',
  185. required=False,
  186. help='Provide the log output file name')
  187. args = parser.parse_args()
  188. if (args.log_output_file) :
  189. if os.path.isfile(args.log_output_file) :
  190. try :
  191. os.remove(args.log_output_file)
  192. except :
  193. pass
  194. global log_file_path
  195. log_file_path = args.log_output_file
  196. printAndLog("***************************************************************************")
  197. printAndLog("**************** MediaTek EFUSE XML Parser ([MTK_XML2BIN]) ****************")
  198. printAndLog("****************************** version 1.3.6.2 ****************************")
  199. printAndLog("***************************************************************************")
  200. printAndLog("Loading XML file: " + os.path.abspath(args.file))
  201. if os.path.isfile(args.output_bin_name) :
  202. os.remove(args.output_bin_name)
  203. printAndLog("Remove old image file: " + os.path.abspath(args.output_bin_name))
  204. printAndLog("-----------------------------------------------")
  205. if not os.path.isfile(args.file) :
  206. PrintError_RaiseException_StopBuild("XML file not exist!!")
  207. try :
  208. xml_file = minidom.parse(args.file)
  209. except Exception:
  210. printAndLog("[Error] ***** XML format is NOT CORRECT. Please check your XML input file. *****")
  211. printAndLog("[Error] ***** XML format is NOT CORRECT. Please check your XML input file. *****")
  212. PrintError_RaiseException_StopBuild("***** XML format is NOT CORRECT. Please check your XML input file. *****")
  213. #Parsing XML to variable
  214. printAndLog("Parsing XML file ...")
  215. #Parse String value
  216. EFUSE_KEY1 = parseXmlTagAndAttribute(xml_file, "magic-key", "key1", 8, True)
  217. EFUSE_KEY2 = parseXmlTagAndAttribute(xml_file, "magic-key", "key2", 8, True)
  218. EFUSE_ac_key = parseXmlTagInnerValue(xml_file, "ac-key", 32, True)
  219. EFUSE_usb_vid = parseXmlTagAndAttribute(xml_file, "usb-id", "vid", 4, True)
  220. EFUSE_usb_pid = parseXmlTagAndAttribute(xml_file, "usb-id", "pid", 4, True)
  221. #Parse Integer value
  222. EFUSE_Disable_NAND_boot_speedup = parseXmlTagAndAttribute(xml_file, "common-ctrl", "Disable_NAND_boot_speedup")
  223. EFUSE_USB_download_type = parseXmlTagAndAttribute(xml_file, "common-ctrl", "USB_download_type")
  224. EFUSE_Disable_NAND_boot = parseXmlTagAndAttribute(xml_file, "common-ctrl", "Disable_NAND_boot")
  225. EFUSE_Disable_EMMC_boot = parseXmlTagAndAttribute(xml_file, "common-ctrl", "Disable_EMMC_boot")
  226. EFUSE_Enable_SW_JTAG_CON = parseXmlTagAndAttribute(xml_file, "secure-ctrl", "Enable_SW_JTAG_CON")
  227. EFUSE_Enable_Root_Cert = parseXmlTagAndAttribute(xml_file, "secure-ctrl", "Enable_Root_Cert")
  228. EFUSE_Enable_ACC = parseXmlTagAndAttribute(xml_file, "secure-ctrl", "Enable_ACC")
  229. EFUSE_Enable_ACK = parseXmlTagAndAttribute(xml_file, "secure-ctrl", "Enable_ACK")
  230. EFUSE_Enable_SLA = parseXmlTagAndAttribute(xml_file, "secure-ctrl", "Enable_SLA")
  231. EFUSE_Enable_DAA = parseXmlTagAndAttribute(xml_file, "secure-ctrl", "Enable_DAA")
  232. EFUSE_Enable_SBC = parseXmlTagAndAttribute(xml_file, "secure-ctrl", "Enable_SBC")
  233. EFUSE_Disable_JTAG = parseXmlTagAndAttribute(xml_file, "secure-ctrl", "Disable_JTAG")
  234. EFUSE_Disable_DBGPORT_LOCK = parseXmlTagAndAttribute(xml_file, "secure-ctrl", "Disable_DBGPORT_LOCK")
  235. EFUSE_C_SEC_CTRL = parseXmlTagAndAttribute(xml_file, "cust-secure-ctrl", "c_sec_ctrl", 2, True)
  236. EFUSE_C_CTRL = parseXmlTagAndAttribute(xml_file, "cust-common-ctrl", "c_ctrl", 2, True)
  237. EFUSE_DISABLE_EFUSE = parseXmlTagAndAttribute(xml_file, "cust-common-ctrl", "DISABLE_EFUSE_BLOW")
  238. EFUSE_com_ctrl_lock = parseXmlTagAndAttribute(xml_file, "common-lock", "com_ctrl_lock")
  239. EFUSE_usb_id_lock = parseXmlTagAndAttribute(xml_file, "common-lock", "usb_id_lock")
  240. EFUSE_sec_attr_lock = parseXmlTagAndAttribute(xml_file, "secure-lock", "sec_attr_lock")
  241. EFUSE_ackey_lock = parseXmlTagAndAttribute(xml_file, "secure-lock", "ackey_lock")
  242. EFUSE_sbc_pubk_hash_lock = parseXmlTagAndAttribute(xml_file, "secure-lock", "sbc_pubk_hash_lock")
  243. if (int(EFUSE_C_CTRL, 16) & 0x80) != 0 : #bit[7] is not masked
  244. PrintError_RaiseException_StopBuild("C_CTRL should only have bit[6:0]. The bit[7] should not be set.")
  245. printAndLog("Parsing XML file ... Done")
  246. #Pre-process value
  247. printAndLog("-----------------------------------------------")
  248. #[Important] Please make sure the value of "print" is the same as xml value
  249. printAndLog("EFUSE_ac_key = " + str(EFUSE_ac_key))
  250. printAndLog("EFUSE_usb_vid = " + str(EFUSE_usb_vid))
  251. printAndLog("EFUSE_usb_pid = " + str(EFUSE_usb_pid))
  252. printAndLog("EFUSE_Disable_NAND_boot_speedup = " + str(EFUSE_Disable_NAND_boot_speedup))
  253. printAndLog("EFUSE_USB_download_type = " + str(EFUSE_USB_download_type))
  254. printAndLog("EFUSE_Disable_NAND_boot = " + str(EFUSE_Disable_NAND_boot))
  255. printAndLog("EFUSE_Disable_EMMC_boot = " + str(EFUSE_Disable_EMMC_boot))
  256. printAndLog("EFUSE_Enable_SW_JTAG_CON = " + str(EFUSE_Enable_SW_JTAG_CON))
  257. printAndLog("EFUSE_Enable_Root_Cert = " + str(EFUSE_Enable_Root_Cert))
  258. printAndLog("EFUSE_Enable_ACC = " + str(EFUSE_Enable_ACC))
  259. printAndLog("EFUSE_Enable_ACK = " + str(EFUSE_Enable_ACK))
  260. printAndLog("EFUSE_Enable_SLA = " + str(EFUSE_Enable_SLA))
  261. printAndLog("EFUSE_Enable_DAA = " + str(EFUSE_Enable_DAA))
  262. printAndLog("EFUSE_Enable_SBC = " + str(EFUSE_Enable_SBC))
  263. printAndLog("EFUSE_Disable_JTAG = " + str(EFUSE_Disable_JTAG))
  264. printAndLog("EFUSE_Disable_DBGPORT_LOCK = " + str(EFUSE_Disable_DBGPORT_LOCK))
  265. printAndLog("EFUSE_C_SEC_CTRL = " + str(EFUSE_C_SEC_CTRL))
  266. printAndLog("EFUSE_DISABLE_EFUSE = " + str(EFUSE_DISABLE_EFUSE))
  267. printAndLog("EFUSE_C_CTRL = " + str(hex(int(EFUSE_C_CTRL, 16) & 0x7F))[2:].zfill(2).upper()) #Mask 0x7F
  268. printAndLog("EFUSE_com_ctrl_lock = " + str(EFUSE_com_ctrl_lock))
  269. printAndLog("EFUSE_usb_id_lock = " + str(EFUSE_usb_id_lock))
  270. printAndLog("EFUSE_sec_attr_lock = " + str(EFUSE_sec_attr_lock))
  271. printAndLog("EFUSE_ackey_lock = " + str(EFUSE_ackey_lock))
  272. printAndLog("EFUSE_sbc_pubk_hash_lock = " + str(EFUSE_sbc_pubk_hash_lock))
  273. printAndLog("-----------------------------------------------")
  274. EFUSE_SBC_PUBK_HASH = '0' * 64
  275. if args.key_hash :
  276. printAndLog("[Info] Loading SBC_PUBK_HASH from key hash file: " + os.path.abspath(args.key_hash))
  277. if os.path.isfile(args.key_hash) :
  278. try:
  279. with open(args.key_hash, 'r') as f:
  280. EFUSE_SBC_PUBK_HASH = f.read()
  281. except Exception:
  282. PrintError_RaiseException_StopBuild("***** Error while reading key hash file *****")
  283. EFUSE_SBC_PUBK_HASH = EFUSE_SBC_PUBK_HASH.strip()
  284. if EFUSE_SBC_PUBK_HASH == "" :
  285. PrintError_RaiseException_StopBuild("SBC_PUBK_HASH is empty and not generated")
  286. if len(EFUSE_SBC_PUBK_HASH) <> 64 :
  287. PrintError_RaiseException_StopBuild("SBC_PUBK_HASH is not in length 64. Current length of SBC_PUBK_HASH is: " + str(len(EFUSE_SBC_PUBK_HASH)))
  288. EFUSE_SBC_PUBK_HASH = EFUSE_SBC_PUBK_HASH.upper()
  289. if not isValidHexString(EFUSE_SBC_PUBK_HASH) :
  290. PrintError_RaiseException_StopBuild("SBC_PUBK_HASH contains invalid hex string(s)! The value should be within [0-9|A-F]")
  291. else :
  292. PrintError_RaiseException_StopBuild(args.key_hash + " is not generated from getKeyHash.sh for SBC_Key_Hash!!")
  293. else :
  294. printAndLog("[Info] SBC_PUBK_HASH is not loaded from key hash file.")
  295. EFUSE_SBC_PUBK_HASH = '0' * 64
  296. printAndLog("EFUSE_SBC_PUBK_HASH = " + EFUSE_SBC_PUBK_HASH)
  297. printAndLog("-----------------------------------------------")
  298. #usb-vid and usb-pid are special cases (The priority is important! PUT IT AFTER PRINT)
  299. EFUSE_usb_vid = EFUSE_usb_vid[2:4] + EFUSE_usb_vid[0:2]
  300. EFUSE_usb_pid = EFUSE_usb_pid[2:4] + EFUSE_usb_pid[0:2]
  301. with open(args.output_bin_name, "wb") as f :
  302. writeHexStringToFile(f, EFUSE_KEY1) #0x0
  303. writeHexStringToFile(f, EFUSE_KEY2) #0x4
  304. writeBitValueToFile(f, [(0, 0)]) #0x8
  305. writeHexStringToFile(f, EFUSE_ac_key[0:8]) #0xC
  306. writeHexStringToFile(f, EFUSE_ac_key[8:16]) #0x10
  307. writeHexStringToFile(f, EFUSE_ac_key[16:24]) #0x14
  308. writeHexStringToFile(f, EFUSE_ac_key[24:32]) #0x18
  309. writeHexStringToFile(f, EFUSE_SBC_PUBK_HASH[0:8]) #0x1C
  310. writeHexStringToFile(f, EFUSE_SBC_PUBK_HASH[8:16]) #0x20
  311. writeHexStringToFile(f, EFUSE_SBC_PUBK_HASH[16:24]) #0x24
  312. writeHexStringToFile(f, EFUSE_SBC_PUBK_HASH[24:32]) #0x28
  313. writeHexStringToFile(f, EFUSE_SBC_PUBK_HASH[32:40]) #0x2C
  314. writeHexStringToFile(f, EFUSE_SBC_PUBK_HASH[40:48]) #0x30
  315. writeHexStringToFile(f, EFUSE_SBC_PUBK_HASH[48:56]) #0x34
  316. writeHexStringToFile(f, EFUSE_SBC_PUBK_HASH[56:64]) #0x38
  317. writeHexStringToFile(f, EFUSE_usb_pid) #0x3C (only 4 digits, auto padding to 8 digits in writeHexStringToFile)
  318. writeHexStringToFile(f, EFUSE_usb_vid) #0x40 (only 4 digits, auto padding to 8 digits in writeHexStringToFile)
  319. writeBitValueToFile(f, [(0, EFUSE_Disable_EMMC_boot), (1, EFUSE_Disable_NAND_boot), (2, EFUSE_USB_download_type), (4, EFUSE_Disable_NAND_boot_speedup)]) #0x44
  320. writeBitValueToFile(f, [(0, EFUSE_Disable_JTAG), (1, EFUSE_Enable_SBC), (2, EFUSE_Enable_DAA), (3, EFUSE_Enable_SLA),(4, EFUSE_Enable_ACK), (5, EFUSE_Enable_ACC), (6, EFUSE_Enable_SW_JTAG_CON), (7, EFUSE_Enable_Root_Cert), (9, EFUSE_Disable_DBGPORT_LOCK)]) #0x48
  321. writeHexStringToFile(f, EFUSE_C_SEC_CTRL) #0x4C (only 2 digits, auto padding to 8 digits in writeHexStringToFile)
  322. if EFUSE_DISABLE_EFUSE == 1 :
  323. writeBitValueAndOneHexStringToFile(f, [(7, 1)], EFUSE_C_CTRL) #0x50
  324. else :
  325. writeBitValueAndOneHexStringToFile(f, [(7, 0)], EFUSE_C_CTRL) #0x50 #[IMPORTANT] You MUST still set bit 7 to value 0 as a mask because the priority of bit input(lstBitValue) is higher than hex input(hexString).
  326. writeBitValueToFile(f, [(0, EFUSE_sbc_pubk_hash_lock), (1, EFUSE_ackey_lock), (2, EFUSE_sec_attr_lock)]) #0x54
  327. writeBitValueToFile(f, [(1, EFUSE_usb_id_lock), (2, EFUSE_com_ctrl_lock)]) #0x58
  328. #extends to 512 bytes file siz
  329. for i in range(97) : #0x5C
  330. writeBitValueToFile(f, [(0, 0)])
  331. bin_file_size_before_hash = os.path.getsize(args.output_bin_name)
  332. printAndLog("")
  333. sha256_hash = get_file_sha256hexdigest(args.output_bin_name)
  334. printAndLog("Image file(" + str(bin_file_size_before_hash) + " bytes) sha256 hash: " + sha256_hash)
  335. with open(args.output_bin_name, "ab") as f :
  336. writeHexStringToFile(f, sha256_hash[0:8]) #0x1E0
  337. writeHexStringToFile(f, sha256_hash[8:16]) #0x1E4
  338. writeHexStringToFile(f, sha256_hash[16:24]) #0x1E8
  339. writeHexStringToFile(f, sha256_hash[24:32]) #0x1EC
  340. writeHexStringToFile(f, sha256_hash[32:40]) #0x1F0
  341. writeHexStringToFile(f, sha256_hash[40:48]) #0x1F4
  342. writeHexStringToFile(f, sha256_hash[48:56]) #0x1F8
  343. writeHexStringToFile(f, sha256_hash[56:64]) #0x1FC
  344. printAndLog("Append sha256 hash to bin: Done!")
  345. bin_file_size = os.path.getsize(args.output_bin_name)
  346. printAndLog("")
  347. printAndLog("[Success] Write to bin: " + os.path.abspath(args.output_bin_name) + " (size: " + str(bin_file_size) + " bytes)")
  348. printAndLog("")
  349. if __name__ == '__main__':
  350. main()