diff mbox

stb: create-container and wrap skiboot in Secure/Trusted Boot container

Message ID 1479371639-31115-1-git-send-email-stewart@linux.vnet.ibm.com
State Accepted
Headers show

Commit Message

Stewart Smith Nov. 17, 2016, 8:33 a.m. UTC
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@linux.vnet.ibm.com>
--
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

Comments

Gavin Shan Nov. 17, 2016, 11:06 p.m. UTC | #1
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@linux.vnet.ibm.com>

Tested-by: Gavin Shan <gwshan@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
Stewart Smith Nov. 24, 2016, 5:53 a.m. UTC | #2
Gavin Shan <gwshan@linux.vnet.ibm.com> writes:
> 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@linux.vnet.ibm.com>
>
> Tested-by: Gavin Shan <gwshan@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)

ahh, thanks for catching that. Pushed to master as of
833b1e6bb2aef485226f8bc48ec1b45c422b2152 with that fix (and a minor
makefile fix).

It turns out I may be able to give talks on how everybody gets POSIX
file IO wrong and be quite accurate about it. Everybody includes me.
diff mbox

Patch

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);
+	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;
+}