forked from raspberrypi/rpi-eeprom
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rpi-eeprom-digest
executable file
·134 lines (107 loc) · 3.37 KB
/
rpi-eeprom-digest
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/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
Creates a .sig file containing the sha256 digest of the IMAGE and an optional
RSA signature of that hash.
Options:
-i The source image.
-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 RSA signature for the EEPROM config file.
rpi-eeprom-digest -k private.pem -i bootconf.txt -o bootconf.sig
# 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
# 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 pieeprom.bin -v pieeprom.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