mirror of
https://github.com/raspberrypi/rpi-eeprom.git
synced 2026-01-21 06:05:02 +08:00
Make it clearer that rpi-eeprom-digest is used create optionally signed hashes for binary files. For secure-boot the update-pieeprom.sh wrapper must be used because only the boot configuration is signed by the customer key rather than the entire SPI flash image.
148 lines
4.0 KiB
Bash
Executable File
148 lines
4.0 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Helper script to generate .sig files for use with the Raspberry Pi bootloader.
|
|
|
|
# This has been implemented in a separate script in order to have avoid having
|
|
# a hard dependency on OpenSSL.
|
|
|
|
set -e
|
|
|
|
OPENSSL=${OPENSSL:-openssl}
|
|
|
|
die() {
|
|
echo "$@" >&2
|
|
exit 1
|
|
}
|
|
|
|
TMP_DIR=""
|
|
cleanup() {
|
|
if [ -d "${TMP_DIR}" ]; then
|
|
rm -rf "${TMP_DIR}"
|
|
fi
|
|
}
|
|
|
|
checkDependencies() {
|
|
if ! command -v sha256sum > /dev/null; then
|
|
die "sha256sum not found. Try installing the coreutilities package."
|
|
fi
|
|
|
|
if [ -n "${KEY}" ] || [ "${VERIFY}" = 1 ]; then
|
|
if ! command -v openssl > /dev/null; then
|
|
die "openssl not found. Try installing the openssl package."
|
|
fi
|
|
|
|
if ! command -v xxd > /dev/null; then
|
|
die "xxd not found. Try installing the xxd package."
|
|
fi
|
|
fi
|
|
}
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
rpi-eeprom-digest [-k RSA_KEY] -i IMAGE -o OUTPUT
|
|
|
|
Tool to generate .sig files containing the SHA256 digest and optional
|
|
RSA signature. Typically this tool is used by rpi-eeprom-update to
|
|
generate a hash to guard against file-system corruption for EEPROM updates
|
|
OR for signing OS images (boot.img) for secure-boot.
|
|
|
|
This tool CANNOT be used directly to sign an bootloader EEPROM image
|
|
for secure-boot because the signed data is bootloader configuration file
|
|
rather than the entire flash image.
|
|
To create signed bootloader images please see
|
|
https://github.com/raspberrypi/usbboot/tree/master/secure-boot-recovery/README.md
|
|
|
|
|
|
Options:
|
|
-i The source image e.g. boot.img
|
|
-o The name of the digest/signature file.
|
|
-k Optional RSA private key.
|
|
|
|
RSA signing
|
|
If a private key in PEM format is supplied then the RSA signature of the
|
|
sha256 digest is included in the .sig file. Currently, the bootloader only
|
|
supports sha256 digests signed with a 2048bit RSA key.
|
|
The bootloader only verifies RSA signatures in signed boot mode
|
|
(not available yet) and only for the EEPROM config file and the signed image.
|
|
|
|
Examples:
|
|
|
|
# Generate the normal sha256 hash to guard against file-system corruption
|
|
rpi-eeprom-digest -i pieeprom.bin -o pieeprom.sig
|
|
rpi-eeprom-digest -i vl805.bin -o vl805.sig
|
|
|
|
# Generate a signed OS ramdisk image for secure-boot
|
|
rpi-eeprom-digest -k private.pem -i boot.img -o boot.sig
|
|
|
|
# Generate RSA signature for the EEPROM config file
|
|
# As used by update-pieeprom.sh in usbboot/secure-boot-recovery
|
|
rpi-eeprom-digest -k private.pem -i bootconf.txt -o bootconf.sig
|
|
|
|
# To verify the signature of an existing .sig file using the public key.
|
|
# N.B The key file must be the PUBLIC key in PEM format.
|
|
rpi-eeprom-digest -k public.pem -i boot.bin -v boot.sig
|
|
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
writeSig() {
|
|
TMP_DIR=$(mktemp -d)
|
|
SIG_TMP="${TMP_DIR}/tmp.sig"
|
|
sha256sum "${IMAGE}" | awk '{print $1}' > "${OUTPUT}"
|
|
|
|
# Include the update-timestamp
|
|
echo "ts: $(date -u +%s)" >> "${OUTPUT}"
|
|
|
|
if [ -n "${KEY}" ]; then
|
|
[ -f "${KEY}" ] || die "RSA private \"${KEY}\" not found"
|
|
"${OPENSSL}" dgst -sign "${KEY}" -keyform PEM -sha256 -out "${SIG_TMP}" "${IMAGE}"
|
|
echo "rsa2048: $(xxd -c 4096 -p < "${SIG_TMP}")" >> "${OUTPUT}"
|
|
fi
|
|
}
|
|
|
|
verifySig() {
|
|
TMP_DIR=$(mktemp -d)
|
|
sig_file="${1}"
|
|
[ -f "${sig_file}" ] || die "Signature file ${sig_file} not found"
|
|
sig_hex="$(grep rsa2048 "${sig_file}" | cut -f 2 -d ' ')"
|
|
[ -n "${sig_hex}" ] || die "No RSA signature in ${sig_file}"
|
|
|
|
echo ${sig_hex} | xxd -c 4096 -p -r > "${TMP_DIR}/sig.bin"
|
|
"${OPENSSL}" dgst -verify "${KEY}" -signature "${TMP_DIR}/sig.bin" "${IMAGE}" || die "${IMAGE} not verified"
|
|
}
|
|
|
|
OUTPUT=""
|
|
VERIFY=0
|
|
while getopts i:k:ho:v: option; do
|
|
case "${option}" in
|
|
i) IMAGE="${OPTARG}"
|
|
;;
|
|
k) KEY="${OPTARG}"
|
|
;;
|
|
o) OUTPUT="${OPTARG}"
|
|
;;
|
|
v) SIGNATURE="${OPTARG}"
|
|
VERIFY=1
|
|
;;
|
|
h) usage
|
|
;;
|
|
*) echo "Unknown argument \"${option}\""
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
|
|
trap cleanup EXIT
|
|
checkDependencies
|
|
|
|
[ -n "${IMAGE}" ] || usage
|
|
[ -f "${IMAGE}" ] || die "Source image \"${IMAGE}\" not found"
|
|
if [ "${VERIFY}" = 1 ]; then
|
|
verifySig "${SIGNATURE}"
|
|
else
|
|
[ -n "${OUTPUT}" ] || usage
|
|
writeSig
|
|
fi
|
|
|