]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'next'
authorTom Rini <trini@ti.com>
Thu, 17 Apr 2014 18:33:25 +0000 (14:33 -0400)
committerTom Rini <trini@ti.com>
Thu, 17 Apr 2014 18:33:25 +0000 (14:33 -0400)
62 files changed:
README
arch/arm/cpu/tegra20-common/crypto.c
arch/sparc/cpu/leon2/config.mk
arch/sparc/cpu/leon3/config.mk
common/Makefile
common/cmd_aes.c [new file with mode: 0644]
common/cmd_fdt.c
common/env_common.c
common/env_dataflash.c
common/env_eeprom.c
common/env_fat.c
common/env_flash.c
common/env_mmc.c
common/env_nand.c
common/env_nvram.c
common/env_onenand.c
common/env_sf.c
common/env_ubi.c
common/hash.c
common/image-fit.c
common/image-sig.c
doc/uImage.FIT/signature.txt
include/aes.h
include/configs/gr_cpci_ax2000.h
include/configs/gr_ep2s60.h
include/configs/gr_xc3s_1500.h
include/configs/grsim.h
include/configs/grsim_leon2.h
include/environment.h
include/fdt_support.h
include/hash.h
include/image.h
include/rsa-checksum.h [new file with mode: 0644]
include/rsa.h
lib/aes.c
lib/fdtdec.c
lib/rsa/Makefile
lib/rsa/rsa-checksum.c [new file with mode: 0644]
lib/rsa/rsa-sign.c
lib/rsa/rsa-verify.c
lib/sha256.c
test/vboot/sign-configs-sha1.its [moved from test/vboot/sign-configs.its with 100% similarity]
test/vboot/sign-configs-sha256.its [new file with mode: 0644]
test/vboot/sign-images-sha1.its [moved from test/vboot/sign-images.its with 100% similarity]
test/vboot/sign-images-sha256.its [new file with mode: 0644]
test/vboot/vboot_test.sh
tools/.gitignore
tools/Makefile
tools/env/Makefile
tools/env/fw_env.c
tools/env/fw_env_main.c
tools/fdt_host.h
tools/fdtdec.c [new file with mode: 0644]
tools/fit_check_sign.c [new file with mode: 0644]
tools/fit_common.c [new file with mode: 0644]
tools/fit_common.h [new file with mode: 0644]
tools/fit_image.c
tools/fit_info.c [new file with mode: 0644]
tools/image-host.c
tools/rsa-checksum.c [new file with mode: 0644]
tools/rsa-verify.c [new file with mode: 0644]
tools/sha256.c [new file with mode: 0644]

diff --git a/README b/README
index 39e05d333c672b5183908a4016ad223641ca023a..52a92e73b8e161126264aea58b4977119047c16d 100644 (file)
--- a/README
+++ b/README
@@ -912,6 +912,7 @@ The following options need to be configured:
                The default command configuration includes all commands
                except those marked below with a "*".
 
+               CONFIG_CMD_AES            AES 128 CBC encrypt/decrypt
                CONFIG_CMD_ASKENV       * ask for env variable
                CONFIG_CMD_BDI            bdinfo
                CONFIG_CMD_BEDBUG       * Include BedBug Debugger
index 8209f7661ad76c631edb8450aa3c489d642cdbde..b18e67c3463e0a3989b8e55d864b0b0bda96be01 100644 (file)
@@ -19,74 +19,6 @@ enum security_op {
        SECURITY_ENCRYPT        = 1 << 1,       /* Encrypt the data */
 };
 
-static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
-{
-       u32 i;
-
-       debug("%s [%d] @0x%08x", name, num_bytes, (u32)data);
-       for (i = 0; i < num_bytes; i++) {
-               if (i % 16 == 0)
-                       debug(" = ");
-               debug("%02x", data[i]);
-               if ((i+1) % 16 != 0)
-                       debug(" ");
-       }
-       debug("\n");
-}
-
-/**
- * Apply chain data to the destination using EOR
- *
- * Each array is of length AES_AES_KEY_LENGTH.
- *
- * \param cbc_chain_data       Chain data
- * \param src                  Source data
- * \param dst                  Destination data, which is modified here
- */
-static void apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
-{
-       int i;
-
-       for (i = 0; i < 16; i++)
-               *dst++ = *src++ ^ *cbc_chain_data++;
-}
-
-/**
- * Encrypt some data with AES.
- *
- * \param key_schedule         Expanded key to use
- * \param src                  Source data to encrypt
- * \param dst                  Destination buffer
- * \param num_aes_blocks       Number of AES blocks to encrypt
- */
-static void encrypt_object(u8 *key_schedule, u8 *src, u8 *dst,
-                          u32 num_aes_blocks)
-{
-       u8 tmp_data[AES_KEY_LENGTH];
-       u8 *cbc_chain_data;
-       u32 i;
-
-       cbc_chain_data = zero_key;      /* Convenient array of 0's for IV */
-
-       for (i = 0; i < num_aes_blocks; i++) {
-               debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
-               debug_print_vector("AES Src", AES_KEY_LENGTH, src);
-
-               /* Apply the chain data */
-               apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
-               debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
-
-               /* encrypt the AES block */
-               aes_encrypt(tmp_data, key_schedule, dst);
-               debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
-
-               /* Update pointers for next loop. */
-               cbc_chain_data = dst;
-               src += AES_KEY_LENGTH;
-               dst += AES_KEY_LENGTH;
-       }
-}
-
 /**
  * Shift a vector left by one bit
  *
@@ -129,7 +61,7 @@ static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst,
        for (i = 0; i < AES_KEY_LENGTH; i++)
                tmp_data[i] = 0;
 
-       encrypt_object(key_schedule, tmp_data, left, 1);
+       aes_cbc_encrypt_blocks(key_schedule, tmp_data, left, 1);
        debug_print_vector("AES(key, nonce)", AES_KEY_LENGTH, left);
 
        left_shift_vector(left, k1, sizeof(left));
@@ -193,7 +125,7 @@ static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src,
        if (oper & SECURITY_ENCRYPT) {
                /* Perform this in place, resulting in src being encrypted. */
                debug("encrypt_and_sign: begin encryption\n");
-               encrypt_object(key_schedule, src, src, num_aes_blocks);
+               aes_cbc_encrypt_blocks(key_schedule, src, src, num_aes_blocks);
                debug("encrypt_and_sign: end encryption\n");
        }
 
index f9b0d347f784b1a943932ebb4dc2968b6a29311a..c44b0930ec08ecbe08186c73fef95562da090e88 100644 (file)
@@ -7,4 +7,4 @@
 
 PLATFORM_RELFLAGS += -fPIC
 
-PLATFORM_CPPFLAGS += -DCONFIG_LEON
+PLATFORM_CPPFLAGS += -DCONFIG_LEON -DCONFIG_LEON2
index f9b0d347f784b1a943932ebb4dc2968b6a29311a..ca6c9b13ec2120a1869bb863c39e8c3377108646 100644 (file)
@@ -7,4 +7,4 @@
 
 PLATFORM_RELFLAGS += -fPIC
 
-PLATFORM_CPPFLAGS += -DCONFIG_LEON
+PLATFORM_CPPFLAGS += -DCONFIG_LEON -DCONFIG_LEON3
index cecd81a9a08e8b986d7828e2d04ccbd559c75e8e..7c853ae4422bf331e98813555ffa2c0d62a02ce9 100644 (file)
@@ -48,6 +48,7 @@ obj-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o
 obj-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
 
 # command
+obj-$(CONFIG_CMD_AES) += cmd_aes.o
 obj-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o
 obj-$(CONFIG_SOURCE) += cmd_source.o
 obj-$(CONFIG_CMD_SOURCE) += cmd_source.o
diff --git a/common/cmd_aes.c b/common/cmd_aes.c
new file mode 100644 (file)
index 0000000..76da3ef
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 Marek Vasut <marex@denx.de>
+ *
+ * Command for en/de-crypting block of memory with AES-128-CBC cipher.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <environment.h>
+#include <aes.h>
+#include <malloc.h>
+#include <asm/byteorder.h>
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * do_aes() - Handle the "aes" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
+static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       uint32_t key_addr, src_addr, dst_addr, len;
+       uint8_t *key_ptr, *src_ptr, *dst_ptr;
+       uint8_t key_exp[AES_EXPAND_KEY_LENGTH];
+       uint32_t aes_blocks;
+       int enc;
+
+       if (argc != 6)
+               return CMD_RET_USAGE;
+
+       if (!strncmp(argv[1], "enc", 3))
+               enc = 1;
+       else if (!strncmp(argv[1], "dec", 3))
+               enc = 0;
+       else
+               return CMD_RET_USAGE;
+
+       key_addr = simple_strtoul(argv[2], NULL, 16);
+       src_addr = simple_strtoul(argv[3], NULL, 16);
+       dst_addr = simple_strtoul(argv[4], NULL, 16);
+       len = simple_strtoul(argv[5], NULL, 16);
+
+       key_ptr = (uint8_t *)key_addr;
+       src_ptr = (uint8_t *)src_addr;
+       dst_ptr = (uint8_t *)dst_addr;
+
+       /* First we expand the key. */
+       aes_expand_key(key_ptr, key_exp);
+
+       /* Calculate the number of AES blocks to encrypt. */
+       aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH);
+
+       if (enc)
+               aes_cbc_encrypt_blocks(key_exp, src_ptr, dst_ptr, aes_blocks);
+       else
+               aes_cbc_decrypt_blocks(key_exp, src_ptr, dst_ptr, aes_blocks);
+
+       return 0;
+}
+
+/***************************************************/
+#ifdef CONFIG_SYS_LONGHELP
+static char aes_help_text[] =
+       "enc key src dst len - Encrypt block of data $len bytes long\n"
+       "                          at address $src using a key at address\n"
+       "                          $key and store the result at address\n"
+       "                          $dst. The $len size must be multiple of\n"
+       "                          16 bytes and $key must be 16 bytes long.\n"
+       "aes dec key src dst len - Decrypt block of data $len bytes long\n"
+       "                          at address $src using a key at address\n"
+       "                          $key and store the result at address\n"
+       "                          $dst. The $len size must be multiple of\n"
+       "                          16 bytes and $key must be 16 bytes long.";
+#endif
+
+U_BOOT_CMD(
+       aes, 6, 1, do_aes,
+       "AES 128 CBC encryption",
+       aes_help_text
+);
index 3a9edd6468c3b47d06fb51018be99651e51077c7..a6744ed9c2509eb14cb441df45d4cb64974f385c 100644 (file)
@@ -570,7 +570,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                ft_board_setup(working_fdt, gd->bd);
 #endif
        /* Create a chosen node */
-       else if (argv[1][0] == 'c') {
+       else if (strncmp(argv[1], "cho", 3) == 0) {
                unsigned long initrd_start = 0, initrd_end = 0;
 
                if ((argc != 2) && (argc != 4))
@@ -583,6 +583,41 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
                fdt_chosen(working_fdt, 1);
                fdt_initrd(working_fdt, initrd_start, initrd_end, 1);
+
+#if defined(CONFIG_FIT_SIGNATURE)
+       } else if (strncmp(argv[1], "che", 3) == 0) {
+               int cfg_noffset;
+               int ret;
+               unsigned long addr;
+               struct fdt_header *blob;
+
+               if (!working_fdt)
+                       return CMD_RET_FAILURE;
+
+               if (argc > 2) {
+                       addr = simple_strtoul(argv[2], NULL, 16);
+                       blob = map_sysmem(addr, 0);
+               } else {
+                       blob = (struct fdt_header *)gd->fdt_blob;
+               }
+               if (!fdt_valid(&blob))
+                       return 1;
+
+               gd->fdt_blob = blob;
+               cfg_noffset = fit_conf_get_node(working_fdt, NULL);
+               if (!cfg_noffset) {
+                       printf("Could not find configuration node: %s\n",
+                              fdt_strerror(cfg_noffset));
+                       return CMD_RET_FAILURE;
+               }
+
+               ret = fit_config_verify(working_fdt, cfg_noffset);
+               if (ret == 1)
+                       return CMD_RET_SUCCESS;
+               else
+                       return CMD_RET_FAILURE;
+#endif
+
        }
        /* resize the fdt */
        else if (strncmp(argv[1], "re", 2) == 0) {
@@ -992,6 +1027,11 @@ static char fdt_help_text[] =
        "fdt rsvmem delete <index>           - Delete a mem reserves\n"
        "fdt chosen [<start> <end>]          - Add/update the /chosen branch in the tree\n"
        "                                        <start>/<end> - initrd start/end addr\n"
+#if defined(CONFIG_FIT_SIGNATURE)
+       "fdt checksign [<addr>]              - check FIT signature\n"
+       "                                        <start> - addr of key blob\n"
+       "                                                  default gd->fdt_blob\n"
+#endif
        "NOTE: Dereference aliases by omiting the leading '/', "
                "e.g. fdt print ethernet0.";
 #endif
index c0bfc2f5db3b3efebb7c039747b54abc186c1acc..cd7b4cd1dfb7c3a59bfad6f1ae6c5fe5bb07dd8f 100644 (file)
@@ -140,6 +140,52 @@ int set_default_vars(int nvars, char * const vars[])
                                H_NOCLEAR | H_INTERACTIVE, nvars, vars);
 }
 
+#ifdef CONFIG_ENV_AES
+#include <aes.h>
+/**
+ * env_aes_cbc_get_key() - Get AES-128-CBC key for the environment
+ *
+ * This function shall return 16-byte array containing AES-128 key used
+ * to encrypt and decrypt the environment. This function must be overriden
+ * by the implementer as otherwise the environment encryption will not
+ * work.
+ */
+__weak uint8_t *env_aes_cbc_get_key(void)
+{
+       return NULL;
+}
+
+static int env_aes_cbc_crypt(env_t *env, const int enc)
+{
+       unsigned char *data = env->data;
+       uint8_t *key;
+       uint8_t key_exp[AES_EXPAND_KEY_LENGTH];
+       uint32_t aes_blocks;
+
+       key = env_aes_cbc_get_key();
+       if (!key)
+               return -EINVAL;
+
+       /* First we expand the key. */
+       aes_expand_key(key, key_exp);
+
+       /* Calculate the number of AES blocks to encrypt. */
+       aes_blocks = ENV_SIZE / AES_KEY_LENGTH;
+
+       if (enc)
+               aes_cbc_encrypt_blocks(key_exp, data, data, aes_blocks);
+       else
+               aes_cbc_decrypt_blocks(key_exp, data, data, aes_blocks);
+
+       return 0;
+}
+#else
+static inline int env_aes_cbc_crypt(env_t *env, const int enc)
+{
+       return 0;
+}
+#endif
+
 /*
  * Check if CRC is valid and (if yes) import the environment.
  * Note that "buf" may or may not be aligned.
@@ -147,6 +193,7 @@ int set_default_vars(int nvars, char * const vars[])
 int env_import(const char *buf, int check)
 {
        env_t *ep = (env_t *)buf;
+       int ret;
 
        if (check) {
                uint32_t crc;
@@ -159,6 +206,14 @@ int env_import(const char *buf, int check)
                }
        }
 
+       /* Decrypt the env if desired. */
+       ret = env_aes_cbc_crypt(ep, 0);
+       if (ret) {
+               error("Failed to decrypt env!\n");
+               set_default_env("!import failed");
+               return ret;
+       }
+
        if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0,
                        0, NULL)) {
                gd->flags |= GD_FLG_ENV_READY;
@@ -172,6 +227,30 @@ int env_import(const char *buf, int check)
        return 0;
 }
 
+/* Emport the environment and generate CRC for it. */
+int env_export(env_t *env_out)
+{
+       char *res;
+       ssize_t len;
+       int ret;
+
+       res = (char *)env_out->data;
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
+       if (len < 0) {
+               error("Cannot export environment: errno = %d\n", errno);
+               return 1;
+       }
+
+       /* Encrypt the env if desired. */
+       ret = env_aes_cbc_crypt(env_out, 1);
+       if (ret)
+               return ret;
+
+       env_out->crc = crc32(0, env_out->data, ENV_SIZE);
+
+       return 0;
+}
+
 void env_relocate(void)
 {
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
index b53b87e95874bb0c9299db2eb2d0bfab6b044aac..034e3231693e3b751dc41f6e181a9672f03d6540 100644 (file)
@@ -56,17 +56,12 @@ void env_relocate_spec(void)
 
 int saveenv(void)
 {
-       env_t   env_new;
-       ssize_t len;
-       char    *res;
-
-       res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               return 1;
-       }
-       env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+       env_t env_new;
+       int ret;
+
+       ret = env_export(&env_new);
+       if (ret)
+               return ret;
 
        return write_dataflash(CONFIG_ENV_ADDR,
                                (unsigned long)&env_new,
index 0db2bb63fe1d9671b7e586a88e9b4f08063fae37..490ac731b31da018a4c3e12d0941e71a35011ec9 100644 (file)
@@ -98,8 +98,6 @@ void env_relocate_spec(void)
 int saveenv(void)
 {
        env_t   env_new;
-       ssize_t len;
-       char    *res;
        int     rc;
        unsigned int off        = CONFIG_ENV_OFFSET;
 #ifdef CONFIG_ENV_OFFSET_REDUND
@@ -109,13 +107,9 @@ int saveenv(void)
 
        BUG_ON(env_ptr != NULL);
 
-       res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               return 1;
-       }
-       env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+       rc = env_export(&env_new);
+       if (rc)
+               return rc;
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
        if (gd->env_valid == 1) {
index 708fd13dc72b25eba1bb3e2a86c0fe7a4706f37d..aad0487c32805aea4ec94e488f498c842e18cef6 100644 (file)
@@ -37,19 +37,14 @@ int env_init(void)
 int saveenv(void)
 {
        env_t   env_new;
-       ssize_t len;
-       char    *res;
        block_dev_desc_t *dev_desc = NULL;
        int dev = FAT_ENV_DEVICE;
        int part = FAT_ENV_PART;
        int err;
 
-       res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               return 1;
-       }
+       err = env_export(&env_new);
+       if (err)
+               return err;
 
 #ifdef CONFIG_MMC
        if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) {
@@ -79,7 +74,6 @@ int saveenv(void)
                return 1;
        }
 
-       env_new.crc = crc32(0, env_new.data, ENV_SIZE);
        err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t));
        if (err == -1) {
                printf("\n** Unable to write \"%s\" from %s%d:%d **\n",
index 7d5a4cfc8aa31d58e0ddf8d79061b87e27dc5b21..b3ad908894551bce70601cb0e7d3cfc9bc679ddb 100644 (file)
@@ -106,8 +106,7 @@ int env_init(void)
 int saveenv(void)
 {
        env_t   env_new;
-       ssize_t len;
-       char    *res, *saved_data = NULL;
+       char    *saved_data = NULL;
        char    flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG;
        int     rc = 1;
 #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
@@ -125,13 +124,9 @@ int saveenv(void)
        if (flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new))
                goto done;
 
-       res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               goto done;
-       }
-       env_new.crc     = crc32(0, env_new.data, ENV_SIZE);
+       rc = env_export(&env_new);
+       if (rc)
+               return rc;
        env_new.flags   = new_flag;
 
 #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
@@ -258,13 +253,9 @@ int saveenv(void)
        if (flash_sect_protect(0, (long)flash_addr, end_addr))
                goto done;
 
-       res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
+       rc = env_export(&env_new);
+       if (rc)
                goto done;
-       }
-       env_new.crc = crc32(0, env_new.data, ENV_SIZE);
 
        puts("Erasing Flash...");
        if (flash_sect_erase((long)flash_addr, end_addr))
index 045428c6ec96038e8aec0ee9d15b3561219e0233..c99fc750fa0a0b95db379b673423866d71b77a82 100644 (file)
@@ -118,8 +118,6 @@ static unsigned char env_flags;
 int saveenv(void)
 {
        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
-       ssize_t len;
-       char    *res;
        struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
        u32     offset;
        int     ret, copy = 0;
@@ -127,15 +125,9 @@ int saveenv(void)
        if (init_mmc_for_env(mmc))
                return 1;
 
-       res = (char *)&env_new->data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               ret = 1;
+       ret = env_export(env_new);
+       if (ret)
                goto fini;
-       }
-
-       env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE);
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
        env_new->flags  = ++env_flags; /* increase the serial */
index 695a9eebb01e68e3f11a7a545d96ac68507eebbc..5a734a9321a9400a73ee8024f29bcdb17d546ee6 100644 (file)
@@ -181,8 +181,6 @@ int saveenv(void)
 {
        int     ret = 0;
        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
-       ssize_t len;
-       char    *res;
        int     env_idx = 0;
        static const struct env_location location[] = {
                {
@@ -207,13 +205,10 @@ int saveenv(void)
        if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
                return 1;
 
-       res = (char *)&env_new->data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               return 1;
-       }
-       env_new->crc   = crc32(0, env_new->data, ENV_SIZE);
+       ret = env_export(env_new);
+       if (ret)
+               return ret;
+
 #ifdef CONFIG_ENV_OFFSET_REDUND
        env_new->flags = ++env_flags; /* increase the serial */
        env_idx = (gd->env_valid == 1);
index 0866cde924b658f37419e42df61624afefb9e297..524f07d5f8967460ac37dd7eb453f385f54cafc8 100644 (file)
@@ -69,17 +69,11 @@ void env_relocate_spec(void)
 int saveenv(void)
 {
        env_t   env_new;
-       ssize_t len;
-       char    *res;
        int     rcode = 0;
 
-       res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               return 1;
-       }
-       env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+       rcode = env_export(&env_new);
+       if (rcode)
+               return rcode;
 
 #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
        nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE);
index 4b4463218092fc48e29c5dce2dd67fb1c90d216a..cc3d670de83d4314834695c86ef8ab654f56a8fd 100644 (file)
@@ -66,8 +66,7 @@ void env_relocate_spec(void)
 int saveenv(void)
 {
        env_t   env_new;
-       ssize_t len;
-       char    *res;
+       int ret;
        struct mtd_info *mtd = &onenand_mtd;
 #ifdef CONFIG_ENV_ADDR_FLEX
        struct onenand_chip *this = &onenand_chip;
@@ -78,13 +77,9 @@ int saveenv(void)
                .callback       = NULL,
        };
 
-       res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               return 1;
-       }
-       env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+       ret = env_export(&env_new);
+       if (ret)
+               return ret;
 
        instr.len = CONFIG_ENV_SIZE;
 #ifdef CONFIG_ENV_ADDR_FLEX
index be270f21bcf6577ae44bd1d394817c5eb609fb01..37ab13ae17842309339fa9a70a42e49b8669207e 100644 (file)
@@ -47,8 +47,7 @@ static struct spi_flash *env_flash;
 int saveenv(void)
 {
        env_t   env_new;
-       ssize_t len;
-       char    *res, *saved_buffer = NULL, flag = OBSOLETE_FLAG;
+       char    *saved_buffer = NULL, flag = OBSOLETE_FLAG;
        u32     saved_size, saved_offset, sector = 1;
        int     ret;
 
@@ -62,13 +61,9 @@ int saveenv(void)
                }
        }
 
-       res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               return 1;
-       }
-       env_new.crc     = crc32(0, env_new.data, ENV_SIZE);
+       ret = env_export(&env_new);
+       if (ret)
+               return ret;
        env_new.flags   = ACTIVE_FLAG;
 
        if (gd->env_valid == 1) {
@@ -225,10 +220,9 @@ out:
 int saveenv(void)
 {
        u32     saved_size, saved_offset, sector = 1;
-       char    *res, *saved_buffer = NULL;
+       char    *saved_buffer = NULL;
        int     ret = 1;
        env_t   env_new;
-       ssize_t len;
 
        if (!env_flash) {
                env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
@@ -260,13 +254,9 @@ int saveenv(void)
                        sector++;
        }
 
-       res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
+       ret = env_export(&env_new);
+       if (ret)
                goto done;
-       }
-       env_new.crc = crc32(0, env_new.data, ENV_SIZE);
 
        puts("Erasing SPI flash...");
        ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET,
index c0828a47d3214131c9156157fe7c53aaf5f2e6cd..77bbfa6ef43caf051ba5166dd8045944e6e7a821 100644 (file)
@@ -37,15 +37,11 @@ static unsigned char env_flags;
 int saveenv(void)
 {
        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
-       ssize_t len;
-       char *res;
+       int ret;
 
-       res = (char *)&env_new->data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               return 1;
-       }
+       ret = env_export(env_new);
+       if (ret)
+               return ret;
 
        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
                printf("\n** Cannot find mtd partition \"%s\"\n",
@@ -53,7 +49,6 @@ int saveenv(void)
                return 1;
        }
 
-       env_new->crc = crc32(0, env_new->data, ENV_SIZE);
        env_new->flags = ++env_flags; /* increase the serial */
 
        if (gd->env_valid == 1) {
@@ -86,15 +81,11 @@ int saveenv(void)
 int saveenv(void)
 {
        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
-       ssize_t len;
-       char *res;
+       int ret;
 
-       res = (char *)&env_new->data;
-       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
-       if (len < 0) {
-               error("Cannot export environment: errno = %d\n", errno);
-               return 1;
-       }
+       ret = env_export(env_new);
+       if (ret)
+               return ret;
 
        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
                printf("\n** Cannot find mtd partition \"%s\"\n",
@@ -102,8 +93,6 @@ int saveenv(void)
                return 1;
        }
 
-       env_new->crc = crc32(0, env_new->data, ENV_SIZE);
-
        if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
                             CONFIG_ENV_SIZE)) {
                printf("\n** Unable to write env to %s:%s **\n",
index 872cd8542800895cd94f13d5290fd1a82c3e9cf7..7627b84b451421a599f378511eccd71639e450fe 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <malloc.h>
 #include <hw_sha.h>
 #include <hash.h>
 #include <sha1.h>
 #include <asm/io.h>
 #include <asm/errno.h>
 
+#ifdef CONFIG_CMD_SHA1SUM
+static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
+{
+       sha1_context *ctx = malloc(sizeof(sha1_context));
+       sha1_starts(ctx);
+       *ctxp = ctx;
+       return 0;
+}
+
+static int hash_update_sha1(struct hash_algo *algo, void *ctx, const void *buf,
+                           unsigned int size, int is_last)
+{
+       sha1_update((sha1_context *)ctx, buf, size);
+       return 0;
+}
+
+static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf,
+                           int size)
+{
+       if (size < algo->digest_size)
+               return -1;
+
+       sha1_finish((sha1_context *)ctx, dest_buf);
+       free(ctx);
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SHA256
+static int hash_init_sha256(struct hash_algo *algo, void **ctxp)
+{
+       sha256_context *ctx = malloc(sizeof(sha256_context));
+       sha256_starts(ctx);
+       *ctxp = ctx;
+       return 0;
+}
+
+static int hash_update_sha256(struct hash_algo *algo, void *ctx,
+                             const void *buf, unsigned int size, int is_last)
+{
+       sha256_update((sha256_context *)ctx, buf, size);
+       return 0;
+}
+
+static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void
+                             *dest_buf, int size)
+{
+       if (size < algo->digest_size)
+               return -1;
+
+       sha256_finish((sha256_context *)ctx, dest_buf);
+       free(ctx);
+       return 0;
+}
+#endif
+
+static int hash_init_crc32(struct hash_algo *algo, void **ctxp)
+{
+       uint32_t *ctx = malloc(sizeof(uint32_t));
+       *ctx = 0;
+       *ctxp = ctx;
+       return 0;
+}
+
+static int hash_update_crc32(struct hash_algo *algo, void *ctx,
+                            const void *buf, unsigned int size, int is_last)
+{
+       *((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size);
+       return 0;
+}
+
+static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf,
+                            int size)
+{
+       if (size < algo->digest_size)
+               return -1;
+
+       *((uint32_t *)dest_buf) = *((uint32_t *)ctx);
+       free(ctx);
+       return 0;
+}
+
 /*
  * These are the hash algorithms we support. Chips which support accelerated
  * crypto could perhaps add named version of these algorithms here. Note that
@@ -53,6 +136,9 @@ static struct hash_algo hash_algo[] = {
                SHA1_SUM_LEN,
                sha1_csum_wd,
                CHUNKSZ_SHA1,
+               hash_init_sha1,
+               hash_update_sha1,
+               hash_finish_sha1,
        },
 #define MULTI_HASH
 #endif
@@ -62,6 +148,9 @@ static struct hash_algo hash_algo[] = {
                SHA256_SUM_LEN,
                sha256_csum_wd,
                CHUNKSZ_SHA256,
+               hash_init_sha256,
+               hash_update_sha256,
+               hash_finish_sha256,
        },
 #define MULTI_HASH
 #endif
@@ -70,6 +159,9 @@ static struct hash_algo hash_algo[] = {
                4,
                crc32_wd_buf,
                CHUNKSZ_CRC32,
+               hash_init_crc32,
+               hash_update_crc32,
+               hash_finish_crc32,
        },
 };
 
@@ -204,16 +296,19 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum,
        return 0;
 }
 
-static struct hash_algo *find_hash_algo(const char *name)
+int hash_lookup_algo(const char *algo_name, struct hash_algo **algop)
 {
        int i;
 
        for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
-               if (!strcmp(name, hash_algo[i].name))
-                       return &hash_algo[i];
+               if (!strcmp(algo_name, hash_algo[i].name)) {
+                       *algop = &hash_algo[i];
+                       return 0;
+               }
        }
 
-       return NULL;
+       debug("Unknown hash algorithm '%s'\n", algo_name);
+       return -EPROTONOSUPPORT;
 }
 
 static void show_hash(struct hash_algo *algo, ulong addr, ulong len,
@@ -230,12 +325,12 @@ int hash_block(const char *algo_name, const void *data, unsigned int len,
               uint8_t *output, int *output_size)
 {
        struct hash_algo *algo;
+       int ret;
+
+       ret = hash_lookup_algo(algo_name, &algo);
+       if (ret)
+               return ret;
 
-       algo = find_hash_algo(algo_name);
-       if (!algo) {
-               debug("Unknown hash algorithm '%s'\n", algo_name);
-               return -EPROTONOSUPPORT;
-       }
        if (output_size && *output_size < algo->digest_size) {
                debug("Output buffer size %d too small (need %d bytes)",
                      *output_size, algo->digest_size);
@@ -265,8 +360,7 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
                u8 vsum[HASH_MAX_DIGEST_SIZE];
                void *buf;
 
-               algo = find_hash_algo(algo_name);
-               if (!algo) {
+               if (hash_lookup_algo(algo_name, &algo)) {
                        printf("Unknown hash algorithm '%s'\n", algo_name);
                        return CMD_RET_USAGE;
                }
index b94a3fe86dc3469bf651f09980b3d366b573cb04..77f32bce316fe41e74e630e5ae6488262988ec06 100644 (file)
@@ -22,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #include <bootstage.h>
 #include <sha1.h>
+#include <sha256.h>
 #include <u-boot/crc.h>
 #include <u-boot/md5.h>
 
@@ -882,6 +883,10 @@ int calculate_hash(const void *data, int data_len, const char *algo,
                sha1_csum_wd((unsigned char *)data, data_len,
                             (unsigned char *)value, CHUNKSZ_SHA1);
                *value_len = 20;
+       } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
+               sha256_csum_wd((unsigned char *)data, data_len,
+                              (unsigned char *)value, CHUNKSZ_SHA256);
+               *value_len = SHA256_SUM_LEN;
        } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
                md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
                *value_len = 16;
index 973b06d505f174177c3ea634af38b86c4eddb6d5..72284eb1d1fd00947863c63b55b1a3f3ece6f8c0 100644 (file)
@@ -14,16 +14,79 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif /* !USE_HOSTCC*/
 #include <image.h>
 #include <rsa.h>
+#include <rsa-checksum.h>
 
 #define IMAGE_MAX_HASHED_NODES         100
 
+#ifdef USE_HOSTCC
+void *host_blob;
+void image_set_host_blob(void *blob)
+{
+       host_blob = blob;
+}
+void *image_get_host_blob(void)
+{
+       return host_blob;
+}
+#endif
+
+struct checksum_algo checksum_algos[] = {
+       {
+               "sha1",
+               SHA1_SUM_LEN,
+               RSA2048_BYTES,
+#if IMAGE_ENABLE_SIGN
+               EVP_sha1,
+#endif
+               sha1_calculate,
+               padding_sha1_rsa2048,
+       },
+       {
+               "sha256",
+               SHA256_SUM_LEN,
+               RSA2048_BYTES,
+#if IMAGE_ENABLE_SIGN
+               EVP_sha256,
+#endif
+               sha256_calculate,
+               padding_sha256_rsa2048,
+       },
+       {
+               "sha256",
+               SHA256_SUM_LEN,
+               RSA4096_BYTES,
+#if IMAGE_ENABLE_SIGN
+               EVP_sha256,
+#endif
+               sha256_calculate,
+               padding_sha256_rsa4096,
+       }
+
+};
+
 struct image_sig_algo image_sig_algos[] = {
        {
                "sha1,rsa2048",
                rsa_sign,
                rsa_add_verify_data,
                rsa_verify,
+               &checksum_algos[0],
+       },
+       {
+               "sha256,rsa2048",
+               rsa_sign,
+               rsa_add_verify_data,
+               rsa_verify,
+               &checksum_algos[1],
+       },
+       {
+               "sha256,rsa4096",
+               rsa_sign,
+               rsa_add_verify_data,
+               rsa_verify,
+               &checksum_algos[2],
        }
+
 };
 
 struct image_sig_algo *image_get_sig_algo(const char *name)
index bc9f3fa6e13684d147e23d90b12a432dc053e7fe..95020377055d259a2b9e285b178371fccefc3ea3 100644 (file)
@@ -346,7 +346,9 @@ Simple Verified Boot Test
 
 Please see doc/uImage.FIT/verified-boot.txt for more information
 
+/home/hs/ids/u-boot/sandbox/tools/mkimage -D -I dts -O dtb -p 2000
 Build keys
+do sha1 test
 Build FIT with signed images
 Test Verified Boot Run: unsigned signatures:: OK
 Sign images
@@ -355,10 +357,26 @@ Build FIT with signed configuration
 Test Verified Boot Run: unsigned config: OK
 Sign images
 Test Verified Boot Run: signed config: OK
+check signed config on the host
+OK
+Test Verified Boot Run: signed config: OK
+Test Verified Boot Run: signed config with bad hash: OK
+do sha256 test
+Build FIT with signed images
+Test Verified Boot Run: unsigned signatures:: OK
+Sign images
+Test Verified Boot Run: signed images: OK
+Build FIT with signed configuration
+Test Verified Boot Run: unsigned config: OK
+Sign images
+Test Verified Boot Run: signed config: OK
+check signed config on the host
+OK
+Test Verified Boot Run: signed config: OK
+Test Verified Boot Run: signed config with bad hash: OK
 
 Test passed
 
-
 Future Work
 -----------
 - Roll-back protection using a TPM is done using the tpm command. This can
index ea063082790ec608726ecbd27fec12f82d02bf62..ee0e6c275f13d4f6e2e79417f2dd08706d048773 100644 (file)
@@ -8,6 +8,13 @@
 #ifndef _AES_REF_H_
 #define _AES_REF_H_
 
+#ifdef USE_HOSTCC
+/* Define compat stuff for use in fw_* tools. */
+typedef unsigned char u8;
+typedef unsigned int u32;
+#define debug(...) do {} while (0)
+#endif
+
 /*
  * AES encryption library, with small code size, supporting only 128-bit AES
  *
@@ -25,30 +32,52 @@ enum {
 };
 
 /**
+ * aes_expand_key() - Expand the AES key
+ *
  * Expand a key into a key schedule, which is then used for the other
  * operations.
  *
- * \param key          Key, of length AES_KEY_LENGTH bytes
- * \param expkey       Buffer to place expanded key, AES_EXPAND_KEY_LENGTH
+ * @key                Key, of length AES_KEY_LENGTH bytes
+ * @expkey     Buffer to place expanded key, AES_EXPAND_KEY_LENGTH
  */
 void aes_expand_key(u8 *key, u8 *expkey);
 
 /**
- * Encrypt a single block of data
+ * aes_encrypt() - Encrypt single block of data with AES 128
  *
- * in          Input data
- * expkey      Expanded key to use for encryption (from aes_expand_key())
- * out         Output data
+ * @in         Input data
+ * @expkey     Expanded key to use for encryption (from aes_expand_key())
+ * @out                Output data
  */
 void aes_encrypt(u8 *in, u8 *expkey, u8 *out);
 
 /**
- * Decrypt a single block of data
+ * aes_decrypt() - Decrypt single block of data with AES 128
  *
- * in          Input data
- * expkey      Expanded key to use for decryption (from aes_expand_key())
- * out         Output data
+ * @in         Input data
+ * @expkey     Expanded key to use for decryption (from aes_expand_key())
+ * @out                Output data
  */
 void aes_decrypt(u8 *in, u8 *expkey, u8 *out);
 
+/**
+ * aes_cbc_encrypt_blocks() - Encrypt multiple blocks of data with AES CBC.
+ *
+ * @key_exp            Expanded key to use
+ * @src                        Source data to encrypt
+ * @dst                        Destination buffer
+ * @num_aes_blocks     Number of AES blocks to encrypt
+ */
+void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks);
+
+/**
+ * Decrypt multiple blocks of data with AES CBC.
+ *
+ * @key_exp            Expanded key to use
+ * @src                        Source data to decrypt
+ * @dst                        Destination buffer
+ * @num_aes_blocks     Number of AES blocks to decrypt
+ */
+void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks);
+
 #endif /* _AES_REF_H_ */
index 2437b4b6133add2629b82c3ed71669c9791dad63..854807d486846ee9f0525e8209e4998bd88899a6 100644 (file)
@@ -19,8 +19,6 @@
  * (easy to change)
  */
 
-#define CONFIG_LEON3           /* This is an LEON3 CPU */
-#define CONFIG_LEON            1       /* This is an LEON CPU */
 #define CONFIG_CPCI_AX2000     1       /* ... on GR-CPCI-AX2000 board */
 
 #define CONFIG_LEON_RAM_SRAM 1
index 2cd6eaedcc36ed235c0d8f778fcc5adaa2ea3edd..ed2dd2a847be9e231d43c47f67ab770ee2af9132 100644 (file)
@@ -20,8 +20,6 @@
  * (easy to change)
  */
 
-#define CONFIG_LEON3           /* This is an LEON3 CPU */
-#define CONFIG_LEON            1       /* This is an LEON CPU */
 /* Altera NIOS Development board, Stratix II board */
 #define CONFIG_GR_EP2S60       1
 
index 39036cdf7e3ece4cc81fd5663595be89f6828978..e3cbb6f5965af7fa89eff870caac14a020092d6c 100644 (file)
@@ -18,8 +18,6 @@
  * (easy to change)
  */
 
-#define CONFIG_LEON3           /* This is an LEON3 CPU */
-#define CONFIG_LEON            1       /* This is an LEON CPU */
 #define CONFIG_GRXC3S1500      1       /* ... on GR-XC3S-1500 board */
 
 /* CPU / AMBA BUS configuration */
index 2d977ceeb6851b5fadf0409b991022c7af15c5dd..556c749f92060c1c44c2bf674c8e7f91b039c4f8 100644 (file)
@@ -24,8 +24,6 @@
  *
  */
 
-#define CONFIG_LEON3                   /* This is an LEON3 CPU */
-#define CONFIG_LEON            1       /* This is an LEON CPU */
 #define CONFIG_GRSIM           0       /* ... not running on GRSIM */
 #define CONFIG_TSIM            1       /* ... running on TSIM */
 
index 36ebaf7ff7ca0f372de49a77ac814a679eadb186..8be98983c9f6a6667b58d1c18fedbeee273fbcfc 100644 (file)
@@ -23,8 +23,6 @@
  *
  */
 
-#define CONFIG_LEON2           /* This is an LEON2 CPU */
-#define CONFIG_LEON            1       /* This is an LEON CPU */
 #define CONFIG_GRSIM           0       /* ... not running on GRSIM */
 #define CONFIG_TSIM            1       /* ... running on TSIM */
 
index 46a3554ff9235607e38fc83e8c1b6321d7bb1113..08679aead95cca90fd4f178d2c5b36e61b061b8e 100644 (file)
@@ -146,7 +146,12 @@ extern unsigned long nand_env_oob_offset;
 extern char *env_name_spec;
 #endif
 
+#ifdef CONFIG_ENV_AES
+/* Make sure the payload is multiple of AES block size */
+#define ENV_SIZE ((CONFIG_ENV_SIZE - ENV_HEADER_SIZE) & ~(16 - 1))
+#else
 #define ENV_SIZE (CONFIG_ENV_SIZE - ENV_HEADER_SIZE)
+#endif
 
 typedef struct environment_s {
        uint32_t        crc;            /* CRC32 over data bytes        */
@@ -154,7 +159,12 @@ typedef struct environment_s {
        unsigned char   flags;          /* active/obsolete flags        */
 #endif
        unsigned char   data[ENV_SIZE]; /* Environment data             */
-} env_t;
+} env_t
+#ifdef CONFIG_ENV_AES
+/* Make sure the env is aligned to block size. */
+__attribute__((aligned(16)))
+#endif
+;
 
 #ifdef ENV_IS_EMBEDDED
 extern env_t environment;
@@ -201,6 +211,9 @@ int set_default_vars(int nvars, char * const vars[]);
 /* Import from binary representation into hash table */
 int env_import(const char *buf, int check);
 
+/* Export from hash table into binary representation */
+int env_export(env_t *env_out);
+
 #endif /* DO_DEPS_ONLY */
 
 #endif /* _ENVIRONMENT_H_ */
index 9871e2f81a09f95d7051c86a739b09bb5ee35817..76c9b2e776ce20469165b1713bc3183c2db5c2d1 100644 (file)
@@ -115,4 +115,9 @@ static inline int fdt_status_disabled_by_alias(void *fdt, const char* alias)
 }
 
 #endif /* ifdef CONFIG_OF_LIBFDT */
+
+#ifdef USE_HOSTCC
+int fdtdec_get_int(const void *blob, int node, const char *prop_name,
+               int default_val);
+#endif
 #endif /* ifndef __FDT_SUPPORT_H */
index e92d27218c486f1dca86368bbca8a788d63e6584..dc21678045e8df71eb30fbb01d72a28c8c92e17e 100644 (file)
@@ -27,6 +27,42 @@ struct hash_algo {
        void (*hash_func_ws)(const unsigned char *input, unsigned int ilen,
                unsigned char *output, unsigned int chunk_sz);
        int chunk_size;                         /* Watchdog chunk size */
+       /*
+        * hash_init: Create the context for progressive hashing
+        *
+        * @algo: Pointer to the hash_algo struct
+        * @ctxp: Pointer to the pointer of the context for hashing
+        * @return 0 if ok, -1 on error
+        */
+       int (*hash_init)(struct hash_algo *algo, void **ctxp);
+       /*
+        * hash_update: Perform hashing on the given buffer
+        *
+        * The context is freed by this function if an error occurs.
+        *
+        * @algo: Pointer to the hash_algo struct
+        * @ctx: Pointer to the context for hashing
+        * @buf: Pointer to the buffer being hashed
+        * @size: Size of the buffer being hashed
+        * @is_last: 1 if this is the last update; 0 otherwise
+        * @return 0 if ok, -1 on error
+        */
+       int (*hash_update)(struct hash_algo *algo, void *ctx, const void *buf,
+                          unsigned int size, int is_last);
+       /*
+        * hash_finish: Write the hash result to the given buffer
+        *
+        * The context is freed by this function.
+        *
+        * @algo: Pointer to the hash_algo struct
+        * @ctx: Pointer to the context for hashing
+        * @dest_buf: Pointer to the buffer for the result
+        * @size: Size of the buffer for the result
+        * @return 0 if ok, -ENOSPC if size of the result buffer is too small
+        *   or -1 on other errors
+        */
+       int (*hash_finish)(struct hash_algo *algo, void *ctx, void *dest_buf,
+                          int size);
 };
 
 /*
@@ -77,4 +113,16 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
 int hash_block(const char *algo_name, const void *data, unsigned int len,
               uint8_t *output, int *output_size);
 
+/**
+ * hash_lookup_algo() - Look up the hash_algo struct for an algorithm
+ *
+ * The function returns the pointer to the struct or -EPROTONOSUPPORT if the
+ * algorithm is not available.
+ *
+ * @algo_name: Hash algorithm to look up
+ * @algop: Pointer to the hash_algo struct if found
+ *
+ * @return 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
+ */
+int hash_lookup_algo(const char *algo_name, struct hash_algo **algop);
 #endif
index 6afd57bafddec7ac067a948897018d3bc334915c..2508d7d2430f100a91741f862655d227c91e169b 100644 (file)
@@ -57,13 +57,18 @@ struct lmb;
 #  ifdef CONFIG_SPL_SHA1_SUPPORT
 #   define IMAGE_ENABLE_SHA1   1
 #  endif
+#  ifdef CONFIG_SPL_SHA256_SUPPORT
+#   define IMAGE_ENABLE_SHA256 1
+#  endif
 # else
 #  define CONFIG_CRC32         /* FIT images need CRC32 support */
 #  define CONFIG_MD5           /* and MD5 */
 #  define CONFIG_SHA1          /* and SHA1 */
+#  define CONFIG_SHA256                /* and SHA256 */
 #  define IMAGE_ENABLE_CRC32   1
 #  define IMAGE_ENABLE_MD5     1
 #  define IMAGE_ENABLE_SHA1    1
+#  define IMAGE_ENABLE_SHA256  1
 # endif
 
 #ifndef IMAGE_ENABLE_CRC32
@@ -78,6 +83,10 @@ struct lmb;
 #define IMAGE_ENABLE_SHA1      0
 #endif
 
+#ifndef IMAGE_ENABLE_SHA256
+#define IMAGE_ENABLE_SHA256    0
+#endif
+
 #endif /* CONFIG_FIT */
 
 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
@@ -823,7 +832,8 @@ int calculate_hash(const void *data, int data_len, const char *algo,
 #if defined(CONFIG_FIT_SIGNATURE)
 # ifdef USE_HOSTCC
 #  define IMAGE_ENABLE_SIGN    1
-#  define IMAGE_ENABLE_VERIFY  0
+#  define IMAGE_ENABLE_VERIFY  1
+# include  <openssl/evp.h>
 #else
 #  define IMAGE_ENABLE_SIGN    0
 #  define IMAGE_ENABLE_VERIFY  1
@@ -834,7 +844,9 @@ int calculate_hash(const void *data, int data_len, const char *algo,
 #endif
 
 #ifdef USE_HOSTCC
-# define gd_fdt_blob()         NULL
+void *image_get_host_blob(void);
+void image_set_host_blob(void *host_blob);
+# define gd_fdt_blob()         image_get_host_blob()
 #else
 # define gd_fdt_blob()         (gd->fdt_blob)
 #endif
@@ -863,6 +875,21 @@ struct image_region {
        int size;
 };
 
+#if IMAGE_ENABLE_VERIFY
+# include <rsa-checksum.h>
+#endif
+struct checksum_algo {
+       const char *name;
+       const int checksum_len;
+       const int pad_len;
+#if IMAGE_ENABLE_SIGN
+       const EVP_MD *(*calculate_sign)(void);
+#endif
+       void (*calculate)(const struct image_region region[],
+                         int region_count, uint8_t *checksum);
+       const uint8_t *rsa_padding;
+};
+
 struct image_sig_algo {
        const char *name;               /* Name of algorithm */
 
@@ -913,6 +940,9 @@ struct image_sig_algo {
        int (*verify)(struct image_sign_info *info,
                      const struct image_region region[], int region_count,
                      uint8_t *sig, uint sig_len);
+
+       /* pointer to checksum algorithm */
+       struct checksum_algo *checksum;
 };
 
 /**
@@ -978,7 +1008,11 @@ struct image_region *fit_region_make_list(const void *fit,
 
 static inline int fit_image_check_target_arch(const void *fdt, int node)
 {
+#ifndef USE_HOSTCC
        return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT);
+#else
+       return 0;
+#endif
 }
 
 #ifdef CONFIG_FIT_VERBOSE
diff --git a/include/rsa-checksum.h b/include/rsa-checksum.h
new file mode 100644 (file)
index 0000000..612db85
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013, Andreas Oetken.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+*/
+
+#ifndef _RSA_CHECKSUM_H
+#define _RSA_CHECKSUM_H
+
+#include <errno.h>
+#include <image.h>
+#include <sha1.h>
+#include <sha256.h>
+
+extern const uint8_t padding_sha256_rsa4096[];
+extern const uint8_t padding_sha256_rsa2048[];
+extern const uint8_t padding_sha1_rsa2048[];
+
+void sha256_calculate(const struct image_region region[], int region_count,
+                     uint8_t *checksum);
+void sha1_calculate(const struct image_region region[], int region_count,
+                   uint8_t *checksum);
+
+#endif
index add4c789f335488f3ed5442365acf9a95dc49d84..a5680ab88c134ded0f3c4814d7d645fc0b0de3bd 100644 (file)
 #include <errno.h>
 #include <image.h>
 
+/**
+ * struct rsa_public_key - holder for a public key
+ *
+ * An RSA public key consists of a modulus (typically called N), the inverse
+ * and R^2, where R is 2^(# key bits).
+ */
+
+struct rsa_public_key {
+       uint len;               /* len of modulus[] in number of uint32_t */
+       uint32_t n0inv;         /* -1 / modulus[0] mod 2^32 */
+       uint32_t *modulus;      /* modulus as little endian array */
+       uint32_t *rr;           /* R^2 as little endian array */
+};
+
 #if IMAGE_ENABLE_SIGN
 /**
  * sign() - calculate and return signature for given input data
@@ -89,4 +103,14 @@ static inline int rsa_verify(struct image_sign_info *info,
 }
 #endif
 
+#define RSA2048_BYTES  (2048 / 8)
+#define RSA4096_BYTES  (4096 / 8)
+
+/* This is the minimum/maximum key size we support, in bits */
+#define RSA_MIN_KEY_BITS       2048
+#define RSA_MAX_KEY_BITS       4096
+
+/* This is the maximum signature length that we support, in bits */
+#define RSA_MAX_SIG_BITS       4096
+
 #endif
index e996b273ac8633adfaea3d8ee3e2eb63e81c06b8..05c97cd740982f38a57a069507494372adf28e96 100644 (file)
--- a/lib/aes.c
+++ b/lib/aes.c
  * REDISTRIBUTION OF THIS SOFTWARE.
 */
 
+#ifndef USE_HOSTCC
 #include <common.h>
+#else
+#include <string.h>
+#endif
 #include "aes.h"
 
 /* forward s-box */
@@ -580,3 +584,83 @@ void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
 
        memcpy(out, state, sizeof(state));
 }
+
+static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
+{
+#ifdef DEBUG
+       printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
+       print_buffer(0, data, 1, num_bytes, 16);
+#endif
+}
+
+/**
+ * Apply chain data to the destination using EOR
+ *
+ * Each array is of length AES_KEY_LENGTH.
+ *
+ * @cbc_chain_data     Chain data
+ * @src                        Source data
+ * @dst                        Destination data, which is modified here
+ */
+static void apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
+{
+       int i;
+
+       for (i = 0; i < AES_KEY_LENGTH; i++)
+               *dst++ = *src++ ^ *cbc_chain_data++;
+}
+
+void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
+{
+       u8 zero_key[AES_KEY_LENGTH] = { 0 };
+       u8 tmp_data[AES_KEY_LENGTH];
+       /* Convenient array of 0's for IV */
+       u8 *cbc_chain_data = zero_key;
+       u32 i;
+
+       for (i = 0; i < num_aes_blocks; i++) {
+               debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
+               debug_print_vector("AES Src", AES_KEY_LENGTH, src);
+
+               /* Apply the chain data */
+               apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
+               debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
+
+               /* Encrypt the AES block */
+               aes_encrypt(tmp_data, key_exp, dst);
+               debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
+
+               /* Update pointers for next loop. */
+               cbc_chain_data = dst;
+               src += AES_KEY_LENGTH;
+               dst += AES_KEY_LENGTH;
+       }
+}
+
+void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
+{
+       u8 tmp_data[AES_KEY_LENGTH], tmp_block[AES_KEY_LENGTH];
+       /* Convenient array of 0's for IV */
+       u8 cbc_chain_data[AES_KEY_LENGTH] = { 0 };
+       u32 i;
+
+       for (i = 0; i < num_aes_blocks; i++) {
+               debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
+               debug_print_vector("AES Src", AES_KEY_LENGTH, src);
+
+               memcpy(tmp_block, src, AES_KEY_LENGTH);
+
+               /* Decrypt the AES block */
+               aes_decrypt(src, key_exp, tmp_data);
+               debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
+
+               /* Apply the chain data */
+               apply_cbc_chain_data(cbc_chain_data, tmp_data, dst);
+               debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
+
+               /* Update pointers for next loop. */
+               memcpy(cbc_chain_data, tmp_block, AES_KEY_LENGTH);
+               src += AES_KEY_LENGTH;
+               dst += AES_KEY_LENGTH;
+       }
+}
index 33265ecfb26cb3d378dc78141f1fd4680b0efe0b..8ecb80f1623bfb95ca02ee8c4be133818be0b87d 100644 (file)
@@ -3,6 +3,7 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#ifndef USE_HOSTCC
 #include <common.h>
 #include <serial.h>
 #include <libfdt.h>
@@ -645,3 +646,22 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
 
        return 0;
 }
+#else
+#include "libfdt.h"
+#include "fdt_support.h"
+
+int fdtdec_get_int(const void *blob, int node, const char *prop_name,
+               int default_val)
+{
+       const int *cell;
+       int len;
+
+       cell = fdt_getprop_w((void *)blob, node, prop_name, &len);
+       if (cell && len >= sizeof(int)) {
+               int val = fdt32_to_cpu(cell[0]);
+
+               return val;
+       }
+       return default_val;
+}
+#endif
index 164ab3996455fb58f4a590b032327c57f6b11d61..a5a96cb680d16d1cea1f88375f2ca1ec7bfc1776 100644 (file)
@@ -7,4 +7,4 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o
+obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
new file mode 100644 (file)
index 0000000..32d6602
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2013, Andreas Oetken.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#include <fdtdec.h>
+#include <asm/byteorder.h>
+#include <asm/errno.h>
+#include <asm/unaligned.h>
+#else
+#include "fdt_host.h"
+#endif
+#include <rsa.h>
+#include <sha1.h>
+#include <sha256.h>
+
+/* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
+
+const uint8_t padding_sha256_rsa2048[RSA2048_BYTES - SHA256_SUM_LEN] = {
+0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
+0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+0x00, 0x04, 0x20
+};
+
+const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = {
+       0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
+       0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
+       0x05, 0x00, 0x04, 0x14
+};
+
+const uint8_t padding_sha256_rsa4096[RSA4096_BYTES - SHA256_SUM_LEN] = {
+       0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
+       0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+       0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+};
+
+void sha1_calculate(const struct image_region region[], int region_count,
+                   uint8_t *checksum)
+{
+       sha1_context ctx;
+       uint32_t i;
+       i = 0;
+
+       sha1_starts(&ctx);
+       for (i = 0; i < region_count; i++)
+               sha1_update(&ctx, region[i].data, region[i].size);
+       sha1_finish(&ctx, checksum);
+}
+
+void sha256_calculate(const struct image_region region[], int region_count,
+                     uint8_t *checksum)
+{
+       sha256_context ctx;
+       uint32_t i;
+       i = 0;
+
+       sha256_starts(&ctx);
+       for (i = 0; i < region_count; i++)
+               sha256_update(&ctx, region[i].data, region[i].size);
+       sha256_finish(&ctx, checksum);
+}
index 549130eda1f3a41759522c1e2b84798061fcf08c..ca8c120d97cf96b0de668674a8d84194139cc9c6 100644 (file)
@@ -159,8 +159,9 @@ static void rsa_remove(void)
        EVP_cleanup();
 }
 
-static int rsa_sign_with_key(RSA *rsa, const struct image_region region[],
-               int region_count, uint8_t **sigp, uint *sig_size)
+static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
+               const struct image_region region[], int region_count,
+               uint8_t **sigp, uint *sig_size)
 {
        EVP_PKEY *key;
        EVP_MD_CTX *context;
@@ -192,7 +193,7 @@ static int rsa_sign_with_key(RSA *rsa, const struct image_region region[],
                goto err_create;
        }
        EVP_MD_CTX_init(context);
-       if (!EVP_SignInit(context, EVP_sha1())) {
+       if (!EVP_SignInit(context, checksum_algo->calculate_sign())) {
                ret = rsa_err("Signer setup failed");
                goto err_sign;
        }
@@ -242,7 +243,8 @@ int rsa_sign(struct image_sign_info *info,
        ret = rsa_get_priv_key(info->keydir, info->keyname, &rsa);
        if (ret)
                goto err_priv;
-       ret = rsa_sign_with_key(rsa, region, region_count, sigp, sig_len);
+       ret = rsa_sign_with_key(rsa, info->algo->checksum, region,
+                               region_count, sigp, sig_len);
        if (ret)
                goto err_sign;
 
index 02cc4e335309becf02288fff81167cdca6734bab..587da5b470685de78ebc86bf611c0abf8fd0c387 100644 (file)
@@ -4,70 +4,27 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#ifndef USE_HOSTCC
 #include <common.h>
 #include <fdtdec.h>
-#include <rsa.h>
-#include <sha1.h>
+#include <asm/types.h>
 #include <asm/byteorder.h>
 #include <asm/errno.h>
+#include <asm/types.h>
 #include <asm/unaligned.h>
-
-/**
- * struct rsa_public_key - holder for a public key
- *
- * An RSA public key consists of a modulus (typically called N), the inverse
- * and R^2, where R is 2^(# key bits).
- */
-struct rsa_public_key {
-       uint len;               /* Length of modulus[] in number of uint32_t */
-       uint32_t n0inv;         /* -1 / modulus[0] mod 2^32 */
-       uint32_t *modulus;      /* modulus as little endian array */
-       uint32_t *rr;           /* R^2 as little endian array */
-};
+#else
+#include "fdt_host.h"
+#include "mkimage.h"
+#include <fdt_support.h>
+#endif
+#include <rsa.h>
+#include <sha1.h>
+#include <sha256.h>
 
 #define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
 
-#define RSA2048_BYTES  (2048 / 8)
-
-/* This is the minimum/maximum key size we support, in bits */
-#define RSA_MIN_KEY_BITS       2048
-#define RSA_MAX_KEY_BITS       2048
-
-/* This is the maximum signature length that we support, in bits */
-#define RSA_MAX_SIG_BITS       2048
-
-static const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = {
-       0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
-       0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
-       0x05, 0x00, 0x04, 0x14
-};
+#define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a)
+#define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a))
 
 /**
  * subtract_modulus() - subtract modulus from the given value
@@ -204,18 +161,18 @@ static int pow_mod(const struct rsa_public_key *key, uint32_t *inout)
        /* Convert to bigendian byte array */
        for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
                put_unaligned_be32(result[i], ptr);
-
        return 0;
 }
 
 static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
-               const uint32_t sig_len, const uint8_t *hash)
+                         const uint32_t sig_len, const uint8_t *hash,
+                         struct checksum_algo *algo)
 {
        const uint8_t *padding;
        int pad_len;
        int ret;
 
-       if (!key || !sig || !hash)
+       if (!key || !sig || !hash || !algo)
                return -EIO;
 
        if (sig_len != (key->len * sizeof(uint32_t))) {
@@ -223,6 +180,8 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
                return -EINVAL;
        }
 
+       debug("Checksum algorithm: %s", algo->name);
+
        /* Sanity check for stack size */
        if (sig_len > RSA_MAX_SIG_BITS / 8) {
                debug("Signature length %u exceeds maximum %d\n", sig_len,
@@ -238,9 +197,8 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
        if (ret)
                return ret;
 
-       /* Determine padding to use depending on the signature type. */
-       padding = padding_sha1_rsa2048;
-       pad_len = RSA2048_BYTES - SHA1_SUM_LEN;
+       padding = algo->rsa_padding;
+       pad_len = algo->pad_len - algo->checksum_len;
 
        /* Check pkcs1.5 padding bytes. */
        if (memcmp(buf, padding, pad_len)) {
@@ -309,7 +267,7 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
        }
 
        debug("key length %d\n", key.len);
-       ret = rsa_verify_key(&key, sig, sig_len, hash);
+       ret = rsa_verify_key(&key, sig, sig_len, hash, info->algo->checksum);
        if (ret) {
                printf("%s: RSA failed to verify: %d\n", __func__, ret);
                return ret;
@@ -323,12 +281,23 @@ int rsa_verify(struct image_sign_info *info,
               uint8_t *sig, uint sig_len)
 {
        const void *blob = info->fdt_blob;
-       uint8_t hash[SHA1_SUM_LEN];
+       /* Reserve memory for maximum checksum-length */
+       uint8_t hash[info->algo->checksum->pad_len];
        int ndepth, noffset;
        int sig_node, node;
        char name[100];
-       sha1_context ctx;
-       int ret, i;
+       int ret;
+
+       /*
+        * Verify that the checksum-length does not exceed the
+        * rsa-signature-length
+        */
+       if (info->algo->checksum->checksum_len >
+           info->algo->checksum->pad_len) {
+               debug("%s: invlaid checksum-algorithm %s for %s\n",
+                     __func__, info->algo->checksum->name, info->algo->name);
+               return -EINVAL;
+       }
 
        sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
        if (sig_node < 0) {
@@ -336,10 +305,8 @@ int rsa_verify(struct image_sign_info *info,
                return -ENOENT;
        }
 
-       sha1_starts(&ctx);
-       for (i = 0; i < region_count; i++)
-               sha1_update(&ctx, region[i].data, region[i].size);
-       sha1_finish(&ctx, hash);
+       /* Calculate checksum with checksum-algorithm */
+       info->algo->checksum->calculate(region, region_count, hash);
 
        /* See if we must use a particular key */
        if (info->required_keynode != -1) {
index 7348162575ceaccda1fa0100298e47e2f0e25af9..3212baba5f6c253f635220bd55b0c31707ae9341 100644 (file)
@@ -258,14 +258,15 @@ void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
 {
        sha256_context ctx;
 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-       unsigned char *end, *curr;
+       const unsigned char *end;
+       unsigned char *curr;
        int chunk;
 #endif
 
        sha256_starts(&ctx);
 
 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-       curr = input;
+       curr = (unsigned char *)input;
        end = input + ilen;
        while (curr < end) {
                chunk = end - curr;
diff --git a/test/vboot/sign-configs-sha256.its b/test/vboot/sign-configs-sha256.its
new file mode 100644 (file)
index 0000000..1b3432e
--- /dev/null
@@ -0,0 +1,45 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       hash@1 {
+                               algo = "sha256";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       hash@1 {
+                               algo = "sha256";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                               sign-images = "fdt", "kernel";
+                       };
+               };
+       };
+};
diff --git a/test/vboot/sign-images-sha256.its b/test/vboot/sign-images-sha256.its
new file mode 100644 (file)
index 0000000..e6aa9fc
--- /dev/null
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+               };
+       };
+};
index bb2c6051c8a41bb7d82214dad884d27d6c2570f9..3c6efa774ec72c3dbd790b31e2946a063eabcfb1 100755 (executable)
@@ -47,6 +47,7 @@ O=$(readlink -f ${O})
 dtc="-I dts -O dtb -p 2000"
 uboot="${O}/u-boot"
 mkimage="${O}/tools/mkimage"
+fit_check_sign="${O}/tools/fit_check_sign"
 keys="${dir}/dev-keys"
 echo ${mkimage} -D "${dtc}"
 
@@ -61,47 +62,76 @@ openssl req -batch -new -x509 -key ${keys}/dev.key -out ${keys}/dev.crt
 
 pushd ${dir} >/dev/null
 
-# Compile our device tree files for kernel and U-Boot (CONFIG_OF_CONTROL)
-dtc -p 0x1000 sandbox-kernel.dts -O dtb -o sandbox-kernel.dtb
-dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
+function do_test {
+       echo do $sha test
+       # Compile our device tree files for kernel and U-Boot
+       dtc -p 0x1000 sandbox-kernel.dts -O dtb -o sandbox-kernel.dtb
+       dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
 
-# Create a number kernel image with zeroes
-head -c 5000 /dev/zero >test-kernel.bin
+       # Create a number kernel image with zeroes
+       head -c 5000 /dev/zero >test-kernel.bin
 
-# Build the FIT, but don't sign anything yet
-echo Build FIT with signed images
-${mkimage} -D "${dtc}" -f sign-images.its test.fit >${tmp}
+       # Build the FIT, but don't sign anything yet
+       echo Build FIT with signed images
+       ${mkimage} -D "${dtc}" -f sign-images-$sha.its test.fit >${tmp}
 
-run_uboot "unsigned signatures:" "dev-"
+       run_uboot "unsigned signatures:" "dev-"
 
-# Sign images with our dev keys
-echo Sign images
-${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp}
+       # Sign images with our dev keys
+       echo Sign images
+       ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \
+               -r test.fit >${tmp}
 
-run_uboot "signed images" "dev+"
+       run_uboot "signed images" "dev+"
 
 
-# Create a fresh .dtb without the public keys
-dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
+       # Create a fresh .dtb without the public keys
+       dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
 
-echo Build FIT with signed configuration
-${mkimage} -D "${dtc}" -f sign-configs.its test.fit >${tmp}
+       echo Build FIT with signed configuration
+       ${mkimage} -D "${dtc}" -f sign-configs-$sha.its test.fit >${tmp}
 
-run_uboot "unsigned config" "sha1+ OK"
+       run_uboot "unsigned config" $sha"+ OK"
 
-# Sign images with our dev keys
-echo Sign images
-${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp}
+       # Sign images with our dev keys
+       echo Sign images
+       ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \
+               -r test.fit >${tmp}
 
-run_uboot "signed config" "dev+"
+       run_uboot "signed config" "dev+"
 
-# Increment the first byte of the signature, which should cause failure
-sig=$(fdtget -t bx test.fit /configurations/conf@1/signature@1 value)
-newbyte=$(printf %x $((0x${sig:0:2} + 1)))
-sig="${newbyte} ${sig:2}"
-fdtput -t bx test.fit /configurations/conf@1/signature@1 value ${sig}
+       echo check signed config on the host
+       if ! ${fit_check_sign} -f test.fit -k sandbox-u-boot.dtb >${tmp}; then
+               echo
+               echo "Verified boot key check on host failed, output follows:"
+               cat ${tmp}
+               false
+       else
+               if ! grep -q "dev+" ${tmp}; then
+                       echo
+                       echo "Verified boot key check failed, output follows:"
+                       cat ${tmp}
+                       false
+               else
+                       echo "OK"
+               fi
+       fi
+
+       run_uboot "signed config" "dev+"
+
+       # Increment the first byte of the signature, which should cause failure
+       sig=$(fdtget -t bx test.fit /configurations/conf@1/signature@1 value)
+       newbyte=$(printf %x $((0x${sig:0:2} + 1)))
+       sig="${newbyte} ${sig:2}"
+       fdtput -t bx test.fit /configurations/conf@1/signature@1 value ${sig}
+
+       run_uboot "signed config with bad hash" "Bad Data Hash"
+}
 
-run_uboot "signed config with bad hash" "Bad Data Hash"
+sha=sha1
+do_test
+sha=sha256
+do_test
 
 popd >/dev/null
 
index 2a90dfe83a52339e2434207f192e475bdaa245d0..b1e997fc3ee0018efb954ad858201e01ca3c3d82 100644 (file)
@@ -1,5 +1,7 @@
 /bmp_logo
 /envcrc
+/fit_check_sign
+/fit_info
 /gen_eth_addr
 /img2srec
 /kwboot
index 097cc1df17838af2f0904f1f6a361efb94d328d2..c5c378cf86f2163bfb79d3c1b660e84ceb22866f 100644 (file)
@@ -40,7 +40,6 @@ CONFIG_BUILD_ENVCRC ?= $(ENVCRC-y)
 
 # TODO: CONFIG_CMD_LICENSE does not work
 hostprogs-$(CONFIG_CMD_LICENSE) += bin2header$(SFX)
-
 hostprogs-$(CONFIG_LCD_LOGO) += bmp_logo$(SFX)
 hostprogs-$(CONFIG_VIDEO_LOGO) += bmp_logo$(SFX)
 HOSTCFLAGS_bmp_logo$(SFX).o := -pedantic
@@ -61,17 +60,22 @@ hostprogs-y += mkenvimage$(SFX)
 mkenvimage$(SFX)-objs := crc32.o mkenvimage.o os_support.o
 
 hostprogs-y += dumpimage$(SFX) mkimage$(SFX)
+ifdef CONFIG_FIT_SIGNATURE
+hostprogs-y += fit_info$(SFX) fit_check_sign$(SFX)
+endif
 
 FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := image-sig.o
 # Flattened device tree objects
 LIBFDT_OBJS := fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o
-RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := rsa-sign.o
+RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := rsa-sign.o rsa-verify.o rsa-checksum.o
 
 # common objs for dumpimage and mkimage
 dumpimage-mkimage-objs := aisimage.o \
                        $(FIT_SIG_OBJS-y) \
                        crc32.o \
                        default_image.o \
+                       fdtdec.o \
+                       fit_common.o \
                        fit_image.o \
                        image-fit.o \
                        image-host.o \
@@ -85,12 +89,15 @@ dumpimage-mkimage-objs := aisimage.o \
                        os_support.o \
                        pblimage.o \
                        sha1.o \
+                       sha256.o \
                        ublimage.o \
                        $(LIBFDT_OBJS) \
                        $(RSA_OBJS-y)
 
 dumpimage$(SFX)-objs := $(dumpimage-mkimage-objs) dumpimage.o
 mkimage$(SFX)-objs   := $(dumpimage-mkimage-objs) mkimage.o
+fit_info$(SFX)-objs   := $(dumpimage-mkimage-objs) fit_info.o
+fit_check_sign$(SFX)-objs   := $(dumpimage-mkimage-objs) fit_check_sign.o
 
 # TODO(sjg@chromium.org): Is this correct on Mac OS?
 
@@ -98,6 +105,8 @@ mkimage$(SFX)-objs   := $(dumpimage-mkimage-objs) mkimage.o
 ifneq ($(CONFIG_MX23)$(CONFIG_MX28),)
 HOSTLOADLIBES_dumpimage$(SFX) := -lssl -lcrypto
 HOSTLOADLIBES_mkimage$(SFX) := -lssl -lcrypto
+HOSTLOADLIBES_fit_info$(SFX) := -lssl -lcrypto
+HOSTLOADLIBES_fit_check_sign$(SFX) := -lssl -lcrypto
 # Add CONFIG_MXS into host CFLAGS, so we can check whether or not register
 # the mxsimage support within tools/mxsimage.c .
 HOSTCFLAGS_mxsimage.o += -DCONFIG_MXS
@@ -106,6 +115,8 @@ endif
 ifdef CONFIG_FIT_SIGNATURE
 HOSTLOADLIBES_dumpimage$(SFX) := -lssl -lcrypto
 HOSTLOADLIBES_mkimage$(SFX) := -lssl -lcrypto
+HOSTLOADLIBES_fit_info$(SFX) := -lssl -lcrypto
+HOSTLOADLIBES_fit_check_sign$(SFX) := -lssl -lcrypto
 
 # This affects include/image.h, but including the board config file
 # is tricky, so manually define this options here.
@@ -137,6 +148,7 @@ hostprogs-$(CONFIG_STATIC_RELA) += relocate-rela$(SFX)
 HOSTCFLAGS_crc32.o := -pedantic
 HOSTCFLAGS_md5.o := -pedantic
 HOSTCFLAGS_sha1.o := -pedantic
+HOSTCFLAGS_sha256.o := -pedantic
 
 # Don't build by default
 #hostprogs-$(CONFIG_PPC) += mpc86x_clk$(SFX)
index fcb752ddb44f292eccb6ba09b770c5b35bba1314..f5368bc4d0253286ae4ba08f501f50ea5605ceb0 100644 (file)
@@ -25,7 +25,7 @@ hostprogs-y := fw_printenv_unstripped
 
 fw_printenv_unstripped-objs := fw_env.o fw_env_main.o \
        crc32.o ctype.o linux_string.o \
-       env_attr.o env_flags.o
+       env_attr.o env_flags.o aes.o
 
 quiet_cmd_strip = STRIP   $@
       cmd_strip = $(STRIP) -o $@ $<
index d228cc34da8637444ee3264597f33bf7a634dfae..fba4c8c6654f0640ddd472d37d11dbf3d7504ac7 100644 (file)
 
 #include "fw_env.h"
 
+#include <aes.h>
+
+#define DIV_ROUND_UP(n, d)     (((n) + (d) - 1) / (d))
+
 #define WHITESPACE(c) ((c == '\t') || (c == ' '))
 
 #define min(x, y) ({                           \
@@ -98,6 +102,11 @@ static struct environment environment = {
        .flag_scheme = FLAG_NONE,
 };
 
+/* Is AES encryption used? */
+static int aes_flag;
+static uint8_t aes_key[AES_KEY_LENGTH] = { 0 };
+static int env_aes_cbc_crypt(char *data, const int enc);
+
 static int HaveRedundEnv = 0;
 
 static unsigned char active_flag = 1;
@@ -120,6 +129,10 @@ static inline ulong getenvsize (void)
 
        if (HaveRedundEnv)
                rc -= sizeof (char);
+
+       if (aes_flag)
+               rc &= ~(AES_KEY_LENGTH - 1);
+
        return rc;
 }
 
@@ -191,6 +204,36 @@ char *fw_getdefenv(char *name)
        return NULL;
 }
 
+static int parse_aes_key(char *key)
+{
+       char tmp[5] = { '0', 'x', 0, 0, 0 };
+       unsigned long ul;
+       int i;
+
+       if (strnlen(key, 64) != 32) {
+               fprintf(stderr,
+                       "## Error: '-a' option requires 16-byte AES key\n");
+               return -1;
+       }
+
+       for (i = 0; i < 16; i++) {
+               tmp[2] = key[0];
+               tmp[3] = key[1];
+               errno = 0;
+               ul = strtoul(tmp, NULL, 16);
+               if (errno) {
+                       fprintf(stderr,
+                               "## Error: '-a' option requires valid AES key\n");
+                       return -1;
+               }
+               aes_key[i] = ul & 0xff;
+               key += 2;
+       }
+       aes_flag = 1;
+
+       return 0;
+}
+
 /*
  * Print the current definition of one, or more, or all
  * environment variables
@@ -201,6 +244,19 @@ int fw_printenv (int argc, char *argv[])
        int i, n_flag;
        int rc = 0;
 
+       if (argc >= 2 && strcmp(argv[1], "-a") == 0) {
+               if (argc < 3) {
+                       fprintf(stderr,
+                               "## Error: '-a' option requires AES key\n");
+                       return -1;
+               }
+               rc = parse_aes_key(argv[2]);
+               if (rc)
+                       return rc;
+               argv += 2;
+               argc -= 2;
+       }
+
        if (fw_env_open())
                return -1;
 
@@ -266,6 +322,16 @@ int fw_printenv (int argc, char *argv[])
 
 int fw_env_close(void)
 {
+       int ret;
+       if (aes_flag) {
+               ret = env_aes_cbc_crypt(environment.data, 1);
+               if (ret) {
+                       fprintf(stderr,
+                               "Error: can't encrypt env for flash\n");
+                       return ret;
+               }
+       }
+
        /*
         * Update CRC
         */
@@ -413,7 +479,7 @@ int fw_env_write(char *name, char *value)
  */
 int fw_setenv(int argc, char *argv[])
 {
-       int i;
+       int i, rc;
        size_t len;
        char *name;
        char *value = NULL;
@@ -423,6 +489,24 @@ int fw_setenv(int argc, char *argv[])
                return -1;
        }
 
+       if (strcmp(argv[1], "-a") == 0) {
+               if (argc < 3) {
+                       fprintf(stderr,
+                               "## Error: '-a' option requires AES key\n");
+                       return -1;
+               }
+               rc = parse_aes_key(argv[2]);
+               if (rc)
+                       return rc;
+               argv += 2;
+               argc -= 2;
+       }
+
+       if (argc < 2) {
+               errno = EINVAL;
+               return -1;
+       }
+
        if (fw_env_open()) {
                fprintf(stderr, "Error: environment not initialized\n");
                return -1;
@@ -900,6 +984,28 @@ static int flash_flag_obsolete (int dev, int fd, off_t offset)
        return rc;
 }
 
+/* Encrypt or decrypt the environment before writing or reading it. */
+static int env_aes_cbc_crypt(char *payload, const int enc)
+{
+       uint8_t *data = (uint8_t *)payload;
+       const int len = getenvsize();
+       uint8_t key_exp[AES_EXPAND_KEY_LENGTH];
+       uint32_t aes_blocks;
+
+       /* First we expand the key. */
+       aes_expand_key(aes_key, key_exp);
+
+       /* Calculate the number of AES blocks to encrypt. */
+       aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH);
+
+       if (enc)
+               aes_cbc_encrypt_blocks(key_exp, data, data, aes_blocks);
+       else
+               aes_cbc_decrypt_blocks(key_exp, data, data, aes_blocks);
+
+       return 0;
+}
+
 static int flash_write (int fd_current, int fd_target, int dev_target)
 {
        int rc;
@@ -923,6 +1029,7 @@ static int flash_write (int fd_current, int fd_target, int dev_target)
        fprintf(stderr, "Writing new environment at 0x%lx on %s\n",
                DEVOFFSET (dev_target), DEVNAME (dev_target));
 #endif
+
        rc = flash_write_buf(dev_target, fd_target, environment.image,
                              CUR_ENVSIZE, DEVOFFSET(dev_target),
                              DEVTYPE(dev_target));
@@ -981,8 +1088,10 @@ static int flash_read (int fd)
 
        rc = flash_read_buf(dev_current, fd, environment.image, CUR_ENVSIZE,
                             DEVOFFSET (dev_current), mtdinfo.type);
+       if (rc != CUR_ENVSIZE)
+               return -1;
 
-       return (rc != CUR_ENVSIZE) ? -1 : 0;
+       return 0;
 }
 
 static int flash_io (int mode)
@@ -1075,6 +1184,8 @@ int fw_env_open(void)
        unsigned char flag1;
        void *addr1;
 
+       int ret;
+
        struct env_image_single *single;
        struct env_image_redundant *redundant;
 
@@ -1109,6 +1220,13 @@ int fw_env_open(void)
                return -1;
 
        crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE);
+
+       if (aes_flag) {
+               ret = env_aes_cbc_crypt(environment.data, 0);
+               if (ret)
+                       return ret;
+       }
+
        crc0_ok = (crc0 == *environment.crc);
        if (!HaveRedundEnv) {
                if (!crc0_ok) {
@@ -1159,6 +1277,13 @@ int fw_env_open(void)
                }
 
                crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE);
+
+               if (aes_flag) {
+                       ret = env_aes_cbc_crypt(redundant->data, 0);
+                       if (ret)
+                               return ret;
+               }
+
                crc1_ok = (crc1 == redundant->crc);
                flag1 = redundant->flags;
 
index 2b85d78864561d9414e085cfbd8081fa305112b9..ce50d58b64648d853ae79fa697167557d6b8ea75 100644 (file)
@@ -9,18 +9,22 @@
  * Command line user interface to firmware (=U-Boot) environment.
  *
  * Implements:
- *     fw_printenv [[ -n name ] | [ name ... ]]
+ *     fw_printenv [ -a key ] [[ -n name ] | [ name ... ]]
  *              - prints the value of a single environment variable
  *                "name", the ``name=value'' pairs of one or more
  *                environment variables "name", or the whole
  *                environment if no names are specified.
- *     fw_setenv name [ value ... ]
+ *     fw_setenv [ -a key ] name [ value ... ]
  *             - If a name without any values is given, the variable
  *               with this name is deleted from the environment;
  *               otherwise, all "value" arguments are concatenated,
  *               separated by single blank characters, and the
  *               resulting string is assigned to the environment
  *               variable "name"
+ *
+ * If '-a key' is specified, the env block is encrypted with AES 128 CBC.
+ * The 'key' argument is in the format of 32 hexadecimal numbers (16 bytes
+ * of AES key), eg. '-a aabbccddeeff00112233445566778899'.
  */
 
 #include <fcntl.h>
@@ -46,8 +50,8 @@ void usage(void)
 
        fprintf(stderr, "fw_printenv/fw_setenv, "
                "a command line interface to U-Boot environment\n\n"
-               "usage:\tfw_printenv [-n] [variable name]\n"
-               "\tfw_setenv [variable name] [variable value]\n"
+               "usage:\tfw_printenv [-a key] [-n] [variable name]\n"
+               "\tfw_setenv [-a key] [variable name] [variable value]\n"
                "\tfw_setenv -s [ file ]\n"
                "\tfw_setenv -s - < [ file ]\n\n"
                "The file passed as argument contains only pairs "
@@ -94,9 +98,12 @@ int main(int argc, char *argv[])
                cmdname = p + 1;
        }
 
-       while ((c = getopt_long (argc, argv, "ns:h",
+       while ((c = getopt_long (argc, argv, "a:ns:h",
                long_options, NULL)) != EOF) {
                switch (c) {
+               case 'a':
+                       /* AES key, handled later */
+                       break;
                case 'n':
                        /* handled in fw_printenv */
                        break;
index c2b23c6217fce0ac39c9c91f758cd2b77dfdc64b..134d9657139b4347257bf34ae644ed08a0fb674d 100644 (file)
@@ -11,4 +11,6 @@
 #include "../include/libfdt.h"
 #include "../include/fdt_support.h"
 
+int fit_check_sign(const void *working_fdt, const void *key);
+
 #endif /* __FDT_HOST_H__ */
diff --git a/tools/fdtdec.c b/tools/fdtdec.c
new file mode 100644 (file)
index 0000000..f1c2256
--- /dev/null
@@ -0,0 +1 @@
+#include "../lib/fdtdec.c"
diff --git a/tools/fit_check_sign.c b/tools/fit_check_sign.c
new file mode 100644 (file)
index 0000000..d6d9340
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * (C) Copyright 2014
+ * DENX Software Engineering
+ * Heiko Schocher <hs@denx.de>
+ *
+ * Based on:
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd@denx.de
+ *
+ * Updated-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *             FIT image specific code abstracted from mkimage.c
+ *             some functions added to address abstraction
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include "mkimage.h"
+#include "fit_common.h"
+#include <image.h>
+#include <u-boot/crc.h>
+
+void usage(char *cmdname)
+{
+       fprintf(stderr, "Usage: %s -f fit file -k key file\n"
+                        "          -f ==> set fit file which should be checked'\n"
+                        "          -k ==> set key file which contains the key'\n",
+               cmdname);
+       exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+       int ffd = -1;
+       int kfd = -1;
+       struct stat fsbuf;
+       struct stat ksbuf;
+       void *fit_blob;
+       char *fdtfile = NULL;
+       char *keyfile = NULL;
+       char cmdname[50];
+       int ret;
+       void *key_blob;
+       int c;
+
+       strcpy(cmdname, *argv);
+       while ((c = getopt(argc, argv, "f:k:")) != -1)
+               switch (c) {
+               case 'f':
+                       fdtfile = optarg;
+                       break;
+               case 'k':
+                       keyfile = optarg;
+                       break;
+               default:
+                       usage(cmdname);
+                       break;
+       }
+
+       ffd = mmap_fdt(cmdname, fdtfile, &fit_blob, &fsbuf, 0);
+       if (ffd < 0)
+               return EXIT_FAILURE;
+       kfd = mmap_fdt(cmdname, keyfile, &key_blob, &ksbuf, 0);
+       if (ffd < 0)
+               return EXIT_FAILURE;
+
+       image_set_host_blob(key_blob);
+       ret = fit_check_sign(fit_blob, key_blob);
+
+       if (ret)
+               ret = EXIT_SUCCESS;
+       else
+               ret = EXIT_FAILURE;
+
+       (void) munmap((void *)fit_blob, fsbuf.st_size);
+       (void) munmap((void *)key_blob, ksbuf.st_size);
+
+       close(ffd);
+       close(kfd);
+       exit(ret);
+}
diff --git a/tools/fit_common.c b/tools/fit_common.c
new file mode 100644 (file)
index 0000000..ee1767b
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * (C) Copyright 2014
+ * DENX Software Engineering
+ * Heiko Schocher <hs@denx.de>
+ *
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd@denx.de
+ *
+ * Updated-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *             FIT image specific code abstracted from mkimage.c
+ *             some functions added to address abstraction
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include "mkimage.h"
+#include "fit_common.h"
+#include <image.h>
+#include <u-boot/crc.h>
+
+int fit_verify_header(unsigned char *ptr, int image_size,
+                       struct image_tool_params *params)
+{
+       return fdt_check_header(ptr);
+}
+
+int fit_check_image_types(uint8_t type)
+{
+       if (type == IH_TYPE_FLATDT)
+               return EXIT_SUCCESS;
+       else
+               return EXIT_FAILURE;
+}
+
+int mmap_fdt(char *cmdname, const char *fname, void **blobp,
+               struct stat *sbuf, int useunlink)
+{
+       void *ptr;
+       int fd;
+
+       /* Load FIT blob into memory (we need to write hashes/signatures) */
+       fd = open(fname, O_RDWR | O_BINARY);
+
+       if (fd < 0) {
+               fprintf(stderr, "%s: Can't open %s: %s\n",
+                       cmdname, fname, strerror(errno));
+               if (useunlink)
+                       unlink(fname);
+               return -1;
+       }
+
+       if (fstat(fd, sbuf) < 0) {
+               fprintf(stderr, "%s: Can't stat %s: %s\n",
+                       cmdname, fname, strerror(errno));
+               if (useunlink)
+                       unlink(fname);
+               return -1;
+       }
+
+       errno = 0;
+       ptr = mmap(0, sbuf->st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+       if ((ptr == MAP_FAILED) || (errno != 0)) {
+               fprintf(stderr, "%s: Can't read %s: %s\n",
+                       cmdname, fname, strerror(errno));
+               if (useunlink)
+                       unlink(fname);
+               return -1;
+       }
+
+       /* check if ptr has a valid blob */
+       if (fdt_check_header(ptr)) {
+               fprintf(stderr, "%s: Invalid FIT blob\n", cmdname);
+               if (useunlink)
+                       unlink(fname);
+               return -1;
+       }
+
+       *blobp = ptr;
+       return fd;
+}
diff --git a/tools/fit_common.h b/tools/fit_common.h
new file mode 100644 (file)
index 0000000..adf4404
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * (C) Copyright 2014
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _FIT_COMMON_H_
+#define _FIT_COMMON_H_
+
+#include "imagetool.h"
+#include "mkimage.h"
+#include <image.h>
+
+int fit_verify_header(unsigned char *ptr, int image_size,
+                       struct image_tool_params *params);
+
+int fit_check_image_types(uint8_t type);
+
+int mmap_fdt(char *cmdname, const char *fname, void **blobp,
+               struct stat *sbuf, int useunlink);
+
+#endif /* _FIT_COMMON_H_ */
index 1466164f0ae067e643e5cddf54d6da26a32dc12e..eeee484cdec096eecda45ad9942fc8354f38f4f3 100644 (file)
  */
 
 #include "imagetool.h"
+#include "fit_common.h"
 #include "mkimage.h"
 #include <image.h>
 #include <u-boot/crc.h>
 
 static image_header_t header;
 
-static int fit_verify_header (unsigned char *ptr, int image_size,
-                       struct image_tool_params *params)
-{
-       return fdt_check_header(ptr);
-}
-
-static int fit_check_image_types (uint8_t type)
-{
-       if (type == IH_TYPE_FLATDT)
-               return EXIT_SUCCESS;
-       else
-               return EXIT_FAILURE;
-}
-
-int mmap_fdt(struct image_tool_params *params, const char *fname, void **blobp,
-               struct stat *sbuf)
-{
-       void *ptr;
-       int fd;
-
-       /* Load FIT blob into memory (we need to write hashes/signatures) */
-       fd = open(fname, O_RDWR | O_BINARY);
-
-       if (fd < 0) {
-               fprintf(stderr, "%s: Can't open %s: %s\n",
-                       params->cmdname, fname, strerror(errno));
-               unlink(fname);
-               return -1;
-       }
-
-       if (fstat(fd, sbuf) < 0) {
-               fprintf(stderr, "%s: Can't stat %s: %s\n",
-                       params->cmdname, fname, strerror(errno));
-               unlink(fname);
-               return -1;
-       }
-
-       ptr = mmap(0, sbuf->st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-       if (ptr == MAP_FAILED) {
-               fprintf(stderr, "%s: Can't read %s: %s\n",
-                       params->cmdname, fname, strerror(errno));
-               unlink(fname);
-               return -1;
-       }
-
-       /* check if ptr has a valid blob */
-       if (fdt_check_header(ptr)) {
-               fprintf(stderr, "%s: Invalid FIT blob\n", params->cmdname);
-               unlink(fname);
-               return -1;
-       }
-
-       *blobp = ptr;
-       return fd;
-}
-
 /**
  * fit_handle_file - main FIT file processing function
  *
@@ -129,13 +74,14 @@ static int fit_handle_file(struct image_tool_params *params)
        }
 
        if (params->keydest) {
-               destfd = mmap_fdt(params, params->keydest, &dest_blob, &sbuf);
+               destfd = mmap_fdt(params->cmdname, params->keydest,
+                                 &dest_blob, &sbuf, 1);
                if (destfd < 0)
                        goto err_keydest;
                destfd_size = sbuf.st_size;
        }
 
-       tfd = mmap_fdt(params, tmpfile, &ptr, &sbuf);
+       tfd = mmap_fdt(params->cmdname, tmpfile, &ptr, &sbuf, 1);
        if (tfd < 0)
                goto err_mmap;
 
diff --git a/tools/fit_info.c b/tools/fit_info.c
new file mode 100644 (file)
index 0000000..50f3c8e
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2014
+ * DENX Software Engineering
+ * Heiko Schocher <hs@denx.de>
+ *
+ * fit_info: print the offset and the len of a property from
+ *          node in a fit file.
+ *
+ * Based on:
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd@denx.de
+ *
+ * Updated-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *             FIT image specific code abstracted from mkimage.c
+ *             some functions added to address abstraction
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include "mkimage.h"
+#include "fit_common.h"
+#include <image.h>
+#include <u-boot/crc.h>
+
+void usage(char *cmdname)
+{
+       fprintf(stderr, "Usage: %s -f fit file -n node -p property\n"
+                        "          -f ==> set fit file which is used'\n"
+                        "          -n ==> set node name'\n"
+                        "          -p ==> set property name'\n",
+               cmdname);
+       exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+       int ffd = -1;
+       struct stat fsbuf;
+       void *fit_blob;
+       int len;
+       int  nodeoffset;        /* node offset from libfdt */
+       const void *nodep;      /* property node pointer */
+       char *fdtfile = NULL;
+       char *nodename = NULL;
+       char *propertyname = NULL;
+       char cmdname[50];
+       int c;
+
+       strcpy(cmdname, *argv);
+       while ((c = getopt(argc, argv, "f:n:p:")) != -1)
+               switch (c) {
+               case 'f':
+                       fdtfile = optarg;
+                       break;
+               case 'n':
+                       nodename = optarg;
+                       break;
+               case 'p':
+                       propertyname = optarg;
+                       break;
+               default:
+                       usage(cmdname);
+                       break;
+               }
+
+       ffd = mmap_fdt(cmdname, fdtfile, &fit_blob, &fsbuf, 0);
+
+       if (ffd < 0) {
+               printf("Could not open %s\n", fdtfile);
+               exit(EXIT_FAILURE);
+       }
+
+       nodeoffset = fdt_path_offset(fit_blob, nodename);
+       if (nodeoffset < 0) {
+               printf("%s not found.", nodename);
+               exit(EXIT_FAILURE);
+       }
+       nodep = fdt_getprop(fit_blob, nodeoffset, propertyname, &len);
+       if (len == 0) {
+               printf("len == 0 %s\n", propertyname);
+               exit(EXIT_FAILURE);
+       }
+
+       printf("NAME: %s\n", fit_get_name(fit_blob, nodeoffset, NULL));
+       printf("LEN: %d\n", len);
+       printf("OFF: %d\n", (int)(nodep - fit_blob));
+       (void) munmap((void *)fit_blob, fsbuf.st_size);
+
+       close(ffd);
+       exit(EXIT_SUCCESS);
+}
index 0d5c88ca73c6894fded23b5c4e0359c5cb63acdf..651f1c2f8b46727eb6aa9dffc470452b3e641026 100644 (file)
@@ -403,7 +403,7 @@ static int fit_config_get_hash_list(void *fit, int conf_noffset,
                goto err_mem;
 
        /* Get a list of images that we intend to sign */
-       prop = fit_config_get_image_list(fit, conf_noffset, &len,
+       prop = fit_config_get_image_list(fit, sig_offset, &len,
                                        &allow_missing);
        if (!prop)
                return 0;
@@ -695,3 +695,18 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
 
        return 0;
 }
+
+#ifdef CONFIG_FIT_SIGNATURE
+int fit_check_sign(const void *working_fdt, const void *key)
+{
+       int cfg_noffset;
+       int ret;
+
+       cfg_noffset = fit_conf_get_node(working_fdt, NULL);
+       if (!cfg_noffset)
+               return -1;
+
+       ret = fit_config_verify(working_fdt, cfg_noffset);
+       return ret;
+}
+#endif
diff --git a/tools/rsa-checksum.c b/tools/rsa-checksum.c
new file mode 100644 (file)
index 0000000..09033e6
--- /dev/null
@@ -0,0 +1 @@
+#include "../lib/rsa/rsa-checksum.c"
diff --git a/tools/rsa-verify.c b/tools/rsa-verify.c
new file mode 100644 (file)
index 0000000..bb662a1
--- /dev/null
@@ -0,0 +1 @@
+#include "../lib/rsa/rsa-verify.c"
diff --git a/tools/sha256.c b/tools/sha256.c
new file mode 100644 (file)
index 0000000..8ca931f
--- /dev/null
@@ -0,0 +1 @@
+#include "../lib/sha256.c"