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