sign_fw.py 1.4 KB

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