[CRYPTO] api: Added crypto_alloc_base
authorHerbert Xu <herbert@gondor.apana.org.au>
Sun, 30 Jul 2006 01:53:01 +0000 (11:53 +1000)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 21 Sep 2006 01:41:50 +0000 (11:41 +1000)
Up until now all crypto transforms have been of the same type, struct
crypto_tfm, regardless of whether they are ciphers, digests, or other
types.  As a result of that, we check the types at run-time before
each crypto operation.

This is rather cumbersome.  We could instead use different C types for
each crypto type to ensure that the correct types are used at compile
time.  That is, we would have crypto_cipher/crypto_digest instead of
just crypto_tfm.  The appropriate type would then be required for the
actual operations such as crypto_digest_digest.

Now that we have the type/mask fields when looking up algorithms, it
is easy to request for an algorithm of the precise type that the user
wants.  However, crypto_alloc_tfm currently does not expose these new
attributes.

This patch introduces the function crypto_alloc_base which will carry
these new parameters.  It will be renamed to crypto_alloc_tfm once
all existing users have been converted.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/api.c
include/linux/crypto.h

index 1e4692a..bc4b790 100644 (file)
@@ -372,6 +372,66 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
        return tfm;
 }
 
+/*
+ *     crypto_alloc_base - Locate algorithm and allocate transform
+ *     @alg_name: Name of algorithm
+ *     @type: Type of algorithm
+ *     @mask: Mask for type comparison
+ *
+ *     crypto_alloc_base() will first attempt to locate an already loaded
+ *     algorithm.  If that fails and the kernel supports dynamically loadable
+ *     modules, it will then attempt to load a module of the same name or
+ *     alias.  If that fails it will send a query to any loaded crypto manager
+ *     to construct an algorithm on the fly.  A refcount is grabbed on the
+ *     algorithm which is then associated with the new transform.
+ *
+ *     The returned transform is of a non-determinate type.  Most people
+ *     should use one of the more specific allocation functions such as
+ *     crypto_alloc_blkcipher.
+ *
+ *     In case of error the return value is an error pointer.
+ */
+struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask)
+{
+       struct crypto_tfm *tfm;
+       int err;
+
+       for (;;) {
+               struct crypto_alg *alg;
+
+               alg = crypto_alg_mod_lookup(alg_name, type, mask);
+               err = PTR_ERR(alg);
+               tfm = ERR_PTR(err);
+               if (IS_ERR(alg))
+                       goto err;
+
+               tfm = __crypto_alloc_tfm(alg, 0);
+               if (!IS_ERR(tfm))
+                       break;
+
+               crypto_mod_put(alg);
+               err = PTR_ERR(tfm);
+
+err:
+               if (err != -EAGAIN)
+                       break;
+               if (signal_pending(current)) {
+                       err = -EINTR;
+                       break;
+               }
+       };
+
+       return tfm;
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_base);
+/*
+ *     crypto_free_tfm - Free crypto transform
+ *     @tfm: Transform to free
+ *
+ *     crypto_free_tfm() frees up the transform and any associated resources,
+ *     then drops the refcount on the associated algorithm.
+ */
 void crypto_free_tfm(struct crypto_tfm *tfm)
 {
        struct crypto_alg *alg;
index 530dc4b..6847ab0 100644 (file)
@@ -194,8 +194,8 @@ static inline int crypto_alg_available(const char *name, u32 flags)
 
 /*
  * Transforms: user-instantiated objects which encapsulate algorithms
- * and core processing logic.  Managed via crypto_alloc_tfm() and
- * crypto_free_tfm(), as well as the various helpers below.
+ * and core processing logic.  Managed via crypto_alloc_*() and
+ * crypto_free_*(), as well as the various helpers below.
  */
 
 struct cipher_tfm {
@@ -278,16 +278,8 @@ struct crypto_attr_alg {
  * Transform user interface.
  */
  
-/*
- * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
- * If that fails and the kernel supports dynamically loadable modules, it
- * will then attempt to load a module of the same name or alias.  A refcount
- * is grabbed on the algorithm which is then associated with the new transform.
- *
- * crypto_free_tfm() frees up the transform and any associated resources,
- * then drops the refcount on the associated algorithm.
- */
 struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
+struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask);
 void crypto_free_tfm(struct crypto_tfm *tfm);
 
 /*