Commit 8b7ad436db40757f1b387647323fe535aa52759b
Committed by
GitHub
Merge pull request #161 from timg236/rpi-eeprom-digest-verify
rpi-eeprom-digest: Add an option to verify RSA signed files.
Showing
1 changed file
with
44 additions
and
19 deletions
tools/rpi-eeprom-digest
| @@ -57,18 +57,50 @@ The bootloader only verifies RSA signatures in signed boot mode | @@ -57,18 +57,50 @@ The bootloader only verifies RSA signatures in signed boot mode | ||
| 57 | Examples: | 57 | Examples: |
| 58 | 58 | ||
| 59 | # Generate RSA signature for the EEPROM config file. | 59 | # Generate RSA signature for the EEPROM config file. |
| 60 | -rpi-eeprom-digest -k key.pem -i bootconf.txt -o bootconf.sig | 60 | +rpi-eeprom-digest -k private.pem -i bootconf.txt -o bootconf.sig |
| 61 | 61 | ||
| 62 | # Generate the normal sha256 hash to guard against file-system corruption | 62 | # Generate the normal sha256 hash to guard against file-system corruption |
| 63 | rpi-eeprom-digest -i pieeprom.bin -o pieeprom.sig | 63 | rpi-eeprom-digest -i pieeprom.bin -o pieeprom.sig |
| 64 | rpi-eeprom-digest -i vl805.bin -o vl805.sig | 64 | rpi-eeprom-digest -i vl805.bin -o vl805.sig |
| 65 | 65 | ||
| 66 | +# To verify the signature of an existing .sig file using the public key. | ||
| 67 | +# N.B The key file must be the PUBLIC key in PEM format. | ||
| 68 | +rpi-eeprom-digest -k public.pem -i pieeprom.bin -v pieeprom.sig | ||
| 69 | + | ||
| 66 | EOF | 70 | EOF |
| 67 | exit 0 | 71 | exit 0 |
| 68 | } | 72 | } |
| 69 | 73 | ||
| 74 | +writeSig() { | ||
| 75 | + TMP_DIR=$(mktemp -d) | ||
| 76 | + SIG_TMP="${TMP_DIR}/tmp.sig" | ||
| 77 | + sha256sum "${IMAGE}" | awk '{print $1}' > "${OUTPUT}" | ||
| 78 | + | ||
| 79 | + # Include the update-timestamp | ||
| 80 | + echo "ts: $(date -u +%s)" >> "${OUTPUT}" | ||
| 81 | + | ||
| 82 | + if [ -n "${KEY}" ]; then | ||
| 83 | + [ -f "${KEY}" ] || die "RSA private \"${KEY}\" not found" | ||
| 84 | + "${OPENSSL}" dgst -sign "${KEY}" -keyform PEM -sha256 -out "${SIG_TMP}" "${IMAGE}" | ||
| 85 | + echo "rsa2048: $(xxd -c 4096 -p < "${SIG_TMP}")" >> "${OUTPUT}" | ||
| 86 | + fi | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +verifySig() { | ||
| 90 | + TMP_DIR=$(mktemp -d) | ||
| 91 | + sig_file="${1}" | ||
| 92 | + [ -f "${sig_file}" ] || die "Signature file ${sig_file} not found" | ||
| 93 | + sig_hex="$(grep rsa2048 "${sig_file}" | cut -f 2 -d ' ')" | ||
| 94 | + echo ${sig_hex} | xxd -c 4096 -p -r > "${TMP_DIR}/sig.bin" | ||
| 95 | + | ||
| 96 | + [ -n "${sig_hex}" ] || die "No RSA signature in ${sig_file}" | ||
| 97 | + sha256=$(sha256sum "${IMAGE}" | awk '{print $1}') | ||
| 98 | + "${OPENSSL}" dgst -verify "${KEY}" -signature "${TMP_DIR}/sig.bin" "${IMAGE}" || die "${IMAGE} not verified" | ||
| 99 | +} | ||
| 100 | + | ||
| 70 | OUTPUT="" | 101 | OUTPUT="" |
| 71 | -while getopts i:k:ho: option; do | 102 | +VERIFY=0 |
| 103 | +while getopts i:k:ho:v: option; do | ||
| 72 | case "${option}" in | 104 | case "${option}" in |
| 73 | i) IMAGE="${OPTARG}" | 105 | i) IMAGE="${OPTARG}" |
| 74 | ;; | 106 | ;; |
| @@ -76,6 +108,9 @@ while getopts i:k:ho: option; do | @@ -76,6 +108,9 @@ while getopts i:k:ho: option; do | ||
| 76 | ;; | 108 | ;; |
| 77 | o) OUTPUT="${OPTARG}" | 109 | o) OUTPUT="${OPTARG}" |
| 78 | ;; | 110 | ;; |
| 111 | + v) SIGNATURE="${OPTARG}" | ||
| 112 | + VERIFY=1 | ||
| 113 | + ;; | ||
| 79 | h) usage | 114 | h) usage |
| 80 | ;; | 115 | ;; |
| 81 | *) echo "Unknown argument \"${option}\"" | 116 | *) echo "Unknown argument \"${option}\"" |
| @@ -84,25 +119,15 @@ while getopts i:k:ho: option; do | @@ -84,25 +119,15 @@ while getopts i:k:ho: option; do | ||
| 84 | esac | 119 | esac |
| 85 | done | 120 | done |
| 86 | 121 | ||
| 87 | -[ -n "${IMAGE}" ] || usage | ||
| 88 | -[ -n "${OUTPUT}" ] || usage | ||
| 89 | - | ||
| 90 | trap cleanup EXIT | 122 | trap cleanup EXIT |
| 91 | - | ||
| 92 | checkDependencies | 123 | checkDependencies |
| 93 | 124 | ||
| 125 | +[ -n "${IMAGE}" ] || usage | ||
| 94 | [ -f "${IMAGE}" ] || die "Source image \"${IMAGE}\" not found" | 126 | [ -f "${IMAGE}" ] || die "Source image \"${IMAGE}\" not found" |
| 95 | - | ||
| 96 | -TMP_DIR=$(mktemp -d) | ||
| 97 | -SIG_TMP="${TMP_DIR}/tmp.sig" | ||
| 98 | -sha256sum "${IMAGE}" | awk '{print $1}' > "${OUTPUT}" | ||
| 99 | - | ||
| 100 | -# Include the update-timestamp | ||
| 101 | -echo "ts: $(date -u +%s)" >> "${OUTPUT}" | ||
| 102 | - | ||
| 103 | -if [ -n "${KEY}" ]; then | ||
| 104 | - [ -f "${KEY}" ] || die "RSA private \"${KEY}\" not found" | ||
| 105 | - | ||
| 106 | - "${OPENSSL}" dgst -sign "${KEY}" -keyform PEM -sha256 -out "${SIG_TMP}" "${IMAGE}" | ||
| 107 | - echo "rsa2048: $(xxd -c 4096 -p < "${SIG_TMP}")" >> "${OUTPUT}" | 127 | +if [ "${VERIFY}" = 1 ]; then |
| 128 | + verifySig "${SIGNATURE}" | ||
| 129 | +else | ||
| 130 | + [ -n "${OUTPUT}" ] || usage | ||
| 131 | + writeSig | ||
| 108 | fi | 132 | fi |
| 133 | + |