-
Notifications
You must be signed in to change notification settings - Fork 54.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
powerpc: Load firmware trusted keys/hashes into kernel keyring
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
Showing
3 changed files
with
108 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |