Re: [PATCH v2 4/4] crypto: aegis128 - expose SIMD code path as separate driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 11 Nov 2020 at 18:46, Ondrej Mosnáček <omosnacek@xxxxxxxxx> wrote:
>
> ut 10. 11. 2020 o 20:04 Ard Biesheuvel <ardb@xxxxxxxxxx> napísal(a):
> > Wiring the SIMD code into the generic driver has the unfortunate side
> > effect that the tcrypt testing code cannot distinguish them, and will
> > therefore not use the latter to fuzz test the former, as it does for
> > other algorithms.
>
> Looking back at cf3d41adcc35 ("crypto: aegis128 - add support for SIMD
> acceleration"), I see that that there are aegis128_do_simd()
> conditionals also in the generic block update functions, so the
> "generic" variant is really only "half" generic. But maybe that
> doesn't really matter for the fuzzing, since the code paths are
> significantly different anyway...
>

Thanks for pointing that out. I think we should be pedantic here, and
ensure that the generic code never takes the SIMD code path.

> >
> > So let's refactor the code a bit so we can register two implementations:
> > aegis128-generic and aegis128-simd.
> >
> > Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
> > ---
> >  crypto/aegis128-core.c | 176 +++++++++++++-------
> >  1 file changed, 119 insertions(+), 57 deletions(-)
> >
> > diff --git a/crypto/aegis128-core.c b/crypto/aegis128-core.c
> > index 859c7b905618..19f38e8c1627 100644
> > --- a/crypto/aegis128-core.c
> > +++ b/crypto/aegis128-core.c
> [...]
> > @@ -482,42 +457,128 @@ static int crypto_aegis128_decrypt(struct aead_request *req)
> >         return 0;
> >  }
> >
> > -static struct aead_alg crypto_aegis128_alg = {
> > -       .setkey = crypto_aegis128_setkey,
> > -       .setauthsize = crypto_aegis128_setauthsize,
> > -       .encrypt = crypto_aegis128_encrypt,
> > -       .decrypt = crypto_aegis128_decrypt,
> > +static int crypto_aegis128_encrypt_simd(struct aead_request *req)
> > +{
> > +       struct crypto_aead *tfm = crypto_aead_reqtfm(req);
> > +       union aegis_block tag = {};
> > +       unsigned int authsize = crypto_aead_authsize(tfm);
> > +       struct aegis_ctx *ctx = crypto_aead_ctx(tfm);
> > +       unsigned int cryptlen = req->cryptlen;
> > +       struct skcipher_walk walk;
> > +       struct aegis_state state;
> >
> > -       .ivsize = AEGIS128_NONCE_SIZE,
> > -       .maxauthsize = AEGIS128_MAX_AUTH_SIZE,
> > -       .chunksize = AEGIS_BLOCK_SIZE,
> > +       if (!aegis128_do_simd())
> > +               return crypto_aegis128_encrypt_generic(req);
> >
> > -       .base = {
> > -               .cra_blocksize = 1,
> > -               .cra_ctxsize = sizeof(struct aegis_ctx),
> > -               .cra_alignmask = 0,
> > +       skcipher_walk_aead_encrypt(&walk, req, false);
> > +       crypto_aegis128_init_simd(&state, &ctx->key, req->iv);
> > +       crypto_aegis128_process_ad(&state, req->src, req->assoclen);
> > +       crypto_aegis128_process_crypt(&state, &walk,
> > +                                     crypto_aegis128_encrypt_chunk_simd);
> > +       crypto_aegis128_final_simd(&state, &tag, req->assoclen, cryptlen, 0);
> >
> > -               .cra_priority = 100,
> > +       scatterwalk_map_and_copy(tag.bytes, req->dst, req->assoclen + cryptlen,
> > +                                authsize, 1);
> > +       return 0;
> > +}
> >
> > -               .cra_name = "aegis128",
> > -               .cra_driver_name = "aegis128-generic",
> > +static int crypto_aegis128_decrypt_simd(struct aead_request *req)
> > +{
> > +       struct crypto_aead *tfm = crypto_aead_reqtfm(req);
> > +       union aegis_block tag;
> > +       unsigned int authsize = crypto_aead_authsize(tfm);
> > +       unsigned int cryptlen = req->cryptlen - authsize;
> > +       struct aegis_ctx *ctx = crypto_aead_ctx(tfm);
> > +       struct skcipher_walk walk;
> > +       struct aegis_state state;
> > +
> > +       if (!aegis128_do_simd())
> > +               return crypto_aegis128_decrypt_generic(req);
> > +
> > +       scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen,
> > +                                authsize, 0);
> > +
> > +       skcipher_walk_aead_decrypt(&walk, req, false);
> > +       crypto_aegis128_init_simd(&state, &ctx->key, req->iv);
> > +       crypto_aegis128_process_ad(&state, req->src, req->assoclen);
> > +       crypto_aegis128_process_crypt(&state, &walk,
> > +                                     crypto_aegis128_decrypt_chunk_simd);
> >
> > -               .cra_module = THIS_MODULE,
> > +       if (unlikely(crypto_aegis128_final_simd(&state, &tag, req->assoclen,
> > +                                               cryptlen, authsize))) {
> > +               skcipher_walk_aead_decrypt(&walk, req, false);
> > +               crypto_aegis128_process_crypt(NULL, &walk,
> > +                                             crypto_aegis128_wipe_chunk);
> > +               return -EBADMSG;
> >         }
> > +       return 0;
> > +}
> > +
> > +static struct aead_alg crypto_aegis128_alg_generic = {
> > +       .setkey                 = crypto_aegis128_setkey,
> > +       .setauthsize            = crypto_aegis128_setauthsize,
> > +       .encrypt                = crypto_aegis128_encrypt_generic,
> > +       .decrypt                = crypto_aegis128_decrypt_generic,
> > +
> > +       .ivsize                 = AEGIS128_NONCE_SIZE,
> > +       .maxauthsize            = AEGIS128_MAX_AUTH_SIZE,
> > +       .chunksize              = AEGIS_BLOCK_SIZE,
> > +
> > +       .base.cra_blocksize     = 1,
> > +       .base.cra_ctxsize       = sizeof(struct aegis_ctx),
> > +       .base.cra_alignmask     = 0,
> > +       .base.cra_priority      = 100,
> > +       .base.cra_name          = "aegis128",
> > +       .base.cra_driver_name   = "aegis128-generic",
> > +};
> > +
> > +static struct aead_alg crypto_aegis128_alg_simd = {
> > +       .base.cra_module        = THIS_MODULE,
>
> This line is listed twice for "crypto_aegis128_alg_simd", but it's
> missing for "crypto_aegis128_alg_generic" - I think you meant to put
> this one three lines higher.
>

Oops. Will fix.

> > +       .setkey                 = crypto_aegis128_setkey,
> > +       .setauthsize            = crypto_aegis128_setauthsize,
> > +       .encrypt                = crypto_aegis128_encrypt_simd,
> > +       .decrypt                = crypto_aegis128_decrypt_simd,
> > +
> > +       .ivsize                 = AEGIS128_NONCE_SIZE,
> > +       .maxauthsize            = AEGIS128_MAX_AUTH_SIZE,
> > +       .chunksize              = AEGIS_BLOCK_SIZE,
> > +
> > +       .base.cra_blocksize     = 1,
> > +       .base.cra_ctxsize       = sizeof(struct aegis_ctx),
> > +       .base.cra_alignmask     = 0,
> > +       .base.cra_priority      = 200,
> > +       .base.cra_name          = "aegis128",
> > +       .base.cra_driver_name   = "aegis128-simd",
> > +       .base.cra_module        = THIS_MODULE,
> >  };
> >
> >  static int __init crypto_aegis128_module_init(void)
> >  {
> > +       int ret;
> > +
> > +       ret = crypto_register_aead(&crypto_aegis128_alg_generic);
> > +       if (ret)
> > +               return ret;
> > +
> >         if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD) &&
> > -           crypto_aegis128_have_simd())
> > +           crypto_aegis128_have_simd()) {
> > +               ret = crypto_register_aead(&crypto_aegis128_alg_simd);
> > +               if (ret) {
> > +                       crypto_unregister_aead(&crypto_aegis128_alg_generic);
> > +                       return ret;
> > +               }
> >                 static_branch_enable(&have_simd);
> > -
> > -       return crypto_register_aead(&crypto_aegis128_alg);
> > +       }
> > +       return 0;
> >  }
> >
> >  static void __exit crypto_aegis128_module_exit(void)
> >  {
> > -       crypto_unregister_aead(&crypto_aegis128_alg);
> > +       if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD) &&
> > +           crypto_aegis128_have_simd())
> > +               crypto_unregister_aead(&crypto_aegis128_alg_simd);
> > +
> > +       crypto_unregister_aead(&crypto_aegis128_alg_generic);
> >  }
> >
> >  subsys_initcall(crypto_aegis128_module_init);
> > @@ -528,3 +589,4 @@ MODULE_AUTHOR("Ondrej Mosnacek <omosnacek@xxxxxxxxx>");
> >  MODULE_DESCRIPTION("AEGIS-128 AEAD algorithm");
> >  MODULE_ALIAS_CRYPTO("aegis128");
> >  MODULE_ALIAS_CRYPTO("aegis128-generic");
> > +MODULE_ALIAS_CRYPTO("aegis128-simd");
> > --
> > 2.17.1
> >




[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux