Commit 126b0bb2 authored by Denis Pynkin's avatar Denis Pynkin Committed by Emanuele Aina

secure-boot.md: FIT image signing

Added description how to produce the FIT image and
sign it with `cst` tool.
Signed-off-by: default avatarDenis Pynkin <denis.pynkin@collabora.com>
parent 582a6bdc
......@@ -421,6 +421,146 @@ sh mod_4_mfgtool.sh set_dcd_addr u-boot.imx
cat u-boot.imx csf_uboot.bin > u-boot.imx.signed_usb
```
## Sign kernel images for U-Boot to load
After the successful startup of U-Boot we need to load the Linux kernel,
initramfs and DTB file into the memory. All these bits must be verified before
transferring control to the kernel. With [FIT (Flattened uImage Tree)](https://github.com/u-boot/u-boot/blob/master/doc/uImage.FIT/source_file_format.txt)
format we can use single signed image with kernel, initramfs and DTB
embedded, and this allows to avoid "mix and match" attacks with
mixed versions of kernel, initramfs, DTB and configuration.
The signing procedure for kernel images is split into 2 parts:
- preparation of the kernel image in FIT format
- sign FIT image
### FIT image creation
[U-Boot documentation](https://github.com/u-boot/u-boot/tree/master/doc/uImage.FIT)
contains a lot of details and examples how to create FIT images
for different purposes.
To embed all bits into the single FIT image we need to prepare file in
image tree source format, for Apertis we use simple
[template](https://gitlab.apertis.org/infrastructure/apertis-image-recipes/-/blob/apertis/v2021dev1/sign/imx6/fit_image.template)
containing configuration with 3 entries for kernel, initramfs and DTB respectively.
So values `{{kernel}}`, `{{ramdisk}}` and `{{dtb}}` should be substituted with
absolute or relative path to corresponding files.
Please pay attention to addresses in `load` fields, since the whole
FIT image is loaded into the memory by address `0x12000000` (check the
value of `kernel_addr_r` in U-Boot environment), it is
important to avoid intersections with embedded binaries since they will
be copied to configured memory regions after successful verification.
To create the FIT image you need to have `mkimage` command from the
package `u-boot-tools` compiled with FIT support. With FIT source file
prepared just run `mkimage` and generate the FIT binary:
```
$ mkimage -f vmlinuz.its vmlinuz.itb
FIT description: Apertis armhf kernel with dtb and initramfs
Created: Fri Mar 13 02:23:33 2020
Image 0 (kernel-0)
Description: Linux Kernel
Created: Fri Mar 13 02:23:33 2020
Type: Kernel Image
Compression: uncompressed
Data Size: 4526592 Bytes = 4420.50 KiB = 4.32 MiB
Architecture: ARM
OS: Linux
Load Address: 0x10800000
Entry Point: 0x10800000
Hash algo: sha1
Hash value: 8a64994bdab06d01450560ea229c9f44f1f0af14
Image 1 (ramdisk-0)
Description: ramdisk
Created: Fri Mar 13 02:23:33 2020
Type: RAMDisk Image
Compression: uncompressed
Data Size: 20285185 Bytes = 19809.75 KiB = 19.35 MiB
Architecture: ARM
OS: Linux
Load Address: 0x15000000
Entry Point: unavailable
Hash algo: sha1
Hash value: c12652573d1b301b191cf3e2a318913afc1ae4b7
Image 2 (fdt-0)
Description: Flattened Device Tree blob
Created: Fri Mar 13 02:23:33 2020
Type: Flat Device Tree
Compression: uncompressed
Data Size: 42366 Bytes = 41.37 KiB = 0.04 MiB
Architecture: ARM
Hash algo: sha1
Hash value: ace0dd1dea00568b1c4e6df3fb0420c912e3e091
Default Configuration: 'conf-0'
Configuration 0 (conf-0)
Description: Boot Apertis
Kernel: kernel-0
Init Ramdisk: ramdisk-0
FDT: fdt-0
Hash algo: sha1
Hash value: unavailable
CSF Processed successfully and signed data available in vmlinuz.itb
```
### Signing the FIT image
Now it is time to sign the produced image. The procedure is similar to
signing U-Boot with additional step -- we need to add the **IVT**
(Image Vector Table) for the kernel image. We skip this step for U-Boot
since it is prepared automatically during the build of the bootloader.
The IVT is needed for the HAB ROM and must be the part of the binary, it should
be aligned to `0x1000` boundary.
For instance, if the produced binary is:
```
$ stat -c "%s" vmlinuz.itb
25555173
```
we need to pad the file to nearest aligned value, which is `25559040`:
```
$ objcopy -I binary -O binary --pad-to=25559040 --gap-fill=0x00 vmlinuz.itb vmlinuz-pad.itb
```
The next step is IVT generation for the FIT image and the easiest method is to
use the [`genIVT` script](https://storage.googleapis.com/boundarydevices.com/genIVT)
provided by Boundary Devices with adaptation for padded FIT image:
- Jump Location -- 0x12000000
Here we expect the image will be loaded by U-Boot
- Self Pointer -- 0x13860000 (Jump Location + size of padded image)
Pointer to the IVT table itself, which will place after padded image
- CSF Pointer -- 0x13860020 (Jump Location + size of padded image + size of IVT)
Pointer to signature data, which we will add after IVT
So, the IVT generation is pretty simple:
```
$ perl genIVT
```
it will generate the binary named `ivt.bin` to be added to the image:
```
$ cat vmlinuz-pad.itb ivt.bin > vmlinuz-pad-ivt.itb
```
We need to prepare the config file for signing the padded FIT image with IVT.
This step is absolutely the same as for [U-Boot signing](#sign-uboot-bootloader-such-that-the-rom-can-verify).
Configuration file for FIT image is created from
template [csf_uboot.txt](https://gitlab.apertis.org/infrastructure/apertis-imx-srk/-/blob/master/csf/csf_uboot.txt),
and values in `[Authenticate Data]` section must be the same as used
for IVT calculation -- Jump Location and the size of generated file:
```
[Authenticate Data]
Verification index = 2
# Authenticate Start Address, Offset, Length and file
Blocks = 0x12000000 0x00000000 0x1860020 "vmlinuz-pad-ivt.itb"
```
At last we are able to sign the prepared FIT image:
```
$ cst -i vmlinuz-pad-ivt.csf -o vmlinuz-pad-ivt.bin
CSF Processed successfully and signed data available in vmlinuz-pad-ivt.bin
```
* Integration of PCKS#11 support in the signing process to support HSM devices
* Automated testing of secure boot if possible
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment