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 <linux/of_fdt.h> 20 #include <linux/libfdt.h> 21 #include <linux/memblock.h> 22 #include <asm/hvcall.h> 23 #include <asm/machdep.h> 24 #include <asm/plpks.h> 25 26 static u8 *ospassword; 27 static u16 ospasswordlength; 28 29 // Retrieved with H_PKS_GET_CONFIG 30 static u8 version; 31 static u16 objoverhead; 32 static u16 maxpwsize; 33 static u16 maxobjsize; 34 static s16 maxobjlabelsize; 35 static u32 totalsize; 36 static u32 usedspace; 37 static u32 supportedpolicies; 38 static u32 maxlargeobjectsize; 39 static u64 signedupdatealgorithms; 40 41 struct plpks_auth { 42 u8 version; 43 u8 consumer; 44 __be64 rsvd0; 45 __be32 rsvd1; 46 __be16 passwordlength; 47 u8 password[]; 48 } __packed __aligned(16); 49 50 struct label_attr { 51 u8 prefix[8]; 52 u8 version; 53 u8 os; 54 u8 length; 55 u8 reserved[5]; 56 }; 57 58 struct label { 59 struct label_attr attr; 60 u8 name[PLPKS_MAX_NAME_SIZE]; 61 size_t size; 62 }; 63 64 static int pseries_status_to_err(int rc) 65 { 66 int err; 67 68 switch (rc) { 69 case H_SUCCESS: 70 err = 0; 71 break; 72 case H_FUNCTION: 73 err = -ENXIO; 74 break; 75 case H_PARAMETER: 76 case H_P2: 77 case H_P3: 78 case H_P4: 79 case H_P5: 80 case H_P6: 81 err = -EINVAL; 82 break; 83 case H_NOT_FOUND: 84 err = -ENOENT; 85 break; 86 case H_BUSY: 87 case H_LONG_BUSY_ORDER_1_MSEC: 88 case H_LONG_BUSY_ORDER_10_MSEC: 89 case H_LONG_BUSY_ORDER_100_MSEC: 90 case H_LONG_BUSY_ORDER_1_SEC: 91 case H_LONG_BUSY_ORDER_10_SEC: 92 case H_LONG_BUSY_ORDER_100_SEC: 93 err = -EBUSY; 94 break; 95 case H_AUTHORITY: 96 err = -EPERM; 97 break; 98 case H_NO_MEM: 99 err = -ENOMEM; 100 break; 101 case H_RESOURCE: 102 err = -EEXIST; 103 break; 104 case H_TOO_BIG: 105 err = -EFBIG; 106 break; 107 case H_STATE: 108 err = -EIO; 109 break; 110 case H_R_STATE: 111 err = -EIO; 112 break; 113 case H_IN_USE: 114 err = -EEXIST; 115 break; 116 case H_ABORTED: 117 err = -EIO; 118 break; 119 default: 120 err = -EINVAL; 121 } 122 123 pr_debug("Converted hypervisor code %d to Linux %d\n", rc, err); 124 125 return err; 126 } 127 128 static int plpks_gen_password(void) 129 { 130 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 131 u8 *password, consumer = PLPKS_OS_OWNER; 132 int rc; 133 134 // If we booted from kexec, we could be reusing an existing password already 135 if (ospassword) { 136 pr_debug("Password of length %u already in use\n", ospasswordlength); 137 return 0; 138 } 139 140 // The password must not cross a page boundary, so we align to the next power of 2 141 password = kzalloc(roundup_pow_of_two(maxpwsize), GFP_KERNEL); 142 if (!password) 143 return -ENOMEM; 144 145 rc = plpar_hcall(H_PKS_GEN_PASSWORD, retbuf, consumer, 0, 146 virt_to_phys(password), maxpwsize); 147 148 if (!rc) { 149 ospasswordlength = maxpwsize; 150 ospassword = kzalloc(maxpwsize, GFP_KERNEL); 151 if (!ospassword) { 152 kfree(password); 153 return -ENOMEM; 154 } 155 memcpy(ospassword, password, ospasswordlength); 156 } else { 157 if (rc == H_IN_USE) { 158 pr_warn("Password already set - authenticated operations will fail\n"); 159 rc = 0; 160 } else { 161 goto out; 162 } 163 } 164 out: 165 kfree(password); 166 167 return pseries_status_to_err(rc); 168 } 169 170 static struct plpks_auth *construct_auth(u8 consumer) 171 { 172 struct plpks_auth *auth; 173 174 if (consumer > PLPKS_OS_OWNER) 175 return ERR_PTR(-EINVAL); 176 177 // The auth structure must not cross a page boundary and must be 178 // 16 byte aligned. We align to the next largest power of 2 179 auth = kzalloc(roundup_pow_of_two(struct_size(auth, password, maxpwsize)), GFP_KERNEL); 180 if (!auth) 181 return ERR_PTR(-ENOMEM); 182 183 auth->version = 1; 184 auth->consumer = consumer; 185 186 if (consumer == PLPKS_FW_OWNER || consumer == PLPKS_BOOTLOADER_OWNER) 187 return auth; 188 189 memcpy(auth->password, ospassword, ospasswordlength); 190 191 auth->passwordlength = cpu_to_be16(ospasswordlength); 192 193 return auth; 194 } 195 196 /** 197 * Label is combination of label attributes + name. 198 * Label attributes are used internally by kernel and not exposed to the user. 199 */ 200 static struct label *construct_label(char *component, u8 varos, u8 *name, 201 u16 namelen) 202 { 203 struct label *label; 204 size_t slen = 0; 205 206 if (!name || namelen > PLPKS_MAX_NAME_SIZE) 207 return ERR_PTR(-EINVAL); 208 209 // Support NULL component for signed updates 210 if (component) { 211 slen = strlen(component); 212 if (slen > sizeof(label->attr.prefix)) 213 return ERR_PTR(-EINVAL); 214 } 215 216 // The label structure must not cross a page boundary, so we align to the next power of 2 217 label = kzalloc(roundup_pow_of_two(sizeof(*label)), GFP_KERNEL); 218 if (!label) 219 return ERR_PTR(-ENOMEM); 220 221 if (component) 222 memcpy(&label->attr.prefix, component, slen); 223 224 label->attr.version = PLPKS_LABEL_VERSION; 225 label->attr.os = varos; 226 label->attr.length = PLPKS_MAX_LABEL_ATTR_SIZE; 227 memcpy(&label->name, name, namelen); 228 229 label->size = sizeof(struct label_attr) + namelen; 230 231 return label; 232 } 233 234 static int _plpks_get_config(void) 235 { 236 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 237 struct config { 238 u8 version; 239 u8 flags; 240 __be16 rsvd0; 241 __be16 objoverhead; 242 __be16 maxpwsize; 243 __be16 maxobjlabelsize; 244 __be16 maxobjsize; 245 __be32 totalsize; 246 __be32 usedspace; 247 __be32 supportedpolicies; 248 __be32 maxlargeobjectsize; 249 __be64 signedupdatealgorithms; 250 u8 rsvd1[476]; 251 } __packed * config; 252 size_t size; 253 int rc = 0; 254 255 size = sizeof(*config); 256 257 // Config struct must not cross a page boundary. So long as the struct 258 // size is a power of 2, this should be fine as alignment is guaranteed 259 config = kzalloc(size, GFP_KERNEL); 260 if (!config) { 261 rc = -ENOMEM; 262 goto err; 263 } 264 265 rc = plpar_hcall(H_PKS_GET_CONFIG, retbuf, virt_to_phys(config), size); 266 267 if (rc != H_SUCCESS) { 268 rc = pseries_status_to_err(rc); 269 goto err; 270 } 271 272 version = config->version; 273 objoverhead = be16_to_cpu(config->objoverhead); 274 maxpwsize = be16_to_cpu(config->maxpwsize); 275 maxobjsize = be16_to_cpu(config->maxobjsize); 276 maxobjlabelsize = be16_to_cpu(config->maxobjlabelsize); 277 totalsize = be32_to_cpu(config->totalsize); 278 usedspace = be32_to_cpu(config->usedspace); 279 supportedpolicies = be32_to_cpu(config->supportedpolicies); 280 maxlargeobjectsize = be32_to_cpu(config->maxlargeobjectsize); 281 signedupdatealgorithms = be64_to_cpu(config->signedupdatealgorithms); 282 283 // Validate that the numbers we get back match the requirements of the spec 284 if (maxpwsize < 32) { 285 pr_err("Invalid Max Password Size received from hypervisor (%d < 32)\n", maxpwsize); 286 rc = -EIO; 287 goto err; 288 } 289 290 if (maxobjlabelsize < 255) { 291 pr_err("Invalid Max Object Label Size received from hypervisor (%d < 255)\n", 292 maxobjlabelsize); 293 rc = -EIO; 294 goto err; 295 } 296 297 if (totalsize < 4096) { 298 pr_err("Invalid Total Size received from hypervisor (%d < 4096)\n", totalsize); 299 rc = -EIO; 300 goto err; 301 } 302 303 if (version >= 3 && maxlargeobjectsize >= 65536 && maxobjsize != 0xFFFF) { 304 pr_err("Invalid Max Object Size (0x%x != 0xFFFF)\n", maxobjsize); 305 rc = -EIO; 306 goto err; 307 } 308 309 err: 310 kfree(config); 311 return rc; 312 } 313 314 u8 plpks_get_version(void) 315 { 316 return version; 317 } 318 319 u16 plpks_get_objoverhead(void) 320 { 321 return objoverhead; 322 } 323 324 u16 plpks_get_maxpwsize(void) 325 { 326 return maxpwsize; 327 } 328 329 u16 plpks_get_maxobjectsize(void) 330 { 331 return maxobjsize; 332 } 333 334 u16 plpks_get_maxobjectlabelsize(void) 335 { 336 return maxobjlabelsize; 337 } 338 339 u32 plpks_get_totalsize(void) 340 { 341 return totalsize; 342 } 343 344 u32 plpks_get_usedspace(void) 345 { 346 // Unlike other config values, usedspace regularly changes as objects 347 // are updated, so we need to refresh. 348 int rc = _plpks_get_config(); 349 if (rc) { 350 pr_err("Couldn't get config, rc: %d\n", rc); 351 return 0; 352 } 353 return usedspace; 354 } 355 356 u32 plpks_get_supportedpolicies(void) 357 { 358 return supportedpolicies; 359 } 360 361 u32 plpks_get_maxlargeobjectsize(void) 362 { 363 return maxlargeobjectsize; 364 } 365 366 u64 plpks_get_signedupdatealgorithms(void) 367 { 368 return signedupdatealgorithms; 369 } 370 371 u16 plpks_get_passwordlen(void) 372 { 373 return ospasswordlength; 374 } 375 376 bool plpks_is_available(void) 377 { 378 int rc; 379 380 rc = _plpks_get_config(); 381 if (rc) 382 return false; 383 384 return true; 385 } 386 387 static int plpks_confirm_object_flushed(struct label *label, 388 struct plpks_auth *auth) 389 { 390 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 391 bool timed_out = true; 392 u64 timeout = 0; 393 u8 status; 394 int rc; 395 396 do { 397 rc = plpar_hcall(H_PKS_CONFIRM_OBJECT_FLUSHED, retbuf, 398 virt_to_phys(auth), virt_to_phys(label), 399 label->size); 400 401 status = retbuf[0]; 402 if (rc) { 403 timed_out = false; 404 if (rc == H_NOT_FOUND && status == 1) 405 rc = 0; 406 break; 407 } 408 409 if (!rc && status == 1) { 410 timed_out = false; 411 break; 412 } 413 414 usleep_range(PLPKS_FLUSH_SLEEP, 415 PLPKS_FLUSH_SLEEP + PLPKS_FLUSH_SLEEP_RANGE); 416 timeout = timeout + PLPKS_FLUSH_SLEEP; 417 } while (timeout < PLPKS_MAX_TIMEOUT); 418 419 if (timed_out) 420 return -ETIMEDOUT; 421 422 return pseries_status_to_err(rc); 423 } 424 425 int plpks_signed_update_var(struct plpks_var *var, u64 flags) 426 { 427 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; 428 int rc; 429 struct label *label; 430 struct plpks_auth *auth; 431 u64 continuetoken = 0; 432 u64 timeout = 0; 433 434 if (!var->data || var->datalen <= 0 || var->namelen > PLPKS_MAX_NAME_SIZE) 435 return -EINVAL; 436 437 if (!(var->policy & PLPKS_SIGNEDUPDATE)) 438 return -EINVAL; 439 440 // Signed updates need the component to be NULL. 441 if (var->component) 442 return -EINVAL; 443 444 auth = construct_auth(PLPKS_OS_OWNER); 445 if (IS_ERR(auth)) 446 return PTR_ERR(auth); 447 448 label = construct_label(var->component, var->os, var->name, var->namelen); 449 if (IS_ERR(label)) { 450 rc = PTR_ERR(label); 451 goto out; 452 } 453 454 do { 455 rc = plpar_hcall9(H_PKS_SIGNED_UPDATE, retbuf, 456 virt_to_phys(auth), virt_to_phys(label), 457 label->size, var->policy, flags, 458 virt_to_phys(var->data), var->datalen, 459 continuetoken); 460 461 continuetoken = retbuf[0]; 462 if (pseries_status_to_err(rc) == -EBUSY) { 463 int delay_ms = get_longbusy_msecs(rc); 464 mdelay(delay_ms); 465 timeout += delay_ms; 466 } 467 rc = pseries_status_to_err(rc); 468 } while (rc == -EBUSY && timeout < PLPKS_MAX_TIMEOUT); 469 470 if (!rc) 471 rc = plpks_confirm_object_flushed(label, auth); 472 473 kfree(label); 474 out: 475 kfree(auth); 476 477 return rc; 478 } 479 480 int plpks_write_var(struct plpks_var var) 481 { 482 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 483 struct plpks_auth *auth; 484 struct label *label; 485 int rc; 486 487 if (!var.component || !var.data || var.datalen <= 0 || 488 var.namelen > PLPKS_MAX_NAME_SIZE || var.datalen > PLPKS_MAX_DATA_SIZE) 489 return -EINVAL; 490 491 if (var.policy & PLPKS_SIGNEDUPDATE) 492 return -EINVAL; 493 494 auth = construct_auth(PLPKS_OS_OWNER); 495 if (IS_ERR(auth)) 496 return PTR_ERR(auth); 497 498 label = construct_label(var.component, var.os, var.name, var.namelen); 499 if (IS_ERR(label)) { 500 rc = PTR_ERR(label); 501 goto out; 502 } 503 504 rc = plpar_hcall(H_PKS_WRITE_OBJECT, retbuf, virt_to_phys(auth), 505 virt_to_phys(label), label->size, var.policy, 506 virt_to_phys(var.data), var.datalen); 507 508 if (!rc) 509 rc = plpks_confirm_object_flushed(label, auth); 510 511 rc = pseries_status_to_err(rc); 512 kfree(label); 513 out: 514 kfree(auth); 515 516 return rc; 517 } 518 519 int plpks_remove_var(char *component, u8 varos, struct plpks_var_name vname) 520 { 521 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 522 struct plpks_auth *auth; 523 struct label *label; 524 int rc; 525 526 if (vname.namelen > PLPKS_MAX_NAME_SIZE) 527 return -EINVAL; 528 529 auth = construct_auth(PLPKS_OS_OWNER); 530 if (IS_ERR(auth)) 531 return PTR_ERR(auth); 532 533 label = construct_label(component, varos, vname.name, vname.namelen); 534 if (IS_ERR(label)) { 535 rc = PTR_ERR(label); 536 goto out; 537 } 538 539 rc = plpar_hcall(H_PKS_REMOVE_OBJECT, retbuf, virt_to_phys(auth), 540 virt_to_phys(label), label->size); 541 542 if (!rc) 543 rc = plpks_confirm_object_flushed(label, auth); 544 545 rc = pseries_status_to_err(rc); 546 kfree(label); 547 out: 548 kfree(auth); 549 550 return rc; 551 } 552 553 static int plpks_read_var(u8 consumer, struct plpks_var *var) 554 { 555 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 556 struct plpks_auth *auth; 557 struct label *label = NULL; 558 u8 *output; 559 int rc; 560 561 if (var->namelen > PLPKS_MAX_NAME_SIZE) 562 return -EINVAL; 563 564 auth = construct_auth(consumer); 565 if (IS_ERR(auth)) 566 return PTR_ERR(auth); 567 568 if (consumer == PLPKS_OS_OWNER) { 569 label = construct_label(var->component, var->os, var->name, 570 var->namelen); 571 if (IS_ERR(label)) { 572 rc = PTR_ERR(label); 573 goto out_free_auth; 574 } 575 } 576 577 output = kzalloc(maxobjsize, GFP_KERNEL); 578 if (!output) { 579 rc = -ENOMEM; 580 goto out_free_label; 581 } 582 583 if (consumer == PLPKS_OS_OWNER) 584 rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth), 585 virt_to_phys(label), label->size, virt_to_phys(output), 586 maxobjsize); 587 else 588 rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth), 589 virt_to_phys(var->name), var->namelen, virt_to_phys(output), 590 maxobjsize); 591 592 593 if (rc != H_SUCCESS) { 594 rc = pseries_status_to_err(rc); 595 goto out_free_output; 596 } 597 598 if (!var->data || var->datalen > retbuf[0]) 599 var->datalen = retbuf[0]; 600 601 var->policy = retbuf[1]; 602 603 if (var->data) 604 memcpy(var->data, output, var->datalen); 605 606 rc = 0; 607 608 out_free_output: 609 kfree(output); 610 out_free_label: 611 kfree(label); 612 out_free_auth: 613 kfree(auth); 614 615 return rc; 616 } 617 618 int plpks_read_os_var(struct plpks_var *var) 619 { 620 return plpks_read_var(PLPKS_OS_OWNER, var); 621 } 622 623 int plpks_read_fw_var(struct plpks_var *var) 624 { 625 return plpks_read_var(PLPKS_FW_OWNER, var); 626 } 627 628 int plpks_read_bootloader_var(struct plpks_var *var) 629 { 630 return plpks_read_var(PLPKS_BOOTLOADER_OWNER, var); 631 } 632 633 int plpks_populate_fdt(void *fdt) 634 { 635 int chosen_offset = fdt_path_offset(fdt, "/chosen"); 636 637 if (chosen_offset < 0) { 638 pr_err("Can't find chosen node: %s\n", 639 fdt_strerror(chosen_offset)); 640 return chosen_offset; 641 } 642 643 return fdt_setprop(fdt, chosen_offset, "ibm,plpks-pw", ospassword, ospasswordlength); 644 } 645 646 // Once a password is registered with the hypervisor it cannot be cleared without 647 // rebooting the LPAR, so to keep using the PLPKS across kexec boots we need to 648 // recover the previous password from the FDT. 649 // 650 // There are a few challenges here. We don't want the password to be visible to 651 // users, so we need to clear it from the FDT. This has to be done in early boot. 652 // Clearing it from the FDT would make the FDT's checksum invalid, so we have to 653 // manually cause the checksum to be recalculated. 654 void __init plpks_early_init_devtree(void) 655 { 656 void *fdt = initial_boot_params; 657 int chosen_node = fdt_path_offset(fdt, "/chosen"); 658 const u8 *password; 659 int len; 660 661 if (chosen_node < 0) 662 return; 663 664 password = fdt_getprop(fdt, chosen_node, "ibm,plpks-pw", &len); 665 if (len <= 0) { 666 pr_debug("Couldn't find ibm,plpks-pw node.\n"); 667 return; 668 } 669 670 ospassword = memblock_alloc_raw(len, SMP_CACHE_BYTES); 671 if (!ospassword) { 672 pr_err("Error allocating memory for password.\n"); 673 goto out; 674 } 675 676 memcpy(ospassword, password, len); 677 ospasswordlength = (u16)len; 678 679 out: 680 fdt_nop_property(fdt, chosen_node, "ibm,plpks-pw"); 681 // Since we've cleared the password, we must update the FDT checksum 682 early_init_dt_verify(fdt); 683 } 684 685 static __init int pseries_plpks_init(void) 686 { 687 int rc; 688 689 rc = _plpks_get_config(); 690 691 if (rc) { 692 pr_err("POWER LPAR Platform KeyStore is not supported or enabled\n"); 693 return rc; 694 } 695 696 rc = plpks_gen_password(); 697 if (rc) 698 pr_err("Failed setting POWER LPAR Platform KeyStore Password\n"); 699 else 700 pr_info("POWER LPAR Platform KeyStore initialized successfully\n"); 701 702 return rc; 703 } 704 machine_arch_initcall(pseries, pseries_plpks_init); 705