diff mbox series

[v2,6/6] KEYS: trusted: Introduce support for NXP CAAM-based trusted keys

Message ID 39e6d65ca5d2a0a35fb71d6c1f85add8ee489a19.1624364386.git-series.a.fatoum@pengutronix.de (mailing list archive)
State New
Headers show
Series KEYS: trusted: Introduce support for NXP CAAM-based trusted keys | expand

Commit Message

Ahmad Fatoum June 22, 2021, 12:37 p.m. UTC
The Cryptographic Acceleration and Assurance Module (CAAM) is an IP core
built into many newer i.MX and QorIQ SoCs by NXP.

The CAAM does crypto acceleration, hardware number generation and
has a blob mechanism for encapsulation/decapsulation of sensitive material.

This blob mechanism depends on a device specific random 256-bit One Time
Programmable Master Key that is fused in each SoC at manufacturing
time. This key is unreadable and can only be used by the CAAM for AES
encryption/decryption of user data.

This makes it a suitable backend (source) for kernel trusted keys.

Previous commits generalized trusted keys to support multiple backends
and added an API to access the CAAM blob mechanism. Based on these,
provide the necessary glue to use the CAAM for trusted keys.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
To: Jonathan Corbet <corbet@lwn.net>
To: David Howells <dhowells@redhat.com>
To: Jarkko Sakkinen <jarkko@kernel.org>
To: James Bottomley <jejb@linux.ibm.com>
To: Mimi Zohar <zohar@linux.ibm.com>
Cc: James Morris <jmorris@namei.org>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: "Horia Geantă" <horia.geanta@nxp.com>
Cc: Aymen Sghaier <aymen.sghaier@nxp.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Udit Agarwal <udit.agarwal@nxp.com>
Cc: Eric Biggers <ebiggers@kernel.org>
Cc: Jan Luebbe <j.luebbe@pengutronix.de>
Cc: David Gstir <david@sigma-star.at>
Cc: Richard Weinberger <richard@nod.at>
Cc: Franck LENORMAND <franck.lenormand@nxp.com>
Cc: Sumit Garg <sumit.garg@linaro.org>
Cc: keyrings@vger.kernel.org
Cc: linux-crypto@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-integrity@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-security-module@vger.kernel.org
---
 Documentation/admin-guide/kernel-parameters.txt   |  1 +-
 Documentation/security/keys/trusted-encrypted.rst | 42 ++++++++-
 include/keys/trusted_caam.h                       | 11 ++-
 security/keys/trusted-keys/Kconfig                | 11 +-
 security/keys/trusted-keys/Makefile               |  2 +-
 security/keys/trusted-keys/trusted_caam.c         | 74 ++++++++++++++++-
 security/keys/trusted-keys/trusted_core.c         |  6 +-
 7 files changed, 143 insertions(+), 4 deletions(-)
 create mode 100644 include/keys/trusted_caam.h
 create mode 100644 security/keys/trusted-keys/trusted_caam.c

Comments

Richard Weinberger July 1, 2021, 8:42 p.m. UTC | #1
Ahmad,

----- Ursprüngliche Mail -----
> Von: "Ahmad Fatoum" <a.fatoum@pengutronix.de>
> +static struct caam_blob_priv *blobifier;
> +
> +#define KEYMOD "kernel:trusted"

I'm still think that hard coding the key modifier is not wise.
As I said[0], there are folks out there that want to provide their own modifier,
so it is not only about being binary compatible with other CAAM blob patches in the wild.

I'll happily implement that feature after your patches got merged but IMHO we should first agree on an interface.
How about allowing another optional parameter to Opt_new and Opt_load and having a key modifier
per struct trusted_key_payload instance?

Thanks,
//richard

[0]
https://patchwork.kernel.org/project/linux-crypto/patch/319e558e1bd19b80ad6447c167a2c3942bdafea2.1615914058.git-series.a.fatoum@pengutronix.de/#24085397
Ahmad Fatoum July 2, 2021, 8 a.m. UTC | #2
Hello Richard,

On 01.07.21 22:42, Richard Weinberger wrote:
> Ahmad,
> 
> ----- Ursprüngliche Mail -----
>> Von: "Ahmad Fatoum" <a.fatoum@pengutronix.de>
>> +static struct caam_blob_priv *blobifier;
>> +
>> +#define KEYMOD "kernel:trusted"
> 
> I'm still think that hard coding the key modifier is not wise.
> As I said[0], there are folks out there that want to provide their own modifier,
> so it is not only about being binary compatible with other CAAM blob patches in the wild.

I don't think the characterization as a salt is accurate. AFAIU it's more
of a namespace, so blobs being loaded are "type-checked" against the modifier.

> I'll happily implement that feature after your patches got merged but IMHO we should first agree on an interface.
> How about allowing another optional parameter to Opt_new and Opt_load

Sound good to me. pcrlock for TPM trusted keys has the same interface.

I'd prefer the new option to accept strings, not hex though.


> and having a key modifier per struct trusted_key_payload instance?

Ye, possibly a void *backend_data, which other trust sources could leverage
as well. But that should be separate discussion.


Cheers,
Ahmad

> 
> Thanks,
> //richard
> 
> [0]
> https://patchwork.kernel.org/project/linux-crypto/patch/319e558e1bd19b80ad6447c167a2c3942bdafea2.1615914058.git-series.a.fatoum@pengutronix.de/#24085397
> 
>
Richard Weinberger July 2, 2021, 10:53 a.m. UTC | #3
Ahmad,

----- Ursprüngliche Mail -----
> Von: "Ahmad Fatoum" <a.fatoum@pengutronix.de>
>> I'm still think that hard coding the key modifier is not wise.
>> As I said[0], there are folks out there that want to provide their own modifier,
>> so it is not only about being binary compatible with other CAAM blob patches in
>> the wild.
> 
> I don't think the characterization as a salt is accurate. AFAIU it's more
> of a namespace, so blobs being loaded are "type-checked" against the modifier.

Well, the CAAM programmer's reference manual states that the blob key is a 128 bit modifier
and has two purposes:
1. It can be used as tag to provide separation between blobs to detect accidental replacement of blobs.
2. But it can also be treated as secret to provide additional protection. Because the blob encryption
key derivation includes the key modifier.

While you have case 1 in mind, I care about case 2. :-)
 
>> I'll happily implement that feature after your patches got merged but IMHO we
>> should first agree on an interface.
>> How about allowing another optional parameter to Opt_new and Opt_load
> 
> Sound good to me. pcrlock for TPM trusted keys has the same interface.
> 
> I'd prefer the new option to accept strings, not hex though.

Both is possible. If the string starts with "0x" it needs to be decoded to a
128 bit key. Otherwise it has to be a up to 16 byte string.

Thanks,
//richard
Ahmad Fatoum July 2, 2021, 12:33 p.m. UTC | #4
On 02.07.21 12:53, Richard Weinberger wrote:
> Ahmad,
> 
> ----- Ursprüngliche Mail -----
>> Von: "Ahmad Fatoum" <a.fatoum@pengutronix.de>
>>> I'm still think that hard coding the key modifier is not wise.
>>> As I said[0], there are folks out there that want to provide their own modifier,
>>> so it is not only about being binary compatible with other CAAM blob patches in
>>> the wild.
>>
>> I don't think the characterization as a salt is accurate. AFAIU it's more
>> of a namespace, so blobs being loaded are "type-checked" against the modifier.
> 
> Well, the CAAM programmer's reference manual states that the blob key is a 128 bit modifier
> and has two purposes:
> 1. It can be used as tag to provide separation between blobs to detect accidental replacement of blobs.
> 2. But it can also be treated as secret to provide additional protection. Because the blob encryption
> key derivation includes the key modifier.
> 
> While you have case 1 in mind, I care about case 2. :-)

Ah, using the key modifier as a passphrase didn't occur to me.

>>> I'll happily implement that feature after your patches got merged but IMHO we
>>> should first agree on an interface.
>>> How about allowing another optional parameter to Opt_new and Opt_load
>>
>> Sound good to me. pcrlock for TPM trusted keys has the same interface.
>>
>> I'd prefer the new option to accept strings, not hex though.
> 
> Both is possible. If the string starts with "0x" it needs to be decoded to a
> 128 bit key. Otherwise it has to be a up to 16 byte string.

Fine by me. Looking forward to your patches. :-)


Cheers,
Ahmad

> 
> Thanks,
> //richard
>
Richard Weinberger July 20, 2021, 7:19 p.m. UTC | #5
On Fri, Jul 2, 2021 at 2:37 PM Ahmad Fatoum <a.fatoum@pengutronix.de> wrote:
> > Both is possible. If the string starts with "0x" it needs to be decoded to a
> > 128 bit key. Otherwise it has to be a up to 16 byte string.
>
> Fine by me. Looking forward to your patches. :-)

I'm not sure how to proceed.  Should I base my changes on this series
or do you plan to send an updated
version soon?
Maybe it makes also sense to base my DCP patch set on yours.

Trusted Keys maintainers, what do you prefer?
Mimi Zohar July 20, 2021, 8:24 p.m. UTC | #6
HI -

On Tue, 2021-07-20 at 21:19 +0200, Richard Weinberger wrote:
> On Fri, Jul 2, 2021 at 2:37 PM Ahmad Fatoum <a.fatoum@pengutronix.de> wrote:
> > > Both is possible. If the string starts with "0x" it needs to be decoded to a
> > > 128 bit key. Otherwise it has to be a up to 16 byte string.
> >
> > Fine by me. Looking forward to your patches. :-)
> 
> I'm not sure how to proceed.  Should I base my changes on this series
> or do you plan to send an updated
> version soon?
> Maybe it makes also sense to base my DCP patch set on yours.
> 
> Trusted Keys maintainers, what do you prefer?

Jarkko sent an email saying he is on vacation for 2 weeks.   James was
on vacation as well.   If there is something that needs immediate
attention, please let me know.

thanks,

Mimi
Richard Weinberger July 20, 2021, 8:37 p.m. UTC | #7
On Tue, Jul 20, 2021 at 10:24 PM Mimi Zohar <zohar@linux.ibm.com> wrote:
> > I'm not sure how to proceed.  Should I base my changes on this series
> > or do you plan to send an updated
> > version soon?
> > Maybe it makes also sense to base my DCP patch set on yours.
> >
> > Trusted Keys maintainers, what do you prefer?
>
> Jarkko sent an email saying he is on vacation for 2 weeks.   James was
> on vacation as well.   If there is something that needs immediate
> attention, please let me know.

Oh, let them enjoy their well deserved vacation.
There no need to hurry. :-)
Ahmad Fatoum July 21, 2021, 5:02 p.m. UTC | #8
Hi,

On 20.07.21 21:19, Richard Weinberger wrote:
> On Fri, Jul 2, 2021 at 2:37 PM Ahmad Fatoum <a.fatoum@pengutronix.de> wrote:
>>> Both is possible. If the string starts with "0x" it needs to be decoded to a
>>> 128 bit key. Otherwise it has to be a up to 16 byte string.
>>
>> Fine by me. Looking forward to your patches. :-)
> 
> I'm not sure how to proceed.  Should I base my changes on this series
> or do you plan to send an updated
> version soon?
> Maybe it makes also sense to base my DCP patch set on yours.
> 
> Trusted Keys maintainers, what do you prefer?

I sent out v3 despite the name (of course forgot that git-send-email -vX is silently
dropped when sending patch files directly..):

https://lore.kernel.org/linux-integrity/cover.9fc9298fd9d63553491871d043a18affc2dbc8a8.1626885907.git-series.a.fatoum@pengutronix.de/T/#t

I'd advise you base your changes on the first two patches there as well as the Kconfig fix/enhancement
I sent out separately:
https://lore.kernel.org/linux-integrity/20210721160258.7024-1-a.fatoum@pengutronix.de/T/#u

Those are relevant for you as well and I assume they should be good to be merged even if the
CAAM series turns out to need some more love.

Cheers,
Ahmad
diff mbox series

Patch

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f8bdc898c354..4a95369c2bc7 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5639,6 +5639,7 @@ 
 			sources:
 			- "tpm"
 			- "tee"
+			- "caam"
 			If not specified then it defaults to iterating through
 			the trust source list starting with TPM and assigns the
 			first trust source as a backend which is initialized
diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst
index 3fb5562ee937..3461746b1fbd 100644
--- a/Documentation/security/keys/trusted-encrypted.rst
+++ b/Documentation/security/keys/trusted-encrypted.rst
@@ -35,6 +35,13 @@  safe.
          Rooted to Hardware Unique Key (HUK) which is generally burnt in on-chip
          fuses and is accessible to TEE only.
 
+     (3) CAAM (Cryptographic Acceleration and Assurance Module: IP on NXP SoCs)
+
+         When High Assurance Boot (HAB) is enabled and the CAAM is in secure
+         mode, trust is rooted to the OTPMK, a never-disclosed 256-bit key
+         randomly generated and fused into each SoC at manufacturing time.
+         Otherwise, a common fixed test key is used instead.
+
   *  Execution isolation
 
      (1) TPM
@@ -46,6 +53,10 @@  safe.
          Customizable set of operations running in isolated execution
          environment verified via Secure/Trusted boot process.
 
+     (3) CAAM
+
+         Fixed set of operations running in isolated execution environment.
+
   * Optional binding to platform integrity state
 
      (1) TPM
@@ -63,6 +74,11 @@  safe.
          Relies on Secure/Trusted boot process for platform integrity. It can
          be extended with TEE based measured boot process.
 
+     (3) CAAM
+
+         Relies on the High Assurance Boot (HAB) mechanism of NXP SoCs
+         for platform integrity.
+
   *  Interfaces and APIs
 
      (1) TPM
@@ -74,10 +90,13 @@  safe.
          TEEs have well-documented, standardized client interface and APIs. For
          more details refer to ``Documentation/staging/tee.rst``.
 
+     (3) CAAM
+
+         Interface is specific to silicon vendor.
 
   *  Threat model
 
-     The strength and appropriateness of a particular TPM or TEE for a given
+     The strength and appropriateness of a particular trust source for a given
      purpose must be assessed when using them to protect security-relevant data.
 
 
@@ -104,8 +123,14 @@  selected trust source:
      from platform specific hardware RNG or a software based Fortuna CSPRNG
      which can be seeded via multiple entropy sources.
 
+  *  CAAM: Kernel RNG
+
+     The normal kernel random number generator is used. To seed it from the
+     CAAM HWRNG, enable CRYPTO_DEV_FSL_CAAM_RNG_API and ensure the device
+     can be probed.
+
 Optionally, users may specify ``trusted.kernel_rng=1`` on the kernel
-command-line to override the used RNG with the kernel's random number pool.
+command-line to force use of the kernel's random number pool.
 
 Encrypted Keys
 --------------
@@ -192,6 +217,19 @@  Usage::
 specific to TEE device implementation.  The key length for new keys is always
 in bytes. Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).
 
+Trusted Keys usage: CAAM
+------------------------
+
+Usage::
+
+    keyctl add trusted name "new keylen" ring
+    keyctl add trusted name "load hex_blob" ring
+    keyctl print keyid
+
+"keyctl print" returns an ASCII hex copy of the sealed key, which is in format
+specific to CAAM device implementation.  The key length for new keys is always
+in bytes. Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).
+
 Trusted Keys: import plain-text key for development
 ---------------------------------------------------
 
diff --git a/include/keys/trusted_caam.h b/include/keys/trusted_caam.h
new file mode 100644
index 000000000000..2fba0996b0b0
--- /dev/null
+++ b/include/keys/trusted_caam.h
@@ -0,0 +1,11 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
+ */
+
+#ifndef __CAAM_TRUSTED_KEY_H
+#define __CAAM_TRUSTED_KEY_H
+
+extern struct trusted_key_ops caam_trusted_key_ops;
+
+#endif
diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig
index 8bd69b252bf9..641bed8923ec 100644
--- a/security/keys/trusted-keys/Kconfig
+++ b/security/keys/trusted-keys/Kconfig
@@ -20,7 +20,16 @@  config TRUSTED_KEYS_TEE
 	  Enable use of the Trusted Execution Environment (TEE) as trusted
 	  key backend.
 
-if !TRUSTED_KEYS_TPM && !TRUSTED_KEYS_TEE
+config TRUSTED_KEYS_CAAM
+	bool "CAAM-based trusted keys"
+	depends on CRYPTO_DEV_FSL_CAAM_JR >= TRUSTED_KEYS
+	select CRYPTO_DEV_FSL_CAAM_BLOB_GEN
+	default y
+	help
+	  Enable use of NXP's Cryptographic Accelerator and Assurance Module
+	  (CAAM) as trusted key backend.
+
+if !TRUSTED_KEYS_TPM && !TRUSTED_KEYS_TEE && !TRUSTED_KEYS_CAAM
 comment "No trust source selected!"
 endif
 
diff --git a/security/keys/trusted-keys/Makefile b/security/keys/trusted-keys/Makefile
index 96fc6c377398..5788bc07a2ab 100644
--- a/security/keys/trusted-keys/Makefile
+++ b/security/keys/trusted-keys/Makefile
@@ -14,3 +14,5 @@  trusted-$(CONFIG_TRUSTED_KEYS_TPM) += tpm2key.asn1.o
 trusted-$(CONFIG_TRUSTED_KEYS_TEE) += trusted_tee.o
 
 trusted-$(CONFIG_TEE) += trusted_tee.o
+
+trusted-$(CONFIG_TRUSTED_KEYS_CAAM) += trusted_caam.o
diff --git a/security/keys/trusted-keys/trusted_caam.c b/security/keys/trusted-keys/trusted_caam.c
new file mode 100644
index 000000000000..01adfd18adda
--- /dev/null
+++ b/security/keys/trusted-keys/trusted_caam.c
@@ -0,0 +1,74 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
+ */
+
+#include <keys/trusted_caam.h>
+#include <keys/trusted-type.h>
+#include <linux/build_bug.h>
+#include <linux/key-type.h>
+#include <soc/fsl/caam-blob.h>
+
+static struct caam_blob_priv *blobifier;
+
+#define KEYMOD "kernel:trusted"
+
+static_assert(MAX_KEY_SIZE + CAAM_BLOB_OVERHEAD <= CAAM_BLOB_MAX_LEN);
+static_assert(MAX_BLOB_SIZE <= CAAM_BLOB_MAX_LEN);
+
+static int trusted_caam_seal(struct trusted_key_payload *p, char *datablob)
+{
+	int length = p->key_len + CAAM_BLOB_OVERHEAD;
+	int ret;
+
+	ret = caam_encap_blob(blobifier, KEYMOD, p->key, p->blob, length);
+	if (ret)
+		return ret;
+
+	p->blob_len = length;
+	return 0;
+}
+
+static int trusted_caam_unseal(struct trusted_key_payload *p, char *datablob)
+{
+	int length = p->blob_len;
+	int ret;
+
+	ret = caam_decap_blob(blobifier, KEYMOD, p->blob, p->key, length);
+	if (ret)
+		return ret;
+
+	p->key_len = length - CAAM_BLOB_OVERHEAD;
+	return 0;
+}
+
+static int trusted_caam_init(void)
+{
+	int ret;
+
+	blobifier = caam_blob_gen_init();
+	if (IS_ERR(blobifier)) {
+		pr_err("Job Ring Device allocation for transform failed\n");
+		return PTR_ERR(blobifier);
+	}
+
+	ret = register_key_type(&key_type_trusted);
+	if (ret)
+		caam_blob_gen_exit(blobifier);
+
+	return ret;
+}
+
+static void trusted_caam_exit(void)
+{
+	unregister_key_type(&key_type_trusted);
+	caam_blob_gen_exit(blobifier);
+}
+
+struct trusted_key_ops caam_trusted_key_ops = {
+	.migratable = 0, /* non-migratable */
+	.init = trusted_caam_init,
+	.seal = trusted_caam_seal,
+	.unseal = trusted_caam_unseal,
+	.exit = trusted_caam_exit,
+};
diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
index 8d829e6866ca..21997a5debde 100644
--- a/security/keys/trusted-keys/trusted_core.c
+++ b/security/keys/trusted-keys/trusted_core.c
@@ -9,6 +9,7 @@ 
 #include <keys/user-type.h>
 #include <keys/trusted-type.h>
 #include <keys/trusted_tee.h>
+#include <keys/trusted_caam.h>
 #include <keys/trusted_tpm.h>
 #include <linux/capability.h>
 #include <linux/err.h>
@@ -29,7 +30,7 @@  MODULE_PARM_DESC(kernel_rng, "Generate key material from kernel RNG");
 
 static char *trusted_key_source;
 module_param_named(source, trusted_key_source, charp, 0);
-MODULE_PARM_DESC(source, "Select trusted keys source (tpm or tee)");
+MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee or caam)");
 
 static const struct trusted_key_source trusted_key_sources[] = {
 #if defined(CONFIG_TRUSTED_KEYS_TPM)
@@ -38,6 +39,9 @@  static const struct trusted_key_source trusted_key_sources[] = {
 #if defined(CONFIG_TRUSTED_KEYS_TEE)
 	{ "tee", &trusted_key_tee_ops },
 #endif
+#if defined(CONFIG_TRUSTED_KEYS_CAAM)
+	{ "caam", &caam_trusted_key_ops },
+#endif
 };
 
 DEFINE_STATIC_CALL_NULL(trusted_key_init, *trusted_key_sources[0].ops->init);