diff mbox series

crypto: ahash - Add support for drivers with no fallback

Message ID aEAX4c2vU46HlBjG@gondor.apana.org.au
State New
Headers show
Series crypto: ahash - Add support for drivers with no fallback | expand

Commit Message

Herbert Xu June 4, 2025, 9:54 a.m. UTC
On Tue, Jun 03, 2025 at 03:49:16PM +0200, Harald Freudenberger wrote:
> Hello Herbert
> 
> I am facing a weird issue with my phmac implementation since kernel 5.15 has
> been released. The algorithm registers fine but obviously it is not
> self-tested
> and thus you can't access it via AF_ALG or with an in-kernel customer.

So the issue is that this algorithm cannot have a fallback, because
the key is held in hardware only.

Please try the following patch and set the bit CRYPTO_ALG_NO_FALLBACK
and see if it works.

Thanks,

---8<---
Some drivers cannot have a fallback, e.g., because the key is held
in hardwre.  Allow these to be used with ahash by adding the bit
CRYPTO_ALG_NO_FALLBACK.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Comments

Harald Freudenberger June 5, 2025, 1:29 p.m. UTC | #1
On 2025-06-04 11:54, Herbert Xu wrote:
> On Tue, Jun 03, 2025 at 03:49:16PM +0200, Harald Freudenberger wrote:
>> Hello Herbert
>> 
>> I am facing a weird issue with my phmac implementation since kernel 
>> 5.15 has
>> been released. The algorithm registers fine but obviously it is not
>> self-tested
>> and thus you can't access it via AF_ALG or with an in-kernel customer.
> 
> So the issue is that this algorithm cannot have a fallback, because
> the key is held in hardware only.
> 
> Please try the following patch and set the bit CRYPTO_ALG_NO_FALLBACK
> and see if it works.
> 
> Thanks,
> 
> ---8<---
> Some drivers cannot have a fallback, e.g., because the key is held
> in hardwre.  Allow these to be used with ahash by adding the bit
> CRYPTO_ALG_NO_FALLBACK.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> 
> diff --git a/crypto/ahash.c b/crypto/ahash.c
> index e10bc2659ae4..bd9e49950201 100644
> --- a/crypto/ahash.c
> +++ b/crypto/ahash.c
> @@ -347,6 +347,9 @@ static int ahash_do_req_chain(struct ahash_request 
> *req,
>  	if (crypto_ahash_statesize(tfm) > HASH_MAX_STATESIZE)
>  		return -ENOSYS;
> 
> +	if (!crypto_ahash_need_fallback(tfm))
> +		return -ENOSYS;
> +
>  	{
>  		u8 state[HASH_MAX_STATESIZE];
> 
> @@ -952,6 +955,10 @@ static int ahash_prepare_alg(struct ahash_alg 
> *alg)
>  	    base->cra_reqsize > MAX_SYNC_HASH_REQSIZE)
>  		return -EINVAL;
> 
> +	if (base->cra_flags & CRYPTO_ALG_NEED_FALLBACK &&
> +	    base->cra_flags & CRYPTO_ALG_NO_FALLBACK)
> +		return -EINVAL;
> +
>  	err = hash_prepare_alg(&alg->halg);
>  	if (err)
>  		return err;
> @@ -960,7 +967,8 @@ static int ahash_prepare_alg(struct ahash_alg *alg)
>  	base->cra_flags |= CRYPTO_ALG_TYPE_AHASH;
> 
>  	if ((base->cra_flags ^ CRYPTO_ALG_REQ_VIRT) &
> -	    (CRYPTO_ALG_ASYNC | CRYPTO_ALG_REQ_VIRT))
> +	    (CRYPTO_ALG_ASYNC | CRYPTO_ALG_REQ_VIRT) &&
> +	    !(base->cra_flags & CRYPTO_ALG_NO_FALLBACK))
>  		base->cra_flags |= CRYPTO_ALG_NEED_FALLBACK;
> 
>  	if (!alg->setkey)
> diff --git a/include/linux/crypto.h b/include/linux/crypto.h
> index b50f1954d1bb..a2137e19be7d 100644
> --- a/include/linux/crypto.h
> +++ b/include/linux/crypto.h
> @@ -136,6 +136,9 @@
>  /* Set if the algorithm supports virtual addresses. */
>  #define CRYPTO_ALG_REQ_VIRT		0x00040000
> 
> +/* Set if the algorithm cannot have a fallback (e.g., phmac). */
> +#define CRYPTO_ALG_NO_FALLBACK		0x00080000
> +
>  /* The high bits 0xff000000 are reserved for type-specific flags. */
> 
>  /*

Works perfect - tested on a fresh clone of cryptodev-2.6 with my
phmac v12 patches on top.
Add a Tested-by: Harald Freudenberger <freude@linux.ibm.com>
Please push into next, maybe fix the typo "hardwre" -> "hardware"
Thanks
diff mbox series

Patch

diff --git a/crypto/ahash.c b/crypto/ahash.c
index e10bc2659ae4..bd9e49950201 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -347,6 +347,9 @@  static int ahash_do_req_chain(struct ahash_request *req,
 	if (crypto_ahash_statesize(tfm) > HASH_MAX_STATESIZE)
 		return -ENOSYS;
 
+	if (!crypto_ahash_need_fallback(tfm))
+		return -ENOSYS;
+
 	{
 		u8 state[HASH_MAX_STATESIZE];
 
@@ -952,6 +955,10 @@  static int ahash_prepare_alg(struct ahash_alg *alg)
 	    base->cra_reqsize > MAX_SYNC_HASH_REQSIZE)
 		return -EINVAL;
 
+	if (base->cra_flags & CRYPTO_ALG_NEED_FALLBACK &&
+	    base->cra_flags & CRYPTO_ALG_NO_FALLBACK)
+		return -EINVAL;
+
 	err = hash_prepare_alg(&alg->halg);
 	if (err)
 		return err;
@@ -960,7 +967,8 @@  static int ahash_prepare_alg(struct ahash_alg *alg)
 	base->cra_flags |= CRYPTO_ALG_TYPE_AHASH;
 
 	if ((base->cra_flags ^ CRYPTO_ALG_REQ_VIRT) &
-	    (CRYPTO_ALG_ASYNC | CRYPTO_ALG_REQ_VIRT))
+	    (CRYPTO_ALG_ASYNC | CRYPTO_ALG_REQ_VIRT) &&
+	    !(base->cra_flags & CRYPTO_ALG_NO_FALLBACK))
 		base->cra_flags |= CRYPTO_ALG_NEED_FALLBACK;
 
 	if (!alg->setkey)
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index b50f1954d1bb..a2137e19be7d 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -136,6 +136,9 @@ 
 /* Set if the algorithm supports virtual addresses. */
 #define CRYPTO_ALG_REQ_VIRT		0x00040000
 
+/* Set if the algorithm cannot have a fallback (e.g., phmac). */
+#define CRYPTO_ALG_NO_FALLBACK		0x00080000
+
 /* The high bits 0xff000000 are reserved for type-specific flags. */
 
 /*