├── README.md ├── img ├── boot.png ├── innoviris.png └── itea3.png └── instructions.md /README.md: -------------------------------------------------------------------------------- 1 | # Enabling Verified Boot On Raspberry Pi 3 2 | 3 | 4 | The `instructionS.md` file contains a step-by-step guide to enabling Verified Boot and booting into OPTEE-OS on a Raspberry Pi 3 B+. 5 | 6 | Want more information about this project? Read our [blogpost](https://blog.nviso.be/2019/04/01/enabling-verified-boot-on-raspberry-pi-3/)! 7 | 8 | ## Acknowledgments 9 | 10 | This project was made possible thanks to [Innoviris](http://innoviris.be/) and SCRATch, an [ITEA3](https://itea3.org/) project. 11 | 12 | ![Innoviris logo](img/innoviris.png) 13 | ![ITEA3 logo](img/itea3.png) 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /img/boot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVISOsecurity/VerifiedBootRPi3/580f77e92636e66ea1c1284d60b359db7a021cd4/img/boot.png -------------------------------------------------------------------------------- /img/innoviris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVISOsecurity/VerifiedBootRPi3/580f77e92636e66ea1c1284d60b359db7a021cd4/img/innoviris.png -------------------------------------------------------------------------------- /img/itea3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVISOsecurity/VerifiedBootRPi3/580f77e92636e66ea1c1284d60b359db7a021cd4/img/itea3.png -------------------------------------------------------------------------------- /instructions.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The following instructions will help you build U-Boot and OPTEE-OS for Raspberry Pi 3 B+ on a Linux host and enable Verified boot. 4 | We built this on Ubuntu 18.04.0. 5 | 6 | ## Part 1 - Building OPTEE-OS 7 | 8 | ### Install the prerequisite packages 9 | 10 | ``` 11 | sudo add-apt-repository universe 12 | ``` 13 | ``` 14 | sudo apt-get install android-tools-adb android-tools-fastboot autoconf automake bc bison build-essential cscope curl device-tree-compiler expect flex ftp-upload gdisk iasl libattr1-dev libcap-dev libfdt-dev libftdi-dev libglib2.0-dev libhidapi-dev libncurses5-dev libpixman-1-dev libssl-dev libtool make mtools netcat python-crypto python-serial python-wand unzip uuid-dev xdg-utils xterm xz-utils zlib1g-dev git 15 | ``` 16 | 17 | ### Setup the Repo tool 18 | 19 | ``` 20 | mkdir ~/bin 21 | PATH=~/bin:$PATH 22 | curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo 23 | chmod a+x ~/bin/repo 24 | git config --global user.name "Your Name" 25 | git config --global user.email "Your email" 26 | ``` 27 | 28 | ### Get and build the OPTEE-OS source code and toolchains 29 | 30 | Note: we’re using OPTEE 3.2 because newer versions cause a number of issues with later steps. 31 | 32 | ``` 33 | mkdir -p $HOME/devel/optee 34 | cd $HOME/devel/optee 35 | repo init -u https://github.com/OP-TEE/manifest.git -m rpi3.xml -b 3.2.0 36 | repo sync 37 | cd build 38 | ``` 39 | 40 | We need to fix a dependency issue in the makefile (see [https://github.com/OP-TEE/build/issues/325](https://github.com/OP-TEE/build/issues/325)): 41 | 42 | ``` 43 | git remote add jbech https://github.com/jbech-linaro/build.git 44 | git remote update 45 | git checkout jbech/3.2.0-dependency-fix 46 | ``` 47 | 48 | Then we can build: 49 | 50 | ``` 51 | make toolchains 52 | make 53 | ``` 54 | 55 | ### Downgrade SSL to compile U-Boot with FIT support 56 | 57 | Because of a bug, we need to install an older version of libssl to compile the U-Boot with FIT signing support: 58 | 59 | ``` 60 | apt install libssl1.0-dev -y 61 | ``` 62 | 63 | ## Part 2 - Implementing Verified boot 64 | 65 | ### Create the Image Source File (ITS) 66 | 67 | Next to the `optee` folder, create a new folder - we call it `fit`. 68 | 69 | ``` 70 | mkdir fit 71 | cd fit 72 | ``` 73 | 74 | Now create the file `image.its` and paste the following contents: 75 | 76 | ``` 77 | /dts-v1/; 78 | / { 79 | description = "RPi FIT Image"; 80 | #address-cells = <2>; 81 | images { 82 | kernel-1 { 83 | description = "default kernel"; 84 | data = /incbin/("Image"); 85 | type = "kernel"; 86 | arch = "arm64"; 87 | os = "linux"; 88 | compression = "none"; 89 | load = <0x00080000>; 90 | entry = <0x00080000>; 91 | hash-1 { 92 | algo = "sha1"; 93 | }; 94 | }; 95 | tee-1 { 96 | description = "atf"; 97 | data = /incbin/("optee.bin"); 98 | type = "standalone"; 99 | arch = "arm64"; 100 | compression = "none"; 101 | load = <0x08400000>; 102 | entry = <0x08400000>; 103 | hash-1 { 104 | algo = "sha1"; 105 | }; 106 | }; 107 | fdt-1 { 108 | description = "device tree"; 109 | data = /incbin/("bcm2710-rpi-3-b.dtb"); 110 | type = "flat_dt"; 111 | arch = "arm64"; 112 | compression = "none"; 113 | hash-1 { 114 | algo = "sha1"; 115 | }; 116 | }; 117 | }; 118 | configurations { 119 | default = "config-1"; 120 | config-1 { 121 | description = "default configuration"; 122 | kernel = "kernel-1"; 123 | loadables = "tee-1"; 124 | fdt = "fdt-1"; 125 | signature-1 { 126 | algo = "sha1,rsa2048"; 127 | key-name-hint = "dev"; 128 | sign-images = "fdt", "kernel", "loadables"; 129 | }; 130 | }; 131 | }; 132 | }; 133 | ``` 134 | 135 | ### Create a new key pair 136 | 137 | We need to generate an RSA key pair with OpenSSL to sign our configuration. Generate the keys in directory fit/keys: 138 | 139 | ``` 140 | mkdir keys 141 | openssl genrsa -F4 -out keys/dev.key 2048 142 | openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt 143 | ``` 144 | 145 | ### Copy the DTB and the OPTEE image 146 | 147 | ``` 148 | ln -s ../optee/linux/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb 149 | ln -s ../optee/linux/arch/arm64/boot/Image 150 | ln -s ../optee/arm-trusted-firmware/build/rpi3/debug/optee.bin 151 | cp ../optee/linux/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb bcm2710-rpi-3-b-pubkey.dtb 152 | ``` 153 | 154 | ### Build U-Boot 155 | 156 | ``` 157 | cd ../optee/build 158 | make EXT_DTB=../../fit/bcm2710-rpi-3-b-pubkey.dtb rpi3-u-boot-bin 159 | ``` 160 | 161 | ### Update the U-Boot environment configuration 162 | 163 | Add the following lines at the end of the `optee/build/rpi3/firmware/uboot.env.txt` file: 164 | 165 | ``` 166 | boot_fit=bootm ${fit_addr} 167 | fit_addr=0x1F000000 168 | load_fit=fatload mmc 0:1 ${fit_addr} image.fit 169 | mmcboot_old=run load_kernel; run load_dtb; run load_firmware; run set_bootargs_tty set_bootargs_mmc set_common_args; run boot_it 170 | mmcboot=run load_fit; run set_bootargs_tty set_bootargs_mmc set_common_args; run boot_fit 171 | nfsboot_old=usb start; dhcp ${kernel_addr_r} ${tftpserverip}:Image; dhcp ${fdt_addr_r} ${tftpserverip}:${fdtfile}; dhcp ${atf_load_addr} ${tftpserverip}:${atf_file}; run set_bootargs_tty set_bootargs_nfs set_common_args; run boot_it 172 | nfsboot=usb start; dhcp ${fit_addr} ${tftpserverip}:image.fit; run set_bootargs_tty set_bootargs_nfs set_common_args; run boot_fit 173 | ``` 174 | 175 | ### Enable FIT support 176 | 177 | Add the following lines to the `optee/u-boot/configs/rpi_3_defconfig` file: 178 | 179 | ``` 180 | CONFIG_OF_CONTROL=y 181 | CONFIG_FIT=y 182 | CONFIG_FIT_SIGNATURE=y 183 | CONFIG_RSA=y 184 | ``` 185 | 186 | Add the following line to support larger FIT images in the file `optee/u-boot/include/configs/rpi.h`: 187 | 188 | ``` 189 | #define CONFIG_SYS_BOOTM_LEN (16 << 20) 190 | ``` 191 | 192 | The relevant part should look like this: 193 | 194 | ``` 195 | /* ATAGs support for bootm/bootz */ 196 | #define CONFIG_SETUP_MEMORY_TAGS 197 | #define CONFIG_CMDLINE_TAG 198 | #define CONFIG_INITRD_TAG 199 | #define CONFIG_SYS_BOOTM_LEN (16 << 20) 200 | ``` 201 | 202 | ### Create and sign the FIT image 203 | 204 | ``` 205 | cd ../../fit 206 | ../optee/u-boot/tools/mkimage -f image.its image.fit 207 | ../optee/u-boot/tools/mkimage -F -k keys/ -K bcm2710-rpi-3-b-pubkey.dtb -r image.fit 208 | ``` 209 | 210 | ### Rebuild the U-Boot binary with the DTB containing the public key 211 | 212 | ``` 213 | make u-boot-clean rpi3-u-boot-bin-clean rpi3-head-bin-clean 214 | make EXT_DTB=../../fit/bcm2710-rpi-3-b-pubkey.dtb u-boot rpi3-u-boot-bin 215 | ``` 216 | 217 | ## Part 3 - Preparing the SD card 218 | 219 | ### Partition the SD card 220 | 221 | Tip: If you’re using a VM, you can mount the SD card as a hard disk. 222 | 223 | 224 | ``` 225 | fdisk /dev/sdx # where sdx is the name of your sd-card 226 | > p # prints partition table 227 | > d # repeat until all partitions are deleted 228 | > n # create a new partition 229 | > p # create primary 230 | > 1 # make it the first partition 231 | > # use the default sector 232 | > +128M # create a boot partition with 32MB of space 233 | > n # create rootfs partition 234 | > p 235 | > 2 236 | > 237 | > # fill the remaining disk, adjust size to fit your needs 238 | > t # change partition type 239 | > 1 # select first partition 240 | > e # use type 'e' (FAT16) 241 | > a # make partition bootable 242 | > 1 # select first partition 243 | > p # double check everything looks right 244 | > w # write partition table to disk. 245 | ``` 246 | 247 | ### Format the SD card and copy files 248 | 249 | Format the SD card and copy the files to the boot and rootfs partitions. 250 | 251 | **Note: Make sure to replace sdX1 and sdX2 with the correct partitions in your system.** 252 | 253 | ``` 254 | mkfs.vfat -F16 -n BOOT /dev/sdX1 255 | mkdir -p /media/boot 256 | mount /dev/sdX1 /media/boot 257 | cd /media 258 | gunzip -cd /root/devel/optee/build/../out-br/images/rootfs.cpio.gz | sudo cpio -idmv "boot/*" 259 | umount boot 260 | ``` 261 | 262 | ``` 263 | mkfs.ext4 -L rootfs /dev/sdX2 264 | mkdir -p /media/rootfs 265 | mount /dev/sdX2 /media/rootfs 266 | cd rootfs 267 | gunzip -cd /root/devel/optee/build/../out-br/images/rootfs.cpio.gz | sudo cpio -idmv 268 | rm -rf /media/rootfs/boot/* 269 | cd .. && umount rootfs 270 | ``` 271 | 272 | ``` 273 | mkdir -p /media/boot 274 | mount /dev/sdX1 /media/boot 275 | cd /media/boot/ 276 | cp /root/devel/optee/out/uboot.env . 277 | cp /root/devel/optee/u-boot/u-boot-rpi.bin . 278 | cp /root/devel/fit/image.fit . 279 | cd .. && umount /dev/sdX1 280 | ``` 281 | 282 | ## Part 4 - Test! 283 | 284 | Insert your SD card in the RPi3. If everything went smoothly and Verified Boot was correctly configured, output from U-Boot should look like this: 285 | 286 | ![Boot output](img/boot.png) 287 | 288 | The important part is the rsa2048:dev+ OK, which shows that the configuration signature verification was performed succesfully. 289 | 290 | 291 | 292 | 293 | 294 | --------------------------------------------------------------------------------