* [PATCH v6 0/4] Add support for more AES modes in TI DTHEv2
@ 2025-11-11 11:08 T Pratham
2025-11-11 11:08 ` [PATCH v6 1/4] crypto: ti - Add support for AES-XTS in DTHEv2 driver T Pratham
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: T Pratham @ 2025-11-11 11:08 UTC (permalink / raw)
To: Herbert Xu, David S . Miller
Cc: T Pratham, linux-crypto, linux-kernel, Manorit Chawdhry,
Kamlesh Gurudasani, Shiva Tripathi, Kavitha Malarvizhi,
Vishal Mahaveer, Praneeth Bajjuri
DTHEv2 is a new cryptography engine introduced in TI AM62L SoC. The
features of DTHEv2 and details of AES modes supported were detailed in
[1]. Additional hardware details available in SoC TRM [2].
This patch series adds support for the following AES modes:
- AES-XTS
- AES-CTR
- AES-GCM
- AES-CCM
The driver is tested using full kernel crypto selftests
(CRYPTO_SELFTESTS_FULL) which all pass successfully [3].
Signed-off-by: T Pratham <t-pratham@ti.com>
---
[1]: [PATCH v7 0/2] Add support for Texas Instruments DTHEv2 Crypto Engine
Link: https://lore.kernel.org/all/20250820092710.3510788-1-t-pratham@ti.com/
[2]: Section 14.6.3 (DMA Control Registers -> DMASS_DTHE)
Link: https://www.ti.com/lit/ug/sprujb4/sprujb4.pdf
[3]: DTHEv2 AES Engine kernel self-tests logs
Link: https://gist.github.com/Pratham-T/aaa499cf50d20310cb27266a645bfd60
Change log:
v6:
- Removed memory alloc calls on the data path (CTR padding in aes_run),
replaced with scatterlist chaining for added a pad buffer. Added two
accompanying helpers dthe_chain_pad_sg() and
dthe_unchain_padded_sg().
- Replaced GFP_KERNEL to GFP_ATOMIC in AEAD src and dst scatterlist
prep functions to avoid deadlock in data path.
- Added fallback to software in AEADs on failure.
v5:
- Simplified AES-XTS fallback allocation, directly using xts(aes) for
alg_name
- Changed fallback to sync and allocated on stack
v4:
- Return -EINVAL in AES-XTS when cryptlen = 0
- Added software fallback for AES-XTS when ciphertext stealing is
required (cryptlen is not multiple of AES_BLOCK_SIZE)
- Changed DTHE_MAX_KEYSIZE definition to use AES_MAX_KEY_SIZE instead
of AES_KEYSIZE_256
- In AES-CTR, also pad dst scatterlist when padding src scatterlist
- Changed polling for TAG ready to use readl_relaxed_poll_timeout()
- Used crypto API functions to access struct members instead of
directly accessing them (crypto_aead_tfm and aead_request_flags)
- Allocated padding buffers in AEAD algos on the stack.
- Changed helper functions dthe_aead_prep_* to return ERR_PTR on error
- Changed some error labels in dthe_aead_run to improve clarity
- Moved iv_in[] declaration from middle of the function to the top
- Corrected setting CCM M value in the hardware register
- Added checks for CCM L value input in the algorithm from IV.
- Added more fallback cases for CCM where hardware has limitations
v3:
- Added header files to remove implicit declaration error.
- Corrected assignment of src_nents and dst_nents in dthe_aead_run
(Ran the lkp kernel test bot script locally to ensure no more such
errors are present)
v2:
- Corrected assignment of variable unpadded_cryptlen in dthe_aead_run.
- Removed some if conditions which are always false, and documented the
cases in comments.
- Moved polling of TAG ready register to a separate function and
returning -ETIMEDOUT on poll timeout.
- Corrected comments to adhere to kernel coding guidelines.
Link to previous version:
v5: https://lore.kernel.org/all/20251022180302.729728-1-t-pratham@ti.com/
v4: https://lore.kernel.org/all/20251009111727.911738-1-t-pratham@ti.com/
v3: https://lore.kernel.org/all/20250910100742.3747614-1-t-pratham@ti.com/
v2: https://lore.kernel.org/all/20250908140928.2801062-1-t-pratham@ti.com/
v1: https://lore.kernel.org/all/20250905133504.2348972-4-t-pratham@ti.com/
---
T Pratham (4):
crypto: ti - Add support for AES-XTS in DTHEv2 driver
crypto: ti - Add support for AES-CTR in DTHEv2 driver
crypto: ti - Add support for AES-GCM in DTHEv2 driver
crypto: ti - Add support for AES-CCM in DTHEv2 driver
drivers/crypto/ti/Kconfig | 5 +
drivers/crypto/ti/dthev2-aes.c | 964 +++++++++++++++++++++++++++++-
drivers/crypto/ti/dthev2-common.c | 19 +
drivers/crypto/ti/dthev2-common.h | 33 +-
4 files changed, 1004 insertions(+), 17 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v6 1/4] crypto: ti - Add support for AES-XTS in DTHEv2 driver
2025-11-11 11:08 [PATCH v6 0/4] Add support for more AES modes in TI DTHEv2 T Pratham
@ 2025-11-11 11:08 ` T Pratham
2025-11-11 11:40 ` T Pratham
2025-11-11 11:08 ` [PATCH v6 2/4] crypto: ti - Add support for AES-CTR " T Pratham
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: T Pratham @ 2025-11-11 11:08 UTC (permalink / raw)
To: T Pratham, Herbert Xu, David S. Miller
Cc: Manorit Chawdhry, Kamlesh Gurudasani, Shiva Tripathi,
Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto, linux-kernel
Add support for XTS mode of operation for AES algorithm in the AES
Engine of the DTHEv2 hardware cryptographic engine.
Signed-off-by: T Pratham <t-pratham@ti.com>
---
drivers/crypto/ti/Kconfig | 1 +
drivers/crypto/ti/dthev2-aes.c | 137 ++++++++++++++++++++++++++++--
drivers/crypto/ti/dthev2-common.h | 10 ++-
3 files changed, 141 insertions(+), 7 deletions(-)
diff --git a/drivers/crypto/ti/Kconfig b/drivers/crypto/ti/Kconfig
index d4f91c1e0cb55..a3692ceec49bc 100644
--- a/drivers/crypto/ti/Kconfig
+++ b/drivers/crypto/ti/Kconfig
@@ -6,6 +6,7 @@ config CRYPTO_DEV_TI_DTHEV2
select CRYPTO_SKCIPHER
select CRYPTO_ECB
select CRYPTO_CBC
+ select CRYPTO_XTS
help
This enables support for the TI DTHE V2 hw cryptography engine
which can be found on TI K3 SOCs. Selecting this enables use
diff --git a/drivers/crypto/ti/dthev2-aes.c b/drivers/crypto/ti/dthev2-aes.c
index 3547c41fa4ed3..7d8123984c1eb 100644
--- a/drivers/crypto/ti/dthev2-aes.c
+++ b/drivers/crypto/ti/dthev2-aes.c
@@ -25,6 +25,7 @@
// AES Engine
#define DTHE_P_AES_BASE 0x7000
+
#define DTHE_P_AES_KEY1_0 0x0038
#define DTHE_P_AES_KEY1_1 0x003C
#define DTHE_P_AES_KEY1_2 0x0030
@@ -33,6 +34,16 @@
#define DTHE_P_AES_KEY1_5 0x002C
#define DTHE_P_AES_KEY1_6 0x0020
#define DTHE_P_AES_KEY1_7 0x0024
+
+#define DTHE_P_AES_KEY2_0 0x0018
+#define DTHE_P_AES_KEY2_1 0x001C
+#define DTHE_P_AES_KEY2_2 0x0010
+#define DTHE_P_AES_KEY2_3 0x0014
+#define DTHE_P_AES_KEY2_4 0x0008
+#define DTHE_P_AES_KEY2_5 0x000C
+#define DTHE_P_AES_KEY2_6 0x0000
+#define DTHE_P_AES_KEY2_7 0x0004
+
#define DTHE_P_AES_IV_IN_0 0x0040
#define DTHE_P_AES_IV_IN_1 0x0044
#define DTHE_P_AES_IV_IN_2 0x0048
@@ -52,6 +63,7 @@
enum aes_ctrl_mode_masks {
AES_CTRL_ECB_MASK = 0x00,
AES_CTRL_CBC_MASK = BIT(5),
+ AES_CTRL_XTS_MASK = BIT(12) | BIT(11),
};
#define DTHE_AES_CTRL_MODE_CLEAR_MASK ~GENMASK(28, 5)
@@ -88,6 +100,31 @@ static int dthe_cipher_init_tfm(struct crypto_skcipher *tfm)
return 0;
}
+static int dthe_cipher_xts_init_tfm(struct crypto_skcipher *tfm)
+{
+ struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+ ctx->dev_data = dev_data;
+ ctx->keylen = 0;
+
+ ctx->skcipher_fb = crypto_alloc_sync_skcipher("xts(aes)", 0,
+ CRYPTO_ALG_NEED_FALLBACK);
+ if (IS_ERR(ctx->skcipher_fb)) {
+ dev_err(dev_data->dev, "fallback driver xts(aes) couldn't be loaded\n");
+ return PTR_ERR(ctx->skcipher_fb);
+ }
+
+ return 0;
+}
+
+static void dthe_cipher_xts_exit_tfm(struct crypto_skcipher *tfm)
+{
+ struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+ crypto_free_sync_skcipher(ctx->skcipher_fb);
+}
+
static int dthe_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
{
struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
@@ -119,6 +156,27 @@ static int dthe_aes_cbc_setkey(struct crypto_skcipher *tfm, const u8 *key, unsig
return dthe_aes_setkey(tfm, key, keylen);
}
+static int dthe_aes_xts_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
+{
+ struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+ if (keylen != 2 * AES_KEYSIZE_128 &&
+ keylen != 2 * AES_KEYSIZE_192 &&
+ keylen != 2 * AES_KEYSIZE_256)
+ return -EINVAL;
+
+ ctx->aes_mode = DTHE_AES_XTS;
+ ctx->keylen = keylen / 2;
+ memcpy(ctx->key, key, keylen);
+
+ crypto_sync_skcipher_clear_flags(ctx->skcipher_fb, CRYPTO_TFM_REQ_MASK);
+ crypto_sync_skcipher_set_flags(ctx->skcipher_fb,
+ crypto_skcipher_get_flags(tfm) &
+ CRYPTO_TFM_REQ_MASK);
+
+ return crypto_sync_skcipher_setkey(ctx->skcipher_fb, key, keylen);
+}
+
static void dthe_aes_set_ctrl_key(struct dthe_tfm_ctx *ctx,
struct dthe_aes_req_ctx *rctx,
u32 *iv_in)
@@ -141,6 +199,24 @@ static void dthe_aes_set_ctrl_key(struct dthe_tfm_ctx *ctx,
writel_relaxed(ctx->key[7], aes_base_reg + DTHE_P_AES_KEY1_7);
}
+ if (ctx->aes_mode == DTHE_AES_XTS) {
+ size_t key2_offset = ctx->keylen / sizeof(u32);
+
+ writel_relaxed(ctx->key[key2_offset + 0], aes_base_reg + DTHE_P_AES_KEY2_0);
+ writel_relaxed(ctx->key[key2_offset + 1], aes_base_reg + DTHE_P_AES_KEY2_1);
+ writel_relaxed(ctx->key[key2_offset + 2], aes_base_reg + DTHE_P_AES_KEY2_2);
+ writel_relaxed(ctx->key[key2_offset + 3], aes_base_reg + DTHE_P_AES_KEY2_3);
+
+ if (ctx->keylen > AES_KEYSIZE_128) {
+ writel_relaxed(ctx->key[key2_offset + 4], aes_base_reg + DTHE_P_AES_KEY2_4);
+ writel_relaxed(ctx->key[key2_offset + 5], aes_base_reg + DTHE_P_AES_KEY2_5);
+ }
+ if (ctx->keylen == AES_KEYSIZE_256) {
+ writel_relaxed(ctx->key[key2_offset + 6], aes_base_reg + DTHE_P_AES_KEY2_6);
+ writel_relaxed(ctx->key[key2_offset + 7], aes_base_reg + DTHE_P_AES_KEY2_7);
+ }
+ }
+
if (rctx->enc)
ctrl_val |= DTHE_AES_CTRL_DIR_ENC;
@@ -160,6 +236,9 @@ static void dthe_aes_set_ctrl_key(struct dthe_tfm_ctx *ctx,
case DTHE_AES_CBC:
ctrl_val |= AES_CTRL_CBC_MASK;
break;
+ case DTHE_AES_XTS:
+ ctrl_val |= AES_CTRL_XTS_MASK;
+ break;
}
if (iv_in) {
@@ -315,24 +394,45 @@ static int dthe_aes_run(struct crypto_engine *engine, void *areq)
local_bh_disable();
crypto_finalize_skcipher_request(dev_data->engine, req, ret);
local_bh_enable();
- return ret;
+ return 0;
}
static int dthe_aes_crypt(struct skcipher_request *req)
{
struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
+ struct dthe_aes_req_ctx *rctx = skcipher_request_ctx(req);
struct dthe_data *dev_data = dthe_get_dev(ctx);
struct crypto_engine *engine;
/*
- * If data is not a multiple of AES_BLOCK_SIZE, need to return -EINVAL
- * If data length input is zero, no need to do any operation.
+ * If data is not a multiple of AES_BLOCK_SIZE:
+ * - need to return -EINVAL for ECB, CBC as they are block ciphers
+ * - need to fallback to software as H/W doesn't support Ciphertext Stealing for XTS
*/
- if (req->cryptlen % AES_BLOCK_SIZE)
+ if (req->cryptlen % AES_BLOCK_SIZE) {
+ if (ctx->aes_mode == DTHE_AES_XTS) {
+ SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->skcipher_fb);
+
+ skcipher_request_set_callback(subreq, skcipher_request_flags(req),
+ req->base.complete, req->base.data);
+ skcipher_request_set_crypt(subreq, req->src, req->dst,
+ req->cryptlen, req->iv);
+
+ return rctx->enc ? crypto_skcipher_encrypt(subreq) :
+ crypto_skcipher_decrypt(subreq);
+ }
return -EINVAL;
+ }
- if (req->cryptlen == 0)
+ /*
+ * If data length input is zero, no need to do any operation.
+ * Except for XTS mode, where data length should be non-zero.
+ */
+ if (req->cryptlen == 0) {
+ if (ctx->aes_mode == DTHE_AES_XTS)
+ return -EINVAL;
return 0;
+ }
engine = dev_data->engine;
return crypto_transfer_skcipher_request_to_engine(engine, req);
@@ -399,7 +499,32 @@ static struct skcipher_engine_alg cipher_algs[] = {
.cra_module = THIS_MODULE,
},
.op.do_one_request = dthe_aes_run,
- } /* CBC AES */
+ }, /* CBC AES */
+ {
+ .base.init = dthe_cipher_xts_init_tfm,
+ .base.exit = dthe_cipher_xts_exit_tfm,
+ .base.setkey = dthe_aes_xts_setkey,
+ .base.encrypt = dthe_aes_encrypt,
+ .base.decrypt = dthe_aes_decrypt,
+ .base.min_keysize = AES_MIN_KEY_SIZE * 2,
+ .base.max_keysize = AES_MAX_KEY_SIZE * 2,
+ .base.ivsize = AES_IV_SIZE,
+ .base.base = {
+ .cra_name = "xts(aes)",
+ .cra_driver_name = "xts-aes-dthev2",
+ .cra_priority = 299,
+ .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+ CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_alignmask = AES_BLOCK_SIZE - 1,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct dthe_tfm_ctx),
+ .cra_reqsize = sizeof(struct dthe_aes_req_ctx),
+ .cra_module = THIS_MODULE,
+ },
+ .op.do_one_request = dthe_aes_run,
+ }, /* XTS AES */
};
int dthe_register_aes_algs(void)
diff --git a/drivers/crypto/ti/dthev2-common.h b/drivers/crypto/ti/dthev2-common.h
index 68c94acda8aaa..c7a06a4c353ff 100644
--- a/drivers/crypto/ti/dthev2-common.h
+++ b/drivers/crypto/ti/dthev2-common.h
@@ -27,10 +27,16 @@
#define DTHE_REG_SIZE 4
#define DTHE_DMA_TIMEOUT_MS 2000
+/*
+ * Size of largest possible key (of all algorithms) to be stored in dthe_tfm_ctx
+ * This is currently the keysize of XTS-AES-256 which is 512 bits (64 bytes)
+ */
+#define DTHE_MAX_KEYSIZE (AES_MAX_KEY_SIZE * 2)
enum dthe_aes_mode {
DTHE_AES_ECB = 0,
DTHE_AES_CBC,
+ DTHE_AES_XTS,
};
/* Driver specific struct definitions */
@@ -73,12 +79,14 @@ struct dthe_list {
* @keylen: AES key length
* @key: AES key
* @aes_mode: AES mode
+ * @skcipher_fb: Fallback crypto skcipher handle for AES-XTS mode
*/
struct dthe_tfm_ctx {
struct dthe_data *dev_data;
unsigned int keylen;
- u32 key[AES_KEYSIZE_256 / sizeof(u32)];
+ u32 key[DTHE_MAX_KEYSIZE / sizeof(u32)];
enum dthe_aes_mode aes_mode;
+ struct crypto_sync_skcipher *skcipher_fb;
};
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 2/4] crypto: ti - Add support for AES-CTR in DTHEv2 driver
2025-11-11 11:08 [PATCH v6 0/4] Add support for more AES modes in TI DTHEv2 T Pratham
2025-11-11 11:08 ` [PATCH v6 1/4] crypto: ti - Add support for AES-XTS in DTHEv2 driver T Pratham
@ 2025-11-11 11:08 ` T Pratham
2025-11-21 3:11 ` Herbert Xu
2025-11-11 11:08 ` [PATCH v6 3/4] crypto: ti - Add support for AES-GCM " T Pratham
2025-11-11 11:08 ` [PATCH v6 4/4] crypto: ti - Add support for AES-CCM " T Pratham
3 siblings, 1 reply; 11+ messages in thread
From: T Pratham @ 2025-11-11 11:08 UTC (permalink / raw)
To: T Pratham, Herbert Xu, David S. Miller
Cc: Manorit Chawdhry, Kamlesh Gurudasani, Shiva Tripathi,
Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto, linux-kernel
Add support for CTR mode of operation for AES algorithm in the AES
Engine of the DTHEv2 hardware cryptographic engine.
Signed-off-by: T Pratham <t-pratham@ti.com>
---
drivers/crypto/ti/Kconfig | 1 +
drivers/crypto/ti/dthev2-aes.c | 139 ++++++++++++++++++++++++++++--
drivers/crypto/ti/dthev2-common.c | 19 ++++
drivers/crypto/ti/dthev2-common.h | 15 ++++
4 files changed, 165 insertions(+), 9 deletions(-)
diff --git a/drivers/crypto/ti/Kconfig b/drivers/crypto/ti/Kconfig
index a3692ceec49bc..6027e12de279d 100644
--- a/drivers/crypto/ti/Kconfig
+++ b/drivers/crypto/ti/Kconfig
@@ -6,6 +6,7 @@ config CRYPTO_DEV_TI_DTHEV2
select CRYPTO_SKCIPHER
select CRYPTO_ECB
select CRYPTO_CBC
+ select CRYPTO_CTR
select CRYPTO_XTS
help
This enables support for the TI DTHE V2 hw cryptography engine
diff --git a/drivers/crypto/ti/dthev2-aes.c b/drivers/crypto/ti/dthev2-aes.c
index 7d8123984c1eb..1f4a953c6e2a0 100644
--- a/drivers/crypto/ti/dthev2-aes.c
+++ b/drivers/crypto/ti/dthev2-aes.c
@@ -63,6 +63,7 @@
enum aes_ctrl_mode_masks {
AES_CTRL_ECB_MASK = 0x00,
AES_CTRL_CBC_MASK = BIT(5),
+ AES_CTRL_CTR_MASK = BIT(6),
AES_CTRL_XTS_MASK = BIT(12) | BIT(11),
};
@@ -74,6 +75,8 @@ enum aes_ctrl_mode_masks {
#define DTHE_AES_CTRL_KEYSIZE_24B BIT(4)
#define DTHE_AES_CTRL_KEYSIZE_32B (BIT(3) | BIT(4))
+#define DTHE_AES_CTRL_CTR_WIDTH_128B (BIT(7) | BIT(8))
+
#define DTHE_AES_CTRL_SAVE_CTX_SET BIT(29)
#define DTHE_AES_CTRL_OUTPUT_READY BIT_MASK(0)
@@ -89,6 +92,46 @@ enum aes_ctrl_mode_masks {
#define AES_BLOCK_WORDS (AES_BLOCK_SIZE / sizeof(u32))
#define AES_IV_WORDS AES_BLOCK_WORDS
+static struct scatterlist *dthe_chain_pad_sg(struct scatterlist *sg,
+ unsigned int nents,
+ struct scatterlist pad_sg[2],
+ u8 *pad_buf, unsigned int pad_len)
+{
+ struct scatterlist *sgl;
+
+ sg_init_table(pad_sg, 2);
+ sgl = sg_last(sg, nents);
+ sg_set_page(&pad_sg[0], sg_page(sgl), sgl->length, sgl->offset);
+ sg_set_buf(&pad_sg[1], pad_buf, pad_len);
+
+ /* First nent can't be an empty chain nent */
+ if (nents == 1)
+ return pad_sg;
+
+ sg_chain(sgl, 1, pad_sg);
+ return sg;
+}
+
+static void dthe_unchain_padded_sg(struct scatterlist *sg,
+ struct scatterlist pad_sg[2],
+ unsigned int nents)
+{
+ struct scatterlist *sgl;
+ unsigned int i;
+
+ /*
+ * The last 2 nents are from our {src,dst}_padded sg.
+ * Go to the (n-3)th nent. Then the next in memory is
+ * the chain sg pointing to our {src,dst}_padded sg.
+ */
+ for (i = 0, sgl = sg; i < nents - 3; ++i)
+ sgl = sg_next(sgl);
+ sgl++;
+ sgl->page_link &= ~SG_CHAIN;
+ sg_set_page(sgl, sg_page(&pad_sg[0]), pad_sg[0].length, pad_sg[0].offset);
+ sg_mark_end(sgl);
+}
+
static int dthe_cipher_init_tfm(struct crypto_skcipher *tfm)
{
struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
@@ -156,6 +199,15 @@ static int dthe_aes_cbc_setkey(struct crypto_skcipher *tfm, const u8 *key, unsig
return dthe_aes_setkey(tfm, key, keylen);
}
+static int dthe_aes_ctr_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
+{
+ struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+ ctx->aes_mode = DTHE_AES_CTR;
+
+ return dthe_aes_setkey(tfm, key, keylen);
+}
+
static int dthe_aes_xts_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
{
struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
@@ -236,6 +288,10 @@ static void dthe_aes_set_ctrl_key(struct dthe_tfm_ctx *ctx,
case DTHE_AES_CBC:
ctrl_val |= AES_CTRL_CBC_MASK;
break;
+ case DTHE_AES_CTR:
+ ctrl_val |= AES_CTRL_CTR_MASK;
+ ctrl_val |= DTHE_AES_CTRL_CTR_WIDTH_128B;
+ break;
case DTHE_AES_XTS:
ctrl_val |= AES_CTRL_XTS_MASK;
break;
@@ -270,12 +326,17 @@ static int dthe_aes_run(struct crypto_engine *engine, void *areq)
struct scatterlist *src = req->src;
struct scatterlist *dst = req->dst;
+ struct scatterlist src_pad[2], dst_pad[2];
+
int src_nents = sg_nents_for_len(src, len);
- int dst_nents;
+ int dst_nents = sg_nents_for_len(dst, len);
int src_mapped_nents;
int dst_mapped_nents;
+ u8 pad_buf[AES_BLOCK_SIZE] = {0};
+ int pad_len = 0;
+
bool diff_dst;
enum dma_data_direction src_dir, dst_dir;
@@ -295,6 +356,31 @@ static int dthe_aes_run(struct crypto_engine *engine, void *areq)
aes_irqenable_val |= DTHE_AES_IRQENABLE_EN_ALL;
writel_relaxed(aes_irqenable_val, aes_base_reg + DTHE_P_AES_IRQENABLE);
+ if (ctx->aes_mode == DTHE_AES_CTR) {
+ /*
+ * CTR mode can operate on any input length, but the hardware
+ * requires input length to be a multiple of the block size.
+ * We need to handle the padding in the driver.
+ */
+ if (req->cryptlen % AES_BLOCK_SIZE) {
+ /* Need to create a new SG list with padding */
+ pad_len = ALIGN(req->cryptlen, AES_BLOCK_SIZE) - req->cryptlen;
+
+ src = dthe_chain_pad_sg(req->src, src_nents, src_pad, pad_buf, pad_len);
+ src_nents++;
+
+ if (req->src == req->dst) {
+ /* In-place operation, use same SG for dst */
+ dst = src;
+ dst_nents = src_nents;
+ } else {
+ dst = dthe_chain_pad_sg(req->dst, dst_nents, dst_pad,
+ pad_buf, pad_len);
+ dst_nents++;
+ }
+ }
+ }
+
if (src == dst) {
diff_dst = false;
src_dir = DMA_BIDIRECTIONAL;
@@ -311,19 +397,16 @@ static int dthe_aes_run(struct crypto_engine *engine, void *areq)
src_mapped_nents = dma_map_sg(tx_dev, src, src_nents, src_dir);
if (src_mapped_nents == 0) {
ret = -EINVAL;
- goto aes_err;
+ goto aes_map_src_err;
}
if (!diff_dst) {
- dst_nents = src_nents;
dst_mapped_nents = src_mapped_nents;
} else {
- dst_nents = sg_nents_for_len(dst, len);
dst_mapped_nents = dma_map_sg(rx_dev, dst, dst_nents, dst_dir);
if (dst_mapped_nents == 0) {
- dma_unmap_sg(tx_dev, src, src_nents, src_dir);
ret = -EINVAL;
- goto aes_err;
+ goto aes_map_dst_err;
}
}
@@ -386,11 +469,24 @@ static int dthe_aes_run(struct crypto_engine *engine, void *areq)
}
aes_prep_err:
- dma_unmap_sg(tx_dev, src, src_nents, src_dir);
if (dst_dir != DMA_BIDIRECTIONAL)
dma_unmap_sg(rx_dev, dst, dst_nents, dst_dir);
+aes_map_dst_err:
+ dma_unmap_sg(tx_dev, src, src_nents, src_dir);
+
+aes_map_src_err:
+ if (ctx->aes_mode == DTHE_AES_CTR && req->cryptlen % AES_BLOCK_SIZE) {
+ /*
+ * Last nent in original sglist is converted to a chain sg.
+ * Need to revert that to keep the original sglist intact.
+ */
+ if (src_nents > 2)
+ dthe_unchain_padded_sg(req->src, src_pad, src_nents);
+
+ if (req->src != req->dst && dst_nents > 2)
+ dthe_unchain_padded_sg(req->dst, dst_pad, dst_nents);
+ }
-aes_err:
local_bh_disable();
crypto_finalize_skcipher_request(dev_data->engine, req, ret);
local_bh_enable();
@@ -408,6 +504,7 @@ static int dthe_aes_crypt(struct skcipher_request *req)
* If data is not a multiple of AES_BLOCK_SIZE:
* - need to return -EINVAL for ECB, CBC as they are block ciphers
* - need to fallback to software as H/W doesn't support Ciphertext Stealing for XTS
+ * - do nothing for CTR
*/
if (req->cryptlen % AES_BLOCK_SIZE) {
if (ctx->aes_mode == DTHE_AES_XTS) {
@@ -421,7 +518,8 @@ static int dthe_aes_crypt(struct skcipher_request *req)
return rctx->enc ? crypto_skcipher_encrypt(subreq) :
crypto_skcipher_decrypt(subreq);
}
- return -EINVAL;
+ if (ctx->aes_mode != DTHE_AES_CTR)
+ return -EINVAL;
}
/*
@@ -500,6 +598,29 @@ static struct skcipher_engine_alg cipher_algs[] = {
},
.op.do_one_request = dthe_aes_run,
}, /* CBC AES */
+ {
+ .base.init = dthe_cipher_init_tfm,
+ .base.setkey = dthe_aes_ctr_setkey,
+ .base.encrypt = dthe_aes_encrypt,
+ .base.decrypt = dthe_aes_decrypt,
+ .base.min_keysize = AES_MIN_KEY_SIZE,
+ .base.max_keysize = AES_MAX_KEY_SIZE,
+ .base.ivsize = AES_IV_SIZE,
+ .base.chunksize = AES_BLOCK_SIZE,
+ .base.base = {
+ .cra_name = "ctr(aes)",
+ .cra_driver_name = "ctr-aes-dthev2",
+ .cra_priority = 299,
+ .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+ CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct dthe_tfm_ctx),
+ .cra_reqsize = sizeof(struct dthe_aes_req_ctx),
+ .cra_module = THIS_MODULE,
+ },
+ .op.do_one_request = dthe_aes_run,
+ }, /* CTR AES */
{
.base.init = dthe_cipher_xts_init_tfm,
.base.exit = dthe_cipher_xts_exit_tfm,
diff --git a/drivers/crypto/ti/dthev2-common.c b/drivers/crypto/ti/dthev2-common.c
index c39d37933b9ee..a2ad79bec105a 100644
--- a/drivers/crypto/ti/dthev2-common.c
+++ b/drivers/crypto/ti/dthev2-common.c
@@ -48,6 +48,25 @@ struct dthe_data *dthe_get_dev(struct dthe_tfm_ctx *ctx)
return dev_data;
}
+struct scatterlist *dthe_copy_sg(struct scatterlist *dst,
+ struct scatterlist *src,
+ int buflen)
+{
+ struct scatterlist *from_sg, *to_sg;
+ int sglen;
+
+ for (to_sg = dst, from_sg = src; buflen && from_sg; buflen -= sglen) {
+ sglen = from_sg->length;
+ if (sglen > buflen)
+ sglen = buflen;
+ sg_set_buf(to_sg, sg_virt(from_sg), sglen);
+ from_sg = sg_next(from_sg);
+ to_sg = sg_next(to_sg);
+ }
+
+ return to_sg;
+}
+
static int dthe_dma_init(struct dthe_data *dev_data)
{
int ret;
diff --git a/drivers/crypto/ti/dthev2-common.h b/drivers/crypto/ti/dthev2-common.h
index c7a06a4c353ff..f12b94d64e134 100644
--- a/drivers/crypto/ti/dthev2-common.h
+++ b/drivers/crypto/ti/dthev2-common.h
@@ -36,6 +36,7 @@
enum dthe_aes_mode {
DTHE_AES_ECB = 0,
DTHE_AES_CBC,
+ DTHE_AES_CTR,
DTHE_AES_XTS,
};
@@ -103,6 +104,20 @@ struct dthe_aes_req_ctx {
struct dthe_data *dthe_get_dev(struct dthe_tfm_ctx *ctx);
+/**
+ * dthe_copy_sg - Copy sg entries from src to dst
+ * @dst: Destination sg to be filled
+ * @src: Source sg to be copied from
+ * @buflen: Number of bytes to be copied
+ *
+ * Description:
+ * Copy buflen bytes of data from src to dst.
+ *
+ **/
+struct scatterlist *dthe_copy_sg(struct scatterlist *dst,
+ struct scatterlist *src,
+ int buflen);
+
int dthe_register_aes_algs(void);
void dthe_unregister_aes_algs(void);
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 3/4] crypto: ti - Add support for AES-GCM in DTHEv2 driver
2025-11-11 11:08 [PATCH v6 0/4] Add support for more AES modes in TI DTHEv2 T Pratham
2025-11-11 11:08 ` [PATCH v6 1/4] crypto: ti - Add support for AES-XTS in DTHEv2 driver T Pratham
2025-11-11 11:08 ` [PATCH v6 2/4] crypto: ti - Add support for AES-CTR " T Pratham
@ 2025-11-11 11:08 ` T Pratham
2025-11-14 6:47 ` kernel test robot
` (2 more replies)
2025-11-11 11:08 ` [PATCH v6 4/4] crypto: ti - Add support for AES-CCM " T Pratham
3 siblings, 3 replies; 11+ messages in thread
From: T Pratham @ 2025-11-11 11:08 UTC (permalink / raw)
To: T Pratham, Herbert Xu, David S. Miller
Cc: Manorit Chawdhry, Kamlesh Gurudasani, Shiva Tripathi,
Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto, linux-kernel
AES-GCM is an AEAD algorithm supporting both encryption and
authentication of data. This patch introduces support for AES-GCM as the
first AEAD algorithm supported by the DTHEv2 driver.
Signed-off-by: T Pratham <t-pratham@ti.com>
---
drivers/crypto/ti/Kconfig | 2 +
drivers/crypto/ti/dthev2-aes.c | 591 +++++++++++++++++++++++++++++-
drivers/crypto/ti/dthev2-common.h | 9 +-
3 files changed, 600 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/ti/Kconfig b/drivers/crypto/ti/Kconfig
index 6027e12de279d..221e483737439 100644
--- a/drivers/crypto/ti/Kconfig
+++ b/drivers/crypto/ti/Kconfig
@@ -8,6 +8,8 @@ config CRYPTO_DEV_TI_DTHEV2
select CRYPTO_CBC
select CRYPTO_CTR
select CRYPTO_XTS
+ select CRYPTO_GCM
+ select SG_SPLIT
help
This enables support for the TI DTHE V2 hw cryptography engine
which can be found on TI K3 SOCs. Selecting this enables use
diff --git a/drivers/crypto/ti/dthev2-aes.c b/drivers/crypto/ti/dthev2-aes.c
index 1f4a953c6e2a0..f52e888cc7bd9 100644
--- a/drivers/crypto/ti/dthev2-aes.c
+++ b/drivers/crypto/ti/dthev2-aes.c
@@ -10,6 +10,7 @@
#include <crypto/aes.h>
#include <crypto/algapi.h>
#include <crypto/engine.h>
+#include <crypto/gcm.h>
#include <crypto/internal/aead.h>
#include <crypto/internal/skcipher.h>
@@ -19,6 +20,7 @@
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/scatterlist.h>
/* Registers */
@@ -53,6 +55,7 @@
#define DTHE_P_AES_C_LENGTH_1 0x0058
#define DTHE_P_AES_AUTH_LENGTH 0x005C
#define DTHE_P_AES_DATA_IN_OUT 0x0060
+#define DTHE_P_AES_TAG_OUT 0x0070
#define DTHE_P_AES_SYSCONFIG 0x0084
#define DTHE_P_AES_IRQSTATUS 0x008C
@@ -65,6 +68,7 @@ enum aes_ctrl_mode_masks {
AES_CTRL_CBC_MASK = BIT(5),
AES_CTRL_CTR_MASK = BIT(6),
AES_CTRL_XTS_MASK = BIT(12) | BIT(11),
+ AES_CTRL_GCM_MASK = BIT(17) | BIT(16) | BIT(6),
};
#define DTHE_AES_CTRL_MODE_CLEAR_MASK ~GENMASK(28, 5)
@@ -91,6 +95,8 @@ enum aes_ctrl_mode_masks {
#define AES_IV_SIZE AES_BLOCK_SIZE
#define AES_BLOCK_WORDS (AES_BLOCK_SIZE / sizeof(u32))
#define AES_IV_WORDS AES_BLOCK_WORDS
+#define DTHE_AES_GCM_AAD_MAXLEN (BIT_ULL(32) - 1)
+#define POLL_TIMEOUT_INTERVAL HZ
static struct scatterlist *dthe_chain_pad_sg(struct scatterlist *sg,
unsigned int nents,
@@ -295,6 +301,9 @@ static void dthe_aes_set_ctrl_key(struct dthe_tfm_ctx *ctx,
case DTHE_AES_XTS:
ctrl_val |= AES_CTRL_XTS_MASK;
break;
+ case DTHE_AES_GCM:
+ ctrl_val |= AES_CTRL_GCM_MASK;
+ break;
}
if (iv_in) {
@@ -552,6 +561,552 @@ static int dthe_aes_decrypt(struct skcipher_request *req)
return dthe_aes_crypt(req);
}
+static int dthe_aead_init_tfm(struct crypto_aead *tfm)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
+ struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+ ctx->dev_data = dev_data;
+
+ const char *alg_name = crypto_tfm_alg_name(crypto_aead_tfm(tfm));
+
+ ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
+ CRYPTO_ALG_NEED_FALLBACK);
+ if (IS_ERR(ctx->aead_fb)) {
+ dev_err(dev_data->dev, "fallback driver %s couldn't be loaded\n",
+ alg_name);
+ return PTR_ERR(ctx->aead_fb);
+ }
+
+ return 0;
+}
+
+static void dthe_aead_exit_tfm(struct crypto_aead *tfm)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
+
+ crypto_free_sync_aead(ctx->aead_fb);
+}
+
+/**
+ * dthe_aead_prep_src - Prepare source scatterlist for AEAD from input req->src
+ * @sg: Input req->src scatterlist
+ * @assoclen: Input req->assoclen
+ * @cryptlen: Input req->cryptlen (minus the size of TAG in decryption)
+ * @assoc_pad_buf: Buffer to hold AAD padding if needed
+ * @crypt_pad_buf: Buffer to hold ciphertext/plaintext padding if needed
+ *
+ * Description:
+ * For modes with authentication, DTHEv2 hardware requires the input AAD and
+ * plaintext/ciphertext to be individually aligned to AES_BLOCK_SIZE. If either is not
+ * aligned, it needs to be padded with zeros by the software before passing the data to
+ * the hardware. However, linux crypto's aead_request provides the input with AAD and
+ * plaintext/ciphertext contiguously appended together in a single scatterlist.
+ *
+ * This helper function takes the input scatterlist and splits it into separate
+ * scatterlists for AAD and plaintext/ciphertext, ensuring each is aligned to
+ * AES_BLOCK_SIZE by adding necessary padding, and then merges the aligned scatterlists
+ * back into a single scatterlist for processing.
+ *
+ * Return:
+ * Pointer to the merged scatterlist, or ERR_PTR(error) on failure.
+ * The calling function needs to free the returned scatterlist when done.
+ **/
+static struct scatterlist *dthe_aead_prep_src(struct scatterlist *sg,
+ unsigned int assoclen,
+ unsigned int cryptlen,
+ u8 *assoc_pad_buf,
+ u8 *crypt_pad_buf)
+{
+ struct scatterlist *in_sg[2];
+ struct scatterlist *to_sg;
+ struct scatterlist *src;
+ size_t split_sizes[2] = {assoclen, cryptlen};
+ int out_mapped_nents[2];
+ int crypt_nents = 0, assoc_nents = 0, src_nents = 0;
+ int err = 0;
+
+ /* sg_split does not work properly if one of the split_sizes is 0 */
+ if (cryptlen == 0 || assoclen == 0) {
+ /*
+ * Assigning both to sg does not matter as assoclen = 0 or cryptlen = 0
+ * being passed to dthe_copy_sg will take care to copy the sg correctly
+ */
+ in_sg[0] = sg;
+ in_sg[1] = sg;
+
+ src_nents = sg_nents_for_len(sg, assoclen + cryptlen);
+ } else {
+ err = sg_split(sg, 0, 0, 2, split_sizes, in_sg, out_mapped_nents, GFP_ATOMIC);
+ if (err)
+ goto dthe_aead_prep_src_split_err;
+ assoc_nents = sg_nents_for_len(in_sg[0], assoclen);
+ crypt_nents = sg_nents_for_len(in_sg[1], cryptlen);
+
+ src_nents = assoc_nents + crypt_nents;
+ }
+
+ if (assoclen % AES_BLOCK_SIZE)
+ src_nents++;
+ if (cryptlen % AES_BLOCK_SIZE)
+ src_nents++;
+
+ src = kmalloc_array(src_nents, sizeof(struct scatterlist), GFP_ATOMIC);
+ if (!src) {
+ err = -ENOMEM;
+ goto dthe_aead_prep_src_mem_err;
+ }
+
+ sg_init_table(src, src_nents);
+ to_sg = src;
+
+ to_sg = dthe_copy_sg(to_sg, in_sg[0], assoclen);
+ if (assoclen % AES_BLOCK_SIZE) {
+ unsigned int pad_len = AES_BLOCK_SIZE - (assoclen % AES_BLOCK_SIZE);
+
+ sg_set_buf(to_sg, assoc_pad_buf, pad_len);
+ to_sg = sg_next(to_sg);
+ }
+
+ to_sg = dthe_copy_sg(to_sg, in_sg[1], cryptlen);
+ if (cryptlen % AES_BLOCK_SIZE) {
+ unsigned int pad_len = AES_BLOCK_SIZE - (cryptlen % AES_BLOCK_SIZE);
+
+ sg_set_buf(to_sg, crypt_pad_buf, pad_len);
+ to_sg = sg_next(to_sg);
+ }
+
+dthe_aead_prep_src_mem_err:
+ if (cryptlen != 0 && assoclen != 0) {
+ kfree(in_sg[0]);
+ kfree(in_sg[1]);
+ }
+
+dthe_aead_prep_src_split_err:
+ if (err)
+ return ERR_PTR(err);
+ return src;
+}
+
+/**
+ * dthe_aead_prep_dst - Prepare destination scatterlist for AEAD from input req->dst
+ * @sg: Input req->dst scatterlist
+ * @assoclen: Input req->assoclen
+ * @cryptlen: Input req->cryptlen (minus the size of TAG in decryption)
+ * @pad_buf: Buffer to hold ciphertext/plaintext padding if needed
+ *
+ * Description:
+ * For modes with authentication, DTHEv2 hardware returns encrypted ciphertext/decrypted
+ * plaintext through DMA and TAG through MMRs. However, the dst scatterlist in linux
+ * crypto's aead_request is allocated same as input req->src scatterlist. That is, it
+ * contains space for AAD in the beginning and ciphertext/plaintext at the end, with no
+ * alignment padding. This causes issues with DMA engine and DTHEv2 hardware.
+ *
+ * This helper function takes the output scatterlist and maps the part of the buffer
+ * which holds only the ciphertext/plaintext to a new scatterlist. It also adds a padding
+ * to align it with AES_BLOCK_SIZE.
+ *
+ * Return:
+ * Pointer to the trimmed scatterlist, or ERR_PTR(error) on failure.
+ * The calling function needs to free the returned scatterlist when done.
+ **/
+static struct scatterlist *dthe_aead_prep_dst(struct scatterlist *sg,
+ unsigned int assoclen,
+ unsigned int cryptlen,
+ u8 *pad_buf)
+{
+ struct scatterlist *out_sg[1];
+ struct scatterlist *dst;
+ struct scatterlist *to_sg;
+ size_t split_sizes[1] = {cryptlen};
+ int out_mapped_nents[1];
+ int dst_nents = 0;
+ int err = 0;
+
+ err = sg_split(sg, 0, assoclen, 1, split_sizes, out_sg, out_mapped_nents, GFP_ATOMIC);
+ if (err)
+ goto dthe_aead_prep_dst_split_err;
+
+ dst_nents = sg_nents_for_len(out_sg[0], cryptlen);
+ if (cryptlen % AES_BLOCK_SIZE)
+ dst_nents++;
+
+ dst = kmalloc_array(dst_nents, sizeof(struct scatterlist), GFP_ATOMIC);
+ if (!dst) {
+ err = -ENOMEM;
+ goto dthe_aead_prep_dst_mem_err;
+ }
+ sg_init_table(dst, dst_nents);
+
+ to_sg = dthe_copy_sg(dst, out_sg[0], cryptlen);
+ if (cryptlen % AES_BLOCK_SIZE) {
+ unsigned int pad_len = AES_BLOCK_SIZE - (cryptlen % AES_BLOCK_SIZE);
+
+ sg_set_buf(to_sg, pad_buf, pad_len);
+ to_sg = sg_next(to_sg);
+ }
+
+dthe_aead_prep_dst_mem_err:
+ kfree(out_sg[0]);
+
+dthe_aead_prep_dst_split_err:
+ if (err)
+ return ERR_PTR(err);
+ return dst;
+}
+
+static int dthe_aead_read_tag(struct dthe_tfm_ctx *ctx, u32 *tag)
+{
+ struct dthe_data *dev_data = dthe_get_dev(ctx);
+ void __iomem *aes_base_reg = dev_data->regs + DTHE_P_AES_BASE;
+ u32 val;
+ int ret;
+
+ ret = readl_relaxed_poll_timeout(aes_base_reg + DTHE_P_AES_CTRL, val,
+ (val & DTHE_AES_CTRL_SAVED_CTX_READY),
+ 0, POLL_TIMEOUT_INTERVAL);
+ if (ret)
+ return ret;
+
+ for (int i = 0; i < AES_BLOCK_WORDS; ++i)
+ tag[i] = readl_relaxed(aes_base_reg +
+ DTHE_P_AES_TAG_OUT +
+ DTHE_REG_SIZE * i);
+ return 0;
+}
+
+static int dthe_aead_enc_get_tag(struct aead_request *req)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
+ u32 tag[AES_BLOCK_WORDS];
+ int nents;
+ int ret;
+
+ ret = dthe_aead_read_tag(ctx, tag);
+ if (ret)
+ return ret;
+
+ nents = sg_nents_for_len(req->dst, req->cryptlen + req->assoclen + ctx->authsize);
+
+ sg_pcopy_from_buffer(req->dst, nents, tag, ctx->authsize,
+ req->assoclen + req->cryptlen);
+
+ return 0;
+}
+
+static int dthe_aead_dec_verify_tag(struct aead_request *req)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
+ u32 tag_out[AES_BLOCK_WORDS];
+ u32 tag_in[AES_BLOCK_WORDS];
+ int nents;
+ int ret;
+
+ ret = dthe_aead_read_tag(ctx, tag_out);
+ if (ret)
+ return ret;
+
+ nents = sg_nents_for_len(req->src, req->assoclen + req->cryptlen);
+
+ sg_pcopy_to_buffer(req->src, nents, tag_in, ctx->authsize,
+ req->assoclen + req->cryptlen - ctx->authsize);
+
+ if (memcmp(tag_in, tag_out, ctx->authsize))
+ return -EBADMSG;
+ else
+ return 0;
+}
+
+static int dthe_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
+
+ if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_256)
+ return -EINVAL;
+
+ ctx->aes_mode = DTHE_AES_GCM;
+ ctx->keylen = keylen;
+ memcpy(ctx->key, key, keylen);
+
+ crypto_sync_aead_clear_flags(ctx->aead_fb, CRYPTO_TFM_REQ_MASK);
+ crypto_sync_aead_set_flags(ctx->aead_fb,
+ crypto_aead_get_flags(tfm) &
+ CRYPTO_TFM_REQ_MASK);
+
+ return crypto_sync_aead_setkey(ctx->aead_fb, key, keylen);
+}
+
+static int dthe_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
+
+ /* Invalid auth size will be handled by crypto_aead_setauthsize() */
+ ctx->authsize = authsize;
+
+ return crypto_sync_aead_setauthsize(ctx->aead_fb, authsize);
+}
+
+static int dthe_aead_do_fallback(struct aead_request *req)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
+ struct dthe_aes_req_ctx *rctx = aead_request_ctx(req);
+
+ SYNC_AEAD_REQUEST_ON_STACK(subreq, ctx->aead_fb);
+
+ aead_request_set_callback(subreq, req->base.flags,
+ req->base.complete, req->base.data);
+ aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, req->iv);
+ aead_request_set_ad(subreq, req->assoclen);
+
+ return rctx->enc ? crypto_aead_encrypt(subreq) :
+ crypto_aead_decrypt(subreq);
+}
+
+static void dthe_aead_dma_in_callback(void *data)
+{
+ struct aead_request *req = (struct aead_request *)data;
+ struct dthe_aes_req_ctx *rctx = aead_request_ctx(req);
+
+ complete(&rctx->aes_compl);
+}
+
+static int dthe_aead_run(struct crypto_engine *engine, void *areq)
+{
+ struct aead_request *req = container_of(areq, struct aead_request, base);
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
+ struct dthe_aes_req_ctx *rctx = aead_request_ctx(req);
+ struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+ unsigned int cryptlen = req->cryptlen;
+ unsigned int assoclen = req->assoclen;
+ unsigned int authsize = ctx->authsize;
+ unsigned int unpadded_cryptlen;
+ struct scatterlist *src = req->src;
+ struct scatterlist *dst = req->dst;
+ u32 iv_in[AES_IV_WORDS];
+
+ int src_nents;
+ int dst_nents;
+ int src_mapped_nents, dst_mapped_nents;
+
+ u8 src_assoc_padbuf[AES_BLOCK_SIZE] = {0};
+ u8 src_crypt_padbuf[AES_BLOCK_SIZE] = {0};
+ u8 dst_crypt_padbuf[AES_BLOCK_SIZE] = {0};
+
+ enum dma_data_direction src_dir, dst_dir;
+
+ struct device *tx_dev, *rx_dev;
+ struct dma_async_tx_descriptor *desc_in, *desc_out;
+
+ int ret;
+
+ void __iomem *aes_base_reg = dev_data->regs + DTHE_P_AES_BASE;
+
+ u32 aes_irqenable_val = readl_relaxed(aes_base_reg + DTHE_P_AES_IRQENABLE);
+ u32 aes_sysconfig_val = readl_relaxed(aes_base_reg + DTHE_P_AES_SYSCONFIG);
+
+ aes_sysconfig_val |= DTHE_AES_SYSCONFIG_DMA_DATA_IN_OUT_EN;
+ writel_relaxed(aes_sysconfig_val, aes_base_reg + DTHE_P_AES_SYSCONFIG);
+
+ aes_irqenable_val |= DTHE_AES_IRQENABLE_EN_ALL;
+ writel_relaxed(aes_irqenable_val, aes_base_reg + DTHE_P_AES_IRQENABLE);
+
+ /* In decryption, the last authsize bytes are the TAG */
+ if (!rctx->enc)
+ cryptlen -= authsize;
+ unpadded_cryptlen = cryptlen;
+
+ /* Prep src and dst scatterlists */
+ src = dthe_aead_prep_src(req->src, req->assoclen, cryptlen,
+ src_assoc_padbuf, src_crypt_padbuf);
+ if (IS_ERR(src)) {
+ ret = PTR_ERR(src);
+ goto aead_prep_src_err;
+ }
+
+ if (req->assoclen % AES_BLOCK_SIZE)
+ assoclen += AES_BLOCK_SIZE - (req->assoclen % AES_BLOCK_SIZE);
+ if (cryptlen % AES_BLOCK_SIZE)
+ cryptlen += AES_BLOCK_SIZE - (cryptlen % AES_BLOCK_SIZE);
+
+ src_nents = sg_nents_for_len(src, assoclen + cryptlen);
+
+ if (cryptlen != 0) {
+ dst = dthe_aead_prep_dst(req->dst, req->assoclen, unpadded_cryptlen,
+ dst_crypt_padbuf);
+ if (IS_ERR(dst)) {
+ ret = PTR_ERR(dst);
+ goto aead_prep_dst_err;
+ }
+
+ dst_nents = sg_nents_for_len(dst, cryptlen);
+ }
+ /* Prep finished */
+
+ src_dir = DMA_TO_DEVICE;
+ dst_dir = DMA_FROM_DEVICE;
+
+ tx_dev = dmaengine_get_dma_device(dev_data->dma_aes_tx);
+ rx_dev = dmaengine_get_dma_device(dev_data->dma_aes_rx);
+
+ src_mapped_nents = dma_map_sg(tx_dev, src, src_nents, src_dir);
+ if (src_mapped_nents == 0) {
+ ret = -EINVAL;
+ goto aead_dma_map_src_err;
+ }
+
+ desc_out = dmaengine_prep_slave_sg(dev_data->dma_aes_tx, src, src_mapped_nents,
+ DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc_out) {
+ ret = -EINVAL;
+ goto aead_dma_prep_src_err;
+ }
+
+ desc_out->callback = dthe_aead_dma_in_callback;
+ desc_out->callback_param = req;
+
+ if (cryptlen != 0) {
+ dst_mapped_nents = dma_map_sg(rx_dev, dst, dst_nents, dst_dir);
+ if (dst_mapped_nents == 0) {
+ ret = -EINVAL;
+ goto aead_dma_prep_src_err;
+ }
+
+ desc_in = dmaengine_prep_slave_sg(dev_data->dma_aes_rx, dst,
+ dst_mapped_nents, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc_in) {
+ ret = -EINVAL;
+ goto aead_dma_prep_dst_err;
+ }
+ }
+
+ init_completion(&rctx->aes_compl);
+
+ /*
+ * HACK: There is an unknown hw issue where if the previous operation had alen = 0 and
+ * plen != 0, the current operation's tag calculation is incorrect in the case where
+ * plen = 0 and alen != 0 currently. This is a workaround for now which somehow works;
+ * by resetting the context by writing a 1 to the C_LENGTH_0 and AUTH_LENGTH registers.
+ */
+ if (cryptlen == 0) {
+ writel_relaxed(1, aes_base_reg + DTHE_P_AES_C_LENGTH_0);
+ writel_relaxed(1, aes_base_reg + DTHE_P_AES_AUTH_LENGTH);
+ }
+
+ if (req->iv) {
+ memcpy(iv_in, req->iv, GCM_AES_IV_SIZE);
+ } else {
+ iv_in[0] = 0;
+ iv_in[1] = 0;
+ iv_in[2] = 0;
+ }
+ iv_in[3] = 0x01000000;
+
+ /* Clear key2 to reset previous GHASH intermediate data */
+ for (int i = 0; i < AES_KEYSIZE_256 / sizeof(u32); ++i)
+ writel_relaxed(0, aes_base_reg + DTHE_P_AES_KEY2_6 + DTHE_REG_SIZE * i);
+
+ dthe_aes_set_ctrl_key(ctx, rctx, iv_in);
+
+ writel_relaxed(lower_32_bits(unpadded_cryptlen), aes_base_reg + DTHE_P_AES_C_LENGTH_0);
+ writel_relaxed(upper_32_bits(unpadded_cryptlen), aes_base_reg + DTHE_P_AES_C_LENGTH_1);
+ writel_relaxed(req->assoclen, aes_base_reg + DTHE_P_AES_AUTH_LENGTH);
+
+ if (cryptlen != 0)
+ dmaengine_submit(desc_in);
+ dmaengine_submit(desc_out);
+
+ if (cryptlen != 0)
+ dma_async_issue_pending(dev_data->dma_aes_rx);
+ dma_async_issue_pending(dev_data->dma_aes_tx);
+
+ /* Need to do timeout to ensure finalise gets called if DMA callback fails for any reason */
+ ret = wait_for_completion_timeout(&rctx->aes_compl, msecs_to_jiffies(DTHE_DMA_TIMEOUT_MS));
+ if (!ret) {
+ ret = -ETIMEDOUT;
+ if (cryptlen != 0)
+ dmaengine_terminate_sync(dev_data->dma_aes_rx);
+ dmaengine_terminate_sync(dev_data->dma_aes_tx);
+
+ for (int i = 0; i < AES_BLOCK_WORDS; ++i)
+ readl_relaxed(aes_base_reg + DTHE_P_AES_DATA_IN_OUT + DTHE_REG_SIZE * i);
+ } else {
+ ret = 0;
+ }
+
+ if (cryptlen != 0)
+ dma_sync_sg_for_cpu(rx_dev, dst, dst_nents, dst_dir);
+ if (rctx->enc)
+ ret = dthe_aead_enc_get_tag(req);
+ else
+ ret = dthe_aead_dec_verify_tag(req);
+
+aead_dma_prep_dst_err:
+ if (cryptlen != 0)
+ dma_unmap_sg(rx_dev, dst, dst_nents, dst_dir);
+aead_dma_prep_src_err:
+ dma_unmap_sg(tx_dev, src, src_nents, src_dir);
+
+aead_dma_map_src_err:
+ if (cryptlen != 0)
+ kfree(dst);
+
+aead_prep_dst_err:
+ kfree(src);
+
+aead_prep_src_err:
+ if (ret)
+ ret = dthe_aead_do_fallback(req);
+ local_bh_disable();
+ crypto_finalize_aead_request(engine, req, ret);
+ local_bh_enable();
+ return 0;
+}
+
+static int dthe_aead_crypt(struct aead_request *req)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
+ struct dthe_aes_req_ctx *rctx = aead_request_ctx(req);
+ struct dthe_data *dev_data = dthe_get_dev(ctx);
+ struct crypto_engine *engine;
+ unsigned int cryptlen = req->cryptlen;
+
+ /* In decryption, last authsize bytes are the TAG */
+ if (!rctx->enc)
+ cryptlen -= ctx->authsize;
+
+ /*
+ * Need to fallback to software in the following cases due to HW restrictions:
+ * - Both AAD and plaintext/ciphertext are zero length
+ * - AAD length is more than 2^32 - 1 bytes
+ * PS: req->cryptlen is currently unsigned int type, which causes the above condition
+ * tautologically false. If req->cryptlen were to be changed to a 64-bit type,
+ * the check for this would need to be added below.
+ */
+ if (req->assoclen == 0 && cryptlen == 0)
+ return dthe_aead_do_fallback(req);
+
+ engine = dev_data->engine;
+ return crypto_transfer_aead_request_to_engine(engine, req);
+}
+
+static int dthe_aead_encrypt(struct aead_request *req)
+{
+ struct dthe_aes_req_ctx *rctx = aead_request_ctx(req);
+
+ rctx->enc = 1;
+ return dthe_aead_crypt(req);
+}
+
+static int dthe_aead_decrypt(struct aead_request *req)
+{
+ struct dthe_aes_req_ctx *rctx = aead_request_ctx(req);
+
+ rctx->enc = 0;
+ return dthe_aead_crypt(req);
+}
+
static struct skcipher_engine_alg cipher_algs[] = {
{
.base.init = dthe_cipher_init_tfm,
@@ -648,12 +1203,46 @@ static struct skcipher_engine_alg cipher_algs[] = {
}, /* XTS AES */
};
+static struct aead_engine_alg aead_algs[] = {
+ {
+ .base.init = dthe_aead_init_tfm,
+ .base.exit = dthe_aead_exit_tfm,
+ .base.setkey = dthe_aead_setkey,
+ .base.setauthsize = dthe_aead_setauthsize,
+ .base.maxauthsize = AES_BLOCK_SIZE,
+ .base.encrypt = dthe_aead_encrypt,
+ .base.decrypt = dthe_aead_decrypt,
+ .base.chunksize = AES_BLOCK_SIZE,
+ .base.ivsize = GCM_AES_IV_SIZE,
+ .base.base = {
+ .cra_name = "gcm(aes)",
+ .cra_driver_name = "gcm-aes-dthev2",
+ .cra_priority = 299,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD |
+ CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct dthe_tfm_ctx),
+ .cra_reqsize = sizeof(struct dthe_aes_req_ctx),
+ .cra_module = THIS_MODULE,
+ },
+ .op.do_one_request = dthe_aead_run,
+ }, /* GCM AES */
+};
+
int dthe_register_aes_algs(void)
{
- return crypto_engine_register_skciphers(cipher_algs, ARRAY_SIZE(cipher_algs));
+ int ret = 0;
+
+ ret |= crypto_engine_register_skciphers(cipher_algs, ARRAY_SIZE(cipher_algs));
+ ret |= crypto_engine_register_aeads(aead_algs, ARRAY_SIZE(aead_algs));
+
+ return ret;
}
void dthe_unregister_aes_algs(void)
{
crypto_engine_unregister_skciphers(cipher_algs, ARRAY_SIZE(cipher_algs));
+ crypto_engine_unregister_aeads(aead_algs, ARRAY_SIZE(aead_algs));
}
diff --git a/drivers/crypto/ti/dthev2-common.h b/drivers/crypto/ti/dthev2-common.h
index f12b94d64e134..7c54291359bf5 100644
--- a/drivers/crypto/ti/dthev2-common.h
+++ b/drivers/crypto/ti/dthev2-common.h
@@ -38,6 +38,7 @@ enum dthe_aes_mode {
DTHE_AES_CBC,
DTHE_AES_CTR,
DTHE_AES_XTS,
+ DTHE_AES_GCM,
};
/* Driver specific struct definitions */
@@ -78,16 +79,22 @@ struct dthe_list {
* struct dthe_tfm_ctx - Transform ctx struct containing ctx for all sub-components of DTHE V2
* @dev_data: Device data struct pointer
* @keylen: AES key length
+ * @authsize: Authentication size for modes with authentication
* @key: AES key
* @aes_mode: AES mode
+ * @aead_fb: Fallback crypto aead handle
* @skcipher_fb: Fallback crypto skcipher handle for AES-XTS mode
*/
struct dthe_tfm_ctx {
struct dthe_data *dev_data;
unsigned int keylen;
+ unsigned int authsize;
u32 key[DTHE_MAX_KEYSIZE / sizeof(u32)];
enum dthe_aes_mode aes_mode;
- struct crypto_sync_skcipher *skcipher_fb;
+ union {
+ struct crypto_sync_aead *aead_fb;
+ struct crypto_sync_skcipher *skcipher_fb;
+ };
};
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 4/4] crypto: ti - Add support for AES-CCM in DTHEv2 driver
2025-11-11 11:08 [PATCH v6 0/4] Add support for more AES modes in TI DTHEv2 T Pratham
` (2 preceding siblings ...)
2025-11-11 11:08 ` [PATCH v6 3/4] crypto: ti - Add support for AES-GCM " T Pratham
@ 2025-11-11 11:08 ` T Pratham
3 siblings, 0 replies; 11+ messages in thread
From: T Pratham @ 2025-11-11 11:08 UTC (permalink / raw)
To: T Pratham, Herbert Xu, David S. Miller
Cc: Manorit Chawdhry, Kamlesh Gurudasani, Shiva Tripathi,
Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto, linux-kernel
AES-CCM is an AEAD algorithm supporting both encryption and
authentication of data. This patch introduces support for AES-CCM AEAD
algorithm in the DTHEv2 driver.
Signed-off-by: T Pratham <t-pratham@ti.com>
---
drivers/crypto/ti/Kconfig | 1 +
drivers/crypto/ti/dthev2-aes.c | 129 ++++++++++++++++++++++++++----
drivers/crypto/ti/dthev2-common.h | 1 +
3 files changed, 115 insertions(+), 16 deletions(-)
diff --git a/drivers/crypto/ti/Kconfig b/drivers/crypto/ti/Kconfig
index 221e483737439..1a3a571ac8cef 100644
--- a/drivers/crypto/ti/Kconfig
+++ b/drivers/crypto/ti/Kconfig
@@ -9,6 +9,7 @@ config CRYPTO_DEV_TI_DTHEV2
select CRYPTO_CTR
select CRYPTO_XTS
select CRYPTO_GCM
+ select CRYPTO_CCM
select SG_SPLIT
help
This enables support for the TI DTHE V2 hw cryptography engine
diff --git a/drivers/crypto/ti/dthev2-aes.c b/drivers/crypto/ti/dthev2-aes.c
index f52e888cc7bd9..5e46733736a7a 100644
--- a/drivers/crypto/ti/dthev2-aes.c
+++ b/drivers/crypto/ti/dthev2-aes.c
@@ -16,6 +16,7 @@
#include "dthev2-common.h"
+#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
@@ -69,6 +70,7 @@ enum aes_ctrl_mode_masks {
AES_CTRL_CTR_MASK = BIT(6),
AES_CTRL_XTS_MASK = BIT(12) | BIT(11),
AES_CTRL_GCM_MASK = BIT(17) | BIT(16) | BIT(6),
+ AES_CTRL_CCM_MASK = BIT(18) | BIT(6),
};
#define DTHE_AES_CTRL_MODE_CLEAR_MASK ~GENMASK(28, 5)
@@ -81,6 +83,11 @@ enum aes_ctrl_mode_masks {
#define DTHE_AES_CTRL_CTR_WIDTH_128B (BIT(7) | BIT(8))
+#define DTHE_AES_CCM_L_FROM_IV_MASK GENMASK(2, 0)
+#define DTHE_AES_CCM_M_BITS GENMASK(2, 0)
+#define DTHE_AES_CTRL_CCM_L_FIELD_MASK GENMASK(21, 19)
+#define DTHE_AES_CTRL_CCM_M_FIELD_MASK GENMASK(24, 22)
+
#define DTHE_AES_CTRL_SAVE_CTX_SET BIT(29)
#define DTHE_AES_CTRL_OUTPUT_READY BIT_MASK(0)
@@ -96,6 +103,8 @@ enum aes_ctrl_mode_masks {
#define AES_BLOCK_WORDS (AES_BLOCK_SIZE / sizeof(u32))
#define AES_IV_WORDS AES_BLOCK_WORDS
#define DTHE_AES_GCM_AAD_MAXLEN (BIT_ULL(32) - 1)
+#define DTHE_AES_CCM_AAD_MAXLEN (BIT(16) - BIT(8))
+#define DTHE_AES_CCM_CRYPT_MAXLEN (BIT_ULL(61) - 1)
#define POLL_TIMEOUT_INTERVAL HZ
static struct scatterlist *dthe_chain_pad_sg(struct scatterlist *sg,
@@ -304,6 +313,13 @@ static void dthe_aes_set_ctrl_key(struct dthe_tfm_ctx *ctx,
case DTHE_AES_GCM:
ctrl_val |= AES_CTRL_GCM_MASK;
break;
+ case DTHE_AES_CCM:
+ ctrl_val |= AES_CTRL_CCM_MASK;
+ ctrl_val |= FIELD_PREP(DTHE_AES_CTRL_CCM_L_FIELD_MASK,
+ (iv_in[0] & DTHE_AES_CCM_L_FROM_IV_MASK));
+ ctrl_val |= FIELD_PREP(DTHE_AES_CTRL_CCM_M_FIELD_MASK,
+ ((ctx->authsize - 2) >> 1) & DTHE_AES_CCM_M_BITS);
+ break;
}
if (iv_in) {
@@ -824,10 +840,6 @@ static int dthe_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int
if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_256)
return -EINVAL;
- ctx->aes_mode = DTHE_AES_GCM;
- ctx->keylen = keylen;
- memcpy(ctx->key, key, keylen);
-
crypto_sync_aead_clear_flags(ctx->aead_fb, CRYPTO_TFM_REQ_MASK);
crypto_sync_aead_set_flags(ctx->aead_fb,
crypto_aead_get_flags(tfm) &
@@ -836,6 +848,28 @@ static int dthe_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int
return crypto_sync_aead_setkey(ctx->aead_fb, key, keylen);
}
+static int dthe_gcm_aes_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
+
+ ctx->aes_mode = DTHE_AES_GCM;
+ ctx->keylen = keylen;
+ memcpy(ctx->key, key, keylen);
+
+ return dthe_aead_setkey(tfm, key, keylen);
+}
+
+static int dthe_ccm_aes_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
+{
+ struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
+
+ ctx->aes_mode = DTHE_AES_CCM;
+ ctx->keylen = keylen;
+ memcpy(ctx->key, key, keylen);
+
+ return dthe_aead_setkey(tfm, key, keylen);
+}
+
static int dthe_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
{
struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
@@ -994,14 +1028,18 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
writel_relaxed(1, aes_base_reg + DTHE_P_AES_AUTH_LENGTH);
}
- if (req->iv) {
- memcpy(iv_in, req->iv, GCM_AES_IV_SIZE);
+ if (ctx->aes_mode == DTHE_AES_GCM) {
+ if (req->iv) {
+ memcpy(iv_in, req->iv, GCM_AES_IV_SIZE);
+ } else {
+ iv_in[0] = 0;
+ iv_in[1] = 0;
+ iv_in[2] = 0;
+ }
+ iv_in[3] = 0x01000000;
} else {
- iv_in[0] = 0;
- iv_in[1] = 0;
- iv_in[2] = 0;
+ memcpy(iv_in, req->iv, AES_IV_SIZE);
}
- iv_in[3] = 0x01000000;
/* Clear key2 to reset previous GHASH intermediate data */
for (int i = 0; i < AES_KEYSIZE_256 / sizeof(u32); ++i)
@@ -1071,20 +1109,54 @@ static int dthe_aead_crypt(struct aead_request *req)
struct dthe_data *dev_data = dthe_get_dev(ctx);
struct crypto_engine *engine;
unsigned int cryptlen = req->cryptlen;
+ bool is_zero_ctr = true;
/* In decryption, last authsize bytes are the TAG */
if (!rctx->enc)
cryptlen -= ctx->authsize;
+ if (ctx->aes_mode == DTHE_AES_CCM) {
+ /*
+ * For CCM Mode, the 128-bit IV contains the following:
+ * | 0 .. 2 | 3 .. 7 | 8 .. (127-8*L) | (128-8*L) .. 127 |
+ * | L-1 | Zero | Nonce | Counter |
+ * L needs to be between 2-8 (inclusive), i.e. 1 <= (L-1) <= 7
+ * and the next 5 bits need to be zeroes. Else return -EINVAL
+ */
+ u8 *iv = req->iv;
+ u8 L = iv[0];
+
+ if (L < 1 || L > 7)
+ return -EINVAL;
+ /*
+ * DTHEv2 HW can only work with zero initial counter in CCM mode.
+ * Check if the initial counter value is zero or not
+ */
+ for (int i = 0; i < L + 1; ++i) {
+ if (iv[AES_IV_SIZE - 1 - i] != 0) {
+ is_zero_ctr = false;
+ break;
+ }
+ }
+ }
+
/*
* Need to fallback to software in the following cases due to HW restrictions:
* - Both AAD and plaintext/ciphertext are zero length
- * - AAD length is more than 2^32 - 1 bytes
- * PS: req->cryptlen is currently unsigned int type, which causes the above condition
- * tautologically false. If req->cryptlen were to be changed to a 64-bit type,
- * the check for this would need to be added below.
+ * - For AES-GCM, AAD length is more than 2^32 - 1 bytes
+ * - For AES-CCM, AAD length is more than 2^16 - 2^8 bytes
+ * - For AES-CCM, plaintext/ciphertext length is more than 2^61 - 1 bytes
+ * - For AES-CCM, AAD length is non-zero but plaintext/ciphertext length is zero
+ * - For AES-CCM, the initial counter (last L+1 bytes of IV) is not all zeroes
+ *
+ * PS: req->cryptlen is currently unsigned int type, which causes the second and fourth
+ * cases above tautologically false. If req->cryptlen is to be changed to a 64-bit
+ * type, the check for these would also need to be added below.
*/
- if (req->assoclen == 0 && cryptlen == 0)
+ if ((req->assoclen == 0 && cryptlen == 0) ||
+ (ctx->aes_mode == DTHE_AES_CCM && req->assoclen > DTHE_AES_CCM_AAD_MAXLEN) ||
+ (ctx->aes_mode == DTHE_AES_CCM && cryptlen == 0) ||
+ (ctx->aes_mode == DTHE_AES_CCM && !is_zero_ctr))
return dthe_aead_do_fallback(req);
engine = dev_data->engine;
@@ -1207,7 +1279,7 @@ static struct aead_engine_alg aead_algs[] = {
{
.base.init = dthe_aead_init_tfm,
.base.exit = dthe_aead_exit_tfm,
- .base.setkey = dthe_aead_setkey,
+ .base.setkey = dthe_gcm_aes_setkey,
.base.setauthsize = dthe_aead_setauthsize,
.base.maxauthsize = AES_BLOCK_SIZE,
.base.encrypt = dthe_aead_encrypt,
@@ -1229,6 +1301,31 @@ static struct aead_engine_alg aead_algs[] = {
},
.op.do_one_request = dthe_aead_run,
}, /* GCM AES */
+ {
+ .base.init = dthe_aead_init_tfm,
+ .base.exit = dthe_aead_exit_tfm,
+ .base.setkey = dthe_ccm_aes_setkey,
+ .base.setauthsize = dthe_aead_setauthsize,
+ .base.maxauthsize = AES_BLOCK_SIZE,
+ .base.encrypt = dthe_aead_encrypt,
+ .base.decrypt = dthe_aead_decrypt,
+ .base.chunksize = AES_BLOCK_SIZE,
+ .base.ivsize = AES_IV_SIZE,
+ .base.base = {
+ .cra_name = "ccm(aes)",
+ .cra_driver_name = "ccm-aes-dthev2",
+ .cra_priority = 299,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD |
+ CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct dthe_tfm_ctx),
+ .cra_reqsize = sizeof(struct dthe_aes_req_ctx),
+ .cra_module = THIS_MODULE,
+ },
+ .op.do_one_request = dthe_aead_run,
+ }, /* CCM AES */
};
int dthe_register_aes_algs(void)
diff --git a/drivers/crypto/ti/dthev2-common.h b/drivers/crypto/ti/dthev2-common.h
index 7c54291359bf5..3b8d30b3408a0 100644
--- a/drivers/crypto/ti/dthev2-common.h
+++ b/drivers/crypto/ti/dthev2-common.h
@@ -39,6 +39,7 @@ enum dthe_aes_mode {
DTHE_AES_CTR,
DTHE_AES_XTS,
DTHE_AES_GCM,
+ DTHE_AES_CCM,
};
/* Driver specific struct definitions */
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v6 1/4] crypto: ti - Add support for AES-XTS in DTHEv2 driver
2025-11-11 11:08 ` [PATCH v6 1/4] crypto: ti - Add support for AES-XTS in DTHEv2 driver T Pratham
@ 2025-11-11 11:40 ` T Pratham
0 siblings, 0 replies; 11+ messages in thread
From: T Pratham @ 2025-11-11 11:40 UTC (permalink / raw)
To: Herbert Xu, David S. Miller
Cc: Manorit Chawdhry, Kamlesh Gurudasani, Shiva Tripathi,
Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto, linux-kernel
On 11/11/25 16:38, T Pratham wrote:
> Add support for XTS mode of operation for AES algorithm in the AES
> Engine of the DTHEv2 hardware cryptographic engine.
>
> Signed-off-by: T Pratham <t-pratham@ti.com>
Hi Herbert,
I noticed after pulling your tree that this patch was already merged.
You can safely ignore this patch in this series as no changes were made
to this.
--
Regards
T Pratham <t-pratham@ti.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 3/4] crypto: ti - Add support for AES-GCM in DTHEv2 driver
2025-11-11 11:08 ` [PATCH v6 3/4] crypto: ti - Add support for AES-GCM " T Pratham
@ 2025-11-14 6:47 ` kernel test robot
2025-11-14 9:04 ` T Pratham
2025-11-14 7:52 ` kernel test robot
2025-11-14 9:36 ` kernel test robot
2 siblings, 1 reply; 11+ messages in thread
From: kernel test robot @ 2025-11-14 6:47 UTC (permalink / raw)
To: T Pratham, Herbert Xu, David S. Miller
Cc: llvm, oe-kbuild-all, netdev, Manorit Chawdhry, Kamlesh Gurudasani,
Shiva Tripathi, Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto,
linux-kernel
Hi Pratham,
kernel test robot noticed the following build errors:
[auto build test ERROR on herbert-crypto-2.6/master]
[also build test ERROR on linus/master v6.18-rc5]
[cannot apply to herbert-cryptodev-2.6/master next-20251113]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/T-Pratham/crypto-ti-Add-support-for-AES-XTS-in-DTHEv2-driver/20251111-192827
base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git master
patch link: https://lore.kernel.org/r/20251111112137.976121-4-t-pratham%40ti.com
patch subject: [PATCH v6 3/4] crypto: ti - Add support for AES-GCM in DTHEv2 driver
config: arm-randconfig-003-20251114 (https://download.01.org/0day-ci/archive/20251114/202511141245.zQcC9EcY-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 0bba1e76581bad04e7d7f09f5115ae5e2989e0d9)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251114/202511141245.zQcC9EcY-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511141245.zQcC9EcY-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/crypto/ti/dthev2-aes.c:573:17: error: call to undeclared function 'crypto_alloc_sync_aead'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
573 | ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
| ^
drivers/crypto/ti/dthev2-aes.c:573:17: note: did you mean 'crypto_alloc_aead'?
include/crypto/aead.h:181:21: note: 'crypto_alloc_aead' declared here
181 | struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask);
| ^
>> drivers/crypto/ti/dthev2-aes.c:573:15: error: incompatible integer to pointer conversion assigning to 'struct crypto_sync_aead *' from 'int' [-Wint-conversion]
573 | ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
574 | CRYPTO_ALG_NEED_FALLBACK);
| ~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/crypto/ti/dthev2-aes.c:588:2: error: call to undeclared function 'crypto_free_sync_aead'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
588 | crypto_free_sync_aead(ctx->aead_fb);
| ^
drivers/crypto/ti/dthev2-aes.c:588:2: note: did you mean 'crypto_free_aead'?
include/crypto/aead.h:194:20: note: 'crypto_free_aead' declared here
194 | static inline void crypto_free_aead(struct crypto_aead *tfm)
| ^
>> drivers/crypto/ti/dthev2-aes.c:831:2: error: call to undeclared function 'crypto_sync_aead_clear_flags'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
831 | crypto_sync_aead_clear_flags(ctx->aead_fb, CRYPTO_TFM_REQ_MASK);
| ^
drivers/crypto/ti/dthev2-aes.c:831:2: note: did you mean 'crypto_aead_clear_flags'?
include/crypto/aead.h:298:20: note: 'crypto_aead_clear_flags' declared here
298 | static inline void crypto_aead_clear_flags(struct crypto_aead *tfm, u32 flags)
| ^
>> drivers/crypto/ti/dthev2-aes.c:832:2: error: call to undeclared function 'crypto_sync_aead_set_flags'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
832 | crypto_sync_aead_set_flags(ctx->aead_fb,
| ^
>> drivers/crypto/ti/dthev2-aes.c:836:9: error: call to undeclared function 'crypto_sync_aead_setkey'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
836 | return crypto_sync_aead_setkey(ctx->aead_fb, key, keylen);
| ^
drivers/crypto/ti/dthev2-aes.c:836:9: note: did you mean 'crypto_aead_setkey'?
include/crypto/aead.h:319:5: note: 'crypto_aead_setkey' declared here
319 | int crypto_aead_setkey(struct crypto_aead *tfm,
| ^
>> drivers/crypto/ti/dthev2-aes.c:846:9: error: call to undeclared function 'crypto_sync_aead_setauthsize'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
846 | return crypto_sync_aead_setauthsize(ctx->aead_fb, authsize);
| ^
drivers/crypto/ti/dthev2-aes.c:846:9: note: did you mean 'crypto_aead_setauthsize'?
include/crypto/aead.h:332:5: note: 'crypto_aead_setauthsize' declared here
332 | int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize);
| ^
>> drivers/crypto/ti/dthev2-aes.c:854:2: error: call to undeclared function 'SYNC_AEAD_REQUEST_ON_STACK'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
854 | SYNC_AEAD_REQUEST_ON_STACK(subreq, ctx->aead_fb);
| ^
>> drivers/crypto/ti/dthev2-aes.c:854:29: error: use of undeclared identifier 'subreq'
854 | SYNC_AEAD_REQUEST_ON_STACK(subreq, ctx->aead_fb);
| ^~~~~~
drivers/crypto/ti/dthev2-aes.c:856:28: error: use of undeclared identifier 'subreq'
856 | aead_request_set_callback(subreq, req->base.flags,
| ^~~~~~
drivers/crypto/ti/dthev2-aes.c:858:25: error: use of undeclared identifier 'subreq'
858 | aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, req->iv);
| ^~~~~~
drivers/crypto/ti/dthev2-aes.c:859:22: error: use of undeclared identifier 'subreq'
859 | aead_request_set_ad(subreq, req->assoclen);
| ^~~~~~
drivers/crypto/ti/dthev2-aes.c:861:41: error: use of undeclared identifier 'subreq'
861 | return rctx->enc ? crypto_aead_encrypt(subreq) :
| ^~~~~~
drivers/crypto/ti/dthev2-aes.c:862:23: error: use of undeclared identifier 'subreq'
862 | crypto_aead_decrypt(subreq);
| ^~~~~~
14 errors generated.
vim +/crypto_alloc_sync_aead +573 drivers/crypto/ti/dthev2-aes.c
563
564 static int dthe_aead_init_tfm(struct crypto_aead *tfm)
565 {
566 struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
567 struct dthe_data *dev_data = dthe_get_dev(ctx);
568
569 ctx->dev_data = dev_data;
570
571 const char *alg_name = crypto_tfm_alg_name(crypto_aead_tfm(tfm));
572
> 573 ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
574 CRYPTO_ALG_NEED_FALLBACK);
575 if (IS_ERR(ctx->aead_fb)) {
576 dev_err(dev_data->dev, "fallback driver %s couldn't be loaded\n",
577 alg_name);
578 return PTR_ERR(ctx->aead_fb);
579 }
580
581 return 0;
582 }
583
584 static void dthe_aead_exit_tfm(struct crypto_aead *tfm)
585 {
586 struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
587
> 588 crypto_free_sync_aead(ctx->aead_fb);
589 }
590
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 3/4] crypto: ti - Add support for AES-GCM in DTHEv2 driver
2025-11-11 11:08 ` [PATCH v6 3/4] crypto: ti - Add support for AES-GCM " T Pratham
2025-11-14 6:47 ` kernel test robot
@ 2025-11-14 7:52 ` kernel test robot
2025-11-14 9:36 ` kernel test robot
2 siblings, 0 replies; 11+ messages in thread
From: kernel test robot @ 2025-11-14 7:52 UTC (permalink / raw)
To: T Pratham, Herbert Xu, David S. Miller
Cc: oe-kbuild-all, netdev, Manorit Chawdhry, Kamlesh Gurudasani,
Shiva Tripathi, Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto,
linux-kernel
Hi Pratham,
kernel test robot noticed the following build warnings:
[auto build test WARNING on herbert-crypto-2.6/master]
[also build test WARNING on linus/master v6.18-rc5]
[cannot apply to herbert-cryptodev-2.6/master next-20251113]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/T-Pratham/crypto-ti-Add-support-for-AES-XTS-in-DTHEv2-driver/20251111-192827
base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git master
patch link: https://lore.kernel.org/r/20251111112137.976121-4-t-pratham%40ti.com
patch subject: [PATCH v6 3/4] crypto: ti - Add support for AES-GCM in DTHEv2 driver
config: s390-randconfig-002-20251114 (https://download.01.org/0day-ci/archive/20251114/202511141528.zox1IMuF-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251114/202511141528.zox1IMuF-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511141528.zox1IMuF-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_init_tfm':
drivers/crypto/ti/dthev2-aes.c:573:24: error: implicit declaration of function 'crypto_alloc_sync_aead'; did you mean 'crypto_alloc_aead'? [-Werror=implicit-function-declaration]
573 | ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
| ^~~~~~~~~~~~~~~~~~~~~~
| crypto_alloc_aead
>> drivers/crypto/ti/dthev2-aes.c:573:22: warning: assignment to 'struct crypto_sync_aead *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
573 | ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
| ^
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_exit_tfm':
drivers/crypto/ti/dthev2-aes.c:588:9: error: implicit declaration of function 'crypto_free_sync_aead'; did you mean 'crypto_free_aead'? [-Werror=implicit-function-declaration]
588 | crypto_free_sync_aead(ctx->aead_fb);
| ^~~~~~~~~~~~~~~~~~~~~
| crypto_free_aead
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_setkey':
drivers/crypto/ti/dthev2-aes.c:831:9: error: implicit declaration of function 'crypto_sync_aead_clear_flags'; did you mean 'crypto_aead_clear_flags'? [-Werror=implicit-function-declaration]
831 | crypto_sync_aead_clear_flags(ctx->aead_fb, CRYPTO_TFM_REQ_MASK);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| crypto_aead_clear_flags
drivers/crypto/ti/dthev2-aes.c:832:9: error: implicit declaration of function 'crypto_sync_aead_set_flags'; did you mean 'crypto_aead_set_flags'? [-Werror=implicit-function-declaration]
832 | crypto_sync_aead_set_flags(ctx->aead_fb,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
| crypto_aead_set_flags
drivers/crypto/ti/dthev2-aes.c:836:16: error: implicit declaration of function 'crypto_sync_aead_setkey'; did you mean 'crypto_aead_setkey'? [-Werror=implicit-function-declaration]
836 | return crypto_sync_aead_setkey(ctx->aead_fb, key, keylen);
| ^~~~~~~~~~~~~~~~~~~~~~~
| crypto_aead_setkey
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_setauthsize':
drivers/crypto/ti/dthev2-aes.c:846:16: error: implicit declaration of function 'crypto_sync_aead_setauthsize'; did you mean 'crypto_aead_setauthsize'? [-Werror=implicit-function-declaration]
846 | return crypto_sync_aead_setauthsize(ctx->aead_fb, authsize);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| crypto_aead_setauthsize
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_do_fallback':
drivers/crypto/ti/dthev2-aes.c:854:9: error: implicit declaration of function 'SYNC_AEAD_REQUEST_ON_STACK'; did you mean 'SYNC_SKCIPHER_REQUEST_ON_STACK'? [-Werror=implicit-function-declaration]
854 | SYNC_AEAD_REQUEST_ON_STACK(subreq, ctx->aead_fb);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
| SYNC_SKCIPHER_REQUEST_ON_STACK
drivers/crypto/ti/dthev2-aes.c:854:36: error: 'subreq' undeclared (first use in this function)
854 | SYNC_AEAD_REQUEST_ON_STACK(subreq, ctx->aead_fb);
| ^~~~~~
drivers/crypto/ti/dthev2-aes.c:854:36: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/crypto/ti/dthev2-aes.c:863:1: warning: control reaches end of non-void function [-Wreturn-type]
863 | }
| ^
cc1: some warnings being treated as errors
vim +573 drivers/crypto/ti/dthev2-aes.c
563
564 static int dthe_aead_init_tfm(struct crypto_aead *tfm)
565 {
566 struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
567 struct dthe_data *dev_data = dthe_get_dev(ctx);
568
569 ctx->dev_data = dev_data;
570
571 const char *alg_name = crypto_tfm_alg_name(crypto_aead_tfm(tfm));
572
> 573 ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
574 CRYPTO_ALG_NEED_FALLBACK);
575 if (IS_ERR(ctx->aead_fb)) {
576 dev_err(dev_data->dev, "fallback driver %s couldn't be loaded\n",
577 alg_name);
578 return PTR_ERR(ctx->aead_fb);
579 }
580
581 return 0;
582 }
583
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 3/4] crypto: ti - Add support for AES-GCM in DTHEv2 driver
2025-11-14 6:47 ` kernel test robot
@ 2025-11-14 9:04 ` T Pratham
0 siblings, 0 replies; 11+ messages in thread
From: T Pratham @ 2025-11-14 9:04 UTC (permalink / raw)
To: kernel test robot, Herbert Xu, David S. Miller
Cc: llvm, oe-kbuild-all, netdev, Manorit Chawdhry, Kamlesh Gurudasani,
Shiva Tripathi, Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto,
linux-kernel
On 14/11/25 12:17, kernel test robot wrote:
> Hi Pratham,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on herbert-crypto-2.6/master]
> [also build test ERROR on linus/master v6.18-rc5]
Applied to incorrect tree. The patch depends on [1] which has been
merged in cryptodev-2.6/master
> [cannot apply to herbert-cryptodev-2.6/master next-20251113]
This is maybe due to the first patch in the series, which was already
present in the tree?
>
> All errors (new ones prefixed by >>):
>
>>> drivers/crypto/ti/dthev2-aes.c:573:17: error: call to undeclared function 'crypto_alloc_sync_aead'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> 573 | ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
> | ^
> drivers/crypto/ti/dthev2-aes.c:573:17: note: did you mean 'crypto_alloc_aead'?
> include/crypto/aead.h:181:21: note: 'crypto_alloc_aead' declared here
> 181 | struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask);
> | ^
>>> drivers/crypto/ti/dthev2-aes.c:573:15: error: incompatible integer to pointer conversion assigning to 'struct crypto_sync_aead *' from 'int' [-Wint-conversion]
> 573 | ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
> | ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 574 | CRYPTO_ALG_NEED_FALLBACK);
> | ~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/crypto/ti/dthev2-aes.c:588:2: error: call to undeclared function 'crypto_free_sync_aead'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> 588 | crypto_free_sync_aead(ctx->aead_fb);
> | ^
> drivers/crypto/ti/dthev2-aes.c:588:2: note: did you mean 'crypto_free_aead'?
> include/crypto/aead.h:194:20: note: 'crypto_free_aead' declared here
> 194 | static inline void crypto_free_aead(struct crypto_aead *tfm)
> | ^
>>> drivers/crypto/ti/dthev2-aes.c:831:2: error: call to undeclared function 'crypto_sync_aead_clear_flags'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> 831 | crypto_sync_aead_clear_flags(ctx->aead_fb, CRYPTO_TFM_REQ_MASK);
> | ^
> drivers/crypto/ti/dthev2-aes.c:831:2: note: did you mean 'crypto_aead_clear_flags'?
> include/crypto/aead.h:298:20: note: 'crypto_aead_clear_flags' declared here
> 298 | static inline void crypto_aead_clear_flags(struct crypto_aead *tfm, u32 flags)
> | ^
>>> drivers/crypto/ti/dthev2-aes.c:832:2: error: call to undeclared function 'crypto_sync_aead_set_flags'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> 832 | crypto_sync_aead_set_flags(ctx->aead_fb,
> | ^
>>> drivers/crypto/ti/dthev2-aes.c:836:9: error: call to undeclared function 'crypto_sync_aead_setkey'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> 836 | return crypto_sync_aead_setkey(ctx->aead_fb, key, keylen);
> | ^
> drivers/crypto/ti/dthev2-aes.c:836:9: note: did you mean 'crypto_aead_setkey'?
> include/crypto/aead.h:319:5: note: 'crypto_aead_setkey' declared here
> 319 | int crypto_aead_setkey(struct crypto_aead *tfm,
> | ^
>>> drivers/crypto/ti/dthev2-aes.c:846:9: error: call to undeclared function 'crypto_sync_aead_setauthsize'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> 846 | return crypto_sync_aead_setauthsize(ctx->aead_fb, authsize);
> | ^
> drivers/crypto/ti/dthev2-aes.c:846:9: note: did you mean 'crypto_aead_setauthsize'?
> include/crypto/aead.h:332:5: note: 'crypto_aead_setauthsize' declared here
> 332 | int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize);
> | ^
>>> drivers/crypto/ti/dthev2-aes.c:854:2: error: call to undeclared function 'SYNC_AEAD_REQUEST_ON_STACK'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> 854 | SYNC_AEAD_REQUEST_ON_STACK(subreq, ctx->aead_fb);
> | ^
>>> drivers/crypto/ti/dthev2-aes.c:854:29: error: use of undeclared identifier 'subreq'
> 854 | SYNC_AEAD_REQUEST_ON_STACK(subreq, ctx->aead_fb);
> | ^~~~~~
> drivers/crypto/ti/dthev2-aes.c:856:28: error: use of undeclared identifier 'subreq'
> 856 | aead_request_set_callback(subreq, req->base.flags,
> | ^~~~~~
> drivers/crypto/ti/dthev2-aes.c:858:25: error: use of undeclared identifier 'subreq'
> 858 | aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, req->iv);
> | ^~~~~~
> drivers/crypto/ti/dthev2-aes.c:859:22: error: use of undeclared identifier 'subreq'
> 859 | aead_request_set_ad(subreq, req->assoclen);
> | ^~~~~~
> drivers/crypto/ti/dthev2-aes.c:861:41: error: use of undeclared identifier 'subreq'
> 861 | return rctx->enc ? crypto_aead_encrypt(subreq) :
> | ^~~~~~
> drivers/crypto/ti/dthev2-aes.c:862:23: error: use of undeclared identifier 'subreq'
> 862 | crypto_aead_decrypt(subreq);
> | ^~~~~~
> 14 errors generated.
>
All the errors are due to the patch [1] not being present in the applied
tree. It should be fine when applied to cryptodev-2.6/master.
[1]:
https://lore.kernel.org/linux-crypto/20251022171902.724369-2-t-pratham@ti.com/
--
Regards
T Pratham <t-pratham@ti.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 3/4] crypto: ti - Add support for AES-GCM in DTHEv2 driver
2025-11-11 11:08 ` [PATCH v6 3/4] crypto: ti - Add support for AES-GCM " T Pratham
2025-11-14 6:47 ` kernel test robot
2025-11-14 7:52 ` kernel test robot
@ 2025-11-14 9:36 ` kernel test robot
2 siblings, 0 replies; 11+ messages in thread
From: kernel test robot @ 2025-11-14 9:36 UTC (permalink / raw)
To: T Pratham, Herbert Xu, David S. Miller
Cc: oe-kbuild-all, netdev, Manorit Chawdhry, Kamlesh Gurudasani,
Shiva Tripathi, Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto,
linux-kernel
Hi Pratham,
kernel test robot noticed the following build errors:
[auto build test ERROR on herbert-crypto-2.6/master]
[also build test ERROR on linus/master v6.18-rc5]
[cannot apply to herbert-cryptodev-2.6/master next-20251114]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/T-Pratham/crypto-ti-Add-support-for-AES-XTS-in-DTHEv2-driver/20251111-192827
base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git master
patch link: https://lore.kernel.org/r/20251111112137.976121-4-t-pratham%40ti.com
patch subject: [PATCH v6 3/4] crypto: ti - Add support for AES-GCM in DTHEv2 driver
config: s390-randconfig-002-20251114 (https://download.01.org/0day-ci/archive/20251114/202511141721.73B0pu4H-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251114/202511141721.73B0pu4H-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511141721.73B0pu4H-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_init_tfm':
>> drivers/crypto/ti/dthev2-aes.c:573:24: error: implicit declaration of function 'crypto_alloc_sync_aead'; did you mean 'crypto_alloc_aead'? [-Werror=implicit-function-declaration]
573 | ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
| ^~~~~~~~~~~~~~~~~~~~~~
| crypto_alloc_aead
drivers/crypto/ti/dthev2-aes.c:573:22: warning: assignment to 'struct crypto_sync_aead *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
573 | ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
| ^
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_exit_tfm':
>> drivers/crypto/ti/dthev2-aes.c:588:9: error: implicit declaration of function 'crypto_free_sync_aead'; did you mean 'crypto_free_aead'? [-Werror=implicit-function-declaration]
588 | crypto_free_sync_aead(ctx->aead_fb);
| ^~~~~~~~~~~~~~~~~~~~~
| crypto_free_aead
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_setkey':
>> drivers/crypto/ti/dthev2-aes.c:831:9: error: implicit declaration of function 'crypto_sync_aead_clear_flags'; did you mean 'crypto_aead_clear_flags'? [-Werror=implicit-function-declaration]
831 | crypto_sync_aead_clear_flags(ctx->aead_fb, CRYPTO_TFM_REQ_MASK);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| crypto_aead_clear_flags
>> drivers/crypto/ti/dthev2-aes.c:832:9: error: implicit declaration of function 'crypto_sync_aead_set_flags'; did you mean 'crypto_aead_set_flags'? [-Werror=implicit-function-declaration]
832 | crypto_sync_aead_set_flags(ctx->aead_fb,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
| crypto_aead_set_flags
>> drivers/crypto/ti/dthev2-aes.c:836:16: error: implicit declaration of function 'crypto_sync_aead_setkey'; did you mean 'crypto_aead_setkey'? [-Werror=implicit-function-declaration]
836 | return crypto_sync_aead_setkey(ctx->aead_fb, key, keylen);
| ^~~~~~~~~~~~~~~~~~~~~~~
| crypto_aead_setkey
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_setauthsize':
>> drivers/crypto/ti/dthev2-aes.c:846:16: error: implicit declaration of function 'crypto_sync_aead_setauthsize'; did you mean 'crypto_aead_setauthsize'? [-Werror=implicit-function-declaration]
846 | return crypto_sync_aead_setauthsize(ctx->aead_fb, authsize);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| crypto_aead_setauthsize
drivers/crypto/ti/dthev2-aes.c: In function 'dthe_aead_do_fallback':
>> drivers/crypto/ti/dthev2-aes.c:854:9: error: implicit declaration of function 'SYNC_AEAD_REQUEST_ON_STACK'; did you mean 'SYNC_SKCIPHER_REQUEST_ON_STACK'? [-Werror=implicit-function-declaration]
854 | SYNC_AEAD_REQUEST_ON_STACK(subreq, ctx->aead_fb);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
| SYNC_SKCIPHER_REQUEST_ON_STACK
>> drivers/crypto/ti/dthev2-aes.c:854:36: error: 'subreq' undeclared (first use in this function)
854 | SYNC_AEAD_REQUEST_ON_STACK(subreq, ctx->aead_fb);
| ^~~~~~
drivers/crypto/ti/dthev2-aes.c:854:36: note: each undeclared identifier is reported only once for each function it appears in
drivers/crypto/ti/dthev2-aes.c:863:1: warning: control reaches end of non-void function [-Wreturn-type]
863 | }
| ^
cc1: some warnings being treated as errors
vim +573 drivers/crypto/ti/dthev2-aes.c
563
564 static int dthe_aead_init_tfm(struct crypto_aead *tfm)
565 {
566 struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
567 struct dthe_data *dev_data = dthe_get_dev(ctx);
568
569 ctx->dev_data = dev_data;
570
571 const char *alg_name = crypto_tfm_alg_name(crypto_aead_tfm(tfm));
572
> 573 ctx->aead_fb = crypto_alloc_sync_aead(alg_name, 0,
574 CRYPTO_ALG_NEED_FALLBACK);
575 if (IS_ERR(ctx->aead_fb)) {
576 dev_err(dev_data->dev, "fallback driver %s couldn't be loaded\n",
577 alg_name);
578 return PTR_ERR(ctx->aead_fb);
579 }
580
581 return 0;
582 }
583
584 static void dthe_aead_exit_tfm(struct crypto_aead *tfm)
585 {
586 struct dthe_tfm_ctx *ctx = crypto_aead_ctx(tfm);
587
> 588 crypto_free_sync_aead(ctx->aead_fb);
589 }
590
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 2/4] crypto: ti - Add support for AES-CTR in DTHEv2 driver
2025-11-11 11:08 ` [PATCH v6 2/4] crypto: ti - Add support for AES-CTR " T Pratham
@ 2025-11-21 3:11 ` Herbert Xu
0 siblings, 0 replies; 11+ messages in thread
From: Herbert Xu @ 2025-11-21 3:11 UTC (permalink / raw)
To: T Pratham
Cc: David S. Miller, Manorit Chawdhry, Kamlesh Gurudasani,
Shiva Tripathi, Kavitha Malarvizhi, Vishal Mahaveer, linux-crypto,
linux-kernel
On Tue, Nov 11, 2025 at 04:38:31PM +0530, T Pratham wrote:
>
> @@ -270,12 +326,17 @@ static int dthe_aes_run(struct crypto_engine *engine, void *areq)
> struct scatterlist *src = req->src;
> struct scatterlist *dst = req->dst;
>
> + struct scatterlist src_pad[2], dst_pad[2];
> +
> int src_nents = sg_nents_for_len(src, len);
> - int dst_nents;
> + int dst_nents = sg_nents_for_len(dst, len);
>
> int src_mapped_nents;
> int dst_mapped_nents;
>
> + u8 pad_buf[AES_BLOCK_SIZE] = {0};
You can't put stack memory into an SG list since the ability to
DMA to the stack is not guaranteed.
I suggest that you place the buffer into the request object instead.
The request object is designed to allow DMA and you can allocate as
much memory as you like by setting reqsize.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-11-21 3:11 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-11 11:08 [PATCH v6 0/4] Add support for more AES modes in TI DTHEv2 T Pratham
2025-11-11 11:08 ` [PATCH v6 1/4] crypto: ti - Add support for AES-XTS in DTHEv2 driver T Pratham
2025-11-11 11:40 ` T Pratham
2025-11-11 11:08 ` [PATCH v6 2/4] crypto: ti - Add support for AES-CTR " T Pratham
2025-11-21 3:11 ` Herbert Xu
2025-11-11 11:08 ` [PATCH v6 3/4] crypto: ti - Add support for AES-GCM " T Pratham
2025-11-14 6:47 ` kernel test robot
2025-11-14 9:04 ` T Pratham
2025-11-14 7:52 ` kernel test robot
2025-11-14 9:36 ` kernel test robot
2025-11-11 11:08 ` [PATCH v6 4/4] crypto: ti - Add support for AES-CCM " T Pratham
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox