Secure boot on RK3566 68 88 - madisongh/meta-rk3588 GitHub Wiki
As of this writing, version 3.0.0 of the Rockchip Linux Secure Boot Developer Guide appears to be the most up-to-date reference for how secure boot is implemented on the Rockchip SoCs.
This page covers only the RK3566/68/88 SoCs with the 5.10-based Linux kernel, using U-Boot FIT images, as implemented in this layer.
Signing steps
The following boot-time artifacts must be signed with the correct key when the SoC is set for secure boot:
- First-stage bootloader package (
idblock.img) - Second-stage bootloader/TOS bundle (the U-Boot FIT image)
- Linux kernel (kernel FIT image)
- USB loader (for flashing from MaskROM mode on the target device)
The FIT image signing support in OE-Core cannot currently be used directly for Rockchip targets due to the following:
- Differences in RSA key handling in the Rockchip downstream U-Boot fork, which is also needed in the U-Boot
mkimagetool - The Rockchip-provided scripts/tools for combining the U-Boot components built from source with the binary-only boot/trust components from the
rkbinrepository, and signing those artifacts, must be run within the U-Boot build tree
So the linux-rockchip-downstream and uboot-rockchip-downstream recipes here use modified copies of the more general bbclasses present in OE-Core.
Signing order
There are some tricky dependencies when FIT signing is used, since the mkimage tool updates the DTB of the bootloader with the public key corresponding to the private key used for signing the FIT. At build time, this means:
- The u-boot recipe must be compiled first, to generate the DTBs for the SPL and main u-boot image.
- The kernel FIT image can then be assembled and signed. Signing that FIT image updates the u-boot DTB.
- The u-boot/TOS bundle FIT image can then be assembled and signed. Signing that FIT image updates the SPL DTB.
- The SPL can then be created (combining the SPL code with modified SPL DTB) and used to create the
idblock.imgfirst-stage loader, which is then signed usingrk_sign_tool. - If the USB loader also uses a built SPL (as it does on the RK3588), that loader can then be built, importing the modified SPL DTB from the above step. The resulting loader binary is then signed using
rk_sign_tool.
This ensures that at boot time, the DTB at the SPL stage contains the public key used to verify the signature of the U-Boot FIT, and the DTB in the U-Boot FIT contains the public key used to verify the signature on the kernel FIT.
Enabling signing during boot
The RK_SECURE_BOOT variable controls whether the bootloaders and kernel should be signed. Set that variable to "1" (or some other boolean true equivalent) in your build configuration to enable signing.
Key selection and generation
The same variables used by the OE-Core U-Boot signing support can be used here for locating the RSA keypair to be used during signing. Note that while it might be possible to use separate keys for signing the idblock.img, the U-Boot FIT, and the kernel FIT (and, theoretically, other algorithms than RSA2048/SHA256 with PSS padding for the latter two), the current implementation assumes you are using the same algorithm and keypair for all three (named "dev").
| Variable | Default | Description |
|---|---|---|
| SPL_SIGN_KEYDIR | ${TOPDIR}/signing-keys |
Location of the RSA key files for signing the U-Boot/TOS FIT image and first-stage bootloader |
| UBOOT_SIGN_KEYDIR | ${SPL_SIGN_KEYDIR} |
Location of the RSA key files for signing the kernel FIT image |
| UBOOT_FIT_GENERATE_KEYS | "0" |
Set this to "1" to have the RSA key files generated automatically during the build |
Testing signed builds before enabling secure boot
You can load signed builds onto the Rockchip device without burning a key into the chip's OTP; using dynamically-generated keys makes this relatively simple. Signature verification will still happen (when the SPL loads the U-Boot FIT, and when U-Boot loads the kernel FIT) -- you will see mentions of the rsa2048,sha256 algorithms on the serial console during boot.
Enabling secure boot on the target device
Before enabling secure boot on your target device, which is a one-time, irreversible operation, you should have
- tested the image verification process,
- securely saved the keys you used (or generated during your test build), and
- implemented a process for securely retrieving them into the
xxx_SIGN_KEYDIRdirectory for your builds before you set the device for secure boot
When you are sure you're ready to set your target for secure boot, set the RK_SIGN_BURN_KEY_HASH variable to "1" (or some other boolean true value) in your build configuration. Setting this variable to a true value causes the SPL DTB to be updated with the burn-key-hash property (set to the value 1) during the build. When the SPL sees this property set to a non-zero value in the SPL DTB, it will:
- program a hash of the RSA public key used to validate the U-Boot FIT image into the OTP (only if it hasn't already been programmed)
- set the secure-boot flag in the OTP (only if it is not already set)
This is done only after the U-Boot FIT signature has been verified. If successful, you should see
RSA: Write key hash successfullyon the serial console during SPL execution.
See the rsa_burn_key_hash function in lib/rsa/rsa-verify.c in the Rockchip U-Boot sources for specifics.
On subsequent boots, the boot ROM will require the idblock.img or USB loader image to be signed with the RSA key corresponding to the hash in the OTP, and will switch to MaskROM mode if it cannot locate a correctly signed first-stage bootloader. The SPL and U-Boot loaders should also display ## Verified-boot: 1 (instead of : 0) while loading the next-stage FIT.