ardupilot/Tools/scripts/signing/make_secure_bl.py

77 lines
2.0 KiB
Python
Executable File

#!/usr/bin/env python3
'''
add a set of up to 10 public keys to an ArduPilot bootloader bin file
'''
import sys
import os
import base64
try:
import monocypher
except ImportError:
print("Please install monocypher with: python3 -m pip install pymonocypher")
sys.exit(1)
# get command line arguments
from argparse import ArgumentParser
parser = ArgumentParser(description='make_secure_bl')
parser.add_argument("--omit-ardupilot-keys", action='store_true', default=False, help="omit ArduPilot signing keys")
parser.add_argument("bootloader", type=str, default=None, help="bootloader")
parser.add_argument("keys", nargs='*', type=str, default=[], help="keys")
args = parser.parse_args()
descriptor = b'\x4e\xcf\x4e\xa5\xa6\xb6\xf7\x29'
max_keys = 10
key_len = 32
img = open(args.bootloader, 'rb').read()
offset = img.find(descriptor)
if offset == -1:
print("Failed to find descriptor")
sys.exit(1)
offset += 8
desc = b''
desc_len = 0
keys = []
if not args.omit_ardupilot_keys:
print("Adding ArduPilot keys")
signing_dir = os.path.dirname(os.path.realpath(__file__))
keydir = os.path.join(signing_dir,"ArduPilotKeys")
for root, dirs, files in os.walk(keydir):
for f in files:
if f.endswith(".dat"):
keys.append(os.path.relpath(os.path.join(keydir, f)))
keys += args.keys[:]
if len(keys) > max_keys:
print("Too many key files %u, max is %u" % (len(keys), max_keys))
sys.exit(1)
if len(keys) <= 0:
print("At least one key file required")
sys.exit(1)
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):])
for kfile in keys:
key = decode_key("PUBLIC", open(kfile, "r").read())
print("Applying Public Key %s" % kfile)
if len(key) != key_len:
print("Bad key length %u in %s" % (len(key), kfile))
sys.exit(1)
desc += key
desc_len += key_len
img = img[:offset] + desc + img[offset+desc_len:]
open(sys.argv[1], 'wb').write(img)