Linux cryptographic layer development
 help / color / mirror / Atom feed
* [PATCH 0/2] Fix Qualcomm Crypto engine self tests failures
@ 2026-06-10  5:54 Kuldeep Singh
  2026-06-10  5:54 ` [PATCH 1/2] crypto: qce: Fix xts-aes-qce for weak keys Kuldeep Singh
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Kuldeep Singh @ 2026-06-10  5:54 UTC (permalink / raw)
  To: Thara Gopinath, Herbert Xu, David S. Miller, Bartosz Golaszewski,
	Eric Biggers
  Cc: Thara Gopinath, linux-crypto, linux-arm-msm, linux-kernel,
	Kuldeep Singh

QCE currents fails with crypto_sefltests for below 2 ciphers.
xts-aes qce and ctr-aes-qce.

Failure log snippet:
[    5.599170] alg: skcipher: xts-aes-qce setkey failed on test vector 0; expected_error=0, actual_error=-126, flags=0x1
[    5.599184] alg: self-tests for xts(aes) using xts-aes-qce failed (rc=-126)
[    5.599187] ------------[ cut here ]------------
[    5.599189] alg: self-tests for xts(aes) using xts-aes-qce failed (rc=-126)
[    5.599222] WARNING: crypto/testmgr.c:5804 at alg_test+0x2a0/0x3bc, CPU#3: cryptomgr_test/150

[    5.606169] alg: skcipher: ctr-aes-qce encryption test failed (wrong output IV) on test vector 4, cfg="in-place (one sglist)"
[    5.606176] 00000000: e7 82 1d b8 53 11 ac 47 e2 7d 18 d6 71 0c a7 61
[    5.606192] alg: self-tests for ctr(aes) using ctr-aes-qce failed (rc=-22)
[    5.606196] ------------[ cut here ]------------
[    5.606198] alg: self-tests for ctr(aes) using ctr-aes-qce failed (rc=-22)
[    5.606231] WARNING: crypto/testmgr.c:5804 at alg_test+0x2a0/0x3bc, CPU#3: cryptomgr_test/149

This patch series attempt to stabilize QCE and stabilize selftest
framework. The failures are common for all targets and is currently
validated on sm8750-mtp and qcs6490-rb3gen2 device.

Steps followed:
  - Enable EXPERT and CRYPTO_SEFLTESTS config.
  - Bootup validation and confirm selftests is triggered.

Signed-off-by: Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>
---
Kuldeep Singh (2):
      crypto: qce: Fix xts-aes-qce for weak keys
      crypto: qce: Fix CTR-AES for partial block requests

 drivers/crypto/qce/cipher.h   |  1 +
 drivers/crypto/qce/skcipher.c | 29 ++++++++++++++++++++++-------
 2 files changed, 23 insertions(+), 7 deletions(-)
---
base-commit: 49e02880ec0a8c378e811bc9d85da188d7c6204c
change-id: 20260610-qce_selftest_fix-2e0b66148651

Best regards,
--  
Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>


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

* [PATCH 1/2] crypto: qce: Fix xts-aes-qce for weak keys
  2026-06-10  5:54 [PATCH 0/2] Fix Qualcomm Crypto engine self tests failures Kuldeep Singh
@ 2026-06-10  5:54 ` Kuldeep Singh
  2026-06-10  5:54 ` [PATCH 2/2] crypto: qce: Fix CTR-AES for partial block requests Kuldeep Singh
  2026-06-10 18:42 ` [PATCH 0/2] Fix Qualcomm Crypto engine self tests failures Eric Biggers
  2 siblings, 0 replies; 5+ messages in thread
From: Kuldeep Singh @ 2026-06-10  5:54 UTC (permalink / raw)
  To: Thara Gopinath, Herbert Xu, David S. Miller, Bartosz Golaszewski,
	Eric Biggers
  Cc: Thara Gopinath, linux-crypto, linux-arm-msm, linux-kernel,
	Kuldeep Singh

The QCE hardware does not support AES XTS mode when key1 and key2 are
equal. The driver was handling this by unconditionally rejecting the
keys with -ENOKEY(-126), regardless of whether FIPS mode is active or
the FORBID_WEAK_KEYS flag is set.
[    5.599170] alg: skcipher: xts-aes-qce setkey failed on test vector 0; expected_error=0, actual_error=-126, flags=0x1
[    5.599184] alg: self-tests for xts(aes) using xts-aes-qce failed (rc=-126)

In general for weak keys,
- If FIPS mode is active or FORBID_WEAK_KEYS is set: return -EINVAL.
- In non-FIPS mode, Accept the key and encrypt successfully.

Since QCE was returning -ENOKEY for non-FIPS mode whereas the
expectation is to encrypt content and return success, the selftest saw a
mismatch and failed.

There are two problems in QCE behavior:
  * -ENOKEY is returned instead of -EINVAL for the FIPS/weak-key
    rejection case.
  * key1 == key2 is rejected even in non-FIPS mode

Fix xts-aes-qce behavior by using generic helper xts_verify_key() to
reject keys early with -EINVAL for FIPS mode active(or FORBID_WEAK_KEYS
set). For non-FIPS mode, since QCE hardware cannot accept the keys, use
software fallback mechanism to encrypt the data.

Fixes: f0d078dd6c49 ("crypto: qce - Return unsupported if key1 and key 2 are same for AES XTS algorithm")
Signed-off-by: Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>
---
 drivers/crypto/qce/cipher.h   |  1 +
 drivers/crypto/qce/skcipher.c | 20 +++++++++++++-------
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/qce/cipher.h b/drivers/crypto/qce/cipher.h
index 850f257d00f3..daea07551118 100644
--- a/drivers/crypto/qce/cipher.h
+++ b/drivers/crypto/qce/cipher.h
@@ -14,6 +14,7 @@
 struct qce_cipher_ctx {
 	u8 enc_key[QCE_MAX_KEY_SIZE];
 	unsigned int enc_keylen;
+	bool use_fallback;
 	struct crypto_skcipher *fallback;
 };
 
diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
index db0b648a56eb..224693a831f5 100644
--- a/drivers/crypto/qce/skcipher.c
+++ b/drivers/crypto/qce/skcipher.c
@@ -13,6 +13,7 @@
 #include <crypto/aes.h>
 #include <crypto/internal/des.h>
 #include <crypto/internal/skcipher.h>
+#include <crypto/xts.h>
 
 #include "cipher.h"
 
@@ -180,14 +181,17 @@ static int qce_skcipher_setkey(struct crypto_skcipher *ablk, const u8 *key,
 	if (!key || !keylen)
 		return -EINVAL;
 
-	/*
-	 * AES XTS key1 = key2 not supported by crypto engine.
-	 * Revisit to request a fallback cipher in this case.
-	 */
 	if (IS_XTS(flags)) {
+		ret = xts_verify_key(ablk, key, keylen);
+		if (ret)
+			return ret;
 		__keylen = keylen >> 1;
-		if (!memcmp(key, key + __keylen, __keylen))
-			return -ENOKEY;
+		/*
+		 * QCE does not support key1 == key2 for XTS.
+		 * Use fallback cipher in this case.
+		 */
+		ctx->use_fallback = !crypto_memneq(key, key + __keylen,
+						       __keylen);
 	} else {
 		__keylen = keylen;
 	}
@@ -287,12 +291,14 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
 	 * AES-XTS request with len > QCE_SECTOR_SIZE and
 	 * is not a multiple of it.(Revisit this condition to check if it is
 	 * needed in all versions of CE)
+	 * AES-XTS for weak keys in non-FIPS mode.
 	 */
 	if (IS_AES(rctx->flags) &&
 	    ((keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_256) ||
 	    (IS_XTS(rctx->flags) && ((req->cryptlen <= aes_sw_max_len) ||
 	    (req->cryptlen > QCE_SECTOR_SIZE &&
-	    req->cryptlen % QCE_SECTOR_SIZE))))) {
+	    req->cryptlen % QCE_SECTOR_SIZE))) ||
+	    (IS_XTS(rctx->flags) && ctx->use_fallback))) {
 		skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback);
 		skcipher_request_set_callback(&rctx->fallback_req,
 					      req->base.flags,

-- 
2.34.1


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

* [PATCH 2/2] crypto: qce: Fix CTR-AES for partial block requests
  2026-06-10  5:54 [PATCH 0/2] Fix Qualcomm Crypto engine self tests failures Kuldeep Singh
  2026-06-10  5:54 ` [PATCH 1/2] crypto: qce: Fix xts-aes-qce for weak keys Kuldeep Singh
@ 2026-06-10  5:54 ` Kuldeep Singh
  2026-06-10 18:46   ` Eric Biggers
  2026-06-10 18:42 ` [PATCH 0/2] Fix Qualcomm Crypto engine self tests failures Eric Biggers
  2 siblings, 1 reply; 5+ messages in thread
From: Kuldeep Singh @ 2026-06-10  5:54 UTC (permalink / raw)
  To: Thara Gopinath, Herbert Xu, David S. Miller, Bartosz Golaszewski,
	Eric Biggers
  Cc: Thara Gopinath, linux-crypto, linux-arm-msm, linux-kernel,
	Kuldeep Singh

In CTR mode, the IV acts as the initial counter block.
APer NIST SP 800-38A, after a CTR mode operation the next unused counter
value is:

IV_next = IV_in + ceil(cryptlen / AES_BLOCK_SIZE)

The skcipher requires req->iv to hold this updated counter on
completion, ensuring chained requests produce correct results.

Referring to Crypto6.0 documentation, Section 2.2.5 says:
"The count value increments automatically once per block of data (in
AES, a block is 16 bytes) based on the value in the
CRYPTO_ENCR_CNTR_MASK registers."

QCE increments internal counter register once per full 16-byte block(for
ctr-aes) is processed. In case of partial request length, the hardware
uses the current counter to generate keystreams but does not increment
the counter register afterwards. So the counter value written in
CRYPTO_ENCR_CNTRn_IVn later once read by software is one less than the
expected value.

Crypto selftest framework capture this scenario with test vector
4 comprising of a 499-byte payload (31 full blocks + 3 partial bytes).
Error:
[    5.606169] alg: skcipher: ctr-aes-qce encryption test failed (wrong output IV) on test vector 4, cfg="in-place (one sglist)"
[    5.606176] 00000000: e7 82 1d b8 53 11 ac 47 e2 7d 18 d6 71 0c a7 61
[    5.606192] alg: self-tests for ctr(aes) using ctr-aes-qce failed (rc=-22)
Expected iv_out: 0x62 (iv_in + 32)
Obtained iv_out: 0x61 (iv_in + 31, partial block not counted)

To fix this, just increase the counter value for partial block requests
by 1 and for the full block size requests, don't take any action as
expected value is already returned by the hardware.

Signed-off-by: Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>
---
 drivers/crypto/qce/skcipher.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
index 224693a831f5..b25e3b76b6c8 100644
--- a/drivers/crypto/qce/skcipher.c
+++ b/drivers/crypto/qce/skcipher.c
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <crypto/aes.h>
+#include <crypto/algapi.h>
 #include <crypto/internal/des.h>
 #include <crypto/internal/skcipher.h>
 #include <crypto/xts.h>
@@ -59,6 +60,14 @@ static void qce_skcipher_done(void *data)
 		dev_dbg(qce->dev, "skcipher operation error (%x)\n", status);
 
 	memcpy(rctx->iv, result_buf->encr_cntr_iv, rctx->ivsize);
+	/*
+	 * QCE hardware does not increment the counter for a partial final
+	 * block. Increment it in software so that iv_out reflects the correct
+	 * next counter value expected by the CTR mode.
+	 */
+	if (IS_CTR(rctx->flags) &&
+	   (rctx->cryptlen % crypto_skcipher_chunksize(crypto_skcipher_reqtfm(req))))
+		crypto_inc(rctx->iv, rctx->ivsize);
 	qce->async_req_done(tmpl->qce, error);
 }
 

-- 
2.34.1


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

* Re: [PATCH 0/2] Fix Qualcomm Crypto engine self tests failures
  2026-06-10  5:54 [PATCH 0/2] Fix Qualcomm Crypto engine self tests failures Kuldeep Singh
  2026-06-10  5:54 ` [PATCH 1/2] crypto: qce: Fix xts-aes-qce for weak keys Kuldeep Singh
  2026-06-10  5:54 ` [PATCH 2/2] crypto: qce: Fix CTR-AES for partial block requests Kuldeep Singh
@ 2026-06-10 18:42 ` Eric Biggers
  2 siblings, 0 replies; 5+ messages in thread
From: Eric Biggers @ 2026-06-10 18:42 UTC (permalink / raw)
  To: Kuldeep Singh
  Cc: Thara Gopinath, Herbert Xu, David S. Miller, Bartosz Golaszewski,
	Thara Gopinath, linux-crypto, linux-arm-msm, linux-kernel

On Wed, Jun 10, 2026 at 11:24:03AM +0530, Kuldeep Singh wrote:
> Steps followed:
>   - Enable EXPERT and CRYPTO_SEFLTESTS config.

So the full tests (CRYPTO_SELFTESTS_FULL) still haven't been run?

- Eric

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

* Re: [PATCH 2/2] crypto: qce: Fix CTR-AES for partial block requests
  2026-06-10  5:54 ` [PATCH 2/2] crypto: qce: Fix CTR-AES for partial block requests Kuldeep Singh
@ 2026-06-10 18:46   ` Eric Biggers
  0 siblings, 0 replies; 5+ messages in thread
From: Eric Biggers @ 2026-06-10 18:46 UTC (permalink / raw)
  To: Kuldeep Singh
  Cc: Thara Gopinath, Herbert Xu, David S. Miller, Bartosz Golaszewski,
	Thara Gopinath, linux-crypto, linux-arm-msm, linux-kernel

On Wed, Jun 10, 2026 at 11:24:05AM +0530, Kuldeep Singh wrote:
> In CTR mode, the IV acts as the initial counter block.
> APer NIST SP 800-38A, after a CTR mode operation the next unused counter
> value is:
> 
> IV_next = IV_in + ceil(cryptlen / AES_BLOCK_SIZE)
> 
> The skcipher requires req->iv to hold this updated counter on
> completion, ensuring chained requests produce correct results.
> 
> Referring to Crypto6.0 documentation, Section 2.2.5 says:
> "The count value increments automatically once per block of data (in
> AES, a block is 16 bytes) based on the value in the
> CRYPTO_ENCR_CNTR_MASK registers."
> 
> QCE increments internal counter register once per full 16-byte block(for
> ctr-aes) is processed. In case of partial request length, the hardware
> uses the current counter to generate keystreams but does not increment
> the counter register afterwards. So the counter value written in
> CRYPTO_ENCR_CNTRn_IVn later once read by software is one less than the
> expected value.
> 
> Crypto selftest framework capture this scenario with test vector
> 4 comprising of a 499-byte payload (31 full blocks + 3 partial bytes).
> Error:
> [    5.606169] alg: skcipher: ctr-aes-qce encryption test failed (wrong output IV) on test vector 4, cfg="in-place (one sglist)"
> [    5.606176] 00000000: e7 82 1d b8 53 11 ac 47 e2 7d 18 d6 71 0c a7 61
> [    5.606192] alg: self-tests for ctr(aes) using ctr-aes-qce failed (rc=-22)
> Expected iv_out: 0x62 (iv_in + 32)
> Obtained iv_out: 0x61 (iv_in + 31, partial block not counted)
> 
> To fix this, just increase the counter value for partial block requests
> by 1 and for the full block size requests, don't take any action as
> expected value is already returned by the hardware.
> 
> Signed-off-by: Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>

This fix isn't Cc'ed to stable, so stable kernels will remain vulnerable
to this bug.

- Eric

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

end of thread, other threads:[~2026-06-10 18:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-10  5:54 [PATCH 0/2] Fix Qualcomm Crypto engine self tests failures Kuldeep Singh
2026-06-10  5:54 ` [PATCH 1/2] crypto: qce: Fix xts-aes-qce for weak keys Kuldeep Singh
2026-06-10  5:54 ` [PATCH 2/2] crypto: qce: Fix CTR-AES for partial block requests Kuldeep Singh
2026-06-10 18:46   ` Eric Biggers
2026-06-10 18:42 ` [PATCH 0/2] Fix Qualcomm Crypto engine self tests failures Eric Biggers

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