2021-07-21 16:50:29

by Ahmad Fatoum

[permalink] [raw]
Subject: [PATCH 0/4] KEYS: trusted: Introduce support for NXP CAAM-based trusted keys

Series applies on top of
https://lore.kernel.org/linux-integrity/[email protected]/T/#u

v2 -> v3:
- Split off first Kconfig preparation patch. It fixes a regression,
so sent that out, so it can be applied separately (Sumit)
- Split off second key import patch. I'll send that out separately
as it's a development aid and not required within the CAAM series
- add MAINTAINERS entry

v1 -> v2:
- Added new commit to make trusted key Kconfig option independent
of TPM and added new Kconfig file for trusted keys
- Add new commit for importing existing key material
- Allow users to force use of kernel RNG (Jarkko)
- Enforce maximum keymod size (Horia)
- Use append_seq_(in|out)_ptr_intlen instead of append_seq_(in|out)_ptr
(Horia)
- Make blobifier handle private to CAAM glue code file (Horia)
- Extend trusted keys documentation for CAAM
- Rebased and updated original cover letter:

The Cryptographic Acceleration and Assurance Module (CAAM) is an IP core
built into many newer i.MX and QorIQ SoCs by NXP.

Its blob mechanism can AES encrypt/decrypt user data using a unique
never-disclosed device-specific key.

There has been multiple discussions on how to represent this within the kernel:

The Cryptographic Acceleration and Assurance Module (CAAM) is an IP core
built into many newer i.MX and QorIQ SoCs by NXP.

Its blob mechanism can AES encrypt/decrypt user data using a unique
never-disclosed device-specific key. There has been multiple
discussions on how to represent this within the kernel:

- [RFC] crypto: caam - add red blobifier
Steffen implemented[1] a PoC sysfs driver to start a discussion on how to
best integrate the blob mechanism.
Mimi suggested that it could be used to implement trusted keys.
Trusted keys back then were a TPM-only feature.

- security/keys/secure_key: Adds the secure key support based on CAAM.
Udit added[2] a new "secure" key type with the CAAM as backend. The key
material stays within the kernel only.
Mimi and James agreed that this needs a generic interface, not specific
to CAAM. Mimi suggested trusted keys. Jan noted that this could serve as
basis for TEE-backed keys.

- [RFC] drivers: crypto: caam: key: Add caam_tk key type
Franck added[3] a new "caam_tk" key type based on Udit's work. This time
it uses CAAM "black blobs" instead of "red blobs", so key material stays
within the CAAM and isn't exposed to kernel in plaintext.
James voiced the opinion that there should be just one user-facing generic
wrap/unwrap key type with multiple possible handlers.
David suggested trusted keys.

- Introduce TEE based Trusted Keys support
Sumit reworked[4] trusted keys to support multiple possible backends with
one chosen at boot time and added a new TEE backend along with TPM.
This now sits in Jarkko's master branch to be sent out for v5.13

This patch series builds on top of Sumit's rework to have the CAAM as yet another
trusted key backend.

The CAAM bits are based on Steffen's initial patch from 2015. His work had been
used in the field for some years now, so I preferred not to deviate too much from it.

This series has been tested with dmcrypt[5] on an i.MX6DL.

Looking forward to your feedback.

Cheers,
Ahmad

[1]: https://lore.kernel.org/linux-crypto/[email protected]/
[2]: https://lore.kernel.org/linux-integrity/[email protected]/
[3]: https://lore.kernel.org/lkml/[email protected]/
[4]: https://lore.kernel.org/lkml/[email protected]/
[5]: https://lore.kernel.org/linux-integrity/[email protected]/

---
To: Jarkko Sakkinen <[email protected]>
To: "Horia Geantă" <[email protected]>
To: Mimi Zohar <[email protected]>
To: Aymen Sghaier <[email protected]>
To: Herbert Xu <[email protected]>
To: "David S. Miller" <[email protected]>
To: James Bottomley <[email protected]>
Cc: David Howells <[email protected]>
Cc: James Morris <[email protected]>
Cc: "Serge E. Hallyn" <[email protected]>
Cc: Steffen Trumtrar <[email protected]>
Cc: Udit Agarwal <[email protected]>
Cc: Jan Luebbe <[email protected]>
Cc: David Gstir <[email protected]>
Cc: Eric Biggers <e[email protected]>
Cc: Richard Weinberger <[email protected]>
Cc: Franck LENORMAND <[email protected]>
Cc: Sumit Garg <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

Ahmad Fatoum (4):
KEYS: trusted: allow users to use kernel RNG for key material
KEYS: trusted: allow trust sources to use kernel RNG for key material
crypto: caam - add in-kernel interface for blob generator
KEYS: trusted: Introduce support for NXP CAAM-based trusted keys

Documentation/admin-guide/kernel-parameters.txt | 8 +-
Documentation/security/keys/trusted-encrypted.rst | 60 +++-
MAINTAINERS | 9 +-
drivers/crypto/caam/Kconfig | 3 +-
drivers/crypto/caam/Makefile | 1 +-
drivers/crypto/caam/blob_gen.c | 230 +++++++++++++++-
include/keys/trusted-type.h | 2 +-
include/keys/trusted_caam.h | 11 +-
include/soc/fsl/caam-blob.h | 56 ++++-
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 | 23 +-
13 files changed, 477 insertions(+), 13 deletions(-)
create mode 100644 drivers/crypto/caam/blob_gen.c
create mode 100644 include/keys/trusted_caam.h
create mode 100644 include/soc/fsl/caam-blob.h
create mode 100644 security/keys/trusted-keys/trusted_caam.c

base-commit: 97408d81ed533b953326c580ff2c3f1948b3fcee
--
git-series 0.9.1


2021-07-21 16:50:46

by Ahmad Fatoum

[permalink] [raw]
Subject: [PATCH 1/4] KEYS: trusted: allow users to use kernel RNG for key material

The two existing trusted key sources don't make use of the kernel RNG,
but instead let the hardware doing the sealing/unsealing also
generate the random key material. However, Users may want to place
less trust into the quality of the trust source's random number
generator and instead use the kernel entropy pool, which can be
seeded from multiple entropy sources.

Make this possible by adding a new trusted.kernel_rng parameter,
that will force use of the kernel RNG. In its absence, it's up
to the trust source to decide, which random numbers to use,
maintaining the existing behavior.

Suggested-by: Jarkko Sakkinen <[email protected]>
Signed-off-by: Ahmad Fatoum <[email protected]>
---
To: James Bottomley <[email protected]>
To: Jarkko Sakkinen <[email protected]>
To: Mimi Zohar <[email protected]>
To: David Howells <[email protected]>
Cc: James Morris <[email protected]>
Cc: "Serge E. Hallyn" <[email protected]>
Cc: "Horia Geantă" <[email protected]>
Cc: Aymen Sghaier <[email protected]>
Cc: Herbert Xu <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Udit Agarwal <[email protected]>
Cc: Jan Luebbe <[email protected]>
Cc: Eric Biggers <[email protected]>
Cc: David Gstir <[email protected]>
Cc: Richard Weinberger <[email protected]>
Cc: Franck LENORMAND <[email protected]>
Cc: Sumit Garg <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
Documentation/admin-guide/kernel-parameters.txt | 7 ++++++-
Documentation/security/keys/trusted-encrypted.rst | 20 +++++++++-------
security/keys/trusted-keys/trusted_core.c | 17 +++++++++++++-
3 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index bdb22006f713..0267ead88902 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5734,6 +5734,13 @@
first trust source as a backend which is initialized
successfully during iteration.

+ trusted.kernel_rng = [KEYS]
+ Format: <bool>
+ When set to true (1), the kernel random number pool
+ is used to generate key material for trusted keys.
+ The default is to leave the RNG's choice to each
+ individual trust source.
+
tsc= Disable clocksource stability checks for TSC.
Format: <string>
[x86] reliable: mark tsc clocksource as reliable, this
diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst
index 80d5a5af62a1..1d4b4b8f12f0 100644
--- a/Documentation/security/keys/trusted-encrypted.rst
+++ b/Documentation/security/keys/trusted-encrypted.rst
@@ -87,22 +87,26 @@ Key Generation
Trusted Keys
------------

-New keys are created from random numbers generated in the trust source. They
-are encrypted/decrypted using a child key in the storage key hierarchy.
-Encryption and decryption of the child key must be protected by a strong
-access control policy within the trust source.
+New keys are created from random numbers. They are encrypted/decrypted using
+a child key in the storage key hierarchy. Encryption and decryption of the
+child key must be protected by a strong access control policy within the
+trust source. The random number generator in use differs according to the
+selected trust source:

- * TPM (hardware device) based RNG
+ * TPM: hardware device based RNG

- Strength of random numbers may vary from one device manufacturer to
- another.
+ Keys are generated within the TPM. Strength of random numbers may vary
+ from one device manufacturer to another.

- * TEE (OP-TEE based on Arm TrustZone) based RNG
+ * TEE: OP-TEE based on Arm TrustZone based RNG

RNG is customizable as per platform needs. It can either be direct output
from platform specific hardware RNG or a software based Fortuna CSPRNG
which can be seeded via multiple entropy sources.

+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.
+
Encrypted Keys
--------------

diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
index 8cab69e5d0da..569af9af8df0 100644
--- a/security/keys/trusted-keys/trusted_core.c
+++ b/security/keys/trusted-keys/trusted_core.c
@@ -16,12 +16,17 @@
#include <linux/key-type.h>
#include <linux/module.h>
#include <linux/parser.h>
+#include <linux/random.h>
#include <linux/rcupdate.h>
#include <linux/slab.h>
#include <linux/static_call.h>
#include <linux/string.h>
#include <linux/uaccess.h>

+static bool trusted_kernel_rng;
+module_param_named(kernel_rng, trusted_kernel_rng, bool, 0);
+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)");
@@ -312,8 +317,14 @@ struct key_type key_type_trusted = {
};
EXPORT_SYMBOL_GPL(key_type_trusted);

+static int kernel_get_random(unsigned char *key, size_t key_len)
+{
+ return get_random_bytes_wait(key, key_len) ?: key_len;
+}
+
static int __init init_trusted(void)
{
+ int (*get_random)(unsigned char *key, size_t key_len);
int i, ret = 0;

for (i = 0; i < ARRAY_SIZE(trusted_key_sources); i++) {
@@ -322,6 +333,10 @@ static int __init init_trusted(void)
strlen(trusted_key_sources[i].name)))
continue;

+ get_random = trusted_key_sources[i].ops->get_random;
+ if (trusted_kernel_rng)
+ get_random = kernel_get_random;
+
static_call_update(trusted_key_init,
trusted_key_sources[i].ops->init);
static_call_update(trusted_key_seal,
@@ -329,7 +344,7 @@ static int __init init_trusted(void)
static_call_update(trusted_key_unseal,
trusted_key_sources[i].ops->unseal);
static_call_update(trusted_key_get_random,
- trusted_key_sources[i].ops->get_random);
+ get_random);
static_call_update(trusted_key_exit,
trusted_key_sources[i].ops->exit);
migratable = trusted_key_sources[i].ops->migratable;
--
git-series 0.9.1

2021-07-21 16:51:16

by Ahmad Fatoum

[permalink] [raw]
Subject: [PATCH 4/4] KEYS: trusted: Introduce support for NXP CAAM-based trusted keys

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 <[email protected]>
---
To: Jonathan Corbet <[email protected]>
To: David Howells <[email protected]>
To: Jarkko Sakkinen <[email protected]>
To: James Bottomley <[email protected]>
To: Mimi Zohar <[email protected]>
Cc: James Morris <[email protected]>
Cc: "Serge E. Hallyn" <[email protected]>
Cc: "Horia Geantă" <[email protected]>
Cc: Aymen Sghaier <[email protected]>
Cc: Herbert Xu <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Udit Agarwal <[email protected]>
Cc: Eric Biggers <[email protected]>
Cc: Jan Luebbe <[email protected]>
Cc: David Gstir <[email protected]>
Cc: Richard Weinberger <[email protected]>
Cc: Franck LENORMAND <[email protected]>
Cc: Sumit Garg <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
Documentation/admin-guide/kernel-parameters.txt | 1 +-
Documentation/security/keys/trusted-encrypted.rst | 42 ++++++++-
MAINTAINERS | 9 ++-
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 +-
8 files changed, 152 insertions(+), 4 deletions(-)
create mode 100644 include/keys/trusted_caam.h
create mode 100644 security/keys/trusted-keys/trusted_caam.c

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 0267ead88902..43010cb27f17 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5729,6 +5729,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 1d4b4b8f12f0..ad66573ca6fd 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).
+
Encrypted Keys usage
--------------------

diff --git a/MAINTAINERS b/MAINTAINERS
index 6c8be735cc91..aa654e69075d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10265,6 +10265,15 @@ S: Supported
F: include/keys/trusted_tee.h
F: security/keys/trusted-keys/trusted_tee.c

+KEYS-TRUSTED-CAAM
+M: Ahmad Fatoum <[email protected]>
+R: Pengutronix Kernel Team <[email protected]>
+L: [email protected]
+L: [email protected]
+S: Supported
+F: include/keys/trusted_caam.h
+F: security/keys/trusted-keys/trusted_caam.c
+
KEYS/KEYRINGS
M: David Howells <[email protected]>
M: Jarkko Sakkinen <[email protected]>
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 <[email protected]>
+ */
+
+#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 c163cfeedff6..fac80117ef46 100644
--- a/security/keys/trusted-keys/Kconfig
+++ b/security/keys/trusted-keys/Kconfig
@@ -24,6 +24,15 @@ 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 2e2371eae4d5..735aa0bc08ef 100644
--- a/security/keys/trusted-keys/Makefile
+++ b/security/keys/trusted-keys/Makefile
@@ -12,3 +12,5 @@ trusted-$(CONFIG_TRUSTED_KEYS_TPM) += trusted_tpm2.o
trusted-$(CONFIG_TRUSTED_KEYS_TPM) += tpm2key.asn1.o

trusted-$(CONFIG_TRUSTED_KEYS_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 <[email protected]>
+ */
+
+#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 d2b7626cde8b..305e44651180 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);
--
git-series 0.9.1

2021-07-21 16:53:53

by Ahmad Fatoum

[permalink] [raw]
Subject: [PATCH 2/4] KEYS: trusted: allow trust sources to use kernel RNG for key material

The two existing trusted key sources don't make use of the kernel RNG,
but instead let the hardware that does the sealing/unsealing also
generate the random key material. While a previous change offers users
the choice to use the kernel RNG instead for both, new trust sources
may want to unconditionally use the kernel RNG for generating key
material, like it's done elsewhere in the kernel.

This is especially prudent for hardware that has proven-in-production
HWRNG drivers implemented, as otherwise code would have to be duplicated
only to arrive at a possibly worse result.

Make this possible by turning struct trusted_key_ops::get_random
into an optional member. If a driver leaves it NULL, kernel RNG
will be used instead.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
To: James Bottomley <[email protected]>
To: Jarkko Sakkinen <[email protected]>
To: Mimi Zohar <[email protected]>
To: David Howells <[email protected]>
Cc: James Morris <[email protected]>
Cc: "Serge E. Hallyn" <[email protected]>
Cc: "Horia Geantă" <[email protected]>
Cc: Aymen Sghaier <[email protected]>
Cc: Herbert Xu <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Udit Agarwal <[email protected]>
Cc: Eric Biggers <[email protected]>
Cc: Jan Luebbe <[email protected]>
Cc: David Gstir <[email protected]>
Cc: Richard Weinberger <[email protected]>
Cc: Franck LENORMAND <[email protected]>
Cc: Sumit Garg <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
include/keys/trusted-type.h | 2 +-
security/keys/trusted-keys/trusted_core.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
index d89fa2579ac0..4eb64548a74f 100644
--- a/include/keys/trusted-type.h
+++ b/include/keys/trusted-type.h
@@ -64,7 +64,7 @@ struct trusted_key_ops {
/* Unseal a key. */
int (*unseal)(struct trusted_key_payload *p, char *datablob);

- /* Get a randomized key. */
+ /* Optional: Get a randomized key. */
int (*get_random)(unsigned char *key, size_t key_len);

/* Exit key interface. */
diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
index 569af9af8df0..d2b7626cde8b 100644
--- a/security/keys/trusted-keys/trusted_core.c
+++ b/security/keys/trusted-keys/trusted_core.c
@@ -334,7 +334,7 @@ static int __init init_trusted(void)
continue;

get_random = trusted_key_sources[i].ops->get_random;
- if (trusted_kernel_rng)
+ if (trusted_kernel_rng || !get_random)
get_random = kernel_get_random;

static_call_update(trusted_key_init,
--
git-series 0.9.1

2021-07-22 06:18:28

by Sumit Garg

[permalink] [raw]
Subject: Re: [PATCH 1/4] KEYS: trusted: allow users to use kernel RNG for key material

On Wed, 21 Jul 2021 at 22:19, Ahmad Fatoum <[email protected]> wrote:
>
> The two existing trusted key sources don't make use of the kernel RNG,
> but instead let the hardware doing the sealing/unsealing also
> generate the random key material. However, Users may want to place
> less trust into the quality of the trust source's random number
> generator and instead use the kernel entropy pool, which can be
> seeded from multiple entropy sources.
>
> Make this possible by adding a new trusted.kernel_rng parameter,
> that will force use of the kernel RNG. In its absence, it's up
> to the trust source to decide, which random numbers to use,
> maintaining the existing behavior.
>
> Suggested-by: Jarkko Sakkinen <[email protected]>
> Signed-off-by: Ahmad Fatoum <[email protected]>
> ---
> To: James Bottomley <[email protected]>
> To: Jarkko Sakkinen <[email protected]>
> To: Mimi Zohar <[email protected]>
> To: David Howells <[email protected]>
> Cc: James Morris <[email protected]>
> Cc: "Serge E. Hallyn" <[email protected]>
> Cc: "Horia Geantă" <[email protected]>
> Cc: Aymen Sghaier <[email protected]>
> Cc: Herbert Xu <[email protected]>
> Cc: "David S. Miller" <[email protected]>
> Cc: Udit Agarwal <[email protected]>
> Cc: Jan Luebbe <[email protected]>
> Cc: Eric Biggers <[email protected]>
> Cc: David Gstir <[email protected]>
> Cc: Richard Weinberger <[email protected]>
> Cc: Franck LENORMAND <[email protected]>
> Cc: Sumit Garg <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> Documentation/admin-guide/kernel-parameters.txt | 7 ++++++-
> Documentation/security/keys/trusted-encrypted.rst | 20 +++++++++-------
> security/keys/trusted-keys/trusted_core.c | 17 +++++++++++++-
> 3 files changed, 35 insertions(+), 9 deletions(-)
>

Sounds like a reasonable approach to me.

Acked-by: Sumit Garg <[email protected]>

-Sumit

> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index bdb22006f713..0267ead88902 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -5734,6 +5734,13 @@
> first trust source as a backend which is initialized
> successfully during iteration.
>
> + trusted.kernel_rng = [KEYS]
> + Format: <bool>
> + When set to true (1), the kernel random number pool
> + is used to generate key material for trusted keys.
> + The default is to leave the RNG's choice to each
> + individual trust source.
> +
> tsc= Disable clocksource stability checks for TSC.
> Format: <string>
> [x86] reliable: mark tsc clocksource as reliable, this
> diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst
> index 80d5a5af62a1..1d4b4b8f12f0 100644
> --- a/Documentation/security/keys/trusted-encrypted.rst
> +++ b/Documentation/security/keys/trusted-encrypted.rst
> @@ -87,22 +87,26 @@ Key Generation
> Trusted Keys
> ------------
>
> -New keys are created from random numbers generated in the trust source. They
> -are encrypted/decrypted using a child key in the storage key hierarchy.
> -Encryption and decryption of the child key must be protected by a strong
> -access control policy within the trust source.
> +New keys are created from random numbers. They are encrypted/decrypted using
> +a child key in the storage key hierarchy. Encryption and decryption of the
> +child key must be protected by a strong access control policy within the
> +trust source. The random number generator in use differs according to the
> +selected trust source:
>
> - * TPM (hardware device) based RNG
> + * TPM: hardware device based RNG
>
> - Strength of random numbers may vary from one device manufacturer to
> - another.
> + Keys are generated within the TPM. Strength of random numbers may vary
> + from one device manufacturer to another.
>
> - * TEE (OP-TEE based on Arm TrustZone) based RNG
> + * TEE: OP-TEE based on Arm TrustZone based RNG
>
> RNG is customizable as per platform needs. It can either be direct output
> from platform specific hardware RNG or a software based Fortuna CSPRNG
> which can be seeded via multiple entropy sources.
>
> +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.
> +
> Encrypted Keys
> --------------
>
> diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
> index 8cab69e5d0da..569af9af8df0 100644
> --- a/security/keys/trusted-keys/trusted_core.c
> +++ b/security/keys/trusted-keys/trusted_core.c
> @@ -16,12 +16,17 @@
> #include <linux/key-type.h>
> #include <linux/module.h>
> #include <linux/parser.h>
> +#include <linux/random.h>
> #include <linux/rcupdate.h>
> #include <linux/slab.h>
> #include <linux/static_call.h>
> #include <linux/string.h>
> #include <linux/uaccess.h>
>
> +static bool trusted_kernel_rng;
> +module_param_named(kernel_rng, trusted_kernel_rng, bool, 0);
> +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)");
> @@ -312,8 +317,14 @@ struct key_type key_type_trusted = {
> };
> EXPORT_SYMBOL_GPL(key_type_trusted);
>
> +static int kernel_get_random(unsigned char *key, size_t key_len)
> +{
> + return get_random_bytes_wait(key, key_len) ?: key_len;
> +}
> +
> static int __init init_trusted(void)
> {
> + int (*get_random)(unsigned char *key, size_t key_len);
> int i, ret = 0;
>
> for (i = 0; i < ARRAY_SIZE(trusted_key_sources); i++) {
> @@ -322,6 +333,10 @@ static int __init init_trusted(void)
> strlen(trusted_key_sources[i].name)))
> continue;
>
> + get_random = trusted_key_sources[i].ops->get_random;
> + if (trusted_kernel_rng)
> + get_random = kernel_get_random;
> +
> static_call_update(trusted_key_init,
> trusted_key_sources[i].ops->init);
> static_call_update(trusted_key_seal,
> @@ -329,7 +344,7 @@ static int __init init_trusted(void)
> static_call_update(trusted_key_unseal,
> trusted_key_sources[i].ops->unseal);
> static_call_update(trusted_key_get_random,
> - trusted_key_sources[i].ops->get_random);
> + get_random);
> static_call_update(trusted_key_exit,
> trusted_key_sources[i].ops->exit);
> migratable = trusted_key_sources[i].ops->migratable;
> --
> git-series 0.9.1

2021-07-22 06:32:33

by Sumit Garg

[permalink] [raw]
Subject: Re: [PATCH 2/4] KEYS: trusted: allow trust sources to use kernel RNG for key material

On Wed, 21 Jul 2021 at 22:19, Ahmad Fatoum <[email protected]> wrote:
>
> The two existing trusted key sources don't make use of the kernel RNG,
> but instead let the hardware that does the sealing/unsealing also
> generate the random key material. While a previous change offers users
> the choice to use the kernel RNG instead for both, new trust sources
> may want to unconditionally use the kernel RNG for generating key
> material, like it's done elsewhere in the kernel.
>
> This is especially prudent for hardware that has proven-in-production
> HWRNG drivers implemented, as otherwise code would have to be duplicated
> only to arrive at a possibly worse result.
>
> Make this possible by turning struct trusted_key_ops::get_random
> into an optional member. If a driver leaves it NULL, kernel RNG
> will be used instead.
>
> Signed-off-by: Ahmad Fatoum <[email protected]>
> ---
> To: James Bottomley <[email protected]>
> To: Jarkko Sakkinen <[email protected]>
> To: Mimi Zohar <[email protected]>
> To: David Howells <[email protected]>
> Cc: James Morris <[email protected]>
> Cc: "Serge E. Hallyn" <[email protected]>
> Cc: "Horia Geantă" <[email protected]>
> Cc: Aymen Sghaier <[email protected]>
> Cc: Herbert Xu <[email protected]>
> Cc: "David S. Miller" <[email protected]>
> Cc: Udit Agarwal <[email protected]>
> Cc: Eric Biggers <[email protected]>
> Cc: Jan Luebbe <[email protected]>
> Cc: David Gstir <[email protected]>
> Cc: Richard Weinberger <[email protected]>
> Cc: Franck LENORMAND <[email protected]>
> Cc: Sumit Garg <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> include/keys/trusted-type.h | 2 +-
> security/keys/trusted-keys/trusted_core.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
> index d89fa2579ac0..4eb64548a74f 100644
> --- a/include/keys/trusted-type.h
> +++ b/include/keys/trusted-type.h
> @@ -64,7 +64,7 @@ struct trusted_key_ops {
> /* Unseal a key. */
> int (*unseal)(struct trusted_key_payload *p, char *datablob);
>
> - /* Get a randomized key. */
> + /* Optional: Get a randomized key. */
> int (*get_random)(unsigned char *key, size_t key_len);
>
> /* Exit key interface. */
> diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
> index 569af9af8df0..d2b7626cde8b 100644
> --- a/security/keys/trusted-keys/trusted_core.c
> +++ b/security/keys/trusted-keys/trusted_core.c
> @@ -334,7 +334,7 @@ static int __init init_trusted(void)
> continue;
>
> get_random = trusted_key_sources[i].ops->get_random;
> - if (trusted_kernel_rng)
> + if (trusted_kernel_rng || !get_random)
> get_random = kernel_get_random;
>

For ease of understanding, I would prefer to write it as:

get_random = trusted_key_sources[i].ops->get_random ?:
kernel_get_random;
if (trusted_kernel_rng)
get_random = kernel_get_random;

With that:

Acked-by: Sumit Garg <[email protected]>

-Sumit

> static_call_update(trusted_key_init,
> --
> git-series 0.9.1