Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'tpmdd-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull tpm updates from Jarkko Sakkinen:

- Restrict linking of keys to .ima and .evm keyrings based on
digitalSignature attribute in the certificate

- PowerVM: load machine owner keys into the .machine [1] keyring

- PowerVM: load module signing keys into the secondary trusted keyring
(keys blessed by the vendor)

- tpm_tis_spi: half-duplex transfer mode

- tpm_tis: retry corrupted transfers

- Apply revocation list (.mokx) to an all system keyrings (e.g.
.machine keyring)

Link: https://blogs.oracle.com/linux/post/the-machine-keyring [1]

* tag 'tpmdd-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
certs: Reference revocation list for all keyrings
tpm/tpm_tis_synquacer: Use module_platform_driver macro to simplify the code
tpm: remove redundant variable len
tpm_tis: Resend command to recover from data transfer errors
tpm_tis: Use responseRetry to recover from data transfer errors
tpm_tis: Move CRC check to generic send routine
tpm_tis_spi: Add hardware wait polling
KEYS: Replace all non-returning strlcpy with strscpy
integrity: PowerVM support for loading third party code signing keys
integrity: PowerVM machine keyring enablement
integrity: check whether imputed trust is enabled
integrity: remove global variable from machine_keyring.c
integrity: ignore keys failing CA restrictions on non-UEFI platform
integrity: PowerVM support for loading CA keys on machine keyring
integrity: Enforce digitalSignature usage in the ima and evm keyrings
KEYS: DigitalSignature link restriction
tpm_tis: Revert "tpm_tis: Disable interrupts on ThinkPad T490s"

+394 -148
+7
Documentation/admin-guide/kernel-parameters.txt
··· 6394 6394 This will guarantee that all the other pcrs 6395 6395 are saved. 6396 6396 6397 + tpm_tis.interrupts= [HW,TPM] 6398 + Enable interrupts for the MMIO based physical layer 6399 + for the FIFO interface. By default it is set to false 6400 + (0). For more information about TPM hardware interfaces 6401 + defined by Trusted Computing Group (TCG) see 6402 + https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/ 6403 + 6397 6404 tp_printk [FTRACE] 6398 6405 Have the tracepoints sent to printk as well as the 6399 6406 tracing ring buffer. This is useful for early boot up
+85 -6
certs/system_keyring.c
··· 51 51 builtin_trusted_keys); 52 52 } 53 53 54 + /** 55 + * restrict_link_by_digsig_builtin - Restrict digitalSignature key additions by the built-in keyring 56 + * @dest_keyring: Keyring being linked to. 57 + * @type: The type of key being added. 58 + * @payload: The payload of the new key. 59 + * @restriction_key: A ring of keys that can be used to vouch for the new cert. 60 + * 61 + * Restrict the addition of keys into a keyring based on the key-to-be-added 62 + * being vouched for by a key in the built in system keyring. The new key 63 + * must have the digitalSignature usage field set. 64 + */ 65 + int restrict_link_by_digsig_builtin(struct key *dest_keyring, 66 + const struct key_type *type, 67 + const union key_payload *payload, 68 + struct key *restriction_key) 69 + { 70 + return restrict_link_by_digsig(dest_keyring, type, payload, 71 + builtin_trusted_keys); 72 + } 73 + 54 74 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING 55 75 /** 56 76 * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring ··· 103 83 secondary_trusted_keys); 104 84 } 105 85 86 + /** 87 + * restrict_link_by_digsig_builtin_and_secondary - Restrict by digitalSignature. 88 + * @dest_keyring: Keyring being linked to. 89 + * @type: The type of key being added. 90 + * @payload: The payload of the new key. 91 + * @restrict_key: A ring of keys that can be used to vouch for the new cert. 92 + * 93 + * Restrict the addition of keys into a keyring based on the key-to-be-added 94 + * being vouched for by a key in either the built-in or the secondary system 95 + * keyrings. The new key must have the digitalSignature usage field set. 96 + */ 97 + int restrict_link_by_digsig_builtin_and_secondary(struct key *dest_keyring, 98 + const struct key_type *type, 99 + const union key_payload *payload, 100 + struct key *restrict_key) 101 + { 102 + /* If we have a secondary trusted keyring, then that contains a link 103 + * through to the builtin keyring and the search will follow that link. 104 + */ 105 + if (type == &key_type_keyring && 106 + dest_keyring == secondary_trusted_keys && 107 + payload == &builtin_trusted_keys->payload) 108 + /* Allow the builtin keyring to be added to the secondary */ 109 + return 0; 110 + 111 + return restrict_link_by_digsig(dest_keyring, type, payload, 112 + secondary_trusted_keys); 113 + } 114 + 106 115 /* 107 116 * Allocate a struct key_restriction for the "builtin and secondary trust" 108 117 * keyring. Only for use in system_trusted_keyring_init(). ··· 151 102 restriction->check = restrict_link_by_builtin_and_secondary_trusted; 152 103 153 104 return restriction; 105 + } 106 + 107 + /** 108 + * add_to_secondary_keyring - Add to secondary keyring. 109 + * @source: Source of key 110 + * @data: The blob holding the key 111 + * @len: The length of the data blob 112 + * 113 + * Add a key to the secondary keyring. The key must be vouched for by a key in the builtin, 114 + * machine or secondary keyring itself. 115 + */ 116 + void __init add_to_secondary_keyring(const char *source, const void *data, size_t len) 117 + { 118 + key_ref_t key; 119 + key_perm_t perm; 120 + 121 + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW; 122 + 123 + key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1), 124 + "asymmetric", 125 + NULL, data, len, perm, 126 + KEY_ALLOC_NOT_IN_QUOTA); 127 + if (IS_ERR(key)) { 128 + pr_err("Problem loading X.509 certificate from %s to secondary keyring %ld\n", 129 + source, PTR_ERR(key)); 130 + return; 131 + } 132 + 133 + pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description); 134 + key_ref_put(key); 154 135 } 155 136 #endif 156 137 #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING ··· 330 251 if (ret < 0) 331 252 goto error; 332 253 254 + ret = is_key_on_revocation_list(pkcs7); 255 + if (ret != -ENOKEY) { 256 + pr_devel("PKCS#7 key is on revocation list\n"); 257 + goto error; 258 + } 259 + 333 260 if (!trusted_keys) { 334 261 trusted_keys = builtin_trusted_keys; 335 262 } else if (trusted_keys == VERIFY_USE_SECONDARY_KEYRING) { ··· 353 268 if (!trusted_keys) { 354 269 ret = -ENOKEY; 355 270 pr_devel("PKCS#7 platform keyring is not available\n"); 356 - goto error; 357 - } 358 - 359 - ret = is_key_on_revocation_list(pkcs7); 360 - if (ret != -ENOKEY) { 361 - pr_devel("PKCS#7 platform key is on revocation list\n"); 362 271 goto error; 363 272 } 364 273 }
+44
crypto/asymmetric_keys/restrict.c
··· 148 148 return 0; 149 149 } 150 150 151 + /** 152 + * restrict_link_by_digsig - Restrict additions to a ring of digsig keys 153 + * @dest_keyring: Keyring being linked to. 154 + * @type: The type of key being added. 155 + * @payload: The payload of the new key. 156 + * @trust_keyring: A ring of keys that can be used to vouch for the new cert. 157 + * 158 + * Check if the new certificate has digitalSignature usage set. If it is, 159 + * then mark the new certificate as being ok to link. Afterwards verify 160 + * the new certificate against the ones in the trust_keyring. 161 + * 162 + * Returns 0 if the new certificate was accepted, -ENOKEY if the 163 + * certificate is not a digsig. -ENOPKG if the signature uses unsupported 164 + * crypto, or some other error if there is a matching certificate but 165 + * the signature check cannot be performed. 166 + */ 167 + int restrict_link_by_digsig(struct key *dest_keyring, 168 + const struct key_type *type, 169 + const union key_payload *payload, 170 + struct key *trust_keyring) 171 + { 172 + const struct public_key *pkey; 173 + 174 + if (type != &key_type_asymmetric) 175 + return -EOPNOTSUPP; 176 + 177 + pkey = payload->data[asym_crypto]; 178 + 179 + if (!pkey) 180 + return -ENOPKG; 181 + 182 + if (!test_bit(KEY_EFLAG_DIGITALSIG, &pkey->key_eflags)) 183 + return -ENOKEY; 184 + 185 + if (test_bit(KEY_EFLAG_CA, &pkey->key_eflags)) 186 + return -ENOKEY; 187 + 188 + if (test_bit(KEY_EFLAG_KEYCERTSIGN, &pkey->key_eflags)) 189 + return -ENOKEY; 190 + 191 + return restrict_link_by_signature(dest_keyring, type, payload, 192 + trust_keyring); 193 + } 194 + 151 195 static bool match_either_id(const struct asymmetric_key_id **pair, 152 196 const struct asymmetric_key_id *single) 153 197 {
+1 -2
drivers/char/tpm/eventlog/tpm1.c
··· 251 251 252 252 static int tpm1_ascii_bios_measurements_show(struct seq_file *m, void *v) 253 253 { 254 - int len = 0; 255 254 char *eventname; 256 255 struct tcpa_event *event = v; 257 256 unsigned char *event_entry = ··· 272 273 /* 3rd: event type identifier */ 273 274 seq_printf(m, " %02x", do_endian_conversion(event->event_type)); 274 275 275 - len += get_event_name(eventname, event, event_entry); 276 + get_event_name(eventname, event, event_entry); 276 277 277 278 /* 4th: eventname <= max + \'0' delimiter */ 278 279 seq_printf(m, " %s\n", eventname);
+2 -91
drivers/char/tpm/tpm_tis.c
··· 27 27 #include <linux/of.h> 28 28 #include <linux/of_device.h> 29 29 #include <linux/kernel.h> 30 - #include <linux/dmi.h> 31 30 #include "tpm.h" 32 31 #include "tpm_tis_core.h" 33 32 ··· 88 89 tpm_tis_flush(iobase); 89 90 } 90 91 91 - static int interrupts; 92 - module_param(interrupts, int, 0444); 92 + static bool interrupts; 93 + module_param(interrupts, bool, 0444); 93 94 MODULE_PARM_DESC(interrupts, "Enable interrupts"); 94 95 95 96 static bool itpm; ··· 101 102 module_param(force, bool, 0444); 102 103 MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); 103 104 #endif 104 - 105 - static int tpm_tis_disable_irq(const struct dmi_system_id *d) 106 - { 107 - if (interrupts == -1) { 108 - pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d->ident); 109 - interrupts = 0; 110 - } 111 - 112 - return 0; 113 - } 114 - 115 - static const struct dmi_system_id tpm_tis_dmi_table[] = { 116 - { 117 - .callback = tpm_tis_disable_irq, 118 - .ident = "Framework Laptop (12th Gen Intel Core)", 119 - .matches = { 120 - DMI_MATCH(DMI_SYS_VENDOR, "Framework"), 121 - DMI_MATCH(DMI_PRODUCT_NAME, "Laptop (12th Gen Intel Core)"), 122 - }, 123 - }, 124 - { 125 - .callback = tpm_tis_disable_irq, 126 - .ident = "Framework Laptop (13th Gen Intel Core)", 127 - .matches = { 128 - DMI_MATCH(DMI_SYS_VENDOR, "Framework"), 129 - DMI_MATCH(DMI_PRODUCT_NAME, "Laptop (13th Gen Intel Core)"), 130 - }, 131 - }, 132 - { 133 - .callback = tpm_tis_disable_irq, 134 - .ident = "ThinkPad T490s", 135 - .matches = { 136 - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 137 - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"), 138 - }, 139 - }, 140 - { 141 - .callback = tpm_tis_disable_irq, 142 - .ident = "ThinkStation P360 Tiny", 143 - .matches = { 144 - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 145 - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P360 Tiny"), 146 - }, 147 - }, 148 - { 149 - .callback = tpm_tis_disable_irq, 150 - .ident = "ThinkPad L490", 151 - .matches = { 152 - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 153 - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L490"), 154 - }, 155 - }, 156 - { 157 - .callback = tpm_tis_disable_irq, 158 - .ident = "ThinkPad L590", 159 - .matches = { 160 - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 161 - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L590"), 162 - }, 163 - }, 164 - { 165 - .callback = tpm_tis_disable_irq, 166 - .ident = "ThinkStation P620", 167 - .matches = { 168 - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 169 - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P620"), 170 - }, 171 - }, 172 - { 173 - .callback = tpm_tis_disable_irq, 174 - .ident = "TUXEDO InfinityBook S 15/17 Gen7", 175 - .matches = { 176 - DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 177 - DMI_MATCH(DMI_PRODUCT_NAME, "TUXEDO InfinityBook S 15/17 Gen7"), 178 - }, 179 - }, 180 - { 181 - .callback = tpm_tis_disable_irq, 182 - .ident = "UPX-TGL", 183 - .matches = { 184 - DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), 185 - DMI_MATCH(DMI_PRODUCT_NAME, "UPX-TGL01"), 186 - }, 187 - }, 188 - {} 189 - }; 190 105 191 106 #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) 192 107 static int has_hid(struct acpi_device *dev, const char *hid) ··· 224 311 struct tpm_tis_tcg_phy *phy; 225 312 int irq = -1; 226 313 int rc; 227 - 228 - dmi_check_system(tpm_tis_dmi_table); 229 314 230 315 rc = check_acpi_tpm2(dev); 231 316 if (rc)
+44 -16
drivers/char/tpm/tpm_tis_core.c
··· 340 340 return size; 341 341 } 342 342 343 - static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) 343 + static int tpm_tis_try_recv(struct tpm_chip *chip, u8 *buf, size_t count) 344 344 { 345 345 struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); 346 346 int size = 0; 347 347 int status; 348 348 u32 expected; 349 349 int rc; 350 - 351 - if (count < TPM_HEADER_SIZE) { 352 - size = -EIO; 353 - goto out; 354 - } 355 350 356 351 size = recv_data(chip, buf, TPM_HEADER_SIZE); 357 352 /* read first 10 bytes, including tag, paramsize, and result */ ··· 380 385 goto out; 381 386 } 382 387 status = tpm_tis_status(chip); 383 - if (status & TPM_STS_DATA_AVAIL) { /* retry? */ 388 + if (status & TPM_STS_DATA_AVAIL) { 384 389 dev_err(&chip->dev, "Error left over data\n"); 385 390 size = -EIO; 386 391 goto out; ··· 394 399 } 395 400 396 401 out: 397 - tpm_tis_ready(chip); 398 402 return size; 403 + } 404 + 405 + static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) 406 + { 407 + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); 408 + unsigned int try; 409 + int rc = 0; 410 + 411 + if (count < TPM_HEADER_SIZE) 412 + return -EIO; 413 + 414 + for (try = 0; try < TPM_RETRY; try++) { 415 + rc = tpm_tis_try_recv(chip, buf, count); 416 + 417 + if (rc == -EIO) 418 + /* Data transfer errors, indicated by EIO, can be 419 + * recovered by rereading the response. 420 + */ 421 + tpm_tis_write8(priv, TPM_STS(priv->locality), 422 + TPM_STS_RESPONSE_RETRY); 423 + else 424 + break; 425 + } 426 + 427 + tpm_tis_ready(chip); 428 + 429 + return rc; 399 430 } 400 431 401 432 /* ··· 490 469 goto out_err; 491 470 } 492 471 472 + rc = tpm_tis_verify_crc(priv, len, buf); 473 + if (rc < 0) { 474 + dev_err(&chip->dev, "CRC mismatch for command.\n"); 475 + goto out_err; 476 + } 477 + 493 478 return 0; 494 479 495 480 out_err: ··· 539 512 int rc; 540 513 u32 ordinal; 541 514 unsigned long dur; 515 + unsigned int try; 542 516 543 - rc = tpm_tis_send_data(chip, buf, len); 544 - if (rc < 0) 545 - return rc; 546 - 547 - rc = tpm_tis_verify_crc(priv, len, buf); 548 - if (rc < 0) { 549 - dev_err(&chip->dev, "CRC mismatch for command.\n"); 550 - return rc; 517 + for (try = 0; try < TPM_RETRY; try++) { 518 + rc = tpm_tis_send_data(chip, buf, len); 519 + if (rc >= 0) 520 + /* Data transfer done successfully */ 521 + break; 522 + else if (rc != -EIO) 523 + /* Data transfer failed, not recoverable */ 524 + return rc; 551 525 } 552 526 553 527 /* go and do it */
+1
drivers/char/tpm/tpm_tis_core.h
··· 34 34 TPM_STS_GO = 0x20, 35 35 TPM_STS_DATA_AVAIL = 0x10, 36 36 TPM_STS_DATA_EXPECT = 0x08, 37 + TPM_STS_RESPONSE_RETRY = 0x02, 37 38 TPM_STS_READ_ZERO = 0x23, /* bits that must be zero on read */ 38 39 }; 39 40
+89 -2
drivers/char/tpm/tpm_tis_spi_main.c
··· 71 71 return 0; 72 72 } 73 73 74 - int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, 75 - u8 *in, const u8 *out) 74 + /* 75 + * Half duplex controller with support for TPM wait state detection like 76 + * Tegra QSPI need CMD, ADDR & DATA sent in single message to manage HW flow 77 + * control. Each phase sent in different transfer for controller to idenity 78 + * phase. 79 + */ 80 + static int tpm_tis_spi_transfer_half(struct tpm_tis_data *data, u32 addr, 81 + u16 len, u8 *in, const u8 *out) 82 + { 83 + struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); 84 + struct spi_transfer spi_xfer[3]; 85 + struct spi_message m; 86 + u8 transfer_len; 87 + int ret; 88 + 89 + while (len) { 90 + transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE); 91 + 92 + spi_message_init(&m); 93 + phy->iobuf[0] = (in ? 0x80 : 0) | (transfer_len - 1); 94 + phy->iobuf[1] = 0xd4; 95 + phy->iobuf[2] = addr >> 8; 96 + phy->iobuf[3] = addr; 97 + 98 + memset(&spi_xfer, 0, sizeof(spi_xfer)); 99 + 100 + spi_xfer[0].tx_buf = phy->iobuf; 101 + spi_xfer[0].len = 1; 102 + spi_message_add_tail(&spi_xfer[0], &m); 103 + 104 + spi_xfer[1].tx_buf = phy->iobuf + 1; 105 + spi_xfer[1].len = 3; 106 + spi_message_add_tail(&spi_xfer[1], &m); 107 + 108 + if (out) { 109 + spi_xfer[2].tx_buf = &phy->iobuf[4]; 110 + spi_xfer[2].rx_buf = NULL; 111 + memcpy(&phy->iobuf[4], out, transfer_len); 112 + out += transfer_len; 113 + } 114 + 115 + if (in) { 116 + spi_xfer[2].tx_buf = NULL; 117 + spi_xfer[2].rx_buf = &phy->iobuf[4]; 118 + } 119 + 120 + spi_xfer[2].len = transfer_len; 121 + spi_message_add_tail(&spi_xfer[2], &m); 122 + 123 + reinit_completion(&phy->ready); 124 + 125 + ret = spi_sync(phy->spi_device, &m); 126 + if (ret < 0) 127 + return ret; 128 + 129 + if (in) { 130 + memcpy(in, &phy->iobuf[4], transfer_len); 131 + in += transfer_len; 132 + } 133 + 134 + len -= transfer_len; 135 + } 136 + 137 + return ret; 138 + } 139 + 140 + static int tpm_tis_spi_transfer_full(struct tpm_tis_data *data, u32 addr, 141 + u16 len, u8 *in, const u8 *out) 76 142 { 77 143 struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); 78 144 int ret = 0; ··· 214 148 return ret; 215 149 } 216 150 151 + int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, 152 + u8 *in, const u8 *out) 153 + { 154 + struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); 155 + struct spi_controller *ctlr = phy->spi_device->controller; 156 + 157 + /* 158 + * TPM flow control over SPI requires full duplex support. 159 + * Send entire message to a half duplex controller to handle 160 + * wait polling in controller. 161 + * Set TPM HW flow control flag.. 162 + */ 163 + if (ctlr->flags & SPI_CONTROLLER_HALF_DUPLEX) 164 + return tpm_tis_spi_transfer_half(data, addr, len, in, out); 165 + else 166 + return tpm_tis_spi_transfer_full(data, addr, len, in, out); 167 + } 168 + 217 169 static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr, 218 170 u16 len, u8 *result, enum tpm_tis_io_mode io_mode) 219 171 { ··· 272 188 return -ENOMEM; 273 189 274 190 phy->flow_control = tpm_tis_spi_flow_control; 191 + 192 + if (dev->controller->flags & SPI_CONTROLLER_HALF_DUPLEX) 193 + dev->mode |= SPI_TPM_HW_FLOW; 275 194 276 195 /* If the SPI device has an IRQ then use that */ 277 196 if (dev->irq > 0)
+1 -17
drivers/char/tpm/tpm_tis_synquacer.c
··· 162 162 }, 163 163 }; 164 164 165 - static int __init tpm_tis_synquacer_module_init(void) 166 - { 167 - int rc; 165 + module_platform_driver(tis_synquacer_drv); 168 166 169 - rc = platform_driver_register(&tis_synquacer_drv); 170 - if (rc) 171 - return rc; 172 - 173 - return 0; 174 - } 175 - 176 - static void __exit tpm_tis_synquacer_module_exit(void) 177 - { 178 - platform_driver_unregister(&tis_synquacer_drv); 179 - } 180 - 181 - module_init(tpm_tis_synquacer_module_init); 182 - module_exit(tpm_tis_synquacer_module_exit); 183 167 MODULE_DESCRIPTION("TPM MMIO Driver for Socionext SynQuacer platform"); 184 168 MODULE_LICENSE("GPL");
+12
include/crypto/public_key.h
··· 78 78 const struct key_type *type, 79 79 const union key_payload *payload, 80 80 struct key *trust_keyring); 81 + int restrict_link_by_digsig(struct key *dest_keyring, 82 + const struct key_type *type, 83 + const union key_payload *payload, 84 + struct key *trust_keyring); 81 85 #else 82 86 static inline int restrict_link_by_ca(struct key *dest_keyring, 83 87 const struct key_type *type, 84 88 const union key_payload *payload, 85 89 struct key *trust_keyring) 90 + { 91 + return 0; 92 + } 93 + 94 + static inline int restrict_link_by_digsig(struct key *dest_keyring, 95 + const struct key_type *type, 96 + const union key_payload *payload, 97 + struct key *trust_keyring) 86 98 { 87 99 return 0; 88 100 }
+14
include/keys/system_keyring.h
··· 23 23 const struct key_type *type, 24 24 const union key_payload *payload, 25 25 struct key *restriction_key); 26 + int restrict_link_by_digsig_builtin(struct key *dest_keyring, 27 + const struct key_type *type, 28 + const union key_payload *payload, 29 + struct key *restriction_key); 26 30 extern __init int load_module_cert(struct key *keyring); 27 31 28 32 #else 29 33 #define restrict_link_by_builtin_trusted restrict_link_reject 34 + #define restrict_link_by_digsig_builtin restrict_link_reject 30 35 31 36 static inline __init int load_module_cert(struct key *keyring) 32 37 { ··· 46 41 const struct key_type *type, 47 42 const union key_payload *payload, 48 43 struct key *restriction_key); 44 + int restrict_link_by_digsig_builtin_and_secondary(struct key *keyring, 45 + const struct key_type *type, 46 + const union key_payload *payload, 47 + struct key *restriction_key); 48 + void __init add_to_secondary_keyring(const char *source, const void *data, size_t len); 49 49 #else 50 50 #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted 51 + #define restrict_link_by_digsig_builtin_and_secondary restrict_link_by_digsig_builtin 52 + static inline void __init add_to_secondary_keyring(const char *source, const void *data, size_t len) 53 + { 54 + } 51 55 #endif 52 56 53 57 #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+3 -1
security/integrity/Kconfig
··· 67 67 depends on SECONDARY_TRUSTED_KEYRING 68 68 depends on INTEGRITY_ASYMMETRIC_KEYS 69 69 depends on SYSTEM_BLACKLIST_KEYRING 70 - depends on LOAD_UEFI_KEYS 70 + depends on LOAD_UEFI_KEYS || LOAD_PPC_KEYS 71 + select INTEGRITY_CA_MACHINE_KEYRING if LOAD_PPC_KEYS 72 + select INTEGRITY_CA_MACHINE_KEYRING_MAX if LOAD_PPC_KEYS 71 73 help 72 74 If set, provide a keyring to which Machine Owner Keys (MOK) may 73 75 be added. This keyring shall contain just MOK keys. Unlike keys
+3 -3
security/integrity/digsig.c
··· 34 34 }; 35 35 36 36 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY 37 - #define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted 37 + #define restrict_link_to_ima restrict_link_by_digsig_builtin_and_secondary 38 38 #else 39 - #define restrict_link_to_ima restrict_link_by_builtin_trusted 39 + #define restrict_link_to_ima restrict_link_by_digsig_builtin 40 40 #endif 41 41 42 42 static struct key *integrity_keyring_from_id(const unsigned int id) ··· 113 113 } else { 114 114 if (id == INTEGRITY_KEYRING_PLATFORM) 115 115 set_platform_trusted_keys(keyring[id]); 116 - if (id == INTEGRITY_KEYRING_MACHINE && trust_moklist()) 116 + if (id == INTEGRITY_KEYRING_MACHINE && imputed_trust_enabled()) 117 117 set_machine_trusted_keys(keyring[id]); 118 118 if (id == INTEGRITY_KEYRING_IMA) 119 119 load_module_cert(keyring[id]);
+2 -1
security/integrity/evm/Kconfig
··· 64 64 65 65 This option enables X509 certificate loading from the kernel 66 66 onto the '.evm' trusted keyring. A public key can be used to 67 - verify EVM integrity starting from the 'init' process. 67 + verify EVM integrity starting from the 'init' process. The 68 + key must have digitalSignature usage set. 68 69 69 70 config EVM_X509_PATH 70 71 string "EVM X509 certificate path"
+2 -1
security/integrity/ima/Kconfig
··· 270 270 help 271 271 Keys may be added to the IMA or IMA blacklist keyrings, if the 272 272 key is validly signed by a CA cert in the system built-in or 273 - secondary trusted keyrings. 273 + secondary trusted keyrings. The key must also have the 274 + digitalSignature usage set. 274 275 275 276 Intermediate keys between those the kernel has compiled in and the 276 277 IMA keys to be added may be added to the system secondary keyring,
+3 -2
security/integrity/integrity.h
··· 320 320 321 321 #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING 322 322 void __init add_to_machine_keyring(const char *source, const void *data, size_t len); 323 - bool __init trust_moklist(void); 323 + bool __init imputed_trust_enabled(void); 324 324 #else 325 325 static inline void __init add_to_machine_keyring(const char *source, 326 326 const void *data, size_t len) 327 327 { 328 328 } 329 - static inline bool __init trust_moklist(void) 329 + 330 + static inline bool __init imputed_trust_enabled(void) 330 331 { 331 332 return false; 332 333 }
+18 -1
security/integrity/platform_certs/keyring_handler.c
··· 61 61 __init efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type) 62 62 { 63 63 if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) { 64 - if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING) && trust_moklist()) 64 + if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING) && 65 + imputed_trust_enabled()) 65 66 return add_to_machine_keyring; 66 67 else 67 68 return add_to_platform_keyring; 68 69 } 70 + return NULL; 71 + } 72 + 73 + __init efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type) 74 + { 75 + if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) 76 + return add_to_machine_keyring; 77 + 78 + return NULL; 79 + } 80 + 81 + __init efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type) 82 + { 83 + if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) 84 + return add_to_secondary_keyring; 85 + 69 86 return NULL; 70 87 } 71 88
+10
security/integrity/platform_certs/keyring_handler.h
··· 30 30 efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type); 31 31 32 32 /* 33 + * Return the handler for particular signature list types for CA keys. 34 + */ 35 + efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type); 36 + 37 + /* 38 + * Return the handler for particular signature list types for code signing keys. 39 + */ 40 + efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type); 41 + 42 + /* 33 43 * Return the handler for particular signature list types found in the dbx. 34 44 */ 35 45 efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type);
+34
security/integrity/platform_certs/load_powerpc.c
··· 59 59 static int __init load_powerpc_certs(void) 60 60 { 61 61 void *db = NULL, *dbx = NULL, *data = NULL; 62 + void *trustedca; 63 + void *moduledb; 62 64 u64 dsize = 0; 63 65 u64 offset = 0; 64 66 int rc = 0; ··· 119 117 get_handler_for_dbx); 120 118 if (rc) 121 119 pr_err("Couldn't parse dbx signatures: %d\n", rc); 120 + kfree(data); 121 + } 122 + 123 + data = get_cert_list("trustedcadb", 12, &dsize); 124 + if (!data) { 125 + pr_info("Couldn't get trustedcadb list from firmware\n"); 126 + } else if (IS_ERR(data)) { 127 + rc = PTR_ERR(data); 128 + pr_err("Error reading trustedcadb from firmware: %d\n", rc); 129 + } else { 130 + extract_esl(trustedca, data, dsize, offset); 131 + 132 + rc = parse_efi_signature_list("powerpc:trustedca", trustedca, dsize, 133 + get_handler_for_ca_keys); 134 + if (rc) 135 + pr_err("Couldn't parse trustedcadb signatures: %d\n", rc); 136 + kfree(data); 137 + } 138 + 139 + data = get_cert_list("moduledb", 9, &dsize); 140 + if (!data) { 141 + pr_info("Couldn't get moduledb list from firmware\n"); 142 + } else if (IS_ERR(data)) { 143 + rc = PTR_ERR(data); 144 + pr_err("Error reading moduledb from firmware: %d\n", rc); 145 + } else { 146 + extract_esl(moduledb, data, dsize, offset); 147 + 148 + rc = parse_efi_signature_list("powerpc:moduledb", moduledb, dsize, 149 + get_handler_for_code_signing_keys); 150 + if (rc) 151 + pr_err("Couldn't parse moduledb signatures: %d\n", rc); 122 152 kfree(data); 123 153 } 124 154
+18 -4
security/integrity/platform_certs/machine_keyring.c
··· 8 8 #include <linux/efi.h> 9 9 #include "../integrity.h" 10 10 11 - static bool trust_mok; 12 - 13 11 static __init int machine_keyring_init(void) 14 12 { 15 13 int rc; ··· 34 36 * If the restriction check does not pass and the platform keyring 35 37 * is configured, try to add it into that keyring instead. 36 38 */ 37 - if (rc && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) 39 + if (rc && efi_enabled(EFI_BOOT) && 40 + IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) 38 41 rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, 39 42 data, len, perm); 40 43 ··· 61 62 return false; 62 63 } 63 64 64 - bool __init trust_moklist(void) 65 + static bool __init trust_moklist(void) 65 66 { 66 67 static bool initialized; 68 + static bool trust_mok; 67 69 68 70 if (!initialized) { 69 71 initialized = true; 72 + trust_mok = false; 70 73 71 74 if (uefi_check_trust_mok_keys()) 72 75 trust_mok = true; 73 76 } 74 77 75 78 return trust_mok; 79 + } 80 + 81 + /* 82 + * Provides platform specific check for trusting imputed keys before loading 83 + * on .machine keyring. UEFI systems enable this trust based on a variable, 84 + * and for other platforms, it is always enabled. 85 + */ 86 + bool __init imputed_trust_enabled(void) 87 + { 88 + if (efi_enabled(EFI_BOOT)) 89 + return trust_moklist(); 90 + 91 + return true; 76 92 }
+1 -1
security/keys/request_key_auth.c
··· 178 178 if (!rka->callout_info) 179 179 goto error_free_rka; 180 180 rka->callout_len = callout_len; 181 - strlcpy(rka->op, op, sizeof(rka->op)); 181 + strscpy(rka->op, op, sizeof(rka->op)); 182 182 183 183 /* see if the calling process is already servicing the key request of 184 184 * another process */