blob: dcde22e644a13dfefb12d7ac7c8cfdc6be73e082 [file] [log] [blame]
Joel Stanleya1fccbf2020-06-23 17:25:56 +09301From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Nayna Jain <nayna@linux.ibm.com>
3Date: Sun, 10 Nov 2019 21:10:36 -0600
Joel Stanley2070d282021-07-15 17:27:03 +09304Subject: [PATCH 11/17] powerpc: Load firmware trusted keys/hashes into kernel
Joel Stanleya1fccbf2020-06-23 17:25:56 +09305 keyring
6
7The keys used to verify the Host OS kernel are managed by firmware as
8secure variables. This patch loads the verification keys into the
9.platform keyring and revocation hashes into .blacklist keyring. This
10enables verification and loading of the kernels signed by the boot
11time keys which are trusted by firmware.
12
13Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
14Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
15Signed-off-by: Eric Richter <erichte@linux.ibm.com>
16[mpe: Search by compatible in load_powerpc_certs(), not using format]
17Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
18Link: https://lore.kernel.org/r/1573441836-3632-5-git-send-email-nayna@linux.ibm.com
19(cherry picked from commit 8220e22d11a05049aab9693839ab82e5e177ccde)
20Signed-off-by: Joel Stanley <joel@jms.id.au>
21---
22 security/integrity/Kconfig | 9 ++
23 security/integrity/Makefile | 4 +-
24 .../integrity/platform_certs/load_powerpc.c | 96 +++++++++++++++++++
25 3 files changed, 108 insertions(+), 1 deletion(-)
26 create mode 100644 security/integrity/platform_certs/load_powerpc.c
27
28diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
29index 0bae6adb63a9..71f0177e8716 100644
30--- a/security/integrity/Kconfig
31+++ b/security/integrity/Kconfig
32@@ -72,6 +72,15 @@ config LOAD_IPL_KEYS
33 depends on S390
34 def_bool y
35
36+config LOAD_PPC_KEYS
37+ bool "Enable loading of platform and blacklisted keys for POWER"
38+ depends on INTEGRITY_PLATFORM_KEYRING
39+ depends on PPC_SECURE_BOOT
40+ default y
41+ help
42+ Enable loading of keys to the .platform keyring and blacklisted
43+ hashes to the .blacklist keyring for powerpc based platforms.
44+
45 config INTEGRITY_AUDIT
46 bool "Enables integrity auditing support "
47 depends on AUDIT
48diff --git a/security/integrity/Makefile b/security/integrity/Makefile
49index 351c9662994b..7ee39d66cf16 100644
50--- a/security/integrity/Makefile
51+++ b/security/integrity/Makefile
52@@ -14,6 +14,8 @@ integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \
53 platform_certs/load_uefi.o \
54 platform_certs/keyring_handler.o
55 integrity-$(CONFIG_LOAD_IPL_KEYS) += platform_certs/load_ipl_s390.o
56-
57+integrity-$(CONFIG_LOAD_PPC_KEYS) += platform_certs/efi_parser.o \
58+ platform_certs/load_powerpc.o \
59+ platform_certs/keyring_handler.o
60 obj-$(CONFIG_IMA) += ima/
61 obj-$(CONFIG_EVM) += evm/
62diff --git a/security/integrity/platform_certs/load_powerpc.c b/security/integrity/platform_certs/load_powerpc.c
63new file mode 100644
64index 000000000000..a2900cb85357
65--- /dev/null
66+++ b/security/integrity/platform_certs/load_powerpc.c
67@@ -0,0 +1,96 @@
68+// SPDX-License-Identifier: GPL-2.0
69+/*
70+ * Copyright (C) 2019 IBM Corporation
71+ * Author: Nayna Jain
72+ *
73+ * - loads keys and hashes stored and controlled by the firmware.
74+ */
75+#include <linux/kernel.h>
76+#include <linux/sched.h>
77+#include <linux/cred.h>
78+#include <linux/err.h>
79+#include <linux/slab.h>
80+#include <linux/of.h>
81+#include <asm/secure_boot.h>
82+#include <asm/secvar.h>
83+#include "keyring_handler.h"
84+
85+/*
86+ * Get a certificate list blob from the named secure variable.
87+ */
88+static __init void *get_cert_list(u8 *key, unsigned long keylen, uint64_t *size)
89+{
90+ int rc;
91+ void *db;
92+
93+ rc = secvar_ops->get(key, keylen, NULL, size);
94+ if (rc) {
95+ pr_err("Couldn't get size: %d\n", rc);
96+ return NULL;
97+ }
98+
99+ db = kmalloc(*size, GFP_KERNEL);
100+ if (!db)
101+ return NULL;
102+
103+ rc = secvar_ops->get(key, keylen, db, size);
104+ if (rc) {
105+ kfree(db);
106+ pr_err("Error reading %s var: %d\n", key, rc);
107+ return NULL;
108+ }
109+
110+ return db;
111+}
112+
113+/*
114+ * Load the certs contained in the keys databases into the platform trusted
115+ * keyring and the blacklisted X.509 cert SHA256 hashes into the blacklist
116+ * keyring.
117+ */
118+static int __init load_powerpc_certs(void)
119+{
120+ void *db = NULL, *dbx = NULL;
121+ uint64_t dbsize = 0, dbxsize = 0;
122+ int rc = 0;
123+ struct device_node *node;
124+
125+ if (!secvar_ops)
126+ return -ENODEV;
127+
128+ /* The following only applies for the edk2-compat backend. */
129+ node = of_find_compatible_node(NULL, NULL, "ibm,edk2-compat-v1");
130+ if (!node)
131+ return -ENODEV;
132+
133+ /*
134+ * Get db, and dbx. They might not exist, so it isn't an error if we
135+ * can't get them.
136+ */
137+ db = get_cert_list("db", 3, &dbsize);
138+ if (!db) {
139+ pr_err("Couldn't get db list from firmware\n");
140+ } else {
141+ rc = parse_efi_signature_list("powerpc:db", db, dbsize,
142+ get_handler_for_db);
143+ if (rc)
144+ pr_err("Couldn't parse db signatures: %d\n", rc);
145+ kfree(db);
146+ }
147+
148+ dbx = get_cert_list("dbx", 4, &dbxsize);
149+ if (!dbx) {
150+ pr_info("Couldn't get dbx list from firmware\n");
151+ } else {
152+ rc = parse_efi_signature_list("powerpc:dbx", dbx, dbxsize,
153+ get_handler_for_dbx);
154+ if (rc)
155+ pr_err("Couldn't parse dbx signatures: %d\n", rc);
156+ kfree(dbx);
157+ }
158+
159+ of_node_put(node);
160+
161+ return rc;
162+}
163+late_initcall(load_powerpc_certs);