[Skiboot] [PATCH v2 08/31] libstb: add required container header structures
Claudio Carvalho
cclaudio at linux.vnet.ibm.com
Wed Sep 28 18:01:07 AEST 2016
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 <cclaudio at linux.vnet.ibm.com>
---
Makefile.main | 3 +-
libstb/Makefile.inc | 11 +++++
libstb/container.c | 74 +++++++++++++++++++++++++++
libstb/container.h | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 227 insertions(+), 1 deletion(-)
create mode 100644 libstb/Makefile.inc
create mode 100644 libstb/container.c
create mode 100644 libstb/container.h
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..5a5cbcd
--- /dev/null
+++ b/libstb/container.c
@@ -0,0 +1,74 @@
+/* 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));
+}
+
+const sha2_hash_t* stb_sw_payload_hash(const void *buf, size_t size)
+{
+ const ROM_prefix_header_raw* prefix;
+ const ROM_prefix_data_raw* hw_data;
+ const ROM_sw_header_raw* header;
+
+ if (!stb_is_container(buf, size))
+ return NULL;
+ prefix = (ROM_prefix_header_raw*) &((ROM_container_raw*)buf)->prefix;
+ hw_data = (ROM_prefix_data_raw*) (prefix->ecid +
+ prefix->ecid_count*ECID_SIZE);
+ header = (ROM_sw_header_raw*) (hw_data->sw_pkey_p +
+ prefix->sw_key_count*sizeof(ecc_key_t));
+ return &header->payload_hash;
+}
+
+void stb_print_data(const void* data, size_t len)
+{
+ int i, j;
+ unsigned char *p;
+ unsigned char hash[30];
+
+ p = (unsigned char*) data;
+ j = 0;
+ for (i = 0; i < len; i++) {
+ if (!(i%10) && i) {
+ prlog(PR_NOTICE, "%s\n", hash);
+ j=0;
+ }
+ snprintf(&hash[j], 30-j, "%02x ", p[i]);
+ j+=3;
+ }
+ prlog(PR_NOTICE, "%s\n", hash);
+}
diff --git a/libstb/container.h b/libstb/container.h
new file mode 100644
index 0000000..8ec040a
--- /dev/null
+++ b/libstb/container.h
@@ -0,0 +1,140 @@
+/* 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 {
+ 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;
+ be64 prefix; /* prefix header place holder */
+ /* followed by sw header (if not special prefix) */
+ /* followed by optional unprotected payload data */
+}__attribute__((packed)) ROM_container_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;
+ uint8_t ecid[ECID_SIZE]; /* 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 {
+ 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;
+ uint8_t ecid[ECID_SIZE]; /* 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;
+
+/*
+ * 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 sha2_hash_t* stb_sw_payload_hash(const void* buf, size_t size);
+
+void stb_print_data(const void *data, size_t len);
+
+#endif /* __STB_CONTAINER_H */
--
1.9.1
More information about the Skiboot
mailing list