2021-10-11 10:04:28

by Ahmad Fatoum

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

Series applies on top of Andreas' regression fix here:
https://lore.kernel.org/linux-integrity/[email protected]/

v3 was here:
https://lore.kernel.org/linux-integrity/cover.9fc9298fd9d63553491871d043a18affc2dbc8a8.1626885907.git-series.a.fatoum@pengutronix.de

v3 -> v4:
- Collected Acked-by's, Reviewed-by's and Tested-by
- Fixed typo spotted by David
- Rebased on top of Andreas' regression fix and pulled Kconfig
inflexibility fix back into series

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 <[email protected]>
Cc: Richard Weinberger <[email protected]>
Cc: Franck LENORMAND <[email protected]>
Cc: Sumit Garg <[email protected]>
Cc: Andreas Rammhold <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

Ahmad Fatoum (5):
KEYS: trusted: allow use of TEE as backend without TCG_TPM support
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 +-
crypto/asymmetric_keys/Kconfig | 2 +-
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/Kconfig | 18 +-
security/keys/trusted-keys/Kconfig | 38 ++-
security/keys/trusted-keys/Makefile | 10 +-
security/keys/trusted-keys/trusted_caam.c | 74 +++++-
security/keys/trusted-keys/trusted_core.c | 27 +-
15 files changed, 519 insertions(+), 30 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/Kconfig
create mode 100644 security/keys/trusted-keys/trusted_caam.c

base-commit: 69226657a551b835e9bee694313b1e3355fa0ac8
--
git-series 0.9.1


2021-10-11 10:05:49

by Ahmad Fatoum

[permalink] [raw]
Subject: [PATCH v4 4/5] crypto: caam - add in-kernel interface for blob generator

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 <[email protected]>
Tested-By: Tim Harvey <[email protected]>
Signed-off-by: Steffen Trumtrar <[email protected]>
Signed-off-by: Ahmad Fatoum <[email protected]>
---
To: "Horia Geantă" <[email protected]>
To: Aymen Sghaier <[email protected]>
To: Herbert Xu <[email protected]>
To: "David S. Miller" <[email protected]>
Cc: James Bottomley <[email protected]>
Cc: Jarkko Sakkinen <[email protected]>
Cc: Mimi Zohar <[email protected]>
Cc: David Howells <[email protected]>
Cc: James Morris <[email protected]>
Cc: Eric Biggers <[email protected]>
Cc: "Serge E. Hallyn" <[email protected]>
Cc: Udit Agarwal <[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]
---
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 <[email protected]>
+ * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <[email protected]>
+ */
+
+#include <linux/device.h>
+#include <soc/fsl/caam-blob.h>
+
+#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 <[email protected]>
+ */
+
+#ifndef __CAAM_BLOB_GEN
+#define __CAAM_BLOB_GEN
+
+#include <linux/types.h>
+
+#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
--
git-series 0.9.1

2021-11-01 08:01:22

by Ahmad Fatoum

[permalink] [raw]
Subject: Re: [PATCH v4 4/5] crypto: caam - add in-kernel interface for blob generator

Hello Horia, Aymen,

On 11.10.21 12:02, Ahmad Fatoum wrote:
> 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.

Did you have time to look at this again?

I have incorporated the changes request in v1 and the
code has since been reviewed and tested by others.

Thanks,
Ahmad

> Reviewed-by: David Gstir <[email protected]>
> Tested-By: Tim Harvey <[email protected]>
> Signed-off-by: Steffen Trumtrar <[email protected]>
> Signed-off-by: Ahmad Fatoum <[email protected]>
> ---
> To: "Horia Geantă" <[email protected]>
> To: Aymen Sghaier <[email protected]>
> To: Herbert Xu <[email protected]>
> To: "David S. Miller" <[email protected]>
> Cc: James Bottomley <[email protected]>
> Cc: Jarkko Sakkinen <[email protected]>
> Cc: Mimi Zohar <[email protected]>
> Cc: David Howells <[email protected]>
> Cc: James Morris <[email protected]>
> Cc: Eric Biggers <[email protected]>
> Cc: "Serge E. Hallyn" <[email protected]>
> Cc: Udit Agarwal <[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]
> ---
> 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 <[email protected]>
> + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <[email protected]>
> + */
> +
> +#include <linux/device.h>
> +#include <soc/fsl/caam-blob.h>
> +
> +#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 <[email protected]>
> + */
> +
> +#ifndef __CAAM_BLOB_GEN
> +#define __CAAM_BLOB_GEN
> +
> +#include <linux/types.h>
> +
> +#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
>


--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2021-11-24 07:48:32

by Ahmad Fatoum

[permalink] [raw]
Subject: Re: [PATCH v4 4/5] crypto: caam - add in-kernel interface for blob generator

Hello again,

On 01.11.21 09:00, Ahmad Fatoum wrote:
> Hello Horia, Aymen,
>
> On 11.10.21 12:02, Ahmad Fatoum wrote:
>> 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.
>
> Did you have time to look at this again?

Ping.

>
> I have incorporated the changes request in v1 and the
> code has since been reviewed and tested by others.
>
> Thanks,
> Ahmad
>
>> Reviewed-by: David Gstir <[email protected]>
>> Tested-By: Tim Harvey <[email protected]>
>> Signed-off-by: Steffen Trumtrar <[email protected]>
>> Signed-off-by: Ahmad Fatoum <[email protected]>
>> ---
>> To: "Horia Geantă" <[email protected]>
>> To: Aymen Sghaier <[email protected]>
>> To: Herbert Xu <[email protected]>
>> To: "David S. Miller" <[email protected]>
>> Cc: James Bottomley <[email protected]>
>> Cc: Jarkko Sakkinen <[email protected]>
>> Cc: Mimi Zohar <[email protected]>
>> Cc: David Howells <[email protected]>
>> Cc: James Morris <[email protected]>
>> Cc: Eric Biggers <[email protected]>
>> Cc: "Serge E. Hallyn" <[email protected]>
>> Cc: Udit Agarwal <[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]
>> ---
>> 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 <[email protected]>
>> + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <[email protected]>
>> + */
>> +
>> +#include <linux/device.h>
>> +#include <soc/fsl/caam-blob.h>
>> +
>> +#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 <[email protected]>
>> + */
>> +
>> +#ifndef __CAAM_BLOB_GEN
>> +#define __CAAM_BLOB_GEN
>> +
>> +#include <linux/types.h>
>> +
>> +#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
>>
>
>


--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2021-12-05 00:18:46

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v4 4/5] crypto: caam - add in-kernel interface for blob generator

On Mon, Oct 11, 2021 at 12:02:37PM +0200, Ahmad Fatoum wrote:
> 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 <[email protected]>
> Tested-By: Tim Harvey <[email protected]>
> Signed-off-by: Steffen Trumtrar <[email protected]>
> Signed-off-by: Ahmad Fatoum <[email protected]>

What is CAAM? This is missing.

/Jarkko

2021-12-13 10:41:31

by Ahmad Fatoum

[permalink] [raw]
Subject: Re: [PATCH v4 4/5] crypto: caam - add in-kernel interface for blob generator

Hello Jarkko,

On 05.12.21 01:18, Jarkko Sakkinen wrote:
> On Mon, Oct 11, 2021 at 12:02:37PM +0200, Ahmad Fatoum wrote:
>> 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 <[email protected]>
>> Tested-By: Tim Harvey <[email protected]>
>> Signed-off-by: Steffen Trumtrar <[email protected]>
>> Signed-off-by: Ahmad Fatoum <[email protected]>
>
> What is CAAM? This is missing.

That's Crypto Accelerator on NXP SoCs. There is a description in the cover
letter and in the follow-up patch wiring this into the new trusted key
source. I didn't elaborate on this here as this patch touches
drivers/crypto/caam and I assumed familiarity.

For v5, I can add some extra info:

"The NXP Cryptographic Acceleration and Assurance Module (CAAM)
can be used to protect user-defined data across system reboot..."

Sounds good? Does the last patch in the series look ok to you?

Cheers,
Ahmad

>
> /Jarkko
>


--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2021-12-23 07:20:12

by Pankaj Gupta (OSS)

[permalink] [raw]
Subject: RE: [EXT] [PATCH v4 4/5] crypto: caam - add in-kernel interface for blob generator

Reviewed-by: Pankaj Gupta <[email protected]>

> -----Original Message-----
> From: Ahmad Fatoum <[email protected]>
> Sent: Monday, October 11, 2021 3:33 PM
> To: Horia Geanta <[email protected]>; Aymen Sghaier
> <[email protected]>; Herbert Xu <[email protected]>;
> David S. Miller <[email protected]>
> Cc: [email protected]; David Gstir <[email protected]>;
> [email protected]; Ahmad Fatoum <[email protected]>; James
> Bottomley <[email protected]>; Jarkko Sakkinen <[email protected]>; Mimi
> Zohar <[email protected]>; David Howells <[email protected]>; James
> Morris <[email protected]>; Eric Biggers <[email protected]>; Serge E.
> Hallyn <[email protected]>; Udit Agarwal <[email protected]>; Jan
> Luebbe <[email protected]>; Richard Weinberger <[email protected]>;
> Franck Lenormand <[email protected]>; Sumit Garg
> <[email protected]>; [email protected];
> [email protected]; [email protected]; linux-
> [email protected]; [email protected]
> Subject: [EXT] [PATCH v4 4/5] crypto: caam - add in-kernel interface for blob
> generator
>
> Caution: EXT Email
>
> 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 <[email protected]>
> Tested-By: Tim Harvey <[email protected]>
> Signed-off-by: Steffen Trumtrar <[email protected]>
> Signed-off-by: Ahmad Fatoum <[email protected]>
> ---
> To: "Horia Geantă" <[email protected]>
> To: Aymen Sghaier <[email protected]>
> To: Herbert Xu <[email protected]>
> To: "David S. Miller" <[email protected]>
> Cc: James Bottomley <[email protected]>
> Cc: Jarkko Sakkinen <[email protected]>
> Cc: Mimi Zohar <[email protected]>
> Cc: David Howells <[email protected]>
> Cc: James Morris <[email protected]>
> Cc: Eric Biggers <[email protected]>
> Cc: "Serge E. Hallyn" <[email protected]>
> Cc: Udit Agarwal <[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]
> ---
> 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
> +<[email protected]>
> + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <[email protected]>
> +*/
> +
> +#include <linux/device.h>
> +#include <soc/fsl/caam-blob.h>
> +
> +#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 <[email protected]>
> +*/
> +
> +#ifndef __CAAM_BLOB_GEN
> +#define __CAAM_BLOB_GEN
> +
> +#include <linux/types.h>
> +
> +#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
> --
> git-series 0.9.1