diff mbox series

crypto: arm/aes-neonbs - fix usage of cbc(aes) fallback

Message ID 20201028090320.4222-1-horia.geanta@nxp.com (mailing list archive)
State New, archived
Headers show
Series crypto: arm/aes-neonbs - fix usage of cbc(aes) fallback | expand

Commit Message

Horia Geanta Oct. 28, 2020, 9:03 a.m. UTC
Loading the module deadlocks since:
-local cbc(aes) implementation needs a fallback and
-crypto API tries to find one but the request_module() resolves back to
the same module

Fix this by changing the module alias for cbc(aes) and
using the NEED_FALLBACK flag when requesting for a fallback algorithm.

Fixes: 00b99ad2bac2 ("crypto: arm/aes-neonbs - Use generic cbc encryption path")
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
---
 arch/arm/crypto/aes-neonbs-glue.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Comments

Ard Biesheuvel Oct. 28, 2020, 9:06 a.m. UTC | #1
On Wed, 28 Oct 2020 at 10:03, Horia Geantă <horia.geanta@nxp.com> wrote:
>
> Loading the module deadlocks since:
> -local cbc(aes) implementation needs a fallback and
> -crypto API tries to find one but the request_module() resolves back to
> the same module
>
> Fix this by changing the module alias for cbc(aes) and
> using the NEED_FALLBACK flag when requesting for a fallback algorithm.
>
> Fixes: 00b99ad2bac2 ("crypto: arm/aes-neonbs - Use generic cbc encryption path")
> Signed-off-by: Horia Geantă <horia.geanta@nxp.com>

Not sure what is happening here: IIRC the intention was to rely on the
fact that only the sync cbc(aes) implementation needs the fallback,
and therefore, allocating a sync skcipher explicitly would avoid this
recursion.

Herbert?

> ---
>  arch/arm/crypto/aes-neonbs-glue.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c
> index bda8bf17631e..f70af1d0514b 100644
> --- a/arch/arm/crypto/aes-neonbs-glue.c
> +++ b/arch/arm/crypto/aes-neonbs-glue.c
> @@ -19,7 +19,7 @@ MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
>  MODULE_LICENSE("GPL v2");
>
>  MODULE_ALIAS_CRYPTO("ecb(aes)");
> -MODULE_ALIAS_CRYPTO("cbc(aes)");
> +MODULE_ALIAS_CRYPTO("cbc(aes)-all");
>  MODULE_ALIAS_CRYPTO("ctr(aes)");
>  MODULE_ALIAS_CRYPTO("xts(aes)");
>
> @@ -191,7 +191,8 @@ static int cbc_init(struct crypto_skcipher *tfm)
>         struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
>         unsigned int reqsize;
>
> -       ctx->enc_tfm = crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
> +       ctx->enc_tfm = crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC |
> +                                            CRYPTO_ALG_NEED_FALLBACK);
>         if (IS_ERR(ctx->enc_tfm))
>                 return PTR_ERR(ctx->enc_tfm);
>
> @@ -441,7 +442,8 @@ static struct skcipher_alg aes_algs[] = { {
>         .base.cra_blocksize     = AES_BLOCK_SIZE,
>         .base.cra_ctxsize       = sizeof(struct aesbs_cbc_ctx),
>         .base.cra_module        = THIS_MODULE,
> -       .base.cra_flags         = CRYPTO_ALG_INTERNAL,
> +       .base.cra_flags         = CRYPTO_ALG_INTERNAL |
> +                                 CRYPTO_ALG_NEED_FALLBACK,
>
>         .min_keysize            = AES_MIN_KEY_SIZE,
>         .max_keysize            = AES_MAX_KEY_SIZE,
> --
> 2.17.1
>
Horia Geanta Oct. 28, 2020, 9:43 a.m. UTC | #2
On 10/28/2020 11:07 AM, Ard Biesheuvel wrote:
> On Wed, 28 Oct 2020 at 10:03, Horia Geantă <horia.geanta@nxp.com> wrote:
>>
>> Loading the module deadlocks since:
>> -local cbc(aes) implementation needs a fallback and
>> -crypto API tries to find one but the request_module() resolves back to
>> the same module
>>
>> Fix this by changing the module alias for cbc(aes) and
>> using the NEED_FALLBACK flag when requesting for a fallback algorithm.
>>
>> Fixes: 00b99ad2bac2 ("crypto: arm/aes-neonbs - Use generic cbc encryption path")
>> Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
> 
> Not sure what is happening here: IIRC the intention was to rely on the
> fact that only the sync cbc(aes) implementation needs the fallback,
> and therefore, allocating a sync skcipher explicitly would avoid this
> recursion.
> 
My understanding is the following:

1. Local cbc_init() tries to allocate a fallback tfm for cbc(aes)

2. crypto API cbc(aes) tries to find a cbc(aes) algorithm implementation
crypto_alloc_skcipher ->
	crypto_alloc_tfm ->
		crypto_alloc_tfm_node ->
			crypto_find_alg ->
				crypto_alg_mod_lookup ->
					crypto_larval_lookup

Here crypto_alg_lookup() fails to find a cbc(aes) implementation.

3. Next step is to try to dynamically load a module (request_module)
that supports this implementation. And here it deadlocks, since it tries
to load aes-arm-bs module...

The fix is providing a way to (partially) skip the dynamic module loading
in crypto_alg_lookup() and allow for the last method of finding an algorithm
implementation, which is creating the cbc(aes) on the fly
via the cbc template - see:
	ok = crypto_probing_notify(CRYPTO_MSG_ALG_REQUEST, larval);
in crypto_alg_mod_lookup().

Horia
Herbert Xu Oct. 29, 2020, 6:49 a.m. UTC | #3
On Wed, Oct 28, 2020 at 10:06:58AM +0100, Ard Biesheuvel wrote:
>
> Not sure what is happening here: IIRC the intention was to rely on the
> fact that only the sync cbc(aes) implementation needs the fallback,
> and therefore, allocating a sync skcipher explicitly would avoid this
> recursion.
> 
> Herbert?

It works only if everything is built in.  If cbc is built as a
module then you need Horia's patch to prevent a loop.

Cheers,
Herbert Xu Nov. 6, 2020, 7:02 a.m. UTC | #4
On Wed, Oct 28, 2020 at 11:03:20AM +0200, Horia Geantă wrote:
> Loading the module deadlocks since:
> -local cbc(aes) implementation needs a fallback and
> -crypto API tries to find one but the request_module() resolves back to
> the same module
> 
> Fix this by changing the module alias for cbc(aes) and
> using the NEED_FALLBACK flag when requesting for a fallback algorithm.
> 
> Fixes: 00b99ad2bac2 ("crypto: arm/aes-neonbs - Use generic cbc encryption path")
> Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
> ---
>  arch/arm/crypto/aes-neonbs-glue.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)

Patch applied.  Thanks.
diff mbox series

Patch

diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c
index bda8bf17631e..f70af1d0514b 100644
--- a/arch/arm/crypto/aes-neonbs-glue.c
+++ b/arch/arm/crypto/aes-neonbs-glue.c
@@ -19,7 +19,7 @@  MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
 MODULE_LICENSE("GPL v2");
 
 MODULE_ALIAS_CRYPTO("ecb(aes)");
-MODULE_ALIAS_CRYPTO("cbc(aes)");
+MODULE_ALIAS_CRYPTO("cbc(aes)-all");
 MODULE_ALIAS_CRYPTO("ctr(aes)");
 MODULE_ALIAS_CRYPTO("xts(aes)");
 
@@ -191,7 +191,8 @@  static int cbc_init(struct crypto_skcipher *tfm)
 	struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
 	unsigned int reqsize;
 
-	ctx->enc_tfm = crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
+	ctx->enc_tfm = crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC |
+					     CRYPTO_ALG_NEED_FALLBACK);
 	if (IS_ERR(ctx->enc_tfm))
 		return PTR_ERR(ctx->enc_tfm);
 
@@ -441,7 +442,8 @@  static struct skcipher_alg aes_algs[] = { {
 	.base.cra_blocksize	= AES_BLOCK_SIZE,
 	.base.cra_ctxsize	= sizeof(struct aesbs_cbc_ctx),
 	.base.cra_module	= THIS_MODULE,
-	.base.cra_flags		= CRYPTO_ALG_INTERNAL,
+	.base.cra_flags		= CRYPTO_ALG_INTERNAL |
+				  CRYPTO_ALG_NEED_FALLBACK,
 
 	.min_keysize		= AES_MIN_KEY_SIZE,
 	.max_keysize		= AES_MAX_KEY_SIZE,