[U-Boot] [PATCH v2 1/3] sunxi: a64: Enable FIT Signature

Enable FIT_SIGNATURE for sunxi a64.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- Changes for v2: - Use imply instead of select
arch/arm/mach-sunxi/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 09cfec6..9ee356f 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -178,6 +178,7 @@ config MACH_SUN50I select SUNXI_DRAM_DW select SUNXI_DRAM_DW_32BIT select FIT + imply FIT_SIGNATURE select SPL_LOAD_FIT
config MACH_SUN50I_H5

The default value of CONFIG_SYS_BOOTM_LEN, 0x800000, causes error when uncompressing Image.gz out of FIT image.
Uncompressing Kernel Image ... Error: inflate() returned -5 Image too large: increase CONFIG_SYS_BOOTM_LEN
and loading Image out of FIT image. Loading Kernel Image ... Image too large: increase CONFIG_SYS_BOOTM_LEN Must RESET board to recover
Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- Changes for v2: - Add in separate patch with proper commit message
include/configs/sunxi-common.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 4391a8c..2bdbc2a 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -34,6 +34,7 @@
#ifdef CONFIG_ARM64 #define CONFIG_BUILD_TARGET "u-boot.itb" +#define CONFIG_SYS_BOOTM_LEN (32 << 20) #endif
/* Serial & console */

Add verified-boot documentation for sunxi a64 platform.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- Changes for v2: - New patch
board/sunxi/README.sunxi64 | 177 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+)
diff --git a/board/sunxi/README.sunxi64 b/board/sunxi/README.sunxi64 index c492f74..5a2fe69 100644 --- a/board/sunxi/README.sunxi64 +++ b/board/sunxi/README.sunxi64 @@ -160,6 +160,183 @@ Then write this image to a microSD card, replacing /dev/sdx with the right device file (see above): $ dd if=firmware.img of=/dev/sdx bs=8k seek=1
+Verified Boot +============= + +U-Boot supports an image verification method called "Verified Boot". +This is a brief tutorial to utilize this feature for the Sunxi A64 platform. +You will find details documents in the doc/uImage.FIT directory. + +Here, we take Orangepi Win board for example, but it should work for any +other boards including 32 bit SoCs. + +1. Generate RSA key to sign + + $ mkdir keys + $ openssl genpkey -algorithm RSA -out keys/dev.key \ + -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 + $ openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt + +Two files "dev.key" and "dev.crt" will be created. The base name is arbitrary, +but need to match to the "key-name-hint" property described below. + +2. FIT Input + +---------------------------------------->8---------------------------------------- +/dts-v1/; +/ { + description = "FIT image with single Linux kernel, FDT blob"; + #address-cells = <1>; + + images { + kernel@0 { + description = "ARM64 Linux kernel"; + data = /incbin/("/path/to/linux/dir/arch/arm64/boot/Image.gz"); + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "gzip"; + load = <0x50080000>; + entry = <0x50080000>; + hash@1 { + algo = "sha256"; + }; + }; + + fdt@0 { + description = "Orangepi Win/Win+ Devicetree blob"; + data = /incbin/("/path/to/linux/dir/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dtb"); + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + hash@1 { + algo = "sha256"; + }; + }; + }; + + configurations { + default = "conf@0"; + + conf@0 { + description = "Boot Linux kernel, FDT blob"; + kernel = "kernel@0"; + fdt = "fdt@0"; + signature@0 { + algo = "sha256,rsa2048"; + key-name-hint = "dev"; + sign-images = "kernel", "fdt"; + }; + }; + }; +}; +---------------------------------------->8---------------------------------------- + +You need to change the two '/incbin/' lines, depending on the location of +your kernel image and devicetree blob. The "load" and "entry" properties also +need to be adjusted if you want to change the physical placement of the kernel. + +The "key-name-hint" must specify the key name you have created in the step 1. + +The FIT file name is arbitrary. Let's say you saved it into "fit.its". + +3. Compile U-Boot with FIT and signature enabled + +To use the Verified Boot, you need to enable the following two options: + CONFIG_FIT + CONFIG_FIT_SIGNATURE + + $ make orangepi_win_defconfig + $ make CROSS_COMPILE=aarch64-linux-gnu- + +4. FIT Output + +After building U-Boot, you will see tools/mkimage. With this tool, you can +create an image tree blob as follows: + + $ tools/mkimage -f fit.its -k keys -K dts/dt.dtb -r -F fitImage + +The -k option must specify the key directory you have created in step 1. + +A file "fitImage" will be created. This includes kernel, DTB, +hash data for each of the three, and signature data. + +The public key needed for the run-time verification is stored in "dts/dt.dtb". + +5. Compile Verified U-Boot + +Since the "dt.dtb" has been updated in step 4, you need to re-compile the +U-Boot. + + $ make CROSS_COMPILE=aarch64-linux-gnu- + +The re-compiled "u-boot.bin" is appended with DTB that contains the public key. + +6. Flash the image + +Flash the "fitImage" to a storage device (SD, NAND, eMMC, or whatever) on your +board. + +7. Boot verified kernel + +Load the fitImage to memory and run the following from the U-Boot command line. + + > bootm <addr> + +Here, <addr> is the base address of the fitImage. + +If it is successful, you will see messages like follows: + +---------------------------------------->8---------------------------------------- +=> setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p1 rootwait +=> ext4load mmc 0:1 $kernel_addr_r /boot/fitImage +16321738 bytes read in 1049 ms (14.8 MiB/s) +=> bootm $kernel_addr_r +## Loading kernel from FIT Image at 40080000 ... + Using 'conf@0' configuration + Verifying Hash Integrity ... OK + Trying 'kernel@0' kernel subimage + Description: ARM64 Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x400800e4 + Data Size: 6884659 Bytes = 6.6 MiB + Architecture: AArch64 + OS: Linux + Load Address: 0x50080000 + Entry Point: 0x50080000 + Hash algo: sha256 + Hash value: 6808fe51ea3c15f31c4510d2701d4707b56d20213c9da05bce79fb53bf108f1a + Verifying Hash Integrity ... sha256+ OK +## Loading fdt from FIT Image at 40080000 ... + Using 'conf@0' configuration + Trying 'fdt@0' fdt subimage + Description: Orangepi Win/Win+ Devicetree blob + Type: Flat Device Tree + Compression: uncompressed + Data Start: 0x40710f24 + Data Size: 9032 Bytes = 8.8 KiB + Architecture: AArch64 + Hash algo: sha256 + Hash value: ca3d874cd10466633ff133cc0156828d48c8efb96987fa45f885761d22a25dc1 + Verifying Hash Integrity ... sha256+ OK + Booting using the fdt blob at 0x40710f24 + Uncompressing Kernel Image ... OK + Loading Device Tree to 0000000049ffa000, end 0000000049fff347 ... OK + +Starting kernel ... +---------------------------------------->8---------------------------------------- + +Please pay attention to the lines that start with "Verifying Hash Integrity". + +"Verifying Hash Integrity ... sha256,rsa2048:dev+ OK" means the signature check +passed. + +"Verifying Hash Integrity ... sha256+ OK" (2 times) means the hash check passed +for kernel and DTB. + +If they are not displayed, the Verified Boot is not working. + [1] https://github.com/apritzel/arm-trusted-firmware.git [2] git://github.com/linux-sunxi/sunxi-tools.git [3] https://github.com/apritzel/pine64/

Hi,
On Fri, Nov 10, 2017 at 10:21:10PM +0530, Jagan Teki wrote:
Add verified-boot documentation for sunxi a64 platform.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com
Changes for v2:
- New patch
board/sunxi/README.sunxi64 | 177 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+)
diff --git a/board/sunxi/README.sunxi64 b/board/sunxi/README.sunxi64 index c492f74..5a2fe69 100644 --- a/board/sunxi/README.sunxi64 +++ b/board/sunxi/README.sunxi64 @@ -160,6 +160,183 @@ Then write this image to a microSD card, replacing /dev/sdx with the right device file (see above): $ dd if=firmware.img of=/dev/sdx bs=8k seek=1
+Verified Boot +=============
+U-Boot supports an image verification method called "Verified Boot". +This is a brief tutorial to utilize this feature for the Sunxi A64 platform. +You will find details documents in the doc/uImage.FIT directory.
+Here, we take Orangepi Win board for example, but it should work for any +other boards including 32 bit SoCs.
It should be in another file then I guess?
+1. Generate RSA key to sign
- $ mkdir keys
- $ openssl genpkey -algorithm RSA -out keys/dev.key \
- -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537
- $ openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt
+Two files "dev.key" and "dev.crt" will be created. The base name is arbitrary, +but need to match to the "key-name-hint" property described below.
+2. FIT Input
+---------------------------------------->8---------------------------------------- +/dts-v1/; +/ {
- description = "FIT image with single Linux kernel, FDT blob";
- #address-cells = <1>;
- images {
kernel@0 {
description = "ARM64 Linux kernel";
data = /incbin/("/path/to/linux/dir/arch/arm64/boot/Image.gz");
type = "kernel";
arch = "arm64";
os = "linux";
compression = "gzip";
load = <0x50080000>;
entry = <0x50080000>;
hash@1 {
algo = "sha256";
};
};
fdt@0 {
description = "Orangepi Win/Win+ Devicetree blob";
data = /incbin/("/path/to/linux/dir/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dtb");
type = "flat_dt";
arch = "arm64";
compression = "none";
hash@1 {
algo = "sha256";
};
};
- };
- configurations {
default = "conf@0";
conf@0 {
description = "Boot Linux kernel, FDT blob";
kernel = "kernel@0";
fdt = "fdt@0";
signature@0 {
algo = "sha256,rsa2048";
key-name-hint = "dev";
sign-images = "kernel", "fdt";
};
};
- };
+}; +---------------------------------------->8----------------------------------------
+You need to change the two '/incbin/' lines, depending on the location of +your kernel image and devicetree blob. The "load" and "entry" properties also +need to be adjusted if you want to change the physical placement of the kernel.
+The "key-name-hint" must specify the key name you have created in the step 1.
+The FIT file name is arbitrary. Let's say you saved it into "fit.its".
+3. Compile U-Boot with FIT and signature enabled
+To use the Verified Boot, you need to enable the following two options:
- CONFIG_FIT
- CONFIG_FIT_SIGNATURE
- $ make orangepi_win_defconfig
- $ make CROSS_COMPILE=aarch64-linux-gnu-
+4. FIT Output
+After building U-Boot, you will see tools/mkimage. With this tool, you can +create an image tree blob as follows:
- $ tools/mkimage -f fit.its -k keys -K dts/dt.dtb -r -F fitImage
+The -k option must specify the key directory you have created in step 1.
+A file "fitImage" will be created. This includes kernel, DTB, +hash data for each of the three, and signature data.
+The public key needed for the run-time verification is stored in "dts/dt.dtb".
+5. Compile Verified U-Boot
+Since the "dt.dtb" has been updated in step 4, you need to re-compile the +U-Boot.
- $ make CROSS_COMPILE=aarch64-linux-gnu-
+The re-compiled "u-boot.bin" is appended with DTB that contains the public key.
+6. Flash the image
+Flash the "fitImage" to a storage device (SD, NAND, eMMC, or whatever) on your +board.
+7. Boot verified kernel
+Load the fitImage to memory and run the following from the U-Boot command line.
bootm <addr>+Here, <addr> is the base address of the fitImage.
+If it is successful, you will see messages like follows:
+---------------------------------------->8---------------------------------------- +=> setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p1 rootwait +=> ext4load mmc 0:1 $kernel_addr_r /boot/fitImage +16321738 bytes read in 1049 ms (14.8 MiB/s) +=> bootm $kernel_addr_r +## Loading kernel from FIT Image at 40080000 ...
- Using 'conf@0' configuration
- Verifying Hash Integrity ... OK
- Trying 'kernel@0' kernel subimage
Description: ARM64 Linux kernel
Type: Kernel Image
Compression: gzip compressed
Data Start: 0x400800e4
Data Size: 6884659 Bytes = 6.6 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x50080000
Entry Point: 0x50080000
Hash algo: sha256
Hash value: 6808fe51ea3c15f31c4510d2701d4707b56d20213c9da05bce79fb53bf108f1a
- Verifying Hash Integrity ... sha256+ OK
+## Loading fdt from FIT Image at 40080000 ...
- Using 'conf@0' configuration
- Trying 'fdt@0' fdt subimage
Description: Orangepi Win/Win+ Devicetree blob
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x40710f24
Data Size: 9032 Bytes = 8.8 KiB
Architecture: AArch64
Hash algo: sha256
Hash value: ca3d874cd10466633ff133cc0156828d48c8efb96987fa45f885761d22a25dc1
- Verifying Hash Integrity ... sha256+ OK
- Booting using the fdt blob at 0x40710f24
- Uncompressing Kernel Image ... OK
- Loading Device Tree to 0000000049ffa000, end 0000000049fff347 ... OK
+Starting kernel ... +---------------------------------------->8----------------------------------------
+Please pay attention to the lines that start with "Verifying Hash Integrity".
+"Verifying Hash Integrity ... sha256,rsa2048:dev+ OK" means the signature check +passed.
+"Verifying Hash Integrity ... sha256+ OK" (2 times) means the hash check passed +for kernel and DTB.
+If they are not displayed, the Verified Boot is not working.
One thing that we should make *really* clear is that it will sign only the kernel and device trees, but it's far from sufficient to implement a full fledged secure boot, and you shouldn't consider your device protected. At least the signature of the SPL and the U-Boot binary are missing to implement something that would have a chance to qualify.
Maxime

On Mon, Nov 13, 2017 at 2:45 PM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
Hi,
On Fri, Nov 10, 2017 at 10:21:10PM +0530, Jagan Teki wrote:
Add verified-boot documentation for sunxi a64 platform.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com
Changes for v2:
- New patch
board/sunxi/README.sunxi64 | 177 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+)
diff --git a/board/sunxi/README.sunxi64 b/board/sunxi/README.sunxi64 index c492f74..5a2fe69 100644 --- a/board/sunxi/README.sunxi64 +++ b/board/sunxi/README.sunxi64 @@ -160,6 +160,183 @@ Then write this image to a microSD card, replacing /dev/sdx with the right device file (see above): $ dd if=firmware.img of=/dev/sdx bs=8k seek=1
+Verified Boot +=============
+U-Boot supports an image verification method called "Verified Boot". +This is a brief tutorial to utilize this feature for the Sunxi A64 platform. +You will find details documents in the doc/uImage.FIT directory.
+Here, we take Orangepi Win board for example, but it should work for any +other boards including 32 bit SoCs.
It should be in another file then I guess?
+1. Generate RSA key to sign
- $ mkdir keys
- $ openssl genpkey -algorithm RSA -out keys/dev.key \
- -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537
- $ openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt
+Two files "dev.key" and "dev.crt" will be created. The base name is arbitrary, +but need to match to the "key-name-hint" property described below.
+2. FIT Input
+---------------------------------------->8---------------------------------------- +/dts-v1/; +/ {
description = "FIT image with single Linux kernel, FDT blob";
#address-cells = <1>;
images {
kernel@0 {
description = "ARM64 Linux kernel";
data = /incbin/("/path/to/linux/dir/arch/arm64/boot/Image.gz");
type = "kernel";
arch = "arm64";
os = "linux";
compression = "gzip";
load = <0x50080000>;
entry = <0x50080000>;
hash@1 {
algo = "sha256";
};
};
fdt@0 {
description = "Orangepi Win/Win+ Devicetree blob";
data = /incbin/("/path/to/linux/dir/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dtb");
type = "flat_dt";
arch = "arm64";
compression = "none";
hash@1 {
algo = "sha256";
};
};
};
configurations {
default = "conf@0";
conf@0 {
description = "Boot Linux kernel, FDT blob";
kernel = "kernel@0";
fdt = "fdt@0";
signature@0 {
algo = "sha256,rsa2048";
key-name-hint = "dev";
sign-images = "kernel", "fdt";
};
};
};
+}; +---------------------------------------->8----------------------------------------
+You need to change the two '/incbin/' lines, depending on the location of +your kernel image and devicetree blob. The "load" and "entry" properties also +need to be adjusted if you want to change the physical placement of the kernel.
+The "key-name-hint" must specify the key name you have created in the step 1.
+The FIT file name is arbitrary. Let's say you saved it into "fit.its".
+3. Compile U-Boot with FIT and signature enabled
+To use the Verified Boot, you need to enable the following two options:
- CONFIG_FIT
- CONFIG_FIT_SIGNATURE
- $ make orangepi_win_defconfig
- $ make CROSS_COMPILE=aarch64-linux-gnu-
+4. FIT Output
+After building U-Boot, you will see tools/mkimage. With this tool, you can +create an image tree blob as follows:
- $ tools/mkimage -f fit.its -k keys -K dts/dt.dtb -r -F fitImage
+The -k option must specify the key directory you have created in step 1.
+A file "fitImage" will be created. This includes kernel, DTB, +hash data for each of the three, and signature data.
+The public key needed for the run-time verification is stored in "dts/dt.dtb".
+5. Compile Verified U-Boot
+Since the "dt.dtb" has been updated in step 4, you need to re-compile the +U-Boot.
- $ make CROSS_COMPILE=aarch64-linux-gnu-
+The re-compiled "u-boot.bin" is appended with DTB that contains the public key.
+6. Flash the image
+Flash the "fitImage" to a storage device (SD, NAND, eMMC, or whatever) on your +board.
+7. Boot verified kernel
+Load the fitImage to memory and run the following from the U-Boot command line.
bootm <addr>+Here, <addr> is the base address of the fitImage.
+If it is successful, you will see messages like follows:
+---------------------------------------->8---------------------------------------- +=> setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p1 rootwait +=> ext4load mmc 0:1 $kernel_addr_r /boot/fitImage +16321738 bytes read in 1049 ms (14.8 MiB/s) +=> bootm $kernel_addr_r +## Loading kernel from FIT Image at 40080000 ...
- Using 'conf@0' configuration
- Verifying Hash Integrity ... OK
- Trying 'kernel@0' kernel subimage
Description: ARM64 Linux kernel
Type: Kernel Image
Compression: gzip compressed
Data Start: 0x400800e4
Data Size: 6884659 Bytes = 6.6 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x50080000
Entry Point: 0x50080000
Hash algo: sha256
Hash value: 6808fe51ea3c15f31c4510d2701d4707b56d20213c9da05bce79fb53bf108f1a
- Verifying Hash Integrity ... sha256+ OK
+## Loading fdt from FIT Image at 40080000 ...
- Using 'conf@0' configuration
- Trying 'fdt@0' fdt subimage
Description: Orangepi Win/Win+ Devicetree blob
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x40710f24
Data Size: 9032 Bytes = 8.8 KiB
Architecture: AArch64
Hash algo: sha256
Hash value: ca3d874cd10466633ff133cc0156828d48c8efb96987fa45f885761d22a25dc1
- Verifying Hash Integrity ... sha256+ OK
- Booting using the fdt blob at 0x40710f24
- Uncompressing Kernel Image ... OK
- Loading Device Tree to 0000000049ffa000, end 0000000049fff347 ... OK
+Starting kernel ... +---------------------------------------->8----------------------------------------
+Please pay attention to the lines that start with "Verifying Hash Integrity".
+"Verifying Hash Integrity ... sha256,rsa2048:dev+ OK" means the signature check +passed.
+"Verifying Hash Integrity ... sha256+ OK" (2 times) means the hash check passed +for kernel and DTB.
+If they are not displayed, the Verified Boot is not working.
One thing that we should make *really* clear is that it will sign only the kernel and device trees, but it's far from sufficient to implement a full fledged secure boot, and you shouldn't consider your device protected. At least the signature of the SPL and the U-Boot binary are missing to implement something that would have a chance to qualify.
True, full secure boot can be an extension of this. will update these in next series.
thanks!

Hi,
On Fri, Nov 10, 2017 at 10:21:08PM +0530, Jagan Teki wrote:
Enable FIT_SIGNATURE for sunxi a64.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com
Changes for v2:
- Use imply instead of select
arch/arm/mach-sunxi/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 09cfec6..9ee356f 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -178,6 +178,7 @@ config MACH_SUN50I select SUNXI_DRAM_DW select SUNXI_DRAM_DW_32BIT select FIT
- imply FIT_SIGNATURE select SPL_LOAD_FIT
Can you put that outside of the block of selects?
Thanks! Maxime
participants (2)
-
Jagan Teki
-
Maxime Ripard