Skip to content

Commit

Permalink
libstb/secureboot.c: import sb_verify() from stb.c
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Claudio Carvalho authored and stewartsmith committed Dec 19, 2017
1 parent 060ff18 commit 3ab91fb
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 9 deletions.
2 changes: 1 addition & 1 deletion 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
Expand Down
4 changes: 2 additions & 2 deletions asm/rom_entry.S → asm/cvc_entry.S
Expand Up @@ -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:
Expand Down
44 changes: 43 additions & 1 deletion libstb/cvc.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
20 changes: 20 additions & 0 deletions libstb/cvc.h
Expand Up @@ -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 */
4 changes: 2 additions & 2 deletions libstb/drivers/romcode.c
Expand Up @@ -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);
Expand All @@ -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) {
/*
Expand Down
52 changes: 49 additions & 3 deletions libstb/secureboot.c
Expand Up @@ -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;
Expand All @@ -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();
}

Expand Down Expand Up @@ -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;
}
17 changes: 17 additions & 0 deletions libstb/secureboot.h
Expand Up @@ -17,6 +17,7 @@
#ifndef __SECUREBOOT_H
#define __SECUREBOOT_H

#include <platform.h>
#include <device.h>
#include "container.h"
#include "cvc.h"
Expand All @@ -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 */

0 comments on commit 3ab91fb

Please sign in to comment.