mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY
@ 2022-09-05 14:36 Pankaj Gupta
  2022-09-05 14:36 ` [RFC PATCH HBK: 1/8] keys-trusted: new cmd line option added Pankaj Gupta
                   ` (7 more replies)
  0 siblings, 8 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

Hardware Bound key(HBK), is never acessible as plain key outside of the
hardware boundary. Thus, it is un-usable, even if somehow fetched
from kernel memory. It ensures run-time security.

This patchset adds generic support for classing the Hardware Bound Key,
based on:

- Newly added flag-'is_hbk', added to the tfm.

  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 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().

First implementation is based on CAAM.

NXP built CAAM IP is the Cryptographic Acceleration and Assurance Module.
This is contain by the i.MX and QorIQ SoCs by NXP.

CAAM is a suitable backend (source) for kernel trusted keys.
This backend source can be used for run-time security as well
by generating the hardware bound key.

Along with plain key, the CAAM generates black key. A black key is an
encrypted key, which can only be decrypted inside CAAM. Hence, CAAM's
black key can only be used by CAAM. Thus it is declared as a hardware bound key.

Pankaj Gupta (8):
  keys-trusted: new cmd line option added
  hw-bound-key: flag-is_hbk added to the tfm
  sk_cipher: checking for hw bound operation
  keys-trusted: re-factored caam based trusted key
  caam blob-gen: moving blob_priv to caam_drv_private
  KEYS: trusted: caam based black key
  caam alg: symmetric key ciphers are updated
  dm-crypt: consumer-app setting the flag-is_hbk

 crypto/skcipher.c                         |   3 +-
 drivers/crypto/caam/blob_gen.c            | 242 ++++++++++++++++++++--
 drivers/crypto/caam/caamalg.c             |  37 +++-
 drivers/crypto/caam/caamalg_desc.c        |   8 +-
 drivers/crypto/caam/desc.h                |   8 +-
 drivers/crypto/caam/desc_constr.h         |   6 +-
 drivers/crypto/caam/intern.h              |   6 +-
 drivers/md/dm-crypt.c                     |   6 +-
 include/keys/trusted-type.h               |   2 +
 include/linux/crypto.h                    |   2 +
 include/soc/fsl/caam-blob.h               |  44 ++--
 security/keys/trusted-keys/trusted_caam.c |   6 +
 security/keys/trusted-keys/trusted_core.c |  14 ++
 13 files changed, 333 insertions(+), 51 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [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	[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	[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	[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	[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	[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	[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	[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	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH HBK: 1/8] keys-trusted: new cmd line option added
  2022-09-06  6:51 ` [RFC PATCH HBK: 1/8] keys-trusted: new cmd line option added Pankaj Gupta
@ 2022-09-06 13:01   ` Ben Boeckel
  0 siblings, 0 replies; 11+ messages in thread
From: Ben Boeckel @ 2022-09-06 13:01 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:50 +0530, Pankaj Gupta wrote:
> 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;

This seems…backwards to me.

> @@ -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;
> +		}

Userspace documentation is missing for this new field. Must it always be
second or is it "any following argument"? For example, let's say we have
another flag like this for "FIPS" (or whatever). It'd be nice if these
all worked:

    'new 32 fips hw'
    'new 32 fips'
    'new 32 hw fips'
    'new 32 hw'

> @@ -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;
> +		}

Same here.

--Ben

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC PATCH HBK: 1/8] keys-trusted: new cmd line option added
  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:01   ` 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

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	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-09-06 13:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [RFC PATCH HBK: 3/8] sk_cipher: checking for hw bound operation Pankaj Gupta
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 ` [RFC PATCH HBK: 5/8] caam blob-gen: moving blob_priv to caam_drv_private Pankaj Gupta
2022-09-05 14:36 ` [RFC PATCH HBK: 6/8] KEYS: trusted: caam based black key 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
2022-09-06  6:51 [RFC PATCH HBK: 0/8] HW BOUND KEY as TRUSTED KEY Pankaj Gupta
2022-09-06  6:51 ` [RFC PATCH HBK: 1/8] keys-trusted: new cmd line option added Pankaj Gupta
2022-09-06 13:01   ` Ben Boeckel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®