[Skiboot] [PATCH v2 05/20] libstb/secureboot.c: import sb_verify() from stb.c

Claudio Carvalho cclaudio at linux.vnet.ibm.com
Sat Dec 9 15:52:19 AEDT 2017


This imports the sb_verify() function from stb.c, but now it calls the
CVC verify wrapper in order to verify signed firmware images. The
hw-key-hash and hw-key-hash-size initialized in secureboot.c are passed
to the CVC verify function wrapper.

In secureboot.c, the sb_verify() is renamed to secureboot_verify(). The
sb_verify() calls are updated in a subsequent patch.

Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
---
 asm/Makefile.inc                 |  2 +-
 asm/{rom_entry.S => cvc_entry.S} |  4 ++--
 libstb/cvc.c                     | 44 +++++++++++++++++++++++++++++++++-
 libstb/cvc.h                     | 20 ++++++++++++++++
 libstb/drivers/romcode.c         |  4 ++--
 libstb/secureboot.c              | 52 +++++++++++++++++++++++++++++++++++++---
 libstb/secureboot.h              | 17 +++++++++++++
 7 files changed, 134 insertions(+), 9 deletions(-)
 rename asm/{rom_entry.S => cvc_entry.S} (96%)

diff --git a/asm/Makefile.inc b/asm/Makefile.inc
index 34e2b28..2828caf 100644
--- a/asm/Makefile.inc
+++ b/asm/Makefile.inc
@@ -1,7 +1,7 @@
 # -*-Makefile-*-
 
 SUBDIRS += asm 
-ASM_OBJS = head.o misc.o kernel-wrapper.o rom_entry.o
+ASM_OBJS = head.o misc.o kernel-wrapper.o cvc_entry.o
 ASM=asm/built-in.o
 
 # Add extra dependency to the kernel wrapper
diff --git a/asm/rom_entry.S b/asm/cvc_entry.S
similarity index 96%
rename from asm/rom_entry.S
rename to asm/cvc_entry.S
index 26d1b96..ccca006 100644
--- a/asm/rom_entry.S
+++ b/asm/cvc_entry.S
@@ -25,10 +25,10 @@
 
 .section .text
 
-.global call_rom_verify
+.global __cvc_verify_v1
 .global call_rom_SHA512
 
-call_rom_verify:
+__cvc_verify_v1:
 call_rom_SHA512:
 
 call_rom_entry:
diff --git a/libstb/cvc.c b/libstb/cvc.c
index 86d292d..96c48f4 100644
--- a/libstb/cvc.c
+++ b/libstb/cvc.c
@@ -20,12 +20,20 @@
 
 #include <skiboot.h>
 #include <string.h>
+#include <opal-api.h>
 #include <chip.h>
 #include <xscom.h>
 #include <inttypes.h>
 #include "secureboot.h"
 #include "cvc.h"
 
+/*
+ * Assembly interfaces to call into the Container Verification Code.
+ * func_ptr: CVC base address + offset
+ */
+ROM_response __cvc_verify_v1(void *func_ptr, ROM_container_raw *container,
+			     ROM_hw_params *params);
+
 struct container_verification_code {
 	uint64_t start_addr;
 	uint64_t end_addr;
@@ -189,6 +197,40 @@ int cvc_init(void)
 		      __func__);
 		return -1;
 	}
-
 	return rc;
 }
+
+int call_cvc_verify(void *container, size_t len, const void *hw_key_hash,
+		    size_t hw_key_hash_size, uint64_t *log)
+{
+	ROM_hw_params hw_params;
+	ROM_response rc;
+	struct cvc_service *service;
+
+	if (!container || len < SECURE_BOOT_HEADERS_SIZE ||
+	    !hw_key_hash || hw_key_hash_size <= 0)
+		return OPAL_PARAMETER;
+
+	service = cvc_find_service(CVC_VERIFY_SERVICE);
+
+	if (!service)
+		return OPAL_UNSUPPORTED;
+
+	memset(&hw_params, 0, sizeof(ROM_hw_params));
+	memcpy(&hw_params.hw_key_hash, hw_key_hash, hw_key_hash_size);
+
+	if (service->version == 1)
+		rc = __cvc_verify_v1((void*) service->addr,
+				   (ROM_container_raw*) container,
+				   &hw_params);
+	else
+		return OPAL_UNSUPPORTED;
+
+	if (log)
+		*log = hw_params.log;
+
+	if (rc != ROM_DONE)
+		return OPAL_PARTIAL;
+
+	return OPAL_SUCCESS;
+}
diff --git a/libstb/cvc.h b/libstb/cvc.h
index 3d7079e..14e8cd2 100644
--- a/libstb/cvc.h
+++ b/libstb/cvc.h
@@ -24,4 +24,24 @@ enum cvc_service_id {
 
 int cvc_init(void);
 
+/************************************************************************
+ * Wrappers for the services provided by the Container-Verification-Code
+ ************************************************************************/
+
+/*
+ * call_cvc_verify - Call the CVC-verify service to verify the container fetched
+ * from PNOR.
+ *
+ * @buf - buffer that has the firmware component to be verified
+ * @size - number of bytes allocated for @buf
+ * @hw_key_hash - hash of the three harware public keys trusted by the platform
+ * owner
+ * @hw_key_hash_size - number of bytes allocated for @hw_key_hash
+ * @log - hexadecimal returned by the CVC. In case of verification failure, it
+ * indicates what checking failed
+ *
+ */
+int call_cvc_verify(void *buf, size_t size, const void *hw_key_hash,
+		    size_t hw_key_hash_size, uint64_t *log);
+
 #endif /* __CVC_H */
diff --git a/libstb/drivers/romcode.c b/libstb/drivers/romcode.c
index 94bd42c..d914ba1 100644
--- a/libstb/drivers/romcode.c
+++ b/libstb/drivers/romcode.c
@@ -42,7 +42,7 @@ static sha2_hash_t *hw_key_hash = NULL;
  * 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_response __cvc_verify_v1(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);
@@ -54,7 +54,7 @@ static int romcode_verify(void *container)
 
 	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,
+	rc = __cvc_verify_v1(romcode_base_addr + ROMCODE_VERIFY_OFFSET,
 			     (ROM_container_raw*) container, &hw_params);
 	if (rc != ROM_DONE) {
 		/*
diff --git a/libstb/secureboot.c b/libstb/secureboot.c
index cdb6ea5..2787951 100644
--- a/libstb/secureboot.c
+++ b/libstb/secureboot.c
@@ -21,9 +21,9 @@
 #include <skiboot.h>
 #include <device.h>
 #include <nvram.h>
+#include <opal-api.h>
+#include <inttypes.h>
 #include "secureboot.h"
-#include "container.h"
-#include "cvc.h"
 
 static const void* hw_key_hash = NULL;
 static size_t hw_key_hash_size;
@@ -48,7 +48,7 @@ static void secureboot_enforce(void)
 	 * extra info to BMC other than just abort.  Terminate Immediate
 	 * Attention ? (TI)
 	 */
-	prlog(PR_EMERG, "enforcing secure mode ...\n");
+	prlog(PR_EMERG, "secure mode enforced, aborting.\n");
 	abort();
 }
 
@@ -146,3 +146,49 @@ void secureboot_init(void)
 	if (cvc_init())
 		secureboot_enforce();
 }
+
+int secureboot_verify(enum resource_id id, void *buf, size_t len)
+{
+	const char *name;
+	uint64_t log;
+	int rc = -1;
+
+	if (!secure_mode)
+		return 0;
+
+	name = flash_map_resource_name(id);
+	if (!name) {
+		prlog(PR_EMERG, "container NOT VERIFIED, resource_id=%d "
+		      "unknown\n", id);
+		secureboot_enforce();
+	}
+
+	rc = call_cvc_verify(buf, len, hw_key_hash, hw_key_hash_size, &log);
+
+	if (rc == OPAL_SUCCESS) {
+		prlog(PR_INFO, "%s verified\n", name);
+	} else if (rc == OPAL_PARTIAL) {
+		/*
+		 * The value returned in log indicates what checking has
+		 * failed. Return codes defined in
+		 * /hostboot/src/include/securerom/status_codes.H
+		 */
+		prlog(PR_EMERG, "%s verification FAILED. log=0x%" PRIx64 "\n",
+			name, be64_to_cpu(log));
+		secureboot_enforce();
+	} else if (rc == OPAL_PARAMETER) {
+		prlog(PR_EMERG, "%s NOT VERIFIED, invalid param. buf=%p, "
+		      "len=%zd key-hash=%p hash-size=%zd\n", name, buf, len,
+		      hw_key_hash, hw_key_hash_size);
+		secureboot_enforce();
+	} else if (rc == OPAL_UNSUPPORTED) {
+		prlog(PR_EMERG, "%s NOT VERIFIED, CVC-verify service not "
+		      "supported\n", name);
+		secureboot_enforce();
+	} else {
+		prlog(PR_EMERG, "%s NOT VERIFIED, unknown CVC-verify error. "
+		      "rc=%d\n", name, rc);
+		secureboot_enforce();
+	}
+	return 0;
+}
diff --git a/libstb/secureboot.h b/libstb/secureboot.h
index 6643160..ea97ed7 100644
--- a/libstb/secureboot.h
+++ b/libstb/secureboot.h
@@ -17,6 +17,7 @@
 #ifndef __SECUREBOOT_H
 #define __SECUREBOOT_H
 
+#include <platform.h>
 #include <device.h>
 #include "container.h"
 #include "cvc.h"
@@ -28,4 +29,20 @@ enum secureboot_version {
 bool secureboot_is_compatible(struct dt_node *node, int *version, const char **compat);
 void secureboot_init(void);
 
+/**
+ * secureboot_verify - verify a PNOR partition content
+ * @id   : PNOR partition id
+ * @buf  : PNOR partition content to be verified
+ * @len  : @buf length
+ *
+ * This verifies the integrity and authenticity of @buf downloaded from PNOR if
+ * secure mode is on. The verification is done by the Container Verification
+ * Code (CVC) flashed in ROM.
+ *
+ * For more information refer to 'doc/stb.rst'
+ *
+ * returns: 0 otherwise the boot process is aborted
+ */
+int secureboot_verify(enum resource_id id, void *buf, size_t len);
+
 #endif /* __SECUREBOOT_H */
-- 
2.7.4



More information about the Skiboot mailing list