Skip to content

Commit

Permalink
releases: helper scripts to facilitate signing jade v2 firmwares
Browse files Browse the repository at this point in the history
  • Loading branch information
JamieDriver committed Nov 26, 2024
1 parent 6ab12bb commit b357ea6
Show file tree
Hide file tree
Showing 8 changed files with 318 additions and 0 deletions.
34 changes: 34 additions & 0 deletions release/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,37 @@ eg: './scripts/mkhashes.sh 0.1.33' or './scripts/mkhashes.sh 0.1.32 0.1.33 0.1.3
- NOTE: Should not be needed in normal operation, as the hash files are produced at
the same times as the compressed firmware file.
Needed to generate hash files for older fw files, or to regenerate hash files.

Jade v2 Signing
===============

* scripts/v2sign.sh <version/dir> <key_label>
eg: './scripts/v2sign.sh 1.0.33 v2pk1'
- For the 'jade2.0' subdir in 'staging/upload/<version/dir>', signs the ble and noradio
firmware and bootloader binaries with the private key named (which must be present as
'scripts/<key_label>.pem'). (Note: the binaries are first hashed with sha256, and
the digests signed.)
The signature files are created in the top level of the version directory, and are
verified with the public key 'scripts/<key_label>.pub'

* scripts/v2jadesign.sh <version/dir> <key_label>
eg: './scripts/v2jadesign.sh 1.0.33 v2pk1'
- For the 'jade2.0' subdir in 'staging/upload/<version/dir>', signs the ble and noradio
firmware and bootloader binaries with the Jade unit connected by usb/serial.
The RSA key is derived from the signer hd wallet root master key using bip85.
(Note: the binaries are first hashed with sha256, and the digests passed to Jade for
signing in a single call.)
The signature files are created in the top level of the version directory, and are
verified with the public key 'scripts/<key_label>.pub'

* scripts/v2applysigs.sh <version/dir> <key_label> [ <key_label> ... ]
eg: './scripts/v2applysigs.sh 1.0.33 v2pk1 v2pk2 v2pk3'
- For the 'jade2.0' subdir in 'staging/upload/<version/dir>', for each of the ble and
noradio firmware and bootloader binaries, assembles the relevant signatures with the
original binary, into a single signed binary file.
The signed bnary files are created in the top level of the version directory but the
jade fw files are copied back into their respective build directories (consistent with
the v1 signing process).
The final signed binaries are verified with the public keys 'scripts/<key_label>.pub'
listed/used.

64 changes: 64 additions & 0 deletions release/scripts/v2applysigs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/bash

if [ -z "${1}" -o -z "${2}" ]
then
echo "Usage: ${0} <version/dir> <key_label> [ <key_label> ... ]"
exit 1
fi
VER_DIR="${1}"
shift
SIGNER_KEY_LABELS="$@"

WORKING_DIR="staging/${VER_DIR}/jade2.0"

BLEDIR="build_v2_prod"
NORADIODIR="build_v2_noradio_prod"

FILE_PREFIX="v2_${VER_DIR}"
FW_SUFFIX="bin"
SIGNED_SUFFIX="signed.bin"

BUILDS="ble noradio"
BINARIES="bootloader jade"

# Relative paths from where it will be referenced in fw dir
PUBKEYS=""
for key_label in ${SIGNER_KEY_LABELS}
do
PUBKEYS="${PUBKEYS} ../../../scripts/${key_label}.pub"
done

pushd "${WORKING_DIR}"

for build in ${BUILDS}
do
for binary in ${BINARIES}
do
sig_files=""
for key_label in ${SIGNER_KEY_LABELS}
do
sig_file="${FILE_PREFIX}_${build}_${binary}.${key_label}.sig"
sig_files="${sig_files} ${sig_file}"
done

file_prefix="${FILE_PREFIX}_${build}_${binary}"
infile="${file_prefix}.${FW_SUFFIX}"
outfile="${file_prefix}_${SIGNED_SUFFIX}"

espsecure.py sign_data --version 2 --pub-key ${PUBKEYS} --signature ${sig_files} --output "${outfile}" "${infile}"
espsecure.py signature_info_v2 "${outfile}"

for pubkey in ${PUBKEYS}
do
espsecure.py verify_signature --version 2 --keyfile "${pubkey}" "${outfile}"
done
done

sha256sum "${FILE_PREFIX}"_*_"${SIGNED_SUFFIX}"
done

# Copy main fw binaries that have been signed
cp "${FILE_PREFIX}_ble_jade_${SIGNED_SUFFIX}" "${BLEDIR}/jade_${SIGNED_SUFFIX}"
cp "${FILE_PREFIX}_noradio_jade_${SIGNED_SUFFIX}" "${NORADIODIR}/jade_${SIGNED_SUFFIX}"

popd
107 changes: 107 additions & 0 deletions release/scripts/v2jadesign.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/bin/bash

if [ -z "${1}" -o -z "${2}" ]
then
echo "Usage: ${0} <version/dir> <key_label>"
exit 1
fi
VER_DIR="${1}"
KEY_LABEL="${2}"

WORKING_DIR="staging/${VER_DIR}/jade2.0"

# Can log if required
LOGGING=""
#LOGGING="--log INFO"

# Can fetch and check the pubkey from Jade - but slower and really no need
# as we verify the signature with the expected pubkey at the end.
CHECK_JADE_PUBKEY=""
JADE_PUBKEY_FILE="jade_signing_key.pub"
#CHECK_JADE_PUBKEY="--savepubkey ${JADE_PUBKEY_FILE}"

# Standard for Jade fw signing
KEYLEN=3072
INDEX=1784767589

# Relative paths from where it will be referenced in fw dir
PUBKEY="../../../scripts/${KEY_LABEL}.pub"

BLEDIR="build_v2_prod"
NORADIODIR="build_v2_noradio_prod"

FILE_PREFIX="v2_${VER_DIR}"
SIG_SUFFIX="${KEY_LABEL}.sig"

HASH_OPTS="-sha256 -binary"
VERIFY_OPTS="-pubin -inkey ${PUBKEY} -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss"
JADE_SIGN_CMD="python ../../../../jade_bip85_rsa_sign.py ${LOGGING} ${CHECK_JADE_PUBKEY} --keylen ${KEYLEN} --index ${INDEX} --digest-files"

pushd "${WORKING_DIR}"

# Verify bootloaders are same
sha1=$(sha256sum "${BLEDIR}/bootloader/bootloader.bin" | cut -d\ -f1)
sha2=$(sha256sum "${NORADIODIR}/bootloader/bootloader.bin" | cut -d\ -f1)
if [ -z "${sha1}" -o -z "${sha2}" -o "${sha1}" != "${sha2}" ]
then
echo "Bootloaders missing or differ!"
popd
exit 2
fi

# Copy binaries that need signing
cp "${BLEDIR}/bootloader/bootloader.bin" "${FILE_PREFIX}_ble_bootloader.bin"
cp "${BLEDIR}/jade.bin" "${FILE_PREFIX}_ble_jade.bin"
cp "${NORADIODIR}/bootloader/bootloader.bin" "${FILE_PREFIX}_noradio_bootloader.bin"
cp "${NORADIODIR}/jade.bin" "${FILE_PREFIX}_noradio_jade.bin"

# Hash the bootloaders and fws locally
HASH_FILES=""
for build in "ble" "noradio"
do
for program in "bootloader" "jade"
do
binary="${FILE_PREFIX}_${build}_${program}.bin"
hash_file="${FILE_PREFIX}_${build}_${program}.hash"
HASH_FILES="${HASH_FILES} ${hash_file}"

openssl dgst ${HASH_OPTS} -out "${hash_file}" "${binary}"
done
done

# Sign the hashes with jade
echo "Please approve signing on your Jade device"
${JADE_SIGN_CMD} ${HASH_FILES}

# Check signatures with labeled pubkey, and rename if good
for build in "ble" "noradio"
do
for program in "bootloader" "jade"
do
hash_file="${FILE_PREFIX}_${build}_${program}.hash"
sig_file="${hash_file}.sig"
openssl pkeyutl -verify ${VERIFY_OPTS} -sigfile "${sig_file}" -in "${hash_file}"
if [ "${?}" -eq 0 ]
then
mv ${sig_file} "${FILE_PREFIX}_${build}_${program}.${SIG_SUFFIX}"
rm "${hash_file}"
else
echo "Signature verification of ${sig_file} over ${hash_file} with ${PUBKEY} failed"
fi
done
done

sha256sum *."${SIG_SUFFIX}"

# Verify jade pubkey matches expected (if feched)
if [ -n "${CHECK_JADE_PUBKEY}" ]
then
sha1=$(sha256sum "${PUBKEY}" | cut -d\ -f1)
sha2=$(sha256sum "${JADE_PUBKEY_FILE}" | cut -d\ -f1)
if [ -z "${sha1}" -o -z "${sha2}" -o "${sha1}" != "${sha2}" ]
then
echo "Error: Pubkey pem mismatch!"
fi
fi

popd
11 changes: 11 additions & 0 deletions release/scripts/v2pk1.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAlV05rBBmSebxHrlpYiHo
5IDzzMZ6iLdiz1bY+CkYScwb1xFFl2LfXIwqmb0YpDGON96SFWZR26E4mbkb5qWT
XAJ6n0rE/Bei2Akt0PxZ8b/Rk3dDGbFHLIeNb6sJsFV232no4eA2GilX2AGbSVpY
uecmIVvzIqapeeg9VmjCAVtGo89HmC3aug+iQDbYo9WG2cgyTwAVouFPBRtfMqxi
RhyWSk1FY08i+i59wRg4MMRWWdWE+uNsIuwJmfm6wIYyEbq6V1sArhs1g6VyKRnd
VBKSWZKpcfZuHvT9BcksQ9y9Cw5IexQ+8/miHWOoYyuQACt+P3J1rvjNVxEqV2rw
e+Iz0ZJlmVUb4Ku9vC8G7XQloZAMeVVAvNkuyiN2E+3PDtkobsvBnCD+5RsYZ2h1
Jdv3WnkdthT+JLYISVRFKHW/O0VjBoNbVWd1e5ev4m7GxUFO2XNtil7TgQ7P/co1
DzGBIbFFVwzBpBIB9yYo63ETUx8zd+VUkQ/j5cRynU8DAgMBAAE=
-----END PUBLIC KEY-----
11 changes: 11 additions & 0 deletions release/scripts/v2pk2.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAxErJHx1UY7r9EBHBmneH
8S45WAMFbjWpS4VvsVRW1kbune4SpsjRXtciO3qJTFFDANpcO1BNm29YWskgKr45
GdhVQjsggFzMsvbV8PYOLOHZcK+Hw5bV9cKycvq9GcaHSQHXVlQl8EiFFNsb7m6K
bPVbylvhXfzt116VXLKiaZj6L1nbjhoqylf0VoAd90BzdDngiN0nwIbhMF3Kqtdu
ix+/+kwnJ7IYiBR2wgHyCuckjTsWx/fL8qgTcn1XrZ/Jrs2qDzHFHGGBRksR6Kra
i6oC0xBatDcaxVCgSXOuuJd+GM4sPn0TD0K43fSnoyit8Lk6aV23jx2m6QZ4ISU3
pii8IlBhqEFTGs8VXTtV7j9755mxd6cibt0N7QowvSo3DWD80CdZiTWcUH3owHJB
iT7iBJaMXRy+TiOzqmGCQjcLThwUL27+5Fvd+XoszE7s3ezdR9is9k99p1Sji09X
ahFFhKbLvyGGhgS1ziSVlbgPkPxw/3tIj1gYVQc2GmcZAgMBAAE=
-----END PUBLIC KEY-----
11 changes: 11 additions & 0 deletions release/scripts/v2pk3.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAg7FH/iN3AqL3xBAiiimf
671/656eSMKrgTrUvu8dr5Z7vC9eNRYHgvIlf5piQN5MosFThJoULOLU4d0a44HQ
xZMI8Lyz/NhHxeZI7XJR9UHZav0MvJj9BUhX16nX9FsNaBm5tu/klK8HNqappi+1
JSMFwjCaFTjciyfaRBqIfEnSkeIDO8wfIcLR7o45TpPT/u8njnkvrDS5/B2Ka3g8
gEsgaQXJJ3pubY9HOu5//fOj2Dvvb0IjcSpa0AQifx1n2zD1Nz/dpUKToKGKquZx
dZYLQOWF09o3u8RX1eUTXdOnM/+JEk7dNOnqtWSdCUyf/XqlRJ2r5Crvj91lNiFT
j6XgMlnF45Mn/65gVSuqYhum7MNIOSI2+brPrv1Y3KWw1ljNWDqZWV2zwofHxaOj
SNNKFM7mnRy5u8wh9Jqr9p/tkxZA2sn3qvhDXIotoGLNNNjsWM32ek/7FJRyCEeu
u5A+Dy16U1dPrhcwSpZsln8CzrYqTxexsSzBGq9JggPFAgMBAAE=
-----END PUBLIC KEY-----
11 changes: 11 additions & 0 deletions release/scripts/v2pkdev.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAufP/ss5BAxgp4TxQNFu4
l2ZomknoIK7wW5PvF59zA+IalObbnmvAHrBaXH5QJiXmEmq76ltwF4BfkTsst0ZK
as0b628r72sS380abov3j6QIqCJ6Xzpqq9WCyHbIDM375/JnRRQXbhU3orsbYIkz
WBKx1ULSuCYY3sWyDrZ4IRuDyKz3ne8dex2fbIDTxqbmQaa/0fkqGVEDO852NPyf
CcfOs4JIcyf/9yarcdEBILQbaGLSGtyE6lakRDnv3QZpMALZk+dU3T80zpDfdc0E
8Ew1T6FuIKGAWgnQn5K47D8G4NMnTd2IxoR39XlRyvwe4YOaTgiFTRyKE0ge3NDE
E+TKm9KlRtYQyY2tGD6IL1JJ7muVRg0Qr7Km2E15a/HdNNx+LsxlUAUDewXOGQRs
pNEi80If5ZuPKusBJGCcuDFW3Bk76E5HSJn+S8+3b43piPJSILj0SpnTPkwwZYBF
deIMsr/mmLbvKzsPV42xHDcUnfwUlFHAnjtBqF5kEWrlAgMBAAE=
-----END PUBLIC KEY-----
69 changes: 69 additions & 0 deletions release/scripts/v2sign.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/bash

if [ -z "${1}" -o -z "${2}" ]
then
echo "Usage: ${0} <version/dir> <key_label>"
exit 1
fi
VER_DIR="${1}"
KEY_LABEL="${2}"

WORKING_DIR="staging/${VER_DIR}/jade2.0"

# Relative paths from where it will be referenced in fw dir
KEY="../../../scripts/${KEY_LABEL}.pem"
PUBKEY="../../../scripts/${KEY_LABEL}.pub"

BLEDIR="build_v2_prod"
NORADIODIR="build_v2_noradio_prod"

FILE_PREFIX="v2_${VER_DIR}"
SIG_SUFFIX="${KEY_LABEL}.sig"

HASH_OPTS="-sha256 -binary"
SIGN_OPTS="-inkey ${KEY} -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss -pkeyopt rsa_pss_saltlen:32 -pkeyopt rsa_mgf1_md:sha256"
VERIFY_OPTS="-pubin -inkey ${PUBKEY} -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss"

pushd "${WORKING_DIR}"

# Verify bootloaders are same
sha1=$(sha256sum "${BLEDIR}/bootloader/bootloader.bin" | cut -d\ -f1)
sha2=$(sha256sum "${NORADIODIR}/bootloader/bootloader.bin" | cut -d\ -f1)
if [ -z "${sha1}" -o -z "${sha2}" -o "${sha1}" != "${sha2}" ]
then
echo "Bootloaders missing or differ!"
popd
exit 2
fi

# Copy binaries that need signing
cp "${BLEDIR}/bootloader/bootloader.bin" "${FILE_PREFIX}_ble_bootloader.bin"
cp "${BLEDIR}/jade.bin" "${FILE_PREFIX}_ble_jade.bin"
cp "${NORADIODIR}/bootloader/bootloader.bin" "${FILE_PREFIX}_noradio_bootloader.bin"
cp "${NORADIODIR}/jade.bin" "${FILE_PREFIX}_noradio_jade.bin"

# Hash the bootloaders and fws locally
for build in "ble" "noradio"
do
for program in "bootloader" "jade"
do
filename_root="${FILE_PREFIX}_${build}_${program}"
binary="${filename_root}.bin"
hash_file="${filename_root}.hash"
sig_file="${filename_root}.${SIG_SUFFIX}"

openssl dgst ${HASH_OPTS} -out "${hash_file}" "${binary}"
openssl pkeyutl -sign ${SIGN_OPTS} -in "${hash_file}" -out "${sig_file}"
openssl pkeyutl -verify ${VERIFY_OPTS} -sigfile "${sig_file}" -in "${hash_file}"
if [ "${?}" -eq 0 ]
then
rm "${hash_file}"
else
echo "Signature verification of ${sig_file} over ${hash_file} with ${PUBKEY} failed"
fi
done
done

sha256sum *."${SIG_SUFFIX}"

popd

0 comments on commit b357ea6

Please sign in to comment.