* [RFC PATCH HBK: 1/8] keys-trusted: new cmd line option added
2022-09-05 14:36 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
@ 2022-09-05 14:36 ` Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 2/8] hw-bound-key: flag-is_hbk added to the tfm Pankaj Gupta
` (6 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Pankaj Gupta @ 2022-09-05 14:36 UTC (permalink / raw)
To: gaurav.jain, sahil.malhotra, kshitiz.varshney, horia.geanta,
linux-kernel, V.Sethi
Cc: Pankaj Gupta
Two changes are done:
- new cmd line option "hw" needs to be suffix, to generate the
hw bound key.
for ex:
$:> keyctl add trusted <KEYNAME> 'new 32 hw' @s
$:> keyctl add trusted <KEYNAME> 'load $(cat <KEY_BLOB_FILE_NAME>) hw' @s
- For "new", generating the hw bounded trusted key, updating the input key
length as part of seal operation as well.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
include/keys/trusted-type.h | 2 ++
security/keys/trusted-keys/trusted_caam.c | 6 ++++++
security/keys/trusted-keys/trusted_core.c | 14 ++++++++++++++
3 files changed, 22 insertions(+)
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
index 4eb64548a74f..064266b936c7 100644
--- a/include/keys/trusted-type.h
+++ b/include/keys/trusted-type.h
@@ -22,6 +22,7 @@
#define MAX_BLOB_SIZE 512
#define MAX_PCRINFO_SIZE 64
#define MAX_DIGEST_SIZE 64
+#define HW_BOUND_KEY 1
struct trusted_key_payload {
struct rcu_head rcu;
@@ -29,6 +30,7 @@ struct trusted_key_payload {
unsigned int blob_len;
unsigned char migratable;
unsigned char old_format;
+ unsigned char is_hw_bound;
unsigned char key[MAX_KEY_SIZE + 1];
unsigned char blob[MAX_BLOB_SIZE];
};
diff --git a/security/keys/trusted-keys/trusted_caam.c b/security/keys/trusted-keys/trusted_caam.c
index e3415c520c0a..fceb9a271c4d 100644
--- a/security/keys/trusted-keys/trusted_caam.c
+++ b/security/keys/trusted-keys/trusted_caam.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
+ * Copyright 2022 NXP, Pankaj Gupta <pankaj.gupta@nxp.com>
*/
#include <keys/trusted_caam.h>
@@ -23,6 +24,7 @@ static int trusted_caam_seal(struct trusted_key_payload *p, char *datablob)
.input = p->key, .input_len = p->key_len,
.output = p->blob, .output_len = MAX_BLOB_SIZE,
.key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1,
+ .is_hw_bound = p->is_hw_bound,
};
ret = caam_encap_blob(blobifier, &info);
@@ -30,6 +32,9 @@ static int trusted_caam_seal(struct trusted_key_payload *p, char *datablob)
return ret;
p->blob_len = info.output_len;
+ if (p->is_hw_bound)
+ p->key_len = info.input_len;
+
return 0;
}
@@ -40,6 +45,7 @@ static int trusted_caam_unseal(struct trusted_key_payload *p, char *datablob)
.input = p->blob, .input_len = p->blob_len,
.output = p->key, .output_len = MAX_KEY_SIZE,
.key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1,
+ .is_hw_bound = p->is_hw_bound,
};
ret = caam_decap_blob(blobifier, &info);
diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
index c6fc50d67214..7f7cc2551b92 100644
--- a/security/keys/trusted-keys/trusted_core.c
+++ b/security/keys/trusted-keys/trusted_core.c
@@ -79,6 +79,8 @@ static int datablob_parse(char **datablob, struct trusted_key_payload *p)
int key_cmd;
char *c;
+ p->is_hw_bound = !HW_BOUND_KEY;
+
/* main command */
c = strsep(datablob, " \t");
if (!c)
@@ -94,6 +96,12 @@ static int datablob_parse(char **datablob, struct trusted_key_payload *p)
if (ret < 0 || keylen < MIN_KEY_SIZE || keylen > MAX_KEY_SIZE)
return -EINVAL;
p->key_len = keylen;
+ /* second argument is to determine if tied to HW */
+ c = strsep(datablob, " \t");
+ if (c) {
+ if (strcmp(c, "hw") == 0)
+ p->is_hw_bound = HW_BOUND_KEY;
+ }
ret = Opt_new;
break;
case Opt_load:
@@ -107,6 +115,12 @@ static int datablob_parse(char **datablob, struct trusted_key_payload *p)
ret = hex2bin(p->blob, c, p->blob_len);
if (ret < 0)
return -EINVAL;
+ /* second argument is to determine if tied to HW */
+ c = strsep(datablob, " \t");
+ if (c) {
+ if (strcmp(c, "hw") == 0)
+ p->is_hw_bound = HW_BOUND_KEY;
+ }
ret = Opt_load;
break;
case Opt_update:
--
2.17.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH HBK: 2/8] hw-bound-key: flag-is_hbk added to the tfm
2022-09-05 14:36 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 1/8] keys-trusted: new cmd line option added Pankaj Gupta
@ 2022-09-05 14:36 ` Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 3/8] sk_cipher: checking for hw bound operation Pankaj Gupta
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Pankaj Gupta @ 2022-09-05 14:36 UTC (permalink / raw)
To: gaurav.jain, sahil.malhotra, kshitiz.varshney, horia.geanta,
linux-kernel, V.Sethi
Cc: Pankaj Gupta
Consumer of the kernel crypto api, after allocating
the transformation, sets this flag based on the basis
of the type of key consumer has. This helps:
- This helps to influence the core processing logic
for the encapsulated algorithm.
- This flag is set by the consumer after allocating
the tfm and before calling the function crypto_xxx_setkey().
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
include/linux/crypto.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 2324ab6f1846..b4fa83ca87bd 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -639,6 +639,8 @@ struct crypto_tfm {
u32 crt_flags;
+ unsigned int is_hbk;
+
int node;
void (*exit)(struct crypto_tfm *tfm);
--
2.17.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH HBK: 3/8] sk_cipher: checking for hw bound operation
2022-09-05 14:36 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 1/8] keys-trusted: new cmd line option added Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 2/8] hw-bound-key: flag-is_hbk added to the tfm Pankaj Gupta
@ 2022-09-05 14:36 ` Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 4/8] keys-trusted: re-factored caam based trusted key Pankaj Gupta
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Pankaj Gupta @ 2022-09-05 14:36 UTC (permalink / raw)
To: gaurav.jain, sahil.malhotra, kshitiz.varshney, horia.geanta,
linux-kernel, V.Sethi
Cc: Pankaj Gupta
Checking for hw bound key. If yes,
- skipping the key-length validation, against the valid min-max range.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
crypto/skcipher.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 418211180cee..0f2d0228d73e 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -598,7 +598,8 @@ int crypto_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
unsigned long alignmask = crypto_skcipher_alignmask(tfm);
int err;
- if (keylen < cipher->min_keysize || keylen > cipher->max_keysize)
+ if ((!tfm->base.is_hbk)
+ && (keylen < cipher->min_keysize || keylen > cipher->max_keysize))
return -EINVAL;
if ((unsigned long)key & alignmask)
--
2.17.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH HBK: 4/8] keys-trusted: re-factored caam based trusted key
2022-09-05 14:36 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
` (2 preceding siblings ...)
2022-09-05 14:36 ` [RFC PATCH HBK: 3/8] sk_cipher: checking for hw bound operation Pankaj Gupta
@ 2022-09-05 14:36 ` Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 5/8] caam blob-gen: moving blob_priv to caam_drv_private Pankaj Gupta
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Pankaj Gupta @ 2022-09-05 14:36 UTC (permalink / raw)
To: gaurav.jain, sahil.malhotra, kshitiz.varshney, horia.geanta,
linux-kernel, V.Sethi
Cc: Pankaj Gupta
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@nxp.com>
---
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@pengutronix.de>
* Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
+ * Copyright 2022 NXP, Pankaj Gupta <pankaj.gupta@nxp.com>
*/
#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@pengutronix.de>
+ * Copyright 2022 NXP, Pankaj Gupta <pankaj.gupta@nxp.com>
*/
#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
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH HBK: 5/8] caam blob-gen: moving blob_priv to caam_drv_private
2022-09-05 14:36 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
` (3 preceding siblings ...)
2022-09-05 14:36 ` [RFC PATCH HBK: 4/8] keys-trusted: re-factored caam based trusted key Pankaj Gupta
@ 2022-09-05 14:36 ` Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 6/8] KEYS: trusted: caam based black key Pankaj Gupta
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Pankaj Gupta @ 2022-09-05 14:36 UTC (permalink / raw)
To: gaurav.jain, sahil.malhotra, kshitiz.varshney, horia.geanta,
linux-kernel, V.Sethi
Cc: Pankaj Gupta
caam blob-gen: moving structure blob_priv to structure caam_drv_private.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
drivers/crypto/caam/blob_gen.c | 8 ++++----
drivers/crypto/caam/intern.h | 6 +++++-
include/soc/fsl/caam-blob.h | 2 +-
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/crypto/caam/blob_gen.c b/drivers/crypto/caam/blob_gen.c
index c128a83cc8dd..5164e62f9596 100644
--- a/drivers/crypto/caam/blob_gen.c
+++ b/drivers/crypto/caam/blob_gen.c
@@ -70,7 +70,7 @@ 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;
+ struct device *jrdev = priv->jrdev;
dma_addr_t dma_in, dma_out;
int op = OP_PCLID_BLOB;
size_t output_len;
@@ -163,7 +163,7 @@ 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;
+ struct device *jrdev = priv->jrdev;
dma_addr_t dma_in, dma_out;
int op = OP_PCLID_BLOB;
size_t output_len;
@@ -267,12 +267,12 @@ struct caam_blob_priv *caam_blob_gen_init(void)
return ERR_PTR(-ENODEV);
}
- return container_of(jrdev, struct caam_blob_priv, jrdev);
+ return &ctrlpriv->blob_priv;
}
EXPORT_SYMBOL(caam_blob_gen_init);
void caam_blob_gen_exit(struct caam_blob_priv *priv)
{
- caam_jr_free(&priv->jrdev);
+ caam_jr_free(priv->jrdev);
}
EXPORT_SYMBOL(caam_blob_gen_exit);
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index 572cf66c887a..2fb7df3ffda5 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -4,7 +4,7 @@
* Private/internal definitions between modules
*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
- * Copyright 2019 NXP
+ * Copyright 2019-2022 NXP
*/
#ifndef INTERN_H
@@ -12,6 +12,7 @@
#include "ctrl.h"
#include <crypto/engine.h>
+#include <soc/fsl/caam-blob.h>
/* Currently comes from Kconfig param as a ^2 (driver-required) */
#define JOBR_DEPTH (1 << CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE)
@@ -114,6 +115,9 @@ struct caam_drv_private {
struct dentry *ctl; /* controller dir */
struct debugfs_blob_wrapper ctl_kek_wrap, ctl_tkek_wrap, ctl_tdsk_wrap;
#endif
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_BLOB_GEN
+ struct caam_blob_priv blob_priv;
+#endif
};
#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API
diff --git a/include/soc/fsl/caam-blob.h b/include/soc/fsl/caam-blob.h
index 632944df29f7..380b0bcb79dc 100644
--- a/include/soc/fsl/caam-blob.h
+++ b/include/soc/fsl/caam-blob.h
@@ -15,7 +15,7 @@
#define CAAM_BLOB_MAX_LEN 4096
struct caam_blob_priv {
- struct device jrdev;
+ struct device *jrdev;
};
--
2.17.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH HBK: 6/8] KEYS: trusted: caam based black key
2022-09-05 14:36 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
` (4 preceding siblings ...)
2022-09-05 14:36 ` [RFC PATCH HBK: 5/8] caam blob-gen: moving blob_priv to caam_drv_private Pankaj Gupta
@ 2022-09-05 14:36 ` Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 7/8] caam alg: symmetric key ciphers are updated Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 8/8] dm-crypt: consumer-app setting the flag-is_hbk Pankaj Gupta
7 siblings, 0 replies; 11+ messages in thread
From: Pankaj Gupta @ 2022-09-05 14:36 UTC (permalink / raw)
To: gaurav.jain, sahil.malhotra, kshitiz.varshney, horia.geanta,
linux-kernel, V.Sethi
Cc: Pankaj Gupta
- CAAM supports two types of black keys:
-- Plain key encrypted with ECB
-- Plain key encrypted with CCM
Note: Due to robustness, default encytption used for black key is CCM.
- A black key blob is generated, and added to trusted key payload.
This is done as part of sealing operation, that was triggered as a result of:
-- new key generation
-- load key,
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
drivers/crypto/caam/blob_gen.c | 132 +++++++++++++++++++++++++++++----
drivers/crypto/caam/desc.h | 8 +-
include/soc/fsl/caam-blob.h | 16 ++++
3 files changed, 140 insertions(+), 16 deletions(-)
diff --git a/drivers/crypto/caam/blob_gen.c b/drivers/crypto/caam/blob_gen.c
index 5164e62f9596..2354e3c6fc61 100644
--- a/drivers/crypto/caam/blob_gen.c
+++ b/drivers/crypto/caam/blob_gen.c
@@ -8,6 +8,7 @@
#define pr_fmt(fmt) "caam blob_gen: " fmt
#include <linux/device.h>
+#include <keys/trusted-type.h>
#include <soc/fsl/caam-blob.h>
#include "compat.h"
@@ -74,8 +75,16 @@ int caam_encap_blob(struct caam_blob_priv *priv,
dma_addr_t dma_in, dma_out;
int op = OP_PCLID_BLOB;
size_t output_len;
+ dma_addr_t dma_blk;
+ u8 *input = info->input;
+ u8 *blk_out;
+ size_t input_len = info->input_len;
u32 *desc;
int ret;
+ int hwbk_caam_ovhd = 0;
+
+ if (info->output_len < info->input_len + CAAM_BLOB_OVERHEAD)
+ return -EINVAL;
if (info->key_mod_len > CAAM_BLOB_KEYMOD_LENGTH)
return -EINVAL;
@@ -83,11 +92,33 @@ int caam_encap_blob(struct caam_blob_priv *priv,
op |= OP_TYPE_ENCAP_PROTOCOL;
output_len = info->input_len + CAAM_BLOB_OVERHEAD;
+ if (info->is_hw_bound == 1) {
+ op |= OP_PCL_BLOB_BLACK;
+ if (priv->hbk_flags & HWBK_FLAGS_CAAM_CCM_ALGO_MASK) {
+ op |= OP_PCL_BLOB_EKT;
+ hwbk_caam_ovhd = CCM_OVERHEAD;
+ }
+
+ if ((input_len + hwbk_caam_ovhd) > MAX_KEY_SIZE)
+ return -EINVAL;
+
+ /* create copy of input buffer */
+ input = kzalloc(info->input_len, GFP_KERNEL | GFP_DMA);
+ if (!input)
+ return -ENOMEM;
+ memcpy(input, info->input, info->input_len);
+
+ /* create hw bound key on input buffer reference */
+ blk_out = info->input;
+
+ info->input_len = input_len + hwbk_caam_ovhd;
+ }
+
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_in = dma_map_single(jrdev, input, input_len,
DMA_TO_DEVICE);
if (dma_mapping_error(jrdev, dma_in)) {
dev_err(jrdev, "unable to map input DMA buffer\n");
@@ -95,12 +126,26 @@ int caam_encap_blob(struct caam_blob_priv *priv,
goto out_free;
}
+ if (info->is_hw_bound == 1) {
+ dma_blk = dma_map_single(jrdev, blk_out,
+ input_len + hwbk_caam_ovhd,
+ 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;
+ }
+ }
+
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;
+ if (info->is_hw_bound == 1)
+ goto out_unmap_blk;
+ else
+ goto out_unmap_in;
}
/*
@@ -112,15 +157,40 @@ int caam_encap_blob(struct caam_blob_priv *priv,
*/
init_job_desc(desc, 0);
+
+ if (info->is_hw_bound == 1) {
+ /*!1. key command used to load class 1 key register
+ * from input plain key.
+ */
+ append_key(desc, dma_in, input_len,
+ CLASS_1 | KEY_DEST_CLASS_REG);
+
+ /*!2. Fifostore to store black key from class 1 key register. */
+ append_fifo_store(desc, dma_blk, input_len,
+ LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_CCM_JKEK);
+
+ append_jump(desc, JUMP_COND_NOP | 1);
+ }
+ /*!3. Load class 2 key with key modifier. */
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);
+
+ /*!4. SEQ IN PTR Command. */
+ if (info->is_hw_bound == 1) {
+ append_seq_in_ptr_intlen(desc, dma_blk, input_len, 0);
+ } else {
+ append_seq_in_ptr_intlen(desc, dma_in, input_len, 0);
+ }
+
+ /*!5. SEQ OUT PTR Command. */
append_seq_out_ptr_intlen(desc, dma_out, output_len, 0);
+
+ /*!6. BlackBlob encapsulation PROTOCOL Command. */
append_operation(desc, op);
print_hex_dump_debug("data@"__stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 1, info->input,
- info->input_len, false);
+ DUMP_PREFIX_ADDRESS, 16, 1, input,
+ input_len + hwbk_caam_ovhd, false);
print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 1, desc,
desc_bytes(desc), false);
@@ -136,15 +206,19 @@ int caam_encap_blob(struct caam_blob_priv *priv,
DUMP_PREFIX_ADDRESS, 16, 1, info->output,
output_len, false);
}
-
- if (ret == 0)
+ if (ret == 0) {
info->output_len = output_len;
-
+ }
dma_unmap_single(jrdev, dma_out, output_len, DMA_FROM_DEVICE);
+out_unmap_blk:
+ if (info->is_hw_bound == 1) {
+ dma_unmap_single(jrdev, dma_blk, info->input_len, DMA_TO_DEVICE);
+ }
out_unmap_in:
dma_unmap_single(jrdev, dma_in, info->input_len, DMA_TO_DEVICE);
out_free:
kfree(desc);
+ kfree(input);
return ret;
}
@@ -168,13 +242,41 @@ int caam_decap_blob(struct caam_blob_priv *priv,
int op = OP_PCLID_BLOB;
size_t output_len;
u32 *desc;
+ u8 *output = info->output;
int ret;
+ int hwbk_caam_ovhd = 0;
+
+ if (info->input_len < CAAM_BLOB_OVERHEAD)
+ return -EINVAL;
if (info->key_mod_len > CAAM_BLOB_KEYMOD_LENGTH)
return -EINVAL;
op |= OP_TYPE_DECAP_PROTOCOL;
output_len = info->input_len - CAAM_BLOB_OVERHEAD;
+ info->output_len = output_len;
+
+ if (info->is_hw_bound == 1) {
+ op |= OP_PCL_BLOB_BLACK;
+ if (priv->hbk_flags & HWBK_FLAGS_CAAM_CCM_ALGO_MASK) {
+ op |= OP_PCL_BLOB_EKT;
+ hwbk_caam_ovhd = CCM_OVERHEAD;
+ }
+
+ if ((output_len + hwbk_caam_ovhd) > MAX_KEY_SIZE)
+ return -EINVAL;
+
+ /* In case of HW Bound Key, lengths have different purpose:
+ * - output_len = HW encrypted key length.
+ * - info->output_len = Length of HW Bound Key Payload
+ * (Payload = Header + outlen)
+ */
+ info->output_len = output_len + hwbk_caam_ovhd;
+
+ output_len += hwbk_caam_ovhd;
+
+ output = info->output;
+ }
desc = kzalloc(CAAM_BLOB_DESC_BYTES_MAX, GFP_KERNEL | GFP_DMA);
if (!desc)
@@ -188,7 +290,7 @@ int caam_decap_blob(struct caam_blob_priv *priv,
goto out_free;
}
- dma_out = dma_map_single(jrdev, info->output, output_len,
+ dma_out = dma_map_single(jrdev, output, output_len,
DMA_FROM_DEVICE);
if (dma_mapping_error(jrdev, dma_out)) {
dev_err(jrdev, "unable to map output DMA buffer\n");
@@ -207,8 +309,8 @@ int caam_decap_blob(struct caam_blob_priv *priv,
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_seq_in_ptr(desc, dma_in, info->input_len, 0);
+ append_seq_out_ptr(desc, dma_out, output_len, 0);
append_operation(desc, op);
print_hex_dump_debug("data@"__stringify(__LINE__)": ",
@@ -226,13 +328,10 @@ int caam_decap_blob(struct caam_blob_priv *priv,
wait_for_completion(&testres.completion);
ret = testres.err;
print_hex_dump_debug("output@"__stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 1, info->output,
+ DUMP_PREFIX_ADDRESS, 16, 1, 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);
@@ -267,6 +366,9 @@ struct caam_blob_priv *caam_blob_gen_init(void)
return ERR_PTR(-ENODEV);
}
+ ctrlpriv->blob_priv.hbk_flags = HWBK_FLAGS_CAAM_CCM_ALGO_MASK;
+ ctrlpriv->blob_priv.jrdev = jrdev;
+
return &ctrlpriv->blob_priv;
}
EXPORT_SYMBOL(caam_blob_gen_init);
diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h
index e13470901586..41b2d0226bdf 100644
--- a/drivers/crypto/caam/desc.h
+++ b/drivers/crypto/caam/desc.h
@@ -4,7 +4,7 @@
* Definitions to support CAAM descriptor instruction generation
*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
- * Copyright 2018 NXP
+ * Copyright 2018-2022 NXP
*/
#ifndef DESC_H
@@ -403,6 +403,7 @@
#define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_CCM_JKEK (0x14 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_JKEK (0x20 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT)
@@ -1001,6 +1002,11 @@
#define OP_PCL_TLS12_AES_256_CBC_SHA384 0xff63
#define OP_PCL_TLS12_AES_256_CBC_SHA512 0xff65
+/* Blob protocol protinfo bits */
+
+#define OP_PCL_BLOB_BLACK 0x0004
+#define OP_PCL_BLOB_EKT 0x0100
+
/* For DTLS - OP_PCLID_DTLS */
#define OP_PCL_DTLS_AES_128_CBC_SHA 0x002f
diff --git a/include/soc/fsl/caam-blob.h b/include/soc/fsl/caam-blob.h
index 380b0bcb79dc..ae2c2a6c8c23 100644
--- a/include/soc/fsl/caam-blob.h
+++ b/include/soc/fsl/caam-blob.h
@@ -10,12 +10,26 @@
#include <linux/types.h>
#include <linux/errno.h>
+#define HWBK_FLAGS_CAAM_CCM_ALGO_MASK 0x01
+
+/*
+ * CCM-Black Key will always be at least 12 bytes longer,
+ * since the encapsulation uses a 6-byte nonce and adds
+ * a 6-byte ICV. But first, the key is padded as necessary so
+ * that CCM-Black Key is a multiple of 8 bytes long.
+ */
+#define NONCE_SIZE 6
+#define ICV_SIZE 6
+#define CCM_OVERHEAD (NONCE_SIZE + ICV_SIZE)
#define CAAM_BLOB_KEYMOD_LENGTH 16
#define CAAM_BLOB_OVERHEAD (32 + 16)
#define CAAM_BLOB_MAX_LEN 4096
struct caam_blob_priv {
struct device *jrdev;
+ /* Flags: whether generated trusted key, is ECB or CCM encrypted.*/
+ uint8_t hbk_flags;
+ uint8_t rsv[3];
};
@@ -38,6 +52,8 @@ struct caam_blob_info {
const void *key_mod;
size_t key_mod_len;
+
+ const char is_hw_bound;
};
/**
--
2.17.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH HBK: 7/8] caam alg: symmetric key ciphers are updated
2022-09-05 14:36 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
` (5 preceding siblings ...)
2022-09-05 14:36 ` [RFC PATCH HBK: 6/8] KEYS: trusted: caam based black key Pankaj Gupta
@ 2022-09-05 14:36 ` Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 8/8] dm-crypt: consumer-app setting the flag-is_hbk Pankaj Gupta
7 siblings, 0 replies; 11+ messages in thread
From: Pankaj Gupta @ 2022-09-05 14:36 UTC (permalink / raw)
To: gaurav.jain, sahil.malhotra, kshitiz.varshney, horia.geanta,
linux-kernel, V.Sethi
Cc: Pankaj Gupta
Changes to enable:
- To work both with black key and plain key.
- It is supported in context of symmetric key ciphers only.
- Based on as crypto layer's flag: tfm->is_hbk, handling for
h/w bound key is done.
- Otherwise, work as previously.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
drivers/crypto/caam/caamalg.c | 37 ++++++++++++++++++++++++++++--
drivers/crypto/caam/caamalg_desc.c | 8 ++++---
drivers/crypto/caam/desc_constr.h | 6 ++++-
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index d3d8bb0a6990..2c96aecab627 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -3,7 +3,7 @@
* caam - Freescale FSL CAAM support for crypto API
*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
- * Copyright 2016-2019 NXP
+ * Copyright 2016-2022 NXP
*
* Based on talitos crypto API driver.
*
@@ -59,6 +59,7 @@
#include <crypto/engine.h>
#include <crypto/xts.h>
#include <asm/unaligned.h>
+#include <soc/fsl/caam-blob.h>
/*
* crypto alg
@@ -734,6 +735,7 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
container_of(crypto_skcipher_alg(skcipher), typeof(*alg),
skcipher);
struct device *jrdev = ctx->jrdev;
+ struct caam_drv_private *ctrlpriv;
unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
u32 *desc;
const bool is_rfc3686 = alg->caam.rfc3686;
@@ -741,9 +743,26 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+ /* Here keylen is actual key length */
ctx->cdata.keylen = keylen;
ctx->cdata.key_virt = key;
ctx->cdata.key_inline = true;
+ /* Here real key len is plain key length */
+ ctx->cdata.key_real_len = keylen;
+ ctx->cdata.key_cmd_opt = 0;
+
+ /* check if the key is HBK */
+ if (skcipher->base.is_hbk) {
+ ctrlpriv = dev_get_drvdata(jrdev->parent);
+ ctx->cdata.key_cmd_opt |= KEY_ENC;
+
+ /* check if the HBK is CCM key */
+ if (ctrlpriv->blob_priv.hbk_flags
+ & HWBK_FLAGS_CAAM_CCM_ALGO_MASK) {
+ ctx->cdata.key_cmd_opt |= KEY_EKT;
+ ctx->cdata.key_real_len = keylen - CCM_OVERHEAD;
+ }
+ }
/* skcipher_encrypt shared descriptor */
desc = ctx->sh_desc_enc;
@@ -766,8 +785,22 @@ static int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
const u8 *key, unsigned int keylen)
{
int err;
+ int overhead = 0;
+ struct caam_ctx *ctx;
+ struct device *jrdev;
+ struct caam_drv_private *ctrlpriv;
+
+ if (skcipher->base.is_hbk) {
+ ctx = crypto_skcipher_ctx(skcipher);
+ jrdev = ctx->jrdev;
+ ctrlpriv = dev_get_drvdata(jrdev->parent);
+ if (ctrlpriv->blob_priv.hbk_flags
+ & HWBK_FLAGS_CAAM_CCM_ALGO_MASK)
+ overhead += CCM_OVERHEAD;
+ }
+
+ err = aes_check_keylen((keylen - overhead));
- err = aes_check_keylen(keylen);
if (err)
return err;
diff --git a/drivers/crypto/caam/caamalg_desc.c b/drivers/crypto/caam/caamalg_desc.c
index 7571e1ac913b..784acae8c9b7 100644
--- a/drivers/crypto/caam/caamalg_desc.c
+++ b/drivers/crypto/caam/caamalg_desc.c
@@ -2,7 +2,7 @@
/*
* Shared descriptors for aead, skcipher algorithms
*
- * Copyright 2016-2019 NXP
+ * Copyright 2016-2022 NXP
*/
#include "compat.h"
@@ -1391,7 +1391,8 @@ void cnstr_shdsc_skcipher_encap(u32 * const desc, struct alginfo *cdata,
/* Load class1 key only */
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
+ cdata->key_real_len, CLASS_1 | KEY_DEST_CLASS_REG
+ | cdata->key_cmd_opt);
/* Load nonce into CONTEXT1 reg */
if (is_rfc3686) {
@@ -1466,7 +1467,8 @@ void cnstr_shdsc_skcipher_decap(u32 * const desc, struct alginfo *cdata,
/* Load class1 key only */
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
+ cdata->key_real_len, CLASS_1 | KEY_DEST_CLASS_REG
+ | cdata->key_cmd_opt);
/* Load nonce into CONTEXT1 reg */
if (is_rfc3686) {
diff --git a/drivers/crypto/caam/desc_constr.h b/drivers/crypto/caam/desc_constr.h
index 62ce6421bb3f..d652bdbf3f91 100644
--- a/drivers/crypto/caam/desc_constr.h
+++ b/drivers/crypto/caam/desc_constr.h
@@ -3,7 +3,7 @@
* caam descriptor construction helper functions
*
* Copyright 2008-2012 Freescale Semiconductor, Inc.
- * Copyright 2019 NXP
+ * Copyright 2019-2022 NXP
*/
#ifndef DESC_CONSTR_H
@@ -500,6 +500,8 @@ do { \
* @key_virt: virtual address where algorithm key resides
* @key_inline: true - key can be inlined in the descriptor; false - key is
* referenced by the descriptor
+ * @key_real_len: size of the key to be loaded by the CAAM
+ * @key_cmd_opt: optional parameters for KEY command
*/
struct alginfo {
u32 algtype;
@@ -508,6 +510,8 @@ struct alginfo {
dma_addr_t key_dma;
const void *key_virt;
bool key_inline;
+ u32 key_real_len;
+ u32 key_cmd_opt;
};
/**
--
2.17.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH HBK: 8/8] dm-crypt: consumer-app setting the flag-is_hbk
2022-09-05 14:36 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
` (6 preceding siblings ...)
2022-09-05 14:36 ` [RFC PATCH HBK: 7/8] caam alg: symmetric key ciphers are updated Pankaj Gupta
@ 2022-09-05 14:36 ` Pankaj Gupta
7 siblings, 0 replies; 11+ messages in thread
From: Pankaj Gupta @ 2022-09-05 14:36 UTC (permalink / raw)
To: gaurav.jain, sahil.malhotra, kshitiz.varshney, horia.geanta,
linux-kernel, V.Sethi
Cc: Pankaj Gupta
Consumer application:
- Adding a flag 'is_hbk', in its "struct crypto_config".
- After fetching the keys, it is setting the above
mentioned flag, based on the key fetched.
-- Note: Supported for trusted keys only.
- After allocating the tfm, and before calling
crypto_xxx_setkey(), setting the tfm flag 'is_hbk':
cc->cipher_tfm.tfms[i]->base.is_hbk = cc->is_hbk;
-- Note: Supported for symmetric-key ciphers only.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
drivers/md/dm-crypt.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 159c6806c19b..12b400e06cbf 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -221,6 +221,7 @@ struct crypt_config {
struct mutex bio_alloc_lock;
u8 *authenc_key; /* space for keys in authenc() format (if used) */
+ unsigned int is_hbk;
u8 key[];
};
@@ -2397,10 +2398,12 @@ static int crypt_setkey(struct crypt_config *cc)
r = crypto_aead_setkey(cc->cipher_tfm.tfms_aead[i],
cc->key + (i * subkey_size),
subkey_size);
- else
+ else {
+ cc->cipher_tfm.tfms[i]->base.is_hbk = cc->is_hbk;
r = crypto_skcipher_setkey(cc->cipher_tfm.tfms[i],
cc->key + (i * subkey_size),
subkey_size);
+ }
if (r)
err = r;
}
@@ -2461,6 +2464,7 @@ static int set_key_trusted(struct crypt_config *cc, struct key *key)
if (!tkp)
return -EKEYREVOKED;
+ cc->is_hbk = tkp->is_hw_bound;
if (cc->key_size != tkp->key_len)
return -EINVAL;
--
2.17.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH HBK: 6/8] KEYS: trusted: caam based black key
2022-09-06 6:51 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
@ 2022-09-06 6:51 ` Pankaj Gupta
2022-09-06 13:03 ` Ben Boeckel
0 siblings, 1 reply; 11+ messages in thread
From: Pankaj Gupta @ 2022-09-06 6:51 UTC (permalink / raw)
To: jarkko, a.fatoum, Jason, jejb, zohar, dhowells, sumit.garg,
david, michael, john.ernberg, jmorris, serge, herbert, davem,
j.luebbe, ebiggers, richard, keyrings, linux-crypto,
linux-integrity, linux-kernel, linux-security-module,
sahil.malhotra, kshitiz.varshney, horia.geanta, pankaj.gupta,
V.Sethi
- CAAM supports two types of black keys:
-- Plain key encrypted with ECB
-- Plain key encrypted with CCM
Note: Due to robustness, default encytption used for black key is CCM.
- A black key blob is generated, and added to trusted key payload.
This is done as part of sealing operation, that was triggered as a result of:
-- new key generation
-- load key,
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
drivers/crypto/caam/blob_gen.c | 132 +++++++++++++++++++++++++++++----
drivers/crypto/caam/desc.h | 8 +-
include/soc/fsl/caam-blob.h | 16 ++++
3 files changed, 140 insertions(+), 16 deletions(-)
diff --git a/drivers/crypto/caam/blob_gen.c b/drivers/crypto/caam/blob_gen.c
index 5164e62f9596..2354e3c6fc61 100644
--- a/drivers/crypto/caam/blob_gen.c
+++ b/drivers/crypto/caam/blob_gen.c
@@ -8,6 +8,7 @@
#define pr_fmt(fmt) "caam blob_gen: " fmt
#include <linux/device.h>
+#include <keys/trusted-type.h>
#include <soc/fsl/caam-blob.h>
#include "compat.h"
@@ -74,8 +75,16 @@ int caam_encap_blob(struct caam_blob_priv *priv,
dma_addr_t dma_in, dma_out;
int op = OP_PCLID_BLOB;
size_t output_len;
+ dma_addr_t dma_blk;
+ u8 *input = info->input;
+ u8 *blk_out;
+ size_t input_len = info->input_len;
u32 *desc;
int ret;
+ int hwbk_caam_ovhd = 0;
+
+ if (info->output_len < info->input_len + CAAM_BLOB_OVERHEAD)
+ return -EINVAL;
if (info->key_mod_len > CAAM_BLOB_KEYMOD_LENGTH)
return -EINVAL;
@@ -83,11 +92,33 @@ int caam_encap_blob(struct caam_blob_priv *priv,
op |= OP_TYPE_ENCAP_PROTOCOL;
output_len = info->input_len + CAAM_BLOB_OVERHEAD;
+ if (info->is_hw_bound == 1) {
+ op |= OP_PCL_BLOB_BLACK;
+ if (priv->hbk_flags & HWBK_FLAGS_CAAM_CCM_ALGO_MASK) {
+ op |= OP_PCL_BLOB_EKT;
+ hwbk_caam_ovhd = CCM_OVERHEAD;
+ }
+
+ if ((input_len + hwbk_caam_ovhd) > MAX_KEY_SIZE)
+ return -EINVAL;
+
+ /* create copy of input buffer */
+ input = kzalloc(info->input_len, GFP_KERNEL | GFP_DMA);
+ if (!input)
+ return -ENOMEM;
+ memcpy(input, info->input, info->input_len);
+
+ /* create hw bound key on input buffer reference */
+ blk_out = info->input;
+
+ info->input_len = input_len + hwbk_caam_ovhd;
+ }
+
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_in = dma_map_single(jrdev, input, input_len,
DMA_TO_DEVICE);
if (dma_mapping_error(jrdev, dma_in)) {
dev_err(jrdev, "unable to map input DMA buffer\n");
@@ -95,12 +126,26 @@ int caam_encap_blob(struct caam_blob_priv *priv,
goto out_free;
}
+ if (info->is_hw_bound == 1) {
+ dma_blk = dma_map_single(jrdev, blk_out,
+ input_len + hwbk_caam_ovhd,
+ 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;
+ }
+ }
+
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;
+ if (info->is_hw_bound == 1)
+ goto out_unmap_blk;
+ else
+ goto out_unmap_in;
}
/*
@@ -112,15 +157,40 @@ int caam_encap_blob(struct caam_blob_priv *priv,
*/
init_job_desc(desc, 0);
+
+ if (info->is_hw_bound == 1) {
+ /*!1. key command used to load class 1 key register
+ * from input plain key.
+ */
+ append_key(desc, dma_in, input_len,
+ CLASS_1 | KEY_DEST_CLASS_REG);
+
+ /*!2. Fifostore to store black key from class 1 key register. */
+ append_fifo_store(desc, dma_blk, input_len,
+ LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_CCM_JKEK);
+
+ append_jump(desc, JUMP_COND_NOP | 1);
+ }
+ /*!3. Load class 2 key with key modifier. */
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);
+
+ /*!4. SEQ IN PTR Command. */
+ if (info->is_hw_bound == 1) {
+ append_seq_in_ptr_intlen(desc, dma_blk, input_len, 0);
+ } else {
+ append_seq_in_ptr_intlen(desc, dma_in, input_len, 0);
+ }
+
+ /*!5. SEQ OUT PTR Command. */
append_seq_out_ptr_intlen(desc, dma_out, output_len, 0);
+
+ /*!6. BlackBlob encapsulation PROTOCOL Command. */
append_operation(desc, op);
print_hex_dump_debug("data@"__stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 1, info->input,
- info->input_len, false);
+ DUMP_PREFIX_ADDRESS, 16, 1, input,
+ input_len + hwbk_caam_ovhd, false);
print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 1, desc,
desc_bytes(desc), false);
@@ -136,15 +206,19 @@ int caam_encap_blob(struct caam_blob_priv *priv,
DUMP_PREFIX_ADDRESS, 16, 1, info->output,
output_len, false);
}
-
- if (ret == 0)
+ if (ret == 0) {
info->output_len = output_len;
-
+ }
dma_unmap_single(jrdev, dma_out, output_len, DMA_FROM_DEVICE);
+out_unmap_blk:
+ if (info->is_hw_bound == 1) {
+ dma_unmap_single(jrdev, dma_blk, info->input_len, DMA_TO_DEVICE);
+ }
out_unmap_in:
dma_unmap_single(jrdev, dma_in, info->input_len, DMA_TO_DEVICE);
out_free:
kfree(desc);
+ kfree(input);
return ret;
}
@@ -168,13 +242,41 @@ int caam_decap_blob(struct caam_blob_priv *priv,
int op = OP_PCLID_BLOB;
size_t output_len;
u32 *desc;
+ u8 *output = info->output;
int ret;
+ int hwbk_caam_ovhd = 0;
+
+ if (info->input_len < CAAM_BLOB_OVERHEAD)
+ return -EINVAL;
if (info->key_mod_len > CAAM_BLOB_KEYMOD_LENGTH)
return -EINVAL;
op |= OP_TYPE_DECAP_PROTOCOL;
output_len = info->input_len - CAAM_BLOB_OVERHEAD;
+ info->output_len = output_len;
+
+ if (info->is_hw_bound == 1) {
+ op |= OP_PCL_BLOB_BLACK;
+ if (priv->hbk_flags & HWBK_FLAGS_CAAM_CCM_ALGO_MASK) {
+ op |= OP_PCL_BLOB_EKT;
+ hwbk_caam_ovhd = CCM_OVERHEAD;
+ }
+
+ if ((output_len + hwbk_caam_ovhd) > MAX_KEY_SIZE)
+ return -EINVAL;
+
+ /* In case of HW Bound Key, lengths have different purpose:
+ * - output_len = HW encrypted key length.
+ * - info->output_len = Length of HW Bound Key Payload
+ * (Payload = Header + outlen)
+ */
+ info->output_len = output_len + hwbk_caam_ovhd;
+
+ output_len += hwbk_caam_ovhd;
+
+ output = info->output;
+ }
desc = kzalloc(CAAM_BLOB_DESC_BYTES_MAX, GFP_KERNEL | GFP_DMA);
if (!desc)
@@ -188,7 +290,7 @@ int caam_decap_blob(struct caam_blob_priv *priv,
goto out_free;
}
- dma_out = dma_map_single(jrdev, info->output, output_len,
+ dma_out = dma_map_single(jrdev, output, output_len,
DMA_FROM_DEVICE);
if (dma_mapping_error(jrdev, dma_out)) {
dev_err(jrdev, "unable to map output DMA buffer\n");
@@ -207,8 +309,8 @@ int caam_decap_blob(struct caam_blob_priv *priv,
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_seq_in_ptr(desc, dma_in, info->input_len, 0);
+ append_seq_out_ptr(desc, dma_out, output_len, 0);
append_operation(desc, op);
print_hex_dump_debug("data@"__stringify(__LINE__)": ",
@@ -226,13 +328,10 @@ int caam_decap_blob(struct caam_blob_priv *priv,
wait_for_completion(&testres.completion);
ret = testres.err;
print_hex_dump_debug("output@"__stringify(__LINE__)": ",
- DUMP_PREFIX_ADDRESS, 16, 1, info->output,
+ DUMP_PREFIX_ADDRESS, 16, 1, 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);
@@ -267,6 +366,9 @@ struct caam_blob_priv *caam_blob_gen_init(void)
return ERR_PTR(-ENODEV);
}
+ ctrlpriv->blob_priv.hbk_flags = HWBK_FLAGS_CAAM_CCM_ALGO_MASK;
+ ctrlpriv->blob_priv.jrdev = jrdev;
+
return &ctrlpriv->blob_priv;
}
EXPORT_SYMBOL(caam_blob_gen_init);
diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h
index e13470901586..41b2d0226bdf 100644
--- a/drivers/crypto/caam/desc.h
+++ b/drivers/crypto/caam/desc.h
@@ -4,7 +4,7 @@
* Definitions to support CAAM descriptor instruction generation
*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
- * Copyright 2018 NXP
+ * Copyright 2018-2022 NXP
*/
#ifndef DESC_H
@@ -403,6 +403,7 @@
#define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_CCM_JKEK (0x14 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_JKEK (0x20 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT)
@@ -1001,6 +1002,11 @@
#define OP_PCL_TLS12_AES_256_CBC_SHA384 0xff63
#define OP_PCL_TLS12_AES_256_CBC_SHA512 0xff65
+/* Blob protocol protinfo bits */
+
+#define OP_PCL_BLOB_BLACK 0x0004
+#define OP_PCL_BLOB_EKT 0x0100
+
/* For DTLS - OP_PCLID_DTLS */
#define OP_PCL_DTLS_AES_128_CBC_SHA 0x002f
diff --git a/include/soc/fsl/caam-blob.h b/include/soc/fsl/caam-blob.h
index 380b0bcb79dc..ae2c2a6c8c23 100644
--- a/include/soc/fsl/caam-blob.h
+++ b/include/soc/fsl/caam-blob.h
@@ -10,12 +10,26 @@
#include <linux/types.h>
#include <linux/errno.h>
+#define HWBK_FLAGS_CAAM_CCM_ALGO_MASK 0x01
+
+/*
+ * CCM-Black Key will always be at least 12 bytes longer,
+ * since the encapsulation uses a 6-byte nonce and adds
+ * a 6-byte ICV. But first, the key is padded as necessary so
+ * that CCM-Black Key is a multiple of 8 bytes long.
+ */
+#define NONCE_SIZE 6
+#define ICV_SIZE 6
+#define CCM_OVERHEAD (NONCE_SIZE + ICV_SIZE)
#define CAAM_BLOB_KEYMOD_LENGTH 16
#define CAAM_BLOB_OVERHEAD (32 + 16)
#define CAAM_BLOB_MAX_LEN 4096
struct caam_blob_priv {
struct device *jrdev;
+ /* Flags: whether generated trusted key, is ECB or CCM encrypted.*/
+ uint8_t hbk_flags;
+ uint8_t rsv[3];
};
@@ -38,6 +52,8 @@ struct caam_blob_info {
const void *key_mod;
size_t key_mod_len;
+
+ const char is_hw_bound;
};
/**
--
2.17.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [RFC PATCH HBK: 6/8] KEYS: trusted: caam based black key
2022-09-06 6:51 ` [RFC PATCH HBK: 6/8] KEYS: trusted: caam based black key Pankaj Gupta
@ 2022-09-06 13:03 ` Ben Boeckel
0 siblings, 0 replies; 11+ messages in thread
From: Ben Boeckel @ 2022-09-06 13:03 UTC (permalink / raw)
To: Pankaj Gupta
Cc: jarkko, a.fatoum, Jason, jejb, zohar, dhowells, sumit.garg,
david, michael, john.ernberg, jmorris, serge, herbert, davem,
j.luebbe, ebiggers, richard, keyrings, linux-crypto,
linux-integrity, linux-kernel, linux-security-module,
sahil.malhotra, kshitiz.varshney, horia.geanta, V.Sethi
On Tue, Sep 06, 2022 at 12:21:55 +0530, Pankaj Gupta wrote:
> - CAAM supports two types of black keys:
What is a "black key"?
> -- Plain key encrypted with ECB
> -- Plain key encrypted with CCM
> Note: Due to robustness, default encytption used for black key is CCM.
^^^^^^^^^^
"encryption"
> - A black key blob is generated, and added to trusted key payload.
Missing "the" before "trusted".
--Ben
^ permalink raw reply [flat|nested] 11+ messages in thread