diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/imx/imx-image.c | 27 | ||||
-rw-r--r-- | scripts/imx/imx.c | 158 |
2 files changed, 174 insertions, 11 deletions
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c index f7ca87bba2..1e04a89b49 100644 --- a/scripts/imx/imx-image.c +++ b/scripts/imx/imx-image.c @@ -43,7 +43,6 @@ * HEADER_SIZE */ #define MAX_DCD ((HEADER_LEN - FLASH_HEADER_OFFSET - sizeof(struct imx_flash_header_v2)) / sizeof(u32)) -#define CSF_LEN 0x2000 /* length of the CSF (needed for HAB) */ static uint32_t dcdtable[MAX_DCD]; static int curdcd; @@ -533,6 +532,7 @@ static int hab_sign(struct config_data *data) struct stat s; char *cst; void *buf; + size_t csf_space = CSF_LEN; cst = getenv("CST"); if (!cst) @@ -634,15 +634,23 @@ static int hab_sign(struct config_data *data) return -errno; } - buf = malloc(CSF_LEN); + /* + * DEK blob needs to be part of CSF area, in order to properly + * load by ROM code. Make space to simply concatenate DEK blob + * to the end of image during device flashing procedure. + */ + if (data->encrypt_image) + csf_space -= (data->dek_size + DEK_BLOB_OVERHEAD); + + buf = malloc(csf_space); if (!buf) return -ENOMEM; - memset(buf, 0x5a, CSF_LEN); + memset(buf, 0x5a, csf_space); - if (s.st_size > CSF_LEN) { - fprintf(stderr, "CSF file size exceeds maximum CSF len of %d bytes\n", - CSF_LEN); + if (s.st_size > csf_space) { + fprintf(stderr, "CSF file size exceeds maximum CSF space of %zu bytes\n", + csf_space); } ret = xread(fd, buf, s.st_size); @@ -653,7 +661,7 @@ static int hab_sign(struct config_data *data) outfd = open(data->outfile, O_WRONLY | O_APPEND); - ret = xwrite(outfd, buf, CSF_LEN); + ret = xwrite(outfd, buf, csf_space); if (ret < 0) { fprintf(stderr, "write failed: %s\n", strerror(errno)); return -errno; @@ -728,7 +736,7 @@ int main(int argc, char *argv[]) prgname = argv[0]; - while ((opt = getopt(argc, argv, "c:hf:o:bdus")) != -1) { + while ((opt = getopt(argc, argv, "c:hf:o:bduse")) != -1) { switch (opt) { case 'c': configfile = optarg; @@ -751,6 +759,9 @@ int main(int argc, char *argv[]) case 'u': create_usb_image = 1; break; + case 'e': + data.encrypt_image = 1; + break; case 'h': usage(argv[0]); default: diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c index 21206387ec..eeb9b69c0f 100644 --- a/scripts/imx/imx.c +++ b/scripts/imx/imx.c @@ -22,6 +22,7 @@ #include <string.h> #include <stdint.h> #include <errno.h> +#include <sys/stat.h> #include <linux/kernel.h> #include <mach/imx_cpu_types.h> @@ -29,6 +30,12 @@ #define MAXARGS 32 +/* + * First word of bootloader image should be authenticated, + * encrypt the rest. + */ +#define ENCRYPT_OFFSET (HEADER_LEN + 0x10) + static int parse_line(char *line, char *argv[]) { int nargs = 0; @@ -320,6 +327,7 @@ static int do_hab_blocks(struct config_data *data, int argc, char *argv[]) const char *type; char *str; int ret; + uint32_t signed_size = data->load_size; if (!data->csf) return -EINVAL; @@ -329,15 +337,22 @@ static int do_hab_blocks(struct config_data *data, int argc, char *argv[]) else type = argv[1]; + /* + * In case of encrypted image we reduce signed area to beginning + * of encrypted area. + */ + if (data->encrypt_image) + signed_size = ENCRYPT_OFFSET; + if (!strcmp(type, "full")) { ret = asprintf(&str, "Blocks = 0x%08x 0 %d \"%s\"\n", - data->image_load_addr, data->load_size, + data->image_load_addr, signed_size, data->outfile); } else if (!strcmp(type, "from-dcdofs")) { ret = asprintf(&str, "Blocks = 0x%08x 0x%x %d \"%s\"\n", data->image_load_addr + data->image_dcd_offset, data->image_dcd_offset, - data->load_size - data->image_dcd_offset, + signed_size - data->image_dcd_offset, data->outfile); } else if (!strcmp(type, "skip-mbr")) { ret = asprintf(&str, @@ -345,7 +360,7 @@ static int do_hab_blocks(struct config_data *data, int argc, char *argv[]) " 0x%08x 512 %d \"%s\"\n", data->image_load_addr, data->outfile, data->image_load_addr + 512, - data->load_size - 512, data->outfile); + signed_size - 512, data->outfile); } else { fprintf(stderr, "Invalid hab_blocks option: %s\n", type); return -EINVAL; @@ -361,6 +376,128 @@ static int do_hab_blocks(struct config_data *data, int argc, char *argv[]) return 0; } +static int do_hab_encrypt(struct config_data *data, int argc, char *argv[]) +{ + if (!data->encrypt_image) + return 0; + + return do_hab(data, argc, argv); +} + +static int do_hab_encrypt_key(struct config_data *data, int argc, char *argv[]) +{ + char *str; + char *dekfile; + int ret; + + if (!data->csf) + return -EINVAL; + + if (!data->encrypt_image) + return 0; + + ret = asprintf(&dekfile, "%s.dek", data->outfile); + if (ret < 0) + return -ENOMEM; + + ret = asprintf(&str, "Key = \"%s\"\n", dekfile); + if (ret < 0) + return -ENOMEM; + + ret = hab_add_str(data, str); + if (ret) + return ret; + + return 0; +} + +static int do_hab_encrypt_key_length(struct config_data *data, int argc, + char *argv[]) +{ + unsigned int dek_bits; + char *str; + int ret; + + if (!data->csf) + return -EINVAL; + + if (!data->encrypt_image) + return 0; + + if (argc < 2) + return -EINVAL; + + dek_bits = strtoul(argv[1], NULL, 0); + + if (dek_bits != 128 && dek_bits != 192 && dek_bits != 256) { + fprintf(stderr, "wrong dek size (%u)\n", dek_bits); + return -EINVAL; + } + + data->dek_size = dek_bits / 8; + + ret = asprintf(&str, "Key Length = %u\n", dek_bits); + if (ret < 0) + return -ENOMEM; + + ret = hab_add_str(data, str); + if (ret) + return ret; + + return 0; +} + +static int do_hab_encrypt_blob_address(struct config_data *data, int argc, + char *argv[]) +{ + char *str; + int ret; + + if (!data->csf) + return -EINVAL; + + if (!data->encrypt_image) + return 0; + + ret = asprintf(&str, + "Blob address = 0x%08zx\n", + data->image_load_addr + data->load_size + CSF_LEN - + (DEK_BLOB_OVERHEAD + data->dek_size)); + if (ret < 0) + return -ENOMEM; + + ret = hab_add_str(data, str); + if (ret) + return ret; + + return 0; +} + +static int do_hab_encrypt_blocks(struct config_data *data, int argc, + char *argv[]) +{ + char *str; + int ret; + + if (!data->csf) + return -EINVAL; + + if (!data->encrypt_image) + return 0; + + ret = asprintf(&str, "Blocks = 0x%08x 0x%x %d \"%s\"\n", + data->image_load_addr + ENCRYPT_OFFSET, ENCRYPT_OFFSET, + data->load_size - ENCRYPT_OFFSET, data->outfile); + if (ret < 0) + return -ENOMEM; + + ret = hab_add_str(data, str); + if (ret) + return ret; + + return 0; +} + static int do_super_root_key(struct config_data *data, int argc, char *argv[]) { int len; @@ -425,6 +562,21 @@ struct command cmds[] = { .name = "hab_blocks", .parse = do_hab_blocks, }, { + .name = "hab_encrypt", + .parse = do_hab_encrypt, + }, { + .name = "hab_encrypt_key", + .parse = do_hab_encrypt_key, + }, { + .name = "hab_encrypt_key_length", + .parse = do_hab_encrypt_key_length, + }, { + .name = "hab_encrypt_blob_address", + .parse = do_hab_encrypt_blob_address, + }, { + .name = "hab_encrypt_blocks", + .parse = do_hab_encrypt_blocks, + }, { .name = "super_root_key", .parse = do_super_root_key, }, |