Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2019 IBM Corporation
0004  * Author: Nayna Jain
0005  *
0006  *      - loads keys and hashes stored and controlled by the firmware.
0007  */
0008 #include <linux/kernel.h>
0009 #include <linux/sched.h>
0010 #include <linux/cred.h>
0011 #include <linux/err.h>
0012 #include <linux/slab.h>
0013 #include <linux/of.h>
0014 #include <asm/secure_boot.h>
0015 #include <asm/secvar.h>
0016 #include "keyring_handler.h"
0017 
0018 /*
0019  * Get a certificate list blob from the named secure variable.
0020  */
0021 static __init void *get_cert_list(u8 *key, unsigned long keylen, uint64_t *size)
0022 {
0023     int rc;
0024     void *db;
0025 
0026     rc = secvar_ops->get(key, keylen, NULL, size);
0027     if (rc) {
0028         pr_err("Couldn't get size: %d\n", rc);
0029         return NULL;
0030     }
0031 
0032     db = kmalloc(*size, GFP_KERNEL);
0033     if (!db)
0034         return NULL;
0035 
0036     rc = secvar_ops->get(key, keylen, db, size);
0037     if (rc) {
0038         kfree(db);
0039         pr_err("Error reading %s var: %d\n", key, rc);
0040         return NULL;
0041     }
0042 
0043     return db;
0044 }
0045 
0046 /*
0047  * Load the certs contained in the keys databases into the platform trusted
0048  * keyring and the blacklisted X.509 cert SHA256 hashes into the blacklist
0049  * keyring.
0050  */
0051 static int __init load_powerpc_certs(void)
0052 {
0053     void *db = NULL, *dbx = NULL;
0054     uint64_t dbsize = 0, dbxsize = 0;
0055     int rc = 0;
0056     struct device_node *node;
0057 
0058     if (!secvar_ops)
0059         return -ENODEV;
0060 
0061     /* The following only applies for the edk2-compat backend. */
0062     node = of_find_compatible_node(NULL, NULL, "ibm,edk2-compat-v1");
0063     if (!node)
0064         return -ENODEV;
0065 
0066     /*
0067      * Get db, and dbx. They might not exist, so it isn't an error if we
0068      * can't get them.
0069      */
0070     db = get_cert_list("db", 3, &dbsize);
0071     if (!db) {
0072         pr_err("Couldn't get db list from firmware\n");
0073     } else {
0074         rc = parse_efi_signature_list("powerpc:db", db, dbsize,
0075                           get_handler_for_db);
0076         if (rc)
0077             pr_err("Couldn't parse db signatures: %d\n", rc);
0078         kfree(db);
0079     }
0080 
0081     dbx = get_cert_list("dbx", 4,  &dbxsize);
0082     if (!dbx) {
0083         pr_info("Couldn't get dbx list from firmware\n");
0084     } else {
0085         rc = parse_efi_signature_list("powerpc:dbx", dbx, dbxsize,
0086                           get_handler_for_dbx);
0087         if (rc)
0088             pr_err("Couldn't parse dbx signatures: %d\n", rc);
0089         kfree(dbx);
0090     }
0091 
0092     of_node_put(node);
0093 
0094     return rc;
0095 }
0096 late_initcall(load_powerpc_certs);