Commit 1a0beef9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tpm updates from Jarkko Sakkinen:

 - The .machine keyring, used for Machine Owner Keys (MOK), acquired the
   ability to store only CA enforced keys, and put rest to the .platform
   keyring, thus separating the code signing keys from the keys that are
   used to sign certificates.

   This essentially unlocks the use of the .machine keyring as a trust
   anchor for IMA. It is an opt-in feature, meaning that the additional
   contraints won't brick anyone who does not care about them.

 - Enable interrupt based transactions with discrete TPM chips (tpm_tis).

   There was code for this existing but it never really worked so I
   consider this a new feature rather than a bug fix. Before the driver
   just fell back to the polling mode.

Link: https://lore.kernel.org/linux-integrity/a93b6222-edda-d43c-f010-a59701f2aeef@gmx.de/
Link: https://lore.kernel.org/linux-integrity/20230302164652.83571-1-eric.snowberg@oracle.com/

* tag 'tpmdd-v6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: (29 commits)
  tpm: Add !tpm_amd_is_rng_defective() to the hwrng_unregister() call site
  tpm_tis: fix stall after iowrite*()s
  tpm/tpm_tis_synquacer: Convert to platform remove callback returning void
  tpm/tpm_tis: Convert to platform remove callback returning void
  tpm/tpm_ftpm_tee: Convert to platform remove callback returning void
  tpm: tpm_tis_spi: Mark ACPI and OF related data as maybe unused
  tpm: st33zp24: Mark ACPI and OF related data as maybe unused
  tpm, tpm_tis: Enable interrupt test
  tpm, tpm_tis: startup chip before testing for interrupts
  tpm, tpm_tis: Claim locality when interrupts are reenabled on resume
  tpm, tpm_tis: Claim locality in interrupt handler
  tpm, tpm_tis: Request threaded interrupt handler
  tpm, tpm: Implement usage counter for locality
  tpm, tpm_tis: do not check for the active locality in interrupt handler
  tpm, tpm_tis: Move interrupt mask checks into own function
  tpm, tpm_tis: Only handle supported interrupts
  tpm, tpm_tis: Claim locality before writing interrupt registers
  tpm, tpm_tis: Do not skip reset of original interrupt vector
  tpm, tpm_tis: Disable interrupts if tpm_tis_probe_irq() failed
  tpm, tpm_tis: Claim locality before writing TPM_INT_ENABLE register
  ...
parents dc7e22a3 bd8621ca
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -33,7 +33,11 @@ extern __initconst const unsigned long system_certificate_list_size;
extern __initconst const unsigned long module_cert_size;

/**
 * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
 * restrict_link_by_builtin_trusted - Restrict keyring addition by built-in CA
 * @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.
@@ -50,7 +54,11 @@ int restrict_link_by_builtin_trusted(struct key *dest_keyring,
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
/**
 * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring
 *   addition by both builtin and secondary keyrings
 *   addition by both built-in and secondary keyrings.
 * @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
@@ -75,7 +83,7 @@ int restrict_link_by_builtin_and_secondary_trusted(
					  secondary_trusted_keys);
}

/**
/*
 * Allocate a struct key_restriction for the "builtin and secondary trust"
 * keyring. Only for use in system_trusted_keyring_init().
 */
+40 −0
Original line number Diff line number Diff line
@@ -108,6 +108,46 @@ int restrict_link_by_signature(struct key *dest_keyring,
	return ret;
}

/**
 * restrict_link_by_ca - Restrict additions to a ring of CA keys
 * @dest_keyring: Keyring being linked to.
 * @type: The type of key being added.
 * @payload: The payload of the new key.
 * @trust_keyring: Unused.
 *
 * Check if the new certificate is a CA. If it is a CA, then mark the new
 * certificate as being ok to link.
 *
 * Returns 0 if the new certificate was accepted, -ENOKEY if the
 * certificate is not a CA. -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_ca(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_CA, &pkey->key_eflags))
		return -ENOKEY;
	if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pkey->key_eflags))
		return -ENOKEY;
	if (!IS_ENABLED(CONFIG_INTEGRITY_CA_MACHINE_KEYRING_MAX))
		return 0;
	if (test_bit(KEY_EFLAG_DIGITALSIG, &pkey->key_eflags))
		return -ENOKEY;

	return 0;
}

static bool match_either_id(const struct asymmetric_key_id **pair,
			    const struct asymmetric_key_id *single)
{
+50 −0
Original line number Diff line number Diff line
@@ -579,6 +579,34 @@ int x509_process_extension(void *context, size_t hdrlen,
		return 0;
	}

	if (ctx->last_oid == OID_keyUsage) {
		/*
		 * Get hold of the keyUsage bit string
		 * v[1] is the encoding size
		 *       (Expect either 0x02 or 0x03, making it 1 or 2 bytes)
		 * v[2] is the number of unused bits in the bit string
		 *       (If >= 3 keyCertSign is missing when v[1] = 0x02)
		 * v[3] and possibly v[4] contain the bit string
		 *
		 * From RFC 5280 4.2.1.3:
		 *   0x04 is where keyCertSign lands in this bit string
		 *   0x80 is where digitalSignature lands in this bit string
		 */
		if (v[0] != ASN1_BTS)
			return -EBADMSG;
		if (vlen < 4)
			return -EBADMSG;
		if (v[2] >= 8)
			return -EBADMSG;
		if (v[3] & 0x80)
			ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_DIGITALSIG;
		if (v[1] == 0x02 && v[2] <= 2 && (v[3] & 0x04))
			ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_KEYCERTSIGN;
		else if (vlen > 4 && v[1] == 0x03 && (v[3] & 0x04))
			ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_KEYCERTSIGN;
		return 0;
	}

	if (ctx->last_oid == OID_authorityKeyIdentifier) {
		/* Get hold of the CA key fingerprint */
		ctx->raw_akid = v;
@@ -586,6 +614,28 @@ int x509_process_extension(void *context, size_t hdrlen,
		return 0;
	}

	if (ctx->last_oid == OID_basicConstraints) {
		/*
		 * Get hold of the basicConstraints
		 * v[1] is the encoding size
		 *	(Expect 0x2 or greater, making it 1 or more bytes)
		 * v[2] is the encoding type
		 *	(Expect an ASN1_BOOL for the CA)
		 * v[3] is the contents of the ASN1_BOOL
		 *      (Expect 1 if the CA is TRUE)
		 * vlen should match the entire extension size
		 */
		if (v[0] != (ASN1_CONS_BIT | ASN1_SEQ))
			return -EBADMSG;
		if (vlen < 2)
			return -EBADMSG;
		if (v[1] != vlen - 2)
			return -EBADMSG;
		if (vlen >= 4 && v[1] != 0 && v[2] == ASN1_BOOL && v[3] == 1)
			ctx->cert->pub->key_eflags |= 1 << KEY_EFLAG_CA;
		return 0;
	}

	return 0;
}

+3 −3
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ static int tpm_bios_measurements_open(struct inode *inode,
		inode_unlock(inode);
		return -ENODEV;
	}
	chip_seqops = (struct tpm_chip_seqops *)inode->i_private;
	chip_seqops = inode->i_private;
	seqops = chip_seqops->seqops;
	chip = chip_seqops->chip;
	get_device(&chip->dev);
@@ -55,8 +55,8 @@ static int tpm_bios_measurements_open(struct inode *inode,
static int tpm_bios_measurements_release(struct inode *inode,
					 struct file *file)
{
	struct seq_file *seq = (struct seq_file *)file->private_data;
	struct tpm_chip *chip = (struct tpm_chip *)seq->private;
	struct seq_file *seq = file->private_data;
	struct tpm_chip *chip = seq->private;

	put_device(&chip->dev);

+2 −2
Original line number Diff line number Diff line
@@ -138,13 +138,13 @@ static const struct i2c_device_id st33zp24_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, st33zp24_i2c_id);

static const struct of_device_id of_st33zp24_i2c_match[] = {
static const struct of_device_id of_st33zp24_i2c_match[] __maybe_unused = {
	{ .compatible = "st,st33zp24-i2c", },
	{}
};
MODULE_DEVICE_TABLE(of, of_st33zp24_i2c_match);

static const struct acpi_device_id st33zp24_i2c_acpi_match[] = {
static const struct acpi_device_id st33zp24_i2c_acpi_match[] __maybe_unused = {
	{"SMO3324"},
	{}
};
Loading