From 141e523914f72575915dd334fce3cef4fb0f1e91 Mon Sep 17 00:00:00 2001 From: Mickaël Salaün Date: Mon, 12 Jul 2021 19:03:12 +0200 Subject: certs: Factor out the blacklist hash creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Factor out the blacklist hash creation with the get_raw_hash() helper. This also centralize the "tbs" and "bin" prefixes and make them private, which help to manage them consistently. Cc: David Howells Cc: David S. Miller Cc: David Woodhouse Cc: Eric Snowberg Cc: Herbert Xu Cc: Jarkko Sakkinen Signed-off-by: Mickaël Salaün Link: https://lore.kernel.org/r/20210712170313.884724-5-mic@digikod.net Signed-off-by: Jarkko Sakkinen --- include/keys/system_keyring.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index 2419a735420f..91e080efb918 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -10,6 +10,13 @@ #include +enum blacklist_hash_type { + /* TBSCertificate hash */ + BLACKLIST_HASH_X509_TBS = 1, + /* Raw data hash */ + BLACKLIST_HASH_BINARY = 2, +}; + #ifdef CONFIG_SYSTEM_TRUSTED_KEYRING extern int restrict_link_by_builtin_trusted(struct key *keyring, @@ -54,13 +61,14 @@ static inline void __init set_machine_trusted_keys(struct key *keyring) extern struct pkcs7_message *pkcs7; #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING -extern int mark_hash_blacklisted(const char *hash); +extern int mark_hash_blacklisted(const u8 *hash, size_t hash_len, + enum blacklist_hash_type hash_type); extern int is_hash_blacklisted(const u8 *hash, size_t hash_len, - const char *type); + enum blacklist_hash_type hash_type); extern int is_binary_blacklisted(const u8 *hash, size_t hash_len); #else static inline int is_hash_blacklisted(const u8 *hash, size_t hash_len, - const char *type) + enum blacklist_hash_type hash_type) { return 0; } -- cgit v1.2.3 From fcd7c26901c83681532c6daac599e53d4df11738 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Fri, 13 May 2022 16:57:00 +0200 Subject: KEYS: trusted: allow use of 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, both users and future backends may want to place less trust into the quality of the trust source's random number generator and instead reuse the kernel entropy pool, which can be seeded from multiple entropy sources. Make this possible by adding a new trusted.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 Acked-by: Pankaj Gupta Reviewed-by: David Gstir Reviewed-by: Pankaj Gupta Reviewed-by: Jarkko Sakkinen Tested-by: Pankaj Gupta Tested-by: Michael Walle # on ls1028a (non-E and E) Tested-by: John Ernberg # iMX8QXP Signed-off-by: Ahmad Fatoum Signed-off-by: Jarkko Sakkinen --- Documentation/admin-guide/kernel-parameters.txt | 10 +++++++ Documentation/security/keys/trusted-encrypted.rst | 20 +++++++------ include/keys/trusted-type.h | 2 +- security/keys/trusted-keys/trusted_core.c | 35 ++++++++++++++++++++++- 4 files changed, 57 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 3f1cc5e317ed..4deed1908a75 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -5963,6 +5963,16 @@ first trust source as a backend which is initialized successfully during iteration. + trusted.rng= [KEYS] + Format: + The RNG used to generate key material for trusted keys. + Can be one of: + - "kernel" + - the same value as trusted.source: "tpm" or "tee" + - "default" + If not specified, "default" is used. In this case, + the RNG's choice is left 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 f614dad7de12..2fe6fd1a2bbd 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. +Users may override this by specifying ``trusted.rng=kernel`` on the kernel +command-line to override the used RNG with the kernel's random number pool. + Encrypted Keys -------------- 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 7cdbd16aed30..9235fb7d0ec9 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 char *trusted_rng = "default"; +module_param_named(rng, trusted_rng, charp, 0); +MODULE_PARM_DESC(rng, "Select trusted key 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,28 @@ static int __init init_trusted(void) strlen(trusted_key_sources[i].name))) continue; + /* + * We always support trusted.rng="kernel" and "default" as + * well as trusted.rng=$trusted.source if the trust source + * defines its own get_random callback. + */ + get_random = trusted_key_sources[i].ops->get_random; + if (trusted_rng && strcmp(trusted_rng, "default")) { + if (!strcmp(trusted_rng, "kernel")) { + get_random = kernel_get_random; + } else if (strcmp(trusted_rng, trusted_key_sources[i].name) || + !get_random) { + pr_warn("Unsupported RNG. Supported: kernel"); + if (get_random) + pr_cont(", %s", trusted_key_sources[i].name); + pr_cont(", default\n"); + return -EINVAL; + } + } + + if (!get_random) + 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 +362,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; -- cgit v1.2.3 From 007c3ff11f38d83cc95b0f402e432cbf484e3c31 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Fri, 13 May 2022 16:57:02 +0200 Subject: crypto: caam - add in-kernel interface for blob generator The NXP Cryptographic Acceleration and Assurance Module (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 Reviewed-by: Pankaj Gupta Tested-by: Tim Harvey Tested-by: Matthias Schiffer Tested-by: Pankaj Gupta Tested-by: Michael Walle # on ls1028a (non-E and E) Tested-by: John Ernberg # iMX8QXP Signed-off-by: Steffen Trumtrar Signed-off-by: Ahmad Fatoum Signed-off-by: Jarkko Sakkinen --- drivers/crypto/caam/Kconfig | 3 + drivers/crypto/caam/Makefile | 1 + drivers/crypto/caam/blob_gen.c | 182 +++++++++++++++++++++++++++++++++++++++++ include/soc/fsl/caam-blob.h | 103 +++++++++++++++++++++++ 4 files changed, 289 insertions(+) create mode 100644 drivers/crypto/caam/blob_gen.c create mode 100644 include/soc/fsl/caam-blob.h (limited to 'include') 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..6345c7269eb0 --- /dev/null +++ b/drivers/crypto/caam/blob_gen.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2015 Pengutronix, Steffen Trumtrar + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum + */ + +#define pr_fmt(fmt) "caam blob_gen: " fmt + +#include +#include + +#include "compat.h" +#include "desc_constr.h" +#include "desc.h" +#include "error.h" +#include "intern.h" +#include "jr.h" +#include "regs.h" + +#define CAAM_BLOB_DESC_BYTES_MAX \ + /* Command to initialize & stating length of descriptor */ \ + (CAAM_CMD_SZ + \ + /* Command to append the key-modifier + key-modifier data */ \ + CAAM_CMD_SZ + CAAM_BLOB_KEYMOD_LENGTH + \ + /* Command to include input key + pointer to the input key */ \ + CAAM_CMD_SZ + CAAM_PTR_SZ_MAX + \ + /* Command to include output key + pointer to the output key */ \ + CAAM_CMD_SZ + CAAM_PTR_SZ_MAX + \ + /* Command describing the operation to perform */ \ + CAAM_CMD_SZ) + +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); +} + +int caam_process_blob(struct caam_blob_priv *priv, + struct caam_blob_info *info, bool encap) +{ + struct caam_blob_job_result testres; + struct device *jrdev = &priv->jrdev; + dma_addr_t dma_in, dma_out; + int op = OP_PCLID_BLOB; + size_t output_len; + u32 *desc; + int ret; + + if (info->key_mod_len > CAAM_BLOB_KEYMOD_LENGTH) + return -EINVAL; + + if (encap) { + op |= OP_TYPE_ENCAP_PROTOCOL; + output_len = info->input_len + CAAM_BLOB_OVERHEAD; + } else { + op |= OP_TYPE_DECAP_PROTOCOL; + output_len = info->input_len - CAAM_BLOB_OVERHEAD; + } + + desc = kzalloc(CAAM_BLOB_DESC_BYTES_MAX, GFP_KERNEL | GFP_DMA); + if (!desc) + return -ENOMEM; + + dma_in = dma_map_single(jrdev, info->input, info->input_len, + 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, info->output, output_len, + 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, info->key_mod, info->key_mod_len, + info->key_mod_len, CLASS_2 | KEY_DEST_CLASS_REG); + append_seq_in_ptr_intlen(desc, dma_in, info->input_len, 0); + append_seq_out_ptr_intlen(desc, dma_out, output_len, 0); + append_operation(desc, op); + + print_hex_dump_debug("data@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 1, info->input, + info->input_len, 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, info->output, + output_len, false); + } + + if (ret == 0) + info->output_len = output_len; + + dma_unmap_single(jrdev, dma_out, output_len, DMA_FROM_DEVICE); +out_unmap_in: + dma_unmap_single(jrdev, dma_in, info->input_len, DMA_TO_DEVICE); +out_free: + kfree(desc); + + return ret; +} +EXPORT_SYMBOL(caam_process_blob); + +struct caam_blob_priv *caam_blob_gen_init(void) +{ + struct caam_drv_private *ctrlpriv; + struct device *jrdev; + + /* + * caam_blob_gen_init() may expectedly fail with -ENODEV, e.g. when + * CAAM driver didn't probe or when SoC lacks BLOB support. An + * error would be harsh in this case, so we stick to info level. + */ + + jrdev = caam_jr_alloc(); + if (IS_ERR(jrdev)) { + pr_info("job ring requested, but none currently available\n"); + return ERR_PTR(-ENODEV); + } + + ctrlpriv = dev_get_drvdata(jrdev->parent); + if (!ctrlpriv->blob_present) { + dev_info(jrdev, "no hardware blob generation support\n"); + caam_jr_free(jrdev); + return ERR_PTR(-ENODEV); + } + + 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..937cac52f36d --- /dev/null +++ b/include/soc/fsl/caam-blob.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Pengutronix, Ahmad Fatoum + */ + +#ifndef __CAAM_BLOB_GEN +#define __CAAM_BLOB_GEN + +#include +#include + +#define CAAM_BLOB_KEYMOD_LENGTH 16 +#define CAAM_BLOB_OVERHEAD (32 + 16) +#define CAAM_BLOB_MAX_LEN 4096 + +struct caam_blob_priv; + +/** + * struct caam_blob_info - information for CAAM blobbing + * @input: pointer to input buffer (must be DMAable) + * @input_len: length of @input buffer in bytes. + * @output: pointer to output buffer (must be DMAable) + * @output_len: length of @output buffer in bytes. + * @key_mod: key modifier + * @key_mod_len: length of @key_mod in bytes. + * May not exceed %CAAM_BLOB_KEYMOD_LENGTH + */ +struct caam_blob_info { + void *input; + size_t input_len; + + void *output; + size_t output_len; + + const void *key_mod; + size_t key_mod_len; +}; + +/** + * caam_blob_gen_init - initialize blob generation + * Return: pointer to new &struct caam_blob_priv instance on success + * and ``ERR_PTR(-ENODEV)`` if CAAM has no hardware blobbing support + * or no job ring could be allocated. + */ +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_process_blob - encapsulate or decapsulate blob + * @priv: instance returned by caam_blob_gen_init() + * @info: pointer to blobbing info describing key, blob and + * key modifier buffers. + * @encap: true for encapsulation, false for decapsulation + * + * Return: %0 and sets ``info->output_len`` on success and a negative + * error code otherwise. + */ +int caam_process_blob(struct caam_blob_priv *priv, + struct caam_blob_info *info, bool encap); + +/** + * caam_encap_blob - encapsulate blob + * @priv: instance returned by caam_blob_gen_init() + * @info: pointer to blobbing info describing input key, + * output blob and key modifier buffers. + * + * Return: %0 and sets ``info->output_len`` on success and + * a negative error code otherwise. + */ +static inline int caam_encap_blob(struct caam_blob_priv *priv, + struct caam_blob_info *info) +{ + if (info->output_len < info->input_len + CAAM_BLOB_OVERHEAD) + return -EINVAL; + + return caam_process_blob(priv, info, true); +} + +/** + * caam_decap_blob - decapsulate blob + * @priv: instance returned by caam_blob_gen_init() + * @info: pointer to blobbing info describing output key, + * input blob and key modifier buffers. + * + * Return: %0 and sets ``info->output_len`` on success and + * a negative error code otherwise. + */ +static inline int caam_decap_blob(struct caam_blob_priv *priv, + struct caam_blob_info *info) +{ + if (info->input_len < CAAM_BLOB_OVERHEAD || + info->output_len < info->input_len - CAAM_BLOB_OVERHEAD) + return -EINVAL; + + return caam_process_blob(priv, info, false); +} + +#endif -- cgit v1.2.3 From e9c5048c2de1913d0bcd589bc1487810c2e24bc1 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Fri, 13 May 2022 16:57:03 +0200 Subject: 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. Reviewed-by: David Gstir Reviewed-by: Pankaj Gupta Reviewed-by: Jarkko Sakkinen Tested-by: Tim Harvey Tested-by: Matthias Schiffer Tested-by: Pankaj Gupta Tested-by: Michael Walle # on ls1028a (non-E and E) Tested-by: John Ernberg # iMX8QXP Signed-off-by: Ahmad Fatoum Signed-off-by: Jarkko Sakkinen --- Documentation/admin-guide/kernel-parameters.txt | 1 + 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 | 80 +++++++++++++++++++++++++ security/keys/trusted-keys/trusted_core.c | 6 +- 6 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 include/keys/trusted_caam.h create mode 100644 security/keys/trusted-keys/trusted_caam.c (limited to 'include') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 4deed1908a75..9afb7046ce97 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -5958,6 +5958,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/include/keys/trusted_caam.h b/include/keys/trusted_caam.h new file mode 100644 index 000000000000..73fe2f32f65e --- /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 trusted_key_caam_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..e3415c520c0a --- /dev/null +++ b/security/keys/trusted-keys/trusted_caam.c @@ -0,0 +1,80 @@ +// 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 "SECURE_KEY" + +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 ret; + struct caam_blob_info info = { + .input = p->key, .input_len = p->key_len, + .output = p->blob, .output_len = MAX_BLOB_SIZE, + .key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1, + }; + + ret = caam_encap_blob(blobifier, &info); + if (ret) + return ret; + + p->blob_len = info.output_len; + return 0; +} + +static int trusted_caam_unseal(struct trusted_key_payload *p, char *datablob) +{ + int ret; + struct caam_blob_info info = { + .input = p->blob, .input_len = p->blob_len, + .output = p->key, .output_len = MAX_KEY_SIZE, + .key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1, + }; + + ret = caam_decap_blob(blobifier, &info); + if (ret) + return ret; + + p->key_len = info.output_len; + return 0; +} + +static int trusted_caam_init(void) +{ + int ret; + + blobifier = caam_blob_gen_init(); + if (IS_ERR(blobifier)) + 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 trusted_key_caam_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 9235fb7d0ec9..c6fc50d67214 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(rng, "Select trusted key 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", &trusted_key_caam_ops }, +#endif }; DEFINE_STATIC_CALL_NULL(trusted_key_init, *trusted_key_sources[0].ops->init); -- cgit v1.2.3