aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile.main3
-rw-r--r--libstb/Makefile.inc11
-rw-r--r--libstb/container.c85
-rw-r--r--libstb/container.h151
-rw-r--r--libstb/test/Makefile.check44
-rw-r--r--libstb/test/print-stb-container.c206
-rw-r--r--libstb/test/run-stb-container.c34
-rw-r--r--libstb/test/t.containerbin0 -> 4096 bytes
-rw-r--r--libstb/test/t.container.out48
10 files changed, 583 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 5d18fe6..02a00cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,6 +73,8 @@ libflash/test/test-blocklevel
libflash/test/test-flash
libflash/test/test-ecc
libflash/test/test-flash-gcov
+libstb/test/run-stb-container
+libstb/test/*-gcov
test/hello_world/hello_kernel/hello_kernel
zImage.epapr
vgcore.*
diff --git a/Makefile.main b/Makefile.main
index ac74e46..86a54be 100644
--- a/Makefile.main
+++ b/Makefile.main
@@ -152,6 +152,7 @@ include $(SRC)/libpore/Makefile.inc
include $(SRC)/libc/Makefile.inc
include $(SRC)/ccan/Makefile.inc
include $(SRC)/$(DEVSRC)/Makefile.inc
+include $(SRC)/libstb/Makefile.inc
# hack for travis-ci and coverity
gard:
@@ -165,7 +166,7 @@ pflash-coverity:
all: $(SUBDIRS) $(TARGET).lid $(TARGET).lid.xz $(TARGET).map extract-gcov
-OBJS := $(ASM) $(CORE) $(HW) $(PLATFORMS) $(LIBFDT) $(LIBFLASH)
+OBJS := $(ASM) $(CORE) $(HW) $(PLATFORMS) $(LIBFDT) $(LIBFLASH) $(LIBSTB)
ifeq ($(PORE),1)
OBJS += $(LIBPORE)
endif
diff --git a/libstb/Makefile.inc b/libstb/Makefile.inc
new file mode 100644
index 0000000..15cdfbe
--- /dev/null
+++ b/libstb/Makefile.inc
@@ -0,0 +1,11 @@
+# -*-Makefile-*-
+
+LIBSTB_DIR = libstb
+
+SUBDIRS += $(LIBSTB_DIR)
+
+LIBSTB_SRCS = container.c
+LIBSTB_OBJS = $(LIBSTB_SRCS:%.c=%.o)
+LIBSTB = $(LIBSTB_DIR)/built-in.o
+
+$(LIBSTB): $(LIBSTB_OBJS:%=$(LIBSTB_DIR)/%)
diff --git a/libstb/container.c b/libstb/container.c
new file mode 100644
index 0000000..19df556
--- /dev/null
+++ b/libstb/container.c
@@ -0,0 +1,85 @@
+/* Copyright 2013-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <skiboot.h>
+#include "container.h"
+
+bool stb_is_container(const void *buf, size_t size)
+{
+ ROM_container_raw *c;
+
+ c = (ROM_container_raw*) buf;
+ if (!buf || size < SECURE_BOOT_HEADERS_SIZE)
+ return false;
+ if (be32_to_cpu(c->magic_number) != ROM_MAGIC_NUMBER )
+ return false;
+ return true;
+}
+
+uint32_t stb_payload_magic(const void *buf, size_t size)
+{
+ uint8_t *p;
+ if (!stb_is_container(buf, size))
+ return 0;
+ p = (uint8_t*) buf;
+ return be32_to_cpu(*(uint32_t*)(p+SECURE_BOOT_HEADERS_SIZE));
+}
+
+int parse_stb_container(const void* data, size_t len, struct parsed_stb_container *c)
+{
+ const size_t prefix_data_min_size = 3 * (EC_COORDBYTES * 2);
+ c->buf = data;
+ c->bufsz = len;
+ c->c = data;
+ c->ph = data += sizeof(ROM_container_raw);
+ c->pd = data += sizeof(ROM_prefix_header_raw) + (c->ph->ecid_count * ECID_SIZE);
+ c->sh = data += prefix_data_min_size + c->ph->sw_key_count * (EC_COORDBYTES * 2);
+ c->ssig = data += sizeof(ROM_sw_header_raw) +
+ c->sh->ecid_count * ECID_SIZE;
+
+ return 0;
+}
+
+const uint8_t* stb_sw_payload_hash(const void *buf, size_t size)
+{
+ struct parsed_stb_container c;
+
+ if (!stb_is_container(buf, size))
+ return NULL;
+ if (parse_stb_container(buf, size, &c) != 0)
+ return NULL;
+
+ return c.sh->payload_hash;
+}
+
+
+void stb_print_data(const void* data, size_t len)
+{
+ char hash[1+SHA512_DIGEST_LENGTH*2];
+ char *h = hash;
+ char *d = (char*)data;
+
+ assert(len <= SHA512_DIGEST_LENGTH);
+
+ while(len) {
+ snprintf(h, 3, "%02x", *d);
+ h+=2;
+ d++;
+ len--;
+ }
+ *h='\0';
+ prlog(PR_NOTICE, "%s\n", hash);
+}
diff --git a/libstb/container.h b/libstb/container.h
new file mode 100644
index 0000000..f65615a
--- /dev/null
+++ b/libstb/container.h
@@ -0,0 +1,151 @@
+/* Copyright 2013-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STB_CONTAINER_H
+#define __STB_CONTAINER_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <ccan/endian/endian.h>
+
+#define SECURE_BOOT_HEADERS_SIZE 4096
+#define SHA256_DIGEST_LENGTH 32
+
+/*
+ * The defines and structures below come from the secure ROM source code
+ * (trusted_boot_rom). Here you will find only the ones required by the
+ * secure and trusted boot implementation in skiboot.
+ */
+
+/* From trusted_boot_rom/src/sha512.h */
+#define SHA512_DIGEST_LENGTH 64
+typedef uint8_t __attribute__((aligned(8))) sha2_hash_t[ SHA512_DIGEST_LENGTH / sizeof(uint8_t) ];
+typedef uint8_t sha2_byte; // Exactly 1 byte
+
+/* From trusted_boot_rom/src/hw_utils.h */
+#define ECID_SIZE 16
+
+/* From trusted_boot_rom/src/ecverify.h */
+#define EC_COORDBYTES 66 /* P-521 */
+typedef uint8_t ecc_key_t[2*EC_COORDBYTES];
+typedef uint8_t ecc_signature_t[2*EC_COORDBYTES];
+
+/* From trusted_boot_rom/src/ROM.h */
+#define ROM_MAGIC_NUMBER 0x17082011
+
+typedef struct {
+ be16 version; /* (1: see versions above) */
+ uint8_t hash_alg; /* (1: SHA-512) */
+ uint8_t sig_alg; /* (1: SHA-512/ECDSA-521) */
+}__attribute__((packed)) ROM_version_raw;
+
+typedef struct {
+ ROM_version_raw ver_alg;
+ be64 code_start_offset;
+ be64 reserved;
+ be32 flags;
+ uint8_t sw_key_count;
+ be64 payload_size;
+ sha2_hash_t payload_hash;
+ uint8_t ecid_count;
+ struct { uint8_t ecid[ECID_SIZE]; } ecid[0]; /* optional ecid place
+ holder ecid_count * ecid_size(128 bits) */
+ /* followed by prefix data (sig,keys) key raw */
+}__attribute__((packed)) ROM_prefix_header_raw;
+
+typedef struct {
+ be32 magic_number; /* (17082011) */
+ be16 version; /* (1: see versions above) */
+ be64 container_size; /* filled by caller */
+ be64 target_hrmor; /* filled by caller */
+ be64 stack_pointer; /* filled by caller */
+ /* bottom of stack -> 128k added by rom code to get real stack pointer */
+ ecc_key_t hw_pkey_a;
+ ecc_key_t hw_pkey_b;
+ ecc_key_t hw_pkey_c;
+ /* followed by sw header (if not special prefix) */
+ /* followed by optional unprotected payload data */
+}__attribute__((packed)) ROM_container_raw;
+
+typedef struct {
+ ecc_signature_t hw_sig_a;
+ ecc_signature_t hw_sig_b;
+ ecc_signature_t hw_sig_c;
+ ecc_key_t sw_pkey_p;
+ ecc_key_t sw_pkey_q;
+ ecc_key_t sw_pkey_r;
+}__attribute__((packed)) ROM_prefix_data_raw;
+
+typedef struct {
+ ROM_version_raw ver_alg;
+ be64 code_start_offset;
+ be64 reserved;
+ be32 flags;
+ uint8_t reserved_0;
+ be64 payload_size;
+ sha2_hash_t payload_hash;
+ uint8_t ecid_count;
+ struct { uint8_t ecid[ECID_SIZE]; } ecid[0]; /* optional ecid place
+ holder ecid_count * ecid_size(128 bits) */
+ /* followed by sw sig raw */
+}__attribute__((packed)) ROM_sw_header_raw;
+
+typedef struct {
+ ecc_signature_t sw_sig_p;
+ ecc_signature_t sw_sig_q;
+ ecc_signature_t sw_sig_r;
+ /* followed by zero's padding to 4K */
+ /* followed by protected sw payload_data */
+ /* followed by unprotected sw payload_text */
+}__attribute__((packed)) ROM_sw_sig_raw;
+
+typedef enum { ROM_DONE, ROM_FAILED, PHYP_PARTIAL } ROM_response;
+
+typedef struct {
+ sha2_hash_t hw_key_hash;
+ uint8_t my_ecid[ECID_SIZE];
+ be64 entry_point;
+ be64 log;
+}__attribute__((packed)) ROM_hw_params;
+
+struct parsed_stb_container {
+ const void *buf;
+ size_t bufsz;
+ const ROM_container_raw *c;
+ const ROM_prefix_header_raw *ph;
+ const ROM_prefix_data_raw *pd;
+ const ROM_sw_header_raw *sh;
+ const ROM_sw_sig_raw *ssig;
+};
+
+/*
+ * Helper functions
+ */
+
+/* Get the container payload eyecatcher */
+uint32_t stb_payload_magic(const void *buf, size_t size);
+
+/* Check if buf is a secure boot container */
+bool stb_is_container(const void* buf, size_t size);
+
+/* Get the pointer for the sw-payload-hash field of the container header */
+const uint8_t* stb_sw_payload_hash(const void* buf, size_t size);
+
+int parse_stb_container(const void* data, size_t len, struct parsed_stb_container *c);
+
+void stb_print_data(const void *data, size_t len);
+
+#endif /* __STB_CONTAINER_H */
diff --git a/libstb/test/Makefile.check b/libstb/test/Makefile.check
new file mode 100644
index 0000000..00e1397
--- /dev/null
+++ b/libstb/test/Makefile.check
@@ -0,0 +1,44 @@
+# -*-Makefile-*-
+LIBSTB_TEST := libstb/test/run-stb-container \
+ libstb/test/print-stb-container
+
+HOSTCFLAGS+=-I . -I include
+
+libstb/test/print-stb-container-check: libstb/test/print-stb-container-q
+
+libstb/test/print-stb-container-q: libstb/test/print-stb-container
+ $(call Q, TEST , $(VALGRIND) libstb/test/print-stb-container libstb/test/t.container |diff -u libstb/test/t.container.out -, $< t.container)
+
+
+.PHONY : libstb-check
+libstb-check: $(LIBSTB_TEST:%=%-check) $(LIBSTB_TEST:%=%-gcov-run)
+libstb-check: $(LIBSTB_TEST_NOSTUB:%=%-check) $(LIBSTB_TEST_NOSTUB:%=%-gcov-run)
+
+.PHONY : libstb-coverage
+libstb-coverage: $(LIBSTB_TEST:%=%-gcov-run)
+libstb-coverage: $(LIBSTB_TEST_NOSTUB:%=%-gcov-run)
+
+check: libstb-check
+coverage: libstb-coverage
+
+$(LIBSTB_TEST:%=%-gcov-run) : %-run: %
+ $(call QTEST, TEST-COVERAGE ,$< , $<)
+
+$(LIBSTB_TEST:%=%-check) : %-check: %
+ $(call QTEST, RUN-TEST ,$(VALGRIND) $<, $<)
+
+$(LIBSTB_TEST) : core/test/stubs.o
+
+$(LIBSTB_TEST) : % : %.c
+ $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) -O0 -g -I include -I . -I libfdt -o $@ $< core/test/stubs.o, $<)
+
+$(LIBSTB_TEST:%=%-gcov): %-gcov : %.c %
+ $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) $(HOSTGCOVCFLAGS) -I include -I . -I libfdt -lgcov -o $@ $< core/test/stubs.o, $<)
+
+-include $(wildcard libstb/test/*.d)
+
+clean: libstb-test-clean
+
+libstb-test-clean:
+ $(RM) -f libstb/test/*.[od] $(LIBSTB_TEST) $(LIBSTB_TEST:%=%-gcov)
+ $(RM) -f libstb/test/*.gcda libstb/test/*.gcno
diff --git a/libstb/test/print-stb-container.c b/libstb/test/print-stb-container.c
new file mode 100644
index 0000000..51566c0
--- /dev/null
+++ b/libstb/test/print-stb-container.c
@@ -0,0 +1,206 @@
+/* Copyright 2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include <stdbool.h>
+#include <types.h>
+#include "../container.h"
+#include "../container.c"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+
+static void display_version_raw(const ROM_version_raw v)
+{
+ printf("ver_alg:\n");
+ printf(" version: %04x\n", be16_to_cpu(v.version));
+ printf(" hash_alg: %02x (%s)\n", v.hash_alg, (v.hash_alg == 1)? "SHA512" : "UNKNOWN");
+ printf(" sig_alg: %02x (%s)\n", v.sig_alg, (v.sig_alg == 1) ? "SHA512/ECDSA-521" : "UNKNOWN");
+}
+
+static void display_sha2_hash_t(const sha2_hash_t h)
+{
+ int i;
+ for(i=0; i<SHA512_DIGEST_LENGTH; i++)
+ printf("%02x", h[i]);
+}
+
+static void display_ecid(const uint8_t *ecid)
+{
+ for(int i=0; i<ECID_SIZE; i++)
+ printf("%02x", ecid[i]);
+}
+
+static void display_prefix_header(const ROM_prefix_header_raw *p)
+{
+ printf("Prefix Header:\n");
+ display_version_raw(p->ver_alg);
+ printf("code_start_offset: %08lx\n", be64_to_cpu(p->code_start_offset));
+ printf("reserved: %08lx\n", be64_to_cpu(p->reserved));
+ printf("flags: %08x\n", be32_to_cpu(p->flags));
+ printf("sw_key_count: %02x\n", p->sw_key_count);
+ printf("payload_size: %08lx\n", be64_to_cpu(p->payload_size));
+ printf("payloah_hash: ");
+ display_sha2_hash_t(p->payload_hash);
+ printf("\n");
+ printf("ecid_count: %02x\n", p->ecid_count);
+ for(int i=0; i< p->ecid_count; i++) {
+ printf("ecid: ");
+ display_ecid(p->ecid[i].ecid);
+ printf("\n");
+ }
+}
+
+static void display_sw_header(const ROM_sw_header_raw *swh)
+{
+ printf("Software Header:\n");
+ display_version_raw(swh->ver_alg);
+ printf("code_start_offset: %08lx\n", be64_to_cpu(swh->code_start_offset));
+ printf("reserved: %08lx\n", be64_to_cpu(swh->reserved));
+ printf("flags: %08x\n", be32_to_cpu(swh->flags));
+ printf("reserved_0: %02x\n", swh->reserved_0);
+ printf("payload_size: %08lx (%lu)\n", be64_to_cpu(swh->payload_size), be64_to_cpu(swh->payload_size));
+ printf("payloah_hash: ");
+ display_sha2_hash_t(swh->payload_hash);
+ printf("\n");
+ printf("ecid_count: %02x\n", swh->ecid_count);
+
+ for(int i=0; i< swh->ecid_count; i++) {
+ printf("ecid: ");
+ display_ecid(swh->ecid[i].ecid);
+ printf("\n");
+ }
+}
+
+static void display_ec_coord(const uint8_t *e)
+{
+ for(int i=0; i<EC_COORDBYTES*2; i++)
+ printf("%02x", e[i]);
+}
+
+static void display_prefix_data(const int sw_key_count, const ROM_prefix_data_raw *pd)
+{
+ printf("Prefix Data:\n");
+ printf("hw_sig_a: "); display_ec_coord(pd->hw_sig_a); printf("\n");
+ printf("hw_sig_b: "); display_ec_coord(pd->hw_sig_b); printf("\n");
+ printf("hw_sig_c: "); display_ec_coord(pd->hw_sig_c); printf("\n");
+ if (sw_key_count >=1) {
+ printf("sw_pkey_p: "); display_ec_coord(pd->sw_pkey_p); printf("\n");
+ }
+ if (sw_key_count >=2) {
+ printf("sw_pkey_q: "); display_ec_coord(pd->sw_pkey_q); printf("\n");
+ }
+ if (sw_key_count >=3) {
+ printf("sw_pkey_r: "); display_ec_coord(pd->sw_pkey_r); printf("\n");
+ }
+}
+
+static void display_sw_sig(const ROM_sw_sig_raw *s)
+{
+ printf("Software Signatures:\n");
+ printf("sw_sig_p: "); display_ec_coord(s->sw_sig_p); printf("\n");
+ printf("sw_sig_q: "); display_ec_coord(s->sw_sig_q); printf("\n");
+ printf("sw_sig_r: "); display_ec_coord(s->sw_sig_r); printf("\n");
+}
+
+static void display_rom_container_raw(const ROM_container_raw *rcr)
+{
+ printf("Container:\n");
+ printf("magic: 0x%04x\n", be32_to_cpu(rcr->magic_number));
+ printf("version: 0x%02x\n", be16_to_cpu(rcr->version));
+ printf("container_size: 0x%08lx (%lu)\n", be64_to_cpu(rcr->container_size), be64_to_cpu(rcr->container_size));
+ printf("target_hrmor: 0x%08lx\n", be64_to_cpu(rcr->target_hrmor));
+ printf("stack_pointer: 0x%08lx\n", be64_to_cpu(rcr->stack_pointer));
+ printf("hw_pkey_a:\n");
+ for(int i=0; i < EC_COORDBYTES; i++)
+ printf("%02x", rcr->hw_pkey_a[i]);
+ printf("\n");
+ printf("hw_pkey_b:\n");
+ for(int i=0; i < EC_COORDBYTES; i++)
+ printf("%02x", rcr->hw_pkey_b[i]);
+ printf("\n");
+ printf("hw_pkey_c:\n");
+ for(int i=0; i < EC_COORDBYTES; i++)
+ printf("%02x", rcr->hw_pkey_c[i]);
+ printf("\n");
+}
+
+static void display_container(char* f)
+{
+ int fd = open(f, O_RDONLY);
+ void *container = malloc(SECURE_BOOT_HEADERS_SIZE);
+ struct parsed_stb_container c;
+ size_t sz;
+
+ assert(container);
+ if (fd == -1) {
+ perror(strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ sz = read(fd, container, SECURE_BOOT_HEADERS_SIZE);
+ if (sz != SECURE_BOOT_HEADERS_SIZE) {
+ perror(strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (!stb_is_container(container, SECURE_BOOT_HEADERS_SIZE)) {
+ fprintf(stderr, "Not a container, missing magic number\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (parse_stb_container(container, SECURE_BOOT_HEADERS_SIZE, &c) != 0) {
+ fprintf(stderr, "Failed to parse container.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ display_rom_container_raw(c.c);
+ printf("\n");
+
+ display_prefix_header(c.ph);
+ printf("\n");
+
+ display_prefix_data(c.ph->sw_key_count, c.pd);
+ printf("\n");
+
+ display_sw_header(c.sh);
+ printf("\n");
+
+ display_sw_sig(c.ssig);
+
+ free(container);
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2) {
+ fprintf(stderr, "Usage %s container_file\n", argv[0]);
+ return 0;
+ }
+
+ display_container(argv[1]);
+
+ return 0;
+}
diff --git a/libstb/test/run-stb-container.c b/libstb/test/run-stb-container.c
new file mode 100644
index 0000000..4bcb4c3
--- /dev/null
+++ b/libstb/test/run-stb-container.c
@@ -0,0 +1,34 @@
+/* Copyright 2013-2014 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include "../container.c"
+
+#include <assert.h>
+
+int main(void)
+{
+ ROM_container_raw *c = malloc(SECURE_BOOT_HEADERS_SIZE);
+ assert(stb_is_container(NULL, 0) == false);
+ assert(stb_is_container(NULL, SECURE_BOOT_HEADERS_SIZE) == false);
+ c->magic_number = cpu_to_be32(ROM_MAGIC_NUMBER + 1);
+ assert(stb_is_container(c, SECURE_BOOT_HEADERS_SIZE) == false);
+ c->magic_number = cpu_to_be32(ROM_MAGIC_NUMBER);
+ assert(stb_is_container(c, SECURE_BOOT_HEADERS_SIZE) == true);
+
+ return 0;
+}
diff --git a/libstb/test/t.container b/libstb/test/t.container
new file mode 100644
index 0000000..cca142e
--- /dev/null
+++ b/libstb/test/t.container
Binary files differ
diff --git a/libstb/test/t.container.out b/libstb/test/t.container.out
new file mode 100644
index 0000000..d613282
--- /dev/null
+++ b/libstb/test/t.container.out
@@ -0,0 +1,48 @@
+Container:
+magic: 0x17082011
+version: 0x01
+container_size: 0x00000000 (0)
+target_hrmor: 0x00000000
+stack_pointer: 0x00000000
+hw_pkey_a:
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+hw_pkey_b:
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+hw_pkey_c:
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+
+Prefix Header:
+ver_alg:
+ version: 0001
+ hash_alg: 01 (SHA512)
+ sig_alg: 01 (SHA512/ECDSA-521)
+code_start_offset: 00000000
+reserved: 00000000
+flags: 00000000
+sw_key_count: 00
+payload_size: 00000000
+payloah_hash: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ecid_count: 00
+
+Prefix Data:
+hw_sig_a: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+hw_sig_b: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+hw_sig_c: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+
+Software Header:
+ver_alg:
+ version: 0000
+ hash_alg: 00 (UNKNOWN)
+ sig_alg: 00 (UNKNOWN)
+code_start_offset: 00000000
+reserved: 00000000
+flags: 00000000
+reserved_0: 00
+payload_size: 00000000 (0)
+payloah_hash: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ecid_count: 00
+
+Software Signatures:
+sw_sig_p: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+sw_sig_q: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+sw_sig_r: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000