blob: 647a99dd31822dc6838b13f1759f521665486f24 [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
18static bool key_revalidate = true;
19module_param(key_revalidate, bool, 0444);
20MODULE_PARM_DESC(key_revalidate, "Require key validation at init.");
21
22static void *key_data(struct key *key)
23{
24 struct encrypted_key_payload *epayload = dereference_key_locked(key);
25
26 lockdep_assert_held_read(&key->sem);
27
28 return epayload->decrypted_data;
29}
30
31static void nvdimm_put_key(struct key *key)
32{
33 up_read(&key->sem);
34 key_put(key);
35}
36
37/*
38 * Retrieve kernel key for DIMM and request from user space if
39 * necessary. Returns a key held for read and must be put by
40 * nvdimm_put_key() before the usage goes out of scope.
41 */
42static struct key *nvdimm_request_key(struct nvdimm *nvdimm)
43{
44 struct key *key = NULL;
45 static const char NVDIMM_PREFIX[] = "nvdimm:";
46 char desc[NVDIMM_KEY_DESC_LEN + sizeof(NVDIMM_PREFIX)];
47 struct device *dev = &nvdimm->dev;
48
49 sprintf(desc, "%s%s", NVDIMM_PREFIX, nvdimm->dimm_id);
50 key = request_key(&key_type_encrypted, desc, "");
51 if (IS_ERR(key)) {
52 if (PTR_ERR(key) == -ENOKEY)
53 dev_warn(dev, "request_key() found no key\n");
54 else
55 dev_warn(dev, "request_key() upcall failed\n");
56 key = NULL;
57 } else {
58 struct encrypted_key_payload *epayload;
59
60 down_read(&key->sem);
61 epayload = dereference_key_locked(key);
62 if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) {
63 up_read(&key->sem);
64 key_put(key);
65 key = NULL;
66 }
67 }
68
69 return key;
70}
71
Dave Jiang03b65b22018-12-07 10:33:30 -070072static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm,
73 key_serial_t id)
74{
75 key_ref_t keyref;
76 struct key *key;
77 struct encrypted_key_payload *epayload;
78 struct device *dev = &nvdimm->dev;
79
80 keyref = lookup_user_key(id, 0, 0);
81 if (IS_ERR(keyref))
82 return NULL;
83
84 key = key_ref_to_ptr(keyref);
85 if (key->type != &key_type_encrypted) {
86 key_put(key);
87 return NULL;
88 }
89 dev_dbg(dev, "%s: key found: %#x\n", __func__, key_serial(key));
90
91
92 down_read(&key->sem);
93 epayload = dereference_key_locked(key);
94 if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) {
95 up_read(&key->sem);
96 key_put(key);
97 key = NULL;
98 }
99 return key;
100}
101
Dave Jiang4c6926a2018-12-06 12:40:01 -0800102static struct key *nvdimm_key_revalidate(struct nvdimm *nvdimm)
103{
104 struct key *key;
105 int rc;
106
107 if (!nvdimm->sec.ops->change_key)
108 return NULL;
109
110 key = nvdimm_request_key(nvdimm);
111 if (!key)
112 return NULL;
113
114 /*
115 * Send the same key to the hardware as new and old key to
116 * verify that the key is good.
117 */
118 rc = nvdimm->sec.ops->change_key(nvdimm, key_data(key), key_data(key));
119 if (rc < 0) {
120 nvdimm_put_key(key);
121 key = NULL;
122 }
123 return key;
124}
125
126static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
127{
128 struct device *dev = &nvdimm->dev;
129 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
130 struct key *key = NULL;
131 int rc;
132
133 /* The bus lock should be held at the top level of the call stack */
134 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
135
136 if (!nvdimm->sec.ops || !nvdimm->sec.ops->unlock
137 || nvdimm->sec.state < 0)
138 return -EIO;
139
140 /*
141 * If the pre-OS has unlocked the DIMM, attempt to send the key
142 * from request_key() to the hardware for verification. Failure
143 * to revalidate the key against the hardware results in a
144 * freeze of the security configuration. I.e. if the OS does not
145 * have the key, security is being managed pre-OS.
146 */
147 if (nvdimm->sec.state == NVDIMM_SECURITY_UNLOCKED) {
148 if (!key_revalidate)
149 return 0;
150
151 key = nvdimm_key_revalidate(nvdimm);
152 if (!key)
153 return nvdimm_security_freeze(nvdimm);
154 } else
155 key = nvdimm_request_key(nvdimm);
156
157 if (!key)
158 return -ENOKEY;
159
160 rc = nvdimm->sec.ops->unlock(nvdimm, key_data(key));
161 dev_dbg(dev, "key: %d unlock: %s\n", key_serial(key),
162 rc == 0 ? "success" : "fail");
163
164 nvdimm_put_key(key);
165 nvdimm->sec.state = nvdimm_security_state(nvdimm);
166 return rc;
167}
168
169int nvdimm_security_unlock(struct device *dev)
170{
171 struct nvdimm *nvdimm = to_nvdimm(dev);
172 int rc;
173
174 nvdimm_bus_lock(dev);
175 rc = __nvdimm_security_unlock(nvdimm);
176 nvdimm_bus_unlock(dev);
177 return rc;
178}
Dave Jiang03b65b22018-12-07 10:33:30 -0700179
180int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid)
181{
182 struct device *dev = &nvdimm->dev;
183 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
184 struct key *key;
185 int rc;
186
187 /* The bus lock should be held at the top level of the call stack */
188 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
189
190 if (!nvdimm->sec.ops || !nvdimm->sec.ops->disable
191 || nvdimm->sec.state < 0)
192 return -EOPNOTSUPP;
193
194 if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
195 dev_warn(dev, "Incorrect security state: %d\n",
196 nvdimm->sec.state);
197 return -EIO;
198 }
199
200 key = nvdimm_lookup_user_key(nvdimm, keyid);
201 if (!key)
202 return -ENOKEY;
203
204 rc = nvdimm->sec.ops->disable(nvdimm, key_data(key));
205 dev_dbg(dev, "key: %d disable: %s\n", key_serial(key),
206 rc == 0 ? "success" : "fail");
207
208 nvdimm_put_key(key);
209 nvdimm->sec.state = nvdimm_security_state(nvdimm);
210 return rc;
211}