aboutsummaryrefslogtreecommitdiff
path: root/libstb
diff options
context:
space:
mode:
authorClaudio Carvalho <cclaudio@linux.vnet.ibm.com>2017-12-09 02:52:19 -0200
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-12-18 21:30:57 -0600
commit3ab91fbec937830f184108a244795a2e05cb275c (patch)
treeb98fb42fb1d4d72cc88c669a9bef4a1cf19c4131 /libstb
parent060ff18d4ddcfb87e9aa31fc5eadaf4318bca9bb (diff)
downloadskiboot-3ab91fbec937830f184108a244795a2e05cb275c.zip
skiboot-3ab91fbec937830f184108a244795a2e05cb275c.tar.gz
skiboot-3ab91fbec937830f184108a244795a2e05cb275c.tar.bz2
libstb/secureboot.c: import sb_verify() from stb.c
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@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'libstb')
-rw-r--r--libstb/cvc.c44
-rw-r--r--libstb/cvc.h20
-rw-r--r--libstb/drivers/romcode.c4
-rw-r--r--libstb/secureboot.c52
-rw-r--r--libstb/secureboot.h17
5 files changed, 131 insertions, 6 deletions
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 */