summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-09-11 17:23:30 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2018-09-11 17:23:30 +0200
commitbe22bb4527e3be70718dfee414e08b17c399f9fd (patch)
tree4031527cb850203102daf8bc80531d384e7452fe /scripts
parentf00f9f52163dbb7847326e5edfa969d12f63be20 (diff)
parent6f56b955bdc6f072687f56a1c851d419512bc056 (diff)
downloadbarebox-be22bb4527e3be70718dfee414e08b17c399f9fd.tar.gz
barebox-be22bb4527e3be70718dfee414e08b17c399f9fd.tar.xz
Merge branch 'for-next/imx-hab'
Diffstat (limited to 'scripts')
-rw-r--r--scripts/imx/imx-image.c50
-rw-r--r--scripts/imx/imx.c183
2 files changed, 221 insertions, 12 deletions
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
index 558dacfbb2..88e2cb955f 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)
@@ -558,7 +558,28 @@ static int hab_sign(struct config_data *data)
}
}
- ret = asprintf(&command, "%s -o %s", cst, csffile);
+ /*
+ * Older versions of "cst" want to read the CSF from STDIN,
+ * while newer versions want to read the CSF from a
+ * file. Sadly, the "-i" option doesn't understand "-i -" to
+ * read from STDIN, so we give it "/dev/stdin" instead.
+ */
+ ret = asprintf(&command,
+ "%s | grep 'Input CSF text filename'",
+ cst);
+ if (ret < 0)
+ return -ENOMEM;
+
+ ret = system(command);
+ free(command);
+ if (ret == -1)
+ return -EINVAL;
+ else if (ret == 0)
+ ret = asprintf(&command, "%s -o %s -i /dev/stdin",
+ cst, csffile);
+ else
+ ret = asprintf(&command, "%s -o %s;",
+ cst, csffile);
if (ret < 0)
return -ENOMEM;
@@ -613,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);
@@ -632,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;
@@ -709,7 +738,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;
@@ -732,6 +761,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 7d2a5c5b8f..2341732b2f 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;
@@ -317,15 +324,170 @@ static int do_hab(struct config_data *data, int argc, char *argv[])
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;
+
+ if (argc < 2)
+ type = "full";
+ 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, 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,
+ signed_size - data->image_dcd_offset,
+ data->outfile);
+ } else if (!strcmp(type, "skip-mbr")) {
+ ret = asprintf(&str,
+ "Blocks = 0x%08x 0 440 \"%s\", \\\n"
+ " 0x%08x 512 %d \"%s\"\n",
+ data->image_load_addr, data->outfile,
+ data->image_load_addr + 512,
+ signed_size - 512, data->outfile);
+ } else {
+ fprintf(stderr, "Invalid hab_blocks option: %s\n", type);
+ return -EINVAL;
+ }
+
+ if (ret < 0)
+ return -ENOMEM;
+
+ ret = hab_add_str(data, str);
+ if (ret)
+ return ret;
+
+ 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;
- ret = asprintf(&str, "Blocks = 0x%08x 0 %d \"%s\"\n",
- data->image_load_addr,
- data->load_size, data->outfile);
+ 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;
@@ -435,6 +597,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,
}, {