1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * POWER LPAR Platform KeyStore(PLPKS) 4 * Copyright (C) 2022 IBM Corporation 5 * Author: Nayna Jain <nayna@linux.ibm.com> 6 * 7 * Provides access to variables stored in Power LPAR Platform KeyStore(PLPKS). 8 */ 9 10 #define pr_fmt(fmt) "plpks: " fmt 11 12 #include <linux/delay.h> 13 #include <linux/errno.h> 14 #include <linux/io.h> 15 #include <linux/printk.h> 16 #include <linux/slab.h> 17 #include <linux/string.h> 18 #include <linux/types.h> 19 #include <asm/hvcall.h> 20 #include <asm/machdep.h> 21 22 #include "plpks.h" 23 24 #define PKS_FW_OWNER 0x1 25 #define PKS_BOOTLOADER_OWNER 0x2 26 #define PKS_OS_OWNER 0x3 27 28 #define LABEL_VERSION 0 29 #define MAX_LABEL_ATTR_SIZE 16 30 #define MAX_NAME_SIZE 239 31 #define MAX_DATA_SIZE 4000 32 33 #define PKS_FLUSH_MAX_TIMEOUT 5000 //msec 34 #define PKS_FLUSH_SLEEP 10 //msec 35 #define PKS_FLUSH_SLEEP_RANGE 400 36 37 static u8 *ospassword; 38 static u16 ospasswordlength; 39 40 // Retrieved with H_PKS_GET_CONFIG 41 static u16 maxpwsize; 42 static u16 maxobjsize; 43 44 struct plpks_auth { 45 u8 version; 46 u8 consumer; 47 __be64 rsvd0; 48 __be32 rsvd1; 49 __be16 passwordlength; 50 u8 password[]; 51 } __packed __aligned(16); 52 53 struct label_attr { 54 u8 prefix[8]; 55 u8 version; 56 u8 os; 57 u8 length; 58 u8 reserved[5]; 59 }; 60 61 struct label { 62 struct label_attr attr; 63 u8 name[MAX_NAME_SIZE]; 64 size_t size; 65 }; 66 67 static int pseries_status_to_err(int rc) 68 { 69 int err; 70 71 switch (rc) { 72 case H_SUCCESS: 73 err = 0; 74 break; 75 case H_FUNCTION: 76 err = -ENXIO; 77 break; 78 case H_PARAMETER: 79 case H_P2: 80 case H_P3: 81 case H_P4: 82 case H_P5: 83 case H_P6: 84 err = -EINVAL; 85 break; 86 case H_NOT_FOUND: 87 err = -ENOENT; 88 break; 89 case H_BUSY: 90 err = -EBUSY; 91 break; 92 case H_AUTHORITY: 93 err = -EPERM; 94 break; 95 case H_NO_MEM: 96 err = -ENOMEM; 97 break; 98 case H_RESOURCE: 99 err = -EEXIST; 100 break; 101 case H_TOO_BIG: 102 err = -EFBIG; 103 break; 104 case H_STATE: 105 err = -EIO; 106 break; 107 case H_R_STATE: 108 err = -EIO; 109 break; 110 case H_IN_USE: 111 err = -EEXIST; 112 break; 113 case H_ABORTED: 114 err = -EIO; 115 break; 116 default: 117 err = -EINVAL; 118 } 119 120 return err; 121 } 122 123 static int plpks_gen_password(void) 124 { 125 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 126 u8 *password, consumer = PKS_OS_OWNER; 127 int rc; 128 129 password = kzalloc(maxpwsize, GFP_KERNEL); 130 if (!password) 131 return -ENOMEM; 132 133 rc = plpar_hcall(H_PKS_GEN_PASSWORD, retbuf, consumer, 0, 134 virt_to_phys(password), maxpwsize); 135 136 if (!rc) { 137 ospasswordlength = maxpwsize; 138 ospassword = kzalloc(maxpwsize, GFP_KERNEL); 139 if (!ospassword) { 140 kfree(password); 141 return -ENOMEM; 142 } 143 memcpy(ospassword, password, ospasswordlength); 144 } else { 145 if (rc == H_IN_USE) { 146 pr_warn("Password is already set for POWER LPAR Platform KeyStore\n"); 147 rc = 0; 148 } else { 149 goto out; 150 } 151 } 152 out: 153 kfree(password); 154 155 return pseries_status_to_err(rc); 156 } 157 158 static struct plpks_auth *construct_auth(u8 consumer) 159 { 160 struct plpks_auth *auth; 161 162 if (consumer > PKS_OS_OWNER) 163 return ERR_PTR(-EINVAL); 164 165 auth = kzalloc(struct_size(auth, password, maxpwsize), GFP_KERNEL); 166 if (!auth) 167 return ERR_PTR(-ENOMEM); 168 169 auth->version = 1; 170 auth->consumer = consumer; 171 172 if (consumer == PKS_FW_OWNER || consumer == PKS_BOOTLOADER_OWNER) 173 return auth; 174 175 memcpy(auth->password, ospassword, ospasswordlength); 176 177 auth->passwordlength = cpu_to_be16(ospasswordlength); 178 179 return auth; 180 } 181 182 /** 183 * Label is combination of label attributes + name. 184 * Label attributes are used internally by kernel and not exposed to the user. 185 */ 186 static struct label *construct_label(char *component, u8 varos, u8 *name, 187 u16 namelen) 188 { 189 struct label *label; 190 size_t slen; 191 192 if (!name || namelen > MAX_NAME_SIZE) 193 return ERR_PTR(-EINVAL); 194 195 slen = strlen(component); 196 if (component && slen > sizeof(label->attr.prefix)) 197 return ERR_PTR(-EINVAL); 198 199 label = kzalloc(sizeof(*label), GFP_KERNEL); 200 if (!label) 201 return ERR_PTR(-ENOMEM); 202 203 if (component) 204 memcpy(&label->attr.prefix, component, slen); 205 206 label->attr.version = LABEL_VERSION; 207 label->attr.os = varos; 208 label->attr.length = MAX_LABEL_ATTR_SIZE; 209 memcpy(&label->name, name, namelen); 210 211 label->size = sizeof(struct label_attr) + namelen; 212 213 return label; 214 } 215 216 static int _plpks_get_config(void) 217 { 218 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 219 struct { 220 u8 version; 221 u8 flags; 222 __be32 rsvd0; 223 __be16 maxpwsize; 224 __be16 maxobjlabelsize; 225 __be16 maxobjsize; 226 __be32 totalsize; 227 __be32 usedspace; 228 __be32 supportedpolicies; 229 __be64 rsvd1; 230 } __packed config; 231 size_t size; 232 int rc; 233 234 size = sizeof(config); 235 236 rc = plpar_hcall(H_PKS_GET_CONFIG, retbuf, virt_to_phys(&config), size); 237 238 if (rc != H_SUCCESS) 239 return pseries_status_to_err(rc); 240 241 maxpwsize = be16_to_cpu(config.maxpwsize); 242 maxobjsize = be16_to_cpu(config.maxobjsize); 243 244 return 0; 245 } 246 247 static int plpks_confirm_object_flushed(struct label *label, 248 struct plpks_auth *auth) 249 { 250 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 251 u64 timeout = 0; 252 u8 status; 253 int rc; 254 255 do { 256 rc = plpar_hcall(H_PKS_CONFIRM_OBJECT_FLUSHED, retbuf, 257 virt_to_phys(auth), virt_to_phys(label), 258 label->size); 259 260 status = retbuf[0]; 261 if (rc) { 262 if (rc == H_NOT_FOUND && status == 1) 263 rc = 0; 264 break; 265 } 266 267 if (!rc && status == 1) 268 break; 269 270 usleep_range(PKS_FLUSH_SLEEP, 271 PKS_FLUSH_SLEEP + PKS_FLUSH_SLEEP_RANGE); 272 timeout = timeout + PKS_FLUSH_SLEEP; 273 } while (timeout < PKS_FLUSH_MAX_TIMEOUT); 274 275 rc = pseries_status_to_err(rc); 276 277 return rc; 278 } 279 280 int plpks_write_var(struct plpks_var var) 281 { 282 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 283 struct plpks_auth *auth; 284 struct label *label; 285 int rc; 286 287 if (!var.component || !var.data || var.datalen <= 0 || 288 var.namelen > MAX_NAME_SIZE || var.datalen > MAX_DATA_SIZE) 289 return -EINVAL; 290 291 if (var.policy & SIGNEDUPDATE) 292 return -EINVAL; 293 294 auth = construct_auth(PKS_OS_OWNER); 295 if (IS_ERR(auth)) 296 return PTR_ERR(auth); 297 298 label = construct_label(var.component, var.os, var.name, var.namelen); 299 if (IS_ERR(label)) { 300 rc = PTR_ERR(label); 301 goto out; 302 } 303 304 rc = plpar_hcall(H_PKS_WRITE_OBJECT, retbuf, virt_to_phys(auth), 305 virt_to_phys(label), label->size, var.policy, 306 virt_to_phys(var.data), var.datalen); 307 308 if (!rc) 309 rc = plpks_confirm_object_flushed(label, auth); 310 311 rc = pseries_status_to_err(rc); 312 kfree(label); 313 out: 314 kfree(auth); 315 316 return rc; 317 } 318 319 int plpks_remove_var(char *component, u8 varos, struct plpks_var_name vname) 320 { 321 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 322 struct plpks_auth *auth; 323 struct label *label; 324 int rc; 325 326 if (!component || vname.namelen > MAX_NAME_SIZE) 327 return -EINVAL; 328 329 auth = construct_auth(PKS_OS_OWNER); 330 if (IS_ERR(auth)) 331 return PTR_ERR(auth); 332 333 label = construct_label(component, varos, vname.name, vname.namelen); 334 if (IS_ERR(label)) { 335 rc = PTR_ERR(label); 336 goto out; 337 } 338 339 rc = plpar_hcall(H_PKS_REMOVE_OBJECT, retbuf, virt_to_phys(auth), 340 virt_to_phys(label), label->size); 341 342 if (!rc) 343 rc = plpks_confirm_object_flushed(label, auth); 344 345 rc = pseries_status_to_err(rc); 346 kfree(label); 347 out: 348 kfree(auth); 349 350 return rc; 351 } 352 353 static int plpks_read_var(u8 consumer, struct plpks_var *var) 354 { 355 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 356 struct plpks_auth *auth; 357 struct label *label = NULL; 358 u8 *output; 359 int rc; 360 361 if (var->namelen > MAX_NAME_SIZE) 362 return -EINVAL; 363 364 auth = construct_auth(consumer); 365 if (IS_ERR(auth)) 366 return PTR_ERR(auth); 367 368 if (consumer == PKS_OS_OWNER) { 369 label = construct_label(var->component, var->os, var->name, 370 var->namelen); 371 if (IS_ERR(label)) { 372 rc = PTR_ERR(label); 373 goto out_free_auth; 374 } 375 } 376 377 output = kzalloc(maxobjsize, GFP_KERNEL); 378 if (!output) { 379 rc = -ENOMEM; 380 goto out_free_label; 381 } 382 383 if (consumer == PKS_OS_OWNER) 384 rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth), 385 virt_to_phys(label), label->size, virt_to_phys(output), 386 maxobjsize); 387 else 388 rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth), 389 virt_to_phys(var->name), var->namelen, virt_to_phys(output), 390 maxobjsize); 391 392 393 if (rc != H_SUCCESS) { 394 rc = pseries_status_to_err(rc); 395 goto out_free_output; 396 } 397 398 if (var->datalen == 0 || var->datalen > retbuf[0]) 399 var->datalen = retbuf[0]; 400 401 var->data = kzalloc(var->datalen, GFP_KERNEL); 402 if (!var->data) { 403 rc = -ENOMEM; 404 goto out_free_output; 405 } 406 var->policy = retbuf[1]; 407 408 memcpy(var->data, output, var->datalen); 409 rc = 0; 410 411 out_free_output: 412 kfree(output); 413 out_free_label: 414 kfree(label); 415 out_free_auth: 416 kfree(auth); 417 418 return rc; 419 } 420 421 int plpks_read_os_var(struct plpks_var *var) 422 { 423 return plpks_read_var(PKS_OS_OWNER, var); 424 } 425 426 int plpks_read_fw_var(struct plpks_var *var) 427 { 428 return plpks_read_var(PKS_FW_OWNER, var); 429 } 430 431 int plpks_read_bootloader_var(struct plpks_var *var) 432 { 433 return plpks_read_var(PKS_BOOTLOADER_OWNER, var); 434 } 435 436 static __init int pseries_plpks_init(void) 437 { 438 int rc; 439 440 rc = _plpks_get_config(); 441 442 if (rc) { 443 pr_err("POWER LPAR Platform KeyStore is not supported or enabled\n"); 444 return rc; 445 } 446 447 rc = plpks_gen_password(); 448 if (rc) 449 pr_err("Failed setting POWER LPAR Platform KeyStore Password\n"); 450 else 451 pr_info("POWER LPAR Platform KeyStore initialized successfully\n"); 452 453 return rc; 454 } 455 machine_arch_initcall(pseries, pseries_plpks_init); 456