[Skiboot] [PATCH] stb: create-container and wrap skiboot in Secure/Trusted Boot container

Gavin Shan gwshan at linux.vnet.ibm.com
Fri Nov 18 10:06:56 AEDT 2016


On Thu, Nov 17, 2016 at 07:33:59PM +1100, Stewart Smith wrote:
>We produce **UNSIGNED** skiboot.lid.stb and skiboot.lid.xz.stb as build
>artifacts
>
>These are suitable blobs for flashing onto Trusted Boot enabled op-build
>builds *WITH* the secure boot jumpers *ON* (i.e. *NOT* in secure mode).
>
>It's just enough of the Secure and Trusted Boot container format to
>make Hostboot behave.
>
>Signed-off-by: Stewart Smith <stewart at linux.vnet.ibm.com>

Tested-by: Gavin Shan <gwshan at linux.vnet.ibm.com>

Thanks, Stewart. There is one minor comment below.

>--
>This is really a V3 of the plain create-container utility.
>This utility still casually sucks, but it's about 8000 LoC smaller than
>the full sb-signing-tool (not to be confused with sbsigntool or signtool).
>---
> Makefile.main             |   7 +++
> libstb/Makefile.inc       |   4 ++
> libstb/create-container.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 129 insertions(+)
> create mode 100644 libstb/create-container.c
>
>diff --git a/Makefile.main b/Makefile.main
>index 62a659d..a2b0bcd 100644
>--- a/Makefile.main
>+++ b/Makefile.main
>@@ -166,6 +166,7 @@ pflash-coverity:
> 	(cd external/pflash; ./build-all-arch.sh)
> 
> all: $(SUBDIRS) $(TARGET).lid $(TARGET).lid.xz $(TARGET).map extract-gcov
>+all: $(TARGET).lid.stb $(TARGET).lid.xz.stb
> 
> OBJS := $(ASM) $(CORE) $(HW) $(PLATFORMS) $(LIBFDT) $(LIBFLASH) $(LIBSTB)
> ifeq ($(PORE),1)
>@@ -184,6 +185,12 @@ $(TARGET).lid.xz: $(TARGET).lid
> $(TARGET).lid: $(TARGET).elf
> 	$(call Q,OBJCOPY, $(OBJCOPY) -O binary -S $^ $@, $@)
> 
>+$(TARGET).lid.stb: $(TARGET).lid libstb/create-container
>+	$(call Q,STB-UNSIGNED-CONTAINER,./libstb/create-container $< $@,$@)
>+
>+$(TARGET).lid.xz.stb: $(TARGET).lid.xz libstb/create-container
>+	$(call Q,STB-UNSIGNED-CONTAINER,./libstb/create-container $< $@,$@)
>+
> $(TARGET).tmp.elf: $(ALL_OBJS_1) $(TARGET).lds $(KERNEL)
> 	$(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_1) -o $@, $@)
> 
>diff --git a/libstb/Makefile.inc b/libstb/Makefile.inc
>index 337b9e4..b7e7841 100644
>--- a/libstb/Makefile.inc
>+++ b/libstb/Makefile.inc
>@@ -12,3 +12,7 @@ include $(SRC)/$(LIBSTB_DIR)/drivers/Makefile.inc
> include $(SRC)/$(LIBSTB_DIR)/tss/Makefile.inc
> 
> $(LIBSTB): $(LIBSTB_OBJS:%=$(LIBSTB_DIR)/%) $(DRIVERS) $(TSS)
>+
>+libstb/create-container: libstb/create-container.c
>+	$(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) \
>+	-Wpadded -O0 -g -I$(SRC) -o $@ $<,$<)
>diff --git a/libstb/create-container.c b/libstb/create-container.c
>new file mode 100644
>index 0000000..1fe222d
>--- /dev/null
>+++ b/libstb/create-container.c
>@@ -0,0 +1,118 @@
>+/* 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 <config.h>
>+
>+#include <stdbool.h>
>+#include <types.h>
>+#include "container.h"
>+
>+#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 <sys/mman.h>
>+#include <fcntl.h>
>+#include <assert.h>
>+
>+int main(int argc, char* argv[])
>+{
>+	int fdin, fdout;
>+	void *container = malloc(SECURE_BOOT_HEADERS_SIZE);
>+	struct stat s;
>+	char *buf = malloc(4096);
>+	off_t l;
>+	void *infile;
>+	int r;
>+	ROM_container_raw *c = (ROM_container_raw*)container;
>+	ROM_prefix_header_raw *ph;
>+	ROM_prefix_data_raw *pd;
>+	ROM_sw_header_raw *swh;
>+
>+	memset(container, 0, SECURE_BOOT_HEADERS_SIZE);
>+
>+	if (argc<3)
>+		return -1;
>+
>+	fdin = open(argv[1], O_RDONLY);
>+	assert(fdin > 0);
>+	r = fstat(fdin, &s);
>+	assert(r==0);
>+	infile = mmap(NULL, s.st_size, PROT_READ, 0, fdin, 0);
>+	assert(infile);
>+	fdout = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC);

The output file's permission is 'x', meaning it can't be overwritten when
re-constructing it. I think the 3rd argument of open() would be as below
and it worked for me :)

(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

>+	assert(fdout > 0);
>+
>+	c->magic_number = cpu_to_be32(ROM_MAGIC_NUMBER);
>+	c->version = 1;
>+	c->container_size = cpu_to_be64(SECURE_BOOT_HEADERS_SIZE + s.st_size);
>+	c->target_hrmor = 0;
>+	c->stack_pointer = 0;
>+	memset(c->hw_pkey_a, 0, sizeof(ecc_key_t));
>+	memset(c->hw_pkey_b, 0, sizeof(ecc_key_t));
>+	memset(c->hw_pkey_c, 0, sizeof(ecc_key_t));
>+
>+	ph = container + sizeof(ROM_container_raw);
>+	ph->ver_alg.version = cpu_to_be16(1);
>+	ph->ver_alg.hash_alg = 1;
>+	ph->ver_alg.sig_alg = 1;
>+	ph->code_start_offset = 0;
>+	ph->reserved = 0;
>+	ph->flags = 0;
>+	ph->sw_key_count = 1; // 1, not 0. Because Hostboot
>+	memset(ph->payload_hash, 0, sizeof(sha2_hash_t)); // TODO
>+	ph->ecid_count = 0;
>+
>+	pd = (ROM_prefix_data_raw*)ph->ecid;
>+	memset(pd->hw_sig_a, 0, sizeof(ecc_signature_t));
>+	memset(pd->hw_sig_b, 0, sizeof(ecc_signature_t));
>+	memset(pd->hw_sig_c, 0, sizeof(ecc_signature_t));
>+	memset(pd->sw_pkey_p, 0, sizeof(ecc_key_t));
>+	memset(pd->sw_pkey_q, 0, sizeof(ecc_key_t));
>+	memset(pd->sw_pkey_r, 0, sizeof(ecc_key_t));
>+	ph->payload_size = cpu_to_be64(sizeof(ecc_signature_t)*3 + ph->sw_key_count * sizeof(ecc_key_t));
>+
>+	swh = (ROM_sw_header_raw*)(((void*)pd) + be64_to_cpu(ph->payload_size));
>+	swh->ver_alg.version = cpu_to_be16(1);
>+	swh->ver_alg.hash_alg = 1;
>+	swh->ver_alg.sig_alg = 1;
>+	swh->code_start_offset = 0;
>+	swh->reserved = 0;
>+	swh->flags = 0;
>+	swh->reserved_0 = 0;
>+	swh->payload_size = cpu_to_be64(s.st_size);
>+
>+	r = write(fdout, container, SECURE_BOOT_HEADERS_SIZE);
>+	assert(r == 4096);
>+	read(fdin, buf, s.st_size%4096);
>+	write(fdout, buf, s.st_size%4096);
>+	l = s.st_size - s.st_size%4096;
>+	while (l) {
>+		read(fdin, buf, 4096);
>+		write(fdout, buf, 4096);
>+		l-=4096;
>+	};
>+	close(fdin);
>+	close(fdout);
>+
>+	free(container);
>+	free(buf);
>+	return 0;
>+}

Thanks,
Gavin



More information about the Skiboot mailing list