Commit f2586d92 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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"
parents 1c59d383 218a2680
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -6394,6 +6394,13 @@
			This will guarantee that all the other pcrs
			are saved.

	tpm_tis.interrupts= [HW,TPM]
			Enable interrupts for the MMIO based physical layer
			for the FIFO interface. By default it is set to false
			(0). For more information about TPM hardware interfaces
			defined by Trusted Computing Group (TCG) see
			https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/

	tp_printk	[FTRACE]
			Have the tracepoints sent to printk as well as the
			tracing ring buffer. This is useful for early boot up
+85 −6
Original line number Diff line number Diff line
@@ -51,6 +51,26 @@ int restrict_link_by_builtin_trusted(struct key *dest_keyring,
					  builtin_trusted_keys);
}

/**
 * restrict_link_by_digsig_builtin - Restrict digitalSignature key additions by the built-in keyring
 * @dest_keyring: Keyring being linked to.
 * @type: The type of key being added.
 * @payload: The payload of the new key.
 * @restriction_key: A ring of keys that can be used to vouch for the new cert.
 *
 * Restrict the addition of keys into a keyring based on the key-to-be-added
 * being vouched for by a key in the built in system keyring. The new key
 * must have the digitalSignature usage field set.
 */
int restrict_link_by_digsig_builtin(struct key *dest_keyring,
				    const struct key_type *type,
				    const union key_payload *payload,
				    struct key *restriction_key)
{
	return restrict_link_by_digsig(dest_keyring, type, payload,
				       builtin_trusted_keys);
}

#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
/**
 * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring
@@ -83,6 +103,35 @@ int restrict_link_by_builtin_and_secondary_trusted(
					  secondary_trusted_keys);
}

/**
 * restrict_link_by_digsig_builtin_and_secondary - Restrict by digitalSignature.
 * @dest_keyring: Keyring being linked to.
 * @type: The type of key being added.
 * @payload: The payload of the new key.
 * @restrict_key: A ring of keys that can be used to vouch for the new cert.
 *
 * Restrict the addition of keys into a keyring based on the key-to-be-added
 * being vouched for by a key in either the built-in or the secondary system
 * keyrings. The new key must have the digitalSignature usage field set.
 */
int restrict_link_by_digsig_builtin_and_secondary(struct key *dest_keyring,
						  const struct key_type *type,
						  const union key_payload *payload,
						  struct key *restrict_key)
{
	/* If we have a secondary trusted keyring, then that contains a link
	 * through to the builtin keyring and the search will follow that link.
	 */
	if (type == &key_type_keyring &&
	    dest_keyring == secondary_trusted_keys &&
	    payload == &builtin_trusted_keys->payload)
		/* Allow the builtin keyring to be added to the secondary */
		return 0;

	return restrict_link_by_digsig(dest_keyring, type, payload,
				       secondary_trusted_keys);
}

/*
 * Allocate a struct key_restriction for the "builtin and secondary trust"
 * keyring. Only for use in system_trusted_keyring_init().
@@ -103,6 +152,36 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void

	return restriction;
}

/**
 * add_to_secondary_keyring - Add to secondary keyring.
 * @source: Source of key
 * @data: The blob holding the key
 * @len: The length of the data blob
 *
 * Add a key to the secondary keyring. The key must be vouched for by a key in the builtin,
 * machine or secondary keyring itself.
 */
void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
{
	key_ref_t key;
	key_perm_t perm;

	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;

	key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
				   "asymmetric",
				   NULL, data, len, perm,
				   KEY_ALLOC_NOT_IN_QUOTA);
	if (IS_ERR(key)) {
		pr_err("Problem loading X.509 certificate from %s to secondary keyring %ld\n",
		       source, PTR_ERR(key));
		return;
	}

	pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description);
	key_ref_put(key);
}
#endif
#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
void __init set_machine_trusted_keys(struct key *keyring)
@@ -251,6 +330,12 @@ int verify_pkcs7_message_sig(const void *data, size_t len,
	if (ret < 0)
		goto error;

	ret = is_key_on_revocation_list(pkcs7);
	if (ret != -ENOKEY) {
		pr_devel("PKCS#7 key is on revocation list\n");
		goto error;
	}

	if (!trusted_keys) {
		trusted_keys = builtin_trusted_keys;
	} else if (trusted_keys == VERIFY_USE_SECONDARY_KEYRING) {
@@ -270,12 +355,6 @@ int verify_pkcs7_message_sig(const void *data, size_t len,
			pr_devel("PKCS#7 platform keyring is not available\n");
			goto error;
		}

		ret = is_key_on_revocation_list(pkcs7);
		if (ret != -ENOKEY) {
			pr_devel("PKCS#7 platform key is on revocation list\n");
			goto error;
		}
	}
	ret = pkcs7_validate_trust(pkcs7, trusted_keys);
	if (ret < 0) {
+44 −0
Original line number Diff line number Diff line
@@ -148,6 +148,50 @@ int restrict_link_by_ca(struct key *dest_keyring,
	return 0;
}

/**
 * restrict_link_by_digsig - Restrict additions to a ring of digsig keys
 * @dest_keyring: Keyring being linked to.
 * @type: The type of key being added.
 * @payload: The payload of the new key.
 * @trust_keyring: A ring of keys that can be used to vouch for the new cert.
 *
 * Check if the new certificate has digitalSignature usage set. If it is,
 * then mark the new certificate as being ok to link. Afterwards verify
 * the new certificate against the ones in the trust_keyring.
 *
 * Returns 0 if the new certificate was accepted, -ENOKEY if the
 * certificate is not a digsig. -ENOPKG if the signature uses unsupported
 * crypto, or some other error if there is a matching certificate but
 * the signature check cannot be performed.
 */
int restrict_link_by_digsig(struct key *dest_keyring,
			    const struct key_type *type,
			    const union key_payload *payload,
			    struct key *trust_keyring)
{
	const struct public_key *pkey;

	if (type != &key_type_asymmetric)
		return -EOPNOTSUPP;

	pkey = payload->data[asym_crypto];

	if (!pkey)
		return -ENOPKG;

	if (!test_bit(KEY_EFLAG_DIGITALSIG, &pkey->key_eflags))
		return -ENOKEY;

	if (test_bit(KEY_EFLAG_CA, &pkey->key_eflags))
		return -ENOKEY;

	if (test_bit(KEY_EFLAG_KEYCERTSIGN, &pkey->key_eflags))
		return -ENOKEY;

	return restrict_link_by_signature(dest_keyring, type, payload,
					  trust_keyring);
}

static bool match_either_id(const struct asymmetric_key_id **pair,
			    const struct asymmetric_key_id *single)
{
+1 −2
Original line number Diff line number Diff line
@@ -251,7 +251,6 @@ static int tpm1_binary_bios_measurements_show(struct seq_file *m, void *v)

static int tpm1_ascii_bios_measurements_show(struct seq_file *m, void *v)
{
	int len = 0;
	char *eventname;
	struct tcpa_event *event = v;
	unsigned char *event_entry =
@@ -273,7 +272,7 @@ static int tpm1_ascii_bios_measurements_show(struct seq_file *m, void *v)
	/* 3rd: event type identifier */
	seq_printf(m, " %02x", do_endian_conversion(event->event_type));

	len += get_event_name(eventname, event, event_entry);
	get_event_name(eventname, event, event_entry);

	/* 4th: eventname <= max + \'0' delimiter */
	seq_printf(m, " %s\n", eventname);
+2 −91
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/kernel.h>
#include <linux/dmi.h>
#include "tpm.h"
#include "tpm_tis_core.h"

@@ -89,8 +88,8 @@ static inline void tpm_tis_iowrite32(u32 b, void __iomem *iobase, u32 addr)
	tpm_tis_flush(iobase);
}

static int interrupts;
module_param(interrupts, int, 0444);
static bool interrupts;
module_param(interrupts, bool, 0444);
MODULE_PARM_DESC(interrupts, "Enable interrupts");

static bool itpm;
@@ -103,92 +102,6 @@ module_param(force, bool, 0444);
MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
#endif

static int tpm_tis_disable_irq(const struct dmi_system_id *d)
{
	if (interrupts == -1) {
		pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d->ident);
		interrupts = 0;
	}

	return 0;
}

static const struct dmi_system_id tpm_tis_dmi_table[] = {
	{
		.callback = tpm_tis_disable_irq,
		.ident = "Framework Laptop (12th Gen Intel Core)",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Laptop (12th Gen Intel Core)"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "Framework Laptop (13th Gen Intel Core)",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Laptop (13th Gen Intel Core)"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "ThinkPad T490s",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "ThinkStation P360 Tiny",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P360 Tiny"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "ThinkPad L490",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L490"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "ThinkPad L590",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L590"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "ThinkStation P620",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P620"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "TUXEDO InfinityBook S 15/17 Gen7",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
			DMI_MATCH(DMI_PRODUCT_NAME, "TUXEDO InfinityBook S 15/17 Gen7"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "UPX-TGL",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
			DMI_MATCH(DMI_PRODUCT_NAME, "UPX-TGL01"),
		},
	},
	{}
};

#if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
static int has_hid(struct acpi_device *dev, const char *hid)
{
@@ -312,8 +225,6 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info)
	int irq = -1;
	int rc;

	dmi_check_system(tpm_tis_dmi_table);

	rc = check_acpi_tpm2(dev);
	if (rc)
		return rc;
Loading