diff mbox series

[v5,4/5] crypto: caam - add in-kernel interface for blob generator

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

Commit Message

Ahmad Fatoum Feb. 22, 2022, 7:58 p.m. UTC
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 <david@sigma-star.at>
Reviewed-by: Pankaj Gupta <pankaj.gupta@nxp.com>
Tested-By: Tim Harvey <tharvey@gateworks.com>
Tested-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
To: "Horia Geantă" <horia.geanta@nxp.com>
To: Aymen Sghaier <aymen.sghaier@nxp.com>
To: Herbert Xu <herbert@gondor.apana.org.au>
To: "David S. Miller" <davem@davemloft.net>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: David Howells <dhowells@redhat.com>
Cc: James Morris <jmorris@namei.org>
Cc: Eric Biggers <ebiggers@kernel.org>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: Jan Luebbe <j.luebbe@pengutronix.de>
Cc: David Gstir <david@sigma-star.at>
Cc: Richard Weinberger <richard@nod.at>
Cc: Franck LENORMAND <franck.lenormand@nxp.com>
Cc: Sumit Garg <sumit.garg@linaro.org>
Cc: Tim Harvey <tharvey@gateworks.com>
Cc: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Cc: Pankaj Gupta <pankaj.gupta@nxp.com>
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

Comments

jarkko@kernel.org Feb. 23, 2022, 3:41 p.m. UTC | #1
On Tue, Feb 22, 2022 at 08:58:18PM +0100, Ahmad Fatoum wrote:
> 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 <david@sigma-star.at>
> Reviewed-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> Tested-By: Tim Harvey <tharvey@gateworks.com>
> Tested-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> To: "Horia Geantă" <horia.geanta@nxp.com>
> To: Aymen Sghaier <aymen.sghaier@nxp.com>
> To: Herbert Xu <herbert@gondor.apana.org.au>
> To: "David S. Miller" <davem@davemloft.net>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Jarkko Sakkinen <jarkko@kernel.org>
> Cc: Mimi Zohar <zohar@linux.ibm.com>
> Cc: David Howells <dhowells@redhat.com>
> Cc: James Morris <jmorris@namei.org>
> Cc: Eric Biggers <ebiggers@kernel.org>
> Cc: "Serge E. Hallyn" <serge@hallyn.com>
> Cc: Jan Luebbe <j.luebbe@pengutronix.de>
> Cc: David Gstir <david@sigma-star.at>
> Cc: Richard Weinberger <richard@nod.at>
> Cc: Franck LENORMAND <franck.lenormand@nxp.com>
> Cc: Sumit Garg <sumit.garg@linaro.org>
> Cc: Tim Harvey <tharvey@gateworks.com>
> Cc: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
> Cc: Pankaj Gupta <pankaj.gupta@nxp.com>
> 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 <kernel@pengutronix.de>
> + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
> + */
> +
> +#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;

Nit: the amount of magic numbers is overwhelming here. I neither understand
the statement nor how that comment should help me to understand it.

BR, Jarkko
Ahmad Fatoum Feb. 23, 2022, 4:20 p.m. UTC | #2
On 23.02.22 16:41, Jarkko Sakkinen wrote:
> On Tue, Feb 22, 2022 at 08:58:18PM +0100, Ahmad Fatoum wrote:
>> 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 <david@sigma-star.at>
>> Reviewed-by: Pankaj Gupta <pankaj.gupta@nxp.com>
>> Tested-By: Tim Harvey <tharvey@gateworks.com>
>> Tested-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
>> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>> To: "Horia Geantă" <horia.geanta@nxp.com>
>> To: Aymen Sghaier <aymen.sghaier@nxp.com>
>> To: Herbert Xu <herbert@gondor.apana.org.au>
>> To: "David S. Miller" <davem@davemloft.net>
>> Cc: James Bottomley <jejb@linux.ibm.com>
>> Cc: Jarkko Sakkinen <jarkko@kernel.org>
>> Cc: Mimi Zohar <zohar@linux.ibm.com>
>> Cc: David Howells <dhowells@redhat.com>
>> Cc: James Morris <jmorris@namei.org>
>> Cc: Eric Biggers <ebiggers@kernel.org>
>> Cc: "Serge E. Hallyn" <serge@hallyn.com>
>> Cc: Jan Luebbe <j.luebbe@pengutronix.de>
>> Cc: David Gstir <david@sigma-star.at>
>> Cc: Richard Weinberger <richard@nod.at>
>> Cc: Franck LENORMAND <franck.lenormand@nxp.com>
>> Cc: Sumit Garg <sumit.garg@linaro.org>
>> Cc: Tim Harvey <tharvey@gateworks.com>
>> Cc: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
>> Cc: Pankaj Gupta <pankaj.gupta@nxp.com>
>> 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 <kernel@pengutronix.de>
>> + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
>> + */
>> +
>> +#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;
> 
> Nit: the amount of magic numbers is overwhelming here. I neither understand
> the statement nor how that comment should help me to understand it.

header              =  4
(key mod immediate) = (4 + ALIGN(keymod_len, 4))
2x pointer          =  2 * (4 + 4 + CAAM_PTR_SZ_MAX)
op                  =  4

I haven't heard back from the CAAM maintainers yet since v1. Perhaps now
is a good occasion to chime in? :-)

@Jarkko, could you take a look at patch 5? That's the gist of the series
and I have yet to get maintainer feedback on that one.

Cheers,
Ahmad


> 
> BR, Jarkko
>
Pankaj Gupta Feb. 25, 2022, 12:20 p.m. UTC | #3
> -----Original Message-----
> From: Ahmad Fatoum <a.fatoum@pengutronix.de>
> Sent: Wednesday, February 23, 2022 9:50 PM
> To: Jarkko Sakkinen <jarkko@kernel.org>
> Cc: Horia Geanta <horia.geanta@nxp.com>; Aymen Sghaier
> <aymen.sghaier@nxp.com>; Herbert Xu <herbert@gondor.apana.org.au>;
> David S. Miller <davem@davemloft.net>; kernel@pengutronix.de; David Gstir
> <david@sigma-star.at>; Pankaj Gupta <pankaj.gupta@nxp.com>;
> tharvey@gateworks.com; Matthias Schiffer <matthias.schiffer@ew.tq-
> group.com>; James Bottomley <jejb@linux.ibm.com>; Mimi Zohar
> <zohar@linux.ibm.com>; David Howells <dhowells@redhat.com>; James Morris
> <jmorris@namei.org>; Eric Biggers <ebiggers@kernel.org>; Serge E. Hallyn
> <serge@hallyn.com>; Jan Luebbe <j.luebbe@pengutronix.de>; Richard
> Weinberger <richard@nod.at>; Franck Lenormand
> <franck.lenormand@nxp.com>; Sumit Garg <sumit.garg@linaro.org>; 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: [EXT] Re: [PATCH v5 4/5] crypto: caam - add in-kernel interface for blob
> generator
> 
> Caution: EXT Email
> 
> On 23.02.22 16:41, Jarkko Sakkinen wrote:
> > On Tue, Feb 22, 2022 at 08:58:18PM +0100, Ahmad Fatoum wrote:
> >> 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 <david@sigma-star.at>
> >> Reviewed-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> >> Tested-By: Tim Harvey <tharvey@gateworks.com>
> >> Tested-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
> >> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> >> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> >> ---
> >> To: "Horia Geantă" <horia.geanta@nxp.com>
> >> To: Aymen Sghaier <aymen.sghaier@nxp.com>
> >> To: Herbert Xu <herbert@gondor.apana.org.au>
> >> To: "David S. Miller" <davem@davemloft.net>
> >> Cc: James Bottomley <jejb@linux.ibm.com>
> >> Cc: Jarkko Sakkinen <jarkko@kernel.org>
> >> Cc: Mimi Zohar <zohar@linux.ibm.com>
> >> Cc: David Howells <dhowells@redhat.com>
> >> Cc: James Morris <jmorris@namei.org>
> >> Cc: Eric Biggers <ebiggers@kernel.org>
> >> Cc: "Serge E. Hallyn" <serge@hallyn.com>
> >> Cc: Jan Luebbe <j.luebbe@pengutronix.de>
> >> Cc: David Gstir <david@sigma-star.at>
> >> Cc: Richard Weinberger <richard@nod.at>
> >> Cc: Franck LENORMAND <franck.lenormand@nxp.com>
> >> Cc: Sumit Garg <sumit.garg@linaro.org>
> >> Cc: Tim Harvey <tharvey@gateworks.com>
> >> Cc: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
> >> Cc: Pankaj Gupta <pankaj.gupta@nxp.com>
> >> 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
> >> +<kernel@pengutronix.de>
> >> + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum
> >> +<kernel@pengutronix.de>  */
> >> +
> >> +#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;
> >
> > Nit: the amount of magic numbers is overwhelming here. I neither
> > understand the statement nor how that comment should help me to
> understand it.
> 
> header              =  4
> (key mod immediate) = (4 + ALIGN(keymod_len, 4))
> 2x pointer          =  2 * (4 + 4 + CAAM_PTR_SZ_MAX)
> op                  =  4

Instead of the function caam_blob_alloc_desc(), it will be great if the caller functions caam_encap_blob()/caam_encap_blob (), could add local array:
uint32_t desc[CAAM_DESC_BYTES_MAX];

> 
> I haven't heard back from the CAAM maintainers yet since v1. Perhaps now is a
> good occasion to chime in? :-)
> 
> @Jarkko, could you take a look at patch 5? That's the gist of the series and I
> have yet to get maintainer feedback on that one.
> 
> Cheers,
> Ahmad
> 
> 
> >
> > BR, Jarkko
> >
> 
> 
> --
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pen
> gutronix.de%2F&amp;data=04%7C01%7Cpankaj.gupta%40nxp.com%7Cc97e9d4
> aaf304124407908d9f6e87101%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%
> 7C0%7C637812300459173929%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wL
> jAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;s
> data=CvnfIXR68DPRCaYrOYQKSv2eSBSNSSJYx2BQJee4yLg%3D&amp;reserved=0
> |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
jarkko@kernel.org Feb. 28, 2022, 12:14 p.m. UTC | #4
On Wed, 2022-02-23 at 17:20 +0100, Ahmad Fatoum wrote:
> On 23.02.22 16:41, Jarkko Sakkinen wrote:
> > On Tue, Feb 22, 2022 at 08:58:18PM +0100, Ahmad Fatoum wrote:
> > > 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 <david@sigma-star.at>
> > > Reviewed-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> > > Tested-By: Tim Harvey <tharvey@gateworks.com>
> > > Tested-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
> > > Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> > > Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> > > ---
> > > To: "Horia Geantă" <horia.geanta@nxp.com>
> > > To: Aymen Sghaier <aymen.sghaier@nxp.com>
> > > To: Herbert Xu <herbert@gondor.apana.org.au>
> > > To: "David S. Miller" <davem@davemloft.net>
> > > Cc: James Bottomley <jejb@linux.ibm.com>
> > > Cc: Jarkko Sakkinen <jarkko@kernel.org>
> > > Cc: Mimi Zohar <zohar@linux.ibm.com>
> > > Cc: David Howells <dhowells@redhat.com>
> > > Cc: James Morris <jmorris@namei.org>
> > > Cc: Eric Biggers <ebiggers@kernel.org>
> > > Cc: "Serge E. Hallyn" <serge@hallyn.com>
> > > Cc: Jan Luebbe <j.luebbe@pengutronix.de>
> > > Cc: David Gstir <david@sigma-star.at>
> > > Cc: Richard Weinberger <richard@nod.at>
> > > Cc: Franck LENORMAND <franck.lenormand@nxp.com>
> > > Cc: Sumit Garg <sumit.garg@linaro.org>
> > > Cc: Tim Harvey <tharvey@gateworks.com>
> > > Cc: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
> > > Cc: Pankaj Gupta <pankaj.gupta@nxp.com>
> > > 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 <kernel@pengutronix.de>
> > > + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
> > > + */
> > > +
> > > +#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;
> > 
> > Nit: the amount of magic numbers is overwhelming here. I neither understand
> > the statement nor how that comment should help me to understand it.
> 
> header              =  4
> (key mod immediate) = (4 + ALIGN(keymod_len, 4))
> 2x pointer          =  2 * (4 + 4 + CAAM_PTR_SZ_MAX)
> op                  =  4

Please create a struct with the associated fields instead and then
it is just sizeof that.

BR, Jarkko
Ahmad Fatoum March 14, 2022, 3:33 p.m. UTC | #5
Hello Pankaj,

On 25.02.22 13:20, Pankaj Gupta wrote:
>>>> +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;
>>>
>>> Nit: the amount of magic numbers is overwhelming here. I neither
>>> understand the statement nor how that comment should help me to
>> understand it.
>>
>> header              =  4
>> (key mod immediate) = (4 + ALIGN(keymod_len, 4))
>> 2x pointer          =  2 * (4 + 4 + CAAM_PTR_SZ_MAX)
>> op                  =  4
> 
> Instead of the function caam_blob_alloc_desc(), it will be great if the caller functions caam_encap_blob()/caam_encap_blob (), could add local array:
> uint32_t desc[CAAM_DESC_BYTES_MAX];

I just looked into this and placing desc on stack is not possible
as it is used for DMA inside caam_jr_enqueue().

Cheers,
Ahmad
Ahmad Fatoum March 16, 2022, 4:44 p.m. UTC | #6
Hello Jarkko,

On 28.02.22 13:14, Jarkko Sakkinen wrote:
> On Wed, 2022-02-23 at 17:20 +0100, Ahmad Fatoum wrote:
>> On 23.02.22 16:41, Jarkko Sakkinen wrote:
>>> On Tue, Feb 22, 2022 at 08:58:18PM +0100, Ahmad Fatoum wrote:
>>>> +       /* header + (key mod immediate) + 2x pointers + op */
>>>> +       len = 4 + (4 + ALIGN(keymod_len, 4)) + 2*(4 + 4 + CAAM_PTR_SZ_MAX) + 4;
>>>
>>> Nit: the amount of magic numbers is overwhelming here. I neither understand
>>> the statement nor how that comment should help me to understand it.
>>
>> header              =  4
>> (key mod immediate) = (4 + ALIGN(keymod_len, 4))
>> 2x pointer          =  2 * (4 + 4 + CAAM_PTR_SZ_MAX)
>> op                  =  4
> 
> Please create a struct with the associated fields instead and then
> it is just sizeof that.

The CAAM descriptor construction code writes the current length
to the first word and then macros are used to append fields to
the descriptor while incrementing the length. The key modifier
is in the middle of the descriptor, so this isn't representable
as a C struct without using VLAs, which are banned in the kernel.
Even if it worked, it's arguably not good style to define a struct
just to compute the size and then cast it to a u32 * to use the
same macros all other CAAM code uses.


I thought this over a bit and figured that we don't really need to
compute the length dynamically as it's at most 44 or 52 bytes
(depending on DMA address width) anyway, so we can just use a fixed
value. I still keep the addition, because I believe there is a value
in seeing how we arrive at the 44 or 52 bytes instead of just hardcoding
it.

Just sent out v6 with these changes. Let me know what you think.

Cheers,
Ahmad
diff mbox series

Patch

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 <kernel@pengutronix.de>
+ * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
+ */
+
+#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 <kernel@pengutronix.de>
+ */
+
+#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