crypto: simd - allow registering multiple algorithms at once
authorEric Biggers <ebiggers@google.com>
Tue, 20 Feb 2018 07:47:59 +0000 (23:47 -0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 2 Mar 2018 16:03:17 +0000 (00:03 +0800)
Add a function to crypto_simd that registers an array of skcipher
algorithms, then allocates and registers the simd wrapper algorithms for
them.  It assumes the naming scheme where the names of the underlying
algorithms are prefixed with two underscores.

Also add the corresponding 'unregister' function.

Most of the x86 crypto modules will be able to use these.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/simd.c
include/crypto/internal/simd.h

index 208226d7f908f79fefe96afa330ec87c154e1532..ea7240be3001ba245c12d3214c11a7c7e6a8a1fd 100644 (file)
@@ -221,4 +221,54 @@ void simd_skcipher_free(struct simd_skcipher_alg *salg)
 }
 EXPORT_SYMBOL_GPL(simd_skcipher_free);
 
+int simd_register_skciphers_compat(struct skcipher_alg *algs, int count,
+                                  struct simd_skcipher_alg **simd_algs)
+{
+       int err;
+       int i;
+       const char *algname;
+       const char *drvname;
+       const char *basename;
+       struct simd_skcipher_alg *simd;
+
+       err = crypto_register_skciphers(algs, count);
+       if (err)
+               return err;
+
+       for (i = 0; i < count; i++) {
+               WARN_ON(strncmp(algs[i].base.cra_name, "__", 2));
+               WARN_ON(strncmp(algs[i].base.cra_driver_name, "__", 2));
+               algname = algs[i].base.cra_name + 2;
+               drvname = algs[i].base.cra_driver_name + 2;
+               basename = algs[i].base.cra_driver_name;
+               simd = simd_skcipher_create_compat(algname, drvname, basename);
+               err = PTR_ERR(simd);
+               if (IS_ERR(simd))
+                       goto err_unregister;
+               simd_algs[i] = simd;
+       }
+       return 0;
+
+err_unregister:
+       simd_unregister_skciphers(algs, count, simd_algs);
+       return err;
+}
+EXPORT_SYMBOL_GPL(simd_register_skciphers_compat);
+
+void simd_unregister_skciphers(struct skcipher_alg *algs, int count,
+                              struct simd_skcipher_alg **simd_algs)
+{
+       int i;
+
+       crypto_unregister_skciphers(algs, count);
+
+       for (i = 0; i < count; i++) {
+               if (simd_algs[i]) {
+                       simd_skcipher_free(simd_algs[i]);
+                       simd_algs[i] = NULL;
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(simd_unregister_skciphers);
+
 MODULE_LICENSE("GPL");
index 32ceb6929885e1abc5bcda021312a285f83357c4..f18344518e322d3656faf862286a91f652970652 100644 (file)
@@ -7,6 +7,7 @@
 #define _CRYPTO_INTERNAL_SIMD_H
 
 struct simd_skcipher_alg;
+struct skcipher_alg;
 
 struct simd_skcipher_alg *simd_skcipher_create_compat(const char *algname,
                                                      const char *drvname,
@@ -15,4 +16,10 @@ struct simd_skcipher_alg *simd_skcipher_create(const char *algname,
                                               const char *basename);
 void simd_skcipher_free(struct simd_skcipher_alg *alg);
 
+int simd_register_skciphers_compat(struct skcipher_alg *algs, int count,
+                                  struct simd_skcipher_alg **simd_algs);
+
+void simd_unregister_skciphers(struct skcipher_alg *algs, int count,
+                              struct simd_skcipher_alg **simd_algs);
+
 #endif /* _CRYPTO_INTERNAL_SIMD_H */