XTS is not defined for a payload shorter than one cipher block. The driver treated a zero-length request as a successful no-op, so the crypto self-tests "unexpectedly succeeded" when -EINVAL was expected. Requests of 1 to 15 bytes are not rejected either and, when they are not diverted to the fallback (e.g. with aes_sw_max_len set to 0), reach the engine which stalls waiting for a full block of input. Return -EINVAL for XTS requests shorter than AES_BLOCK_SIZE while keeping the no-op behavior for empty requests of the other ciphers, which the crypto engine simply cannot process due to its DMA not supporting zero-length transfers. Cc: stable@vger.kernel.org Fixes: f08789462255 ("crypto: qce - Return error for zero length messages") Tested-by: Kuldeep Singh Tested-by: Pankaj Patil Signed-off-by: Bartosz Golaszewski --- drivers/crypto/qce/skcipher.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c index 03a3cec2bb90e8d8c17e491ca40ec740a003d1b4..d9a5b255015341e741515bdfd6ff54bd3b24f1e3 100644 --- a/drivers/crypto/qce/skcipher.c +++ b/drivers/crypto/qce/skcipher.c @@ -221,6 +221,14 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt) rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT; keylen = IS_XTS(rctx->flags) ? ctx->enc_keylen >> 1 : ctx->enc_keylen; + /* + * XTS requires at least one full block of data. Reject anything + * shorter here as the engine would stall waiting for more input if + * such a request reached it. + */ + if (IS_XTS(rctx->flags) && req->cryptlen < AES_BLOCK_SIZE) + return -EINVAL; + /* CE does not handle 0 length messages */ if (!req->cryptlen) return 0; -- 2.47.3