summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Mehltretter <kmehltretter@gmail.com>2026-09-22 07:17:04 +0200
committerHerbert Xu <herbert@gondor.apana.org.au>2026-10-02 18:12:43 +1000
commitccbd95b3efbc0580b6abde2a905823417ca56022 (patch)
treea257523332175083b6fe101edefe545503b3573b
parentedf73c9922672ff94ca12162829ea178685430fd (diff)
crypto: atmel - handle authenc requests without plaintext
Authenc permits a nonempty associated-data string with no plaintext. The Atmel driver accepts such a request, has SHA process the associated data, and then unconditionally asks AES DMA to transfer zero bytes. The Atmel DMA engines reject the zero-length descriptor, so the valid request fails, normally with -ENOMEM. Skip the AES transfer when textlen is zero and proceed directly to SHA finalization. Once an HMAC transform has cached its inner and outer states, SHA can complete this path synchronously. The forced ahash completion callback then invokes the AES finalizer through a void function and discards its return value. This loses -EBADMSG for a mismatched tag and reports successful decryption. For synchronous SHA completion, release the SHA device without invoking the ahash callback and call the AES finalizer directly. Its result then propagates through the synchronous call chain. Keep the existing callback path for asynchronous completion. On a SAM9X75, the unpatched driver failed valid AAD-only requests and returned success for a bad tag after the transform had been used once. With this change, bad tags return -EBADMSG for both fresh and reused transforms. Fixes: 89a82ef87e01 ("crypto: atmel-authenc - add support to authenc(hmac(shaX), Y(aes)) modes") Assisted-by: LLM Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/atmel-aes.c2
-rw-r--r--drivers/crypto/atmel-sha.c14
2 files changed, 16 insertions, 0 deletions
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index 8e4de859cadc..84392411b98d 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -1826,6 +1826,8 @@ static int atmel_aes_authenc_transfer(struct atmel_aes_dev *dd, int err,
dd->is_async = true;
if (err)
return atmel_aes_complete(dd, err);
+ if (!rctx->textlen)
+ return atmel_aes_authenc_digest(dd);
/* Prepare src and dst scatter-lists to transfer cipher/plain texts. */
src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen);
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index 2d70a4107693..4b883a8dcf30 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -2386,11 +2386,25 @@ static int atmel_sha_authenc_final_done(struct atmel_sha_dev *dd)
{
struct ahash_request *req = dd->req;
struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req);
+ atmel_aes_authenc_fn_t cb;
+ struct atmel_aes_dev *aes_dev;
size_t i, num_words = authctx->digestlen / sizeof(u32);
for (i = 0; i < num_words; ++i)
authctx->digest[i] = atmel_sha_read(dd, SHA_REG_DIGEST(i));
+ if (!dd->is_async) {
+ /*
+ * Return the AES finalizer's status directly for synchronous requests.
+ * The ahash callback cannot propagate it.
+ */
+ cb = authctx->cb;
+ aes_dev = authctx->aes_dev;
+ dd->force_complete = false;
+ (void)atmel_sha_complete(dd, 0);
+ return cb(aes_dev, 0, false);
+ }
+
return atmel_sha_complete(dd, 0);
}