LCOV - code coverage report
Current view: top level - crypto - algapi.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 136 543 25.0 %
Date: 2021-04-22 12:43:58 Functions: 11 45 24.4 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * Cryptographic API for algorithms (i.e., low-level API).
       4             :  *
       5             :  * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
       6             :  */
       7             : 
       8             : #include <crypto/algapi.h>
       9             : #include <linux/err.h>
      10             : #include <linux/errno.h>
      11             : #include <linux/fips.h>
      12             : #include <linux/init.h>
      13             : #include <linux/kernel.h>
      14             : #include <linux/list.h>
      15             : #include <linux/module.h>
      16             : #include <linux/rtnetlink.h>
      17             : #include <linux/slab.h>
      18             : #include <linux/string.h>
      19             : 
      20             : #include "internal.h"
      21             : 
      22             : static LIST_HEAD(crypto_template_list);
      23             : 
      24          10 : static inline void crypto_check_module_sig(struct module *mod)
      25             : {
      26          10 :         if (fips_enabled && mod && !module_sig_ok(mod))
      27             :                 panic("Module %s signature verification failed in FIPS mode\n",
      28             :                       module_name(mod));
      29             : }
      30             : 
      31          10 : static int crypto_check_alg(struct crypto_alg *alg)
      32             : {
      33          10 :         crypto_check_module_sig(alg->cra_module);
      34             : 
      35          10 :         if (!alg->cra_name[0] || !alg->cra_driver_name[0])
      36             :                 return -EINVAL;
      37             : 
      38          10 :         if (alg->cra_alignmask & (alg->cra_alignmask + 1))
      39             :                 return -EINVAL;
      40             : 
      41             :         /* General maximums for all algs. */
      42          10 :         if (alg->cra_alignmask > MAX_ALGAPI_ALIGNMASK)
      43             :                 return -EINVAL;
      44             : 
      45          10 :         if (alg->cra_blocksize > MAX_ALGAPI_BLOCKSIZE)
      46             :                 return -EINVAL;
      47             : 
      48             :         /* Lower maximums for specific alg types. */
      49          10 :         if (!alg->cra_type && (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
      50             :                                CRYPTO_ALG_TYPE_CIPHER) {
      51           2 :                 if (alg->cra_alignmask > MAX_CIPHER_ALIGNMASK)
      52             :                         return -EINVAL;
      53             : 
      54           2 :                 if (alg->cra_blocksize > MAX_CIPHER_BLOCKSIZE)
      55             :                         return -EINVAL;
      56             :         }
      57             : 
      58          10 :         if (alg->cra_priority < 0)
      59             :                 return -EINVAL;
      60             : 
      61          10 :         refcount_set(&alg->cra_refcnt, 1);
      62             : 
      63          10 :         return 0;
      64             : }
      65             : 
      66           0 : static void crypto_free_instance(struct crypto_instance *inst)
      67             : {
      68           0 :         inst->alg.cra_type->free(inst);
      69             : }
      70             : 
      71           0 : static void crypto_destroy_instance(struct crypto_alg *alg)
      72             : {
      73           0 :         struct crypto_instance *inst = (void *)alg;
      74           0 :         struct crypto_template *tmpl = inst->tmpl;
      75             : 
      76           0 :         crypto_free_instance(inst);
      77           0 :         crypto_tmpl_put(tmpl);
      78           0 : }
      79             : 
      80             : /*
      81             :  * This function adds a spawn to the list secondary_spawns which
      82             :  * will be used at the end of crypto_remove_spawns to unregister
      83             :  * instances, unless the spawn happens to be one that is depended
      84             :  * on by the new algorithm (nalg in crypto_remove_spawns).
      85             :  *
      86             :  * This function is also responsible for resurrecting any algorithms
      87             :  * in the dependency chain of nalg by unsetting n->dead.
      88             :  */
      89           1 : static struct list_head *crypto_more_spawns(struct crypto_alg *alg,
      90             :                                             struct list_head *stack,
      91             :                                             struct list_head *top,
      92             :                                             struct list_head *secondary_spawns)
      93             : {
      94           1 :         struct crypto_spawn *spawn, *n;
      95             : 
      96           1 :         spawn = list_first_entry_or_null(stack, struct crypto_spawn, list);
      97           0 :         if (!spawn)
      98             :                 return NULL;
      99             : 
     100           0 :         n = list_prev_entry(spawn, list);
     101           0 :         list_move(&spawn->list, secondary_spawns);
     102             : 
     103           0 :         if (list_is_last(&n->list, stack))
     104             :                 return top;
     105             : 
     106           0 :         n = list_next_entry(n, list);
     107           0 :         if (!spawn->dead)
     108           0 :                 n->dead = false;
     109             : 
     110           0 :         return &n->inst->alg.cra_users;
     111             : }
     112             : 
     113           0 : static void crypto_remove_instance(struct crypto_instance *inst,
     114             :                                    struct list_head *list)
     115             : {
     116           0 :         struct crypto_template *tmpl = inst->tmpl;
     117             : 
     118           0 :         if (crypto_is_dead(&inst->alg))
     119             :                 return;
     120             : 
     121           0 :         inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
     122             : 
     123           0 :         if (!tmpl || !crypto_tmpl_get(tmpl))
     124             :                 return;
     125             : 
     126           0 :         list_move(&inst->alg.cra_list, list);
     127           0 :         hlist_del(&inst->list);
     128           0 :         inst->alg.cra_destroy = crypto_destroy_instance;
     129             : 
     130           0 :         BUG_ON(!list_empty(&inst->alg.cra_users));
     131             : }
     132             : 
     133             : /*
     134             :  * Given an algorithm alg, remove all algorithms that depend on it
     135             :  * through spawns.  If nalg is not null, then exempt any algorithms
     136             :  * that is depended on by nalg.  This is useful when nalg itself
     137             :  * depends on alg.
     138             :  */
     139           1 : void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
     140             :                           struct crypto_alg *nalg)
     141             : {
     142           1 :         u32 new_type = (nalg ?: alg)->cra_flags;
     143           1 :         struct crypto_spawn *spawn, *n;
     144           1 :         LIST_HEAD(secondary_spawns);
     145           1 :         struct list_head *spawns;
     146           1 :         LIST_HEAD(stack);
     147           1 :         LIST_HEAD(top);
     148             : 
     149           1 :         spawns = &alg->cra_users;
     150           1 :         list_for_each_entry_safe(spawn, n, spawns, list) {
     151           0 :                 if ((spawn->alg->cra_flags ^ new_type) & spawn->mask)
     152           0 :                         continue;
     153             : 
     154           0 :                 list_move(&spawn->list, &top);
     155             :         }
     156             : 
     157             :         /*
     158             :          * Perform a depth-first walk starting from alg through
     159             :          * the cra_users tree.  The list stack records the path
     160             :          * from alg to the current spawn.
     161             :          */
     162             :         spawns = &top;
     163             :         do {
     164           1 :                 while (!list_empty(spawns)) {
     165           0 :                         struct crypto_instance *inst;
     166             : 
     167           0 :                         spawn = list_first_entry(spawns, struct crypto_spawn,
     168             :                                                  list);
     169           0 :                         inst = spawn->inst;
     170             : 
     171           0 :                         list_move(&spawn->list, &stack);
     172           0 :                         spawn->dead = !spawn->registered || &inst->alg != nalg;
     173             : 
     174           0 :                         if (!spawn->registered)
     175             :                                 break;
     176             : 
     177           0 :                         BUG_ON(&inst->alg == alg);
     178             : 
     179           0 :                         if (&inst->alg == nalg)
     180             :                                 break;
     181             : 
     182           0 :                         spawns = &inst->alg.cra_users;
     183             : 
     184             :                         /*
     185             :                          * Even if spawn->registered is true, the
     186             :                          * instance itself may still be unregistered.
     187             :                          * This is because it may have failed during
     188             :                          * registration.  Therefore we still need to
     189             :                          * make the following test.
     190             :                          *
     191             :                          * We may encounter an unregistered instance here, since
     192             :                          * an instance's spawns are set up prior to the instance
     193             :                          * being registered.  An unregistered instance will have
     194             :                          * NULL ->cra_users.next, since ->cra_users isn't
     195             :                          * properly initialized until registration.  But an
     196             :                          * unregistered instance cannot have any users, so treat
     197             :                          * it the same as ->cra_users being empty.
     198             :                          */
     199           0 :                         if (spawns->next == NULL)
     200             :                                 break;
     201             :                 }
     202           1 :         } while ((spawns = crypto_more_spawns(alg, &stack, &top,
     203           1 :                                               &secondary_spawns)));
     204             : 
     205             :         /*
     206             :          * Remove all instances that are marked as dead.  Also
     207             :          * complete the resurrection of the others by moving them
     208             :          * back to the cra_users list.
     209             :          */
     210           1 :         list_for_each_entry_safe(spawn, n, &secondary_spawns, list) {
     211           0 :                 if (!spawn->dead)
     212           0 :                         list_move(&spawn->list, &spawn->alg->cra_users);
     213           0 :                 else if (spawn->registered)
     214           0 :                         crypto_remove_instance(spawn->inst, list);
     215             :         }
     216           1 : }
     217             : EXPORT_SYMBOL_GPL(crypto_remove_spawns);
     218             : 
     219          10 : static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
     220             : {
     221          10 :         struct crypto_alg *q;
     222          10 :         struct crypto_larval *larval;
     223          10 :         int ret = -EAGAIN;
     224             : 
     225          10 :         if (crypto_is_dead(alg))
     226           0 :                 goto err;
     227             : 
     228          10 :         INIT_LIST_HEAD(&alg->cra_users);
     229             : 
     230             :         /* No cheating! */
     231          10 :         alg->cra_flags &= ~CRYPTO_ALG_TESTED;
     232             : 
     233          10 :         ret = -EEXIST;
     234             : 
     235          55 :         list_for_each_entry(q, &crypto_alg_list, cra_list) {
     236          45 :                 if (q == alg)
     237           0 :                         goto err;
     238             : 
     239          45 :                 if (crypto_is_moribund(q))
     240           0 :                         continue;
     241             : 
     242          45 :                 if (crypto_is_larval(q)) {
     243           0 :                         if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
     244           0 :                                 goto err;
     245           0 :                         continue;
     246             :                 }
     247             : 
     248          45 :                 if (!strcmp(q->cra_driver_name, alg->cra_name) ||
     249          45 :                     !strcmp(q->cra_name, alg->cra_driver_name))
     250           0 :                         goto err;
     251             :         }
     252             : 
     253          10 :         larval = crypto_larval_alloc(alg->cra_name,
     254             :                                      alg->cra_flags | CRYPTO_ALG_TESTED, 0);
     255          10 :         if (IS_ERR(larval))
     256           0 :                 goto out;
     257             : 
     258          10 :         ret = -ENOENT;
     259          10 :         larval->adult = crypto_mod_get(alg);
     260          10 :         if (!larval->adult)
     261           0 :                 goto free_larval;
     262             : 
     263          10 :         refcount_set(&larval->alg.cra_refcnt, 1);
     264          10 :         memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
     265             :                CRYPTO_MAX_ALG_NAME);
     266          10 :         larval->alg.cra_priority = alg->cra_priority;
     267             : 
     268          10 :         list_add(&alg->cra_list, &crypto_alg_list);
     269          10 :         list_add(&larval->alg.cra_list, &crypto_alg_list);
     270             : 
     271          10 :         crypto_stats_init(alg);
     272             : 
     273          10 : out:
     274          10 :         return larval;
     275             : 
     276           0 : free_larval:
     277           0 :         kfree(larval);
     278           0 : err:
     279           0 :         larval = ERR_PTR(ret);
     280           0 :         goto out;
     281             : }
     282             : 
     283          10 : void crypto_alg_tested(const char *name, int err)
     284             : {
     285          10 :         struct crypto_larval *test;
     286          10 :         struct crypto_alg *alg;
     287          10 :         struct crypto_alg *q;
     288          10 :         LIST_HEAD(list);
     289          10 :         bool best;
     290             : 
     291          10 :         down_write(&crypto_alg_sem);
     292          10 :         list_for_each_entry(q, &crypto_alg_list, cra_list) {
     293          10 :                 if (crypto_is_moribund(q) || !crypto_is_larval(q))
     294           0 :                         continue;
     295             : 
     296          10 :                 test = (struct crypto_larval *)q;
     297             : 
     298          10 :                 if (!strcmp(q->cra_driver_name, name))
     299          10 :                         goto found;
     300             :         }
     301             : 
     302           0 :         pr_err("alg: Unexpected test result for %s: %d\n", name, err);
     303           0 :         goto unlock;
     304             : 
     305          10 : found:
     306          10 :         q->cra_flags |= CRYPTO_ALG_DEAD;
     307          10 :         alg = test->adult;
     308          10 :         if (err || list_empty(&alg->cra_list))
     309           0 :                 goto complete;
     310             : 
     311          10 :         alg->cra_flags |= CRYPTO_ALG_TESTED;
     312             : 
     313             :         /* Only satisfy larval waiters if we are the best. */
     314          10 :         best = true;
     315          75 :         list_for_each_entry(q, &crypto_alg_list, cra_list) {
     316          65 :                 if (crypto_is_moribund(q) || !crypto_is_larval(q))
     317          65 :                         continue;
     318             : 
     319           0 :                 if (strcmp(alg->cra_name, q->cra_name))
     320           0 :                         continue;
     321             : 
     322           0 :                 if (q->cra_priority > alg->cra_priority) {
     323             :                         best = false;
     324             :                         break;
     325             :                 }
     326             :         }
     327             : 
     328          75 :         list_for_each_entry(q, &crypto_alg_list, cra_list) {
     329          65 :                 if (q == alg)
     330          10 :                         continue;
     331             : 
     332          55 :                 if (crypto_is_moribund(q))
     333          10 :                         continue;
     334             : 
     335          45 :                 if (crypto_is_larval(q)) {
     336           0 :                         struct crypto_larval *larval = (void *)q;
     337             : 
     338             :                         /*
     339             :                          * Check to see if either our generic name or
     340             :                          * specific name can satisfy the name requested
     341             :                          * by the larval entry q.
     342             :                          */
     343           0 :                         if (strcmp(alg->cra_name, q->cra_name) &&
     344           0 :                             strcmp(alg->cra_driver_name, q->cra_name))
     345           0 :                                 continue;
     346             : 
     347           0 :                         if (larval->adult)
     348           0 :                                 continue;
     349           0 :                         if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
     350           0 :                                 continue;
     351             : 
     352           0 :                         if (best && crypto_mod_get(alg))
     353           0 :                                 larval->adult = alg;
     354             :                         else
     355           0 :                                 larval->adult = ERR_PTR(-EAGAIN);
     356             : 
     357           0 :                         continue;
     358             :                 }
     359             : 
     360          45 :                 if (strcmp(alg->cra_name, q->cra_name))
     361          44 :                         continue;
     362             : 
     363           1 :                 if (strcmp(alg->cra_driver_name, q->cra_driver_name) &&
     364           1 :                     q->cra_priority > alg->cra_priority)
     365           0 :                         continue;
     366             : 
     367           1 :                 crypto_remove_spawns(q, &list, alg);
     368             :         }
     369             : 
     370          10 : complete:
     371          10 :         complete_all(&test->completion);
     372             : 
     373          10 : unlock:
     374          10 :         up_write(&crypto_alg_sem);
     375             : 
     376          10 :         crypto_remove_final(&list);
     377          10 : }
     378             : EXPORT_SYMBOL_GPL(crypto_alg_tested);
     379             : 
     380          10 : void crypto_remove_final(struct list_head *list)
     381             : {
     382          10 :         struct crypto_alg *alg;
     383          10 :         struct crypto_alg *n;
     384             : 
     385          10 :         list_for_each_entry_safe(alg, n, list, cra_list) {
     386           0 :                 list_del_init(&alg->cra_list);
     387           0 :                 crypto_alg_put(alg);
     388             :         }
     389          10 : }
     390             : EXPORT_SYMBOL_GPL(crypto_remove_final);
     391             : 
     392          10 : static void crypto_wait_for_test(struct crypto_larval *larval)
     393             : {
     394          10 :         int err;
     395             : 
     396          10 :         err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
     397          10 :         if (err != NOTIFY_STOP) {
     398          10 :                 if (WARN_ON(err != NOTIFY_DONE))
     399           0 :                         goto out;
     400          10 :                 crypto_alg_tested(larval->alg.cra_driver_name, 0);
     401             :         }
     402             : 
     403          10 :         err = wait_for_completion_killable(&larval->completion);
     404          10 :         WARN_ON(err);
     405          10 :         if (!err)
     406          10 :                 crypto_notify(CRYPTO_MSG_ALG_LOADED, larval);
     407             : 
     408           0 : out:
     409          10 :         crypto_larval_kill(&larval->alg);
     410          10 : }
     411             : 
     412          10 : int crypto_register_alg(struct crypto_alg *alg)
     413             : {
     414          10 :         struct crypto_larval *larval;
     415          10 :         int err;
     416             : 
     417          10 :         alg->cra_flags &= ~CRYPTO_ALG_DEAD;
     418          10 :         err = crypto_check_alg(alg);
     419          10 :         if (err)
     420             :                 return err;
     421             : 
     422          10 :         down_write(&crypto_alg_sem);
     423          10 :         larval = __crypto_register_alg(alg);
     424          10 :         up_write(&crypto_alg_sem);
     425             : 
     426          10 :         if (IS_ERR(larval))
     427           0 :                 return PTR_ERR(larval);
     428             : 
     429          10 :         crypto_wait_for_test(larval);
     430          10 :         return 0;
     431             : }
     432             : EXPORT_SYMBOL_GPL(crypto_register_alg);
     433             : 
     434           0 : static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list)
     435             : {
     436           0 :         if (unlikely(list_empty(&alg->cra_list)))
     437             :                 return -ENOENT;
     438             : 
     439           0 :         alg->cra_flags |= CRYPTO_ALG_DEAD;
     440             : 
     441           0 :         list_del_init(&alg->cra_list);
     442           0 :         crypto_remove_spawns(alg, list, NULL);
     443             : 
     444           0 :         return 0;
     445             : }
     446             : 
     447           0 : void crypto_unregister_alg(struct crypto_alg *alg)
     448             : {
     449           0 :         int ret;
     450           0 :         LIST_HEAD(list);
     451             : 
     452           0 :         down_write(&crypto_alg_sem);
     453           0 :         ret = crypto_remove_alg(alg, &list);
     454           0 :         up_write(&crypto_alg_sem);
     455             : 
     456           0 :         if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name))
     457           0 :                 return;
     458             : 
     459           0 :         BUG_ON(refcount_read(&alg->cra_refcnt) != 1);
     460           0 :         if (alg->cra_destroy)
     461           0 :                 alg->cra_destroy(alg);
     462             : 
     463           0 :         crypto_remove_final(&list);
     464             : }
     465             : EXPORT_SYMBOL_GPL(crypto_unregister_alg);
     466             : 
     467           1 : int crypto_register_algs(struct crypto_alg *algs, int count)
     468             : {
     469           1 :         int i, ret;
     470             : 
     471           3 :         for (i = 0; i < count; i++) {
     472           2 :                 ret = crypto_register_alg(&algs[i]);
     473           2 :                 if (ret)
     474           0 :                         goto err;
     475             :         }
     476             : 
     477             :         return 0;
     478             : 
     479           0 : err:
     480           0 :         for (--i; i >= 0; --i)
     481           0 :                 crypto_unregister_alg(&algs[i]);
     482             : 
     483             :         return ret;
     484             : }
     485             : EXPORT_SYMBOL_GPL(crypto_register_algs);
     486             : 
     487           0 : void crypto_unregister_algs(struct crypto_alg *algs, int count)
     488             : {
     489           0 :         int i;
     490             : 
     491           0 :         for (i = 0; i < count; i++)
     492           0 :                 crypto_unregister_alg(&algs[i]);
     493           0 : }
     494             : EXPORT_SYMBOL_GPL(crypto_unregister_algs);
     495             : 
     496           0 : int crypto_register_template(struct crypto_template *tmpl)
     497             : {
     498           0 :         struct crypto_template *q;
     499           0 :         int err = -EEXIST;
     500             : 
     501           0 :         down_write(&crypto_alg_sem);
     502             : 
     503           0 :         crypto_check_module_sig(tmpl->module);
     504             : 
     505           0 :         list_for_each_entry(q, &crypto_template_list, list) {
     506           0 :                 if (q == tmpl)
     507           0 :                         goto out;
     508             :         }
     509             : 
     510           0 :         list_add(&tmpl->list, &crypto_template_list);
     511           0 :         err = 0;
     512           0 : out:
     513           0 :         up_write(&crypto_alg_sem);
     514           0 :         return err;
     515             : }
     516             : EXPORT_SYMBOL_GPL(crypto_register_template);
     517             : 
     518           0 : int crypto_register_templates(struct crypto_template *tmpls, int count)
     519             : {
     520           0 :         int i, err;
     521             : 
     522           0 :         for (i = 0; i < count; i++) {
     523           0 :                 err = crypto_register_template(&tmpls[i]);
     524           0 :                 if (err)
     525           0 :                         goto out;
     526             :         }
     527             :         return 0;
     528             : 
     529           0 : out:
     530           0 :         for (--i; i >= 0; --i)
     531           0 :                 crypto_unregister_template(&tmpls[i]);
     532             :         return err;
     533             : }
     534             : EXPORT_SYMBOL_GPL(crypto_register_templates);
     535             : 
     536           0 : void crypto_unregister_template(struct crypto_template *tmpl)
     537             : {
     538           0 :         struct crypto_instance *inst;
     539           0 :         struct hlist_node *n;
     540           0 :         struct hlist_head *list;
     541           0 :         LIST_HEAD(users);
     542             : 
     543           0 :         down_write(&crypto_alg_sem);
     544             : 
     545           0 :         BUG_ON(list_empty(&tmpl->list));
     546           0 :         list_del_init(&tmpl->list);
     547             : 
     548           0 :         list = &tmpl->instances;
     549           0 :         hlist_for_each_entry(inst, list, list) {
     550           0 :                 int err = crypto_remove_alg(&inst->alg, &users);
     551             : 
     552           0 :                 BUG_ON(err);
     553             :         }
     554             : 
     555           0 :         up_write(&crypto_alg_sem);
     556             : 
     557           0 :         hlist_for_each_entry_safe(inst, n, list, list) {
     558           0 :                 BUG_ON(refcount_read(&inst->alg.cra_refcnt) != 1);
     559           0 :                 crypto_free_instance(inst);
     560             :         }
     561           0 :         crypto_remove_final(&users);
     562           0 : }
     563             : EXPORT_SYMBOL_GPL(crypto_unregister_template);
     564             : 
     565           0 : void crypto_unregister_templates(struct crypto_template *tmpls, int count)
     566             : {
     567           0 :         int i;
     568             : 
     569           0 :         for (i = count - 1; i >= 0; --i)
     570           0 :                 crypto_unregister_template(&tmpls[i]);
     571           0 : }
     572             : EXPORT_SYMBOL_GPL(crypto_unregister_templates);
     573             : 
     574           0 : static struct crypto_template *__crypto_lookup_template(const char *name)
     575             : {
     576           0 :         struct crypto_template *q, *tmpl = NULL;
     577             : 
     578           0 :         down_read(&crypto_alg_sem);
     579           0 :         list_for_each_entry(q, &crypto_template_list, list) {
     580           0 :                 if (strcmp(q->name, name))
     581           0 :                         continue;
     582           0 :                 if (unlikely(!crypto_tmpl_get(q)))
     583             :                         continue;
     584             : 
     585             :                 tmpl = q;
     586             :                 break;
     587             :         }
     588           0 :         up_read(&crypto_alg_sem);
     589             : 
     590           0 :         return tmpl;
     591             : }
     592             : 
     593           0 : struct crypto_template *crypto_lookup_template(const char *name)
     594             : {
     595           0 :         return try_then_request_module(__crypto_lookup_template(name),
     596             :                                        "crypto-%s", name);
     597             : }
     598             : EXPORT_SYMBOL_GPL(crypto_lookup_template);
     599             : 
     600           0 : int crypto_register_instance(struct crypto_template *tmpl,
     601             :                              struct crypto_instance *inst)
     602             : {
     603           0 :         struct crypto_larval *larval;
     604           0 :         struct crypto_spawn *spawn;
     605           0 :         int err;
     606             : 
     607           0 :         err = crypto_check_alg(&inst->alg);
     608           0 :         if (err)
     609             :                 return err;
     610             : 
     611           0 :         inst->alg.cra_module = tmpl->module;
     612           0 :         inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
     613             : 
     614           0 :         down_write(&crypto_alg_sem);
     615             : 
     616           0 :         larval = ERR_PTR(-EAGAIN);
     617           0 :         for (spawn = inst->spawns; spawn;) {
     618           0 :                 struct crypto_spawn *next;
     619             : 
     620           0 :                 if (spawn->dead)
     621           0 :                         goto unlock;
     622             : 
     623           0 :                 next = spawn->next;
     624           0 :                 spawn->inst = inst;
     625           0 :                 spawn->registered = true;
     626             : 
     627           0 :                 crypto_mod_put(spawn->alg);
     628             : 
     629           0 :                 spawn = next;
     630             :         }
     631             : 
     632           0 :         larval = __crypto_register_alg(&inst->alg);
     633           0 :         if (IS_ERR(larval))
     634           0 :                 goto unlock;
     635             : 
     636           0 :         hlist_add_head(&inst->list, &tmpl->instances);
     637           0 :         inst->tmpl = tmpl;
     638             : 
     639           0 : unlock:
     640           0 :         up_write(&crypto_alg_sem);
     641             : 
     642           0 :         err = PTR_ERR(larval);
     643           0 :         if (IS_ERR(larval))
     644           0 :                 goto err;
     645             : 
     646           0 :         crypto_wait_for_test(larval);
     647           0 :         err = 0;
     648             : 
     649             : err:
     650             :         return err;
     651             : }
     652             : EXPORT_SYMBOL_GPL(crypto_register_instance);
     653             : 
     654           0 : void crypto_unregister_instance(struct crypto_instance *inst)
     655             : {
     656           0 :         LIST_HEAD(list);
     657             : 
     658           0 :         down_write(&crypto_alg_sem);
     659             : 
     660           0 :         crypto_remove_spawns(&inst->alg, &list, NULL);
     661           0 :         crypto_remove_instance(inst, &list);
     662             : 
     663           0 :         up_write(&crypto_alg_sem);
     664             : 
     665           0 :         crypto_remove_final(&list);
     666           0 : }
     667             : EXPORT_SYMBOL_GPL(crypto_unregister_instance);
     668             : 
     669           0 : int crypto_grab_spawn(struct crypto_spawn *spawn, struct crypto_instance *inst,
     670             :                       const char *name, u32 type, u32 mask)
     671             : {
     672           0 :         struct crypto_alg *alg;
     673           0 :         int err = -EAGAIN;
     674             : 
     675           0 :         if (WARN_ON_ONCE(inst == NULL))
     676             :                 return -EINVAL;
     677             : 
     678             :         /* Allow the result of crypto_attr_alg_name() to be passed directly */
     679           0 :         if (IS_ERR(name))
     680           0 :                 return PTR_ERR(name);
     681             : 
     682           0 :         alg = crypto_find_alg(name, spawn->frontend, type, mask);
     683           0 :         if (IS_ERR(alg))
     684           0 :                 return PTR_ERR(alg);
     685             : 
     686           0 :         down_write(&crypto_alg_sem);
     687           0 :         if (!crypto_is_moribund(alg)) {
     688           0 :                 list_add(&spawn->list, &alg->cra_users);
     689           0 :                 spawn->alg = alg;
     690           0 :                 spawn->mask = mask;
     691           0 :                 spawn->next = inst->spawns;
     692           0 :                 inst->spawns = spawn;
     693           0 :                 inst->alg.cra_flags |=
     694           0 :                         (alg->cra_flags & CRYPTO_ALG_INHERITED_FLAGS);
     695           0 :                 err = 0;
     696             :         }
     697           0 :         up_write(&crypto_alg_sem);
     698           0 :         if (err)
     699           0 :                 crypto_mod_put(alg);
     700             :         return err;
     701             : }
     702             : EXPORT_SYMBOL_GPL(crypto_grab_spawn);
     703             : 
     704           0 : void crypto_drop_spawn(struct crypto_spawn *spawn)
     705             : {
     706           0 :         if (!spawn->alg) /* not yet initialized? */
     707             :                 return;
     708             : 
     709           0 :         down_write(&crypto_alg_sem);
     710           0 :         if (!spawn->dead)
     711           0 :                 list_del(&spawn->list);
     712           0 :         up_write(&crypto_alg_sem);
     713             : 
     714           0 :         if (!spawn->registered)
     715           0 :                 crypto_mod_put(spawn->alg);
     716             : }
     717             : EXPORT_SYMBOL_GPL(crypto_drop_spawn);
     718             : 
     719           0 : static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
     720             : {
     721           0 :         struct crypto_alg *alg = ERR_PTR(-EAGAIN);
     722           0 :         struct crypto_alg *target;
     723           0 :         bool shoot = false;
     724             : 
     725           0 :         down_read(&crypto_alg_sem);
     726           0 :         if (!spawn->dead) {
     727           0 :                 alg = spawn->alg;
     728           0 :                 if (!crypto_mod_get(alg)) {
     729           0 :                         target = crypto_alg_get(alg);
     730           0 :                         shoot = true;
     731           0 :                         alg = ERR_PTR(-EAGAIN);
     732             :                 }
     733             :         }
     734           0 :         up_read(&crypto_alg_sem);
     735             : 
     736           0 :         if (shoot) {
     737           0 :                 crypto_shoot_alg(target);
     738           0 :                 crypto_alg_put(target);
     739             :         }
     740             : 
     741           0 :         return alg;
     742             : }
     743             : 
     744           0 : struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
     745             :                                     u32 mask)
     746             : {
     747           0 :         struct crypto_alg *alg;
     748           0 :         struct crypto_tfm *tfm;
     749             : 
     750           0 :         alg = crypto_spawn_alg(spawn);
     751           0 :         if (IS_ERR(alg))
     752           0 :                 return ERR_CAST(alg);
     753             : 
     754           0 :         tfm = ERR_PTR(-EINVAL);
     755           0 :         if (unlikely((alg->cra_flags ^ type) & mask))
     756           0 :                 goto out_put_alg;
     757             : 
     758           0 :         tfm = __crypto_alloc_tfm(alg, type, mask);
     759           0 :         if (IS_ERR(tfm))
     760           0 :                 goto out_put_alg;
     761             : 
     762             :         return tfm;
     763             : 
     764           0 : out_put_alg:
     765           0 :         crypto_mod_put(alg);
     766           0 :         return tfm;
     767             : }
     768             : EXPORT_SYMBOL_GPL(crypto_spawn_tfm);
     769             : 
     770           0 : void *crypto_spawn_tfm2(struct crypto_spawn *spawn)
     771             : {
     772           0 :         struct crypto_alg *alg;
     773           0 :         struct crypto_tfm *tfm;
     774             : 
     775           0 :         alg = crypto_spawn_alg(spawn);
     776           0 :         if (IS_ERR(alg))
     777           0 :                 return ERR_CAST(alg);
     778             : 
     779           0 :         tfm = crypto_create_tfm(alg, spawn->frontend);
     780           0 :         if (IS_ERR(tfm))
     781           0 :                 goto out_put_alg;
     782             : 
     783             :         return tfm;
     784             : 
     785           0 : out_put_alg:
     786           0 :         crypto_mod_put(alg);
     787           0 :         return tfm;
     788             : }
     789             : EXPORT_SYMBOL_GPL(crypto_spawn_tfm2);
     790             : 
     791           0 : int crypto_register_notifier(struct notifier_block *nb)
     792             : {
     793           0 :         return blocking_notifier_chain_register(&crypto_chain, nb);
     794             : }
     795             : EXPORT_SYMBOL_GPL(crypto_register_notifier);
     796             : 
     797           0 : int crypto_unregister_notifier(struct notifier_block *nb)
     798             : {
     799           0 :         return blocking_notifier_chain_unregister(&crypto_chain, nb);
     800             : }
     801             : EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
     802             : 
     803           0 : struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
     804             : {
     805           0 :         struct rtattr *rta = tb[0];
     806           0 :         struct crypto_attr_type *algt;
     807             : 
     808           0 :         if (!rta)
     809           0 :                 return ERR_PTR(-ENOENT);
     810           0 :         if (RTA_PAYLOAD(rta) < sizeof(*algt))
     811           0 :                 return ERR_PTR(-EINVAL);
     812           0 :         if (rta->rta_type != CRYPTOA_TYPE)
     813           0 :                 return ERR_PTR(-EINVAL);
     814             : 
     815           0 :         algt = RTA_DATA(rta);
     816             : 
     817           0 :         return algt;
     818             : }
     819             : EXPORT_SYMBOL_GPL(crypto_get_attr_type);
     820             : 
     821             : /**
     822             :  * crypto_check_attr_type() - check algorithm type and compute inherited mask
     823             :  * @tb: the template parameters
     824             :  * @type: the algorithm type the template would be instantiated as
     825             :  * @mask_ret: (output) the mask that should be passed to crypto_grab_*()
     826             :  *            to restrict the flags of any inner algorithms
     827             :  *
     828             :  * Validate that the algorithm type the user requested is compatible with the
     829             :  * one the template would actually be instantiated as.  E.g., if the user is
     830             :  * doing crypto_alloc_shash("cbc(aes)", ...), this would return an error because
     831             :  * the "cbc" template creates an "skcipher" algorithm, not an "shash" algorithm.
     832             :  *
     833             :  * Also compute the mask to use to restrict the flags of any inner algorithms.
     834             :  *
     835             :  * Return: 0 on success; -errno on failure
     836             :  */
     837           0 : int crypto_check_attr_type(struct rtattr **tb, u32 type, u32 *mask_ret)
     838             : {
     839           0 :         struct crypto_attr_type *algt;
     840             : 
     841           0 :         algt = crypto_get_attr_type(tb);
     842           0 :         if (IS_ERR(algt))
     843           0 :                 return PTR_ERR(algt);
     844             : 
     845           0 :         if ((algt->type ^ type) & algt->mask)
     846             :                 return -EINVAL;
     847             : 
     848           0 :         *mask_ret = crypto_algt_inherited_mask(algt);
     849           0 :         return 0;
     850             : }
     851             : EXPORT_SYMBOL_GPL(crypto_check_attr_type);
     852             : 
     853           0 : const char *crypto_attr_alg_name(struct rtattr *rta)
     854             : {
     855           0 :         struct crypto_attr_alg *alga;
     856             : 
     857           0 :         if (!rta)
     858           0 :                 return ERR_PTR(-ENOENT);
     859           0 :         if (RTA_PAYLOAD(rta) < sizeof(*alga))
     860           0 :                 return ERR_PTR(-EINVAL);
     861           0 :         if (rta->rta_type != CRYPTOA_ALG)
     862           0 :                 return ERR_PTR(-EINVAL);
     863             : 
     864           0 :         alga = RTA_DATA(rta);
     865           0 :         alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
     866             : 
     867           0 :         return alga->name;
     868             : }
     869             : EXPORT_SYMBOL_GPL(crypto_attr_alg_name);
     870             : 
     871           0 : int crypto_attr_u32(struct rtattr *rta, u32 *num)
     872             : {
     873           0 :         struct crypto_attr_u32 *nu32;
     874             : 
     875           0 :         if (!rta)
     876             :                 return -ENOENT;
     877           0 :         if (RTA_PAYLOAD(rta) < sizeof(*nu32))
     878             :                 return -EINVAL;
     879           0 :         if (rta->rta_type != CRYPTOA_U32)
     880             :                 return -EINVAL;
     881             : 
     882           0 :         nu32 = RTA_DATA(rta);
     883           0 :         *num = nu32->num;
     884             : 
     885           0 :         return 0;
     886             : }
     887             : EXPORT_SYMBOL_GPL(crypto_attr_u32);
     888             : 
     889           0 : int crypto_inst_setname(struct crypto_instance *inst, const char *name,
     890             :                         struct crypto_alg *alg)
     891             : {
     892           0 :         if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", name,
     893           0 :                      alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
     894             :                 return -ENAMETOOLONG;
     895             : 
     896           0 :         if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
     897           0 :                      name, alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
     898           0 :                 return -ENAMETOOLONG;
     899             : 
     900             :         return 0;
     901             : }
     902             : EXPORT_SYMBOL_GPL(crypto_inst_setname);
     903             : 
     904           0 : void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen)
     905             : {
     906           0 :         INIT_LIST_HEAD(&queue->list);
     907           0 :         queue->backlog = &queue->list;
     908           0 :         queue->qlen = 0;
     909           0 :         queue->max_qlen = max_qlen;
     910           0 : }
     911             : EXPORT_SYMBOL_GPL(crypto_init_queue);
     912             : 
     913           0 : int crypto_enqueue_request(struct crypto_queue *queue,
     914             :                            struct crypto_async_request *request)
     915             : {
     916           0 :         int err = -EINPROGRESS;
     917             : 
     918           0 :         if (unlikely(queue->qlen >= queue->max_qlen)) {
     919           0 :                 if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
     920           0 :                         err = -ENOSPC;
     921           0 :                         goto out;
     922             :                 }
     923           0 :                 err = -EBUSY;
     924           0 :                 if (queue->backlog == &queue->list)
     925           0 :                         queue->backlog = &request->list;
     926             :         }
     927             : 
     928           0 :         queue->qlen++;
     929           0 :         list_add_tail(&request->list, &queue->list);
     930             : 
     931           0 : out:
     932           0 :         return err;
     933             : }
     934             : EXPORT_SYMBOL_GPL(crypto_enqueue_request);
     935             : 
     936           0 : void crypto_enqueue_request_head(struct crypto_queue *queue,
     937             :                                  struct crypto_async_request *request)
     938             : {
     939           0 :         queue->qlen++;
     940           0 :         list_add(&request->list, &queue->list);
     941           0 : }
     942             : EXPORT_SYMBOL_GPL(crypto_enqueue_request_head);
     943             : 
     944           0 : struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
     945             : {
     946           0 :         struct list_head *request;
     947             : 
     948           0 :         if (unlikely(!queue->qlen))
     949             :                 return NULL;
     950             : 
     951           0 :         queue->qlen--;
     952             : 
     953           0 :         if (queue->backlog != &queue->list)
     954           0 :                 queue->backlog = queue->backlog->next;
     955             : 
     956           0 :         request = queue->list.next;
     957           0 :         list_del(request);
     958             : 
     959           0 :         return list_entry(request, struct crypto_async_request, list);
     960             : }
     961             : EXPORT_SYMBOL_GPL(crypto_dequeue_request);
     962             : 
     963           0 : static inline void crypto_inc_byte(u8 *a, unsigned int size)
     964             : {
     965           0 :         u8 *b = (a + size);
     966           0 :         u8 c;
     967             : 
     968           0 :         for (; size; size--) {
     969           0 :                 c = *--b + 1;
     970           0 :                 *b = c;
     971           0 :                 if (c)
     972             :                         break;
     973             :         }
     974           0 : }
     975             : 
     976           0 : void crypto_inc(u8 *a, unsigned int size)
     977             : {
     978           0 :         __be32 *b = (__be32 *)(a + size);
     979           0 :         u32 c;
     980             : 
     981           0 :         if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
     982             :             IS_ALIGNED((unsigned long)b, __alignof__(*b)))
     983           0 :                 for (; size >= 4; size -= 4) {
     984           0 :                         c = be32_to_cpu(*--b) + 1;
     985           0 :                         *b = cpu_to_be32(c);
     986           0 :                         if (likely(c))
     987             :                                 return;
     988             :                 }
     989             : 
     990           0 :         crypto_inc_byte(a, size);
     991             : }
     992             : EXPORT_SYMBOL_GPL(crypto_inc);
     993             : 
     994           0 : void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len)
     995             : {
     996           0 :         int relalign = 0;
     997             : 
     998           0 :         if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
     999             :                 int size = sizeof(unsigned long);
    1000             :                 int d = (((unsigned long)dst ^ (unsigned long)src1) |
    1001             :                          ((unsigned long)dst ^ (unsigned long)src2)) &
    1002             :                         (size - 1);
    1003             : 
    1004             :                 relalign = d ? 1 << __ffs(d) : size;
    1005             : 
    1006             :                 /*
    1007             :                  * If we care about alignment, process as many bytes as
    1008             :                  * needed to advance dst and src to values whose alignments
    1009             :                  * equal their relative alignment. This will allow us to
    1010             :                  * process the remainder of the input using optimal strides.
    1011             :                  */
    1012             :                 while (((unsigned long)dst & (relalign - 1)) && len > 0) {
    1013             :                         *dst++ = *src1++ ^ *src2++;
    1014             :                         len--;
    1015             :                 }
    1016             :         }
    1017             : 
    1018           0 :         while (IS_ENABLED(CONFIG_64BIT) && len >= 8 && !(relalign & 7)) {
    1019           0 :                 *(u64 *)dst = *(u64 *)src1 ^  *(u64 *)src2;
    1020           0 :                 dst += 8;
    1021           0 :                 src1 += 8;
    1022           0 :                 src2 += 8;
    1023           0 :                 len -= 8;
    1024             :         }
    1025             : 
    1026           0 :         while (len >= 4 && !(relalign & 3)) {
    1027           0 :                 *(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
    1028           0 :                 dst += 4;
    1029           0 :                 src1 += 4;
    1030           0 :                 src2 += 4;
    1031           0 :                 len -= 4;
    1032             :         }
    1033             : 
    1034           0 :         while (len >= 2 && !(relalign & 1)) {
    1035           0 :                 *(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
    1036           0 :                 dst += 2;
    1037           0 :                 src1 += 2;
    1038           0 :                 src2 += 2;
    1039           0 :                 len -= 2;
    1040             :         }
    1041             : 
    1042           0 :         while (len--)
    1043           0 :                 *dst++ = *src1++ ^ *src2++;
    1044           0 : }
    1045             : EXPORT_SYMBOL_GPL(__crypto_xor);
    1046             : 
    1047           2 : unsigned int crypto_alg_extsize(struct crypto_alg *alg)
    1048             : {
    1049           2 :         return alg->cra_ctxsize +
    1050           2 :                (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1));
    1051             : }
    1052             : EXPORT_SYMBOL_GPL(crypto_alg_extsize);
    1053             : 
    1054           0 : int crypto_type_has_alg(const char *name, const struct crypto_type *frontend,
    1055             :                         u32 type, u32 mask)
    1056             : {
    1057           0 :         int ret = 0;
    1058           0 :         struct crypto_alg *alg = crypto_find_alg(name, frontend, type, mask);
    1059             : 
    1060           0 :         if (!IS_ERR(alg)) {
    1061           0 :                 crypto_mod_put(alg);
    1062           0 :                 ret = 1;
    1063             :         }
    1064             : 
    1065           0 :         return ret;
    1066             : }
    1067             : EXPORT_SYMBOL_GPL(crypto_type_has_alg);
    1068             : 
    1069             : #ifdef CONFIG_CRYPTO_STATS
    1070             : void crypto_stats_init(struct crypto_alg *alg)
    1071             : {
    1072             :         memset(&alg->stats, 0, sizeof(alg->stats));
    1073             : }
    1074             : EXPORT_SYMBOL_GPL(crypto_stats_init);
    1075             : 
    1076             : void crypto_stats_get(struct crypto_alg *alg)
    1077             : {
    1078             :         crypto_alg_get(alg);
    1079             : }
    1080             : EXPORT_SYMBOL_GPL(crypto_stats_get);
    1081             : 
    1082             : void crypto_stats_aead_encrypt(unsigned int cryptlen, struct crypto_alg *alg,
    1083             :                                int ret)
    1084             : {
    1085             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1086             :                 atomic64_inc(&alg->stats.aead.err_cnt);
    1087             :         } else {
    1088             :                 atomic64_inc(&alg->stats.aead.encrypt_cnt);
    1089             :                 atomic64_add(cryptlen, &alg->stats.aead.encrypt_tlen);
    1090             :         }
    1091             :         crypto_alg_put(alg);
    1092             : }
    1093             : EXPORT_SYMBOL_GPL(crypto_stats_aead_encrypt);
    1094             : 
    1095             : void crypto_stats_aead_decrypt(unsigned int cryptlen, struct crypto_alg *alg,
    1096             :                                int ret)
    1097             : {
    1098             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1099             :                 atomic64_inc(&alg->stats.aead.err_cnt);
    1100             :         } else {
    1101             :                 atomic64_inc(&alg->stats.aead.decrypt_cnt);
    1102             :                 atomic64_add(cryptlen, &alg->stats.aead.decrypt_tlen);
    1103             :         }
    1104             :         crypto_alg_put(alg);
    1105             : }
    1106             : EXPORT_SYMBOL_GPL(crypto_stats_aead_decrypt);
    1107             : 
    1108             : void crypto_stats_akcipher_encrypt(unsigned int src_len, int ret,
    1109             :                                    struct crypto_alg *alg)
    1110             : {
    1111             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1112             :                 atomic64_inc(&alg->stats.akcipher.err_cnt);
    1113             :         } else {
    1114             :                 atomic64_inc(&alg->stats.akcipher.encrypt_cnt);
    1115             :                 atomic64_add(src_len, &alg->stats.akcipher.encrypt_tlen);
    1116             :         }
    1117             :         crypto_alg_put(alg);
    1118             : }
    1119             : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_encrypt);
    1120             : 
    1121             : void crypto_stats_akcipher_decrypt(unsigned int src_len, int ret,
    1122             :                                    struct crypto_alg *alg)
    1123             : {
    1124             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1125             :                 atomic64_inc(&alg->stats.akcipher.err_cnt);
    1126             :         } else {
    1127             :                 atomic64_inc(&alg->stats.akcipher.decrypt_cnt);
    1128             :                 atomic64_add(src_len, &alg->stats.akcipher.decrypt_tlen);
    1129             :         }
    1130             :         crypto_alg_put(alg);
    1131             : }
    1132             : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_decrypt);
    1133             : 
    1134             : void crypto_stats_akcipher_sign(int ret, struct crypto_alg *alg)
    1135             : {
    1136             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY)
    1137             :                 atomic64_inc(&alg->stats.akcipher.err_cnt);
    1138             :         else
    1139             :                 atomic64_inc(&alg->stats.akcipher.sign_cnt);
    1140             :         crypto_alg_put(alg);
    1141             : }
    1142             : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_sign);
    1143             : 
    1144             : void crypto_stats_akcipher_verify(int ret, struct crypto_alg *alg)
    1145             : {
    1146             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY)
    1147             :                 atomic64_inc(&alg->stats.akcipher.err_cnt);
    1148             :         else
    1149             :                 atomic64_inc(&alg->stats.akcipher.verify_cnt);
    1150             :         crypto_alg_put(alg);
    1151             : }
    1152             : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_verify);
    1153             : 
    1154             : void crypto_stats_compress(unsigned int slen, int ret, struct crypto_alg *alg)
    1155             : {
    1156             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1157             :                 atomic64_inc(&alg->stats.compress.err_cnt);
    1158             :         } else {
    1159             :                 atomic64_inc(&alg->stats.compress.compress_cnt);
    1160             :                 atomic64_add(slen, &alg->stats.compress.compress_tlen);
    1161             :         }
    1162             :         crypto_alg_put(alg);
    1163             : }
    1164             : EXPORT_SYMBOL_GPL(crypto_stats_compress);
    1165             : 
    1166             : void crypto_stats_decompress(unsigned int slen, int ret, struct crypto_alg *alg)
    1167             : {
    1168             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1169             :                 atomic64_inc(&alg->stats.compress.err_cnt);
    1170             :         } else {
    1171             :                 atomic64_inc(&alg->stats.compress.decompress_cnt);
    1172             :                 atomic64_add(slen, &alg->stats.compress.decompress_tlen);
    1173             :         }
    1174             :         crypto_alg_put(alg);
    1175             : }
    1176             : EXPORT_SYMBOL_GPL(crypto_stats_decompress);
    1177             : 
    1178             : void crypto_stats_ahash_update(unsigned int nbytes, int ret,
    1179             :                                struct crypto_alg *alg)
    1180             : {
    1181             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY)
    1182             :                 atomic64_inc(&alg->stats.hash.err_cnt);
    1183             :         else
    1184             :                 atomic64_add(nbytes, &alg->stats.hash.hash_tlen);
    1185             :         crypto_alg_put(alg);
    1186             : }
    1187             : EXPORT_SYMBOL_GPL(crypto_stats_ahash_update);
    1188             : 
    1189             : void crypto_stats_ahash_final(unsigned int nbytes, int ret,
    1190             :                               struct crypto_alg *alg)
    1191             : {
    1192             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1193             :                 atomic64_inc(&alg->stats.hash.err_cnt);
    1194             :         } else {
    1195             :                 atomic64_inc(&alg->stats.hash.hash_cnt);
    1196             :                 atomic64_add(nbytes, &alg->stats.hash.hash_tlen);
    1197             :         }
    1198             :         crypto_alg_put(alg);
    1199             : }
    1200             : EXPORT_SYMBOL_GPL(crypto_stats_ahash_final);
    1201             : 
    1202             : void crypto_stats_kpp_set_secret(struct crypto_alg *alg, int ret)
    1203             : {
    1204             :         if (ret)
    1205             :                 atomic64_inc(&alg->stats.kpp.err_cnt);
    1206             :         else
    1207             :                 atomic64_inc(&alg->stats.kpp.setsecret_cnt);
    1208             :         crypto_alg_put(alg);
    1209             : }
    1210             : EXPORT_SYMBOL_GPL(crypto_stats_kpp_set_secret);
    1211             : 
    1212             : void crypto_stats_kpp_generate_public_key(struct crypto_alg *alg, int ret)
    1213             : {
    1214             :         if (ret)
    1215             :                 atomic64_inc(&alg->stats.kpp.err_cnt);
    1216             :         else
    1217             :                 atomic64_inc(&alg->stats.kpp.generate_public_key_cnt);
    1218             :         crypto_alg_put(alg);
    1219             : }
    1220             : EXPORT_SYMBOL_GPL(crypto_stats_kpp_generate_public_key);
    1221             : 
    1222             : void crypto_stats_kpp_compute_shared_secret(struct crypto_alg *alg, int ret)
    1223             : {
    1224             :         if (ret)
    1225             :                 atomic64_inc(&alg->stats.kpp.err_cnt);
    1226             :         else
    1227             :                 atomic64_inc(&alg->stats.kpp.compute_shared_secret_cnt);
    1228             :         crypto_alg_put(alg);
    1229             : }
    1230             : EXPORT_SYMBOL_GPL(crypto_stats_kpp_compute_shared_secret);
    1231             : 
    1232             : void crypto_stats_rng_seed(struct crypto_alg *alg, int ret)
    1233             : {
    1234             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY)
    1235             :                 atomic64_inc(&alg->stats.rng.err_cnt);
    1236             :         else
    1237             :                 atomic64_inc(&alg->stats.rng.seed_cnt);
    1238             :         crypto_alg_put(alg);
    1239             : }
    1240             : EXPORT_SYMBOL_GPL(crypto_stats_rng_seed);
    1241             : 
    1242             : void crypto_stats_rng_generate(struct crypto_alg *alg, unsigned int dlen,
    1243             :                                int ret)
    1244             : {
    1245             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1246             :                 atomic64_inc(&alg->stats.rng.err_cnt);
    1247             :         } else {
    1248             :                 atomic64_inc(&alg->stats.rng.generate_cnt);
    1249             :                 atomic64_add(dlen, &alg->stats.rng.generate_tlen);
    1250             :         }
    1251             :         crypto_alg_put(alg);
    1252             : }
    1253             : EXPORT_SYMBOL_GPL(crypto_stats_rng_generate);
    1254             : 
    1255             : void crypto_stats_skcipher_encrypt(unsigned int cryptlen, int ret,
    1256             :                                    struct crypto_alg *alg)
    1257             : {
    1258             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1259             :                 atomic64_inc(&alg->stats.cipher.err_cnt);
    1260             :         } else {
    1261             :                 atomic64_inc(&alg->stats.cipher.encrypt_cnt);
    1262             :                 atomic64_add(cryptlen, &alg->stats.cipher.encrypt_tlen);
    1263             :         }
    1264             :         crypto_alg_put(alg);
    1265             : }
    1266             : EXPORT_SYMBOL_GPL(crypto_stats_skcipher_encrypt);
    1267             : 
    1268             : void crypto_stats_skcipher_decrypt(unsigned int cryptlen, int ret,
    1269             :                                    struct crypto_alg *alg)
    1270             : {
    1271             :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1272             :                 atomic64_inc(&alg->stats.cipher.err_cnt);
    1273             :         } else {
    1274             :                 atomic64_inc(&alg->stats.cipher.decrypt_cnt);
    1275             :                 atomic64_add(cryptlen, &alg->stats.cipher.decrypt_tlen);
    1276             :         }
    1277             :         crypto_alg_put(alg);
    1278             : }
    1279             : EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt);
    1280             : #endif
    1281             : 
    1282           1 : static int __init crypto_algapi_init(void)
    1283             : {
    1284           1 :         crypto_init_proc();
    1285           1 :         return 0;
    1286             : }
    1287             : 
    1288           0 : static void __exit crypto_algapi_exit(void)
    1289             : {
    1290           0 :         crypto_exit_proc();
    1291           0 : }
    1292             : 
    1293             : module_init(crypto_algapi_init);
    1294             : module_exit(crypto_algapi_exit);
    1295             : 
    1296             : MODULE_LICENSE("GPL");
    1297             : MODULE_DESCRIPTION("Cryptographic algorithms API");

Generated by: LCOV version 1.14