Commit 451819aa authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'tpmdd-next-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull tpm driver updates from Jarkko Sakkinen:
 "The highlights are:

   - Support for signing LKM's with ECDSA keys

   - An integer overflow bug fix in pkey"

* tag 'tpmdd-next-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
  crypto: public_key: fix overflow during implicit conversion
  tpm: ibmvtpm: Avoid error message when process gets signal while waiting
  certs: Add support for using elliptic curve keys for signing modules
  certs: Trigger creation of RSA module signing key if it's not an RSA key
  char: tpm: cr50_i2c: convert to new probe interface
  char: tpm: Kconfig: remove bad i2c cr50 select
parents 4520dcbe f985911b
...@@ -15,6 +15,32 @@ config MODULE_SIG_KEY ...@@ -15,6 +15,32 @@ config MODULE_SIG_KEY
then the kernel will automatically generate the private key and then the kernel will automatically generate the private key and
certificate as described in Documentation/admin-guide/module-signing.rst certificate as described in Documentation/admin-guide/module-signing.rst
choice
prompt "Type of module signing key to be generated"
default MODULE_SIG_KEY_TYPE_RSA
help
The type of module signing key type to generate. This option
does not apply if a #PKCS11 URI is used.
config MODULE_SIG_KEY_TYPE_RSA
bool "RSA"
depends on MODULE_SIG || (IMA_APPRAISE_MODSIG && MODULES)
help
Use an RSA key for module signing.
config MODULE_SIG_KEY_TYPE_ECDSA
bool "ECDSA"
select CRYPTO_ECDSA
depends on MODULE_SIG || (IMA_APPRAISE_MODSIG && MODULES)
help
Use an elliptic curve key (NIST P384) for module signing. Consider
using a strong hash like sha256 or sha384 for hashing modules.
Note: Remove all ECDSA signing keys, e.g. certs/signing_key.pem,
when falling back to building Linux 5.14 and older kernels.
endchoice
config SYSTEM_TRUSTED_KEYRING config SYSTEM_TRUSTED_KEYRING
bool "Provide system-wide ring of trusted keys" bool "Provide system-wide ring of trusted keys"
depends on KEYS depends on KEYS
......
...@@ -57,11 +57,31 @@ endif ...@@ -57,11 +57,31 @@ endif
redirect_openssl = 2>&1 redirect_openssl = 2>&1
quiet_redirect_openssl = 2>&1 quiet_redirect_openssl = 2>&1
silent_redirect_openssl = 2>/dev/null silent_redirect_openssl = 2>/dev/null
openssl_available = $(shell openssl help 2>/dev/null && echo yes)
# We do it this way rather than having a boolean option for enabling an # We do it this way rather than having a boolean option for enabling an
# external private key, because 'make randconfig' might enable such a # external private key, because 'make randconfig' might enable such a
# boolean option and we unfortunately can't make it depend on !RANDCONFIG. # boolean option and we unfortunately can't make it depend on !RANDCONFIG.
ifeq ($(CONFIG_MODULE_SIG_KEY),"certs/signing_key.pem") ifeq ($(CONFIG_MODULE_SIG_KEY),"certs/signing_key.pem")
ifeq ($(openssl_available),yes)
X509TEXT=$(shell openssl x509 -in "certs/signing_key.pem" -text 2>/dev/null)
endif
# Support user changing key type
ifdef CONFIG_MODULE_SIG_KEY_TYPE_ECDSA
keytype_openssl = -newkey ec -pkeyopt ec_paramgen_curve:secp384r1
ifeq ($(openssl_available),yes)
$(if $(findstring id-ecPublicKey,$(X509TEXT)),,$(shell rm -f "certs/signing_key.pem"))
endif
endif # CONFIG_MODULE_SIG_KEY_TYPE_ECDSA
ifdef CONFIG_MODULE_SIG_KEY_TYPE_RSA
ifeq ($(openssl_available),yes)
$(if $(findstring rsaEncryption,$(X509TEXT)),,$(shell rm -f "certs/signing_key.pem"))
endif
endif # CONFIG_MODULE_SIG_KEY_TYPE_RSA
$(obj)/signing_key.pem: $(obj)/x509.genkey $(obj)/signing_key.pem: $(obj)/x509.genkey
@$(kecho) "###" @$(kecho) "###"
@$(kecho) "### Now generating an X.509 key pair to be used for signing modules." @$(kecho) "### Now generating an X.509 key pair to be used for signing modules."
...@@ -75,6 +95,7 @@ $(obj)/signing_key.pem: $(obj)/x509.genkey ...@@ -75,6 +95,7 @@ $(obj)/signing_key.pem: $(obj)/x509.genkey
-batch -x509 -config $(obj)/x509.genkey \ -batch -x509 -config $(obj)/x509.genkey \
-outform PEM -out $(obj)/signing_key.pem \ -outform PEM -out $(obj)/signing_key.pem \
-keyout $(obj)/signing_key.pem \ -keyout $(obj)/signing_key.pem \
$(keytype_openssl) \
$($(quiet)redirect_openssl) $($(quiet)redirect_openssl)
@$(kecho) "###" @$(kecho) "###"
@$(kecho) "### Key pair generated." @$(kecho) "### Key pair generated."
......
...@@ -269,6 +269,14 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen, ...@@ -269,6 +269,14 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
ctx->sinfo->sig->pkey_algo = "rsa"; ctx->sinfo->sig->pkey_algo = "rsa";
ctx->sinfo->sig->encoding = "pkcs1"; ctx->sinfo->sig->encoding = "pkcs1";
break; break;
case OID_id_ecdsa_with_sha1:
case OID_id_ecdsa_with_sha224:
case OID_id_ecdsa_with_sha256:
case OID_id_ecdsa_with_sha384:
case OID_id_ecdsa_with_sha512:
ctx->sinfo->sig->pkey_algo = "ecdsa";
ctx->sinfo->sig->encoding = "x962";
break;
default: default:
printk("Unsupported pkey algo: %u\n", ctx->last_oid); printk("Unsupported pkey algo: %u\n", ctx->last_oid);
return -ENOPKG; return -ENOPKG;
......
...@@ -89,7 +89,6 @@ config TCG_TIS_SYNQUACER ...@@ -89,7 +89,6 @@ config TCG_TIS_SYNQUACER
config TCG_TIS_I2C_CR50 config TCG_TIS_I2C_CR50
tristate "TPM Interface Specification 2.0 Interface (I2C - CR50)" tristate "TPM Interface Specification 2.0 Interface (I2C - CR50)"
depends on I2C depends on I2C
select TCG_CR50
help help
This is a driver for the Google cr50 I2C TPM interface which is a This is a driver for the Google cr50 I2C TPM interface which is a
custom microcontroller and requires a custom i2c protocol interface custom microcontroller and requires a custom i2c protocol interface
......
...@@ -106,17 +106,12 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -106,17 +106,12 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{ {
struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
u16 len; u16 len;
int sig;
if (!ibmvtpm->rtce_buf) { if (!ibmvtpm->rtce_buf) {
dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n"); dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n");
return 0; return 0;
} }
sig = wait_event_interruptible(ibmvtpm->wq, !ibmvtpm->tpm_processing_cmd);
if (sig)
return -EINTR;
len = ibmvtpm->res_len; len = ibmvtpm->res_len;
if (count < len) { if (count < len) {
...@@ -237,7 +232,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -237,7 +232,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
* set the processing flag before the Hcall, since we may get the * set the processing flag before the Hcall, since we may get the
* result (interrupt) before even being able to check rc. * result (interrupt) before even being able to check rc.
*/ */
ibmvtpm->tpm_processing_cmd = true; ibmvtpm->tpm_processing_cmd = 1;
again: again:
rc = ibmvtpm_send_crq(ibmvtpm->vdev, rc = ibmvtpm_send_crq(ibmvtpm->vdev,
...@@ -255,7 +250,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -255,7 +250,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
goto again; goto again;
} }
dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
ibmvtpm->tpm_processing_cmd = false; ibmvtpm->tpm_processing_cmd = 0;
} }
spin_unlock(&ibmvtpm->rtce_lock); spin_unlock(&ibmvtpm->rtce_lock);
...@@ -269,7 +264,9 @@ static void tpm_ibmvtpm_cancel(struct tpm_chip *chip) ...@@ -269,7 +264,9 @@ static void tpm_ibmvtpm_cancel(struct tpm_chip *chip)
static u8 tpm_ibmvtpm_status(struct tpm_chip *chip) static u8 tpm_ibmvtpm_status(struct tpm_chip *chip)
{ {
return 0; struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
return ibmvtpm->tpm_processing_cmd;
} }
/** /**
...@@ -457,7 +454,7 @@ static const struct tpm_class_ops tpm_ibmvtpm = { ...@@ -457,7 +454,7 @@ static const struct tpm_class_ops tpm_ibmvtpm = {
.send = tpm_ibmvtpm_send, .send = tpm_ibmvtpm_send,
.cancel = tpm_ibmvtpm_cancel, .cancel = tpm_ibmvtpm_cancel,
.status = tpm_ibmvtpm_status, .status = tpm_ibmvtpm_status,
.req_complete_mask = 0, .req_complete_mask = 1,
.req_complete_val = 0, .req_complete_val = 0,
.req_canceled = tpm_ibmvtpm_req_canceled, .req_canceled = tpm_ibmvtpm_req_canceled,
}; };
...@@ -550,7 +547,7 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, ...@@ -550,7 +547,7 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
case VTPM_TPM_COMMAND_RES: case VTPM_TPM_COMMAND_RES:
/* len of the data in rtce buffer */ /* len of the data in rtce buffer */
ibmvtpm->res_len = be16_to_cpu(crq->len); ibmvtpm->res_len = be16_to_cpu(crq->len);
ibmvtpm->tpm_processing_cmd = false; ibmvtpm->tpm_processing_cmd = 0;
wake_up_interruptible(&ibmvtpm->wq); wake_up_interruptible(&ibmvtpm->wq);
return; return;
default: default:
...@@ -688,8 +685,15 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, ...@@ -688,8 +685,15 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
goto init_irq_cleanup; goto init_irq_cleanup;
} }
if (!strcmp(id->compat, "IBM,vtpm20")) {
if (!strcmp(id->compat, "IBM,vtpm20"))
chip->flags |= TPM_CHIP_FLAG_TPM2; chip->flags |= TPM_CHIP_FLAG_TPM2;
rc = tpm_get_timeouts(chip);
if (rc)
goto init_irq_cleanup;
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
rc = tpm2_get_cc_attrs_tbl(chip); rc = tpm2_get_cc_attrs_tbl(chip);
if (rc) if (rc)
goto init_irq_cleanup; goto init_irq_cleanup;
......
...@@ -41,7 +41,7 @@ struct ibmvtpm_dev { ...@@ -41,7 +41,7 @@ struct ibmvtpm_dev {
wait_queue_head_t wq; wait_queue_head_t wq;
u16 res_len; u16 res_len;
u32 vtpm_version; u32 vtpm_version;
bool tpm_processing_cmd; u8 tpm_processing_cmd;
}; };
#define CRQ_RES_BUF_SIZE PAGE_SIZE #define CRQ_RES_BUF_SIZE PAGE_SIZE
......
...@@ -639,12 +639,6 @@ static const struct tpm_class_ops cr50_i2c = { ...@@ -639,12 +639,6 @@ static const struct tpm_class_ops cr50_i2c = {
.req_canceled = &tpm_cr50_i2c_req_canceled, .req_canceled = &tpm_cr50_i2c_req_canceled,
}; };
static const struct i2c_device_id cr50_i2c_table[] = {
{"cr50_i2c", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, cr50_i2c_table);
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static const struct acpi_device_id cr50_i2c_acpi_id[] = { static const struct acpi_device_id cr50_i2c_acpi_id[] = {
{ "GOOG0005", 0 }, { "GOOG0005", 0 },
...@@ -670,8 +664,7 @@ MODULE_DEVICE_TABLE(of, of_cr50_i2c_match); ...@@ -670,8 +664,7 @@ MODULE_DEVICE_TABLE(of, of_cr50_i2c_match);
* - 0: Success. * - 0: Success.
* - -errno: A POSIX error code. * - -errno: A POSIX error code.
*/ */
static int tpm_cr50_i2c_probe(struct i2c_client *client, static int tpm_cr50_i2c_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
struct tpm_i2c_cr50_priv_data *priv; struct tpm_i2c_cr50_priv_data *priv;
struct device *dev = &client->dev; struct device *dev = &client->dev;
...@@ -774,8 +767,7 @@ static int tpm_cr50_i2c_remove(struct i2c_client *client) ...@@ -774,8 +767,7 @@ static int tpm_cr50_i2c_remove(struct i2c_client *client)
static SIMPLE_DEV_PM_OPS(cr50_i2c_pm, tpm_pm_suspend, tpm_pm_resume); static SIMPLE_DEV_PM_OPS(cr50_i2c_pm, tpm_pm_suspend, tpm_pm_resume);
static struct i2c_driver cr50_i2c_driver = { static struct i2c_driver cr50_i2c_driver = {
.id_table = cr50_i2c_table, .probe_new = tpm_cr50_i2c_probe,
.probe = tpm_cr50_i2c_probe,
.remove = tpm_cr50_i2c_remove, .remove = tpm_cr50_i2c_remove,
.driver = { .driver = {
.name = "cr50_i2c", .name = "cr50_i2c",
......
...@@ -38,9 +38,9 @@ extern void public_key_free(struct public_key *key); ...@@ -38,9 +38,9 @@ extern void public_key_free(struct public_key *key);
struct public_key_signature { struct public_key_signature {
struct asymmetric_key_id *auth_ids[2]; struct asymmetric_key_id *auth_ids[2];
u8 *s; /* Signature */ u8 *s; /* Signature */
u32 s_size; /* Number of bytes in signature */
u8 *digest; u8 *digest;
u8 digest_size; /* Number of bytes in digest */ u32 s_size; /* Number of bytes in signature */
u32 digest_size; /* Number of bytes in digest */
const char *pkey_algo; const char *pkey_algo;
const char *hash_algo; const char *hash_algo;
const char *encoding; const char *encoding;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment