From fab5418b256817e2695aa653d4840bfa5b5be53b Mon Sep 17 00:00:00 2001 From: Claudio Carvalho Date: Wed, 28 Sep 2016 05:01:07 -0300 Subject: libstb: add required container header structures The full container header layout will be released soon either as a separate github project or as part of hostboot. This adds the secure boot header structures required by skiboot, and also implements some helper routines related to containers. Signed-off-by: Claudio Carvalho [stewart@linux.vnet.ibm.com: Add unit test, print utility, use zero length arrays to ensure sizeof() works correctly, add parsing function] Signed-off-by: Stewart Smith --- libstb/test/Makefile.check | 44 ++++++++ libstb/test/print-stb-container.c | 206 ++++++++++++++++++++++++++++++++++++++ libstb/test/run-stb-container.c | 34 +++++++ libstb/test/t.container | Bin 0 -> 4096 bytes libstb/test/t.container.out | 48 +++++++++ 5 files changed, 332 insertions(+) create mode 100644 libstb/test/Makefile.check create mode 100644 libstb/test/print-stb-container.c create mode 100644 libstb/test/run-stb-container.c create mode 100644 libstb/test/t.container create mode 100644 libstb/test/t.container.out (limited to 'libstb/test') 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 + +#include +#include +#include "../container.h" +#include "../container.c" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; iver_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; ihw_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 + +#include "../container.c" + +#include + +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 Binary files /dev/null and b/libstb/test/t.container 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 -- cgit v1.1