| 1 | [[PageOutline]] |
| 2 | |
| 3 | = Newport CN803x secure boot |
| 4 | 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). |
| 5 | |
| 6 | ** 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 ** |
| 7 | |
| 8 | See also [wiki:secure_boot] for information on securing the rest of your firmware. |
| 9 | |
| 10 | |
| 11 | [=#bdk] |
| 12 | == Marvell BDK as the SPL |
| 13 | 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. |
| 14 | |
| 15 | The BDK is always built with signed images using keys in the bdk/trust-keys directory: |
| 16 | * hw-rot-public.pem ROTPK (root of trust private key) |
| 17 | - a 256bit hash of this is blown into One Time Programmable fuses for verification of the BDK boot stub and the BDK public key |
| 18 | - erased with a 'make -C bdk distclean' and re-created if needed |
| 19 | - created with: |
| 20 | {{{#!bash |
| 21 | outopenssl ecparam -name prime256v1 -genkey -noout -out bdk/trust-keys/hw-rot-private.pem |
| 22 | }}} |
| 23 | * bdk-sign-private.pem BDK private key |
| 24 | - 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 |
| 25 | - erased with a 'make -C bdk distclean' and re-created if needed |
| 26 | - created with: |
| 27 | {{{#!bash |
| 28 | openssl ecparam -name prime256v1 -genkey -noout -out bdk/trust-keys/bdk-sign-private.pem |
| 29 | }}} |
| 30 | |
| 31 | To build a version of boot firmware in the Newport BSP directory using keys that you create and manage in the ~/keys directory: |
| 32 | {{{#!bash |
| 33 | KEY_DIR=~/keys |
| 34 | # cd to where you have the Newport BSP |
| 35 | cd /usr/src/newport/bsp |
| 36 | # setup your enviroment |
| 37 | . ./setup-environment |
| 38 | # perform a distclean to remove everything including keys |
| 39 | make distclean |
| 40 | # create your private keys (if not already created) |
| 41 | outopenssl ecparam -name prime256v1 -genkey -noout -out $KEY_DIR/hw-rot-private.pem |
| 42 | openssl ecparam -name prime256v1 -genkey -noout -out $KEY_DIR/bdk-sign-private.pem |
| 43 | # copy your keys to the bdk |
| 44 | cp $KEY_DIR/hw-rot-private.pem $KEY_DIR/bdk-sign-private.pem bdk/trust-keys |
| 45 | # build the bdk and firmware |
| 46 | make bdk |
| 47 | make firmware-image |
| 48 | }}} |
| 49 | |
| 50 | To easily obtain the SHA256 of the ROTPK public key you can use: |
| 51 | {{{#!bash |
| 52 | ./newport/getkey.py bdk/trust-keys/hw-rot-private.pem |
| 53 | }}} |
| 54 | |
| 55 | ** |
| 56 | 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. |
| 57 | ** |
| 58 | |
| 59 | [=#dtb] |
| 60 | == Adding signature node to DTB for booting signed FIT images |
| 61 | 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. |
| 62 | |
| 63 | To accomplish this you must alter your board dtb in the boot firmware FATFS using the method discussed in [wiki:secure_boot#fit]. |
| 64 | |
| 65 | 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 |
| 66 | {{{#!bash |
| 67 | # define vars used in commands below |
| 68 | BSP_DIR=/usr/src/newport/bsp |
| 69 | DTB=gw6304-linux.dtb |
| 70 | KEY_DIR=~/keys |
| 71 | KEY_NAME=fit |
| 72 | |
| 73 | # get latest boot firmware |
| 74 | wget http://dev.gateworks.com/newport/boot_firmware/firmware-newport.img |
| 75 | |
| 76 | # extract your DTB to current directory |
| 77 | $BSP_DIR/bin/fatfs-tool -i firmware-newport.img extract /$DTB . |
| 78 | |
| 79 | # use mkimage to apply the key signature node |
| 80 | cat << EOF > dummy.its |
| 81 | /dts-v1/; |
| 82 | |
| 83 | / { |
| 84 | description = "Dummy file for signing board .dtb files"; |
| 85 | #address-cells = <1>; |
| 86 | |
| 87 | /* dummy image just to keep mkimage tool happy */ |
| 88 | images { |
| 89 | kernel@1 { |
| 90 | description = "dummy kernel image"; |
| 91 | data = /incbin/("dummy.bin"); |
| 92 | type = "kernel"; |
| 93 | arch = "arm64"; |
| 94 | os = "linux"; |
| 95 | compression = "none"; |
| 96 | load = <0x0>; |
| 97 | entry = <0x0>; |
| 98 | hash@1 { |
| 99 | algo = "sha256"; |
| 100 | }; |
| 101 | }; |
| 102 | }; |
| 103 | configurations { |
| 104 | default = "config@1"; |
| 105 | config@1 { |
| 106 | description = "Linux configuration"; |
| 107 | kernel = "kernel@1"; |
| 108 | signature@1 { |
| 109 | algo = "sha256,rsa2048"; |
| 110 | key-name-hint = "dummy"; |
| 111 | }; |
| 112 | }; |
| 113 | }; |
| 114 | }; |
| 115 | EOF |
| 116 | touch dummy.bin |
| 117 | # replace dummy placeholders for key-name |
| 118 | sed -i "s;key-name-hint = \"dummy\";key-name-hint = \"$KEY_NAME\";g" dummy.its |
| 119 | # create cert for key |
| 120 | openssl req -batch -new -x509 -key $KEY_DIR/$KEY_NAME.key -out $KEY_DIR/$KEY_NAME.crt |
| 121 | # add signature node to myboard.dtb |
| 122 | $BSP_DIR/bin/mkimage -r -k $KEY_DIR -K $DTB -f dummy.its dummy.itb |
| 123 | |
| 124 | # pad and sign the dtb |
| 125 | BDK_ROOT=$BSP_DIR/bdk $BSP_DIR/bdk/bin/bdk-aes-pad $DTB |
| 126 | BDK_ROOT=$BSP_DIR/bdk $BSP_DIR/bdk/bin/bdk-sign bdk-sign-private $DTB.sign $DTB |
| 127 | |
| 128 | # copy the new dtb and its signature into the FATFS |
| 129 | $BSP_DIR/bin/fatfs-tool -i firmware-newport.img cp $DTB $DTB.sign / |
| 130 | }}} |
| 131 | |
| 132 | |
| 133 | [=#otp] |
| 134 | == Blowing Fuses to lock a device to use trusted boot |
| 135 | |
| 136 | **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.** |
| 137 | |
| 138 | In order to enable trusted boot you must: |
| 139 | * program the ROTPK 256bit hash into OTP |
| 140 | * enable the tz-force bit |
| 141 | * enable the fj-dis bit if you want to disable a fallback to insecure boot firmware if secure boot fails |
| 142 | |
| 143 | The 256bit ROTPK that needs to be used for trusted boot can be found using the following in the Newport BSP directory: |
| 144 | {{{#!bash |
| 145 | ./newport/getkey.py bdk/trust-keys/hw-rot-private.pem |
| 146 | }}} |
| 147 | |
| 148 | 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. |
| 149 | |
| 150 | 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: |
| 151 | * soft blow (for testing) |
| 152 | {{{#!bash |
| 153 | octeontxotp --rotpk $ROTPK |
| 154 | octeontxotp --tz_force |
| 155 | octeontxotp --fj_dis |
| 156 | i2cset -f -y 0 0x20 0 0 # disable power-cycle on reset |
| 157 | octeontxotp --reset |
| 158 | }}} |
| 159 | * hard blow (after testing via soft blow) **this is permanent and you will no longer be able to JTAG program or RMA your board**) |
| 160 | {{{#!bash |
| 161 | octeontxotp --hard --force --rotpk $ROTPK |
| 162 | octeontxotp --hard --force --lock rotpk |
| 163 | octeontxotp --hard --force --tz_force |
| 164 | octeontxotp --hard --force --fj_dis |
| 165 | }}} |