[U-Boot] [PATCH] RFC: Secure boot to U-Boot proper from SPL

For those that have asked me about this, I have dug into the past and cannot find my experiment. In the end I managed to reduce U-Boot proper down to about 100KB of code (by dropping CONFIG_CMD and removing video and USB drivers) and this was small enough to fit in SRAM. So SPL was not needed.
That said, my experiment drove a lot of the FIT and image refactoring and I think it is actually pretty easy now to enable the full FIT implementation in SPL, if your SoC limitations allow it.
In the case of Chrome OS, both U-Boot SPL and U-Boot proper are in read-only memory so there is no need for this. But even then it is useful to be able to have the smallest amount of non-updateable software, so quite a bit of work was done (for pit/pi) to support loading a read-write 'U-Boot proper' from SPL.
So I think it would be useful to support loading and verifying FIT images with public key encryption in U-Boot, and fairly straightforward.
To help things along, here is a starting point for firefly-rk3288 (Thumb 2). This board already uses device tree in SPL (perhaps bravely given the SoC size limitations) so the additional code would be a few KB larger for platforms that don't.
For firefly the code size increases from 26KB to 40 KB. There is a fair bit of opportunity to reduce this if needed, for example by cutting out strings.
Please reply on this thread if you plan to pick this up and prepare a series to enable this in U-Boot, to reduce duplicated work. Signed-off-by: Simon Glass sjg@chromium.org ---
Kconfig | 8 ++++++++ common/Makefile | 3 ++- common/image-fit.c | 2 +- common/spl/spl.c | 1 + configs/firefly-rk3288_defconfig | 5 +++++ drivers/Makefile | 1 + include/configs/rk3288_common.h | 2 ++ lib/Makefile | 3 ++- lib/rsa/rsa-verify.c | 5 ++++- 9 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/Kconfig b/Kconfig index f53759a..4ffcc76 100644 --- a/Kconfig +++ b/Kconfig @@ -183,6 +183,10 @@ config FIT verified boot (secure boot using RSA). This option enables that feature.
+config SPL_FIT + bool "Support Flattened Image Tree in SPL" + depends on FIT + config FIT_VERBOSE bool "Display verbose messages on FIT boot" depends on FIT @@ -205,6 +209,10 @@ config FIT_SIGNATURE format support in this case, enable it using CONFIG_IMAGE_FORMAT_LEGACY.
+config SPL_FIT_SIGNATURE + bool "Enable signature verification of FIT uImages in SPL" + depends on FIT_SIGNATURE + config FIT_BEST_MATCH bool "Select the best match for the kernel device tree" depends on FIT diff --git a/common/Makefile b/common/Makefile index b23f312..647a4ed 100644 --- a/common/Makefile +++ b/common/Makefile @@ -10,7 +10,6 @@ ifndef CONFIG_SPL_BUILD obj-y += init/ obj-y += main.o obj-y += exports.o -obj-y += hash.o ifdef CONFIG_SYS_HUSH_PARSER obj-y += cli_hush.o endif @@ -150,6 +149,8 @@ obj-y += fb_nand.o endif endif
+obj-y += hash.o + # We always have this since drivers/ddr/fs/interactive.c needs it obj-$(CONFIG_CMDLINE) += cli_simple.o
diff --git a/common/image-fit.c b/common/image-fit.c index 25f8a11..12c94e1 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1502,7 +1502,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
static int fit_image_select(const void *fit, int rd_noffset, int verify) { - fit_image_print(fit, rd_noffset, " "); +// fit_image_print(fit, rd_noffset, " ");
if (verify) { puts(" Verifying Hash Integrity ... "); diff --git a/common/spl/spl.c b/common/spl/spl.c index 82e7f58..017ca82 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -345,6 +345,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) int i;
debug(">>spl:board_init_r()\n"); + fit_image_load(NULL, 0, NULL, NULL, 0, 0, 0, 0, NULL, NULL);
#if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig index 0995f9b..596475c 100644 --- a/configs/firefly-rk3288_defconfig +++ b/configs/firefly-rk3288_defconfig @@ -69,3 +69,8 @@ CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_SPL_FIT=y +CONFIG_SPL_OF_LIBFDT +CONFIG_FIT_SIGNATURE=y +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_FIT=y diff --git a/drivers/Makefile b/drivers/Makefile index 6900097..baf9dee 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_SPL_WATCHDOG_SUPPORT) += watchdog/ obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += usb/host/ obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/ +obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/
else
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index 8a81397..39bffcb 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -11,6 +11,8 @@
#include <asm/arch/hardware.h>
+#define CONFIG_SPL_CRYPTO_SUPPORT + #define CONFIG_SYS_NO_FLASH #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_ENV_SIZE 0x2000 diff --git a/lib/Makefile b/lib/Makefile index 02dfa29..b3ea4bd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,6 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ -obj-$(CONFIG_RSA) += rsa/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_LZO) += lzo/ obj-$(CONFIG_ZLIB) += zlib/ @@ -49,6 +48,8 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif
+obj-$(CONFIG_RSA) += rsa/ + obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/ ifdef CONFIG_SPL_OF_CONTROL obj-$(CONFIG_OF_LIBFDT) += libfdt/ diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 60126d2..341ce2e 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -200,7 +200,10 @@ int rsa_verify(struct image_sign_info *info, }
/* Look for a key that matches our hint */ - snprintf(name, sizeof(name), "key-%s", info->keyname); + // FIXME + //snprintf(name, sizeof(name), "key-%s", info->keyname); + strcpy(name, "key-"); + strcat(name, info->keyname); node = fdt_subnode_offset(blob, sig_node, name); ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node); if (!ret)

I've been using the following patch for my configurations, please excuse the top-posting. I think the only difference is enabling the uclass mod_exp driver to initialize without needing relocation.
---
This allows a board to configure verified boot within the SPL using a FIT or FIT with external data. It also allows the SPL to perform signature verification without needing relocation.
The board configuration will need to add the following feature defines: CONFIG_SPL_CRYPTO_SUPPORT CONFIG_SPL_HASH_SUPPORT CONFIG_SPL_SHA256
In this example, SHA256 is the selected hashing algorithm.
And the following booleans: CONFIG_SPL=y CONFIG_SPL_DM=y CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_FIT=y CONFIG_SPL_OF_CONTROL=y CONFIG_SPL_OF_LIBFDT=y CONFIG_SPL_FIT_SIGNATURE=y
Signed-off-by: Teddy Reed teddy.reed@gmail.com --- Kconfig | 11 +++++++++++ common/Makefile | 1 + drivers/Makefile | 1 + drivers/crypto/rsa_mod_exp/mod_exp_sw.c | 1 + lib/Makefile | 9 +++++---- lib/rsa/Kconfig | 3 +++ lib/rsa/Makefile | 2 +- 7 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/Kconfig b/Kconfig index f53759a..e73ad03 100644 --- a/Kconfig +++ b/Kconfig @@ -183,6 +183,11 @@ config FIT verified boot (secure boot using RSA). This option enables that feature.
+config SPL_FIT + bool "Support Flattened Image Tree within SPL" + depends on FIT + depends on SPL + config FIT_VERBOSE bool "Display verbose messages on FIT boot" depends on FIT @@ -205,6 +210,12 @@ config FIT_SIGNATURE format support in this case, enable it using CONFIG_IMAGE_FORMAT_LEGACY.
+config SPL_FIT_SIGNATURE + bool "Enable signature verification of FIT firmware within SPL" + depends on SPL_FIT + depends on SPL_DM + select SPL_RSA + config FIT_BEST_MATCH bool "Select the best match for the kernel device tree" depends on FIT diff --git a/common/Makefile b/common/Makefile index b23f312..271f633 100644 --- a/common/Makefile +++ b/common/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o endif # !CONFIG_SPL_BUILD
ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_HASH_SUPPORT) += hash.o obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o diff --git a/drivers/Makefile b/drivers/Makefile index 6900097..456492f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_$(SPL_)RAM) += ram/
ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/ obj-$(CONFIG_SPL_I2C_SUPPORT) += i2c/ obj-$(CONFIG_SPL_GPIO_SUPPORT) += gpio/ obj-$(CONFIG_SPL_MMC_SUPPORT) += mmc/ diff --git a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c index dc6c064..56d7e89 100644 --- a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c +++ b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c @@ -32,6 +32,7 @@ U_BOOT_DRIVER(mod_exp_sw) = { .name = "mod_exp_sw", .id = UCLASS_MOD_EXP, .ops = &mod_exp_ops_sw, + .flags = DM_FLAG_PRE_RELOC, };
U_BOOT_DEVICE(mod_exp_sw) = { diff --git a/lib/Makefile b/lib/Makefile index 02dfa29..5c83e32 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,6 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ -obj-$(CONFIG_RSA) += rsa/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_LZO) += lzo/ obj-$(CONFIG_ZLIB) += zlib/ @@ -25,8 +24,6 @@ obj-y += crc8.o obj-y += crc16.o obj-$(CONFIG_ERRNO_STR) += errno_str.o obj-$(CONFIG_FIT) += fdtdec_common.o -obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o -obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o obj-$(CONFIG_GZIP) += gunzip.o obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o @@ -41,7 +38,6 @@ obj-y += qsort.o obj-y += rc4.o obj-$(CONFIG_SHA1) += sha1.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o -obj-$(CONFIG_SHA256) += sha256.o obj-y += strmhz.o obj-$(CONFIG_TPM) += tpm.o obj-$(CONFIG_RBTREE) += rbtree.o @@ -49,6 +45,11 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif
+obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o +obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o +obj-$(CONFIG_$(SPL_)RSA) += rsa/ +obj-$(CONFIG_$(SPL_)SHA256) += sha256.o + obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/ ifdef CONFIG_SPL_OF_CONTROL obj-$(CONFIG_OF_LIBFDT) += libfdt/ diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig index 86df0a0..ec80e43 100644 --- a/lib/rsa/Kconfig +++ b/lib/rsa/Kconfig @@ -13,6 +13,9 @@ config RSA option. The software based modular exponentiation is built into mkimage irrespective of this option.
+config SPL_RSA + bool "Use RSA Library within SPL" + if RSA config RSA_SOFTWARE_EXP bool "Enable driver for RSA Modular Exponentiation in software" diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile index 6867e50..4b2c1ba 100644 --- a/lib/rsa/Makefile +++ b/lib/rsa/Makefile @@ -7,5 +7,5 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o +obj-$(CONFIG_$(SPL_)FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o obj-$(CONFIG_RSA_SOFTWARE_EXP) += rsa-mod-exp.o

On Sun, May 1, 2016 at 11:12 AM, Teddy Reed teddy.reed@gmail.com wrote:
I've been using the following patch for my configurations, please excuse the top-posting. I think the only difference is enabling the uclass mod_exp driver to initialize without needing relocation.
If no one has any additional notes / requirements for enablement in SPL I can send my tiny bit of configuration changes as a patch.
I've tested the DM flag change for the RSA mod_exp driver class for both relocated (u-boot) and non-relocated (SPL) builds and found no issues. It would be awesome to get another set of eyes on the Makefile feature reorganization as I don't want this to include unneeded code into SPLs. :)
This allows a board to configure verified boot within the SPL using a FIT or FIT with external data. It also allows the SPL to perform signature verification without needing relocation.
The board configuration will need to add the following feature defines: CONFIG_SPL_CRYPTO_SUPPORT CONFIG_SPL_HASH_SUPPORT CONFIG_SPL_SHA256
In this example, SHA256 is the selected hashing algorithm.
And the following booleans: CONFIG_SPL=y CONFIG_SPL_DM=y CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_FIT=y CONFIG_SPL_OF_CONTROL=y CONFIG_SPL_OF_LIBFDT=y CONFIG_SPL_FIT_SIGNATURE=y
Signed-off-by: Teddy Reed teddy.reed@gmail.com
Kconfig | 11 +++++++++++ common/Makefile | 1 + drivers/Makefile | 1 + drivers/crypto/rsa_mod_exp/mod_exp_sw.c | 1 + lib/Makefile | 9 +++++---- lib/rsa/Kconfig | 3 +++ lib/rsa/Makefile | 2 +- 7 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/Kconfig b/Kconfig index f53759a..e73ad03 100644 --- a/Kconfig +++ b/Kconfig @@ -183,6 +183,11 @@ config FIT verified boot (secure boot using RSA). This option enables that feature.
+config SPL_FIT
bool "Support Flattened Image Tree within SPL"
depends on FIT
depends on SPL
config FIT_VERBOSE bool "Display verbose messages on FIT boot" depends on FIT @@ -205,6 +210,12 @@ config FIT_SIGNATURE format support in this case, enable it using CONFIG_IMAGE_FORMAT_LEGACY.
+config SPL_FIT_SIGNATURE
bool "Enable signature verification of FIT firmware within SPL"
depends on SPL_FIT
depends on SPL_DM
select SPL_RSA
config FIT_BEST_MATCH bool "Select the best match for the kernel device tree" depends on FIT diff --git a/common/Makefile b/common/Makefile index b23f312..271f633 100644 --- a/common/Makefile +++ b/common/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o endif # !CONFIG_SPL_BUILD
ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_HASH_SUPPORT) += hash.o obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o diff --git a/drivers/Makefile b/drivers/Makefile index 6900097..456492f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_$(SPL_)RAM) += ram/
ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/ obj-$(CONFIG_SPL_I2C_SUPPORT) += i2c/ obj-$(CONFIG_SPL_GPIO_SUPPORT) += gpio/ obj-$(CONFIG_SPL_MMC_SUPPORT) += mmc/ diff --git a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c index dc6c064..56d7e89 100644 --- a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c +++ b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c @@ -32,6 +32,7 @@ U_BOOT_DRIVER(mod_exp_sw) = { .name = "mod_exp_sw", .id = UCLASS_MOD_EXP, .ops = &mod_exp_ops_sw,
.flags = DM_FLAG_PRE_RELOC,
};
U_BOOT_DEVICE(mod_exp_sw) = { diff --git a/lib/Makefile b/lib/Makefile index 02dfa29..5c83e32 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,6 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ -obj-$(CONFIG_RSA) += rsa/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_LZO) += lzo/ obj-$(CONFIG_ZLIB) += zlib/ @@ -25,8 +24,6 @@ obj-y += crc8.o obj-y += crc16.o obj-$(CONFIG_ERRNO_STR) += errno_str.o obj-$(CONFIG_FIT) += fdtdec_common.o -obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o -obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o obj-$(CONFIG_GZIP) += gunzip.o obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o @@ -41,7 +38,6 @@ obj-y += qsort.o obj-y += rc4.o obj-$(CONFIG_SHA1) += sha1.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o -obj-$(CONFIG_SHA256) += sha256.o obj-y += strmhz.o obj-$(CONFIG_TPM) += tpm.o obj-$(CONFIG_RBTREE) += rbtree.o @@ -49,6 +45,11 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif
+obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o +obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o +obj-$(CONFIG_$(SPL_)RSA) += rsa/ +obj-$(CONFIG_$(SPL_)SHA256) += sha256.o
obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/ ifdef CONFIG_SPL_OF_CONTROL obj-$(CONFIG_OF_LIBFDT) += libfdt/ diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig index 86df0a0..ec80e43 100644 --- a/lib/rsa/Kconfig +++ b/lib/rsa/Kconfig @@ -13,6 +13,9 @@ config RSA option. The software based modular exponentiation is built into mkimage irrespective of this option.
+config SPL_RSA
bool "Use RSA Library within SPL"
if RSA config RSA_SOFTWARE_EXP bool "Enable driver for RSA Modular Exponentiation in software" diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile index 6867e50..4b2c1ba 100644 --- a/lib/rsa/Makefile +++ b/lib/rsa/Makefile @@ -7,5 +7,5 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o +obj-$(CONFIG_$(SPL_)FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o obj-$(CONFIG_RSA_SOFTWARE_EXP) += rsa-mod-exp.o -- 1.9.1
On Sun, 1 May 2016 11:45:22 -0600 Simon Glass sjg@chromium.org wrote:
For those that have asked me about this, I have dug into the past and cannot find my experiment. In the end I managed to reduce U-Boot proper down to about 100KB of code (by dropping CONFIG_CMD and removing video and USB drivers) and this was small enough to fit in SRAM. So SPL was not needed.
That said, my experiment drove a lot of the FIT and image refactoring and I think it is actually pretty easy now to enable the full FIT implementation in SPL, if your SoC limitations allow it.
In the case of Chrome OS, both U-Boot SPL and U-Boot proper are in read-only memory so there is no need for this. But even then it is useful to be able to have the smallest amount of non-updateable software, so quite a bit of work was done (for pit/pi) to support loading a read-write 'U-Boot proper' from SPL.
So I think it would be useful to support loading and verifying FIT images with public key encryption in U-Boot, and fairly straightforward.
To help things along, here is a starting point for firefly-rk3288 (Thumb 2). This board already uses device tree in SPL (perhaps bravely given the SoC size limitations) so the additional code would be a few KB larger for platforms that don't.
For firefly the code size increases from 26KB to 40 KB. There is a fair bit of opportunity to reduce this if needed, for example by cutting out strings.
Please reply on this thread if you plan to pick this up and prepare a series to enable this in U-Boot, to reduce duplicated work. Signed-off-by: Simon Glass sjg@chromium.org
Kconfig | 8 ++++++++ common/Makefile | 3 ++- common/image-fit.c | 2 +- common/spl/spl.c | 1 + configs/firefly-rk3288_defconfig | 5 +++++ drivers/Makefile | 1 + include/configs/rk3288_common.h | 2 ++ lib/Makefile | 3 ++- lib/rsa/rsa-verify.c | 5 ++++- 9 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/Kconfig b/Kconfig index f53759a..4ffcc76 100644 --- a/Kconfig +++ b/Kconfig @@ -183,6 +183,10 @@ config FIT verified boot (secure boot using RSA). This option enables that feature.
+config SPL_FIT
bool "Support Flattened Image Tree in SPL"
depends on FIT
config FIT_VERBOSE bool "Display verbose messages on FIT boot" depends on FIT @@ -205,6 +209,10 @@ config FIT_SIGNATURE format support in this case, enable it using CONFIG_IMAGE_FORMAT_LEGACY.
+config SPL_FIT_SIGNATURE
bool "Enable signature verification of FIT uImages in SPL"
depends on FIT_SIGNATURE
config FIT_BEST_MATCH bool "Select the best match for the kernel device tree" depends on FIT diff --git a/common/Makefile b/common/Makefile index b23f312..647a4ed 100644 --- a/common/Makefile +++ b/common/Makefile @@ -10,7 +10,6 @@ ifndef CONFIG_SPL_BUILD obj-y += init/ obj-y += main.o obj-y += exports.o -obj-y += hash.o ifdef CONFIG_SYS_HUSH_PARSER obj-y += cli_hush.o endif @@ -150,6 +149,8 @@ obj-y += fb_nand.o endif endif
+obj-y += hash.o
# We always have this since drivers/ddr/fs/interactive.c needs it obj-$(CONFIG_CMDLINE) += cli_simple.o
diff --git a/common/image-fit.c b/common/image-fit.c index 25f8a11..12c94e1 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1502,7 +1502,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
static int fit_image_select(const void *fit, int rd_noffset, int verify) {
fit_image_print(fit, rd_noffset, " ");
+// fit_image_print(fit, rd_noffset, " ");
if (verify) { puts(" Verifying Hash Integrity ... ");
diff --git a/common/spl/spl.c b/common/spl/spl.c index 82e7f58..017ca82 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -345,6 +345,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) int i;
debug(">>spl:board_init_r()\n");
fit_image_load(NULL, 0, NULL, NULL, 0, 0, 0, 0, NULL, NULL);
#if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig index 0995f9b..596475c 100644 --- a/configs/firefly-rk3288_defconfig +++ b/configs/firefly-rk3288_defconfig @@ -69,3 +69,8 @@ CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_SPL_FIT=y +CONFIG_SPL_OF_LIBFDT +CONFIG_FIT_SIGNATURE=y +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_FIT=y diff --git a/drivers/Makefile b/drivers/Makefile index 6900097..baf9dee 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_SPL_WATCHDOG_SUPPORT) += watchdog/ obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += usb/host/ obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/ +obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/
else
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index 8a81397..39bffcb 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -11,6 +11,8 @@
#include <asm/arch/hardware.h>
+#define CONFIG_SPL_CRYPTO_SUPPORT
#define CONFIG_SYS_NO_FLASH #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_ENV_SIZE 0x2000 diff --git a/lib/Makefile b/lib/Makefile index 02dfa29..b3ea4bd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,6 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ -obj-$(CONFIG_RSA) += rsa/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_LZO) += lzo/ obj-$(CONFIG_ZLIB) += zlib/ @@ -49,6 +48,8 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif
+obj-$(CONFIG_RSA) += rsa/
obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/ ifdef CONFIG_SPL_OF_CONTROL obj-$(CONFIG_OF_LIBFDT) += libfdt/ diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 60126d2..341ce2e 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -200,7 +200,10 @@ int rsa_verify(struct image_sign_info *info, }
/* Look for a key that matches our hint */
snprintf(name, sizeof(name), "key-%s", info->keyname);
// FIXME
//snprintf(name, sizeof(name), "key-%s", info->keyname);
strcpy(name, "key-");
strcat(name, info->keyname); node = fdt_subnode_offset(blob, sig_node, name); ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node); if (!ret)
-- 2.8.0.rc3.226.g39d4020

Hi Teddy,
On 8 May 2016 at 19:13, Teddy Reed teddy.reed@gmail.com wrote:
On Sun, May 1, 2016 at 11:12 AM, Teddy Reed teddy.reed@gmail.com wrote:
I've been using the following patch for my configurations, please excuse the top-posting. I think the only difference is enabling the uclass mod_exp driver to initialize without needing relocation.
If no one has any additional notes / requirements for enablement in SPL I can send my tiny bit of configuration changes as a patch.
I've tested the DM flag change for the RSA mod_exp driver class for both relocated (u-boot) and non-relocated (SPL) builds and found no issues. It would be awesome to get another set of eyes on the Makefile feature reorganization as I don't want this to include unneeded code into SPLs. :)
Sounds good, a few patches would be useful.
Regards, Simon

On Sun, May 08, 2016 at 06:13:50PM -0700, Teddy Reed wrote:
On Sun, May 1, 2016 at 11:12 AM, Teddy Reed teddy.reed@gmail.com wrote:
I've been using the following patch for my configurations, please excuse the top-posting. I think the only difference is enabling the uclass mod_exp driver to initialize without needing relocation.
If no one has any additional notes / requirements for enablement in SPL I can send my tiny bit of configuration changes as a patch.
I've tested the DM flag change for the RSA mod_exp driver class for both relocated (u-boot) and non-relocated (SPL) builds and found no issues. It would be awesome to get another set of eyes on the Makefile feature reorganization as I don't want this to include unneeded code into SPLs. :)
Hi Teddy, I was just trying to work your patch into my U-Boot tree to experiment with it some when I realized that it requires CONFIG_SPL_DM which is something the platforms I work with don't currently support :(
I'll need to look further and see what I can do about it (using the non-DM rsa_mod_exp_sw routine instead of rsa_mod_exp?) but generally speaking it seems like that non-DM based authentication could be a useful feature for SPL, since one big reason of using an SPL in the first place is to have something that fits into the minimum amount of on-chip RAM possible...
Thanks and Regards,
-- Andreas Dannenberg Texas Instruments Inc
This allows a board to configure verified boot within the SPL using a FIT or FIT with external data. It also allows the SPL to perform signature verification without needing relocation.
The board configuration will need to add the following feature defines: CONFIG_SPL_CRYPTO_SUPPORT CONFIG_SPL_HASH_SUPPORT CONFIG_SPL_SHA256
In this example, SHA256 is the selected hashing algorithm.
And the following booleans: CONFIG_SPL=y CONFIG_SPL_DM=y CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_FIT=y CONFIG_SPL_OF_CONTROL=y CONFIG_SPL_OF_LIBFDT=y CONFIG_SPL_FIT_SIGNATURE=y
Signed-off-by: Teddy Reed teddy.reed@gmail.com
Kconfig | 11 +++++++++++ common/Makefile | 1 + drivers/Makefile | 1 + drivers/crypto/rsa_mod_exp/mod_exp_sw.c | 1 + lib/Makefile | 9 +++++---- lib/rsa/Kconfig | 3 +++ lib/rsa/Makefile | 2 +- 7 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/Kconfig b/Kconfig index f53759a..e73ad03 100644 --- a/Kconfig +++ b/Kconfig @@ -183,6 +183,11 @@ config FIT verified boot (secure boot using RSA). This option enables that feature.
+config SPL_FIT
bool "Support Flattened Image Tree within SPL"
depends on FIT
depends on SPL
config FIT_VERBOSE bool "Display verbose messages on FIT boot" depends on FIT @@ -205,6 +210,12 @@ config FIT_SIGNATURE format support in this case, enable it using CONFIG_IMAGE_FORMAT_LEGACY.
+config SPL_FIT_SIGNATURE
bool "Enable signature verification of FIT firmware within SPL"
depends on SPL_FIT
depends on SPL_DM
select SPL_RSA
config FIT_BEST_MATCH bool "Select the best match for the kernel device tree" depends on FIT diff --git a/common/Makefile b/common/Makefile index b23f312..271f633 100644 --- a/common/Makefile +++ b/common/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o endif # !CONFIG_SPL_BUILD
ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_HASH_SUPPORT) += hash.o obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o diff --git a/drivers/Makefile b/drivers/Makefile index 6900097..456492f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_$(SPL_)RAM) += ram/
ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/ obj-$(CONFIG_SPL_I2C_SUPPORT) += i2c/ obj-$(CONFIG_SPL_GPIO_SUPPORT) += gpio/ obj-$(CONFIG_SPL_MMC_SUPPORT) += mmc/ diff --git a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c index dc6c064..56d7e89 100644 --- a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c +++ b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c @@ -32,6 +32,7 @@ U_BOOT_DRIVER(mod_exp_sw) = { .name = "mod_exp_sw", .id = UCLASS_MOD_EXP, .ops = &mod_exp_ops_sw,
.flags = DM_FLAG_PRE_RELOC,
};
U_BOOT_DEVICE(mod_exp_sw) = { diff --git a/lib/Makefile b/lib/Makefile index 02dfa29..5c83e32 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,6 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ -obj-$(CONFIG_RSA) += rsa/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_LZO) += lzo/ obj-$(CONFIG_ZLIB) += zlib/ @@ -25,8 +24,6 @@ obj-y += crc8.o obj-y += crc16.o obj-$(CONFIG_ERRNO_STR) += errno_str.o obj-$(CONFIG_FIT) += fdtdec_common.o -obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o -obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o obj-$(CONFIG_GZIP) += gunzip.o obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o @@ -41,7 +38,6 @@ obj-y += qsort.o obj-y += rc4.o obj-$(CONFIG_SHA1) += sha1.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o -obj-$(CONFIG_SHA256) += sha256.o obj-y += strmhz.o obj-$(CONFIG_TPM) += tpm.o obj-$(CONFIG_RBTREE) += rbtree.o @@ -49,6 +45,11 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif
+obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o +obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o +obj-$(CONFIG_$(SPL_)RSA) += rsa/ +obj-$(CONFIG_$(SPL_)SHA256) += sha256.o
obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/ ifdef CONFIG_SPL_OF_CONTROL obj-$(CONFIG_OF_LIBFDT) += libfdt/ diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig index 86df0a0..ec80e43 100644 --- a/lib/rsa/Kconfig +++ b/lib/rsa/Kconfig @@ -13,6 +13,9 @@ config RSA option. The software based modular exponentiation is built into mkimage irrespective of this option.
+config SPL_RSA
bool "Use RSA Library within SPL"
if RSA config RSA_SOFTWARE_EXP bool "Enable driver for RSA Modular Exponentiation in software" diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile index 6867e50..4b2c1ba 100644 --- a/lib/rsa/Makefile +++ b/lib/rsa/Makefile @@ -7,5 +7,5 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o +obj-$(CONFIG_$(SPL_)FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o obj-$(CONFIG_RSA_SOFTWARE_EXP) += rsa-mod-exp.o -- 1.9.1
On Sun, 1 May 2016 11:45:22 -0600 Simon Glass sjg@chromium.org wrote:
For those that have asked me about this, I have dug into the past and cannot find my experiment. In the end I managed to reduce U-Boot proper down to about 100KB of code (by dropping CONFIG_CMD and removing video and USB drivers) and this was small enough to fit in SRAM. So SPL was not needed.
That said, my experiment drove a lot of the FIT and image refactoring and I think it is actually pretty easy now to enable the full FIT implementation in SPL, if your SoC limitations allow it.
In the case of Chrome OS, both U-Boot SPL and U-Boot proper are in read-only memory so there is no need for this. But even then it is useful to be able to have the smallest amount of non-updateable software, so quite a bit of work was done (for pit/pi) to support loading a read-write 'U-Boot proper' from SPL.
So I think it would be useful to support loading and verifying FIT images with public key encryption in U-Boot, and fairly straightforward.
To help things along, here is a starting point for firefly-rk3288 (Thumb 2). This board already uses device tree in SPL (perhaps bravely given the SoC size limitations) so the additional code would be a few KB larger for platforms that don't.
For firefly the code size increases from 26KB to 40 KB. There is a fair bit of opportunity to reduce this if needed, for example by cutting out strings.
Please reply on this thread if you plan to pick this up and prepare a series to enable this in U-Boot, to reduce duplicated work. Signed-off-by: Simon Glass sjg@chromium.org
Kconfig | 8 ++++++++ common/Makefile | 3 ++- common/image-fit.c | 2 +- common/spl/spl.c | 1 + configs/firefly-rk3288_defconfig | 5 +++++ drivers/Makefile | 1 + include/configs/rk3288_common.h | 2 ++ lib/Makefile | 3 ++- lib/rsa/rsa-verify.c | 5 ++++- 9 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/Kconfig b/Kconfig index f53759a..4ffcc76 100644 --- a/Kconfig +++ b/Kconfig @@ -183,6 +183,10 @@ config FIT verified boot (secure boot using RSA). This option enables that feature.
+config SPL_FIT
bool "Support Flattened Image Tree in SPL"
depends on FIT
config FIT_VERBOSE bool "Display verbose messages on FIT boot" depends on FIT @@ -205,6 +209,10 @@ config FIT_SIGNATURE format support in this case, enable it using CONFIG_IMAGE_FORMAT_LEGACY.
+config SPL_FIT_SIGNATURE
bool "Enable signature verification of FIT uImages in SPL"
depends on FIT_SIGNATURE
config FIT_BEST_MATCH bool "Select the best match for the kernel device tree" depends on FIT diff --git a/common/Makefile b/common/Makefile index b23f312..647a4ed 100644 --- a/common/Makefile +++ b/common/Makefile @@ -10,7 +10,6 @@ ifndef CONFIG_SPL_BUILD obj-y += init/ obj-y += main.o obj-y += exports.o -obj-y += hash.o ifdef CONFIG_SYS_HUSH_PARSER obj-y += cli_hush.o endif @@ -150,6 +149,8 @@ obj-y += fb_nand.o endif endif
+obj-y += hash.o
# We always have this since drivers/ddr/fs/interactive.c needs it obj-$(CONFIG_CMDLINE) += cli_simple.o
diff --git a/common/image-fit.c b/common/image-fit.c index 25f8a11..12c94e1 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1502,7 +1502,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
static int fit_image_select(const void *fit, int rd_noffset, int verify) {
fit_image_print(fit, rd_noffset, " ");
+// fit_image_print(fit, rd_noffset, " ");
if (verify) { puts(" Verifying Hash Integrity ... ");
diff --git a/common/spl/spl.c b/common/spl/spl.c index 82e7f58..017ca82 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -345,6 +345,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) int i;
debug(">>spl:board_init_r()\n");
fit_image_load(NULL, 0, NULL, NULL, 0, 0, 0, 0, NULL, NULL);
#if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig index 0995f9b..596475c 100644 --- a/configs/firefly-rk3288_defconfig +++ b/configs/firefly-rk3288_defconfig @@ -69,3 +69,8 @@ CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_SPL_FIT=y +CONFIG_SPL_OF_LIBFDT +CONFIG_FIT_SIGNATURE=y +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_FIT=y diff --git a/drivers/Makefile b/drivers/Makefile index 6900097..baf9dee 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_SPL_WATCHDOG_SUPPORT) += watchdog/ obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += usb/host/ obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/ +obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/
else
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index 8a81397..39bffcb 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -11,6 +11,8 @@
#include <asm/arch/hardware.h>
+#define CONFIG_SPL_CRYPTO_SUPPORT
#define CONFIG_SYS_NO_FLASH #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_ENV_SIZE 0x2000 diff --git a/lib/Makefile b/lib/Makefile index 02dfa29..b3ea4bd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,6 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ -obj-$(CONFIG_RSA) += rsa/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_LZO) += lzo/ obj-$(CONFIG_ZLIB) += zlib/ @@ -49,6 +48,8 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif
+obj-$(CONFIG_RSA) += rsa/
obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/ ifdef CONFIG_SPL_OF_CONTROL obj-$(CONFIG_OF_LIBFDT) += libfdt/ diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 60126d2..341ce2e 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -200,7 +200,10 @@ int rsa_verify(struct image_sign_info *info, }
/* Look for a key that matches our hint */
snprintf(name, sizeof(name), "key-%s", info->keyname);
// FIXME
//snprintf(name, sizeof(name), "key-%s", info->keyname);
strcpy(name, "key-");
strcat(name, info->keyname); node = fdt_subnode_offset(blob, sig_node, name); ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node); if (!ret)
-- 2.8.0.rc3.226.g39d4020
-- Teddy Reed V _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On May 23, 2016, at 1:15 PM, Andreas Dannenberg dannenberg@ti.com wrote:
On Sun, May 08, 2016 at 06:13:50PM -0700, Teddy Reed wrote:
On Sun, May 1, 2016 at 11:12 AM, Teddy Reed teddy.reed@gmail.com wrote: I've been using the following patch for my configurations, please excuse the top-posting. I think the only difference is enabling the uclass mod_exp driver to initialize without needing relocation.
If no one has any additional notes / requirements for enablement in SPL I can send my tiny bit of configuration changes as a patch.
I've tested the DM flag change for the RSA mod_exp driver class for both relocated (u-boot) and non-relocated (SPL) builds and found no issues. It would be awesome to get another set of eyes on the Makefile feature reorganization as I don't want this to include unneeded code into SPLs. :)
Hi Teddy, I was just trying to work your patch into my U-Boot tree to experiment with it some when I realized that it requires CONFIG_SPL_DM which is something the platforms I work with don't currently support :(
I'll need to look further and see what I can do about it (using the non-DM rsa_mod_exp_sw routine instead of rsa_mod_exp?) but generally speaking it seems like that non-DM based authentication could be a useful feature for SPL, since one big reason of using an SPL in the first place is to have something that fits into the minimum amount of on-chip RAM possible...
Definitely! My original goal was verified boot in SPL with a minimum set of configuration/code changes. I've been working in the code base for a few weeks now and absolutely agree that with a bit more code modifications the driver model requirement could removed.
I do love the concept of representing the EXP implementation as a uclass driver, but for highly constrained SPLs it's not the best.
I think it's a good idea to land the proposed minimum set of configuration changes required for verified boot in SPL. Then we can iterate together on removing the DM requirement. What do you think? The main reason I suggest multiple patches is because the decoupling may also affect non-SPL verified boots. :)
Take care! -Teddy
Thanks and Regards,
-- Andreas Dannenberg Texas Instruments Inc
This allows a board to configure verified boot within the SPL using a FIT or FIT with external data. It also allows the SPL to perform signature verification without needing relocation.
The board configuration will need to add the following feature defines: CONFIG_SPL_CRYPTO_SUPPORT CONFIG_SPL_HASH_SUPPORT CONFIG_SPL_SHA256
In this example, SHA256 is the selected hashing algorithm.
And the following booleans: CONFIG_SPL=y CONFIG_SPL_DM=y CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_FIT=y CONFIG_SPL_OF_CONTROL=y CONFIG_SPL_OF_LIBFDT=y CONFIG_SPL_FIT_SIGNATURE=y
Signed-off-by: Teddy Reed teddy.reed@gmail.com
Kconfig | 11 +++++++++++ common/Makefile | 1 + drivers/Makefile | 1 + drivers/crypto/rsa_mod_exp/mod_exp_sw.c | 1 + lib/Makefile | 9 +++++---- lib/rsa/Kconfig | 3 +++ lib/rsa/Makefile | 2 +- 7 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/Kconfig b/Kconfig index f53759a..e73ad03 100644 --- a/Kconfig +++ b/Kconfig @@ -183,6 +183,11 @@ config FIT verified boot (secure boot using RSA). This option enables that feature.
+config SPL_FIT
bool "Support Flattened Image Tree within SPL"
depends on FIT
depends on SPL
config FIT_VERBOSE bool "Display verbose messages on FIT boot" depends on FIT @@ -205,6 +210,12 @@ config FIT_SIGNATURE format support in this case, enable it using CONFIG_IMAGE_FORMAT_LEGACY.
+config SPL_FIT_SIGNATURE
bool "Enable signature verification of FIT firmware within SPL"
depends on SPL_FIT
depends on SPL_DM
select SPL_RSA
config FIT_BEST_MATCH bool "Select the best match for the kernel device tree" depends on FIT diff --git a/common/Makefile b/common/Makefile index b23f312..271f633 100644 --- a/common/Makefile +++ b/common/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o endif # !CONFIG_SPL_BUILD
ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_HASH_SUPPORT) += hash.o obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o diff --git a/drivers/Makefile b/drivers/Makefile index 6900097..456492f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_$(SPL_)RAM) += ram/
ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/ obj-$(CONFIG_SPL_I2C_SUPPORT) += i2c/ obj-$(CONFIG_SPL_GPIO_SUPPORT) += gpio/ obj-$(CONFIG_SPL_MMC_SUPPORT) += mmc/ diff --git a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c index dc6c064..56d7e89 100644 --- a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c +++ b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c @@ -32,6 +32,7 @@ U_BOOT_DRIVER(mod_exp_sw) = { .name = "mod_exp_sw", .id = UCLASS_MOD_EXP, .ops = &mod_exp_ops_sw,
.flags = DM_FLAG_PRE_RELOC,
};
U_BOOT_DEVICE(mod_exp_sw) = { diff --git a/lib/Makefile b/lib/Makefile index 02dfa29..5c83e32 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,6 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ -obj-$(CONFIG_RSA) += rsa/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_LZO) += lzo/ obj-$(CONFIG_ZLIB) += zlib/ @@ -25,8 +24,6 @@ obj-y += crc8.o obj-y += crc16.o obj-$(CONFIG_ERRNO_STR) += errno_str.o obj-$(CONFIG_FIT) += fdtdec_common.o -obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o -obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o obj-$(CONFIG_GZIP) += gunzip.o obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o @@ -41,7 +38,6 @@ obj-y += qsort.o obj-y += rc4.o obj-$(CONFIG_SHA1) += sha1.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o -obj-$(CONFIG_SHA256) += sha256.o obj-y += strmhz.o obj-$(CONFIG_TPM) += tpm.o obj-$(CONFIG_RBTREE) += rbtree.o @@ -49,6 +45,11 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif
+obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o +obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o +obj-$(CONFIG_$(SPL_)RSA) += rsa/ +obj-$(CONFIG_$(SPL_)SHA256) += sha256.o
obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/ ifdef CONFIG_SPL_OF_CONTROL obj-$(CONFIG_OF_LIBFDT) += libfdt/ diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig index 86df0a0..ec80e43 100644 --- a/lib/rsa/Kconfig +++ b/lib/rsa/Kconfig @@ -13,6 +13,9 @@ config RSA option. The software based modular exponentiation is built into mkimage irrespective of this option.
+config SPL_RSA
bool "Use RSA Library within SPL"
if RSA config RSA_SOFTWARE_EXP bool "Enable driver for RSA Modular Exponentiation in software" diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile index 6867e50..4b2c1ba 100644 --- a/lib/rsa/Makefile +++ b/lib/rsa/Makefile @@ -7,5 +7,5 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o +obj-$(CONFIG_$(SPL_)FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o obj-$(CONFIG_RSA_SOFTWARE_EXP) += rsa-mod-exp.o -- 1.9.1
On Sun, 1 May 2016 11:45:22 -0600 Simon Glass sjg@chromium.org wrote:
For those that have asked me about this, I have dug into the past and cannot find my experiment. In the end I managed to reduce U-Boot proper down to about 100KB of code (by dropping CONFIG_CMD and removing video and USB drivers) and this was small enough to fit in SRAM. So SPL was not needed.
That said, my experiment drove a lot of the FIT and image refactoring and I think it is actually pretty easy now to enable the full FIT implementation in SPL, if your SoC limitations allow it.
In the case of Chrome OS, both U-Boot SPL and U-Boot proper are in read-only memory so there is no need for this. But even then it is useful to be able to have the smallest amount of non-updateable software, so quite a bit of work was done (for pit/pi) to support loading a read-write 'U-Boot proper' from SPL.
So I think it would be useful to support loading and verifying FIT images with public key encryption in U-Boot, and fairly straightforward.
To help things along, here is a starting point for firefly-rk3288 (Thumb 2). This board already uses device tree in SPL (perhaps bravely given the SoC size limitations) so the additional code would be a few KB larger for platforms that don't.
For firefly the code size increases from 26KB to 40 KB. There is a fair bit of opportunity to reduce this if needed, for example by cutting out strings.
Please reply on this thread if you plan to pick this up and prepare a series to enable this in U-Boot, to reduce duplicated work. Signed-off-by: Simon Glass sjg@chromium.org
Kconfig | 8 ++++++++ common/Makefile | 3 ++- common/image-fit.c | 2 +- common/spl/spl.c | 1 + configs/firefly-rk3288_defconfig | 5 +++++ drivers/Makefile | 1 + include/configs/rk3288_common.h | 2 ++ lib/Makefile | 3 ++- lib/rsa/rsa-verify.c | 5 ++++- 9 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/Kconfig b/Kconfig index f53759a..4ffcc76 100644 --- a/Kconfig +++ b/Kconfig @@ -183,6 +183,10 @@ config FIT verified boot (secure boot using RSA). This option enables that feature.
+config SPL_FIT
bool "Support Flattened Image Tree in SPL"
depends on FIT
config FIT_VERBOSE bool "Display verbose messages on FIT boot" depends on FIT @@ -205,6 +209,10 @@ config FIT_SIGNATURE format support in this case, enable it using CONFIG_IMAGE_FORMAT_LEGACY.
+config SPL_FIT_SIGNATURE
bool "Enable signature verification of FIT uImages in SPL"
depends on FIT_SIGNATURE
config FIT_BEST_MATCH bool "Select the best match for the kernel device tree" depends on FIT diff --git a/common/Makefile b/common/Makefile index b23f312..647a4ed 100644 --- a/common/Makefile +++ b/common/Makefile @@ -10,7 +10,6 @@ ifndef CONFIG_SPL_BUILD obj-y += init/ obj-y += main.o obj-y += exports.o -obj-y += hash.o ifdef CONFIG_SYS_HUSH_PARSER obj-y += cli_hush.o endif @@ -150,6 +149,8 @@ obj-y += fb_nand.o endif endif
+obj-y += hash.o
# We always have this since drivers/ddr/fs/interactive.c needs it obj-$(CONFIG_CMDLINE) += cli_simple.o
diff --git a/common/image-fit.c b/common/image-fit.c index 25f8a11..12c94e1 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1502,7 +1502,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
static int fit_image_select(const void *fit, int rd_noffset, int verify) {
fit_image_print(fit, rd_noffset, " ");
+// fit_image_print(fit, rd_noffset, " ");
if (verify) { puts(" Verifying Hash Integrity ... ");
diff --git a/common/spl/spl.c b/common/spl/spl.c index 82e7f58..017ca82 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -345,6 +345,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) int i;
debug(">>spl:board_init_r()\n");
fit_image_load(NULL, 0, NULL, NULL, 0, 0, 0, 0, NULL, NULL);
#if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig index 0995f9b..596475c 100644 --- a/configs/firefly-rk3288_defconfig +++ b/configs/firefly-rk3288_defconfig @@ -69,3 +69,8 @@ CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_SPL_FIT=y +CONFIG_SPL_OF_LIBFDT +CONFIG_FIT_SIGNATURE=y +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_FIT=y diff --git a/drivers/Makefile b/drivers/Makefile index 6900097..baf9dee 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_SPL_WATCHDOG_SUPPORT) += watchdog/ obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += usb/host/ obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/ +obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/
else
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index 8a81397..39bffcb 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -11,6 +11,8 @@
#include <asm/arch/hardware.h>
+#define CONFIG_SPL_CRYPTO_SUPPORT
#define CONFIG_SYS_NO_FLASH #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_ENV_SIZE 0x2000 diff --git a/lib/Makefile b/lib/Makefile index 02dfa29..b3ea4bd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,6 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_EFI_LOADER) += efi_loader/ -obj-$(CONFIG_RSA) += rsa/ obj-$(CONFIG_LZMA) += lzma/ obj-$(CONFIG_LZO) += lzo/ obj-$(CONFIG_ZLIB) += zlib/ @@ -49,6 +48,8 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif
+obj-$(CONFIG_RSA) += rsa/
obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/ ifdef CONFIG_SPL_OF_CONTROL obj-$(CONFIG_OF_LIBFDT) += libfdt/ diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 60126d2..341ce2e 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -200,7 +200,10 @@ int rsa_verify(struct image_sign_info *info, }
/* Look for a key that matches our hint */
snprintf(name, sizeof(name), "key-%s", info->keyname);
// FIXME
//snprintf(name, sizeof(name), "key-%s", info->keyname);
strcpy(name, "key-");
node = fdt_subnode_offset(blob, sig_node, name); ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node); if (!ret)strcat(name, info->keyname);
-- 2.8.0.rc3.226.g39d4020
-- Teddy Reed V _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi Teddy,
On Mon, May 23, 2016 at 01:53:35PM -0400, Teddy Reed wrote:
On May 23, 2016, at 1:15 PM, Andreas Dannenberg dannenberg@ti.com wrote:
On Sun, May 08, 2016 at 06:13:50PM -0700, Teddy Reed wrote:
On Sun, May 1, 2016 at 11:12 AM, Teddy Reed teddy.reed@gmail.com wrote: I've been using the following patch for my configurations, please excuse the top-posting. I think the only difference is enabling the uclass mod_exp driver to initialize without needing relocation.
If no one has any additional notes / requirements for enablement in SPL I can send my tiny bit of configuration changes as a patch.
I've tested the DM flag change for the RSA mod_exp driver class for both relocated (u-boot) and non-relocated (SPL) builds and found no issues. It would be awesome to get another set of eyes on the Makefile feature reorganization as I don't want this to include unneeded code into SPLs. :)
Hi Teddy, I was just trying to work your patch into my U-Boot tree to experiment with it some when I realized that it requires CONFIG_SPL_DM which is something the platforms I work with don't currently support :(
I'll need to look further and see what I can do about it (using the non-DM rsa_mod_exp_sw routine instead of rsa_mod_exp?) but generally speaking it seems like that non-DM based authentication could be a useful feature for SPL, since one big reason of using an SPL in the first place is to have something that fits into the minimum amount of on-chip RAM possible...
Definitely! My original goal was verified boot in SPL with a minimum set of configuration/code changes. I've been working in the code base for a few weeks now and absolutely agree that with a bit more code modifications the driver model requirement could removed.
I do love the concept of representing the EXP implementation as a uclass driver, but for highly constrained SPLs it's not the best.
I think it's a good idea to land the proposed minimum set of configuration changes required for verified boot in SPL. Then we can iterate together on removing the DM requirement. What do you think?
Yes I think what you have in your RFC is definitely a good starting point and building this out with additional patches sounds like a reasonable approach. But as you are preparing your actual initial patch submission it'd be good to keep in the back of your mind to architect it such that it can be build upon further... (I realize it's a bit of a chicken-and-egg problem but I wanted to make that comment anways ha). But I'm definitely going to further experiment with this and let you know if there are relevant findings.
Since you seem to be spending quite a bit of energy on the auth stuff I suppose there is another thing you probably ran into as well which is related to how the public key gets embedded into the DTB file. When using CONFIG_SPL_LOAD_FIT to build a FIT blob containing U-Boot and one or several DTBs I think the mkimage-based process of embedding said public key [1] doesn't really apply. So for now I "hacked" it by embedding the public key manually directly in the DTS source files so that U-Boot can access it but clearly this needs a better solution. I'm thinking of an approach of where the U-Boot build process would consume the public key (maybe specified via a CONFIG_xxx) and bake it directly into DTB file(s) specified by CONFIG_OF_LIST during build before they get bundled together into a FIT blob but I wonder if you might have already had some thoughts on this topic.
Thanks and Regards, Andreas
[1] http://git.denx.de/?p=u-boot.git;a=blob;f=doc/uImage.FIT/beaglebone_vboot.tx...
The main reason I suggest multiple patches is because the decoupling may also affect non-SPL verified boots. :)
Take care! -Teddy
participants (4)
-
Andreas Dannenberg
-
Simon Glass
-
Teddy Reed
-
Teddy Reed