[PATCH 4/4] crypto: ti: Add support for AES-CCM in DTHEv2 driver

T Pratham posted 4 patches 4 days, 15 hours ago
There is a newer version of this series
[PATCH 4/4] crypto: ti: Add support for AES-CCM in DTHEv2 driver
Posted by T Pratham 4 days, 15 hours ago
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    | 90 ++++++++++++++++++++++++++-----
 drivers/crypto/ti/dthev2-common.h |  1 +
 3 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/drivers/crypto/ti/Kconfig b/drivers/crypto/ti/Kconfig
index e1ef84b39267..02eff4f0e04b 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 6a3447846fbb..a40c6ea811c1 100644
--- a/drivers/crypto/ti/dthev2-aes.c
+++ b/drivers/crypto/ti/dthev2-aes.c
@@ -68,6 +68,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)
@@ -80,6 +81,10 @@ 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_CTRL_CCM_L_MASK		GENMASK(21, 19)
+#define DTHE_AES_CTRL_CCM_M_MAXVAL		GENMASK(24, 22)
+
 #define DTHE_AES_CTRL_SAVE_CTX_SET		BIT(29)
 
 #define DTHE_AES_CTRL_OUTPUT_READY		BIT_MASK(0)
@@ -95,6 +100,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)
 
 static int dthe_cipher_init_tfm(struct crypto_skcipher *tfm)
 {
@@ -232,6 +239,12 @@ 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_MASK,
+				       (iv_in[0] & DTHE_AES_CCM_L_FROM_IV_MASK));
+		ctrl_val |= DTHE_AES_CTRL_CCM_M_MAXVAL;
+		break;
 	}
 
 	if (iv_in) {
@@ -705,10 +718,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_aead_clear_flags(ctx->aead_fb, CRYPTO_TFM_REQ_MASK);
 	crypto_aead_set_flags(ctx->aead_fb,
 			      crypto_aead_get_flags(tfm) &
@@ -717,6 +726,28 @@ static int dthe_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int
 	return crypto_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);
@@ -855,14 +886,18 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
 
 	u32 iv_in[AES_IV_WORDS];
 
-	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)
@@ -950,10 +985,14 @@ static int dthe_aead_crypt(struct aead_request *req)
 
 	/* 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
+	 * - 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, ciphertext length is more than 2^61 - 1 bytes
 	 */
 	if ((req->assoclen == 0 && cryptlen == 0) ||
-	    req->assoclen > DTHE_AES_GCM_AAD_MAXLEN) {
+	    (ctx->aes_mode == DTHE_AES_GCM && req->assoclen > DTHE_AES_GCM_AAD_MAXLEN) ||
+	    (ctx->aes_mode == DTHE_AES_CCM && req->assoclen > DTHE_AES_CCM_AAD_MAXLEN) ||
+	    (ctx->aes_mode == DTHE_AES_CCM && cryptlen > DTHE_AES_CCM_CRYPT_MAXLEN)) {
 		struct aead_request *subreq = &rctx->fb_req;
 		int ret;
 
@@ -1084,7 +1123,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,
@@ -1106,6 +1145,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 3c9fe0633cca..3b3b133fc984 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
Re: [PATCH 4/4] crypto: ti: Add support for AES-CCM in DTHEv2 driver
Posted by kernel test robot 3 days, 9 hours ago
Hi Pratham,

kernel test robot noticed the following build warnings:

[auto build test WARNING on herbert-cryptodev-2.6/master]
[also build test WARNING on next-20250905]
[cannot apply to herbert-crypto-2.6/master linus/master v6.17-rc4]
[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/20250905-214245
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
patch link:    https://lore.kernel.org/r/20250905133504.2348972-8-t-pratham%40ti.com
patch subject: [PATCH 4/4] crypto: ti: Add support for AES-CCM in DTHEv2 driver
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20250907/202509070251.7MfOWGUB-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250907/202509070251.7MfOWGUB-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/202509070251.7MfOWGUB-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/crypto/ti/dthev2-aes.c:818:7: warning: variable 'unpadded_cryptlen' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
     818 |                 if (!dst) {
         |                     ^~~~
   drivers/crypto/ti/dthev2-aes.c:962:6: note: uninitialized use occurs here
     962 |         if (unpadded_cryptlen % AES_BLOCK_SIZE)
         |             ^~~~~~~~~~~~~~~~~
   drivers/crypto/ti/dthev2-aes.c:818:3: note: remove the 'if' if its condition is always false
     818 |                 if (!dst) {
         |                 ^~~~~~~~~~~
     819 |                         ret = -ENOMEM;
         |                         ~~~~~~~~~~~~~~
     820 |                         goto aead_prep_dst_err;
         |                         ~~~~~~~~~~~~~~~~~~~~~~~
     821 |                 }
         |                 ~
   drivers/crypto/ti/dthev2-aes.c:779:32: note: initialize the variable 'unpadded_cryptlen' to silence this warning
     779 |         unsigned int unpadded_cryptlen;
         |                                       ^
         |                                        = 0
>> drivers/crypto/ti/dthev2-aes.c:995:49: warning: result of comparison of constant 2305843009213693951 with expression of type 'unsigned int' is always false [-Wtautological-constant-out-of-range-compare]
     995 |             (ctx->aes_mode == DTHE_AES_CCM && cryptlen > DTHE_AES_CCM_CRYPT_MAXLEN)) {
         |                                               ~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~
   2 warnings generated.


vim +995 drivers/crypto/ti/dthev2-aes.c

   973	
   974	static int dthe_aead_crypt(struct aead_request *req)
   975	{
   976		struct dthe_tfm_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
   977		struct dthe_aes_req_ctx *rctx = aead_request_ctx(req);
   978		struct dthe_data *dev_data = dthe_get_dev(ctx);
   979		struct crypto_engine *engine;
   980		unsigned int cryptlen = req->cryptlen;
   981	
   982		// In decryption, last authsize bytes are the TAG
   983		if (!rctx->enc)
   984			cryptlen -= ctx->authsize;
   985	
   986		/* Need to fallback to software in the following cases due to HW restrictions:
   987		 * - Both AAD and plaintext/ciphertext are zero length
   988		 * - For AES-GCM, AAD length is more than 2^32 - 1 bytes
   989		 * - For AES-CCM, AAD length is more than 2^16 - 2^8 bytes
   990		 * - For AES-CCM, ciphertext length is more than 2^61 - 1 bytes
   991		 */
   992		if ((req->assoclen == 0 && cryptlen == 0) ||
   993		    (ctx->aes_mode == DTHE_AES_GCM && req->assoclen > DTHE_AES_GCM_AAD_MAXLEN) ||
   994		    (ctx->aes_mode == DTHE_AES_CCM && req->assoclen > DTHE_AES_CCM_AAD_MAXLEN) ||
 > 995		    (ctx->aes_mode == DTHE_AES_CCM && cryptlen > DTHE_AES_CCM_CRYPT_MAXLEN)) {
   996			struct aead_request *subreq = &rctx->fb_req;
   997			int ret;
   998	
   999			aead_request_set_tfm(subreq, ctx->aead_fb);
  1000			aead_request_set_callback(subreq, req->base.flags,
  1001						  req->base.complete, req->base.data);
  1002			aead_request_set_crypt(subreq, req->src, req->dst,
  1003					       req->cryptlen, req->iv);
  1004			aead_request_set_ad(subreq, req->assoclen);
  1005	
  1006			ret = rctx->enc ? crypto_aead_encrypt(subreq) :
  1007				crypto_aead_decrypt(subreq);
  1008	
  1009			return ret;
  1010		}
  1011	
  1012		engine = dev_data->engine;
  1013		return crypto_transfer_aead_request_to_engine(engine, req);
  1014	}
  1015	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki