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> 6 #include <asm/smp.h> 7 #include "intel.h" 8 #include "nfit.h" 9 10 static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm, 11 enum nvdimm_passphrase_type ptype) 12 { 13 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 14 struct { 15 struct nd_cmd_pkg pkg; 16 struct nd_intel_get_security_state cmd; 17 } nd_cmd = { 18 .pkg = { 19 .nd_command = NVDIMM_INTEL_GET_SECURITY_STATE, 20 .nd_family = NVDIMM_FAMILY_INTEL, 21 .nd_size_out = 22 sizeof(struct nd_intel_get_security_state), 23 .nd_fw_size = 24 sizeof(struct nd_intel_get_security_state), 25 }, 26 }; 27 int rc; 28 29 if (!test_bit(NVDIMM_INTEL_GET_SECURITY_STATE, &nfit_mem->dsm_mask)) 30 return -ENXIO; 31 32 /* 33 * Short circuit the state retrieval while we are doing overwrite. 34 * The DSM spec states that the security state is indeterminate 35 * until the overwrite DSM completes. 36 */ 37 if (nvdimm_in_overwrite(nvdimm) && ptype == NVDIMM_USER) 38 return NVDIMM_SECURITY_OVERWRITE; 39 40 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 41 if (rc < 0) 42 return rc; 43 if (nd_cmd.cmd.status) 44 return -EIO; 45 46 /* check and see if security is enabled and locked */ 47 if (ptype == NVDIMM_MASTER) { 48 if (nd_cmd.cmd.extended_state & ND_INTEL_SEC_ESTATE_ENABLED) 49 return NVDIMM_SECURITY_UNLOCKED; 50 else if (nd_cmd.cmd.extended_state & 51 ND_INTEL_SEC_ESTATE_PLIMIT) 52 return NVDIMM_SECURITY_FROZEN; 53 } else { 54 if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_UNSUPPORTED) 55 return -ENXIO; 56 else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_ENABLED) { 57 if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_LOCKED) 58 return NVDIMM_SECURITY_LOCKED; 59 else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_FROZEN 60 || nd_cmd.cmd.state & 61 ND_INTEL_SEC_STATE_PLIMIT) 62 return NVDIMM_SECURITY_FROZEN; 63 else 64 return NVDIMM_SECURITY_UNLOCKED; 65 } 66 } 67 68 /* this should cover master security disabled as well */ 69 return NVDIMM_SECURITY_DISABLED; 70 } 71 72 static int intel_security_freeze(struct nvdimm *nvdimm) 73 { 74 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 75 struct { 76 struct nd_cmd_pkg pkg; 77 struct nd_intel_freeze_lock cmd; 78 } nd_cmd = { 79 .pkg = { 80 .nd_command = NVDIMM_INTEL_FREEZE_LOCK, 81 .nd_family = NVDIMM_FAMILY_INTEL, 82 .nd_size_out = ND_INTEL_STATUS_SIZE, 83 .nd_fw_size = ND_INTEL_STATUS_SIZE, 84 }, 85 }; 86 int rc; 87 88 if (!test_bit(NVDIMM_INTEL_FREEZE_LOCK, &nfit_mem->dsm_mask)) 89 return -ENOTTY; 90 91 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 92 if (rc < 0) 93 return rc; 94 if (nd_cmd.cmd.status) 95 return -EIO; 96 return 0; 97 } 98 99 static int intel_security_change_key(struct nvdimm *nvdimm, 100 const struct nvdimm_key_data *old_data, 101 const struct nvdimm_key_data *new_data, 102 enum nvdimm_passphrase_type ptype) 103 { 104 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 105 unsigned int cmd = ptype == NVDIMM_MASTER ? 106 NVDIMM_INTEL_SET_MASTER_PASSPHRASE : 107 NVDIMM_INTEL_SET_PASSPHRASE; 108 struct { 109 struct nd_cmd_pkg pkg; 110 struct nd_intel_set_passphrase cmd; 111 } nd_cmd = { 112 .pkg = { 113 .nd_family = NVDIMM_FAMILY_INTEL, 114 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE * 2, 115 .nd_size_out = ND_INTEL_STATUS_SIZE, 116 .nd_fw_size = ND_INTEL_STATUS_SIZE, 117 .nd_command = cmd, 118 }, 119 }; 120 int rc; 121 122 if (!test_bit(cmd, &nfit_mem->dsm_mask)) 123 return -ENOTTY; 124 125 if (old_data) 126 memcpy(nd_cmd.cmd.old_pass, old_data->data, 127 sizeof(nd_cmd.cmd.old_pass)); 128 memcpy(nd_cmd.cmd.new_pass, new_data->data, 129 sizeof(nd_cmd.cmd.new_pass)); 130 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 131 if (rc < 0) 132 return rc; 133 134 switch (nd_cmd.cmd.status) { 135 case 0: 136 return 0; 137 case ND_INTEL_STATUS_INVALID_PASS: 138 return -EINVAL; 139 case ND_INTEL_STATUS_NOT_SUPPORTED: 140 return -EOPNOTSUPP; 141 case ND_INTEL_STATUS_INVALID_STATE: 142 default: 143 return -EIO; 144 } 145 } 146 147 static void nvdimm_invalidate_cache(void); 148 149 static int intel_security_unlock(struct nvdimm *nvdimm, 150 const struct nvdimm_key_data *key_data) 151 { 152 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 153 struct { 154 struct nd_cmd_pkg pkg; 155 struct nd_intel_unlock_unit cmd; 156 } nd_cmd = { 157 .pkg = { 158 .nd_command = NVDIMM_INTEL_UNLOCK_UNIT, 159 .nd_family = NVDIMM_FAMILY_INTEL, 160 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE, 161 .nd_size_out = ND_INTEL_STATUS_SIZE, 162 .nd_fw_size = ND_INTEL_STATUS_SIZE, 163 }, 164 }; 165 int rc; 166 167 if (!test_bit(NVDIMM_INTEL_UNLOCK_UNIT, &nfit_mem->dsm_mask)) 168 return -ENOTTY; 169 170 memcpy(nd_cmd.cmd.passphrase, key_data->data, 171 sizeof(nd_cmd.cmd.passphrase)); 172 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 173 if (rc < 0) 174 return rc; 175 switch (nd_cmd.cmd.status) { 176 case 0: 177 break; 178 case ND_INTEL_STATUS_INVALID_PASS: 179 return -EINVAL; 180 default: 181 return -EIO; 182 } 183 184 /* DIMM unlocked, invalidate all CPU caches before we read it */ 185 nvdimm_invalidate_cache(); 186 187 return 0; 188 } 189 190 static int intel_security_disable(struct nvdimm *nvdimm, 191 const struct nvdimm_key_data *key_data) 192 { 193 int rc; 194 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 195 struct { 196 struct nd_cmd_pkg pkg; 197 struct nd_intel_disable_passphrase cmd; 198 } nd_cmd = { 199 .pkg = { 200 .nd_command = NVDIMM_INTEL_DISABLE_PASSPHRASE, 201 .nd_family = NVDIMM_FAMILY_INTEL, 202 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE, 203 .nd_size_out = ND_INTEL_STATUS_SIZE, 204 .nd_fw_size = ND_INTEL_STATUS_SIZE, 205 }, 206 }; 207 208 if (!test_bit(NVDIMM_INTEL_DISABLE_PASSPHRASE, &nfit_mem->dsm_mask)) 209 return -ENOTTY; 210 211 memcpy(nd_cmd.cmd.passphrase, key_data->data, 212 sizeof(nd_cmd.cmd.passphrase)); 213 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 214 if (rc < 0) 215 return rc; 216 217 switch (nd_cmd.cmd.status) { 218 case 0: 219 break; 220 case ND_INTEL_STATUS_INVALID_PASS: 221 return -EINVAL; 222 case ND_INTEL_STATUS_INVALID_STATE: 223 default: 224 return -ENXIO; 225 } 226 227 return 0; 228 } 229 230 static int intel_security_erase(struct nvdimm *nvdimm, 231 const struct nvdimm_key_data *key, 232 enum nvdimm_passphrase_type ptype) 233 { 234 int rc; 235 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 236 unsigned int cmd = ptype == NVDIMM_MASTER ? 237 NVDIMM_INTEL_MASTER_SECURE_ERASE : NVDIMM_INTEL_SECURE_ERASE; 238 struct { 239 struct nd_cmd_pkg pkg; 240 struct nd_intel_secure_erase cmd; 241 } nd_cmd = { 242 .pkg = { 243 .nd_family = NVDIMM_FAMILY_INTEL, 244 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE, 245 .nd_size_out = ND_INTEL_STATUS_SIZE, 246 .nd_fw_size = ND_INTEL_STATUS_SIZE, 247 .nd_command = cmd, 248 }, 249 }; 250 251 if (!test_bit(cmd, &nfit_mem->dsm_mask)) 252 return -ENOTTY; 253 254 /* flush all cache before we erase DIMM */ 255 nvdimm_invalidate_cache(); 256 memcpy(nd_cmd.cmd.passphrase, key->data, 257 sizeof(nd_cmd.cmd.passphrase)); 258 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 259 if (rc < 0) 260 return rc; 261 262 switch (nd_cmd.cmd.status) { 263 case 0: 264 break; 265 case ND_INTEL_STATUS_NOT_SUPPORTED: 266 return -EOPNOTSUPP; 267 case ND_INTEL_STATUS_INVALID_PASS: 268 return -EINVAL; 269 case ND_INTEL_STATUS_INVALID_STATE: 270 default: 271 return -ENXIO; 272 } 273 274 /* DIMM erased, invalidate all CPU caches before we read it */ 275 nvdimm_invalidate_cache(); 276 return 0; 277 } 278 279 static int intel_security_query_overwrite(struct nvdimm *nvdimm) 280 { 281 int rc; 282 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 283 struct { 284 struct nd_cmd_pkg pkg; 285 struct nd_intel_query_overwrite cmd; 286 } nd_cmd = { 287 .pkg = { 288 .nd_command = NVDIMM_INTEL_QUERY_OVERWRITE, 289 .nd_family = NVDIMM_FAMILY_INTEL, 290 .nd_size_out = ND_INTEL_STATUS_SIZE, 291 .nd_fw_size = ND_INTEL_STATUS_SIZE, 292 }, 293 }; 294 295 if (!test_bit(NVDIMM_INTEL_QUERY_OVERWRITE, &nfit_mem->dsm_mask)) 296 return -ENOTTY; 297 298 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 299 if (rc < 0) 300 return rc; 301 302 switch (nd_cmd.cmd.status) { 303 case 0: 304 break; 305 case ND_INTEL_STATUS_OQUERY_INPROGRESS: 306 return -EBUSY; 307 default: 308 return -ENXIO; 309 } 310 311 /* flush all cache before we make the nvdimms available */ 312 nvdimm_invalidate_cache(); 313 return 0; 314 } 315 316 static int intel_security_overwrite(struct nvdimm *nvdimm, 317 const struct nvdimm_key_data *nkey) 318 { 319 int rc; 320 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 321 struct { 322 struct nd_cmd_pkg pkg; 323 struct nd_intel_overwrite cmd; 324 } nd_cmd = { 325 .pkg = { 326 .nd_command = NVDIMM_INTEL_OVERWRITE, 327 .nd_family = NVDIMM_FAMILY_INTEL, 328 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE, 329 .nd_size_out = ND_INTEL_STATUS_SIZE, 330 .nd_fw_size = ND_INTEL_STATUS_SIZE, 331 }, 332 }; 333 334 if (!test_bit(NVDIMM_INTEL_OVERWRITE, &nfit_mem->dsm_mask)) 335 return -ENOTTY; 336 337 /* flush all cache before we erase DIMM */ 338 nvdimm_invalidate_cache(); 339 if (nkey) 340 memcpy(nd_cmd.cmd.passphrase, nkey->data, 341 sizeof(nd_cmd.cmd.passphrase)); 342 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 343 if (rc < 0) 344 return rc; 345 346 switch (nd_cmd.cmd.status) { 347 case 0: 348 return 0; 349 case ND_INTEL_STATUS_OVERWRITE_UNSUPPORTED: 350 return -ENOTSUPP; 351 case ND_INTEL_STATUS_INVALID_PASS: 352 return -EINVAL; 353 case ND_INTEL_STATUS_INVALID_STATE: 354 default: 355 return -ENXIO; 356 } 357 } 358 359 /* 360 * TODO: define a cross arch wbinvd equivalent when/if 361 * NVDIMM_FAMILY_INTEL command support arrives on another arch. 362 */ 363 #ifdef CONFIG_X86 364 static void nvdimm_invalidate_cache(void) 365 { 366 wbinvd_on_all_cpus(); 367 } 368 #else 369 static void nvdimm_invalidate_cache(void) 370 { 371 WARN_ON_ONCE("cache invalidation required after unlock\n"); 372 } 373 #endif 374 375 static const struct nvdimm_security_ops __intel_security_ops = { 376 .state = intel_security_state, 377 .freeze = intel_security_freeze, 378 .change_key = intel_security_change_key, 379 .disable = intel_security_disable, 380 #ifdef CONFIG_X86 381 .unlock = intel_security_unlock, 382 .erase = intel_security_erase, 383 .overwrite = intel_security_overwrite, 384 .query_overwrite = intel_security_query_overwrite, 385 #endif 386 }; 387 388 const struct nvdimm_security_ops *intel_security_ops = &__intel_security_ops; 389