Ledger Nano X - The secure hardware wallet
SHARE
TWEET

hg658v2_configtool.py

hg658c Dec 4th, 2017 (edited) 1,267 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #! /usr/bin/env python
  2.  
  3. # hg658c.wordpress.com
  4. # This is for the Huawei hg658v2
  5. """
  6. To decrypt encrypted values in the config, use
  7. echo -n "RvldRxOemFEAL+AInOj90g==" | base64 -d | openssl enc -d -aes-128-cbc
  8. -K B3C353837F0A5B90EDD013087DA2B607 -iv 3C46FCF50F4EC875DE0AD8DA9A6D02BF -nopad ; echo
  9. """
  10.  
  11. import sys
  12. import os
  13. from binascii import hexlify, unhexlify
  14. from Crypto.Cipher import AES
  15. from Crypto.Hash import MD5
  16. from Crypto.Util import number
  17. import zlib
  18.  
  19. #30003/100020
  20. RSA_D = (
  21.     "C07474EB69963FEDE42C6A3852A296E0"
  22.     "9C977669102975249359F88547FD10C6"
  23.     "149D78FA1BD5B6E4BE94656A96AAABA3"
  24.     "D31C5B00D117C82ED5921C83C1F8D65F"
  25.     "4DF41AD244009F24F5F01049D213F02A"
  26.     "E5DAF65DA8D7323EE63D29AFF61204D2"
  27.     "C032610F5E6A90617FC13665C8E3E0C9"
  28.     "3441B2A2C053A3DF7BD0636610CAC8C9")
  29.  
  30. #30003/40010
  31. RSA_N = (
  32.     "EAB4FB648F8CB95E4A29EC4A8265EC57"
  33.     "450836763D48977A76E7FC39398B0D9D"
  34.     "93E393D289DA5EA60FF6CBDFF324D213"
  35.     "2C47B1F9A064E232309ABCAEBF2C3944"
  36.     "C4A0D16638512EA9E74E71C0F8633B74"
  37.     "D914106250726A82B3E09191B119E1F0"
  38.     "7F7039E8DAD77D8E4453D040AF41684D"
  39.     "3F715BF97284A72565FD0B59575121E7")
  40.  
  41. RSA_E = "010001"        
  42.  
  43. SIG_TEMPLATE = ("0001ffffffffffffffffffffffffffff"
  44.                 "ffffffffffffffffffffffffffffffff"
  45.                 "ffffffffffffffffffffffffffffffff"
  46.                 "ffffffffffffffffffffffffffffffff"
  47.                 "ffffffffffffffffffffffffffffffff"
  48.                 "ffffffffffffffffffffffffff003020"
  49.                 "300c06082a864886f70d020505000410")
  50.  
  51. #30000/10040
  52. AES256CBC_KEY = "BDE00F6EE8FC04C8B427B1B6CAF24DAAE9304E3FD24B247BE07E2129F758A4BC"
  53. #30000/20040
  54. AES256CBC_IV  = "4E14D5457EC485B25A32212398D88371"
  55.  
  56. XML_VERSION_STRING = b'<?xml version="1.0" ?>'
  57.  
  58. def print_usage():
  59.     print("Usage : " + sys.argv[0] + " {encrypt | decrypt} input_file output_file")
  60.     sys.exit(1)
  61.  
  62. def load_config(config_file):
  63.     if os.path.isfile(config_file):
  64.         cf = open(config_file, "rb")
  65.         config = cf.read()
  66.         cf.close()
  67.     else:
  68.         print("Config file not found..exiting")
  69.         sys.exit(1)
  70.     return config
  71.  
  72. def save_to_file(dest_file, data):
  73.     wfile = open(dest_file,"wb")
  74.     wfile.write(data)
  75.     wfile.close()
  76.  
  77. def get_md5_hash_from_sig(sig):
  78.     sig_int = int(hexlify(sig),16)
  79.     rsa_n = int(RSA_N,16)
  80.     dec_sig_as_int = pow(sig_int, 0x10001, rsa_n );
  81.     decrypted_sig = number.long_to_bytes(dec_sig_as_int, 128)
  82.     target_md5 = hexlify(decrypted_sig)[-64:]
  83.     return target_md5
  84.  
  85. def calc_actual_md5_hash(enc_config_body):
  86.     md5 = MD5.new()
  87.     md5.update(enc_config_body)
  88.     actual_md5_sig = md5.hexdigest()
  89.     actual_md5_sig = str.encode(actual_md5_sig)
  90.     return actual_md5_sig
  91.  
  92. def decrypt_config(input_file, output_file):
  93.     enc_config=load_config(input_file)
  94.  
  95.     print("Decrypting...")
  96.     iv = unhexlify(AES256CBC_IV)
  97.     key= unhexlify(AES256CBC_KEY)
  98.     cipher = AES.new(key, AES.MODE_CBC, iv)
  99.     try:
  100.         decrypted_data = cipher.decrypt(enc_config)
  101.         decompressed_data=""
  102.  
  103.         decompressed_data = zlib.decompress(decrypted_data)
  104.     except:
  105.         print("Bad config file...exiting")
  106.         sys.exit(1)
  107.  
  108.     config_text = decompressed_data[:-0x80]
  109.     actual_md5_hash = calc_actual_md5_hash(config_text)
  110.  
  111.     print("Verifying signature...")
  112.     sig = decompressed_data [-0x80:]
  113.     sig_int = int(hexlify(sig),16)
  114.     rsa_n = int(RSA_N,16)
  115.     dec_sig_as_int = pow(sig_int, 0x10001, rsa_n );
  116.     decrypted_sig = number.long_to_bytes(dec_sig_as_int, 128)
  117.     target_md5_hash = hexlify(decrypted_sig)[-32:]
  118.  
  119.     if (actual_md5_hash == target_md5_hash):
  120.         print("Signature ok...")        
  121.     else:
  122.         print("Signature not ok...exiting")
  123.         sys.exit(1)
  124.  
  125.     config_text = config_text[:-1]
  126.     check_config(config_text)
  127.  
  128.     print("Saving decrypted config to " + output_file + "...")
  129.     save_to_file(output_file, config_text)
  130.  
  131. def check_config(new_config_file):
  132.     head = new_config_file[0:len(XML_VERSION_STRING)]
  133.     if head != XML_VERSION_STRING:
  134.         print("Not a valid config file...exiting")
  135.         sys.exit(1)
  136.  
  137. def encrypt_config(input_file, output_file):
  138.     new_config_data=load_config(input_file)
  139.     check_config(new_config_data)
  140.     new_config_data += '\0'.encode()
  141.  
  142.     print("Calculating MD5 hash...")
  143.     h = MD5.new()
  144.     h.update(new_config_data)
  145.     actual_md5_sig = h.hexdigest()
  146.  
  147.     sig = SIG_TEMPLATE + actual_md5_sig;
  148.  
  149.     print("Adding Signature...")
  150.     sig_int = int(sig,16)
  151.     rsa_d = int(RSA_D,16)
  152.     rsa_n = int(RSA_N,16)
  153.     enc_sig_int = pow(sig_int, rsa_d, rsa_n);
  154.     encrypted_sig = number.long_to_bytes(enc_sig_int, 128)
  155.     new_config_data = new_config_data + encrypted_sig
  156.  
  157.     print("Compressing config...")
  158.     compressed_data = zlib.compress(new_config_data, 9)
  159.  
  160.     padding_amount = len(compressed_data) % 16
  161.     print("" + str(padding_amount) + " bytes padding needed")
  162.     print("Adding padding...")
  163.     compressed_data=compressed_data + b'\0'*(16-padding_amount)
  164.  
  165.     print("Encrypting config...")
  166.     iv = unhexlify(AES256CBC_IV)
  167.     key= unhexlify(AES256CBC_KEY)
  168.     aes = AES.new(key, AES.MODE_CBC, iv)
  169.     enc_new_config = aes.encrypt(compressed_data)
  170.  
  171.     print("Saving encrypted config to " + output_file + "...")
  172.     save_to_file(output_file, enc_new_config)
  173.  
  174. def main():
  175.     if len(sys.argv) < 4:
  176.         print_usage()
  177.  
  178.     input_file = sys.argv[2]
  179.     output_file = sys.argv[3]
  180.     command = sys.argv[1]
  181.  
  182.     if (command == "encrypt"):
  183.         encrypt_config(input_file, output_file)
  184.     elif (command == "decrypt"):
  185.         decrypt_config(input_file, output_file)
  186.     else:
  187.         print_usage()
  188.  
  189.  
  190. if __name__ == "__main__":
  191.     main()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top