diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 52a825b..1d6b4e1 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -799,7 +799,7 @@ config HABV4_IMG_CRT_PEM string "Path to IMG certificate" - default "../crts/IMG_1_sha256_4096_65537_v3_usr_crt.pem" + default "../crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem" help Path to the Image certificate, produced by the Freescale Public Key Infrastructure (PKI) script. diff --git a/arch/arm/mach-imx/include/mach/habv4-imx6-gencsf.h b/arch/arm/mach-imx/include/mach/habv4-imx6-gencsf.h index 0649caa..5818879 100644 --- a/arch/arm/mach-imx/include/mach/habv4-imx6-gencsf.h +++ b/arch/arm/mach-imx/include/mach/habv4-imx6-gencsf.h @@ -43,3 +43,16 @@ hab Verification index = 2 hab_blocks + +hab_encrypt [Install Secret Key] +hab_encrypt Verification index = 0 +hab_encrypt Target index = 0 +hab_encrypt_key +hab_encrypt_key_length 256 +hab_encrypt_blob_address + +hab_encrypt [Decrypt Data] +hab_encrypt Verification index = 0 +hab_encrypt Mac Bytes = 16 + +hab_encrypt_blocks diff --git a/arch/arm/mach-imx/include/mach/imx-header.h b/arch/arm/mach-imx/include/mach/imx-header.h index d9c0933..05f1669 100644 --- a/arch/arm/mach-imx/include/mach/imx-header.h +++ b/arch/arm/mach-imx/include/mach/imx-header.h @@ -4,6 +4,14 @@ #include #define HEADER_LEN 0x1000 /* length of the blank area + IVT + DCD */ +#define CSF_LEN 0x2000 /* length of the CSF (needed for HAB) */ + +#define DEK_BLOB_HEADER 8 /* length of DEK blob header */ +#define DEK_BLOB_KEY 32 /* length of DEK blob AES-256 key */ +#define DEK_BLOB_MAC 16 /* length of DEK blob MAC */ + +/* DEK blob length excluding DEK itself */ +#define DEK_BLOB_OVERHEAD (DEK_BLOB_HEADER + DEK_BLOB_KEY + DEK_BLOB_MAC) /* * ============================================================================ @@ -103,6 +111,8 @@ int csf_space; char *csf; char *signed_hdmi_firmware_file; + int encrypt_image; + size_t dek_size; }; #define MAX_RECORDS_DCD_V2 1024 diff --git a/drivers/hab/habv4.c b/drivers/hab/habv4.c index ae43bdf..28fd42e 100644 --- a/drivers/hab/habv4.c +++ b/drivers/hab/habv4.c @@ -27,13 +27,28 @@ #define HABV4_RVT_IMX28 0xffff8af8 #define HABV4_RVT_IMX6_OLD 0x00000094 #define HABV4_RVT_IMX6_NEW 0x00000098 -#define HABV4_RVT_IMX6UL 0x00000100 +#define HABV4_RVT_IMX6UL 0x00000100 + +struct __packed hab_hdr { + uint8_t tag; /* Tag field */ + __be16 len; /* Length field in bytes (big-endian) */ + uint8_t par; /* Parameters field */ +}; + +struct __packed hab_event_record { + struct hab_hdr hdr; + uint8_t status; /* Status -> enum hab_status*/ + uint8_t reason; /* Reason -> enum hab_reason */ + uint8_t context; /* Context -> enum hab_context */ + uint8_t engine; /* Engine -> enum hab_engine */ + uint8_t data[0]; /* Record Data */ +}; enum hab_tag { HAB_TAG_IVT = 0xd1, /* Image Vector Table */ HAB_TAG_DCD = 0xd2, /* Device Configuration Data */ HAB_TAG_CSF = 0xd4, /* Command Sequence File */ - HAB_TAG_CRT = 0xd7, /* Certificate */ + HAB_TAG_CRT = 0xd7, /* Certificate */ HAB_TAG_SIG = 0xd8, /* Signature */ HAB_TAG_EVT = 0xdb, /* Event */ HAB_TAG_RVT = 0xdd, /* ROM Vector Table */ @@ -69,6 +84,66 @@ HAB_STATE_NONE = 0xf0, /* No security state machine */ }; +enum hab_reason { + HAB_REASON_RSN_ANY = 0x00, /* Match any reason */ + HAB_REASON_UNS_COMMAND = 0x03, /* Unsupported command */ + HAB_REASON_INV_IVT = 0x05, /* Invalid ivt */ + HAB_REASON_INV_COMMAND = 0x06, /* Invalid command: command malformed */ + HAB_REASON_UNS_STATE = 0x09, /* Unsuitable state */ + HAB_REASON_UNS_ENGINE = 0x0a, /* Unsupported engine */ + HAB_REASON_INV_ASSERTION = 0x0c, /* Invalid assertion */ + HAB_REASON_INV_INDEX = 0x0f, /* Invalid index: access denied */ + HAB_REASON_INV_CSF = 0x11, /* Invalid csf */ + HAB_REASON_UNS_ALGORITHM = 0x12, /* Unsupported algorithm */ + HAB_REASON_UNS_PROTOCOL = 0x14, /* Unsupported protocol */ + HAB_REASON_INV_SIZE = 0x17, /* Invalid data size */ + HAB_REASON_INV_SIGNATURE = 0x18, /* Invalid signature */ + HAB_REASON_UNS_KEY = 0x1b, /* Unsupported key type/parameters */ + HAB_REASON_INV_KEY = 0x1d, /* Invalid key */ + HAB_REASON_INV_RETURN = 0x1e, /* Failed callback function */ + HAB_REASON_INV_CERTIFICATE = 0x21, /* Invalid certificate */ + HAB_REASON_INV_ADDRESS = 0x22, /* Invalid address: access denied */ + HAB_REASON_UNS_ITEM = 0x24, /* Unsupported configuration item */ + HAB_REASON_INV_DCD = 0x27, /* Invalid dcd */ + HAB_REASON_INV_CALL = 0x28, /* Function called out of sequence */ + HAB_REASON_OVR_COUNT = 0x2b, /* Expired poll count */ + HAB_REASON_OVR_STORAGE = 0x2d, /* Exhausted storage region */ + HAB_REASON_MEM_FAIL = 0x2e, /* Memory failure */ + HAB_REASON_ENG_FAIL = 0x30, /* Engine failure */ +}; + +enum hab_context { + HAB_CONTEXT_ANY = 0x00, /* Match any context */ + HAB_CONTEXT_AUTHENTICATE = 0x0a, /* Logged in hab_rvt.authenticate_image() */ + HAB_CONTEXT_TARGET = 0x33, /* Event logged in hab_rvt.check_target() */ + HAB_CONTEXT_ASSERT = 0xa0, /* Event logged in hab_rvt.assert() */ + HAB_CONTEXT_COMMAND = 0xc0, /* Event logged executing csf/dcd command */ + HAB_CONTEXT_CSF = 0xcf, /* Event logged in hab_rvt.run_csf() */ + HAB_CONTEXT_AUT_DAT = 0xdb, /* Authenticated data block */ + HAB_CONTEXT_DCD = 0xdd, /* Event logged in hab_rvt.run_dcd() */ + HAB_CONTEXT_ENTRY = 0xe1, /* Event logged in hab_rvt.entry() */ + HAB_CONTEXT_EXIT = 0xee, /* Event logged in hab_rvt.exit() */ + HAB_CONTEXT_FAB = 0xff, /* Event logged in hab_fab_test() */ +}; + +enum hab_engine { + HAB_ENGINE_ANY = 0x00, /* Select first compatible engine */ + HAB_ENGINE_SCC = 0x03, /* Security controller */ + HAB_ENGINE_RTIC = 0x05, /* Run-time integrity checker */ + HAB_ENGINE_SAHARA = 0x06, /* Crypto accelerator */ + HAB_ENGINE_CSU = 0x0a, /* Central Security Unit */ + HAB_ENGINE_SRTC = 0x0c, /* Secure clock */ + HAB_ENGINE_DCP = 0x1b, /* Data Co-Processor */ + HAB_ENGINE_CAAM = 0x1d, /* CAAM */ + HAB_ENGINE_SNVS = 0x1e, /* Secure Non-Volatile Storage */ + HAB_ENGINE_OCOTP = 0x21, /* Fuse controller */ + HAB_ENGINE_DTCP = 0x22, /* DTCP co-processor */ + HAB_ENGINE_HDCP = 0x24, /* HDCP co-processor */ + HAB_ENGINE_ROM = 0x36, /* Protected ROM area */ + HAB_ENGINE_RTL = 0x77, /* RTL simulation engine */ + HAB_ENGINE_SW = 0xff, /* Software engine */ +}; + enum hab_target { HAB_TARGET_MEMORY = 0x0f, /* Check memory white list */ HAB_TARGET_PERIPHERAL = 0xf0, /* Check peripheral white list*/ @@ -157,29 +232,165 @@ return ""; } +static const char *habv4_get_reason_str(enum hab_reason reason) +{ + switch (reason) { + case HAB_REASON_RSN_ANY: + return "Match any reason"; break; + case HAB_REASON_UNS_COMMAND: + return "Unsupported command"; break; + case HAB_REASON_INV_IVT: + return "Invalid ivt"; break; + case HAB_REASON_INV_COMMAND: + return "Invalid command: command malformed"; break; + case HAB_REASON_UNS_STATE: + return "Unsuitable state"; break; + case HAB_REASON_UNS_ENGINE: + return "Unsupported engine"; break; + case HAB_REASON_INV_ASSERTION: + return "Invalid assertion"; break; + case HAB_REASON_INV_INDEX: + return "Invalid index: access denied"; break; + case HAB_REASON_INV_CSF: + return "Invalid csf"; break; + case HAB_REASON_UNS_ALGORITHM: + return "Unsupported algorithm"; break; + case HAB_REASON_UNS_PROTOCOL: + return "Unsupported protocol"; break; + case HAB_REASON_INV_SIZE: + return "Invalid data size"; break; + case HAB_REASON_INV_SIGNATURE: + return "Invalid signature"; break; + case HAB_REASON_UNS_KEY: + return "Unsupported key type/parameters"; break; + case HAB_REASON_INV_KEY: + return "Invalid key"; break; + case HAB_REASON_INV_RETURN: + return "Failed callback function"; break; + case HAB_REASON_INV_CERTIFICATE: + return "Invalid certificate"; break; + case HAB_REASON_INV_ADDRESS: + return "Invalid address: access denied"; break; + case HAB_REASON_UNS_ITEM: + return "Unsupported configuration item"; break; + case HAB_REASON_INV_DCD: + return "Invalid dcd"; break; + case HAB_REASON_INV_CALL: + return "Function called out of sequence"; break; + case HAB_REASON_OVR_COUNT: + return "Expired poll count"; break; + case HAB_REASON_OVR_STORAGE: + return "Exhausted storage region"; break; + case HAB_REASON_MEM_FAIL: + return "Memory failure"; break; + case HAB_REASON_ENG_FAIL: + return "Engine failure"; break; + } + + return ""; +} + +static const char *habv4_get_context_str(enum hab_context context) +{ + switch (context){ + case HAB_CONTEXT_ANY: + return "Match any context"; break; + case HAB_CONTEXT_AUTHENTICATE: + return "Logged in hab_rvt.authenticate_image()"; break; + case HAB_CONTEXT_TARGET: + return "Event logged in hab_rvt.check_target()"; break; + case HAB_CONTEXT_ASSERT: + return "Event logged in hab_rvt.assert()"; break; + case HAB_CONTEXT_COMMAND: + return "Event logged executing csf/dcd command"; break; + case HAB_CONTEXT_CSF: + return "Event logged in hab_rvt.run_csf()"; break; + case HAB_CONTEXT_AUT_DAT: + return "Authenticated data block"; break; + case HAB_CONTEXT_DCD: + return "Event logged in hab_rvt.run_dcd()"; break; + case HAB_CONTEXT_ENTRY: + return "Event logged in hab_rvt.entry()"; break; + case HAB_CONTEXT_EXIT: + return "Event logged in hab_rvt.exit()"; break; + case HAB_CONTEXT_FAB: + return "Event logged in hab_fab_test()"; break; + } + + return ""; +} + +static const char *habv4_get_engine_str(enum hab_engine engine) +{ + switch (engine){ + case HAB_ENGINE_ANY: + return "Select first compatible engine"; break; + case HAB_ENGINE_SCC: + return "Security controller"; break; + case HAB_ENGINE_RTIC: + return "Run-time integrity checker"; break; + case HAB_ENGINE_SAHARA: + return "Crypto accelerator"; break; + case HAB_ENGINE_CSU: + return "Central Security Unit"; break; + case HAB_ENGINE_SRTC: + return "Secure clock"; break; + case HAB_ENGINE_DCP: + return "Data Co-Processor"; break; + case HAB_ENGINE_CAAM: + return "CAAM"; break; + case HAB_ENGINE_SNVS: + return "Secure Non-Volatile Storage"; break; + case HAB_ENGINE_OCOTP: + return "Fuse controller"; break; + case HAB_ENGINE_DTCP: + return "DTCP co-processor"; break; + case HAB_ENGINE_HDCP: + return "HDCP co-processor"; break; + case HAB_ENGINE_ROM: + return "Protected ROM area"; break; + case HAB_ENGINE_RTL: + return "RTL simulation engine"; break; + case HAB_ENGINE_SW: + return "Software engine"; break; + } + + return ""; +} + +static void habv4_display_event_record(struct hab_event_record *record) +{ + pr_err("Status: %s (0x%02x)\n", habv4_get_status_str(record->status), record->status); + pr_err("Reason: %s (0x%02x)\n", habv4_get_reason_str(record->reason), record->reason); + pr_err("Context: %s (0x%02x)\n", habv4_get_context_str(record->context), record->context); + pr_err("Engine: %s (0x%02x)\n", habv4_get_engine_str(record->engine), record->engine); +} + static void habv4_display_event(uint8_t *data, uint32_t len) { unsigned int i; if (data && len) { for (i = 0; i < len; i++) { - if (i == 0) - printf(" %02x", data[i]); - else if ((i % 8) == 0) - printf("\n %02x", data[i]); + if ((i % 8) == 0) + pr_err(" %02x", data[i]); else if ((i % 4) == 0) - printf(" %02x", data[i]); + pr_cont(" %02x", data[i]); + else if ((i % 8) == 7) + pr_cont(" %02x\n", data[i]); else - printf(" %02x", data[i]); + pr_cont(" %02x", data[i]); } + pr_cont("\n"); } - printf("\n\n"); + + habv4_display_event_record((struct hab_event_record *)data); } static int habv4_get_status(const struct habv4_rvt *rvt) { uint8_t data[256]; - uint32_t len = sizeof(data); + uint32_t len; uint32_t index = 0; enum hab_status status; enum hab_config config = 0x0; @@ -200,9 +411,20 @@ return 0; } + len = sizeof(data); + while (rvt->report_event(HAB_STATUS_WARNING, index, data, &len) == HAB_STATUS_SUCCESS) { + pr_err("-------- HAB warning Event %d --------\n", index); + pr_err("event data:\n"); + + habv4_display_event(data, len); + len = sizeof(data); + index++; + } + + len = sizeof(data); while (rvt->report_event(HAB_STATUS_FAILURE, index, data, &len) == HAB_STATUS_SUCCESS) { - printf("-------- HAB Event %d --------\n" - "event data:\n", index); + pr_err("-------- HAB failure Event %d --------\n", index); + pr_err("event data:\n"); habv4_display_event(data, len); len = sizeof(data); @@ -210,6 +432,7 @@ } /* Check reason for stopping */ + len = sizeof(data); if (rvt->report_event(HAB_STATUS_ANY, index, NULL, &len) == HAB_STATUS_SUCCESS) pr_err("ERROR: Recompile with larger event data buffer (at least %d bytes)\n\n", len); diff --git a/images/Makefile.imx b/images/Makefile.imx index 746fc14..f0014ac 100644 --- a/images/Makefile.imx +++ b/images/Makefile.imx @@ -14,6 +14,14 @@ $(obj)/%.usimximg: $(obj)/% FORCE $(call if_changed,imx_image,$(CFG_$(patsubst %.usimximg,%.imximg,$(@F))),-s -u) +$(obj)/%.esimximg $(obj)/%.esimximg.dek: $(obj)/% FORCE + $(call if_changed,imx_image,$(CFG_$(patsubst %.esimximg,%.imximg,$(@F))),-s -e) + +.SECONDEXPANSION: +$(obj)/%.img.dek: $(obj)/$$(FILE_$$(@F)) + $(Q)if [ -z $(FILE_$(@F)) ]; then echo "FILE_$(@F) empty!"; false; fi + $(call if_changed,shipped) + quiet_cmd_imx_sram_img ?= IMX-SRAM-IMG $@ cmd_imx_sram_img ?= cat $(obj)/$(patsubst %.imx-sram-img,%.pblb,$(2)) > $@; \ $(call size_append, $(obj)/barebox.z) >> $@; \ diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c index 558dacf..88e2cb9 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 @@ struct stat s; char *cst; void *buf; + size_t csf_space = CSF_LEN; cst = getenv("CST"); if (!cst) @@ -558,7 +558,28 @@ } } - 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 @@ 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 @@ 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 @@ 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 @@ 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 7d2a5c5..2341732 100644 --- a/scripts/imx/imx.c +++ b/scripts/imx/imx.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -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_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; - 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; + + 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; @@ -435,6 +597,21 @@ .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, }, {