[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