1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2018 Intel Corporation. All rights reserved. */
3 #include <linux/libnvdimm.h>
4 #include <linux/ndctl.h>
5 #include <linux/acpi.h>
10 static unsigned long intel_security_flags(struct nvdimm *nvdimm,
11 enum nvdimm_passphrase_type ptype)
13 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
14 unsigned long security_flags = 0;
16 struct nd_cmd_pkg pkg;
17 struct nd_intel_get_security_state cmd;
20 .nd_command = NVDIMM_INTEL_GET_SECURITY_STATE,
21 .nd_family = NVDIMM_FAMILY_INTEL,
23 sizeof(struct nd_intel_get_security_state),
25 sizeof(struct nd_intel_get_security_state),
30 if (!test_bit(NVDIMM_INTEL_GET_SECURITY_STATE, &nfit_mem->dsm_mask))
34 * Short circuit the state retrieval while we are doing overwrite.
35 * The DSM spec states that the security state is indeterminate
36 * until the overwrite DSM completes.
38 if (nvdimm_in_overwrite(nvdimm) && ptype == NVDIMM_USER)
39 return BIT(NVDIMM_SECURITY_OVERWRITE);
41 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
42 if (rc < 0 || nd_cmd.cmd.status) {
43 pr_err("%s: security state retrieval failed (%d:%#x)\n",
44 nvdimm_name(nvdimm), rc, nd_cmd.cmd.status);
48 /* check and see if security is enabled and locked */
49 if (ptype == NVDIMM_MASTER) {
50 if (nd_cmd.cmd.extended_state & ND_INTEL_SEC_ESTATE_ENABLED)
51 set_bit(NVDIMM_SECURITY_UNLOCKED, &security_flags);
53 set_bit(NVDIMM_SECURITY_DISABLED, &security_flags);
54 if (nd_cmd.cmd.extended_state & ND_INTEL_SEC_ESTATE_PLIMIT)
55 set_bit(NVDIMM_SECURITY_FROZEN, &security_flags);
56 return security_flags;
59 if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_UNSUPPORTED)
62 if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_ENABLED) {
63 if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_FROZEN ||
64 nd_cmd.cmd.state & ND_INTEL_SEC_STATE_PLIMIT)
65 set_bit(NVDIMM_SECURITY_FROZEN, &security_flags);
67 if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_LOCKED)
68 set_bit(NVDIMM_SECURITY_LOCKED, &security_flags);
70 set_bit(NVDIMM_SECURITY_UNLOCKED, &security_flags);
72 set_bit(NVDIMM_SECURITY_DISABLED, &security_flags);
74 return security_flags;
77 static int intel_security_freeze(struct nvdimm *nvdimm)
79 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
81 struct nd_cmd_pkg pkg;
82 struct nd_intel_freeze_lock cmd;
85 .nd_command = NVDIMM_INTEL_FREEZE_LOCK,
86 .nd_family = NVDIMM_FAMILY_INTEL,
87 .nd_size_out = ND_INTEL_STATUS_SIZE,
88 .nd_fw_size = ND_INTEL_STATUS_SIZE,
93 if (!test_bit(NVDIMM_INTEL_FREEZE_LOCK, &nfit_mem->dsm_mask))
96 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
99 if (nd_cmd.cmd.status)
104 static int intel_security_change_key(struct nvdimm *nvdimm,
105 const struct nvdimm_key_data *old_data,
106 const struct nvdimm_key_data *new_data,
107 enum nvdimm_passphrase_type ptype)
109 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
110 unsigned int cmd = ptype == NVDIMM_MASTER ?
111 NVDIMM_INTEL_SET_MASTER_PASSPHRASE :
112 NVDIMM_INTEL_SET_PASSPHRASE;
114 struct nd_cmd_pkg pkg;
115 struct nd_intel_set_passphrase cmd;
118 .nd_family = NVDIMM_FAMILY_INTEL,
119 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE * 2,
120 .nd_size_out = ND_INTEL_STATUS_SIZE,
121 .nd_fw_size = ND_INTEL_STATUS_SIZE,
127 if (!test_bit(cmd, &nfit_mem->dsm_mask))
130 memcpy(nd_cmd.cmd.old_pass, old_data->data,
131 sizeof(nd_cmd.cmd.old_pass));
132 memcpy(nd_cmd.cmd.new_pass, new_data->data,
133 sizeof(nd_cmd.cmd.new_pass));
134 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
138 switch (nd_cmd.cmd.status) {
141 case ND_INTEL_STATUS_INVALID_PASS:
143 case ND_INTEL_STATUS_NOT_SUPPORTED:
145 case ND_INTEL_STATUS_INVALID_STATE:
151 static void nvdimm_invalidate_cache(void);
153 static int __maybe_unused intel_security_unlock(struct nvdimm *nvdimm,
154 const struct nvdimm_key_data *key_data)
156 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
158 struct nd_cmd_pkg pkg;
159 struct nd_intel_unlock_unit cmd;
162 .nd_command = NVDIMM_INTEL_UNLOCK_UNIT,
163 .nd_family = NVDIMM_FAMILY_INTEL,
164 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE,
165 .nd_size_out = ND_INTEL_STATUS_SIZE,
166 .nd_fw_size = ND_INTEL_STATUS_SIZE,
171 if (!test_bit(NVDIMM_INTEL_UNLOCK_UNIT, &nfit_mem->dsm_mask))
174 memcpy(nd_cmd.cmd.passphrase, key_data->data,
175 sizeof(nd_cmd.cmd.passphrase));
176 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
179 switch (nd_cmd.cmd.status) {
182 case ND_INTEL_STATUS_INVALID_PASS:
188 /* DIMM unlocked, invalidate all CPU caches before we read it */
189 nvdimm_invalidate_cache();
194 static int intel_security_disable(struct nvdimm *nvdimm,
195 const struct nvdimm_key_data *key_data)
198 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
200 struct nd_cmd_pkg pkg;
201 struct nd_intel_disable_passphrase cmd;
204 .nd_command = NVDIMM_INTEL_DISABLE_PASSPHRASE,
205 .nd_family = NVDIMM_FAMILY_INTEL,
206 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE,
207 .nd_size_out = ND_INTEL_STATUS_SIZE,
208 .nd_fw_size = ND_INTEL_STATUS_SIZE,
212 if (!test_bit(NVDIMM_INTEL_DISABLE_PASSPHRASE, &nfit_mem->dsm_mask))
215 memcpy(nd_cmd.cmd.passphrase, key_data->data,
216 sizeof(nd_cmd.cmd.passphrase));
217 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
221 switch (nd_cmd.cmd.status) {
224 case ND_INTEL_STATUS_INVALID_PASS:
226 case ND_INTEL_STATUS_INVALID_STATE:
234 static int __maybe_unused intel_security_erase(struct nvdimm *nvdimm,
235 const struct nvdimm_key_data *key,
236 enum nvdimm_passphrase_type ptype)
239 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
240 unsigned int cmd = ptype == NVDIMM_MASTER ?
241 NVDIMM_INTEL_MASTER_SECURE_ERASE : NVDIMM_INTEL_SECURE_ERASE;
243 struct nd_cmd_pkg pkg;
244 struct nd_intel_secure_erase cmd;
247 .nd_family = NVDIMM_FAMILY_INTEL,
248 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE,
249 .nd_size_out = ND_INTEL_STATUS_SIZE,
250 .nd_fw_size = ND_INTEL_STATUS_SIZE,
255 if (!test_bit(cmd, &nfit_mem->dsm_mask))
258 /* flush all cache before we erase DIMM */
259 nvdimm_invalidate_cache();
260 memcpy(nd_cmd.cmd.passphrase, key->data,
261 sizeof(nd_cmd.cmd.passphrase));
262 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
266 switch (nd_cmd.cmd.status) {
269 case ND_INTEL_STATUS_NOT_SUPPORTED:
271 case ND_INTEL_STATUS_INVALID_PASS:
273 case ND_INTEL_STATUS_INVALID_STATE:
278 /* DIMM erased, invalidate all CPU caches before we read it */
279 nvdimm_invalidate_cache();
283 static int __maybe_unused intel_security_query_overwrite(struct nvdimm *nvdimm)
286 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
288 struct nd_cmd_pkg pkg;
289 struct nd_intel_query_overwrite cmd;
292 .nd_command = NVDIMM_INTEL_QUERY_OVERWRITE,
293 .nd_family = NVDIMM_FAMILY_INTEL,
294 .nd_size_out = ND_INTEL_STATUS_SIZE,
295 .nd_fw_size = ND_INTEL_STATUS_SIZE,
299 if (!test_bit(NVDIMM_INTEL_QUERY_OVERWRITE, &nfit_mem->dsm_mask))
302 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
306 switch (nd_cmd.cmd.status) {
309 case ND_INTEL_STATUS_OQUERY_INPROGRESS:
315 /* flush all cache before we make the nvdimms available */
316 nvdimm_invalidate_cache();
320 static int __maybe_unused intel_security_overwrite(struct nvdimm *nvdimm,
321 const struct nvdimm_key_data *nkey)
324 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
326 struct nd_cmd_pkg pkg;
327 struct nd_intel_overwrite cmd;
330 .nd_command = NVDIMM_INTEL_OVERWRITE,
331 .nd_family = NVDIMM_FAMILY_INTEL,
332 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE,
333 .nd_size_out = ND_INTEL_STATUS_SIZE,
334 .nd_fw_size = ND_INTEL_STATUS_SIZE,
338 if (!test_bit(NVDIMM_INTEL_OVERWRITE, &nfit_mem->dsm_mask))
341 /* flush all cache before we erase DIMM */
342 nvdimm_invalidate_cache();
343 memcpy(nd_cmd.cmd.passphrase, nkey->data,
344 sizeof(nd_cmd.cmd.passphrase));
345 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
349 switch (nd_cmd.cmd.status) {
352 case ND_INTEL_STATUS_OVERWRITE_UNSUPPORTED:
354 case ND_INTEL_STATUS_INVALID_PASS:
356 case ND_INTEL_STATUS_INVALID_STATE:
363 * TODO: define a cross arch wbinvd equivalent when/if
364 * NVDIMM_FAMILY_INTEL command support arrives on another arch.
367 static void nvdimm_invalidate_cache(void)
369 wbinvd_on_all_cpus();
372 static void nvdimm_invalidate_cache(void)
374 WARN_ON_ONCE("cache invalidation required after unlock\n");
378 static const struct nvdimm_security_ops __intel_security_ops = {
379 .get_flags = intel_security_flags,
380 .freeze = intel_security_freeze,
381 .change_key = intel_security_change_key,
382 .disable = intel_security_disable,
384 .unlock = intel_security_unlock,
385 .erase = intel_security_erase,
386 .overwrite = intel_security_overwrite,
387 .query_overwrite = intel_security_query_overwrite,
391 const struct nvdimm_security_ops *intel_security_ops = &__intel_security_ops;