This directory contains the beta bootcode5.bin (recovery.bin) and a pre-release pieeprom.bin bootloader release. Older bootloader and recovery.bin releases do not support secure boot.
sudo apt install xxd python3-pycryptodomeAlternatively, specify the path when invoking the helper scripts.
export KEY_FILE="${HOME}/private.pem"Customise with the desired bootloader settings. See: Bootloader configuration
The BCM2712 boot ROM requires the second-stage firmware (recovery.bin / bootcode5.bin) to be counter-signed with the customer private key in secure-boot mode.
Pass the f flag to enable firmware counter-signing.
../tools/update-pieeprom.sh -f -k "${KEY_FILE}"
If secure-boot has already been enabled on the device, then recovery.bin must also be counter-signed.
However, booting a counter-signed recovery.bin image on a fresh board without secure-boot enabled will fail
because the ROM is effectively checking this against a key hash of zero.
../tools/update-pieeprom.sh -fr -k "${KEY_FILE}"
When using a Hardware Security Module (HSM), you need to provide both the HSM wrapper script and the corresponding public key:
../tools/update-pieeprom.sh -f -H hsm-wrapper -p public.pem
For recovery.bin signing with HSM:
../tools/update-pieeprom.sh -fr -H hsm-wrapper -p public.pem
The HSM wrapper script should:
- Take a single argument which is a temporary filename containing the data to sign
- Output the PKCS#1 v1.5 signature in hex format
- Return a non-zero exit code if signing fails
pieeprom.bin can then be flashed to the bootloader EEPROM via rpiboot.
- Power off the device
- Set nRPIBOOT jumper (or hold power button before power on) and remove EEPROM WP protection
cd secure-boot-recovery5
mkdir -p metadata
../rpiboot -d . -j metadataThe BCM2712 will not boot a signed EEPROM image unless it holds the public key in its One Time Programmable (OTP) memory. If you try to boot a signed EEPROM image without burning the public key into OTP:
- The EEPROM firmware will not run and there will be no output on the debug header. The device will not boot.
- On the BCM2712 C1 stepping (found on older Pi 5B models), the boot LED on the Raspberry Pi 5B will display an error code by flashing green 2 times.
- On the BCM2712 D0 stepping (found on Pi 500, CM5, and newer Pi 5Bs), the boot LED will not display an error code, however the device will still not boot.
This is different from the BCM2711 chip used in the Raspberry Pi 4B and CM4. On the BCM2711, it was possible to test out the secure boot flow without making irreversible changes to the OTP. The user could flash a signed pieeprom.bin EEPROM firmware image and test that it would verify the signature of the boot.img file correctly. On the Pi 5, this is not possible.
However, it is possible to check that your signed boot.img file is bootable on the BCM2712. To do this, place the files boot.img and boot.sig in the boot partition of your Raspberry Pi OS image. Then modify the file config.txt on the boot partition to contain the entry boot_ramdisk=1. On the next boot, the Raspberry Pi will unpack the boot.img into memory and treat it as the boot partition.
This output is given by the EEPROM bootloader when it verifies the signature of a boot.img. It can be read over the 3-pin Serial Debug Port. This is accessible via a JST-SH header on the Pi 5B. On the CM5, it is unpopulated on the top side of the board.
3.04 OTP boardrev b04170 bootrom a a
3.06 Customer key hash 8251a63a2edee9d8f710d63e9da5d639064929ce15a2238986a189ac6fcd3cee
3.13 VC-JTAG unlocked
3.36 RP1_BOOT chip ID: 0x20001927
3.41 bootconf.sig
3.41 hash: f71ede8fad8bea2f853bcff41173ffedde48c5b76ed46bc38fa057ce46e5d58b
3.47 rsa2048: 3f215305d5aff620219da94f6f1294787e3a407102a507da96c28e9195d3ccb2f144cac66919f9d86ba9f54a8d20ff57c80d6d269e6e49a16dc23553974489947fe05bf3b7df5cd2c5040a9eebadca754ff4be50600b06fd9f565639adc859d88052e15e0ff6eecf7fec0386d41f81e5d009b04520bb83f17663b62b1271b9d27ec2344c73a20d42dfd68facd741d48c0453e8149448537abfed1d4805872c16182a3e9f25c0b86e002e88949d62c148a561aa8137c257ce0d3e0ae5761aa64c225e9c9782b2bb613de7d90499567c56218bb18a239d4347967b68b3ebd06eaa48215f16316d2a697bb2e67cb3883068f6284e2ca71d25ce0099a1ceb37a85c9
3.94 RSA verify
3.10 rsa-verify pass (0x0)
Metadata output is enabled by default to stdout. Optional argument can be used to specify writing a JSON file to the given directory. This can be useful for debug or for storing in a provisioning database.
Example metadata:
{
"USER_SERIAL_NUM": "a7eb274c",
"MAC_ADDR": "2c:cf:67:70:76:f3",
"EEPROM_UPDATE": "success",
"EEPROM_HASH": "dfc8ef2c77b8152a5cfa008c2296246413fd580fdc26dfacd431e348571a2137",
"SECURE_BOOT_PROVISION": "success",
"CUSTOMER_KEY_HASH": "8251a63a2edee9d8f710d63e9da5d639064929ce15a2238986a189ac6fcd3cee",
"BOOT_ROM": "0000000a",
"BOARD_ATTR": "00000000",
"USER_BOARDREV": "b04170",
"JTAG_LOCKED": "0",
"SIGNATURE_MODE": "0",
"MAC_WIFI_ADDR": "2c:cf:67:70:76:f4",
"MAC_BT_ADDR": "2c:cf:67:70:76:f5",
"FACTORY_UUID": "001000911006186073"
}- Power ON the DUT
After verifying that the signed OS image boots successfully the system can be locked into secure-boot mode. This writes the hash of the customer public key to "one time programmable" (OTP) bits. From then onwards:
- The 2712 boot ROM verifies that the second-stage firmware (recovery.bin / bootsys) is signed with the customer private key in addition to the Raspberry Pi private key.
- The bootloader will only load OS images signed with the customer private key.
- The EEPROM configuration file must be signed with the customer private key.
- It is not possible to downgrade to an old version of the bootloader that doesn't support secure boot.
To enable this, edit the config.txt file in this directory and set program_pubkey=1
before flashing the Pi firmware as described in the section Programming the EEPROM image using rpiboot.
Note that the file config.txt in this directory is unrelated to the config.txt commonly
found in the boot parition of Raspberry Pi OS. The file config.txt in this directory
is used to configure the rpiboot tool.
VideoCore JTAG may be permanently disabled by setting program_jtag_lock in
config.txt. This option has no effect unless the public key hash (program_pubkey) has been successfully programmed.
See config.txt