Skip to content

Commit

Permalink
powerpc: Load firmware trusted keys/hashes into kernel keyring
Browse files Browse the repository at this point in the history
The keys used to verify the Host OS kernel are managed by firmware as
secure variables. This patch loads the verification keys into the
.platform keyring and revocation hashes into .blacklist keyring. This
enables verification and loading of the kernels signed by the boot
time keys which are trusted by firmware.

Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Eric Richter <erichte@linux.ibm.com>
[mpe: Search by compatible in load_powerpc_certs(), not using format]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1573441836-3632-5-git-send-email-nayna@linux.ibm.com
  • Loading branch information
naynajain authored and mpe committed Nov 12, 2019
1 parent ad72367 commit 8220e22
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 1 deletion.
9 changes: 9 additions & 0 deletions security/integrity/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ config LOAD_IPL_KEYS
depends on S390
def_bool y

config LOAD_PPC_KEYS
bool "Enable loading of platform and blacklisted keys for POWER"
depends on INTEGRITY_PLATFORM_KEYRING
depends on PPC_SECURE_BOOT
default y
help
Enable loading of keys to the .platform keyring and blacklisted
hashes to the .blacklist keyring for powerpc based platforms.

config INTEGRITY_AUDIT
bool "Enables integrity auditing support "
depends on AUDIT
Expand Down
4 changes: 3 additions & 1 deletion security/integrity/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \
platform_certs/load_uefi.o \
platform_certs/keyring_handler.o
integrity-$(CONFIG_LOAD_IPL_KEYS) += platform_certs/load_ipl_s390.o

integrity-$(CONFIG_LOAD_PPC_KEYS) += platform_certs/efi_parser.o \
platform_certs/load_powerpc.o \
platform_certs/keyring_handler.o
obj-$(CONFIG_IMA) += ima/
obj-$(CONFIG_EVM) += evm/
96 changes: 96 additions & 0 deletions security/integrity/platform_certs/load_powerpc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 IBM Corporation
* Author: Nayna Jain
*
* - loads keys and hashes stored and controlled by the firmware.
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/cred.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <asm/secure_boot.h>
#include <asm/secvar.h>
#include "keyring_handler.h"

/*
* Get a certificate list blob from the named secure variable.
*/
static __init void *get_cert_list(u8 *key, unsigned long keylen, uint64_t *size)
{
int rc;
void *db;

rc = secvar_ops->get(key, keylen, NULL, size);
if (rc) {
pr_err("Couldn't get size: %d\n", rc);
return NULL;
}

db = kmalloc(*size, GFP_KERNEL);
if (!db)
return NULL;

rc = secvar_ops->get(key, keylen, db, size);
if (rc) {
kfree(db);
pr_err("Error reading %s var: %d\n", key, rc);
return NULL;
}

return db;
}

/*
* Load the certs contained in the keys databases into the platform trusted
* keyring and the blacklisted X.509 cert SHA256 hashes into the blacklist
* keyring.
*/
static int __init load_powerpc_certs(void)
{
void *db = NULL, *dbx = NULL;
uint64_t dbsize = 0, dbxsize = 0;
int rc = 0;
struct device_node *node;

if (!secvar_ops)
return -ENODEV;

/* The following only applies for the edk2-compat backend. */
node = of_find_compatible_node(NULL, NULL, "ibm,edk2-compat-v1");
if (!node)
return -ENODEV;

/*
* Get db, and dbx. They might not exist, so it isn't an error if we
* can't get them.
*/
db = get_cert_list("db", 3, &dbsize);
if (!db) {
pr_err("Couldn't get db list from firmware\n");
} else {
rc = parse_efi_signature_list("powerpc:db", db, dbsize,
get_handler_for_db);
if (rc)
pr_err("Couldn't parse db signatures: %d\n", rc);
kfree(db);
}

dbx = get_cert_list("dbx", 4, &dbxsize);
if (!dbx) {
pr_info("Couldn't get dbx list from firmware\n");
} else {
rc = parse_efi_signature_list("powerpc:dbx", dbx, dbxsize,
get_handler_for_dbx);
if (rc)
pr_err("Couldn't parse dbx signatures: %d\n", rc);
kfree(dbx);
}

of_node_put(node);

return rc;
}
late_initcall(load_powerpc_certs);

0 comments on commit 8220e22

Please sign in to comment.