| | 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 | }}} |