ide/arm/ide_arm.c: add MODULE_LICENSE
[sfrench/cifs-2.6.git] / crypto / algapi.c
index 38aa9e994703829a40bd6a09542f0cef97b63fef..e65cb50cf4aff8b739130ba7012e383196ef286a 100644 (file)
@@ -63,9 +63,6 @@ static int crypto_check_alg(struct crypto_alg *alg)
        if (alg->cra_alignmask & (alg->cra_alignmask + 1))
                return -EINVAL;
 
-       if (alg->cra_alignmask & alg->cra_blocksize)
-               return -EINVAL;
-
        if (alg->cra_blocksize > PAGE_SIZE / 8)
                return -EINVAL;
 
@@ -98,6 +95,9 @@ static void crypto_remove_spawn(struct crypto_spawn *spawn,
                return;
 
        inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
+       if (hlist_unhashed(&inst->list))
+               return;
+
        if (!tmpl || !crypto_tmpl_get(tmpl))
                return;
 
@@ -152,6 +152,11 @@ static int __crypto_register_alg(struct crypto_alg *alg,
                if (crypto_is_larval(q)) {
                        struct crypto_larval *larval = (void *)q;
 
+                       /*
+                        * Check to see if either our generic name or
+                        * specific name can satisfy the name requested
+                        * by the larval entry q.
+                        */
                        if (strcmp(alg->cra_name, q->cra_name) &&
                            strcmp(alg->cra_driver_name, q->cra_name))
                                continue;
@@ -333,9 +338,6 @@ int crypto_register_instance(struct crypto_template *tmpl,
        LIST_HEAD(list);
        int err = -EINVAL;
 
-       if (inst->alg.cra_destroy)
-               goto err;
-
        err = crypto_check_alg(&inst->alg);
        if (err)
                goto err;
@@ -439,13 +441,15 @@ EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
 
 struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
 {
-       struct rtattr *rta = tb[CRYPTOA_TYPE - 1];
+       struct rtattr *rta = tb[0];
        struct crypto_attr_type *algt;
 
        if (!rta)
                return ERR_PTR(-ENOENT);
        if (RTA_PAYLOAD(rta) < sizeof(*algt))
                return ERR_PTR(-EINVAL);
+       if (rta->rta_type != CRYPTOA_TYPE)
+               return ERR_PTR(-EINVAL);
 
        algt = RTA_DATA(rta);
 
@@ -468,22 +472,55 @@ int crypto_check_attr_type(struct rtattr **tb, u32 type)
 }
 EXPORT_SYMBOL_GPL(crypto_check_attr_type);
 
-struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask)
+const char *crypto_attr_alg_name(struct rtattr *rta)
 {
-       struct rtattr *rta = tb[CRYPTOA_ALG - 1];
        struct crypto_attr_alg *alga;
 
        if (!rta)
                return ERR_PTR(-ENOENT);
        if (RTA_PAYLOAD(rta) < sizeof(*alga))
                return ERR_PTR(-EINVAL);
+       if (rta->rta_type != CRYPTOA_ALG)
+               return ERR_PTR(-EINVAL);
 
        alga = RTA_DATA(rta);
        alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
 
-       return crypto_alg_mod_lookup(alga->name, type, mask);
+       return alga->name;
+}
+EXPORT_SYMBOL_GPL(crypto_attr_alg_name);
+
+struct crypto_alg *crypto_attr_alg(struct rtattr *rta, u32 type, u32 mask)
+{
+       const char *name;
+       int err;
+
+       name = crypto_attr_alg_name(rta);
+       err = PTR_ERR(name);
+       if (IS_ERR(name))
+               return ERR_PTR(err);
+
+       return crypto_alg_mod_lookup(name, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_attr_alg);
+
+int crypto_attr_u32(struct rtattr *rta, u32 *num)
+{
+       struct crypto_attr_u32 *nu32;
+
+       if (!rta)
+               return -ENOENT;
+       if (RTA_PAYLOAD(rta) < sizeof(*nu32))
+               return -EINVAL;
+       if (rta->rta_type != CRYPTOA_U32)
+               return -EINVAL;
+
+       nu32 = RTA_DATA(rta);
+       *num = nu32->num;
+
+       return 0;
 }
-EXPORT_SYMBOL_GPL(crypto_get_attr_alg);
+EXPORT_SYMBOL_GPL(crypto_attr_u32);
 
 struct crypto_instance *crypto_alloc_instance(const char *name,
                                              struct crypto_alg *alg)
@@ -582,6 +619,53 @@ int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm)
 }
 EXPORT_SYMBOL_GPL(crypto_tfm_in_queue);
 
+static inline void crypto_inc_byte(u8 *a, unsigned int size)
+{
+       u8 *b = (a + size);
+       u8 c;
+
+       for (; size; size--) {
+               c = *--b + 1;
+               *b = c;
+               if (c)
+                       break;
+       }
+}
+
+void crypto_inc(u8 *a, unsigned int size)
+{
+       __be32 *b = (__be32 *)(a + size);
+       u32 c;
+
+       for (; size >= 4; size -= 4) {
+               c = be32_to_cpu(*--b) + 1;
+               *b = cpu_to_be32(c);
+               if (c)
+                       return;
+       }
+
+       crypto_inc_byte(a, size);
+}
+EXPORT_SYMBOL_GPL(crypto_inc);
+
+static inline void crypto_xor_byte(u8 *a, const u8 *b, unsigned int size)
+{
+       for (; size; size--)
+               *a++ ^= *b++;
+}
+
+void crypto_xor(u8 *dst, const u8 *src, unsigned int size)
+{
+       u32 *a = (u32 *)dst;
+       u32 *b = (u32 *)src;
+
+       for (; size >= 4; size -= 4)
+               *a++ ^= *b++;
+
+       crypto_xor_byte((u8 *)a, (u8 *)b, size);
+}
+EXPORT_SYMBOL_GPL(crypto_xor);
+
 static int __init crypto_algapi_init(void)
 {
        crypto_init_proc();