wiki:newport/secure_boot

Version 2 (modified by Tim Harvey, 17 months ago) (diff)

added additional references

Newport CN803x secure boot

Trusted Mode Boot is the hardware and firmware implementation of secure boot for the CN803x based on the ARM Trusted Board Boot Requirements (TBBR) specification described in the ARM Trusted Firmware. It utilizes the ARM TrustZone architecture and the ARM Trusted Firmware (ATF).

Note that trusted boot on CN803x requires the -AUC (Secure Boot without Crypto) or -AUS (Secure Boot with Crypto) variant of the CN80XX processor which is not on Newport standard product boards. The standard Newport boards have the -SCP variant which has Crypto but no Secure Boot. Non AUC/AUS parts will come with the OTP fuses locked from the factory such that the ROTPK (Root of Trust Private Key) and others can not be programmed. Contact sales@… if you wish to use Trusted boot on a Gateworks Custom or Special

See also secure_boot for information on securing the rest of your firmware.

For more information see:

Marvell BDK as the SPL

The boot code loaded by the CN803x BOOT ROM is the Marvell BDK which we use as a Secondary Program Loader (SPL) in order to load the board DTB, ARM Trusted Firmware (ATF), and U-boot propper.

The BDK is always built with signed images using keys in the bdk/trust-keys directory:

  • hw-rot-public.pem ROTPK (root of trust private key)
    • a 256bit hash of this is blown into One Time Programmable fuses for verification of the BDK boot stub and the BDK public key
    • erased with a 'make -C bdk distclean' and re-created if needed
    • created with:
      outopenssl ecparam -name prime256v1 -genkey -noout -out bdk/trust-keys/hw-rot-private.pem
      
  • bdk-sign-private.pem BDK private key
    • used to sign and validate all files within the FATFS including board DTB's, various applications of the BDK, and the ATF and U-Boot FIP package
    • erased with a 'make -C bdk distclean' and re-created if needed
    • created with:
      openssl ecparam -name prime256v1 -genkey -noout -out bdk/trust-keys/bdk-sign-private.pem
      

To build a version of boot firmware in the Newport BSP directory using keys that you create and manage in the ~/keys directory:

KEY_DIR=~/keys
# cd to where you have the Newport BSP
cd /usr/src/newport/bsp
# setup your enviroment
. ./setup-environment
# perform a distclean to remove everything including keys
make distclean
# create your private keys (if not already created)
outopenssl ecparam -name prime256v1 -genkey -noout -out $KEY_DIR/hw-rot-private.pem
openssl ecparam -name prime256v1 -genkey -noout -out $KEY_DIR/bdk-sign-private.pem
# copy your keys to the bdk
cp $KEY_DIR/hw-rot-private.pem $KEY_DIR/bdk-sign-private.pem bdk/trust-keys
# build the bdk and firmware
make bdk
make firmware-image

To easily obtain the SHA256 of the ROTPK public key you can use:

./newport/getkey.py bdk/trust-keys/hw-rot-private.pem

The hw-rot-private.pem and bdk-sign-private.pem files must be stored in a secure database preferably indexed by board serial number in case you even need to change them.

Adding signature node to DTB for booting signed FIT images

To add the kernel, fdt, and ramdisk to the chain of trust you can use a signed fit image (see secure_boot). This requires that the FDT controlling U-Boot have a signature node containing the key data used to verify the FIT image.

To accomplish this you must alter your board dtb in the boot firmware FATFS using the method discussed in secure_boot.

You can do this using the fatfs-tool which is built by the Newport BSP. For example, if your board is a GW6304 thus uses the gw6304-linux.dtb, your Newport BSP is in /usr/src/newport/bsp, and your FIT key is ~/keys/fit.key

# define vars used in commands below
BSP_DIR=/usr/src/newport/bsp
DTB=gw6304-linux.dtb
KEY_DIR=~/keys
KEY_NAME=fit

# get latest boot firmware
wget http://dev.gateworks.com/newport/boot_firmware/firmware-newport.img

# extract your DTB to current directory
$BSP_DIR/bin/fatfs-tool -i firmware-newport.img extract /$DTB .

# use mkimage to apply the key signature node
cat << EOF > dummy.its
/dts-v1/;

/ {
        description = "Dummy file for signing board .dtb files";
        #address-cells = <1>;

        /* dummy image just to keep mkimage tool happy */
        images {
                kernel@1 {
                        description = "dummy kernel image";
                        data = /incbin/("dummy.bin");
                        type = "kernel";
                        arch = "arm64";
                        os = "linux";
                        compression = "none";
                        load = <0x0>;
                        entry = <0x0>;
                        hash@1 {
                                algo = "sha256";
                        };
                };
        };
        configurations {
                default = "config@1";
                config@1 {
                        description = "Linux configuration";
                        kernel = "kernel@1";
                        signature@1 {
                                algo = "sha256,rsa2048";
                                key-name-hint = "dummy";
                        };
                };
        };
};
EOF
touch dummy.bin
# replace dummy placeholders for key-name
sed -i "s;key-name-hint = \"dummy\";key-name-hint = \"$KEY_NAME\";g" dummy.its
# create cert for key
openssl req -batch -new -x509 -key $KEY_DIR/$KEY_NAME.key -out $KEY_DIR/$KEY_NAME.crt
# add signature node to myboard.dtb
$BSP_DIR/bin/mkimage -r -k $KEY_DIR -K $DTB -f dummy.its dummy.itb

# pad and sign the dtb
BDK_ROOT=$BSP_DIR/bdk $BSP_DIR/bdk/bin/bdk-aes-pad $DTB
BDK_ROOT=$BSP_DIR/bdk $BSP_DIR/bdk/bin/bdk-sign bdk-sign-private $DTB.sign $DTB

# copy the new dtb and its signature into the FATFS
$BSP_DIR/bin/fatfs-tool -i firmware-newport.img cp $DTB $DTB.sign /

Blowing Fuses to lock a device to use trusted boot

Important Note: Once boards have been configured for trusted-mode boot by hard blowing fuses the JTAG chain is disabled and boards can not be re-tested by Gateworks and as a result returns (RMA) will not be accepted. It is recommended that OEM's test board functionality before permanently setting trusted-mode boot fuses.

In order to enable trusted boot you must:

  • program the ROTPK 256bit hash into OTP
  • enable the tz-force bit
  • enable the fj-dis bit if you want to disable a fallback to insecure boot firmware if secure boot fails

The 256bit ROTPK that needs to be used for trusted boot can be found using the following in the Newport BSP directory:

./newport/getkey.py bdk/trust-keys/hw-rot-private.pem

Before doing this permanently there is a way to 'soft' blow the fuses where you can perform a warm reset to verify everything boots as expected.

Gateworks provides an octeontxotp application on its pre-built buildroot based minimal kernel+ramdisk that can be used for provisioning boards. This program can be used to blow the fuses necessary to enable trusted boot:

  • soft blow (for testing)
    octeontxotp --rotpk $ROTPK
    octeontxotp --tz_force
    octeontxotp --fj_dis
    i2cset -f -y 0 0x20 0 0 # disable power-cycle on reset
    octeontxotp --reset
    
  • hard blow (after testing via soft blow) this is permanent and you will no longer be able to JTAG program or RMA your board)
    octeontxotp --hard --force --rotpk $ROTPK
    octeontxotp --hard --force --lock rotpk
    octeontxotp --hard --force --tz_force
    octeontxotp --hard --force --fj_dis