[[PageOutline]] = Newport CN803x secure boot Trusted Mode Boot is the hardware and firmware implementation of secure boot for the CN803x based on the [https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/trusted-board-boot.rst ARM Trusted Board Boot Requirements (TBBR) specification] described in the [https://github.com/ARM-software/arm-trusted-firmware ARM Trusted Firmware]. It utilizes the [https://developer.arm.com/technologies/trustzone 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@gateworks.com if you wish to use Trusted boot on a Gateworks Custom or Special ** * -AUC (Secure Boot without Crypto) * -AUS (Secure Boot with Crypto) * -SCP (No Secure Boot with Crypto) See also [wiki:secure_boot] for information on securing the rest of your firmware. For more information see: - Cavium OCTEON TX Trusted-Mode Boot PDF (Obtain from Cavium under NDA) - [https://developer.arm.com/documentation/den0006/d/ ARM Trusted Board Boot Requirements (TBBR) specification] - [https://github.com/ARM-software/arm-trusted-firmware ARM Trusted Firmware] - [https://developer.arm.com/technologies/trustzone ARM TrustZone] [=#bdk] == 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: {{{#!bash 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: {{{#!bash 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: {{{#!bash 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: {{{#!bash ./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. ** [=#dtb] == 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 [wiki:secure_boot#fit]). 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 [wiki:secure_boot#fit]. 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 {{{#!bash # 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 / }}} [=#otp] == 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: {{{#!bash ./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) {{{#!bash 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**) {{{#!bash octeontxotp --hard --force --rotpk $ROTPK octeontxotp --hard --force --lock rotpk octeontxotp --hard --force --tz_force octeontxotp --hard --force --fj_dis }}}