summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/imx/imx-image.c27
-rw-r--r--scripts/imx/imx.c158
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,
},