Skip to content

Commit d2e5b64

Browse files
davejiangdjbw
authored andcommitted
libnvdimm/security, acpi/nfit: unify zero-key for all security commands
With zero-key defined, we can remove previous detection of key id 0 or null key in order to deal with a zero-key situation. Syncing all security commands to use the zero-key. Helper functions are introduced to return the data that points to the actual key payload or the zero_key. This helps uniformly handle the key material even with zero_key. Signed-off-by: Dave Jiang <[email protected]> Signed-off-by: Dan Williams <[email protected]>
1 parent 037c848 commit d2e5b64

File tree

2 files changed

+73
-54
lines changed

2 files changed

+73
-54
lines changed

drivers/acpi/nfit/intel.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,8 @@ static int intel_security_change_key(struct nvdimm *nvdimm,
122122
if (!test_bit(cmd, &nfit_mem->dsm_mask))
123123
return -ENOTTY;
124124

125-
if (old_data)
126-
memcpy(nd_cmd.cmd.old_pass, old_data->data,
127-
sizeof(nd_cmd.cmd.old_pass));
125+
memcpy(nd_cmd.cmd.old_pass, old_data->data,
126+
sizeof(nd_cmd.cmd.old_pass));
128127
memcpy(nd_cmd.cmd.new_pass, new_data->data,
129128
sizeof(nd_cmd.cmd.new_pass));
130129
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,
336335

337336
/* flush all cache before we erase DIMM */
338337
nvdimm_invalidate_cache();
339-
if (nkey)
340-
memcpy(nd_cmd.cmd.passphrase, nkey->data,
341-
sizeof(nd_cmd.cmd.passphrase));
338+
memcpy(nd_cmd.cmd.passphrase, nkey->data,
339+
sizeof(nd_cmd.cmd.passphrase));
342340
rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
343341
if (rc < 0)
344342
return rc;

drivers/nvdimm/security.c

Lines changed: 69 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ static struct key *nvdimm_request_key(struct nvdimm *nvdimm)
7777
return key;
7878
}
7979

80+
static 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+
8090
static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm,
8191
key_serial_t id, int subclass)
8292
{
@@ -107,36 +117,57 @@ static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm,
107117
return key;
108118
}
109119

110-
static struct key *nvdimm_key_revalidate(struct nvdimm *nvdimm)
120+
static 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+
139+
static int nvdimm_key_revalidate(struct nvdimm *nvdimm)
111140
{
112141
struct key *key;
113142
int rc;
143+
const void *data;
114144

115145
if (!nvdimm->sec.ops->change_key)
116-
return NULL;
146+
return -EOPNOTSUPP;
117147

118-
key = nvdimm_request_key(nvdimm);
119-
if (!key)
120-
return NULL;
148+
data = nvdimm_get_key_payload(nvdimm, &key);
121149

122150
/*
123151
* Send the same key to the hardware as new and old key to
124152
* verify that the key is good.
125153
*/
126-
rc = nvdimm->sec.ops->change_key(nvdimm, key_data(key),
127-
key_data(key), NVDIMM_USER);
154+
rc = nvdimm->sec.ops->change_key(nvdimm, data, data, NVDIMM_USER);
128155
if (rc < 0) {
129156
nvdimm_put_key(key);
130-
key = NULL;
157+
return rc;
131158
}
132-
return key;
159+
160+
nvdimm_put_key(key);
161+
nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
162+
return 0;
133163
}
134164

135165
static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
136166
{
137167
struct device *dev = &nvdimm->dev;
138168
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
139-
struct key *key = NULL;
169+
struct key *key;
170+
const void *data;
140171
int rc;
141172

142173
/* 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)
162193
if (!key_revalidate)
163194
return 0;
164195

165-
key = nvdimm_key_revalidate(nvdimm);
166-
if (!key)
167-
return nvdimm_security_freeze(nvdimm);
196+
return nvdimm_key_revalidate(nvdimm);
168197
} else
169-
key = nvdimm_request_key(nvdimm);
198+
data = nvdimm_get_key_payload(nvdimm, &key);
170199

171-
if (!key)
172-
return -ENOKEY;
173-
174-
rc = nvdimm->sec.ops->unlock(nvdimm, key_data(key));
200+
rc = nvdimm->sec.ops->unlock(nvdimm, data);
175201
dev_dbg(dev, "key: %d unlock: %s\n", key_serial(key),
176202
rc == 0 ? "success" : "fail");
177203

@@ -197,6 +223,7 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid)
197223
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
198224
struct key *key;
199225
int rc;
226+
const void *data;
200227

201228
/* The bus lock should be held at the top level of the call stack */
202229
lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
@@ -216,11 +243,12 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid)
216243
return -EBUSY;
217244
}
218245

219-
key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
220-
if (!key)
246+
data = nvdimm_get_user_key_payload(nvdimm, keyid,
247+
NVDIMM_BASE_KEY, &key);
248+
if (!data)
221249
return -ENOKEY;
222250

223-
rc = nvdimm->sec.ops->disable(nvdimm, key_data(key));
251+
rc = nvdimm->sec.ops->disable(nvdimm, data);
224252
dev_dbg(dev, "key: %d disable: %s\n", key_serial(key),
225253
rc == 0 ? "success" : "fail");
226254

@@ -237,6 +265,7 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
237265
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
238266
struct key *key, *newkey;
239267
int rc;
268+
const void *data, *newdata;
240269

241270
/* The bus lock should be held at the top level of the call stack */
242271
lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
@@ -251,22 +280,19 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
251280
return -EIO;
252281
}
253282

254-
if (keyid == 0)
255-
key = NULL;
256-
else {
257-
key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
258-
if (!key)
259-
return -ENOKEY;
260-
}
283+
data = nvdimm_get_user_key_payload(nvdimm, keyid,
284+
NVDIMM_BASE_KEY, &key);
285+
if (!data)
286+
return -ENOKEY;
261287

262-
newkey = nvdimm_lookup_user_key(nvdimm, new_keyid, NVDIMM_NEW_KEY);
263-
if (!newkey) {
288+
newdata = nvdimm_get_user_key_payload(nvdimm, new_keyid,
289+
NVDIMM_NEW_KEY, &newkey);
290+
if (!newdata) {
264291
nvdimm_put_key(key);
265292
return -ENOKEY;
266293
}
267294

268-
rc = nvdimm->sec.ops->change_key(nvdimm, key ? key_data(key) : NULL,
269-
key_data(newkey), pass_type);
295+
rc = nvdimm->sec.ops->change_key(nvdimm, data, newdata, pass_type);
270296
dev_dbg(dev, "key: %d %d update%s: %s\n",
271297
key_serial(key), key_serial(newkey),
272298
pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
@@ -322,13 +348,10 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
322348
return -EOPNOTSUPP;
323349
}
324350

325-
if (keyid != 0) {
326-
key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
327-
if (!key)
328-
return -ENOKEY;
329-
data = key_data(key);
330-
} else
331-
data = zero_key;
351+
data = nvdimm_get_user_key_payload(nvdimm, keyid,
352+
NVDIMM_BASE_KEY, &key);
353+
if (!data)
354+
return -ENOKEY;
332355

333356
rc = nvdimm->sec.ops->erase(nvdimm, data, pass_type);
334357
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)
344367
{
345368
struct device *dev = &nvdimm->dev;
346369
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
347-
struct key *key;
370+
struct key *key = NULL;
348371
int rc;
372+
const void *data;
349373

350374
/* The bus lock should be held at the top level of the call stack */
351375
lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
@@ -375,15 +399,12 @@ int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid)
375399
return -EBUSY;
376400
}
377401

378-
if (keyid == 0)
379-
key = NULL;
380-
else {
381-
key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
382-
if (!key)
383-
return -ENOKEY;
384-
}
402+
data = nvdimm_get_user_key_payload(nvdimm, keyid,
403+
NVDIMM_BASE_KEY, &key);
404+
if (!data)
405+
return -ENOKEY;
385406

386-
rc = nvdimm->sec.ops->overwrite(nvdimm, key ? key_data(key) : NULL);
407+
rc = nvdimm->sec.ops->overwrite(nvdimm, data);
387408
dev_dbg(dev, "key: %d overwrite submission: %s\n", key_serial(key),
388409
rc == 0 ? "success" : "fail");
389410

0 commit comments

Comments
 (0)