On Mon, 2019-08-26 at 09:23 -0400, Nayna Jain wrote: > 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@xxxxxxxxxxxxx> Feel free to add my tag after addressing the formatting issues. Reviewed-by: Mimi Zohar <zohar@xxxxxxxxxxxxx> > diff --git a/security/integrity/platform_certs/load_powerpc.c b/security/integrity/platform_certs/load_powerpc.c > new file mode 100644 > index 000000000000..359d5063d4da > --- /dev/null > +++ b/security/integrity/platform_certs/load_powerpc.c > @@ -0,0 +1,88 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2019 IBM Corporation > + * Author: Nayna Jain <nayna@xxxxxxxxxxxxx> > + * > + * - 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 <asm/secboot.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 db var: %d\n", 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; > + > + if (!secvar_ops) > + 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); There's no need to split this line. > + kfree(db); > + } > + > + dbx = get_cert_list("dbx", 3, &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); Formatting of this line is off. > + if (rc) > + pr_err("Couldn't parse dbx signatures: %d\n", rc); > + kfree(dbx); > + } > + > + return rc; > +} > +late_initcall(load_powerpc_certs);