[Skiboot] [PATCH 14/15] libstb/drivers: Add ROM code driver
Claudio Carvalho
cclaudio at linux.vnet.ibm.com
Thu Aug 11 15:23:56 AEST 2016
This adds a driver for the ROM verification code. The driver is compatible
with 'ibm,secureboot-v1'.
The presense of a verification code in the platform is indicated by the
presence of the ibm,secureboot node in the device tree.
The ibm,secureboot node is documented in 'doc/device-tree/ibm,secureboot.txt'
Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
---
libstb/drivers/Makefile.inc | 2 +-
libstb/drivers/romcode.c | 144 ++++++++++++++++++++++++++++++++++++++++++++
libstb/drivers/romcode.h | 24 ++++++++
libstb/rom.c | 3 +-
libstb/status_codes.h | 3 +
5 files changed, 174 insertions(+), 2 deletions(-)
create mode 100644 libstb/drivers/romcode.c
create mode 100644 libstb/drivers/romcode.h
diff --git a/libstb/drivers/Makefile.inc b/libstb/drivers/Makefile.inc
index 12d8e82..20ba998 100644
--- a/libstb/drivers/Makefile.inc
+++ b/libstb/drivers/Makefile.inc
@@ -4,7 +4,7 @@ DRIVERS_DIR = libstb/drivers
SUBDIRS += $(DRIVERS_DIR)
-DRIVERS_SRCS = tpm_i2c_nuvoton.c
+DRIVERS_SRCS = tpm_i2c_nuvoton.c romcode.c
DRIVERS_OBJS = $(DRIVERS_SRCS:%.c=%.o)
DRIVERS = $(DRIVERS_DIR)/built-in.o
diff --git a/libstb/drivers/romcode.c b/libstb/drivers/romcode.c
new file mode 100644
index 0000000..557a345
--- /dev/null
+++ b/libstb/drivers/romcode.c
@@ -0,0 +1,144 @@
+/* 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 <chip.h>
+#include <xscom.h>
+#include <string.h>
+#include <skiboot.h>
+
+#include "../status_codes.h"
+#include "../rom.h"
+#include "romcode.h"
+
+#define DRIVER_NAME "romcode"
+
+#define ROMCODE_MEMORY_SIZE (16 * 1024)
+
+/* From the source code of the ROM code */
+#define ROMCODE_SHA512_OFFSET 0x20
+#define ROMCODE_VERIFY_OFFSET 0x30
+
+static const char *compat = "ibm,secureboot-v1";
+static void *romcode_base_addr = NULL;
+static sha2_hash_t *hw_key_hash = NULL;
+
+/**
+ * Assembly interfaces to call into ROM code.
+ * func_ptr is the ROM code function address, followed
+ * by additional parameters as necessary
+ */
+ROM_response call_rom_verify(void *func_ptr, ROM_container_raw *container,
+ ROM_hw_params *params);
+void call_rom_SHA512(void *func_ptr, const uint8_t *data, size_t len,
+ uint8_t *digest);
+
+static int romcode_verify(void *container)
+{
+ ROM_hw_params hw_params;
+ ROM_response rc;
+
+ memset(&hw_params, 0, sizeof(ROM_hw_params));
+ memcpy(&hw_params.hw_key_hash, hw_key_hash, sizeof(sha2_hash_t));
+
+ rc = call_rom_verify(romcode_base_addr + ROMCODE_VERIFY_OFFSET,
+ (ROM_container_raw*) container, &hw_params);
+
+ if (rc != ROM_DONE) {
+ /**
+ * Verify failed. hw_params.log indicates what checking has
+ * failed. This will abort the boot process.
+ */
+ prlog(PR_ERR, "ROM: %s failed (rc=%d, hw_params.log=0x%llx)\n",
+ __func__, rc, hw_params.log);
+ return STB_VERIFY_FAILED;
+ }
+
+ return STB_SUCCESS;
+}
+
+static void romcode_sha512(const uint8_t *data, size_t len, uint8_t *digest)
+{
+ memset(digest, 0, sizeof(sha2_hash_t));
+ call_rom_SHA512(romcode_base_addr + ROMCODE_SHA512_OFFSET,
+ data, len, digest);
+}
+
+static void romcode_cleanup(void) {
+ if (romcode_base_addr) {
+ free(romcode_base_addr);
+ }
+ hw_key_hash = NULL;
+}
+
+static struct rom_driver_ops romcode_driver = {
+ .name = DRIVER_NAME,
+ .verify = romcode_verify,
+ .sha512 = romcode_sha512,
+ .cleanup = romcode_cleanup
+};
+
+void romcode_probe(const struct dt_node *node)
+{
+ /* This xscom register has the ROM code base address */
+ const uint32_t reg_addr = 0x02020017;
+ uint64_t reg_data;
+ struct proc_chip *chip;
+
+ const char* hash_algo;
+
+ if (!dt_node_is_compatible(node, compat)) {
+ prlog(PR_DEBUG, "ROM: %s node is not compatible\n",
+ node->name);
+ return;
+ }
+
+ /* secureboot-v1 defines containers with sha512 hashes */
+ hash_algo = dt_prop_get(node, "hash-algo");
+ if (strcmp(hash_algo, "sha512")) {
+ /**
+ * @fwts-label ROMHashAlgorithmInvalid
+ * @fwts-advice Hostboot creates the ibm,secureboot node and
+ * the hash-algo property. Check that the ibm,secureboot node
+ * still have the same design.
+ */
+ prlog(PR_ERR, "ROM: hash-algo=%s not expected\n", hash_algo);
+ return;
+ }
+
+ hw_key_hash = (sha2_hash_t*) dt_prop_get(node, "hw-key-hash");
+
+ romcode_base_addr = malloc(ROMCODE_MEMORY_SIZE);
+ assert(romcode_base_addr);
+
+ /**
+ * We use memcpy_ci to copy the verification code from the secure ROM
+ * to memory. Due to performance issues we opted to run it from memory.
+ */
+ chip = next_chip(NULL);
+ xscom_read(chip->id, reg_addr, ®_data);
+ memcpy_ci(romcode_base_addr, (void*) reg_data,
+ ROMCODE_MEMORY_SIZE);
+
+ /**
+ * Skiboot runs with IR (Instruction Relocation) &
+ * DR (Data Relocation) off, so there is no need to neither MMIO
+ * the ROM code nor set the memory region as executable.
+ * skiboot access the physical memory directly. Real mode.
+ */
+
+ rom_set_driver(&romcode_driver);
+}
+
diff --git a/libstb/drivers/romcode.h b/libstb/drivers/romcode.h
new file mode 100644
index 0000000..4152eae
--- /dev/null
+++ b/libstb/drivers/romcode.h
@@ -0,0 +1,24 @@
+/* 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 __ROMCODE_H
+#define __ROMCODE_H
+
+#include <device.h>
+
+extern void romcode_probe(const struct dt_node *node);
+
+#endif /* __ROMCODE_H */
diff --git a/libstb/rom.c b/libstb/rom.c
index 7981eca..842243a 100644
--- a/libstb/rom.c
+++ b/libstb/rom.c
@@ -17,6 +17,7 @@
#include <skiboot.h>
#include "rom.h"
+#include "drivers/romcode.h"
static struct rom_driver_ops *rom_driver = NULL;
@@ -26,6 +27,7 @@ struct rom_driver_ops* rom_init(const struct dt_node *node)
goto end;
/* ROM drivers supported */
+ romcode_probe(node);
if (!rom_driver)
prlog(PR_NOTICE, "ROM: no rom driver found\n");
@@ -49,4 +51,3 @@ void rom_set_driver(struct rom_driver_ops *driver)
rom_driver = driver;
prlog(PR_NOTICE, "ROM: %s driver registered\n", driver->name);
}
-
diff --git a/libstb/status_codes.h b/libstb/status_codes.h
index a1a71da..106853c 100644
--- a/libstb/status_codes.h
+++ b/libstb/status_codes.h
@@ -22,6 +22,9 @@
#define STB_ARG_ERROR -1
#define STB_DRIVER_ERROR -2
+/* secure boot */
+#define STB_VERIFY_FAILED -100
+
/* trusted boot */
#define STB_EVENTLOG_FAILED -200
#define STB_PCR_EXTEND_FAILED -201
--
1.9.1
More information about the Skiboot
mailing list