All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.