sign_fw.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/env python3
  2. '''
  3. sign an OTA bin
  4. '''
  5. # python ../scripts/sign_fw.py ArduRemoteID-VKUAV_RID.bin ../VK_private_key1.dat 13
  6. import sys
  7. import struct
  8. import base64
  9. try:
  10. import monocypher
  11. except ImportError:
  12. print("Please install monocypher with: python3 -m pip install pymonocypher==3.1.3.2")
  13. sys.exit(1)
  14. key_len = 32
  15. sig_len = 64
  16. descriptor = b'\x43\x2a\xf1\x37\x46\xe2\x75\x19'
  17. if len(sys.argv) < 4:
  18. print("Usage: sign_fw OTA_FILE PRIVATE_KEYFILE BOARD_ID")
  19. sys.exit(1)
  20. ota_file = sys.argv[1]
  21. key_file = sys.argv[2]
  22. board_id = int(sys.argv[3])
  23. img = open(ota_file,'rb').read()
  24. img_len = len(img)
  25. def decode_key(ktype, key):
  26. ktype += "_KEYV1:"
  27. if not key.startswith(ktype):
  28. print("Invalid key type")
  29. sys.exit(1)
  30. return base64.b64decode(key[len(ktype):])
  31. key = decode_key("PRIVATE", open(key_file, 'r').read())
  32. if len(key) != key_len:
  33. print("Bad key length %u" % len(key))
  34. sys.exit(1)
  35. desc_len = 80
  36. ad_start = len(img)-desc_len
  37. if img[ad_start:ad_start+8] == descriptor:
  38. print("Image is already signed")
  39. sys.exit(1)
  40. signature = monocypher.signature_sign(key, img)
  41. if len(signature) != sig_len:
  42. print("Bad signature length %u should be %u" % (len(signature), sig_len))
  43. sys.exit(1)
  44. desc = struct.pack("<II64s", board_id, img_len, signature)
  45. img = img + descriptor + desc
  46. if len(img) != img_len + desc_len:
  47. print("Error: incorrect image length")
  48. sys.exit(1)
  49. print("Applying signature")
  50. open(ota_file, "wb").write(img)
  51. print("Wrote %s" % ota_file)