security.c (cdd5b5a9761fd66d17586e4f4ba6588c70e640ea) | security.c (b5209da36b19b573cf25fe7e698e3a45b0f40a75) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* Copyright(c) 2022 Intel Corporation. All rights reserved. */ 3#include <linux/libnvdimm.h> 4#include <asm/unaligned.h> 5#include <linux/module.h> 6#include <linux/async.h> 7#include <linux/slab.h> 8#include <linux/memregion.h> 9#include "cxlmem.h" 10#include "cxl.h" 11 12static unsigned long cxl_pmem_get_security_flags(struct nvdimm *nvdimm, 13 enum nvdimm_passphrase_type ptype) 14{ 15 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 16 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; | 1// SPDX-License-Identifier: GPL-2.0-only 2/* Copyright(c) 2022 Intel Corporation. All rights reserved. */ 3#include <linux/libnvdimm.h> 4#include <asm/unaligned.h> 5#include <linux/module.h> 6#include <linux/async.h> 7#include <linux/slab.h> 8#include <linux/memregion.h> 9#include "cxlmem.h" 10#include "cxl.h" 11 12static unsigned long cxl_pmem_get_security_flags(struct nvdimm *nvdimm, 13 enum nvdimm_passphrase_type ptype) 14{ 15 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 16 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; |
17 struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox; |
|
17 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); 18 unsigned long security_flags = 0; 19 struct cxl_get_security_output { 20 __le32 flags; 21 } out; 22 struct cxl_mbox_cmd mbox_cmd; 23 u32 sec_out; 24 int rc; 25 26 mbox_cmd = (struct cxl_mbox_cmd) { 27 .opcode = CXL_MBOX_OP_GET_SECURITY_STATE, 28 .size_out = sizeof(out), 29 .payload_out = &out, 30 }; 31 | 18 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); 19 unsigned long security_flags = 0; 20 struct cxl_get_security_output { 21 __le32 flags; 22 } out; 23 struct cxl_mbox_cmd mbox_cmd; 24 u32 sec_out; 25 int rc; 26 27 mbox_cmd = (struct cxl_mbox_cmd) { 28 .opcode = CXL_MBOX_OP_GET_SECURITY_STATE, 29 .size_out = sizeof(out), 30 .payload_out = &out, 31 }; 32 |
32 rc = cxl_internal_send_cmd(mds, &mbox_cmd); | 33 rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd); |
33 if (rc < 0) 34 return 0; 35 36 sec_out = le32_to_cpu(out.flags); 37 /* cache security state */ 38 mds->security.state = sec_out; 39 40 if (ptype == NVDIMM_MASTER) { --- 24 unchanged lines hidden (view full) --- 65 66static int cxl_pmem_security_change_key(struct nvdimm *nvdimm, 67 const struct nvdimm_key_data *old_data, 68 const struct nvdimm_key_data *new_data, 69 enum nvdimm_passphrase_type ptype) 70{ 71 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 72 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; | 34 if (rc < 0) 35 return 0; 36 37 sec_out = le32_to_cpu(out.flags); 38 /* cache security state */ 39 mds->security.state = sec_out; 40 41 if (ptype == NVDIMM_MASTER) { --- 24 unchanged lines hidden (view full) --- 66 67static int cxl_pmem_security_change_key(struct nvdimm *nvdimm, 68 const struct nvdimm_key_data *old_data, 69 const struct nvdimm_key_data *new_data, 70 enum nvdimm_passphrase_type ptype) 71{ 72 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 73 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; |
73 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); | 74 struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox; |
74 struct cxl_mbox_cmd mbox_cmd; 75 struct cxl_set_pass set_pass; 76 77 set_pass = (struct cxl_set_pass) { 78 .type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER : 79 CXL_PMEM_SEC_PASS_USER, 80 }; 81 memcpy(set_pass.old_pass, old_data->data, NVDIMM_PASSPHRASE_LEN); 82 memcpy(set_pass.new_pass, new_data->data, NVDIMM_PASSPHRASE_LEN); 83 84 mbox_cmd = (struct cxl_mbox_cmd) { 85 .opcode = CXL_MBOX_OP_SET_PASSPHRASE, 86 .size_in = sizeof(set_pass), 87 .payload_in = &set_pass, 88 }; 89 | 75 struct cxl_mbox_cmd mbox_cmd; 76 struct cxl_set_pass set_pass; 77 78 set_pass = (struct cxl_set_pass) { 79 .type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER : 80 CXL_PMEM_SEC_PASS_USER, 81 }; 82 memcpy(set_pass.old_pass, old_data->data, NVDIMM_PASSPHRASE_LEN); 83 memcpy(set_pass.new_pass, new_data->data, NVDIMM_PASSPHRASE_LEN); 84 85 mbox_cmd = (struct cxl_mbox_cmd) { 86 .opcode = CXL_MBOX_OP_SET_PASSPHRASE, 87 .size_in = sizeof(set_pass), 88 .payload_in = &set_pass, 89 }; 90 |
90 return cxl_internal_send_cmd(mds, &mbox_cmd); | 91 return cxl_internal_send_cmd(cxl_mbox, &mbox_cmd); |
91} 92 93static int __cxl_pmem_security_disable(struct nvdimm *nvdimm, 94 const struct nvdimm_key_data *key_data, 95 enum nvdimm_passphrase_type ptype) 96{ 97 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 98 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; | 92} 93 94static int __cxl_pmem_security_disable(struct nvdimm *nvdimm, 95 const struct nvdimm_key_data *key_data, 96 enum nvdimm_passphrase_type ptype) 97{ 98 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 99 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; |
99 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); | 100 struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox; |
100 struct cxl_disable_pass dis_pass; 101 struct cxl_mbox_cmd mbox_cmd; 102 103 dis_pass = (struct cxl_disable_pass) { 104 .type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER : 105 CXL_PMEM_SEC_PASS_USER, 106 }; 107 memcpy(dis_pass.pass, key_data->data, NVDIMM_PASSPHRASE_LEN); 108 109 mbox_cmd = (struct cxl_mbox_cmd) { 110 .opcode = CXL_MBOX_OP_DISABLE_PASSPHRASE, 111 .size_in = sizeof(dis_pass), 112 .payload_in = &dis_pass, 113 }; 114 | 101 struct cxl_disable_pass dis_pass; 102 struct cxl_mbox_cmd mbox_cmd; 103 104 dis_pass = (struct cxl_disable_pass) { 105 .type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER : 106 CXL_PMEM_SEC_PASS_USER, 107 }; 108 memcpy(dis_pass.pass, key_data->data, NVDIMM_PASSPHRASE_LEN); 109 110 mbox_cmd = (struct cxl_mbox_cmd) { 111 .opcode = CXL_MBOX_OP_DISABLE_PASSPHRASE, 112 .size_in = sizeof(dis_pass), 113 .payload_in = &dis_pass, 114 }; 115 |
115 return cxl_internal_send_cmd(mds, &mbox_cmd); | 116 return cxl_internal_send_cmd(cxl_mbox, &mbox_cmd); |
116} 117 118static int cxl_pmem_security_disable(struct nvdimm *nvdimm, 119 const struct nvdimm_key_data *key_data) 120{ 121 return __cxl_pmem_security_disable(nvdimm, key_data, NVDIMM_USER); 122} 123 124static int cxl_pmem_security_disable_master(struct nvdimm *nvdimm, 125 const struct nvdimm_key_data *key_data) 126{ 127 return __cxl_pmem_security_disable(nvdimm, key_data, NVDIMM_MASTER); 128} 129 130static int cxl_pmem_security_freeze(struct nvdimm *nvdimm) 131{ 132 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 133 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; | 117} 118 119static int cxl_pmem_security_disable(struct nvdimm *nvdimm, 120 const struct nvdimm_key_data *key_data) 121{ 122 return __cxl_pmem_security_disable(nvdimm, key_data, NVDIMM_USER); 123} 124 125static int cxl_pmem_security_disable_master(struct nvdimm *nvdimm, 126 const struct nvdimm_key_data *key_data) 127{ 128 return __cxl_pmem_security_disable(nvdimm, key_data, NVDIMM_MASTER); 129} 130 131static int cxl_pmem_security_freeze(struct nvdimm *nvdimm) 132{ 133 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 134 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; |
134 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); | 135 struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox; |
135 struct cxl_mbox_cmd mbox_cmd = { 136 .opcode = CXL_MBOX_OP_FREEZE_SECURITY, 137 }; 138 | 136 struct cxl_mbox_cmd mbox_cmd = { 137 .opcode = CXL_MBOX_OP_FREEZE_SECURITY, 138 }; 139 |
139 return cxl_internal_send_cmd(mds, &mbox_cmd); | 140 return cxl_internal_send_cmd(cxl_mbox, &mbox_cmd); |
140} 141 142static int cxl_pmem_security_unlock(struct nvdimm *nvdimm, 143 const struct nvdimm_key_data *key_data) 144{ 145 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 146 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; | 141} 142 143static int cxl_pmem_security_unlock(struct nvdimm *nvdimm, 144 const struct nvdimm_key_data *key_data) 145{ 146 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 147 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; |
147 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); | 148 struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox; |
148 u8 pass[NVDIMM_PASSPHRASE_LEN]; 149 struct cxl_mbox_cmd mbox_cmd; 150 int rc; 151 152 memcpy(pass, key_data->data, NVDIMM_PASSPHRASE_LEN); 153 mbox_cmd = (struct cxl_mbox_cmd) { 154 .opcode = CXL_MBOX_OP_UNLOCK, 155 .size_in = NVDIMM_PASSPHRASE_LEN, 156 .payload_in = pass, 157 }; 158 | 149 u8 pass[NVDIMM_PASSPHRASE_LEN]; 150 struct cxl_mbox_cmd mbox_cmd; 151 int rc; 152 153 memcpy(pass, key_data->data, NVDIMM_PASSPHRASE_LEN); 154 mbox_cmd = (struct cxl_mbox_cmd) { 155 .opcode = CXL_MBOX_OP_UNLOCK, 156 .size_in = NVDIMM_PASSPHRASE_LEN, 157 .payload_in = pass, 158 }; 159 |
159 rc = cxl_internal_send_cmd(mds, &mbox_cmd); | 160 rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd); |
160 if (rc < 0) 161 return rc; 162 163 return 0; 164} 165 166static int cxl_pmem_security_passphrase_erase(struct nvdimm *nvdimm, 167 const struct nvdimm_key_data *key, 168 enum nvdimm_passphrase_type ptype) 169{ 170 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 171 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; | 161 if (rc < 0) 162 return rc; 163 164 return 0; 165} 166 167static int cxl_pmem_security_passphrase_erase(struct nvdimm *nvdimm, 168 const struct nvdimm_key_data *key, 169 enum nvdimm_passphrase_type ptype) 170{ 171 struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); 172 struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; |
172 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); | 173 struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox; |
173 struct cxl_mbox_cmd mbox_cmd; 174 struct cxl_pass_erase erase; 175 int rc; 176 177 erase = (struct cxl_pass_erase) { 178 .type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER : 179 CXL_PMEM_SEC_PASS_USER, 180 }; 181 memcpy(erase.pass, key->data, NVDIMM_PASSPHRASE_LEN); 182 mbox_cmd = (struct cxl_mbox_cmd) { 183 .opcode = CXL_MBOX_OP_PASSPHRASE_SECURE_ERASE, 184 .size_in = sizeof(erase), 185 .payload_in = &erase, 186 }; 187 | 174 struct cxl_mbox_cmd mbox_cmd; 175 struct cxl_pass_erase erase; 176 int rc; 177 178 erase = (struct cxl_pass_erase) { 179 .type = ptype == NVDIMM_MASTER ? CXL_PMEM_SEC_PASS_MASTER : 180 CXL_PMEM_SEC_PASS_USER, 181 }; 182 memcpy(erase.pass, key->data, NVDIMM_PASSPHRASE_LEN); 183 mbox_cmd = (struct cxl_mbox_cmd) { 184 .opcode = CXL_MBOX_OP_PASSPHRASE_SECURE_ERASE, 185 .size_in = sizeof(erase), 186 .payload_in = &erase, 187 }; 188 |
188 rc = cxl_internal_send_cmd(mds, &mbox_cmd); | 189 rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd); |
189 if (rc < 0) 190 return rc; 191 192 return 0; 193} 194 195static const struct nvdimm_security_ops __cxl_security_ops = { 196 .get_flags = cxl_pmem_get_security_flags, 197 .change_key = cxl_pmem_security_change_key, 198 .disable = cxl_pmem_security_disable, 199 .freeze = cxl_pmem_security_freeze, 200 .unlock = cxl_pmem_security_unlock, 201 .erase = cxl_pmem_security_passphrase_erase, 202 .disable_master = cxl_pmem_security_disable_master, 203}; 204 205const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops; | 190 if (rc < 0) 191 return rc; 192 193 return 0; 194} 195 196static const struct nvdimm_security_ops __cxl_security_ops = { 197 .get_flags = cxl_pmem_get_security_flags, 198 .change_key = cxl_pmem_security_change_key, 199 .disable = cxl_pmem_security_disable, 200 .freeze = cxl_pmem_security_freeze, 201 .unlock = cxl_pmem_security_unlock, 202 .erase = cxl_pmem_security_passphrase_erase, 203 .disable_master = cxl_pmem_security_disable_master, 204}; 205 206const struct nvdimm_security_ops *cxl_security_ops = &__cxl_security_ops; |