diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile.main | 3 | ||||
-rw-r--r-- | libstb/Makefile.inc | 11 | ||||
-rw-r--r-- | libstb/container.c | 85 | ||||
-rw-r--r-- | libstb/container.h | 151 | ||||
-rw-r--r-- | libstb/test/Makefile.check | 44 | ||||
-rw-r--r-- | libstb/test/print-stb-container.c | 206 | ||||
-rw-r--r-- | libstb/test/run-stb-container.c | 34 | ||||
-rw-r--r-- | libstb/test/t.container | bin | 0 -> 4096 bytes | |||
-rw-r--r-- | libstb/test/t.container.out | 48 |
10 files changed, 583 insertions, 1 deletions
@@ -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 Binary files differnew file mode 100644 index 0000000..cca142e --- /dev/null +++ b/libstb/test/t.container 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 |