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