Merge branch 'next'

This commit is contained in:
Tom Rini 2014-04-17 14:33:25 -04:00
commit 0f507779ca
62 changed files with 1572 additions and 398 deletions

1
README
View File

@ -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

View 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");
}

View File

@ -7,4 +7,4 @@
PLATFORM_RELFLAGS += -fPIC
PLATFORM_CPPFLAGS += -DCONFIG_LEON
PLATFORM_CPPFLAGS += -DCONFIG_LEON -DCONFIG_LEON2

View File

@ -7,4 +7,4 @@
PLATFORM_RELFLAGS += -fPIC
PLATFORM_CPPFLAGS += -DCONFIG_LEON
PLATFORM_CPPFLAGS += -DCONFIG_LEON -DCONFIG_LEON3

View 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

89
common/cmd_aes.c Normal file
View File

@ -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
);

View 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

View 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)

View File

@ -56,17 +56,12 @@ void env_relocate_spec(void)
int saveenv(void)
{
env_t env_new;
ssize_t len;
char *res;
env_t env_new;
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;
}
env_new.crc = crc32(0, env_new.data, ENV_SIZE);
ret = env_export(&env_new);
if (ret)
return ret;
return write_dataflash(CONFIG_ENV_ADDR,
(unsigned long)&env_new,

View 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) {

View 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",

View 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))

View 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 */

View 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);

View 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);

View 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

View 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,

View 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",

View File

@ -12,6 +12,7 @@
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <hw_sha.h>
#include <hash.h>
#include <sha1.h>
@ -19,6 +20,88 @@
#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;
}

View 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;

View 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)

View 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

View 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_ */

View 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

View 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

View 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 */

View 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 */

View 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 */

View 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_ */

View 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 */

View 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

View 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

24
include/rsa-checksum.h Normal file
View File

@ -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

View File

@ -15,6 +15,20 @@
#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

View File

@ -22,7 +22,11 @@
* 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;
}
}

View 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

View 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

163
lib/rsa/rsa-checksum.c Normal file
View File

@ -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);
}

View 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;

View 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) {

View 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;

View File

@ -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";
};
};
};
};

View File

@ -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";
};
};
};

View File

@ -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 with bad hash" "Bad Data Hash"
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"
}
sha=sha1
do_test
sha=sha256
do_test
popd >/dev/null

2
tools/.gitignore vendored
View File

@ -1,5 +1,7 @@
/bmp_logo
/envcrc
/fit_check_sign
/fit_info
/gen_eth_addr
/img2srec
/kwboot

View 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)

2
tools/env/Makefile vendored
View 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 $@ $<

129
tools/env/fw_env.c vendored
View File

@ -31,6 +31,10 @@
#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;

View 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;

View 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__ */

1
tools/fdtdec.c Normal file
View File

@ -0,0 +1 @@
#include "../lib/fdtdec.c"

85
tools/fit_check_sign.c Normal file
View File

@ -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);
}

86
tools/fit_common.c Normal file
View File

@ -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;
}

22
tools/fit_common.h Normal file
View File

@ -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_ */

View File

@ -15,68 +15,13 @@
*/
#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;

96
tools/fit_info.c Normal file
View File

@ -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);
}

View 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

1
tools/rsa-checksum.c Normal file
View File

@ -0,0 +1 @@
#include "../lib/rsa/rsa-checksum.c"

1
tools/rsa-verify.c Normal file
View File

@ -0,0 +1 @@
#include "../lib/rsa/rsa-verify.c"

1
tools/sha256.c Normal file
View File

@ -0,0 +1 @@
#include "../lib/sha256.c"