linux-crypto.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Eric Biggers <ebiggers@kernel.org>
Cc: "open list:HARDWARE RANDOM NUMBER GENERATOR CORE" 
	<linux-crypto@vger.kernel.org>,
	Pascal Van Leeuwen <pvanleeuwen@verimatrix.com>
Subject: Re: [PATCH] crypto: api - fix unexpectedly getting generic implementation
Date: Tue, 3 Dec 2019 11:44:13 +0000	[thread overview]
Message-ID: <CAKv+Gu-h+yFj-9FwNnA7Qj_TWMQf_rcbRt=NMW7NOvkafCZnUw@mail.gmail.com> (raw)
In-Reply-To: <20191202221319.258002-1-ebiggers@kernel.org>

On Mon, 2 Dec 2019 at 22:13, Eric Biggers <ebiggers@kernel.org> wrote:
>
> From: Eric Biggers <ebiggers@google.com>
>
> When CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y, the first lookup of an
> algorithm that needs to be instantiated using a template will always get
> the generic implementation, even when an accelerated one is available.
>
> This happens because the extra self-tests for the accelerated
> implementation allocate the generic implementation for comparison
> purposes, and then crypto_alg_tested() for the generic implementation
> "fulfills" the original request (i.e. sets crypto_larval::adult).
>
> Fix this by making crypto_alg_tested() replace an already-set
> crypto_larval::adult when it has lower priority and the larval hasn't
> already been complete()d (by cryptomgr_probe()).
>
> This also required adding crypto_alg_sem protection to completing the
> larval in cryptomgr_probe().
>
> Also add some comments to crypto_alg_tested() to make it easier to
> understand what's going on.
>
> Fixes: 9a8a6b3f0950 ("crypto: testmgr - fuzz hashes against their generic implementation")
> Fixes: d435e10e67be ("crypto: testmgr - fuzz skciphers against their generic implementation")
> Fixes: 40153b10d91c ("crypto: testmgr - fuzz AEADs against their generic implementation")
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Thanks for fixing this.

Acked-by: Ard Biesheuvel <ardb@kernel.org>

> ---
>  crypto/algapi.c   | 46 +++++++++++++++++++++++++++++++++++++++++-----
>  crypto/algboss.c  |  4 ++++
>  crypto/api.c      |  5 -----
>  crypto/internal.h |  5 +++++
>  4 files changed, 50 insertions(+), 10 deletions(-)
>
> diff --git a/crypto/algapi.c b/crypto/algapi.c
> index b052f38edba621..6c5406d342e2b7 100644
> --- a/crypto/algapi.c
> +++ b/crypto/algapi.c
> @@ -251,6 +251,17 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
>         goto out;
>  }
>
> +/**
> + * crypto_alg_tested() - handle a self-test result
> + * @name: the driver name of the algorithm that was tested
> + * @err: 0 if testing passed, nonzero if testing failed
> + *
> + * If testing passed, mark the algorithm as tested and try to use it to fulfill
> + * any outstanding template instantiation requests.  Also remove any template
> + * instances that use a lower-priority implementation of the same algorithm.
> + *
> + * In any case, also wake up anyone waiting for the algorithm to be tested.
> + */
>  void crypto_alg_tested(const char *name, int err)
>  {
>         struct crypto_larval *test;
> @@ -258,6 +269,7 @@ void crypto_alg_tested(const char *name, int err)
>         struct crypto_alg *q;
>         LIST_HEAD(list);
>
> +       /* Find the algorithm's test larval */
>         down_write(&crypto_alg_sem);
>         list_for_each_entry(q, &crypto_alg_list, cra_list) {
>                 if (crypto_is_moribund(q) || !crypto_is_larval(q))
> @@ -290,26 +302,50 @@ void crypto_alg_tested(const char *name, int err)
>                 if (crypto_is_larval(q)) {
>                         struct crypto_larval *larval = (void *)q;
>
> +                       if (crypto_is_test_larval(larval))
> +                               continue;
> +
>                         /*
> -                        * Check to see if either our generic name or
> -                        * specific name can satisfy the name requested
> -                        * by the larval entry q.
> +                        * Fulfill the request larval 'q' (set larval->adult) if
> +                        * the tested algorithm is compatible with it, i.e. if
> +                        * the request is for the same generic or driver name
> +                        * and for compatible flags.
> +                        *
> +                        * If larval->adult is already set, replace it if the
> +                        * tested algorithm is higher priority and the larval
> +                        * hasn't been completed()d yet.  This is needed to
> +                        * avoid users always getting the generic implementation
> +                        * on first use when the extra self-tests are enabled.
>                          */
> +
>                         if (strcmp(alg->cra_name, q->cra_name) &&
>                             strcmp(alg->cra_driver_name, q->cra_name))
>                                 continue;
>
> -                       if (larval->adult)
> -                               continue;
>                         if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
>                                 continue;
> +
> +                       if (larval->adult &&
> +                           larval->adult->cra_priority >= alg->cra_priority)
> +                               continue;
> +
> +                       if (completion_done(&larval->completion))
> +                               continue;
> +
>                         if (!crypto_mod_get(alg))
>                                 continue;
>
> +                       if (larval->adult)
> +                               crypto_mod_put(larval->adult);
>                         larval->adult = alg;
>                         continue;
>                 }
>
> +               /*
> +                * Remove any template instances that use a lower-priority
> +                * implementation of the same algorithm.
> +                */
> +
>                 if (strcmp(alg->cra_name, q->cra_name))
>                         continue;
>
> diff --git a/crypto/algboss.c b/crypto/algboss.c
> index a62149d6c839f5..f2b3b3ab008334 100644
> --- a/crypto/algboss.c
> +++ b/crypto/algboss.c
> @@ -81,7 +81,11 @@ static int cryptomgr_probe(void *data)
>         crypto_tmpl_put(tmpl);
>
>  out:
> +       /* crypto_alg_sem is needed to synchronize with crypto_alg_tested() */
> +       down_write(&crypto_alg_sem);
>         complete_all(&param->larval->completion);
> +       up_write(&crypto_alg_sem);
> +
>         crypto_alg_put(&param->larval->alg);
>         kfree(param);
>         module_put_and_exit(0);
> diff --git a/crypto/api.c b/crypto/api.c
> index ef96142ceca746..855004cb0b4d59 100644
> --- a/crypto/api.c
> +++ b/crypto/api.c
> @@ -47,11 +47,6 @@ void crypto_mod_put(struct crypto_alg *alg)
>  }
>  EXPORT_SYMBOL_GPL(crypto_mod_put);
>
> -static inline int crypto_is_test_larval(struct crypto_larval *larval)
> -{
> -       return larval->alg.cra_driver_name[0];
> -}
> -
>  static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
>                                               u32 mask)
>  {
> diff --git a/crypto/internal.h b/crypto/internal.h
> index ff06a3bd1ca10c..ba744ac2ee1f09 100644
> --- a/crypto/internal.h
> +++ b/crypto/internal.h
> @@ -110,6 +110,11 @@ static inline int crypto_is_larval(struct crypto_alg *alg)
>         return alg->cra_flags & CRYPTO_ALG_LARVAL;
>  }
>
> +static inline int crypto_is_test_larval(struct crypto_larval *larval)
> +{
> +       return larval->alg.cra_driver_name[0];
> +}
> +
>  static inline int crypto_is_dead(struct crypto_alg *alg)
>  {
>         return alg->cra_flags & CRYPTO_ALG_DEAD;
> --
> 2.24.0.393.g34dc348eaf-goog
>

  reply	other threads:[~2019-12-03 11:44 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-02 22:13 [PATCH] crypto: api - fix unexpectedly getting generic implementation Eric Biggers
2019-12-03 11:44 ` Ard Biesheuvel [this message]
2019-12-04  9:19 ` [v2 PATCH] " Herbert Xu
2019-12-04 17:22   ` Eric Biggers
2019-12-05  1:58     ` [v3 " Herbert Xu
2019-12-05  3:43       ` Eric Biggers
2019-12-05  4:55         ` [v4 " Herbert Xu
2019-12-11  2:26           ` Eric Biggers
2019-12-11  2:50             ` [v5 " Herbert Xu
2019-12-11  3:15               ` Eric Biggers
2019-12-05  4:04       ` [v3 " Eric Biggers
2019-12-05  4:23         ` Herbert Xu
2019-12-05  4:27           ` Herbert Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAKv+Gu-h+yFj-9FwNnA7Qj_TWMQf_rcbRt=NMW7NOvkafCZnUw@mail.gmail.com' \
    --to=ard.biesheuvel@linaro.org \
    --cc=ebiggers@kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=pvanleeuwen@verimatrix.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).