mirror of
https://github.com/raspberrypi/rpi-eeprom.git
synced 2026-01-20 21:13:36 +08:00
Merge branch 'master' into debian/bullseye
This commit is contained in:
BIN
firmware/critical/pieeprom-2022-11-25.bin
Normal file
BIN
firmware/critical/pieeprom-2022-11-25.bin
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,15 @@
|
||||
# Raspberry Pi4 bootloader EEPROM release notes
|
||||
|
||||
## 2022-12-01 - Promote pieeprom-2022-11-25 to the DEFAULT release.
|
||||
Interesting changes since the last default release
|
||||
* [tryboot] conditional statement + tryboot_a_b mode
|
||||
* Support custom OTP mac addresses
|
||||
* Increase TFTP_MAX_BLOCK_SIZE
|
||||
* Stop NVMe cleanly
|
||||
* Fixes for NETCONSOLE parsing and initialisation.
|
||||
* Long filename support for start_file / fixup_file.
|
||||
* Secure boot and display debug info on the diagnostis screen.
|
||||
|
||||
## 2022-11-25 - Fix unconfigured netconsole messages - BETA + STABLE
|
||||
* Fix unconfigured netconsole messages https://github.com/raspberrypi/rpi-eeprom/issues/452
|
||||
* Add display state to HDMI diagnostics screen
|
||||
|
||||
49
tools/rpi-bootloader-key-convert
Executable file
49
tools/rpi-bootloader-key-convert
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import struct
|
||||
import sys
|
||||
|
||||
from Cryptodome.PublicKey import RSA
|
||||
|
||||
def bintopem(infile, outf):
|
||||
f = open(infile, 'rb')
|
||||
arr = f.read(264)
|
||||
|
||||
n = int.from_bytes(struct.unpack_from("256B", arr, 0), 'little')
|
||||
e = struct.unpack_from("<Q", arr, 256)[0]
|
||||
pubkey = RSA.construct((n, e))
|
||||
outf.write(pubkey.exportKey())
|
||||
|
||||
def pemtobin(infile, outf):
|
||||
key = RSA.importKey(open(infile, 'r').read())
|
||||
|
||||
if key.size_in_bits() != 2048:
|
||||
raise Exception("RSA key size must be 2048")
|
||||
|
||||
# Extract the public key componenet n,e and store as little endian
|
||||
outf.write(key.n.to_bytes(256, byteorder='little'))
|
||||
outf.write(key.e.to_bytes(8, byteorder='little'))
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser('Converts RSA keys between PEM format and the raw binary format used by the Raspberry Pi 4 bootloader')
|
||||
parser.add_argument('input', nargs='+')
|
||||
parser.add_argument('--inform', default="pem")
|
||||
parser.add_argument('--output', required=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.output:
|
||||
outf = open(args.output, 'wb')
|
||||
else:
|
||||
outf = sys.stdout.buffer
|
||||
|
||||
if args.inform == "pem":
|
||||
pemtobin(args.input[0], outf)
|
||||
elif args.inform == "bin":
|
||||
bintopem(args.input[0], outf)
|
||||
else:
|
||||
raise Exception("Unknown format %s" % args.inform)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
124
tools/rpi-otp-private-key
Executable file
124
tools/rpi-otp-private-key
Executable file
@@ -0,0 +1,124 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
FORCE=0
|
||||
READ_KEY=""
|
||||
WRITE_KEY=""
|
||||
OUTPUT_BINARY=0
|
||||
|
||||
die() {
|
||||
echo "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
$(basename "$0") [-cfwy] <key>
|
||||
|
||||
No args - reads the current private key from OTP. These values are NOT visible via 'vcgencmd otp_dump'.
|
||||
|
||||
-b Output the key in binary format.
|
||||
-c Reads key and exits with 1 if it is all zeros i.e. not set.
|
||||
-f Force write (if OTP is non-zero).
|
||||
The vcmailbox API checks that the new key is equal to the bitwise OR of the current OTP and the new key.
|
||||
N.B. OTP bits can never change from 1 to 0.
|
||||
-w Writes the new key to OTP memory.
|
||||
-y Skip the confirmation prompt when writing to OTP.
|
||||
|
||||
<key> is a 64 digit hex number (256 bit) e.g. to generate a 256 random number run 'openssl rand -hex 32'
|
||||
|
||||
IMPORTANT: Raspberry Pi 4 and earlier revisions do not have a hardware secure key store. These OTP rows are visible
|
||||
to any user in the 'video' group via vcmailbox. Therefore this functionality is only suitable for key
|
||||
storage if the OS has already been restricted using the signed boot functionality.
|
||||
|
||||
WARNING: Changes to OTP memory are permanent and cannot be undone.
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
check_key_set() {
|
||||
read_key
|
||||
if [ -z "$(echo "${READ_KEY}" | sed s/0//g)" ]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
read_key() {
|
||||
out=READ_KEY="$(vcmailbox 0x00030081 40 40 0 8 0 0 0 0 0 0 0 0)" || die "Failed to read the current key from OTP"
|
||||
READ_KEY="$(echo "${out}" | sed 's/0x//g' | awk '{for(i=8;i<16;i++) printf $i; print ""}')"
|
||||
}
|
||||
|
||||
write_key() {
|
||||
key="${1}"
|
||||
# Normalize formatting and check the length
|
||||
key="$(echo "${key}" | tr 'A-Z' 'a-z')"
|
||||
key="$(echo "${key}" | sed 's/[^a-f0-9]//g')"
|
||||
[ "$(echo -n "${key}" | wc -c)" = 64 ] || die "Invalid key parameter"
|
||||
|
||||
count=0
|
||||
key_params=""
|
||||
while [ ${count} -lt 8 ]; do
|
||||
start=$(((count * 8) + 1))
|
||||
end=$((start + 7))
|
||||
key_params="${key_params} 0x$(echo -n "${key}" | cut -c${start}-${end})"
|
||||
count=$((count + 1))
|
||||
done
|
||||
|
||||
if [ "${YES}" = 0 ] && [ -t 0 ]; then
|
||||
echo "Write ${key} to OTP?"
|
||||
echo
|
||||
echo "WARNING: Updates to OTP registers are permanent and cannot be undone."
|
||||
|
||||
echo "Type YES (in upper case) to continue or press return to exit."
|
||||
read -r confirm
|
||||
if [ "${confirm}" != "YES" ]; then
|
||||
echo "Cancelled"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
vcmailbox 0x38081 40 40 0 8 ${key_params} || die "Failed to write key"
|
||||
read_key
|
||||
[ "${READ_KEY}" = "${key}" ] || die "Key readback check failed. ${out}"
|
||||
}
|
||||
|
||||
YES=0
|
||||
while getopts bcfhw:y option; do
|
||||
case "${option}" in
|
||||
b) OUTPUT_BINARY=1
|
||||
;;
|
||||
c)
|
||||
if check_key_set; then
|
||||
exit 0
|
||||
fi
|
||||
exit 1
|
||||
;;
|
||||
f) FORCE=1
|
||||
;;
|
||||
h) usage
|
||||
;;
|
||||
w) WRITE_KEY="${OPTARG}"
|
||||
;;
|
||||
y) YES=1
|
||||
;;
|
||||
*) echo "Unknown argument \"${option}\""
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "${WRITE_KEY}" ]; then
|
||||
if [ "${FORCE}" = 0 ] && check_key_set; then
|
||||
die "Current key is non-zero. Specify -f to write anyway"
|
||||
fi
|
||||
write_key "${WRITE_KEY}"
|
||||
else
|
||||
read_key
|
||||
if [ "${OUTPUT_BINARY}" = 1 ]; then
|
||||
echo "${READ_KEY}" | xxd -r -p
|
||||
else
|
||||
echo "${READ_KEY}"
|
||||
fi
|
||||
fi
|
||||
Reference in New Issue
Block a user