aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/nfit/intel.c10
-rw-r--r--drivers/nvdimm/security.c117
2 files changed, 73 insertions, 54 deletions
diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c
index f70de71f79d6..cddd0fcf622c 100644
--- a/drivers/acpi/nfit/intel.c
+++ b/drivers/acpi/nfit/intel.c
@@ -122,9 +122,8 @@ static int intel_security_change_key(struct nvdimm *nvdimm,
122 if (!test_bit(cmd, &nfit_mem->dsm_mask)) 122 if (!test_bit(cmd, &nfit_mem->dsm_mask))
123 return -ENOTTY; 123 return -ENOTTY;
124 124
125 if (old_data) 125 memcpy(nd_cmd.cmd.old_pass, old_data->data,
126 memcpy(nd_cmd.cmd.old_pass, old_data->data, 126 sizeof(nd_cmd.cmd.old_pass));
127 sizeof(nd_cmd.cmd.old_pass));
128 memcpy(nd_cmd.cmd.new_pass, new_data->data, 127 memcpy(nd_cmd.cmd.new_pass, new_data->data,
129 sizeof(nd_cmd.cmd.new_pass)); 128 sizeof(nd_cmd.cmd.new_pass));
130 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 129 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
@@ -336,9 +335,8 @@ static int __maybe_unused intel_security_overwrite(struct nvdimm *nvdimm,
336 335
337 /* flush all cache before we erase DIMM */ 336 /* flush all cache before we erase DIMM */
338 nvdimm_invalidate_cache(); 337 nvdimm_invalidate_cache();
339 if (nkey) 338 memcpy(nd_cmd.cmd.passphrase, nkey->data,
340 memcpy(nd_cmd.cmd.passphrase, nkey->data, 339 sizeof(nd_cmd.cmd.passphrase));
341 sizeof(nd_cmd.cmd.passphrase));
342 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 340 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
343 if (rc < 0) 341 if (rc < 0)
344 return rc; 342 return rc;
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index 6bea6852bf27..a570f2263a42 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -77,6 +77,16 @@ static struct key *nvdimm_request_key(struct nvdimm *nvdimm)
77 return key; 77 return key;
78} 78}
79 79
80static const void *nvdimm_get_key_payload(struct nvdimm *nvdimm,
81 struct key **key)
82{
83 *key = nvdimm_request_key(nvdimm);
84 if (!*key)
85 return zero_key;
86
87 return key_data(*key);
88}
89
80static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm, 90static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm,
81 key_serial_t id, int subclass) 91 key_serial_t id, int subclass)
82{ 92{
@@ -107,36 +117,57 @@ static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm,
107 return key; 117 return key;
108} 118}
109 119
110static struct key *nvdimm_key_revalidate(struct nvdimm *nvdimm) 120static const void *nvdimm_get_user_key_payload(struct nvdimm *nvdimm,
121 key_serial_t id, int subclass, struct key **key)
122{
123 *key = NULL;
124 if (id == 0) {
125 if (subclass == NVDIMM_BASE_KEY)
126 return zero_key;
127 else
128 return NULL;
129 }
130
131 *key = nvdimm_lookup_user_key(nvdimm, id, subclass);
132 if (!*key)
133 return NULL;
134
135 return key_data(*key);
136}
137
138
139static int nvdimm_key_revalidate(struct nvdimm *nvdimm)
111{ 140{
112 struct key *key; 141 struct key *key;
113 int rc; 142 int rc;
143 const void *data;
114 144
115 if (!nvdimm->sec.ops->change_key) 145 if (!nvdimm->sec.ops->change_key)
116 return NULL; 146 return -EOPNOTSUPP;
117 147
118 key = nvdimm_request_key(nvdimm); 148 data = nvdimm_get_key_payload(nvdimm, &key);
119 if (!key)
120 return NULL;
121 149
122 /* 150 /*
123 * Send the same key to the hardware as new and old key to 151 * Send the same key to the hardware as new and old key to
124 * verify that the key is good. 152 * verify that the key is good.
125 */ 153 */
126 rc = nvdimm->sec.ops->change_key(nvdimm, key_data(key), 154 rc = nvdimm->sec.ops->change_key(nvdimm, data, data, NVDIMM_USER);
127 key_data(key), NVDIMM_USER);
128 if (rc < 0) { 155 if (rc < 0) {
129 nvdimm_put_key(key); 156 nvdimm_put_key(key);
130 key = NULL; 157 return rc;
131 } 158 }
132 return key; 159
160 nvdimm_put_key(key);
161 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
162 return 0;
133} 163}
134 164
135static int __nvdimm_security_unlock(struct nvdimm *nvdimm) 165static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
136{ 166{
137 struct device *dev = &nvdimm->dev; 167 struct device *dev = &nvdimm->dev;
138 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 168 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
139 struct key *key = NULL; 169 struct key *key;
170 const void *data;
140 int rc; 171 int rc;
141 172
142 /* The bus lock should be held at the top level of the call stack */ 173 /* The bus lock should be held at the top level of the call stack */
@@ -162,16 +193,11 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
162 if (!key_revalidate) 193 if (!key_revalidate)
163 return 0; 194 return 0;
164 195
165 key = nvdimm_key_revalidate(nvdimm); 196 return nvdimm_key_revalidate(nvdimm);
166 if (!key)
167 return nvdimm_security_freeze(nvdimm);
168 } else 197 } else
169 key = nvdimm_request_key(nvdimm); 198 data = nvdimm_get_key_payload(nvdimm, &key);
170 199
171 if (!key) 200 rc = nvdimm->sec.ops->unlock(nvdimm, data);
172 return -ENOKEY;
173
174 rc = nvdimm->sec.ops->unlock(nvdimm, key_data(key));
175 dev_dbg(dev, "key: %d unlock: %s\n", key_serial(key), 201 dev_dbg(dev, "key: %d unlock: %s\n", key_serial(key),
176 rc == 0 ? "success" : "fail"); 202 rc == 0 ? "success" : "fail");
177 203
@@ -197,6 +223,7 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid)
197 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 223 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
198 struct key *key; 224 struct key *key;
199 int rc; 225 int rc;
226 const void *data;
200 227
201 /* The bus lock should be held at the top level of the call stack */ 228 /* The bus lock should be held at the top level of the call stack */
202 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); 229 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
@@ -216,11 +243,12 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid)
216 return -EBUSY; 243 return -EBUSY;
217 } 244 }
218 245
219 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); 246 data = nvdimm_get_user_key_payload(nvdimm, keyid,
220 if (!key) 247 NVDIMM_BASE_KEY, &key);
248 if (!data)
221 return -ENOKEY; 249 return -ENOKEY;
222 250
223 rc = nvdimm->sec.ops->disable(nvdimm, key_data(key)); 251 rc = nvdimm->sec.ops->disable(nvdimm, data);
224 dev_dbg(dev, "key: %d disable: %s\n", key_serial(key), 252 dev_dbg(dev, "key: %d disable: %s\n", key_serial(key),
225 rc == 0 ? "success" : "fail"); 253 rc == 0 ? "success" : "fail");
226 254
@@ -237,6 +265,7 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
237 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 265 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
238 struct key *key, *newkey; 266 struct key *key, *newkey;
239 int rc; 267 int rc;
268 const void *data, *newdata;
240 269
241 /* The bus lock should be held at the top level of the call stack */ 270 /* The bus lock should be held at the top level of the call stack */
242 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); 271 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
@@ -251,22 +280,19 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
251 return -EIO; 280 return -EIO;
252 } 281 }
253 282
254 if (keyid == 0) 283 data = nvdimm_get_user_key_payload(nvdimm, keyid,
255 key = NULL; 284 NVDIMM_BASE_KEY, &key);
256 else { 285 if (!data)
257 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); 286 return -ENOKEY;
258 if (!key)
259 return -ENOKEY;
260 }
261 287
262 newkey = nvdimm_lookup_user_key(nvdimm, new_keyid, NVDIMM_NEW_KEY); 288 newdata = nvdimm_get_user_key_payload(nvdimm, new_keyid,
263 if (!newkey) { 289 NVDIMM_NEW_KEY, &newkey);
290 if (!newdata) {
264 nvdimm_put_key(key); 291 nvdimm_put_key(key);
265 return -ENOKEY; 292 return -ENOKEY;
266 } 293 }
267 294
268 rc = nvdimm->sec.ops->change_key(nvdimm, key ? key_data(key) : NULL, 295 rc = nvdimm->sec.ops->change_key(nvdimm, data, newdata, pass_type);
269 key_data(newkey), pass_type);
270 dev_dbg(dev, "key: %d %d update%s: %s\n", 296 dev_dbg(dev, "key: %d %d update%s: %s\n",
271 key_serial(key), key_serial(newkey), 297 key_serial(key), key_serial(newkey),
272 pass_type == NVDIMM_MASTER ? "(master)" : "(user)", 298 pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
@@ -322,13 +348,10 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
322 return -EOPNOTSUPP; 348 return -EOPNOTSUPP;
323 } 349 }
324 350
325 if (keyid != 0) { 351 data = nvdimm_get_user_key_payload(nvdimm, keyid,
326 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); 352 NVDIMM_BASE_KEY, &key);
327 if (!key) 353 if (!data)
328 return -ENOKEY; 354 return -ENOKEY;
329 data = key_data(key);
330 } else
331 data = zero_key;
332 355
333 rc = nvdimm->sec.ops->erase(nvdimm, data, pass_type); 356 rc = nvdimm->sec.ops->erase(nvdimm, data, pass_type);
334 dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key), 357 dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key),
@@ -344,8 +367,9 @@ int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid)
344{ 367{
345 struct device *dev = &nvdimm->dev; 368 struct device *dev = &nvdimm->dev;
346 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 369 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
347 struct key *key; 370 struct key *key = NULL;
348 int rc; 371 int rc;
372 const void *data;
349 373
350 /* The bus lock should be held at the top level of the call stack */ 374 /* The bus lock should be held at the top level of the call stack */
351 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); 375 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
@@ -375,15 +399,12 @@ int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid)
375 return -EBUSY; 399 return -EBUSY;
376 } 400 }
377 401
378 if (keyid == 0) 402 data = nvdimm_get_user_key_payload(nvdimm, keyid,
379 key = NULL; 403 NVDIMM_BASE_KEY, &key);
380 else { 404 if (!data)
381 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); 405 return -ENOKEY;
382 if (!key)
383 return -ENOKEY;
384 }
385 406
386 rc = nvdimm->sec.ops->overwrite(nvdimm, key ? key_data(key) : NULL); 407 rc = nvdimm->sec.ops->overwrite(nvdimm, data);
387 dev_dbg(dev, "key: %d overwrite submission: %s\n", key_serial(key), 408 dev_dbg(dev, "key: %d overwrite submission: %s\n", key_serial(key),
388 rc == 0 ? "success" : "fail"); 409 rc == 0 ? "success" : "fail");
389 410