]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - crypto/api.c
hfsplus: ensure bio requests are not smaller than the hardware sectors
[linux-2.6.git] / crypto / api.c
index 9975a7bd246c21d4d7e3152249ffefdb38812ee5..033a7147e5ebc4317b3bf082f090e8f2c2c8c115 100644 (file)
@@ -10,7 +10,7 @@
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option) 
+ * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
  *
  */
@@ -215,8 +215,17 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask)
        mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
        type &= mask;
 
-       alg = try_then_request_module(crypto_alg_lookup(name, type, mask),
-                                     name);
+       alg = crypto_alg_lookup(name, type, mask);
+       if (!alg) {
+               request_module("%s", name);
+
+               if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask &
+                     CRYPTO_ALG_NEED_FALLBACK))
+                       request_module("%s-all", name);
+
+               alg = crypto_alg_lookup(name, type, mask);
+       }
+
        if (alg)
                return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
 
@@ -244,7 +253,7 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
        struct crypto_alg *larval;
        int ok;
 
-       if (!(mask & CRYPTO_ALG_TESTED)) {
+       if (!((type | mask) & CRYPTO_ALG_TESTED)) {
                type |= CRYPTO_ALG_TESTED;
                mask |= CRYPTO_ALG_TESTED;
        }
@@ -276,21 +285,14 @@ static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
        switch (crypto_tfm_alg_type(tfm)) {
        case CRYPTO_ALG_TYPE_CIPHER:
                return crypto_init_cipher_ops(tfm);
-               
-       case CRYPTO_ALG_TYPE_DIGEST:
-               if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) !=
-                   CRYPTO_ALG_TYPE_HASH_MASK)
-                       return crypto_init_digest_ops_async(tfm);
-               else
-                       return crypto_init_digest_ops(tfm);
 
        case CRYPTO_ALG_TYPE_COMPRESS:
                return crypto_init_compress_ops(tfm);
-       
+
        default:
                break;
        }
-       
+
        BUG();
        return -EINVAL;
 }
@@ -309,18 +311,13 @@ static void crypto_exit_ops(struct crypto_tfm *tfm)
        case CRYPTO_ALG_TYPE_CIPHER:
                crypto_exit_cipher_ops(tfm);
                break;
-               
-       case CRYPTO_ALG_TYPE_DIGEST:
-               crypto_exit_digest_ops(tfm);
-               break;
-               
+
        case CRYPTO_ALG_TYPE_COMPRESS:
                crypto_exit_compress_ops(tfm);
                break;
-       
+
        default:
                BUG();
-               
        }
 }
 
@@ -340,11 +337,7 @@ static unsigned int crypto_ctxsize(struct crypto_alg *alg, u32 type, u32 mask)
        case CRYPTO_ALG_TYPE_CIPHER:
                len += crypto_cipher_ctxsize(alg);
                break;
-               
-       case CRYPTO_ALG_TYPE_DIGEST:
-               len += crypto_digest_ctxsize(alg);
-               break;
-               
+
        case CRYPTO_ALG_TYPE_COMPRESS:
                len += crypto_compress_ctxsize(alg);
                break;
@@ -453,8 +446,8 @@ err:
 }
 EXPORT_SYMBOL_GPL(crypto_alloc_base);
 
-struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg,
-                                    const struct crypto_type *frontend)
+void *crypto_create_tfm(struct crypto_alg *alg,
+                       const struct crypto_type *frontend)
 {
        char *mem;
        struct crypto_tfm *tfm = NULL;
@@ -463,7 +456,7 @@ struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg,
        int err = -ENOMEM;
 
        tfmsize = frontend->tfmsize;
-       total = tfmsize + sizeof(*tfm) + frontend->extsize(alg, frontend);
+       total = tfmsize + sizeof(*tfm) + frontend->extsize(alg);
 
        mem = kzalloc(total, GFP_KERNEL);
        if (mem == NULL)
@@ -472,7 +465,7 @@ struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg,
        tfm = (struct crypto_tfm *)(mem + tfmsize);
        tfm->__crt_alg = alg;
 
-       err = frontend->init_tfm(tfm, frontend);
+       err = frontend->init_tfm(tfm);
        if (err)
                goto out_free_tfm;
 
@@ -488,12 +481,33 @@ out_free_tfm:
                crypto_shoot_alg(alg);
        kfree(mem);
 out_err:
-       tfm = ERR_PTR(err);
+       mem = ERR_PTR(err);
 out:
-       return tfm;
+       return mem;
 }
 EXPORT_SYMBOL_GPL(crypto_create_tfm);
 
+struct crypto_alg *crypto_find_alg(const char *alg_name,
+                                  const struct crypto_type *frontend,
+                                  u32 type, u32 mask)
+{
+       struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask) =
+               crypto_alg_mod_lookup;
+
+       if (frontend) {
+               type &= frontend->maskclear;
+               mask &= frontend->maskclear;
+               type |= frontend->type;
+               mask |= frontend->maskset;
+
+               if (frontend->lookup)
+                       lookup = frontend->lookup;
+       }
+
+       return lookup(alg_name, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_find_alg);
+
 /*
  *     crypto_alloc_tfm - Locate algorithm and allocate transform
  *     @alg_name: Name of algorithm
@@ -514,25 +528,16 @@ EXPORT_SYMBOL_GPL(crypto_create_tfm);
  *
  *     In case of error the return value is an error pointer.
  */
-struct crypto_tfm *crypto_alloc_tfm(const char *alg_name,
-                                   const struct crypto_type *frontend,
-                                   u32 type, u32 mask)
+void *crypto_alloc_tfm(const char *alg_name,
+                      const struct crypto_type *frontend, u32 type, u32 mask)
 {
-       struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask);
-       struct crypto_tfm *tfm;
+       void *tfm;
        int err;
 
-       type &= frontend->maskclear;
-       mask &= frontend->maskclear;
-       type |= frontend->type;
-       mask |= frontend->maskset;
-
-       lookup = frontend->lookup ?: crypto_alg_mod_lookup;
-
        for (;;) {
                struct crypto_alg *alg;
 
-               alg = lookup(alg_name, type, mask);
+               alg = crypto_find_alg(alg_name, frontend, type, mask);
                if (IS_ERR(alg)) {
                        err = PTR_ERR(alg);
                        goto err;
@@ -557,45 +562,42 @@ err:
        return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
+
 /*
- *     crypto_free_tfm - Free crypto transform
+ *     crypto_destroy_tfm - Free crypto transform
+ *     @mem: Start of tfm slab
  *     @tfm: Transform to free
  *
- *     crypto_free_tfm() frees up the transform and any associated resources,
+ *     This function frees up the transform and any associated resources,
  *     then drops the refcount on the associated algorithm.
  */
-void crypto_free_tfm(struct crypto_tfm *tfm)
+void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
 {
        struct crypto_alg *alg;
-       int size;
 
-       if (unlikely(!tfm))
+       if (unlikely(!mem))
                return;
 
        alg = tfm->__crt_alg;
-       size = sizeof(*tfm) + alg->cra_ctxsize;
 
        if (!tfm->exit && alg->cra_exit)
                alg->cra_exit(tfm);
        crypto_exit_ops(tfm);
        crypto_mod_put(alg);
-       memset(tfm, 0, size);
-       kfree(tfm);
+       kzfree(mem);
 }
-
-EXPORT_SYMBOL_GPL(crypto_free_tfm);
+EXPORT_SYMBOL_GPL(crypto_destroy_tfm);
 
 int crypto_has_alg(const char *name, u32 type, u32 mask)
 {
        int ret = 0;
        struct crypto_alg *alg = crypto_alg_mod_lookup(name, type, mask);
-       
+
        if (!IS_ERR(alg)) {
                crypto_mod_put(alg);
                ret = 1;
        }
-       
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(crypto_has_alg);