From patchwork Mon Oct 11 10:02:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ahmad Fatoum X-Patchwork-Id: 12549621 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA177C433EF for ; Mon, 11 Oct 2021 10:03:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AEC6961038 for ; Mon, 11 Oct 2021 10:03:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235781AbhJKKFT (ORCPT ); Mon, 11 Oct 2021 06:05:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39194 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235762AbhJKKFP (ORCPT ); Mon, 11 Oct 2021 06:05:15 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7762DC061745 for ; Mon, 11 Oct 2021 03:03:15 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mZs8v-0006Sj-Kj; Mon, 11 Oct 2021 12:02:49 +0200 Received: from afa by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1mZs8r-0002cg-Rq; Mon, 11 Oct 2021 12:02:45 +0200 From: Ahmad Fatoum To: Jarkko Sakkinen , James Morris , "Serge E. Hallyn" , James Bottomley , Mimi Zohar , Sumit Garg , David Howells , Herbert Xu , "David S. Miller" Cc: kernel@pengutronix.de, Andreas Rammhold , Tim Harvey , Ahmad Fatoum , David Gstir , Richard Weinberger , keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-integrity@vger.kernel.org Subject: [PATCH v4 1/5] KEYS: trusted: allow use of TEE as backend without TCG_TPM support Date: Mon, 11 Oct 2021 12:02:34 +0200 Message-Id: X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: afa@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-integrity@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org With recent rework, trusted keys are no longer limited to TPM as trust source. The Kconfig symbol is unchanged however leading to a few issues: - TCG_TPM is required, even if only TEE is to be used - Enabling TCG_TPM, but excluding it from available trusted sources is not possible - TEE=m && TRUSTED_KEYS=y will lead to TEE support being silently dropped, which is not the best user experience Remedy these issues by introducing two new boolean Kconfig symbols: TRUSTED_KEYS_TPM and TRUSTED_KEYS_TEE with the appropriate dependencies. Any code depending on the TPM trusted key backend or symbols exported by it will now need to explicitly state that it depends on TRUSTED_KEYS && TRUSTED_KEYS_TPM The latter to ensure the dependency is built and the former to ensure it's reachable for module builds. This currently only affects CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE, so it's fixed up here as well. Reviewed-by: Sumit Garg Tested-By: Andreas Rammhold Tested-By: Tim Harvey Signed-off-by: Ahmad Fatoum Reviewed-by: Jarkko Sakkinen --- v3 -> v4: - rebased on top of Andreas' regression fix and pulled it back into series v2 -> v3: - factored this patch out as a fix for backporting v1 -> v2: - Move rest of TPM-related selects from TRUSTED_KEYS to TRUSTED_KEYS_TPM (Sumit) - Remove left-over line in Makefile (Sumit) - added Fixes: tag - adjust commit message to reference the regression reported by Andreas - have ASYMMETRIC_TPM_KEY_SUBTYPE depend on TRUSTED_KEYS_TPM, because it references global symbols that are exported by the trusted key TPM backend. [1]: https://lore.kernel.org/linux-integrity/f8285eb0135ba30c9d846cf9dd395d1f5f8b1efc.1624364386.git-series.a.fatoum@pengutronix.de/ [2]: https://lore.kernel.org/linux-integrity/20210719091335.vwfebcpkf4pag3wm@wrt/T/#t To: Jarkko Sakkinen To: James Morris To: "Serge E. Hallyn" To: James Bottomley To: Mimi Zohar To: Sumit Garg To: David Howells To: Herbert Xu To: "David S. Miller" Cc: David Gstir Cc: Richard Weinberger Cc: keyrings@vger.kernel.org Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-security-module@vger.kernel.org Cc: linux-integrity@vger.kernel.org --- crypto/asymmetric_keys/Kconfig | 2 +- security/keys/Kconfig | 18 +++++---------- security/keys/trusted-keys/Kconfig | 29 ++++++++++++++++++++++++- security/keys/trusted-keys/Makefile | 8 +++---- security/keys/trusted-keys/trusted_core.c | 4 +-- 5 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 security/keys/trusted-keys/Kconfig diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig index 1f1f004dc757..8886eddbf881 100644 --- a/crypto/asymmetric_keys/Kconfig +++ b/crypto/asymmetric_keys/Kconfig @@ -25,7 +25,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE config ASYMMETRIC_TPM_KEY_SUBTYPE tristate "Asymmetric TPM backed private key subtype" depends on TCG_TPM - depends on TRUSTED_KEYS + depends on TRUSTED_KEYS && TRUSTED_KEYS_TPM select CRYPTO_HMAC select CRYPTO_SHA1 select CRYPTO_HASH_INFO diff --git a/security/keys/Kconfig b/security/keys/Kconfig index 64b81abd087e..9ec302962fe2 100644 --- a/security/keys/Kconfig +++ b/security/keys/Kconfig @@ -70,23 +70,19 @@ config BIG_KEYS config TRUSTED_KEYS tristate "TRUSTED KEYS" - depends on KEYS && TCG_TPM - select CRYPTO - select CRYPTO_HMAC - select CRYPTO_SHA1 - select CRYPTO_HASH_INFO - select ASN1_ENCODER - select OID_REGISTRY - select ASN1 + depends on KEYS help This option provides support for creating, sealing, and unsealing keys in the kernel. Trusted keys are random number symmetric keys, - generated and RSA-sealed by the TPM. The TPM only unseals the keys, - if the boot PCRs and other criteria match. Userspace will only ever - see encrypted blobs. + generated and sealed by a trust source selected at kernel boot-time. + Userspace will only ever see encrypted blobs. If you are unsure as to whether this is required, answer N. +if TRUSTED_KEYS +source "security/keys/trusted-keys/Kconfig" +endif + config ENCRYPTED_KEYS tristate "ENCRYPTED KEYS" depends on KEYS diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig new file mode 100644 index 000000000000..fc4abd581abb --- /dev/null +++ b/security/keys/trusted-keys/Kconfig @@ -0,0 +1,29 @@ +config TRUSTED_KEYS_TPM + bool "TPM-based trusted keys" + depends on TCG_TPM >= TRUSTED_KEYS + default y + select CRYPTO + select CRYPTO_HMAC + select CRYPTO_SHA1 + select CRYPTO_HASH_INFO + select ASN1_ENCODER + select OID_REGISTRY + select ASN1 + help + Enable use of the Trusted Platform Module (TPM) as trusted key + backend. Trusted keys are random number symmetric keys, + which will be generated and RSA-sealed by the TPM. + The TPM only unseals the keys, if the boot PCRs and other + criteria match. + +config TRUSTED_KEYS_TEE + bool "TEE-based trusted keys" + depends on TEE >= TRUSTED_KEYS + default y + help + Enable use of the Trusted Execution Environment (TEE) as trusted + key backend. + +if !TRUSTED_KEYS_TPM && !TRUSTED_KEYS_TEE +comment "No trust source selected!" +endif diff --git a/security/keys/trusted-keys/Makefile b/security/keys/trusted-keys/Makefile index feb8b6c3cc79..2e2371eae4d5 100644 --- a/security/keys/trusted-keys/Makefile +++ b/security/keys/trusted-keys/Makefile @@ -5,10 +5,10 @@ obj-$(CONFIG_TRUSTED_KEYS) += trusted.o trusted-y += trusted_core.o -trusted-y += trusted_tpm1.o +trusted-$(CONFIG_TRUSTED_KEYS_TPM) += trusted_tpm1.o $(obj)/trusted_tpm2.o: $(obj)/tpm2key.asn1.h -trusted-y += trusted_tpm2.o -trusted-y += tpm2key.asn1.o +trusted-$(CONFIG_TRUSTED_KEYS_TPM) += trusted_tpm2.o +trusted-$(CONFIG_TRUSTED_KEYS_TPM) += tpm2key.asn1.o -trusted-$(CONFIG_TEE) += trusted_tee.o +trusted-$(CONFIG_TRUSTED_KEYS_TEE) += trusted_tee.o diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c index 5b35f1b87644..8cab69e5d0da 100644 --- a/security/keys/trusted-keys/trusted_core.c +++ b/security/keys/trusted-keys/trusted_core.c @@ -27,10 +27,10 @@ module_param_named(source, trusted_key_source, charp, 0); MODULE_PARM_DESC(source, "Select trusted keys source (tpm or tee)"); static const struct trusted_key_source trusted_key_sources[] = { -#if IS_REACHABLE(CONFIG_TCG_TPM) +#if defined(CONFIG_TRUSTED_KEYS_TPM) { "tpm", &trusted_key_tpm_ops }, #endif -#if IS_REACHABLE(CONFIG_TEE) +#if defined(CONFIG_TRUSTED_KEYS_TEE) { "tee", &trusted_key_tee_ops }, #endif }; From patchwork Mon Oct 11 10:02:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ahmad Fatoum X-Patchwork-Id: 12549623 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2412CC433F5 for ; Mon, 11 Oct 2021 10:03:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0FC6561039 for ; Mon, 11 Oct 2021 10:03:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235782AbhJKKFY (ORCPT ); Mon, 11 Oct 2021 06:05:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235754AbhJKKFS (ORCPT ); Mon, 11 Oct 2021 06:05:18 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9D27C061767 for ; Mon, 11 Oct 2021 03:03:17 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mZs8v-0006Sk-Gu; Mon, 11 Oct 2021 12:02:49 +0200 Received: from afa by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1mZs8r-0002cm-T7; Mon, 11 Oct 2021 12:02:45 +0200 From: Ahmad Fatoum To: James Bottomley , Jarkko Sakkinen , Mimi Zohar , David Howells Cc: kernel@pengutronix.de, Sumit Garg , David Gstir , Tim Harvey , Ahmad Fatoum , James Morris , "Serge E. Hallyn" , =?utf-8?q?Horia_Geant=C4=83?= , Aymen Sghaier , Herbert Xu , "David S. Miller" , Udit Agarwal , Jan Luebbe , Eric Biggers , Richard Weinberger , Franck LENORMAND , keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org Subject: [PATCH v4 2/5] KEYS: trusted: allow users to use kernel RNG for key material Date: Mon, 11 Oct 2021 12:02:35 +0200 Message-Id: <9bd8c969d5c656825a35aab6fb0725282a8a62cc.1633946449.git-series.a.fatoum@pengutronix.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: afa@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-integrity@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org 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 Acked-by: Sumit Garg Reviewed-by: David Gstir Tested-By: Tim Harvey Signed-off-by: Ahmad Fatoum Reviewed-by: Pankaj Gupta --- To: James Bottomley To: Jarkko Sakkinen To: Mimi Zohar To: David Howells Cc: James Morris Cc: "Serge E. Hallyn" Cc: "Horia Geantă" Cc: Aymen Sghaier Cc: Herbert Xu Cc: "David S. Miller" Cc: Udit Agarwal Cc: Jan Luebbe Cc: Eric Biggers Cc: David Gstir Cc: Richard Weinberger Cc: Franck LENORMAND Cc: Sumit Garg Cc: keyrings@vger.kernel.org Cc: linux-crypto@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 | 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 43dc35fe5bc0..d5969452f063 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -5772,6 +5772,13 @@ first trust source as a backend which is initialized successfully during iteration. + trusted.kernel_rng = [KEYS] + Format: + 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: [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 #include #include +#include #include #include #include #include #include +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; From patchwork Mon Oct 11 10:02:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ahmad Fatoum X-Patchwork-Id: 12549619 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92060C433EF for ; Mon, 11 Oct 2021 10:03:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 84D8E60F43 for ; Mon, 11 Oct 2021 10:03:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235750AbhJKKFO (ORCPT ); Mon, 11 Oct 2021 06:05:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39178 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235745AbhJKKFN (ORCPT ); Mon, 11 Oct 2021 06:05:13 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9A3BC061764 for ; Mon, 11 Oct 2021 03:03:13 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mZs8v-0006Sl-Gx; Mon, 11 Oct 2021 12:02:49 +0200 Received: from afa by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1mZs8r-0002cs-UL; Mon, 11 Oct 2021 12:02:45 +0200 From: Ahmad Fatoum To: James Bottomley , Jarkko Sakkinen , Mimi Zohar , David Howells Cc: kernel@pengutronix.de, Sumit Garg , David Gstir , Tim Harvey , Ahmad Fatoum , James Morris , "Serge E. Hallyn" , =?utf-8?q?Horia_Geant=C4=83?= , Aymen Sghaier , Herbert Xu , "David S. Miller" , Udit Agarwal , Eric Biggers , Jan Luebbe , Richard Weinberger , Franck LENORMAND , keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org Subject: [PATCH v4 3/5] KEYS: trusted: allow trust sources to use kernel RNG for key material Date: Mon, 11 Oct 2021 12:02:36 +0200 Message-Id: <9431f31594f9ea693b201cfbfa9e7b221e500e6a.1633946449.git-series.a.fatoum@pengutronix.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: afa@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-integrity@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org 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. Acked-by: Sumit Garg Reviewed-by: David Gstir Tested-By: Tim Harvey Signed-off-by: Ahmad Fatoum --- To: James Bottomley To: Jarkko Sakkinen To: Mimi Zohar To: David Howells Cc: James Morris Cc: "Serge E. Hallyn" Cc: "Horia Geantă" Cc: Aymen Sghaier Cc: Herbert Xu Cc: "David S. Miller" Cc: Udit Agarwal Cc: Eric Biggers Cc: Jan Luebbe Cc: David Gstir Cc: Richard Weinberger Cc: Franck LENORMAND Cc: Sumit Garg Cc: keyrings@vger.kernel.org Cc: linux-crypto@vger.kernel.org Cc: linux-integrity@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-security-module@vger.kernel.org --- 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, From patchwork Mon Oct 11 10:02:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ahmad Fatoum X-Patchwork-Id: 12549627 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5FF6C4332F for ; Mon, 11 Oct 2021 10:03:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AEBD660F5B for ; Mon, 11 Oct 2021 10:03:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235793AbhJKKFs (ORCPT ); Mon, 11 Oct 2021 06:05:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39276 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235839AbhJKKFe (ORCPT ); Mon, 11 Oct 2021 06:05:34 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A893C06176E for ; Mon, 11 Oct 2021 03:03:29 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mZs8v-0006Sm-HC; Mon, 11 Oct 2021 12:02:49 +0200 Received: from afa by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1mZs8r-0002cx-VZ; Mon, 11 Oct 2021 12:02:45 +0200 From: Ahmad Fatoum To: =?utf-8?q?Horia_Geant=C4=83?= , Aymen Sghaier , Herbert Xu , "David S. Miller" Cc: kernel@pengutronix.de, David Gstir , Tim Harvey , Ahmad Fatoum , James Bottomley , Jarkko Sakkinen , Mimi Zohar , David Howells , James Morris , Eric Biggers , "Serge E. Hallyn" , Udit Agarwal , Jan Luebbe , Richard Weinberger , Franck LENORMAND , Sumit Garg , linux-integrity@vger.kernel.org, keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org Subject: [PATCH v4 4/5] crypto: caam - add in-kernel interface for blob generator Date: Mon, 11 Oct 2021 12:02:37 +0200 Message-Id: <3ea6e5c37559eddfdc51f26c4dff0abbbc894839.1633946449.git-series.a.fatoum@pengutronix.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: afa@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-integrity@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The CAAM can be used to protect user-defined data across system reboot: - When the system is fused and boots into secure state, the master key is a unique never-disclosed device-specific key - random key is encrypted by key derived from master key - data is encrypted using the random key - encrypted data and its encrypted random key are stored alongside - This blob can now be safely stored in non-volatile memory On next power-on: - blob is loaded into CAAM - CAAM writes decrypted data either into memory or key register Add functions to realize encrypting and decrypting into memory alongside the CAAM driver. They will be used in a later commit as a source for the trusted key seal/unseal mechanism. Reviewed-by: David Gstir Tested-By: Tim Harvey Signed-off-by: Steffen Trumtrar Signed-off-by: Ahmad Fatoum Reviewed-by: Pankaj Gupta --- To: "Horia Geantă" To: Aymen Sghaier To: Herbert Xu To: "David S. Miller" Cc: James Bottomley Cc: Jarkko Sakkinen Cc: Mimi Zohar Cc: David Howells Cc: James Morris Cc: Eric Biggers Cc: "Serge E. Hallyn" Cc: Udit Agarwal Cc: Jan Luebbe Cc: David Gstir Cc: Richard Weinberger Cc: Franck LENORMAND Cc: Sumit Garg Cc: linux-integrity@vger.kernel.org Cc: keyrings@vger.kernel.org Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-security-module@vger.kernel.org --- drivers/crypto/caam/Kconfig | 3 +- drivers/crypto/caam/Makefile | 1 +- drivers/crypto/caam/blob_gen.c | 230 ++++++++++++++++++++++++++++++++++- include/soc/fsl/caam-blob.h | 56 ++++++++- 4 files changed, 290 insertions(+) create mode 100644 drivers/crypto/caam/blob_gen.c create mode 100644 include/soc/fsl/caam-blob.h diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index 84ea7cba5ee5..ea9f8b1ae981 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -151,6 +151,9 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API Selecting this will register the SEC4 hardware rng to the hw_random API for supplying the kernel entropy pool. +config CRYPTO_DEV_FSL_CAAM_BLOB_GEN + bool + endif # CRYPTO_DEV_FSL_CAAM_JR endif # CRYPTO_DEV_FSL_CAAM diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile index 3570286eb9ce..25f7ae5a4642 100644 --- a/drivers/crypto/caam/Makefile +++ b/drivers/crypto/caam/Makefile @@ -21,6 +21,7 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o +caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_BLOB_GEN) += blob_gen.o caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),) diff --git a/drivers/crypto/caam/blob_gen.c b/drivers/crypto/caam/blob_gen.c new file mode 100644 index 000000000000..513d3f90e438 --- /dev/null +++ b/drivers/crypto/caam/blob_gen.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2015 Pengutronix, Steffen Trumtrar + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum + */ + +#include +#include + +#include "compat.h" +#include "desc_constr.h" +#include "desc.h" +#include "error.h" +#include "intern.h" +#include "jr.h" +#include "regs.h" + +struct caam_blob_priv { + struct device jrdev; +}; + +struct caam_blob_job_result { + int err; + struct completion completion; +}; + +static void caam_blob_job_done(struct device *dev, u32 *desc, u32 err, void *context) +{ + struct caam_blob_job_result *res = context; + int ecode = 0; + + dev_dbg(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); + + if (err) + ecode = caam_jr_strstatus(dev, err); + + res->err = ecode; + + /* + * Upon completion, desc points to a buffer containing a CAAM job + * descriptor which encapsulates data into an externally-storable + * blob. + */ + complete(&res->completion); +} + +static u32 *caam_blob_alloc_desc(size_t keymod_len) +{ + size_t len; + + /* header + (key mod immediate) + 2x pointers + op */ + len = 4 + (4 + ALIGN(keymod_len, 4)) + 2*(4 + 4 + CAAM_PTR_SZ_MAX) + 4; + + if (len > CAAM_DESC_BYTES_MAX) + return NULL; + + return kzalloc(len, GFP_KERNEL | GFP_DMA); +} + +int caam_encap_blob(struct caam_blob_priv *priv, const char *keymod, + void *input, void *output, size_t length) +{ + u32 *desc; + struct device *jrdev = &priv->jrdev; + dma_addr_t dma_in, dma_out; + struct caam_blob_job_result testres; + size_t keymod_len = strlen(keymod); + int ret; + + if (length <= CAAM_BLOB_OVERHEAD || keymod_len > CAAM_BLOB_KEYMOD_LENGTH) + return -EINVAL; + + desc = caam_blob_alloc_desc(keymod_len); + if (!desc) { + dev_err(jrdev, "unable to allocate desc\n"); + return -ENOMEM; + } + + dma_in = dma_map_single(jrdev, input, length - CAAM_BLOB_OVERHEAD, DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, dma_in)) { + dev_err(jrdev, "unable to map input DMA buffer\n"); + ret = -ENOMEM; + goto out_free; + } + + dma_out = dma_map_single(jrdev, output, length, DMA_FROM_DEVICE); + if (dma_mapping_error(jrdev, dma_out)) { + dev_err(jrdev, "unable to map output DMA buffer\n"); + ret = -ENOMEM; + goto out_unmap_in; + } + + /* + * A data blob is encrypted using a blob key (BK); a random number. + * The BK is used as an AES-CCM key. The initial block (B0) and the + * initial counter (Ctr0) are generated automatically and stored in + * Class 1 Context DWords 0+1+2+3. The random BK is stored in the + * Class 1 Key Register. Operation Mode is set to AES-CCM. + */ + + init_job_desc(desc, 0); + append_key_as_imm(desc, keymod, keymod_len, keymod_len, + CLASS_2 | KEY_DEST_CLASS_REG); + append_seq_in_ptr_intlen(desc, dma_in, length - CAAM_BLOB_OVERHEAD, 0); + append_seq_out_ptr_intlen(desc, dma_out, length, 0); + append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB); + + print_hex_dump_debug("data@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 1, input, + length - CAAM_BLOB_OVERHEAD, false); + print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 1, desc, + desc_bytes(desc), false); + + testres.err = 0; + init_completion(&testres.completion); + + ret = caam_jr_enqueue(jrdev, desc, caam_blob_job_done, &testres); + if (ret == -EINPROGRESS) { + wait_for_completion(&testres.completion); + ret = testres.err; + print_hex_dump_debug("output@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 1, output, + length, false); + } + + dma_unmap_single(jrdev, dma_out, length, DMA_FROM_DEVICE); +out_unmap_in: + dma_unmap_single(jrdev, dma_in, length - CAAM_BLOB_OVERHEAD, DMA_TO_DEVICE); +out_free: + kfree(desc); + + return ret; +} +EXPORT_SYMBOL(caam_encap_blob); + +int caam_decap_blob(struct caam_blob_priv *priv, const char *keymod, + void *input, void *output, size_t length) +{ + u32 *desc; + struct device *jrdev = &priv->jrdev; + dma_addr_t dma_in, dma_out; + struct caam_blob_job_result testres; + size_t keymod_len = strlen(keymod); + int ret; + + if (length <= CAAM_BLOB_OVERHEAD || keymod_len > CAAM_BLOB_KEYMOD_LENGTH) + return -EINVAL; + + desc = caam_blob_alloc_desc(keymod_len); + if (!desc) { + dev_err(jrdev, "unable to allocate desc\n"); + return -ENOMEM; + } + + dma_in = dma_map_single(jrdev, input, length, DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, dma_in)) { + dev_err(jrdev, "unable to map input DMA buffer\n"); + ret = -ENOMEM; + goto out_free; + } + + dma_out = dma_map_single(jrdev, output, length - CAAM_BLOB_OVERHEAD, DMA_FROM_DEVICE); + if (dma_mapping_error(jrdev, dma_out)) { + dev_err(jrdev, "unable to map output DMA buffer\n"); + ret = -ENOMEM; + goto out_unmap_in; + } + + /* + * A data blob is encrypted using a blob key (BK); a random number. + * The BK is used as an AES-CCM key. The initial block (B0) and the + * initial counter (Ctr0) are generated automatically and stored in + * Class 1 Context DWords 0+1+2+3. The random BK is stored in the + * Class 1 Key Register. Operation Mode is set to AES-CCM. + */ + + init_job_desc(desc, 0); + append_key_as_imm(desc, keymod, keymod_len, keymod_len, + CLASS_2 | KEY_DEST_CLASS_REG); + append_seq_in_ptr(desc, dma_in, length, 0); + append_seq_out_ptr(desc, dma_out, length - CAAM_BLOB_OVERHEAD, 0); + append_operation(desc, OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB); + + print_hex_dump_debug("data@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 1, input, + length, false); + print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 1, desc, + desc_bytes(desc), false); + + testres.err = 0; + init_completion(&testres.completion); + + ret = caam_jr_enqueue(jrdev, desc, caam_blob_job_done, &testres); + if (ret == -EINPROGRESS) { + wait_for_completion(&testres.completion); + ret = testres.err; + print_hex_dump_debug("output@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 1, output, + length - CAAM_BLOB_OVERHEAD, false); + } + + dma_unmap_single(jrdev, dma_out, length - CAAM_BLOB_OVERHEAD, DMA_FROM_DEVICE); +out_unmap_in: + dma_unmap_single(jrdev, dma_in, length, DMA_TO_DEVICE); +out_free: + kfree(desc); + + return ret; +} +EXPORT_SYMBOL(caam_decap_blob); + +struct caam_blob_priv *caam_blob_gen_init(void) +{ + struct device *jrdev; + + jrdev = caam_jr_alloc(); + if (IS_ERR(jrdev)) + return ERR_CAST(jrdev); + + return container_of(jrdev, struct caam_blob_priv, jrdev); +} +EXPORT_SYMBOL(caam_blob_gen_init); + +void caam_blob_gen_exit(struct caam_blob_priv *priv) +{ + caam_jr_free(&priv->jrdev); +} +EXPORT_SYMBOL(caam_blob_gen_exit); diff --git a/include/soc/fsl/caam-blob.h b/include/soc/fsl/caam-blob.h new file mode 100644 index 000000000000..83fd990ebdce --- /dev/null +++ b/include/soc/fsl/caam-blob.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Pengutronix, Ahmad Fatoum + */ + +#ifndef __CAAM_BLOB_GEN +#define __CAAM_BLOB_GEN + +#include + +#define CAAM_BLOB_KEYMOD_LENGTH 16 +#define CAAM_BLOB_OVERHEAD (32 + 16) +#define CAAM_BLOB_MAX_LEN 4096 + +struct caam_blob_priv; + +/** caam_blob_gen_init - initialize blob generation + * + * returns either pointer to new caam_blob_priv instance + * or error pointer + */ +struct caam_blob_priv *caam_blob_gen_init(void); + +/** caam_blob_gen_exit - free blob generation resources + * + * @priv: instance returned by caam_blob_gen_init + */ +void caam_blob_gen_exit(struct caam_blob_priv *priv); + +/** caam_encap_blob - encapsulate blob + * + * @priv: instance returned by caam_blob_gen_init + * @keymod: string to use as key modifier for blob encapsulation + * can't be longer than CAAM_BLOB_KEYMOD_LENGTH + * @input: buffer which CAAM will DMA from + * @output: buffer which CAAM will DMA to + * @length: buffer length including blob overhead + * CAAM_BLOB_OVERHEAD < length <= CAAM_BLOB_MAX_LEN + */ +int caam_encap_blob(struct caam_blob_priv *priv, const char *keymod, + void *input, void *output, size_t length); + +/** caam_decap_blob - decapsulate blob + * + * @priv: instance returned by caam_blob_gen_init + * @keymod: string to use as key modifier for blob decapsulation + * can't be longer than CAAM_BLOB_KEYMOD_LENGTH + * @input: buffer which CAAM will DMA from + * @output: buffer which CAAM will DMA to + * @length: buffer length including blob overhead + * CAAM_BLOB_OVERHEAD < length <= CAAM_BLOB_MAX_LEN + */ +int caam_decap_blob(struct caam_blob_priv *priv, const char *keymod, + void *input, void *output, size_t length); + +#endif From patchwork Mon Oct 11 10:02:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ahmad Fatoum X-Patchwork-Id: 12549625 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AB6F1C433F5 for ; Mon, 11 Oct 2021 10:03:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 907D160F43 for ; Mon, 11 Oct 2021 10:03:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235709AbhJKKFr (ORCPT ); Mon, 11 Oct 2021 06:05:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235838AbhJKKFe (ORCPT ); Mon, 11 Oct 2021 06:05:34 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E92B3C061775 for ; Mon, 11 Oct 2021 03:03:30 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mZs8v-0006Sn-HC; Mon, 11 Oct 2021 12:02:49 +0200 Received: from afa by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1mZs8s-0002d3-0e; Mon, 11 Oct 2021 12:02:46 +0200 From: Ahmad Fatoum To: Jonathan Corbet , David Howells , Jarkko Sakkinen , James Bottomley , Mimi Zohar Cc: kernel@pengutronix.de, David Gstir , Tim Harvey , Ahmad Fatoum , James Morris , "Serge E. Hallyn" , =?utf-8?q?Horia_Geant=C4=83?= , Aymen Sghaier , Herbert Xu , "David S. Miller" , Udit Agarwal , Eric Biggers , Jan Luebbe , Richard Weinberger , Franck LENORMAND , Sumit Garg , keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, linux-doc@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org Subject: [PATCH v4 5/5] KEYS: trusted: Introduce support for NXP CAAM-based trusted keys Date: Mon, 11 Oct 2021 12:02:38 +0200 Message-Id: X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: afa@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-integrity@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org 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. Reviewed-by: David Gstir Tested-By: Tim Harvey Signed-off-by: Ahmad Fatoum Tested-by: Matthias Schiffer --- To: Jonathan Corbet To: David Howells To: Jarkko Sakkinen To: James Bottomley To: Mimi Zohar Cc: James Morris Cc: "Serge E. Hallyn" Cc: "Horia Geantă" Cc: Aymen Sghaier Cc: Herbert Xu Cc: "David S. Miller" Cc: Udit Agarwal Cc: Eric Biggers Cc: Jan Luebbe Cc: David Gstir Cc: Richard Weinberger Cc: Franck LENORMAND Cc: Sumit Garg 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 ++++++++- 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 d5969452f063..0ed1165e0f55 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -5767,6 +5767,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 a4a0c2baaf27..2c6514759222 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10364,6 +10364,15 @@ S: Supported F: include/keys/trusted_tee.h F: security/keys/trusted-keys/trusted_tee.c +KEYS-TRUSTED-CAAM +M: Ahmad Fatoum +R: Pengutronix Kernel Team +L: linux-integrity@vger.kernel.org +L: keyrings@vger.kernel.org +S: Supported +F: include/keys/trusted_caam.h +F: security/keys/trusted-keys/trusted_caam.c + KEYS/KEYRINGS M: David Howells M: Jarkko Sakkinen 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 + */ + +#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 fc4abd581abb..dbfdd8536468 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 + */ + +#include +#include +#include +#include +#include + +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 #include #include +#include #include #include #include @@ -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);