blob: df7f070e96fb17a4d1756d74540ca7f1e8d7d963 [file] [log] [blame]
Dave Jiang4c6926a2018-12-06 12:40:01 -08001// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2018 Intel Corporation. All rights reserved. */
3
4#include <linux/module.h>
5#include <linux/device.h>
6#include <linux/ndctl.h>
7#include <linux/slab.h>
8#include <linux/io.h>
9#include <linux/mm.h>
10#include <linux/cred.h>
11#include <linux/key.h>
12#include <linux/key-type.h>
13#include <keys/user-type.h>
14#include <keys/encrypted-type.h>
15#include "nd-core.h"
16#include "nd.h"
17
Dave Jiangd2a4ac72018-12-07 13:29:09 -070018#define NVDIMM_BASE_KEY 0
19#define NVDIMM_NEW_KEY 1
20
Dave Jiang4c6926a2018-12-06 12:40:01 -080021static bool key_revalidate = true;
22module_param(key_revalidate, bool, 0444);
23MODULE_PARM_DESC(key_revalidate, "Require key validation at init.");
24
25static void *key_data(struct key *key)
26{
27 struct encrypted_key_payload *epayload = dereference_key_locked(key);
28
29 lockdep_assert_held_read(&key->sem);
30
31 return epayload->decrypted_data;
32}
33
34static void nvdimm_put_key(struct key *key)
35{
36 up_read(&key->sem);
37 key_put(key);
38}
39
40/*
41 * Retrieve kernel key for DIMM and request from user space if
42 * necessary. Returns a key held for read and must be put by
43 * nvdimm_put_key() before the usage goes out of scope.
44 */
45static struct key *nvdimm_request_key(struct nvdimm *nvdimm)
46{
47 struct key *key = NULL;
48 static const char NVDIMM_PREFIX[] = "nvdimm:";
49 char desc[NVDIMM_KEY_DESC_LEN + sizeof(NVDIMM_PREFIX)];
50 struct device *dev = &nvdimm->dev;
51
52 sprintf(desc, "%s%s", NVDIMM_PREFIX, nvdimm->dimm_id);
53 key = request_key(&key_type_encrypted, desc, "");
54 if (IS_ERR(key)) {
55 if (PTR_ERR(key) == -ENOKEY)
56 dev_warn(dev, "request_key() found no key\n");
57 else
58 dev_warn(dev, "request_key() upcall failed\n");
59 key = NULL;
60 } else {
61 struct encrypted_key_payload *epayload;
62
63 down_read(&key->sem);
64 epayload = dereference_key_locked(key);
65 if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) {
66 up_read(&key->sem);
67 key_put(key);
68 key = NULL;
69 }
70 }
71
72 return key;
73}
74
Dave Jiang03b65b22018-12-07 10:33:30 -070075static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm,
Dave Jiangd2a4ac72018-12-07 13:29:09 -070076 key_serial_t id, int subclass)
Dave Jiang03b65b22018-12-07 10:33:30 -070077{
78 key_ref_t keyref;
79 struct key *key;
80 struct encrypted_key_payload *epayload;
81 struct device *dev = &nvdimm->dev;
82
83 keyref = lookup_user_key(id, 0, 0);
84 if (IS_ERR(keyref))
85 return NULL;
86
87 key = key_ref_to_ptr(keyref);
88 if (key->type != &key_type_encrypted) {
89 key_put(key);
90 return NULL;
91 }
Dave Jiangd2a4ac72018-12-07 13:29:09 -070092
Dave Jiang03b65b22018-12-07 10:33:30 -070093 dev_dbg(dev, "%s: key found: %#x\n", __func__, key_serial(key));
94
Dave Jiangd2a4ac72018-12-07 13:29:09 -070095 down_read_nested(&key->sem, subclass);
Dave Jiang03b65b22018-12-07 10:33:30 -070096 epayload = dereference_key_locked(key);
97 if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) {
98 up_read(&key->sem);
99 key_put(key);
100 key = NULL;
101 }
102 return key;
103}
104
Dave Jiang4c6926a2018-12-06 12:40:01 -0800105static struct key *nvdimm_key_revalidate(struct nvdimm *nvdimm)
106{
107 struct key *key;
108 int rc;
109
110 if (!nvdimm->sec.ops->change_key)
111 return NULL;
112
113 key = nvdimm_request_key(nvdimm);
114 if (!key)
115 return NULL;
116
117 /*
118 * Send the same key to the hardware as new and old key to
119 * verify that the key is good.
120 */
121 rc = nvdimm->sec.ops->change_key(nvdimm, key_data(key), key_data(key));
122 if (rc < 0) {
123 nvdimm_put_key(key);
124 key = NULL;
125 }
126 return key;
127}
128
129static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
130{
131 struct device *dev = &nvdimm->dev;
132 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
133 struct key *key = NULL;
134 int rc;
135
136 /* The bus lock should be held at the top level of the call stack */
137 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
138
139 if (!nvdimm->sec.ops || !nvdimm->sec.ops->unlock
140 || nvdimm->sec.state < 0)
141 return -EIO;
142
143 /*
144 * If the pre-OS has unlocked the DIMM, attempt to send the key
145 * from request_key() to the hardware for verification. Failure
146 * to revalidate the key against the hardware results in a
147 * freeze of the security configuration. I.e. if the OS does not
148 * have the key, security is being managed pre-OS.
149 */
150 if (nvdimm->sec.state == NVDIMM_SECURITY_UNLOCKED) {
151 if (!key_revalidate)
152 return 0;
153
154 key = nvdimm_key_revalidate(nvdimm);
155 if (!key)
156 return nvdimm_security_freeze(nvdimm);
157 } else
158 key = nvdimm_request_key(nvdimm);
159
160 if (!key)
161 return -ENOKEY;
162
163 rc = nvdimm->sec.ops->unlock(nvdimm, key_data(key));
164 dev_dbg(dev, "key: %d unlock: %s\n", key_serial(key),
165 rc == 0 ? "success" : "fail");
166
167 nvdimm_put_key(key);
168 nvdimm->sec.state = nvdimm_security_state(nvdimm);
169 return rc;
170}
171
172int nvdimm_security_unlock(struct device *dev)
173{
174 struct nvdimm *nvdimm = to_nvdimm(dev);
175 int rc;
176
177 nvdimm_bus_lock(dev);
178 rc = __nvdimm_security_unlock(nvdimm);
179 nvdimm_bus_unlock(dev);
180 return rc;
181}
Dave Jiang03b65b22018-12-07 10:33:30 -0700182
183int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid)
184{
185 struct device *dev = &nvdimm->dev;
186 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
187 struct key *key;
188 int rc;
189
190 /* The bus lock should be held at the top level of the call stack */
191 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
192
193 if (!nvdimm->sec.ops || !nvdimm->sec.ops->disable
194 || nvdimm->sec.state < 0)
195 return -EOPNOTSUPP;
196
197 if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
198 dev_warn(dev, "Incorrect security state: %d\n",
199 nvdimm->sec.state);
200 return -EIO;
201 }
202
Dave Jiangd2a4ac72018-12-07 13:29:09 -0700203 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
Dave Jiang03b65b22018-12-07 10:33:30 -0700204 if (!key)
205 return -ENOKEY;
206
207 rc = nvdimm->sec.ops->disable(nvdimm, key_data(key));
208 dev_dbg(dev, "key: %d disable: %s\n", key_serial(key),
209 rc == 0 ? "success" : "fail");
210
211 nvdimm_put_key(key);
212 nvdimm->sec.state = nvdimm_security_state(nvdimm);
213 return rc;
214}
Dave Jiangd2a4ac72018-12-07 13:29:09 -0700215
216int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
217 unsigned int new_keyid)
218{
219 struct device *dev = &nvdimm->dev;
220 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
221 struct key *key, *newkey;
222 int rc;
223
224 /* The bus lock should be held at the top level of the call stack */
225 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
226
227 if (!nvdimm->sec.ops || !nvdimm->sec.ops->change_key
228 || nvdimm->sec.state < 0)
229 return -EOPNOTSUPP;
230
231 if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
232 dev_warn(dev, "Incorrect security state: %d\n",
233 nvdimm->sec.state);
234 return -EIO;
235 }
236
237 if (keyid == 0)
238 key = NULL;
239 else {
240 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
241 if (!key)
242 return -ENOKEY;
243 }
244
245 newkey = nvdimm_lookup_user_key(nvdimm, new_keyid, NVDIMM_NEW_KEY);
246 if (!newkey) {
247 nvdimm_put_key(key);
248 return -ENOKEY;
249 }
250
251 rc = nvdimm->sec.ops->change_key(nvdimm, key ? key_data(key) : NULL,
252 key_data(newkey));
253 dev_dbg(dev, "key: %d %d update: %s\n",
254 key_serial(key), key_serial(newkey),
255 rc == 0 ? "success" : "fail");
256
257 nvdimm_put_key(newkey);
258 nvdimm_put_key(key);
259 nvdimm->sec.state = nvdimm_security_state(nvdimm);
260 return rc;
261}