diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/board_f.c | 2 | ||||
-rw-r--r-- | common/board_r.c | 7 | ||||
-rw-r--r-- | common/bootstage.c | 1 | ||||
-rw-r--r-- | common/cli.c | 1 | ||||
-rw-r--r-- | common/command.c | 2 | ||||
-rw-r--r-- | common/flash.c | 2 | ||||
-rw-r--r-- | common/image-cipher.c | 167 | ||||
-rw-r--r-- | common/image-fdt.c | 5 | ||||
-rw-r--r-- | common/image-fit.c | 90 | ||||
-rw-r--r-- | common/image.c | 18 | ||||
-rw-r--r-- | common/main.c | 1 | ||||
-rw-r--r-- | common/memsize.c | 1 | ||||
-rw-r--r-- | common/spl/spl.c | 1 | ||||
-rw-r--r-- | common/spl/spl_net.c | 4 | ||||
-rw-r--r-- | common/spl/spl_opensbi.c | 1 | ||||
-rw-r--r-- | common/update.c | 4 |
17 files changed, 290 insertions, 18 deletions
diff --git a/common/Makefile b/common/Makefile index 029cc0f2ce6..5f62b8d0b13 100644 --- a/common/Makefile +++ b/common/Makefile @@ -113,6 +113,7 @@ obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += image-sig.o +obj-$(CONFIG_$(SPL_TPL_)FIT_CIPHER) += image-cipher.o obj-$(CONFIG_IO_TRACE) += iotrace.o obj-y += memsize.o obj-y += stdio.o diff --git a/common/board_f.c b/common/board_f.c index d66afb37ca2..3f0132a6e33 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -11,6 +11,7 @@ #include <common.h> #include <bloblist.h> +#include <clock_legacy.h> #include <console.h> #include <cpu.h> #include <cpu_func.h> @@ -19,6 +20,7 @@ #include <env_internal.h> #include <fdtdec.h> #include <fs.h> +#include <hang.h> #include <i2c.h> #include <init.h> #include <initcall.h> diff --git a/common/board_r.c b/common/board_r.c index e711de64b5b..8a0c1114e77 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -12,7 +12,11 @@ #include <common.h> #include <api.h> #include <cpu_func.h> +#include <exports.h> +#include <hang.h> +#include <image.h> #include <irq_func.h> +#include <net.h> #include <u-boot/crc.h> /* TODO: can we just include all these headers whether needed or not? */ #if defined(CONFIG_CMD_BEDBUG) @@ -26,6 +30,7 @@ #include <env_internal.h> #include <fdtdec.h> #include <ide.h> +#include <init.h> #include <initcall.h> #if defined(CONFIG_CMD_KGDB) #include <kgdb.h> @@ -481,7 +486,7 @@ static int initr_env(void) #endif /* Initialize from environment */ - load_addr = env_get_ulong("loadaddr", 16, load_addr); + image_load_addr = env_get_ulong("loadaddr", 16, image_load_addr); return 0; } diff --git a/common/bootstage.c b/common/bootstage.c index 79972e46f29..d2ed33663b7 100644 --- a/common/bootstage.c +++ b/common/bootstage.c @@ -10,6 +10,7 @@ */ #include <common.h> +#include <hang.h> #include <malloc.h> #include <sort.h> #include <spl.h> diff --git a/common/cli.c b/common/cli.c index 67ceb635a67..7ffe902b88d 100644 --- a/common/cli.c +++ b/common/cli.c @@ -15,6 +15,7 @@ #include <console.h> #include <env.h> #include <fdtdec.h> +#include <hang.h> #include <malloc.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/common/command.c b/common/command.c index ceca9925107..0d8bf244be2 100644 --- a/common/command.c +++ b/common/command.c @@ -469,7 +469,7 @@ int cmd_get_data_size(char* arg, int default_size) return 2; case 'l': return 4; -#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA case 'q': return 8; #endif diff --git a/common/flash.c b/common/flash.c index efe8f53de66..5f155aefd1d 100644 --- a/common/flash.c +++ b/common/flash.c @@ -179,7 +179,7 @@ flash_write (char *src, ulong addr, ulong cnt) /*----------------------------------------------------------------------- */ -void flash_perror (int err) +void flash_perror(int err) { switch (err) { case ERR_OK: diff --git a/common/image-cipher.c b/common/image-cipher.c new file mode 100644 index 00000000000..cee3b03ee50 --- /dev/null +++ b/common/image-cipher.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2019, Softathome + */ + +#ifdef USE_HOSTCC +#include "mkimage.h" +#include <time.h> +#else +#include <common.h> +#include <malloc.h> +DECLARE_GLOBAL_DATA_PTR; +#endif /* !USE_HOSTCC*/ +#include <image.h> +#include <uboot_aes.h> +#include <u-boot/aes.h> + +struct cipher_algo cipher_algos[] = { + { + .name = "aes128", + .key_len = AES128_KEY_LENGTH, + .iv_len = AES_BLOCK_LENGTH, +#if IMAGE_ENABLE_ENCRYPT + .calculate_type = EVP_aes_128_cbc, +#endif + .encrypt = image_aes_encrypt, + .decrypt = image_aes_decrypt, + .add_cipher_data = image_aes_add_cipher_data + }, + { + .name = "aes192", + .key_len = AES192_KEY_LENGTH, + .iv_len = AES_BLOCK_LENGTH, +#if IMAGE_ENABLE_ENCRYPT + .calculate_type = EVP_aes_192_cbc, +#endif + .encrypt = image_aes_encrypt, + .decrypt = image_aes_decrypt, + .add_cipher_data = image_aes_add_cipher_data + }, + { + .name = "aes256", + .key_len = AES256_KEY_LENGTH, + .iv_len = AES_BLOCK_LENGTH, +#if IMAGE_ENABLE_ENCRYPT + .calculate_type = EVP_aes_256_cbc, +#endif + .encrypt = image_aes_encrypt, + .decrypt = image_aes_decrypt, + .add_cipher_data = image_aes_add_cipher_data + } +}; + +struct cipher_algo *image_get_cipher_algo(const char *full_name) +{ + int i; + const char *name; + + for (i = 0; i < ARRAY_SIZE(cipher_algos); i++) { + name = cipher_algos[i].name; + if (!strncmp(name, full_name, strlen(name))) + return &cipher_algos[i]; + } + + return NULL; +} + +static int fit_image_setup_decrypt(struct image_cipher_info *info, + const void *fit, int image_noffset, + int cipher_noffset) +{ + const void *fdt = gd_fdt_blob(); + const char *node_name; + char node_path[128]; + int noffset; + char *algo_name; + int ret; + + node_name = fit_get_name(fit, image_noffset, NULL); + if (!node_name) { + printf("Can't get node name\n"); + return -1; + } + + if (fit_image_cipher_get_algo(fit, cipher_noffset, &algo_name)) { + printf("Can't get algo name for cipher '%s' in image '%s'\n", + node_name, node_name); + return -1; + } + + info->keyname = fdt_getprop(fit, cipher_noffset, "key-name-hint", NULL); + if (!info->keyname) { + printf("Can't get key name\n"); + return -1; + } + + info->ivname = fdt_getprop(fit, cipher_noffset, "iv-name-hint", NULL); + if (!info->ivname) { + printf("Can't get IV name\n"); + return -1; + } + + info->fit = fit; + info->node_noffset = image_noffset; + info->name = algo_name; + info->cipher = image_get_cipher_algo(algo_name); + if (!info->cipher) { + printf("Can't get cipher\n"); + return -1; + } + + ret = fit_image_get_data_size_unciphered(fit, image_noffset, + &info->size_unciphered); + if (ret) { + printf("Can't get size of unciphered data\n"); + return -1; + } + + /* + * Search the cipher node in the u-boot fdt + * the path should be: /cipher/key-<algo>-<key>-<iv> + */ + snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s-%s", + FIT_CIPHER_NODENAME, algo_name, info->keyname, info->ivname); + + noffset = fdt_path_offset(fdt, node_path); + if (noffset < 0) { + printf("Can't found cipher node offset\n"); + return -1; + } + + /* read key */ + info->key = fdt_getprop(fdt, noffset, "key", NULL); + if (!info->key) { + printf("Can't get key in cipher node '%s'\n", node_path); + return -1; + } + + /* read iv */ + info->iv = fdt_getprop(fdt, noffset, "iv", NULL); + if (!info->iv) { + printf("Can't get IV in cipher node '%s'\n", node_path); + return -1; + } + + return 0; +} + +int fit_image_decrypt_data(const void *fit, + int image_noffset, int cipher_noffset, + const void *data_ciphered, size_t size_ciphered, + void **data_unciphered, size_t *size_unciphered) +{ + struct image_cipher_info info; + int ret; + + ret = fit_image_setup_decrypt(&info, fit, image_noffset, + cipher_noffset); + if (ret < 0) + goto out; + + ret = info.cipher->decrypt(&info, data_ciphered, size_ciphered, + data_unciphered, size_unciphered); + + out: + return ret; +} diff --git a/common/image-fdt.c b/common/image-fdt.c index 48388488d98..dbb1e6e131c 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -285,7 +285,8 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, *of_flat_tree = NULL; *of_size = 0; - img_addr = (argc == 0) ? load_addr : simple_strtoul(argv[0], NULL, 16); + img_addr = (argc == 0) ? image_load_addr : + simple_strtoul(argv[0], NULL, 16); buf = map_sysmem(img_addr, 0); if (argc > 2) @@ -304,7 +305,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, else if (images->fit_uname_os) default_addr = (ulong)images->fit_hdr_os; else - default_addr = load_addr; + default_addr = image_load_addr; if (fit_parse_conf(select, default_addr, &fdt_addr, &fit_uname_config)) { diff --git a/common/image-fit.c b/common/image-fit.c index 231612ff5f0..f3bb00c98a5 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -948,6 +948,31 @@ int fit_image_get_data_size(const void *fit, int noffset, int *data_size) } /** + * Get 'data-size-unciphered' property from a given image node. + * + * @fit: pointer to the FIT image header + * @noffset: component image node offset + * @data_size: holds the data-size property + * + * returns: + * 0, on success + * -ENOENT if the property could not be found + */ +int fit_image_get_data_size_unciphered(const void *fit, int noffset, + size_t *data_size) +{ + const fdt32_t *val; + + val = fdt_getprop(fit, noffset, "data-size-unciphered", NULL); + if (!val) + return -ENOENT; + + *data_size = (size_t)fdt32_to_cpu(*val); + + return 0; +} + +/** * fit_image_get_data_and_size - get data and its size including * both embedded and external data * @fit: pointer to the FIT format image header @@ -1080,6 +1105,33 @@ static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore) return 0; } +/** + * fit_image_cipher_get_algo - get cipher algorithm name + * @fit: pointer to the FIT format image header + * @noffset: cipher node offset + * @algo: double pointer to char, will hold pointer to the algorithm name + * + * fit_image_cipher_get_algo() finds cipher algorithm property in a given + * cipher node. If the property is found its data start address is returned + * to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo) +{ + int len; + + *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len); + if (!*algo) { + fit_get_debug(fit, noffset, FIT_ALGO_PROP, len); + return -1; + } + + return 0; +} + ulong fit_get_end(const void *fit) { return map_to_sysmem((void *)(fit + fdt_totalsize(fit))); @@ -1354,6 +1406,32 @@ int fit_all_image_verify(const void *fit) return 1; } +#ifdef CONFIG_FIT_CIPHER +static int fit_image_uncipher(const void *fit, int image_noffset, + void **data, size_t *size) +{ + int cipher_noffset, ret; + void *dst; + size_t size_dst; + + cipher_noffset = fdt_subnode_offset(fit, image_noffset, + FIT_CIPHER_NODENAME); + if (cipher_noffset < 0) + return 0; + + ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset, + *data, *size, &dst, &size_dst); + if (ret) + goto out; + + *data = dst; + *size = size_dst; + + out: + return ret; +} +#endif /* CONFIG_FIT_CIPHER */ + /** * fit_image_check_os - check whether image node is of a given os type * @fit: pointer to the FIT format image header @@ -1954,6 +2032,18 @@ int fit_image_load(bootm_headers_t *images, ulong addr, return -ENOENT; } +#ifdef CONFIG_FIT_CIPHER + /* Decrypt data before uncompress/move */ + if (IMAGE_ENABLE_DECRYPT) { + puts(" Decrypting Data ... "); + if (fit_image_uncipher(fit, noffset, &buf, &size)) { + puts("Error\n"); + return -EACCES; + } + puts("OK\n"); + } +#endif + #if !defined(USE_HOSTCC) && defined(CONFIG_FIT_IMAGE_POST_PROCESS) /* perform any post-processing on the image data */ board_fit_image_post_process(&buf, &size); diff --git a/common/image.c b/common/image.c index 75d5dd944ff..2288cff1266 100644 --- a/common/image.c +++ b/common/image.c @@ -557,9 +557,9 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch, /* Shared dual-format routines */ /*****************************************************************************/ #ifndef USE_HOSTCC -ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ -ulong save_addr; /* Default Save Address */ -ulong save_size; /* Default Save Size (in bytes) */ +ulong image_load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ +ulong image_save_addr; /* Default Save Address */ +ulong image_save_size; /* Default Save Size (in bytes) */ static int on_loadaddr(const char *name, const char *value, enum env_op op, int flags) @@ -567,7 +567,7 @@ static int on_loadaddr(const char *name, const char *value, enum env_op op, switch (op) { case env_op_create: case env_op_overwrite: - load_addr = simple_strtoul(value, NULL, 16); + image_load_addr = simple_strtoul(value, NULL, 16); break; default: break; @@ -936,15 +936,15 @@ ulong genimg_get_kernel_addr_fit(char * const img_addr, /* find out kernel image address */ if (!img_addr) { - kernel_addr = load_addr; + kernel_addr = image_load_addr; debug("* kernel: default image load address = 0x%08lx\n", - load_addr); + image_load_addr); #if CONFIG_IS_ENABLED(FIT) - } else if (fit_parse_conf(img_addr, load_addr, &kernel_addr, + } else if (fit_parse_conf(img_addr, image_load_addr, &kernel_addr, fit_uname_config)) { debug("* kernel: config '%s' from image at 0x%08lx\n", *fit_uname_config, kernel_addr); - } else if (fit_parse_subimage(img_addr, load_addr, &kernel_addr, + } else if (fit_parse_subimage(img_addr, image_load_addr, &kernel_addr, fit_uname_kernel)) { debug("* kernel: subimage '%s' from image at 0x%08lx\n", *fit_uname_kernel, kernel_addr); @@ -1102,7 +1102,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, if (images->fit_uname_os) default_addr = (ulong)images->fit_hdr_os; else - default_addr = load_addr; + default_addr = image_load_addr; if (fit_parse_conf(select, default_addr, &rd_addr, &fit_uname_config)) { diff --git a/common/main.c b/common/main.c index a94df7ae042..ec8994ad457 100644 --- a/common/main.c +++ b/common/main.c @@ -12,6 +12,7 @@ #include <command.h> #include <console.h> #include <env.h> +#include <init.h> #include <version.h> /* diff --git a/common/memsize.c b/common/memsize.c index 13b00477866..e95c68265ab 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -5,6 +5,7 @@ */ #include <common.h> +#include <init.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/common/spl/spl.c b/common/spl/spl.c index 19085ad2701..932e6ab98ac 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -11,6 +11,7 @@ #include <binman_sym.h> #include <dm.h> #include <handoff.h> +#include <hang.h> #include <irq_func.h> #include <serial.h> #include <spl.h> diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c index 803303249c7..30c050c0b3e 100644 --- a/common/spl/spl_net.c +++ b/common/spl/spl_net.c @@ -19,14 +19,14 @@ static ulong spl_net_load_read(struct spl_load_info *load, ulong sector, { debug("%s: sector %lx, count %lx, buf %lx\n", __func__, sector, count, (ulong)buf); - memcpy(buf, (void *)(load_addr + sector), count); + memcpy(buf, (void *)(image_load_addr + sector), count); return count; } static int spl_net_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header = (struct image_header *)load_addr; + struct image_header *header = (struct image_header *)image_load_addr; int rv; env_init(); diff --git a/common/spl/spl_opensbi.c b/common/spl/spl_opensbi.c index 6404373ecad..a136073fdbb 100644 --- a/common/spl/spl_opensbi.c +++ b/common/spl/spl_opensbi.c @@ -8,6 +8,7 @@ #include <common.h> #include <cpu_func.h> #include <errno.h> +#include <hang.h> #include <spl.h> #include <asm/smp.h> #include <opensbi.h> diff --git a/common/update.c b/common/update.c index 13b09ab00f3..c8dd346a095 100644 --- a/common/update.c +++ b/common/update.c @@ -8,6 +8,7 @@ #include <common.h> #include <cpu_func.h> +#include <image.h> #if !(defined(CONFIG_FIT) && defined(CONFIG_OF_LIBFDT)) #error "CONFIG_FIT and CONFIG_OF_LIBFDT are required for auto-update feature" @@ -45,7 +46,6 @@ extern ulong tftp_timeout_ms; extern int tftp_timeout_count_max; -extern ulong load_addr; #ifdef CONFIG_MTD_NOR_FLASH extern flash_info_t flash_info[]; static uchar *saved_prot_info; @@ -72,7 +72,7 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) env_set("netretry", "no"); /* download the update file */ - load_addr = addr; + image_load_addr = addr; copy_filename(net_boot_file_name, filename, sizeof(net_boot_file_name)); size = net_loop(TFTPGET); |