Back to home page

LXR

 
 

    


0001 /*
0002  * Cryptographic API for algorithms (i.e., low-level API).
0003  *
0004  * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
0005  *
0006  * This program is free software; you can redistribute it and/or modify it
0007  * under the terms of the GNU General Public License as published by the Free
0008  * Software Foundation; either version 2 of the License, or (at your option)
0009  * any later version.
0010  *
0011  */
0012 
0013 #include <linux/err.h>
0014 #include <linux/errno.h>
0015 #include <linux/fips.h>
0016 #include <linux/init.h>
0017 #include <linux/kernel.h>
0018 #include <linux/list.h>
0019 #include <linux/module.h>
0020 #include <linux/rtnetlink.h>
0021 #include <linux/slab.h>
0022 #include <linux/string.h>
0023 
0024 #include "internal.h"
0025 
0026 static LIST_HEAD(crypto_template_list);
0027 
0028 static inline int crypto_set_driver_name(struct crypto_alg *alg)
0029 {
0030     static const char suffix[] = "-generic";
0031     char *driver_name = alg->cra_driver_name;
0032     int len;
0033 
0034     if (*driver_name)
0035         return 0;
0036 
0037     len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
0038     if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME)
0039         return -ENAMETOOLONG;
0040 
0041     memcpy(driver_name + len, suffix, sizeof(suffix));
0042     return 0;
0043 }
0044 
0045 static inline void crypto_check_module_sig(struct module *mod)
0046 {
0047     if (fips_enabled && mod && !module_sig_ok(mod))
0048         panic("Module %s signature verification failed in FIPS mode\n",
0049               module_name(mod));
0050 }
0051 
0052 static int crypto_check_alg(struct crypto_alg *alg)
0053 {
0054     crypto_check_module_sig(alg->cra_module);
0055 
0056     if (alg->cra_alignmask & (alg->cra_alignmask + 1))
0057         return -EINVAL;
0058 
0059     if (alg->cra_blocksize > PAGE_SIZE / 8)
0060         return -EINVAL;
0061 
0062     if (alg->cra_priority < 0)
0063         return -EINVAL;
0064 
0065     atomic_set(&alg->cra_refcnt, 1);
0066 
0067     return crypto_set_driver_name(alg);
0068 }
0069 
0070 static void crypto_free_instance(struct crypto_instance *inst)
0071 {
0072     if (!inst->alg.cra_type->free) {
0073         inst->tmpl->free(inst);
0074         return;
0075     }
0076 
0077     inst->alg.cra_type->free(inst);
0078 }
0079 
0080 static void crypto_destroy_instance(struct crypto_alg *alg)
0081 {
0082     struct crypto_instance *inst = (void *)alg;
0083     struct crypto_template *tmpl = inst->tmpl;
0084 
0085     crypto_free_instance(inst);
0086     crypto_tmpl_put(tmpl);
0087 }
0088 
0089 static struct list_head *crypto_more_spawns(struct crypto_alg *alg,
0090                         struct list_head *stack,
0091                         struct list_head *top,
0092                         struct list_head *secondary_spawns)
0093 {
0094     struct crypto_spawn *spawn, *n;
0095 
0096     spawn = list_first_entry_or_null(stack, struct crypto_spawn, list);
0097     if (!spawn)
0098         return NULL;
0099 
0100     n = list_next_entry(spawn, list);
0101 
0102     if (spawn->alg && &n->list != stack && !n->alg)
0103         n->alg = (n->list.next == stack) ? alg :
0104              &list_next_entry(n, list)->inst->alg;
0105 
0106     list_move(&spawn->list, secondary_spawns);
0107 
0108     return &n->list == stack ? top : &n->inst->alg.cra_users;
0109 }
0110 
0111 static void crypto_remove_instance(struct crypto_instance *inst,
0112                    struct list_head *list)
0113 {
0114     struct crypto_template *tmpl = inst->tmpl;
0115 
0116     if (crypto_is_dead(&inst->alg))
0117         return;
0118 
0119     inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
0120     if (hlist_unhashed(&inst->list))
0121         return;
0122 
0123     if (!tmpl || !crypto_tmpl_get(tmpl))
0124         return;
0125 
0126     crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg);
0127     list_move(&inst->alg.cra_list, list);
0128     hlist_del(&inst->list);
0129     inst->alg.cra_destroy = crypto_destroy_instance;
0130 
0131     BUG_ON(!list_empty(&inst->alg.cra_users));
0132 }
0133 
0134 void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
0135               struct crypto_alg *nalg)
0136 {
0137     u32 new_type = (nalg ?: alg)->cra_flags;
0138     struct crypto_spawn *spawn, *n;
0139     LIST_HEAD(secondary_spawns);
0140     struct list_head *spawns;
0141     LIST_HEAD(stack);
0142     LIST_HEAD(top);
0143 
0144     spawns = &alg->cra_users;
0145     list_for_each_entry_safe(spawn, n, spawns, list) {
0146         if ((spawn->alg->cra_flags ^ new_type) & spawn->mask)
0147             continue;
0148 
0149         list_move(&spawn->list, &top);
0150     }
0151 
0152     spawns = &top;
0153     do {
0154         while (!list_empty(spawns)) {
0155             struct crypto_instance *inst;
0156 
0157             spawn = list_first_entry(spawns, struct crypto_spawn,
0158                          list);
0159             inst = spawn->inst;
0160 
0161             BUG_ON(&inst->alg == alg);
0162 
0163             list_move(&spawn->list, &stack);
0164 
0165             if (&inst->alg == nalg)
0166                 break;
0167 
0168             spawn->alg = NULL;
0169             spawns = &inst->alg.cra_users;
0170         }
0171     } while ((spawns = crypto_more_spawns(alg, &stack, &top,
0172                           &secondary_spawns)));
0173 
0174     list_for_each_entry_safe(spawn, n, &secondary_spawns, list) {
0175         if (spawn->alg)
0176             list_move(&spawn->list, &spawn->alg->cra_users);
0177         else
0178             crypto_remove_instance(spawn->inst, list);
0179     }
0180 }
0181 EXPORT_SYMBOL_GPL(crypto_remove_spawns);
0182 
0183 static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
0184 {
0185     struct crypto_alg *q;
0186     struct crypto_larval *larval;
0187     int ret = -EAGAIN;
0188 
0189     if (crypto_is_dead(alg))
0190         goto err;
0191 
0192     INIT_LIST_HEAD(&alg->cra_users);
0193 
0194     /* No cheating! */
0195     alg->cra_flags &= ~CRYPTO_ALG_TESTED;
0196 
0197     ret = -EEXIST;
0198 
0199     list_for_each_entry(q, &crypto_alg_list, cra_list) {
0200         if (q == alg)
0201             goto err;
0202 
0203         if (crypto_is_moribund(q))
0204             continue;
0205 
0206         if (crypto_is_larval(q)) {
0207             if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
0208                 goto err;
0209             continue;
0210         }
0211 
0212         if (!strcmp(q->cra_driver_name, alg->cra_name) ||
0213             !strcmp(q->cra_name, alg->cra_driver_name))
0214             goto err;
0215     }
0216 
0217     larval = crypto_larval_alloc(alg->cra_name,
0218                      alg->cra_flags | CRYPTO_ALG_TESTED, 0);
0219     if (IS_ERR(larval))
0220         goto out;
0221 
0222     ret = -ENOENT;
0223     larval->adult = crypto_mod_get(alg);
0224     if (!larval->adult)
0225         goto free_larval;
0226 
0227     atomic_set(&larval->alg.cra_refcnt, 1);
0228     memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
0229            CRYPTO_MAX_ALG_NAME);
0230     larval->alg.cra_priority = alg->cra_priority;
0231 
0232     list_add(&alg->cra_list, &crypto_alg_list);
0233     list_add(&larval->alg.cra_list, &crypto_alg_list);
0234 
0235 out:
0236     return larval;
0237 
0238 free_larval:
0239     kfree(larval);
0240 err:
0241     larval = ERR_PTR(ret);
0242     goto out;
0243 }
0244 
0245 void crypto_alg_tested(const char *name, int err)
0246 {
0247     struct crypto_larval *test;
0248     struct crypto_alg *alg;
0249     struct crypto_alg *q;
0250     LIST_HEAD(list);
0251 
0252     down_write(&crypto_alg_sem);
0253     list_for_each_entry(q, &crypto_alg_list, cra_list) {
0254         if (crypto_is_moribund(q) || !crypto_is_larval(q))
0255             continue;
0256 
0257         test = (struct crypto_larval *)q;
0258 
0259         if (!strcmp(q->cra_driver_name, name))
0260             goto found;
0261     }
0262 
0263     printk(KERN_ERR "alg: Unexpected test result for %s: %d\n", name, err);
0264     goto unlock;
0265 
0266 found:
0267     q->cra_flags |= CRYPTO_ALG_DEAD;
0268     alg = test->adult;
0269     if (err || list_empty(&alg->cra_list))
0270         goto complete;
0271 
0272     alg->cra_flags |= CRYPTO_ALG_TESTED;
0273 
0274     list_for_each_entry(q, &crypto_alg_list, cra_list) {
0275         if (q == alg)
0276             continue;
0277 
0278         if (crypto_is_moribund(q))
0279             continue;
0280 
0281         if (crypto_is_larval(q)) {
0282             struct crypto_larval *larval = (void *)q;
0283 
0284             /*
0285              * Check to see if either our generic name or
0286              * specific name can satisfy the name requested
0287              * by the larval entry q.
0288              */
0289             if (strcmp(alg->cra_name, q->cra_name) &&
0290                 strcmp(alg->cra_driver_name, q->cra_name))
0291                 continue;
0292 
0293             if (larval->adult)
0294                 continue;
0295             if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
0296                 continue;
0297             if (!crypto_mod_get(alg))
0298                 continue;
0299 
0300             larval->adult = alg;
0301             continue;
0302         }
0303 
0304         if (strcmp(alg->cra_name, q->cra_name))
0305             continue;
0306 
0307         if (strcmp(alg->cra_driver_name, q->cra_driver_name) &&
0308             q->cra_priority > alg->cra_priority)
0309             continue;
0310 
0311         crypto_remove_spawns(q, &list, alg);
0312     }
0313 
0314 complete:
0315     complete_all(&test->completion);
0316 
0317 unlock:
0318     up_write(&crypto_alg_sem);
0319 
0320     crypto_remove_final(&list);
0321 }
0322 EXPORT_SYMBOL_GPL(crypto_alg_tested);
0323 
0324 void crypto_remove_final(struct list_head *list)
0325 {
0326     struct crypto_alg *alg;
0327     struct crypto_alg *n;
0328 
0329     list_for_each_entry_safe(alg, n, list, cra_list) {
0330         list_del_init(&alg->cra_list);
0331         crypto_alg_put(alg);
0332     }
0333 }
0334 EXPORT_SYMBOL_GPL(crypto_remove_final);
0335 
0336 static void crypto_wait_for_test(struct crypto_larval *larval)
0337 {
0338     int err;
0339 
0340     err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
0341     if (err != NOTIFY_STOP) {
0342         if (WARN_ON(err != NOTIFY_DONE))
0343             goto out;
0344         crypto_alg_tested(larval->alg.cra_driver_name, 0);
0345     }
0346 
0347     err = wait_for_completion_killable(&larval->completion);
0348     WARN_ON(err);
0349 
0350 out:
0351     crypto_larval_kill(&larval->alg);
0352 }
0353 
0354 int crypto_register_alg(struct crypto_alg *alg)
0355 {
0356     struct crypto_larval *larval;
0357     int err;
0358 
0359     alg->cra_flags &= ~CRYPTO_ALG_DEAD;
0360     err = crypto_check_alg(alg);
0361     if (err)
0362         return err;
0363 
0364     down_write(&crypto_alg_sem);
0365     larval = __crypto_register_alg(alg);
0366     up_write(&crypto_alg_sem);
0367 
0368     if (IS_ERR(larval))
0369         return PTR_ERR(larval);
0370 
0371     crypto_wait_for_test(larval);
0372     return 0;
0373 }
0374 EXPORT_SYMBOL_GPL(crypto_register_alg);
0375 
0376 static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list)
0377 {
0378     if (unlikely(list_empty(&alg->cra_list)))
0379         return -ENOENT;
0380 
0381     alg->cra_flags |= CRYPTO_ALG_DEAD;
0382 
0383     crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg);
0384     list_del_init(&alg->cra_list);
0385     crypto_remove_spawns(alg, list, NULL);
0386 
0387     return 0;
0388 }
0389 
0390 int crypto_unregister_alg(struct crypto_alg *alg)
0391 {
0392     int ret;
0393     LIST_HEAD(list);
0394 
0395     down_write(&crypto_alg_sem);
0396     ret = crypto_remove_alg(alg, &list);
0397     up_write(&crypto_alg_sem);
0398 
0399     if (ret)
0400         return ret;
0401 
0402     BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
0403     if (alg->cra_destroy)
0404         alg->cra_destroy(alg);
0405 
0406     crypto_remove_final(&list);
0407     return 0;
0408 }
0409 EXPORT_SYMBOL_GPL(crypto_unregister_alg);
0410 
0411 int crypto_register_algs(struct crypto_alg *algs, int count)
0412 {
0413     int i, ret;
0414 
0415     for (i = 0; i < count; i++) {
0416         ret = crypto_register_alg(&algs[i]);
0417         if (ret)
0418             goto err;
0419     }
0420 
0421     return 0;
0422 
0423 err:
0424     for (--i; i >= 0; --i)
0425         crypto_unregister_alg(&algs[i]);
0426 
0427     return ret;
0428 }
0429 EXPORT_SYMBOL_GPL(crypto_register_algs);
0430 
0431 int crypto_unregister_algs(struct crypto_alg *algs, int count)
0432 {
0433     int i, ret;
0434 
0435     for (i = 0; i < count; i++) {
0436         ret = crypto_unregister_alg(&algs[i]);
0437         if (ret)
0438             pr_err("Failed to unregister %s %s: %d\n",
0439                    algs[i].cra_driver_name, algs[i].cra_name, ret);
0440     }
0441 
0442     return 0;
0443 }
0444 EXPORT_SYMBOL_GPL(crypto_unregister_algs);
0445 
0446 int crypto_register_template(struct crypto_template *tmpl)
0447 {
0448     struct crypto_template *q;
0449     int err = -EEXIST;
0450 
0451     down_write(&crypto_alg_sem);
0452 
0453     crypto_check_module_sig(tmpl->module);
0454 
0455     list_for_each_entry(q, &crypto_template_list, list) {
0456         if (q == tmpl)
0457             goto out;
0458     }
0459 
0460     list_add(&tmpl->list, &crypto_template_list);
0461     crypto_notify(CRYPTO_MSG_TMPL_REGISTER, tmpl);
0462     err = 0;
0463 out:
0464     up_write(&crypto_alg_sem);
0465     return err;
0466 }
0467 EXPORT_SYMBOL_GPL(crypto_register_template);
0468 
0469 void crypto_unregister_template(struct crypto_template *tmpl)
0470 {
0471     struct crypto_instance *inst;
0472     struct hlist_node *n;
0473     struct hlist_head *list;
0474     LIST_HEAD(users);
0475 
0476     down_write(&crypto_alg_sem);
0477 
0478     BUG_ON(list_empty(&tmpl->list));
0479     list_del_init(&tmpl->list);
0480 
0481     list = &tmpl->instances;
0482     hlist_for_each_entry(inst, list, list) {
0483         int err = crypto_remove_alg(&inst->alg, &users);
0484 
0485         BUG_ON(err);
0486     }
0487 
0488     crypto_notify(CRYPTO_MSG_TMPL_UNREGISTER, tmpl);
0489 
0490     up_write(&crypto_alg_sem);
0491 
0492     hlist_for_each_entry_safe(inst, n, list, list) {
0493         BUG_ON(atomic_read(&inst->alg.cra_refcnt) != 1);
0494         crypto_free_instance(inst);
0495     }
0496     crypto_remove_final(&users);
0497 }
0498 EXPORT_SYMBOL_GPL(crypto_unregister_template);
0499 
0500 static struct crypto_template *__crypto_lookup_template(const char *name)
0501 {
0502     struct crypto_template *q, *tmpl = NULL;
0503 
0504     down_read(&crypto_alg_sem);
0505     list_for_each_entry(q, &crypto_template_list, list) {
0506         if (strcmp(q->name, name))
0507             continue;
0508         if (unlikely(!crypto_tmpl_get(q)))
0509             continue;
0510 
0511         tmpl = q;
0512         break;
0513     }
0514     up_read(&crypto_alg_sem);
0515 
0516     return tmpl;
0517 }
0518 
0519 struct crypto_template *crypto_lookup_template(const char *name)
0520 {
0521     return try_then_request_module(__crypto_lookup_template(name),
0522                        "crypto-%s", name);
0523 }
0524 EXPORT_SYMBOL_GPL(crypto_lookup_template);
0525 
0526 int crypto_register_instance(struct crypto_template *tmpl,
0527                  struct crypto_instance *inst)
0528 {
0529     struct crypto_larval *larval;
0530     int err;
0531 
0532     err = crypto_check_alg(&inst->alg);
0533     if (err)
0534         return err;
0535 
0536     inst->alg.cra_module = tmpl->module;
0537     inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
0538 
0539     if (unlikely(!crypto_mod_get(&inst->alg)))
0540         return -EAGAIN;
0541 
0542     down_write(&crypto_alg_sem);
0543 
0544     larval = __crypto_register_alg(&inst->alg);
0545     if (IS_ERR(larval))
0546         goto unlock;
0547 
0548     hlist_add_head(&inst->list, &tmpl->instances);
0549     inst->tmpl = tmpl;
0550 
0551 unlock:
0552     up_write(&crypto_alg_sem);
0553 
0554     err = PTR_ERR(larval);
0555     if (IS_ERR(larval))
0556         goto err;
0557 
0558     crypto_wait_for_test(larval);
0559 
0560     /* Remove instance if test failed */
0561     if (!(inst->alg.cra_flags & CRYPTO_ALG_TESTED))
0562         crypto_unregister_instance(inst);
0563     err = 0;
0564 
0565 err:
0566     crypto_mod_put(&inst->alg);
0567     return err;
0568 }
0569 EXPORT_SYMBOL_GPL(crypto_register_instance);
0570 
0571 int crypto_unregister_instance(struct crypto_instance *inst)
0572 {
0573     LIST_HEAD(list);
0574 
0575     down_write(&crypto_alg_sem);
0576 
0577     crypto_remove_spawns(&inst->alg, &list, NULL);
0578     crypto_remove_instance(inst, &list);
0579 
0580     up_write(&crypto_alg_sem);
0581 
0582     crypto_remove_final(&list);
0583 
0584     return 0;
0585 }
0586 EXPORT_SYMBOL_GPL(crypto_unregister_instance);
0587 
0588 int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
0589               struct crypto_instance *inst, u32 mask)
0590 {
0591     int err = -EAGAIN;
0592 
0593     spawn->inst = inst;
0594     spawn->mask = mask;
0595 
0596     down_write(&crypto_alg_sem);
0597     if (!crypto_is_moribund(alg)) {
0598         list_add(&spawn->list, &alg->cra_users);
0599         spawn->alg = alg;
0600         err = 0;
0601     }
0602     up_write(&crypto_alg_sem);
0603 
0604     return err;
0605 }
0606 EXPORT_SYMBOL_GPL(crypto_init_spawn);
0607 
0608 int crypto_init_spawn2(struct crypto_spawn *spawn, struct crypto_alg *alg,
0609                struct crypto_instance *inst,
0610                const struct crypto_type *frontend)
0611 {
0612     int err = -EINVAL;
0613 
0614     if ((alg->cra_flags ^ frontend->type) & frontend->maskset)
0615         goto out;
0616 
0617     spawn->frontend = frontend;
0618     err = crypto_init_spawn(spawn, alg, inst, frontend->maskset);
0619 
0620 out:
0621     return err;
0622 }
0623 EXPORT_SYMBOL_GPL(crypto_init_spawn2);
0624 
0625 int crypto_grab_spawn(struct crypto_spawn *spawn, const char *name,
0626               u32 type, u32 mask)
0627 {
0628     struct crypto_alg *alg;
0629     int err;
0630 
0631     alg = crypto_find_alg(name, spawn->frontend, type, mask);
0632     if (IS_ERR(alg))
0633         return PTR_ERR(alg);
0634 
0635     err = crypto_init_spawn(spawn, alg, spawn->inst, mask);
0636     crypto_mod_put(alg);
0637     return err;
0638 }
0639 EXPORT_SYMBOL_GPL(crypto_grab_spawn);
0640 
0641 void crypto_drop_spawn(struct crypto_spawn *spawn)
0642 {
0643     if (!spawn->alg)
0644         return;
0645 
0646     down_write(&crypto_alg_sem);
0647     list_del(&spawn->list);
0648     up_write(&crypto_alg_sem);
0649 }
0650 EXPORT_SYMBOL_GPL(crypto_drop_spawn);
0651 
0652 static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
0653 {
0654     struct crypto_alg *alg;
0655     struct crypto_alg *alg2;
0656 
0657     down_read(&crypto_alg_sem);
0658     alg = spawn->alg;
0659     alg2 = alg;
0660     if (alg2)
0661         alg2 = crypto_mod_get(alg2);
0662     up_read(&crypto_alg_sem);
0663 
0664     if (!alg2) {
0665         if (alg)
0666             crypto_shoot_alg(alg);
0667         return ERR_PTR(-EAGAIN);
0668     }
0669 
0670     return alg;
0671 }
0672 
0673 struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
0674                     u32 mask)
0675 {
0676     struct crypto_alg *alg;
0677     struct crypto_tfm *tfm;
0678 
0679     alg = crypto_spawn_alg(spawn);
0680     if (IS_ERR(alg))
0681         return ERR_CAST(alg);
0682 
0683     tfm = ERR_PTR(-EINVAL);
0684     if (unlikely((alg->cra_flags ^ type) & mask))
0685         goto out_put_alg;
0686 
0687     tfm = __crypto_alloc_tfm(alg, type, mask);
0688     if (IS_ERR(tfm))
0689         goto out_put_alg;
0690 
0691     return tfm;
0692 
0693 out_put_alg:
0694     crypto_mod_put(alg);
0695     return tfm;
0696 }
0697 EXPORT_SYMBOL_GPL(crypto_spawn_tfm);
0698 
0699 void *crypto_spawn_tfm2(struct crypto_spawn *spawn)
0700 {
0701     struct crypto_alg *alg;
0702     struct crypto_tfm *tfm;
0703 
0704     alg = crypto_spawn_alg(spawn);
0705     if (IS_ERR(alg))
0706         return ERR_CAST(alg);
0707 
0708     tfm = crypto_create_tfm(alg, spawn->frontend);
0709     if (IS_ERR(tfm))
0710         goto out_put_alg;
0711 
0712     return tfm;
0713 
0714 out_put_alg:
0715     crypto_mod_put(alg);
0716     return tfm;
0717 }
0718 EXPORT_SYMBOL_GPL(crypto_spawn_tfm2);
0719 
0720 int crypto_register_notifier(struct notifier_block *nb)
0721 {
0722     return blocking_notifier_chain_register(&crypto_chain, nb);
0723 }
0724 EXPORT_SYMBOL_GPL(crypto_register_notifier);
0725 
0726 int crypto_unregister_notifier(struct notifier_block *nb)
0727 {
0728     return blocking_notifier_chain_unregister(&crypto_chain, nb);
0729 }
0730 EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
0731 
0732 struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
0733 {
0734     struct rtattr *rta = tb[0];
0735     struct crypto_attr_type *algt;
0736 
0737     if (!rta)
0738         return ERR_PTR(-ENOENT);
0739     if (RTA_PAYLOAD(rta) < sizeof(*algt))
0740         return ERR_PTR(-EINVAL);
0741     if (rta->rta_type != CRYPTOA_TYPE)
0742         return ERR_PTR(-EINVAL);
0743 
0744     algt = RTA_DATA(rta);
0745 
0746     return algt;
0747 }
0748 EXPORT_SYMBOL_GPL(crypto_get_attr_type);
0749 
0750 int crypto_check_attr_type(struct rtattr **tb, u32 type)
0751 {
0752     struct crypto_attr_type *algt;
0753 
0754     algt = crypto_get_attr_type(tb);
0755     if (IS_ERR(algt))
0756         return PTR_ERR(algt);
0757 
0758     if ((algt->type ^ type) & algt->mask)
0759         return -EINVAL;
0760 
0761     return 0;
0762 }
0763 EXPORT_SYMBOL_GPL(crypto_check_attr_type);
0764 
0765 const char *crypto_attr_alg_name(struct rtattr *rta)
0766 {
0767     struct crypto_attr_alg *alga;
0768 
0769     if (!rta)
0770         return ERR_PTR(-ENOENT);
0771     if (RTA_PAYLOAD(rta) < sizeof(*alga))
0772         return ERR_PTR(-EINVAL);
0773     if (rta->rta_type != CRYPTOA_ALG)
0774         return ERR_PTR(-EINVAL);
0775 
0776     alga = RTA_DATA(rta);
0777     alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
0778 
0779     return alga->name;
0780 }
0781 EXPORT_SYMBOL_GPL(crypto_attr_alg_name);
0782 
0783 struct crypto_alg *crypto_attr_alg2(struct rtattr *rta,
0784                     const struct crypto_type *frontend,
0785                     u32 type, u32 mask)
0786 {
0787     const char *name;
0788 
0789     name = crypto_attr_alg_name(rta);
0790     if (IS_ERR(name))
0791         return ERR_CAST(name);
0792 
0793     return crypto_find_alg(name, frontend, type, mask);
0794 }
0795 EXPORT_SYMBOL_GPL(crypto_attr_alg2);
0796 
0797 int crypto_attr_u32(struct rtattr *rta, u32 *num)
0798 {
0799     struct crypto_attr_u32 *nu32;
0800 
0801     if (!rta)
0802         return -ENOENT;
0803     if (RTA_PAYLOAD(rta) < sizeof(*nu32))
0804         return -EINVAL;
0805     if (rta->rta_type != CRYPTOA_U32)
0806         return -EINVAL;
0807 
0808     nu32 = RTA_DATA(rta);
0809     *num = nu32->num;
0810 
0811     return 0;
0812 }
0813 EXPORT_SYMBOL_GPL(crypto_attr_u32);
0814 
0815 int crypto_inst_setname(struct crypto_instance *inst, const char *name,
0816             struct crypto_alg *alg)
0817 {
0818     if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", name,
0819              alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
0820         return -ENAMETOOLONG;
0821 
0822     if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
0823              name, alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
0824         return -ENAMETOOLONG;
0825 
0826     return 0;
0827 }
0828 EXPORT_SYMBOL_GPL(crypto_inst_setname);
0829 
0830 void *crypto_alloc_instance2(const char *name, struct crypto_alg *alg,
0831                  unsigned int head)
0832 {
0833     struct crypto_instance *inst;
0834     char *p;
0835     int err;
0836 
0837     p = kzalloc(head + sizeof(*inst) + sizeof(struct crypto_spawn),
0838             GFP_KERNEL);
0839     if (!p)
0840         return ERR_PTR(-ENOMEM);
0841 
0842     inst = (void *)(p + head);
0843 
0844     err = crypto_inst_setname(inst, name, alg);
0845     if (err)
0846         goto err_free_inst;
0847 
0848     return p;
0849 
0850 err_free_inst:
0851     kfree(p);
0852     return ERR_PTR(err);
0853 }
0854 EXPORT_SYMBOL_GPL(crypto_alloc_instance2);
0855 
0856 struct crypto_instance *crypto_alloc_instance(const char *name,
0857                           struct crypto_alg *alg)
0858 {
0859     struct crypto_instance *inst;
0860     struct crypto_spawn *spawn;
0861     int err;
0862 
0863     inst = crypto_alloc_instance2(name, alg, 0);
0864     if (IS_ERR(inst))
0865         goto out;
0866 
0867     spawn = crypto_instance_ctx(inst);
0868     err = crypto_init_spawn(spawn, alg, inst,
0869                 CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
0870 
0871     if (err)
0872         goto err_free_inst;
0873 
0874     return inst;
0875 
0876 err_free_inst:
0877     kfree(inst);
0878     inst = ERR_PTR(err);
0879 
0880 out:
0881     return inst;
0882 }
0883 EXPORT_SYMBOL_GPL(crypto_alloc_instance);
0884 
0885 void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen)
0886 {
0887     INIT_LIST_HEAD(&queue->list);
0888     queue->backlog = &queue->list;
0889     queue->qlen = 0;
0890     queue->max_qlen = max_qlen;
0891 }
0892 EXPORT_SYMBOL_GPL(crypto_init_queue);
0893 
0894 int crypto_enqueue_request(struct crypto_queue *queue,
0895                struct crypto_async_request *request)
0896 {
0897     int err = -EINPROGRESS;
0898 
0899     if (unlikely(queue->qlen >= queue->max_qlen)) {
0900         err = -EBUSY;
0901         if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
0902             goto out;
0903         if (queue->backlog == &queue->list)
0904             queue->backlog = &request->list;
0905     }
0906 
0907     queue->qlen++;
0908     list_add_tail(&request->list, &queue->list);
0909 
0910 out:
0911     return err;
0912 }
0913 EXPORT_SYMBOL_GPL(crypto_enqueue_request);
0914 
0915 struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
0916 {
0917     struct list_head *request;
0918 
0919     if (unlikely(!queue->qlen))
0920         return NULL;
0921 
0922     queue->qlen--;
0923 
0924     if (queue->backlog != &queue->list)
0925         queue->backlog = queue->backlog->next;
0926 
0927     request = queue->list.next;
0928     list_del(request);
0929 
0930     return list_entry(request, struct crypto_async_request, list);
0931 }
0932 EXPORT_SYMBOL_GPL(crypto_dequeue_request);
0933 
0934 int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm)
0935 {
0936     struct crypto_async_request *req;
0937 
0938     list_for_each_entry(req, &queue->list, list) {
0939         if (req->tfm == tfm)
0940             return 1;
0941     }
0942 
0943     return 0;
0944 }
0945 EXPORT_SYMBOL_GPL(crypto_tfm_in_queue);
0946 
0947 static inline void crypto_inc_byte(u8 *a, unsigned int size)
0948 {
0949     u8 *b = (a + size);
0950     u8 c;
0951 
0952     for (; size; size--) {
0953         c = *--b + 1;
0954         *b = c;
0955         if (c)
0956             break;
0957     }
0958 }
0959 
0960 void crypto_inc(u8 *a, unsigned int size)
0961 {
0962     __be32 *b = (__be32 *)(a + size);
0963     u32 c;
0964 
0965     for (; size >= 4; size -= 4) {
0966         c = be32_to_cpu(*--b) + 1;
0967         *b = cpu_to_be32(c);
0968         if (c)
0969             return;
0970     }
0971 
0972     crypto_inc_byte(a, size);
0973 }
0974 EXPORT_SYMBOL_GPL(crypto_inc);
0975 
0976 static inline void crypto_xor_byte(u8 *a, const u8 *b, unsigned int size)
0977 {
0978     for (; size; size--)
0979         *a++ ^= *b++;
0980 }
0981 
0982 void crypto_xor(u8 *dst, const u8 *src, unsigned int size)
0983 {
0984     u32 *a = (u32 *)dst;
0985     u32 *b = (u32 *)src;
0986 
0987     for (; size >= 4; size -= 4)
0988         *a++ ^= *b++;
0989 
0990     crypto_xor_byte((u8 *)a, (u8 *)b, size);
0991 }
0992 EXPORT_SYMBOL_GPL(crypto_xor);
0993 
0994 unsigned int crypto_alg_extsize(struct crypto_alg *alg)
0995 {
0996     return alg->cra_ctxsize +
0997            (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1));
0998 }
0999 EXPORT_SYMBOL_GPL(crypto_alg_extsize);
1000 
1001 int crypto_type_has_alg(const char *name, const struct crypto_type *frontend,
1002             u32 type, u32 mask)
1003 {
1004     int ret = 0;
1005     struct crypto_alg *alg = crypto_find_alg(name, frontend, type, mask);
1006 
1007     if (!IS_ERR(alg)) {
1008         crypto_mod_put(alg);
1009         ret = 1;
1010     }
1011 
1012     return ret;
1013 }
1014 EXPORT_SYMBOL_GPL(crypto_type_has_alg);
1015 
1016 static int __init crypto_algapi_init(void)
1017 {
1018     crypto_init_proc();
1019     return 0;
1020 }
1021 
1022 static void __exit crypto_algapi_exit(void)
1023 {
1024     crypto_exit_proc();
1025 }
1026 
1027 module_init(crypto_algapi_init);
1028 module_exit(crypto_algapi_exit);
1029 
1030 MODULE_LICENSE("GPL");
1031 MODULE_DESCRIPTION("Cryptographic algorithms API");