[RFC PATCH HBK: 4/8] keys-trusted: re-factored caam based trusted key

From: Pankaj Gupta
Date: Tue Sep 06 2022 - 01:51:26 EST


Re-factored caam based trusted key code:
- Two separate definition for encap and decap having
separate code for creating CAAM job descriptor.

Signed-off-by: Pankaj Gupta <pankaj.gupta@xxxxxxx>
---
drivers/crypto/caam/blob_gen.c | 122 +++++++++++++++++++++++++++++----
include/soc/fsl/caam-blob.h | 28 +++-----
2 files changed, 118 insertions(+), 32 deletions(-)

diff --git a/drivers/crypto/caam/blob_gen.c b/drivers/crypto/caam/blob_gen.c
index 6345c7269eb0..c128a83cc8dd 100644
--- a/drivers/crypto/caam/blob_gen.c
+++ b/drivers/crypto/caam/blob_gen.c
@@ -2,6 +2,7 @@
/*
* Copyright (C) 2015 Pengutronix, Steffen Trumtrar <kernel@xxxxxxxxxxxxxx>
* Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@xxxxxxxxxxxxxx>
+ * Copyright 2022 NXP, Pankaj Gupta <pankaj.gupta@xxxxxxx>
*/

#define pr_fmt(fmt) "caam blob_gen: " fmt
@@ -29,10 +30,6 @@
/* Command describing the operation to perform */ \
CAAM_CMD_SZ)

-struct caam_blob_priv {
- struct device jrdev;
-};
-
struct caam_blob_job_result {
int err;
struct completion completion;
@@ -58,8 +55,19 @@ static void caam_blob_job_done(struct device *dev, u32 *desc, u32 err, void *con
complete(&res->completion);
}

-int caam_process_blob(struct caam_blob_priv *priv,
- struct caam_blob_info *info, bool encap)
+
+
+/** caam_encap_blob - encapsulate blob
+ *
+ * @priv: instance returned by caam_blob_gen_init
+ * @info: pointer to blobbing info describing input key,
+ * output blob and key modifier buffers.
+ *
+ * returns 0 and sets info->output_len on success and returns
+ * a negative error code otherwise.
+ */
+int caam_encap_blob(struct caam_blob_priv *priv,
+ struct caam_blob_info *info)
{
struct caam_blob_job_result testres;
struct device *jrdev = &priv->jrdev;
@@ -72,14 +80,102 @@ int caam_process_blob(struct caam_blob_priv *priv,
if (info->key_mod_len > CAAM_BLOB_KEYMOD_LENGTH)
return -EINVAL;

- if (encap) {
- op |= OP_TYPE_ENCAP_PROTOCOL;
- output_len = info->input_len + CAAM_BLOB_OVERHEAD;
- } else {
- op |= OP_TYPE_DECAP_PROTOCOL;
- output_len = info->input_len - CAAM_BLOB_OVERHEAD;
+ op |= OP_TYPE_ENCAP_PROTOCOL;
+ output_len = info->input_len + CAAM_BLOB_OVERHEAD;
+
+ desc = kzalloc(CAAM_BLOB_DESC_BYTES_MAX, GFP_KERNEL | GFP_DMA);
+ if (!desc)
+ return -ENOMEM;
+
+ dma_in = dma_map_single(jrdev, info->input, info->input_len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, dma_in)) {
+ dev_err(jrdev, "unable to map input DMA buffer\n");
+ ret = -ENOMEM;
+ goto out_free;
+ }
+
+ dma_out = dma_map_single(jrdev, info->output, output_len,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(jrdev, dma_out)) {
+ dev_err(jrdev, "unable to map output DMA buffer\n");
+ ret = -ENOMEM;
+ goto out_unmap_in;
+ }
+
+ /*
+ * A data blob is encrypted using a blob key (BK); a random number.
+ * The BK is used as an AES-CCM key. The initial block (B0) and the
+ * initial counter (Ctr0) are generated automatically and stored in
+ * Class 1 Context DWords 0+1+2+3. The random BK is stored in the
+ * Class 1 Key Register. Operation Mode is set to AES-CCM.
+ */
+
+ init_job_desc(desc, 0);
+ append_key_as_imm(desc, info->key_mod, info->key_mod_len,
+ info->key_mod_len, CLASS_2 | KEY_DEST_CLASS_REG);
+ append_seq_in_ptr_intlen(desc, dma_in, info->input_len, 0);
+ append_seq_out_ptr_intlen(desc, dma_out, output_len, 0);
+ append_operation(desc, op);
+
+ print_hex_dump_debug("data@"__stringify(__LINE__)": ",
+ DUMP_PREFIX_ADDRESS, 16, 1, info->input,
+ info->input_len, false);
+ print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ",
+ DUMP_PREFIX_ADDRESS, 16, 1, desc,
+ desc_bytes(desc), false);
+
+ testres.err = 0;
+ init_completion(&testres.completion);
+
+ ret = caam_jr_enqueue(jrdev, desc, caam_blob_job_done, &testres);
+ if (ret == -EINPROGRESS) {
+ wait_for_completion(&testres.completion);
+ ret = testres.err;
+ print_hex_dump_debug("output@"__stringify(__LINE__)": ",
+ DUMP_PREFIX_ADDRESS, 16, 1, info->output,
+ output_len, false);
}

+ if (ret == 0)
+ info->output_len = output_len;
+
+ dma_unmap_single(jrdev, dma_out, output_len, DMA_FROM_DEVICE);
+out_unmap_in:
+ dma_unmap_single(jrdev, dma_in, info->input_len, DMA_TO_DEVICE);
+out_free:
+ kfree(desc);
+
+ return ret;
+}
+EXPORT_SYMBOL(caam_encap_blob);
+
+/** caam_decap_blob - decapsulate blob
+ *
+ * @priv: instance returned by caam_blob_gen_init
+ * @info: pointer to blobbing info describing output key,
+ * input blob and key modifier buffers.
+ *
+ * returns 0 and sets info->output_len on success and returns
+ * a negative error code otherwise.
+ */
+int caam_decap_blob(struct caam_blob_priv *priv,
+ struct caam_blob_info *info)
+{
+ struct caam_blob_job_result testres;
+ struct device *jrdev = &priv->jrdev;
+ dma_addr_t dma_in, dma_out;
+ int op = OP_PCLID_BLOB;
+ size_t output_len;
+ u32 *desc;
+ int ret;
+
+ if (info->key_mod_len > CAAM_BLOB_KEYMOD_LENGTH)
+ return -EINVAL;
+
+ op |= OP_TYPE_DECAP_PROTOCOL;
+ output_len = info->input_len - CAAM_BLOB_OVERHEAD;
+
desc = kzalloc(CAAM_BLOB_DESC_BYTES_MAX, GFP_KERNEL | GFP_DMA);
if (!desc)
return -ENOMEM;
@@ -145,7 +241,7 @@ int caam_process_blob(struct caam_blob_priv *priv,

return ret;
}
-EXPORT_SYMBOL(caam_process_blob);
+EXPORT_SYMBOL(caam_decap_blob);

struct caam_blob_priv *caam_blob_gen_init(void)
{
diff --git a/include/soc/fsl/caam-blob.h b/include/soc/fsl/caam-blob.h
index 937cac52f36d..632944df29f7 100644
--- a/include/soc/fsl/caam-blob.h
+++ b/include/soc/fsl/caam-blob.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 Pengutronix, Ahmad Fatoum <kernel@xxxxxxxxxxxxxx>
+ * Copyright 2022 NXP, Pankaj Gupta <pankaj.gupta@xxxxxxx>
*/

#ifndef __CAAM_BLOB_GEN
@@ -13,7 +14,10 @@
#define CAAM_BLOB_OVERHEAD (32 + 16)
#define CAAM_BLOB_MAX_LEN 4096

-struct caam_blob_priv;
+struct caam_blob_priv {
+ struct device jrdev;
+};
+

/**
* struct caam_blob_info - information for CAAM blobbing
@@ -72,15 +76,8 @@ int caam_process_blob(struct caam_blob_priv *priv,
* Return: %0 and sets ``info->output_len`` on success and
* a negative error code otherwise.
*/
-static inline int caam_encap_blob(struct caam_blob_priv *priv,
- struct caam_blob_info *info)
-{
- if (info->output_len < info->input_len + CAAM_BLOB_OVERHEAD)
- return -EINVAL;
-
- return caam_process_blob(priv, info, true);
-}
-
+int caam_encap_blob(struct caam_blob_priv *priv,
+ struct caam_blob_info *info);
/**
* caam_decap_blob - decapsulate blob
* @priv: instance returned by caam_blob_gen_init()
@@ -90,14 +87,7 @@ static inline int caam_encap_blob(struct caam_blob_priv *priv,
* Return: %0 and sets ``info->output_len`` on success and
* a negative error code otherwise.
*/
-static inline int caam_decap_blob(struct caam_blob_priv *priv,
- struct caam_blob_info *info)
-{
- if (info->input_len < CAAM_BLOB_OVERHEAD ||
- info->output_len < info->input_len - CAAM_BLOB_OVERHEAD)
- return -EINVAL;
-
- return caam_process_blob(priv, info, false);
-}
+int caam_decap_blob(struct caam_blob_priv *priv,
+ struct caam_blob_info *info);

#endif
--
2.17.1