LCOV - code coverage report
Current view: top level - crypto - algapi.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 238 496 48.0 %
Date: 2022-03-28 15:32:58 Functions: 20 41 48.8 %
Branches: 102 308 33.1 %

           Branch data     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                 :       1176 : static inline void crypto_check_module_sig(struct module *mod)
      25                 :            : {
      26                 :       1176 :         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                 :        672 : static int crypto_check_alg(struct crypto_alg *alg)
      32                 :            : {
      33                 :        672 :         crypto_check_module_sig(alg->cra_module);
      34                 :            : 
      35   [ +  -  +  - ]:        672 :         if (!alg->cra_name[0] || !alg->cra_driver_name[0])
      36                 :            :                 return -EINVAL;
      37                 :            : 
      38         [ +  - ]:        672 :         if (alg->cra_alignmask & (alg->cra_alignmask + 1))
      39                 :            :                 return -EINVAL;
      40                 :            : 
      41                 :            :         /* General maximums for all algs. */
      42         [ +  - ]:        672 :         if (alg->cra_alignmask > MAX_ALGAPI_ALIGNMASK)
      43                 :            :                 return -EINVAL;
      44                 :            : 
      45         [ +  - ]:        672 :         if (alg->cra_blocksize > MAX_ALGAPI_BLOCKSIZE)
      46                 :            :                 return -EINVAL;
      47                 :            : 
      48                 :            :         /* Lower maximums for specific alg types. */
      49   [ +  +  +  + ]:        672 :         if (!alg->cra_type && (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
      50                 :            :                                CRYPTO_ALG_TYPE_CIPHER) {
      51         [ +  - ]:        112 :                 if (alg->cra_alignmask > MAX_CIPHER_ALIGNMASK)
      52                 :            :                         return -EINVAL;
      53                 :            : 
      54         [ +  - ]:        112 :                 if (alg->cra_blocksize > MAX_CIPHER_BLOCKSIZE)
      55                 :            :                         return -EINVAL;
      56                 :            :         }
      57                 :            : 
      58         [ +  - ]:        672 :         if (alg->cra_priority < 0)
      59                 :            :                 return -EINVAL;
      60                 :            : 
      61                 :        672 :         refcount_set(&alg->cra_refcnt, 1);
      62                 :            : 
      63                 :        672 :         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                 :            : 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                 :            :         struct crypto_spawn *spawn, *n;
      95                 :            : 
      96                 :            :         spawn = list_first_entry_or_null(stack, struct crypto_spawn, list);
      97                 :            :         if (!spawn)
      98                 :            :                 return NULL;
      99                 :            : 
     100                 :            :         n = list_prev_entry(spawn, list);
     101                 :            :         list_move(&spawn->list, secondary_spawns);
     102                 :            : 
     103                 :            :         if (list_is_last(&n->list, stack))
     104                 :            :                 return top;
     105                 :            : 
     106                 :            :         n = list_next_entry(n, list);
     107                 :            :         if (!spawn->dead)
     108                 :            :                 n->dead = false;
     109                 :            : 
     110                 :            :         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                 :          0 :                 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                 :        784 : void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
     140                 :            :                           struct crypto_alg *nalg)
     141                 :            : {
     142         [ -  + ]:        784 :         u32 new_type = (nalg ?: alg)->cra_flags;
     143                 :        784 :         struct crypto_spawn *spawn, *n;
     144                 :        784 :         LIST_HEAD(secondary_spawns);
     145                 :        784 :         struct list_head *spawns;
     146                 :        784 :         LIST_HEAD(stack);
     147                 :        784 :         LIST_HEAD(top);
     148                 :            : 
     149                 :        784 :         spawns = &alg->cra_users;
     150         [ -  + ]:        784 :         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         [ -  + ]:        784 :                 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                 :        784 :         } while ((spawns = crypto_more_spawns(alg, &stack, &top,
     203         [ -  + ]:        784 :                                               &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         [ -  + ]:        784 :         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                 :        784 : }
     217                 :            : EXPORT_SYMBOL_GPL(crypto_remove_spawns);
     218                 :            : 
     219                 :        672 : static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
     220                 :            : {
     221                 :        672 :         struct crypto_alg *q;
     222                 :        672 :         struct crypto_larval *larval;
     223                 :        672 :         int ret = -EAGAIN;
     224                 :            : 
     225         [ -  + ]:        672 :         if (crypto_is_dead(alg))
     226                 :          0 :                 goto err;
     227                 :            : 
     228                 :        672 :         INIT_LIST_HEAD(&alg->cra_users);
     229                 :            : 
     230                 :            :         /* No cheating! */
     231                 :        672 :         alg->cra_flags &= ~CRYPTO_ALG_TESTED;
     232                 :            : 
     233                 :        672 :         ret = -EEXIST;
     234                 :            : 
     235         [ +  + ]:       8428 :         list_for_each_entry(q, &crypto_alg_list, cra_list) {
     236         [ -  + ]:       7756 :                 if (q == alg)
     237                 :          0 :                         goto err;
     238                 :            : 
     239         [ -  + ]:       7756 :                 if (crypto_is_moribund(q))
     240                 :          0 :                         continue;
     241                 :            : 
     242         [ +  + ]:       7756 :                 if (crypto_is_larval(q)) {
     243         [ -  + ]:         28 :                         if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
     244                 :          0 :                                 goto err;
     245                 :         28 :                         continue;
     246                 :            :                 }
     247                 :            : 
     248         [ +  - ]:       7728 :                 if (!strcmp(q->cra_driver_name, alg->cra_name) ||
     249         [ -  + ]:       7728 :                     !strcmp(q->cra_name, alg->cra_driver_name))
     250                 :          0 :                         goto err;
     251                 :            :         }
     252                 :            : 
     253                 :        672 :         larval = crypto_larval_alloc(alg->cra_name,
     254                 :            :                                      alg->cra_flags | CRYPTO_ALG_TESTED, 0);
     255         [ -  + ]:        672 :         if (IS_ERR(larval))
     256                 :          0 :                 goto out;
     257                 :            : 
     258                 :        672 :         ret = -ENOENT;
     259                 :        672 :         larval->adult = crypto_mod_get(alg);
     260         [ -  + ]:        672 :         if (!larval->adult)
     261                 :          0 :                 goto free_larval;
     262                 :            : 
     263                 :        672 :         refcount_set(&larval->alg.cra_refcnt, 1);
     264                 :        672 :         memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
     265                 :            :                CRYPTO_MAX_ALG_NAME);
     266                 :        672 :         larval->alg.cra_priority = alg->cra_priority;
     267                 :            : 
     268                 :        672 :         list_add(&alg->cra_list, &crypto_alg_list);
     269                 :        672 :         list_add(&larval->alg.cra_list, &crypto_alg_list);
     270                 :            : 
     271                 :            :         crypto_stats_init(alg);
     272                 :            : 
     273                 :        672 : out:
     274                 :        672 :         return larval;
     275                 :            : 
     276                 :            : free_larval:
     277                 :          0 :         kfree(larval);
     278                 :          0 : err:
     279                 :          0 :         larval = ERR_PTR(ret);
     280                 :          0 :         goto out;
     281                 :            : }
     282                 :            : 
     283                 :        672 : void crypto_alg_tested(const char *name, int err)
     284                 :            : {
     285                 :        672 :         struct crypto_larval *test;
     286                 :        672 :         struct crypto_alg *alg;
     287                 :        672 :         struct crypto_alg *q;
     288                 :        672 :         LIST_HEAD(list);
     289                 :        672 :         bool best;
     290                 :            : 
     291                 :        672 :         down_write(&crypto_alg_sem);
     292         [ +  - ]:        672 :         list_for_each_entry(q, &crypto_alg_list, cra_list) {
     293   [ +  -  -  + ]:        672 :                 if (crypto_is_moribund(q) || !crypto_is_larval(q))
     294                 :          0 :                         continue;
     295                 :            : 
     296                 :        672 :                 test = (struct crypto_larval *)q;
     297                 :            : 
     298         [ +  - ]:        672 :                 if (!strcmp(q->cra_driver_name, name))
     299                 :        672 :                         goto found;
     300                 :            :         }
     301                 :            : 
     302                 :          0 :         pr_err("alg: Unexpected test result for %s: %d\n", name, err);
     303                 :          0 :         goto unlock;
     304                 :            : 
     305                 :            : found:
     306                 :        672 :         q->cra_flags |= CRYPTO_ALG_DEAD;
     307                 :        672 :         alg = test->adult;
     308   [ +  -  -  + ]:        672 :         if (err || list_empty(&alg->cra_list))
     309                 :          0 :                 goto complete;
     310                 :            : 
     311                 :        672 :         alg->cra_flags |= CRYPTO_ALG_TESTED;
     312                 :            : 
     313                 :            :         /* Only satisfy larval waiters if we are the best. */
     314                 :        672 :         best = true;
     315         [ +  + ]:       9772 :         list_for_each_entry(q, &crypto_alg_list, cra_list) {
     316   [ +  +  +  + ]:       9100 :                 if (crypto_is_moribund(q) || !crypto_is_larval(q))
     317                 :       9072 :                         continue;
     318                 :            : 
     319         [ -  + ]:         28 :                 if (strcmp(alg->cra_name, q->cra_name))
     320                 :          0 :                         continue;
     321                 :            : 
     322         [ +  - ]:         28 :                 if (q->cra_priority > alg->cra_priority) {
     323                 :            :                         best = false;
     324                 :            :                         break;
     325                 :            :                 }
     326                 :            :         }
     327                 :            : 
     328         [ +  + ]:       9772 :         list_for_each_entry(q, &crypto_alg_list, cra_list) {
     329         [ +  + ]:       9100 :                 if (q == alg)
     330                 :        672 :                         continue;
     331                 :            : 
     332         [ +  + ]:       8428 :                 if (crypto_is_moribund(q))
     333                 :        672 :                         continue;
     334                 :            : 
     335         [ +  + ]:       7756 :                 if (crypto_is_larval(q)) {
     336                 :         28 :                         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         [ -  + ]:         28 :                         if (strcmp(alg->cra_name, q->cra_name) &&
     344         [ #  # ]:          0 :                             strcmp(alg->cra_driver_name, q->cra_name))
     345                 :          0 :                                 continue;
     346                 :            : 
     347         [ -  + ]:         28 :                         if (larval->adult)
     348                 :          0 :                                 continue;
     349         [ -  + ]:         28 :                         if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
     350                 :          0 :                                 continue;
     351                 :            : 
     352   [ +  -  +  - ]:         28 :                         if (best && crypto_mod_get(alg))
     353                 :         28 :                                 larval->adult = alg;
     354                 :            :                         else
     355                 :          0 :                                 larval->adult = ERR_PTR(-EAGAIN);
     356                 :            : 
     357                 :         28 :                         continue;
     358                 :            :                 }
     359                 :            : 
     360         [ +  + ]:       7728 :                 if (strcmp(alg->cra_name, q->cra_name))
     361                 :       6944 :                         continue;
     362                 :            : 
     363         [ +  - ]:        784 :                 if (strcmp(alg->cra_driver_name, q->cra_driver_name) &&
     364         [ -  + ]:        784 :                     q->cra_priority > alg->cra_priority)
     365                 :          0 :                         continue;
     366                 :            : 
     367                 :        784 :                 crypto_remove_spawns(q, &list, alg);
     368                 :            :         }
     369                 :            : 
     370                 :        672 : complete:
     371                 :        672 :         complete_all(&test->completion);
     372                 :            : 
     373                 :        672 : unlock:
     374                 :        672 :         up_write(&crypto_alg_sem);
     375                 :            : 
     376                 :        672 :         crypto_remove_final(&list);
     377                 :        672 : }
     378                 :            : EXPORT_SYMBOL_GPL(crypto_alg_tested);
     379                 :            : 
     380                 :        672 : void crypto_remove_final(struct list_head *list)
     381                 :            : {
     382                 :        672 :         struct crypto_alg *alg;
     383                 :        672 :         struct crypto_alg *n;
     384                 :            : 
     385         [ -  + ]:        672 :         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                 :        672 : }
     390                 :            : EXPORT_SYMBOL_GPL(crypto_remove_final);
     391                 :            : 
     392                 :        672 : static void crypto_wait_for_test(struct crypto_larval *larval)
     393                 :            : {
     394                 :        672 :         int err;
     395                 :            : 
     396                 :        672 :         err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
     397         [ -  + ]:        672 :         if (err != NOTIFY_STOP) {
     398   [ #  #  #  # ]:          0 :                 if (WARN_ON(err != NOTIFY_DONE))
     399                 :          0 :                         goto out;
     400                 :          0 :                 crypto_alg_tested(larval->alg.cra_driver_name, 0);
     401                 :            :         }
     402                 :            : 
     403                 :        672 :         err = wait_for_completion_killable(&larval->completion);
     404         [ -  + ]:        672 :         WARN_ON(err);
     405         [ -  + ]:        672 :         if (!err)
     406                 :        672 :                 crypto_probing_notify(CRYPTO_MSG_ALG_LOADED, larval);
     407                 :            : 
     408                 :          0 : out:
     409                 :        672 :         crypto_larval_kill(&larval->alg);
     410                 :        672 : }
     411                 :            : 
     412                 :        644 : int crypto_register_alg(struct crypto_alg *alg)
     413                 :            : {
     414                 :        644 :         struct crypto_larval *larval;
     415                 :        644 :         int err;
     416                 :            : 
     417                 :        644 :         alg->cra_flags &= ~CRYPTO_ALG_DEAD;
     418                 :        644 :         err = crypto_check_alg(alg);
     419         [ +  - ]:        644 :         if (err)
     420                 :            :                 return err;
     421                 :            : 
     422                 :        644 :         down_write(&crypto_alg_sem);
     423                 :        644 :         larval = __crypto_register_alg(alg);
     424                 :        644 :         up_write(&crypto_alg_sem);
     425                 :            : 
     426         [ -  + ]:        644 :         if (IS_ERR(larval))
     427                 :          0 :                 return PTR_ERR(larval);
     428                 :            : 
     429                 :        644 :         crypto_wait_for_test(larval);
     430                 :        644 :         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                 :         56 : int crypto_register_algs(struct crypto_alg *algs, int count)
     468                 :            : {
     469                 :         56 :         int i, ret;
     470                 :            : 
     471         [ +  + ]:        168 :         for (i = 0; i < count; i++) {
     472                 :        112 :                 ret = crypto_register_alg(&algs[i]);
     473         [ -  + ]:        112 :                 if (ret)
     474                 :          0 :                         goto err;
     475                 :            :         }
     476                 :            : 
     477                 :            :         return 0;
     478                 :            : 
     479                 :            : 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                 :        504 : int crypto_register_template(struct crypto_template *tmpl)
     497                 :            : {
     498                 :        504 :         struct crypto_template *q;
     499                 :        504 :         int err = -EEXIST;
     500                 :            : 
     501                 :        504 :         down_write(&crypto_alg_sem);
     502                 :            : 
     503                 :        504 :         crypto_check_module_sig(tmpl->module);
     504                 :            : 
     505         [ +  + ]:       4788 :         list_for_each_entry(q, &crypto_template_list, list) {
     506         [ -  + ]:       4284 :                 if (q == tmpl)
     507                 :          0 :                         goto out;
     508                 :            :         }
     509                 :            : 
     510                 :        504 :         list_add(&tmpl->list, &crypto_template_list);
     511                 :        504 :         err = 0;
     512                 :        504 : out:
     513                 :        504 :         up_write(&crypto_alg_sem);
     514                 :        504 :         return err;
     515                 :            : }
     516                 :            : EXPORT_SYMBOL_GPL(crypto_register_template);
     517                 :            : 
     518                 :         84 : int crypto_register_templates(struct crypto_template *tmpls, int count)
     519                 :            : {
     520                 :         84 :         int i, err;
     521                 :            : 
     522         [ +  + ]:        364 :         for (i = 0; i < count; i++) {
     523                 :        280 :                 err = crypto_register_template(&tmpls[i]);
     524         [ -  + ]:        280 :                 if (err)
     525                 :          0 :                         goto out;
     526                 :            :         }
     527                 :            :         return 0;
     528                 :            : 
     529                 :            : 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                 :         28 : static struct crypto_template *__crypto_lookup_template(const char *name)
     575                 :            : {
     576                 :         28 :         struct crypto_template *q, *tmpl = NULL;
     577                 :            : 
     578                 :         28 :         down_read(&crypto_alg_sem);
     579         [ +  - ]:        448 :         list_for_each_entry(q, &crypto_template_list, list) {
     580         [ +  + ]:        448 :                 if (strcmp(q->name, name))
     581                 :        420 :                         continue;
     582         [ -  + ]:         28 :                 if (unlikely(!crypto_tmpl_get(q)))
     583                 :          0 :                         continue;
     584                 :            : 
     585                 :            :                 tmpl = q;
     586                 :            :                 break;
     587                 :            :         }
     588                 :         28 :         up_read(&crypto_alg_sem);
     589                 :            : 
     590                 :         28 :         return tmpl;
     591                 :            : }
     592                 :            : 
     593                 :         28 : struct crypto_template *crypto_lookup_template(const char *name)
     594                 :            : {
     595         [ -  + ]:         28 :         return try_then_request_module(__crypto_lookup_template(name),
     596                 :            :                                        "crypto-%s", name);
     597                 :            : }
     598                 :            : EXPORT_SYMBOL_GPL(crypto_lookup_template);
     599                 :            : 
     600                 :         28 : int crypto_register_instance(struct crypto_template *tmpl,
     601                 :            :                              struct crypto_instance *inst)
     602                 :            : {
     603                 :         28 :         struct crypto_larval *larval;
     604                 :         28 :         struct crypto_spawn *spawn;
     605                 :         28 :         int err;
     606                 :            : 
     607                 :         28 :         err = crypto_check_alg(&inst->alg);
     608         [ +  - ]:         28 :         if (err)
     609                 :            :                 return err;
     610                 :            : 
     611                 :         28 :         inst->alg.cra_module = tmpl->module;
     612                 :         28 :         inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
     613                 :            : 
     614                 :         28 :         down_write(&crypto_alg_sem);
     615                 :            : 
     616                 :         28 :         larval = ERR_PTR(-EAGAIN);
     617         [ +  + ]:         56 :         for (spawn = inst->spawns; spawn;) {
     618                 :         28 :                 struct crypto_spawn *next;
     619                 :            : 
     620         [ -  + ]:         28 :                 if (spawn->dead)
     621                 :          0 :                         goto unlock;
     622                 :            : 
     623                 :         28 :                 next = spawn->next;
     624                 :         28 :                 spawn->inst = inst;
     625                 :         28 :                 spawn->registered = true;
     626                 :            : 
     627                 :         28 :                 crypto_mod_put(spawn->alg);
     628                 :            : 
     629                 :         28 :                 spawn = next;
     630                 :            :         }
     631                 :            : 
     632                 :         28 :         larval = __crypto_register_alg(&inst->alg);
     633         [ -  + ]:         28 :         if (IS_ERR(larval))
     634                 :          0 :                 goto unlock;
     635                 :            : 
     636         [ -  + ]:         28 :         hlist_add_head(&inst->list, &tmpl->instances);
     637                 :         28 :         inst->tmpl = tmpl;
     638                 :            : 
     639                 :         28 : unlock:
     640                 :         28 :         up_write(&crypto_alg_sem);
     641                 :            : 
     642         [ -  + ]:         28 :         err = PTR_ERR(larval);
     643         [ -  + ]:         28 :         if (IS_ERR(larval))
     644                 :          0 :                 goto err;
     645                 :            : 
     646                 :         28 :         crypto_wait_for_test(larval);
     647                 :         28 :         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                 :         28 : int crypto_grab_spawn(struct crypto_spawn *spawn, struct crypto_instance *inst,
     670                 :            :                       const char *name, u32 type, u32 mask)
     671                 :            : {
     672                 :         28 :         struct crypto_alg *alg;
     673                 :         28 :         int err = -EAGAIN;
     674                 :            : 
     675   [ -  +  +  - ]:         28 :         if (WARN_ON_ONCE(inst == NULL))
     676                 :            :                 return -EINVAL;
     677                 :            : 
     678                 :            :         /* Allow the result of crypto_attr_alg_name() to be passed directly */
     679         [ -  + ]:         28 :         if (IS_ERR(name))
     680                 :          0 :                 return PTR_ERR(name);
     681                 :            : 
     682                 :         28 :         alg = crypto_find_alg(name, spawn->frontend, type, mask);
     683         [ -  + ]:         28 :         if (IS_ERR(alg))
     684                 :          0 :                 return PTR_ERR(alg);
     685                 :            : 
     686                 :         28 :         down_write(&crypto_alg_sem);
     687         [ +  - ]:         28 :         if (!crypto_is_moribund(alg)) {
     688                 :         28 :                 list_add(&spawn->list, &alg->cra_users);
     689                 :         28 :                 spawn->alg = alg;
     690                 :         28 :                 spawn->mask = mask;
     691                 :         28 :                 spawn->next = inst->spawns;
     692                 :         28 :                 inst->spawns = spawn;
     693                 :         28 :                 err = 0;
     694                 :            :         }
     695                 :         28 :         up_write(&crypto_alg_sem);
     696         [ -  + ]:         28 :         if (err)
     697                 :          0 :                 crypto_mod_put(alg);
     698                 :            :         return err;
     699                 :            : }
     700                 :            : EXPORT_SYMBOL_GPL(crypto_grab_spawn);
     701                 :            : 
     702                 :          0 : void crypto_drop_spawn(struct crypto_spawn *spawn)
     703                 :            : {
     704         [ #  # ]:          0 :         if (!spawn->alg) /* not yet initialized? */
     705                 :            :                 return;
     706                 :            : 
     707                 :          0 :         down_write(&crypto_alg_sem);
     708         [ #  # ]:          0 :         if (!spawn->dead)
     709                 :          0 :                 list_del(&spawn->list);
     710                 :          0 :         up_write(&crypto_alg_sem);
     711                 :            : 
     712         [ #  # ]:          0 :         if (!spawn->registered)
     713                 :          0 :                 crypto_mod_put(spawn->alg);
     714                 :            : }
     715                 :            : EXPORT_SYMBOL_GPL(crypto_drop_spawn);
     716                 :            : 
     717                 :            : static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
     718                 :            : {
     719                 :            :         struct crypto_alg *alg;
     720                 :            : 
     721                 :            :         down_read(&crypto_alg_sem);
     722                 :            :         alg = spawn->alg;
     723                 :            :         if (!spawn->dead && !crypto_mod_get(alg)) {
     724                 :            :                 alg->cra_flags |= CRYPTO_ALG_DYING;
     725                 :            :                 alg = NULL;
     726                 :            :         }
     727                 :            :         up_read(&crypto_alg_sem);
     728                 :            : 
     729                 :            :         return alg ?: ERR_PTR(-EAGAIN);
     730                 :            : }
     731                 :            : 
     732                 :          0 : struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
     733                 :            :                                     u32 mask)
     734                 :            : {
     735                 :          0 :         struct crypto_alg *alg;
     736                 :          0 :         struct crypto_tfm *tfm;
     737                 :            : 
     738                 :          0 :         alg = crypto_spawn_alg(spawn);
     739         [ #  # ]:          0 :         if (IS_ERR(alg))
     740                 :            :                 return ERR_CAST(alg);
     741                 :            : 
     742         [ #  # ]:          0 :         tfm = ERR_PTR(-EINVAL);
     743         [ #  # ]:          0 :         if (unlikely((alg->cra_flags ^ type) & mask))
     744                 :          0 :                 goto out_put_alg;
     745                 :            : 
     746                 :          0 :         tfm = __crypto_alloc_tfm(alg, type, mask);
     747         [ #  # ]:          0 :         if (IS_ERR(tfm))
     748                 :          0 :                 goto out_put_alg;
     749                 :            : 
     750                 :            :         return tfm;
     751                 :            : 
     752                 :          0 : out_put_alg:
     753                 :          0 :         crypto_mod_put(alg);
     754                 :          0 :         return tfm;
     755                 :            : }
     756                 :            : EXPORT_SYMBOL_GPL(crypto_spawn_tfm);
     757                 :            : 
     758                 :         28 : void *crypto_spawn_tfm2(struct crypto_spawn *spawn)
     759                 :            : {
     760                 :         28 :         struct crypto_alg *alg;
     761                 :         28 :         struct crypto_tfm *tfm;
     762                 :            : 
     763                 :         28 :         alg = crypto_spawn_alg(spawn);
     764         [ +  - ]:         28 :         if (IS_ERR(alg))
     765                 :            :                 return ERR_CAST(alg);
     766                 :            : 
     767                 :         28 :         tfm = crypto_create_tfm(alg, spawn->frontend);
     768         [ -  + ]:         28 :         if (IS_ERR(tfm))
     769                 :          0 :                 goto out_put_alg;
     770                 :            : 
     771                 :            :         return tfm;
     772                 :            : 
     773                 :            : out_put_alg:
     774                 :          0 :         crypto_mod_put(alg);
     775                 :          0 :         return tfm;
     776                 :            : }
     777                 :            : EXPORT_SYMBOL_GPL(crypto_spawn_tfm2);
     778                 :            : 
     779                 :         28 : int crypto_register_notifier(struct notifier_block *nb)
     780                 :            : {
     781                 :         28 :         return blocking_notifier_chain_register(&crypto_chain, nb);
     782                 :            : }
     783                 :            : EXPORT_SYMBOL_GPL(crypto_register_notifier);
     784                 :            : 
     785                 :          0 : int crypto_unregister_notifier(struct notifier_block *nb)
     786                 :            : {
     787                 :          0 :         return blocking_notifier_chain_unregister(&crypto_chain, nb);
     788                 :            : }
     789                 :            : EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
     790                 :            : 
     791                 :         28 : struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
     792                 :            : {
     793                 :         28 :         struct rtattr *rta = tb[0];
     794                 :         28 :         struct crypto_attr_type *algt;
     795                 :            : 
     796         [ +  - ]:         28 :         if (!rta)
     797                 :            :                 return ERR_PTR(-ENOENT);
     798   [ -  -  +  - ]:         28 :         if (RTA_PAYLOAD(rta) < sizeof(*algt))
     799                 :            :                 return ERR_PTR(-EINVAL);
     800   [ -  -  +  - ]:         28 :         if (rta->rta_type != CRYPTOA_TYPE)
     801                 :            :                 return ERR_PTR(-EINVAL);
     802                 :            : 
     803                 :         28 :         algt = RTA_DATA(rta);
     804                 :            : 
     805                 :         28 :         return algt;
     806                 :            : }
     807                 :            : EXPORT_SYMBOL_GPL(crypto_get_attr_type);
     808                 :            : 
     809                 :          0 : int crypto_check_attr_type(struct rtattr **tb, u32 type)
     810                 :            : {
     811                 :          0 :         struct crypto_attr_type *algt;
     812                 :            : 
     813         [ #  # ]:          0 :         algt = crypto_get_attr_type(tb);
     814         [ #  # ]:          0 :         if (IS_ERR(algt))
     815                 :          0 :                 return PTR_ERR(algt);
     816                 :            : 
     817         [ #  # ]:          0 :         if ((algt->type ^ type) & algt->mask)
     818                 :          0 :                 return -EINVAL;
     819                 :            : 
     820                 :            :         return 0;
     821                 :            : }
     822                 :            : EXPORT_SYMBOL_GPL(crypto_check_attr_type);
     823                 :            : 
     824                 :         56 : const char *crypto_attr_alg_name(struct rtattr *rta)
     825                 :            : {
     826                 :         56 :         struct crypto_attr_alg *alga;
     827                 :            : 
     828         [ +  - ]:         56 :         if (!rta)
     829                 :            :                 return ERR_PTR(-ENOENT);
     830         [ +  - ]:         56 :         if (RTA_PAYLOAD(rta) < sizeof(*alga))
     831                 :            :                 return ERR_PTR(-EINVAL);
     832         [ +  - ]:         56 :         if (rta->rta_type != CRYPTOA_ALG)
     833                 :            :                 return ERR_PTR(-EINVAL);
     834                 :            : 
     835                 :         56 :         alga = RTA_DATA(rta);
     836                 :         56 :         alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
     837                 :            : 
     838                 :         56 :         return alga->name;
     839                 :            : }
     840                 :            : EXPORT_SYMBOL_GPL(crypto_attr_alg_name);
     841                 :            : 
     842                 :          0 : int crypto_attr_u32(struct rtattr *rta, u32 *num)
     843                 :            : {
     844                 :          0 :         struct crypto_attr_u32 *nu32;
     845                 :            : 
     846         [ #  # ]:          0 :         if (!rta)
     847                 :            :                 return -ENOENT;
     848         [ #  # ]:          0 :         if (RTA_PAYLOAD(rta) < sizeof(*nu32))
     849                 :            :                 return -EINVAL;
     850         [ #  # ]:          0 :         if (rta->rta_type != CRYPTOA_U32)
     851                 :            :                 return -EINVAL;
     852                 :            : 
     853                 :          0 :         nu32 = RTA_DATA(rta);
     854                 :          0 :         *num = nu32->num;
     855                 :            : 
     856                 :          0 :         return 0;
     857                 :            : }
     858                 :            : EXPORT_SYMBOL_GPL(crypto_attr_u32);
     859                 :            : 
     860                 :          0 : int crypto_inst_setname(struct crypto_instance *inst, const char *name,
     861                 :            :                         struct crypto_alg *alg)
     862                 :            : {
     863                 :          0 :         if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", name,
     864         [ #  # ]:          0 :                      alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
     865                 :            :                 return -ENAMETOOLONG;
     866                 :            : 
     867                 :          0 :         if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
     868         [ #  # ]:          0 :                      name, alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
     869                 :          0 :                 return -ENAMETOOLONG;
     870                 :            : 
     871                 :            :         return 0;
     872                 :            : }
     873                 :            : EXPORT_SYMBOL_GPL(crypto_inst_setname);
     874                 :            : 
     875                 :          0 : void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen)
     876                 :            : {
     877                 :          0 :         INIT_LIST_HEAD(&queue->list);
     878                 :          0 :         queue->backlog = &queue->list;
     879                 :          0 :         queue->qlen = 0;
     880                 :          0 :         queue->max_qlen = max_qlen;
     881                 :          0 : }
     882                 :            : EXPORT_SYMBOL_GPL(crypto_init_queue);
     883                 :            : 
     884                 :          0 : int crypto_enqueue_request(struct crypto_queue *queue,
     885                 :            :                            struct crypto_async_request *request)
     886                 :            : {
     887                 :          0 :         int err = -EINPROGRESS;
     888                 :            : 
     889         [ #  # ]:          0 :         if (unlikely(queue->qlen >= queue->max_qlen)) {
     890         [ #  # ]:          0 :                 if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
     891                 :          0 :                         err = -ENOSPC;
     892                 :          0 :                         goto out;
     893                 :            :                 }
     894                 :          0 :                 err = -EBUSY;
     895         [ #  # ]:          0 :                 if (queue->backlog == &queue->list)
     896                 :          0 :                         queue->backlog = &request->list;
     897                 :            :         }
     898                 :            : 
     899                 :          0 :         queue->qlen++;
     900                 :          0 :         list_add_tail(&request->list, &queue->list);
     901                 :            : 
     902                 :          0 : out:
     903                 :          0 :         return err;
     904                 :            : }
     905                 :            : EXPORT_SYMBOL_GPL(crypto_enqueue_request);
     906                 :            : 
     907                 :          0 : struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
     908                 :            : {
     909                 :          0 :         struct list_head *request;
     910                 :            : 
     911         [ #  # ]:          0 :         if (unlikely(!queue->qlen))
     912                 :            :                 return NULL;
     913                 :            : 
     914                 :          0 :         queue->qlen--;
     915                 :            : 
     916         [ #  # ]:          0 :         if (queue->backlog != &queue->list)
     917                 :          0 :                 queue->backlog = queue->backlog->next;
     918                 :            : 
     919                 :          0 :         request = queue->list.next;
     920                 :          0 :         list_del(request);
     921                 :            : 
     922                 :          0 :         return list_entry(request, struct crypto_async_request, list);
     923                 :            : }
     924                 :            : EXPORT_SYMBOL_GPL(crypto_dequeue_request);
     925                 :            : 
     926                 :          0 : static inline void crypto_inc_byte(u8 *a, unsigned int size)
     927                 :            : {
     928                 :          0 :         u8 *b = (a + size);
     929                 :          0 :         u8 c;
     930                 :            : 
     931         [ #  # ]:          0 :         for (; size; size--) {
     932                 :          0 :                 c = *--b + 1;
     933                 :          0 :                 *b = c;
     934         [ #  # ]:          0 :                 if (c)
     935                 :            :                         break;
     936                 :            :         }
     937                 :            : }
     938                 :            : 
     939                 :          0 : void crypto_inc(u8 *a, unsigned int size)
     940                 :            : {
     941                 :          0 :         __be32 *b = (__be32 *)(a + size);
     942                 :          0 :         u32 c;
     943                 :            : 
     944                 :          0 :         if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
     945                 :            :             IS_ALIGNED((unsigned long)b, __alignof__(*b)))
     946         [ #  # ]:          0 :                 for (; size >= 4; size -= 4) {
     947                 :          0 :                         c = be32_to_cpu(*--b) + 1;
     948                 :          0 :                         *b = cpu_to_be32(c);
     949         [ #  # ]:          0 :                         if (likely(c))
     950                 :            :                                 return;
     951                 :            :                 }
     952                 :            : 
     953                 :          0 :         crypto_inc_byte(a, size);
     954                 :            : }
     955                 :            : EXPORT_SYMBOL_GPL(crypto_inc);
     956                 :            : 
     957                 :          0 : void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len)
     958                 :            : {
     959                 :          0 :         int relalign = 0;
     960                 :            : 
     961                 :          0 :         if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
     962                 :            :                 int size = sizeof(unsigned long);
     963                 :            :                 int d = (((unsigned long)dst ^ (unsigned long)src1) |
     964                 :            :                          ((unsigned long)dst ^ (unsigned long)src2)) &
     965                 :            :                         (size - 1);
     966                 :            : 
     967                 :            :                 relalign = d ? 1 << __ffs(d) : size;
     968                 :            : 
     969                 :            :                 /*
     970                 :            :                  * If we care about alignment, process as many bytes as
     971                 :            :                  * needed to advance dst and src to values whose alignments
     972                 :            :                  * equal their relative alignment. This will allow us to
     973                 :            :                  * process the remainder of the input using optimal strides.
     974                 :            :                  */
     975                 :            :                 while (((unsigned long)dst & (relalign - 1)) && len > 0) {
     976                 :            :                         *dst++ = *src1++ ^ *src2++;
     977                 :            :                         len--;
     978                 :            :                 }
     979                 :            :         }
     980                 :            : 
     981         [ #  # ]:          0 :         while (IS_ENABLED(CONFIG_64BIT) && len >= 8 && !(relalign & 7)) {
     982                 :          0 :                 *(u64 *)dst = *(u64 *)src1 ^  *(u64 *)src2;
     983                 :          0 :                 dst += 8;
     984                 :          0 :                 src1 += 8;
     985                 :          0 :                 src2 += 8;
     986                 :          0 :                 len -= 8;
     987                 :            :         }
     988                 :            : 
     989         [ #  # ]:          0 :         while (len >= 4 && !(relalign & 3)) {
     990                 :          0 :                 *(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
     991                 :          0 :                 dst += 4;
     992                 :          0 :                 src1 += 4;
     993                 :          0 :                 src2 += 4;
     994                 :          0 :                 len -= 4;
     995                 :            :         }
     996                 :            : 
     997         [ #  # ]:          0 :         while (len >= 2 && !(relalign & 1)) {
     998                 :          0 :                 *(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
     999                 :          0 :                 dst += 2;
    1000                 :          0 :                 src1 += 2;
    1001                 :          0 :                 src2 += 2;
    1002                 :          0 :                 len -= 2;
    1003                 :            :         }
    1004                 :            : 
    1005         [ #  # ]:          0 :         while (len--)
    1006                 :          0 :                 *dst++ = *src1++ ^ *src2++;
    1007                 :          0 : }
    1008                 :            : EXPORT_SYMBOL_GPL(__crypto_xor);
    1009                 :            : 
    1010                 :        252 : unsigned int crypto_alg_extsize(struct crypto_alg *alg)
    1011                 :            : {
    1012                 :        252 :         return alg->cra_ctxsize +
    1013                 :        252 :                (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1));
    1014                 :            : }
    1015                 :            : EXPORT_SYMBOL_GPL(crypto_alg_extsize);
    1016                 :            : 
    1017                 :          0 : int crypto_type_has_alg(const char *name, const struct crypto_type *frontend,
    1018                 :            :                         u32 type, u32 mask)
    1019                 :            : {
    1020                 :          0 :         int ret = 0;
    1021                 :          0 :         struct crypto_alg *alg = crypto_find_alg(name, frontend, type, mask);
    1022                 :            : 
    1023         [ #  # ]:          0 :         if (!IS_ERR(alg)) {
    1024                 :          0 :                 crypto_mod_put(alg);
    1025                 :          0 :                 ret = 1;
    1026                 :            :         }
    1027                 :            : 
    1028                 :          0 :         return ret;
    1029                 :            : }
    1030                 :            : EXPORT_SYMBOL_GPL(crypto_type_has_alg);
    1031                 :            : 
    1032                 :            : #ifdef CONFIG_CRYPTO_STATS
    1033                 :            : void crypto_stats_init(struct crypto_alg *alg)
    1034                 :            : {
    1035                 :            :         memset(&alg->stats, 0, sizeof(alg->stats));
    1036                 :            : }
    1037                 :            : EXPORT_SYMBOL_GPL(crypto_stats_init);
    1038                 :            : 
    1039                 :            : void crypto_stats_get(struct crypto_alg *alg)
    1040                 :            : {
    1041                 :            :         crypto_alg_get(alg);
    1042                 :            : }
    1043                 :            : EXPORT_SYMBOL_GPL(crypto_stats_get);
    1044                 :            : 
    1045                 :            : void crypto_stats_aead_encrypt(unsigned int cryptlen, struct crypto_alg *alg,
    1046                 :            :                                int ret)
    1047                 :            : {
    1048                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1049                 :            :                 atomic64_inc(&alg->stats.aead.err_cnt);
    1050                 :            :         } else {
    1051                 :            :                 atomic64_inc(&alg->stats.aead.encrypt_cnt);
    1052                 :            :                 atomic64_add(cryptlen, &alg->stats.aead.encrypt_tlen);
    1053                 :            :         }
    1054                 :            :         crypto_alg_put(alg);
    1055                 :            : }
    1056                 :            : EXPORT_SYMBOL_GPL(crypto_stats_aead_encrypt);
    1057                 :            : 
    1058                 :            : void crypto_stats_aead_decrypt(unsigned int cryptlen, struct crypto_alg *alg,
    1059                 :            :                                int ret)
    1060                 :            : {
    1061                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1062                 :            :                 atomic64_inc(&alg->stats.aead.err_cnt);
    1063                 :            :         } else {
    1064                 :            :                 atomic64_inc(&alg->stats.aead.decrypt_cnt);
    1065                 :            :                 atomic64_add(cryptlen, &alg->stats.aead.decrypt_tlen);
    1066                 :            :         }
    1067                 :            :         crypto_alg_put(alg);
    1068                 :            : }
    1069                 :            : EXPORT_SYMBOL_GPL(crypto_stats_aead_decrypt);
    1070                 :            : 
    1071                 :            : void crypto_stats_akcipher_encrypt(unsigned int src_len, int ret,
    1072                 :            :                                    struct crypto_alg *alg)
    1073                 :            : {
    1074                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1075                 :            :                 atomic64_inc(&alg->stats.akcipher.err_cnt);
    1076                 :            :         } else {
    1077                 :            :                 atomic64_inc(&alg->stats.akcipher.encrypt_cnt);
    1078                 :            :                 atomic64_add(src_len, &alg->stats.akcipher.encrypt_tlen);
    1079                 :            :         }
    1080                 :            :         crypto_alg_put(alg);
    1081                 :            : }
    1082                 :            : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_encrypt);
    1083                 :            : 
    1084                 :            : void crypto_stats_akcipher_decrypt(unsigned int src_len, int ret,
    1085                 :            :                                    struct crypto_alg *alg)
    1086                 :            : {
    1087                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1088                 :            :                 atomic64_inc(&alg->stats.akcipher.err_cnt);
    1089                 :            :         } else {
    1090                 :            :                 atomic64_inc(&alg->stats.akcipher.decrypt_cnt);
    1091                 :            :                 atomic64_add(src_len, &alg->stats.akcipher.decrypt_tlen);
    1092                 :            :         }
    1093                 :            :         crypto_alg_put(alg);
    1094                 :            : }
    1095                 :            : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_decrypt);
    1096                 :            : 
    1097                 :            : void crypto_stats_akcipher_sign(int ret, struct crypto_alg *alg)
    1098                 :            : {
    1099                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY)
    1100                 :            :                 atomic64_inc(&alg->stats.akcipher.err_cnt);
    1101                 :            :         else
    1102                 :            :                 atomic64_inc(&alg->stats.akcipher.sign_cnt);
    1103                 :            :         crypto_alg_put(alg);
    1104                 :            : }
    1105                 :            : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_sign);
    1106                 :            : 
    1107                 :            : void crypto_stats_akcipher_verify(int ret, struct crypto_alg *alg)
    1108                 :            : {
    1109                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY)
    1110                 :            :                 atomic64_inc(&alg->stats.akcipher.err_cnt);
    1111                 :            :         else
    1112                 :            :                 atomic64_inc(&alg->stats.akcipher.verify_cnt);
    1113                 :            :         crypto_alg_put(alg);
    1114                 :            : }
    1115                 :            : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_verify);
    1116                 :            : 
    1117                 :            : void crypto_stats_compress(unsigned int slen, int ret, struct crypto_alg *alg)
    1118                 :            : {
    1119                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1120                 :            :                 atomic64_inc(&alg->stats.compress.err_cnt);
    1121                 :            :         } else {
    1122                 :            :                 atomic64_inc(&alg->stats.compress.compress_cnt);
    1123                 :            :                 atomic64_add(slen, &alg->stats.compress.compress_tlen);
    1124                 :            :         }
    1125                 :            :         crypto_alg_put(alg);
    1126                 :            : }
    1127                 :            : EXPORT_SYMBOL_GPL(crypto_stats_compress);
    1128                 :            : 
    1129                 :            : void crypto_stats_decompress(unsigned int slen, int ret, struct crypto_alg *alg)
    1130                 :            : {
    1131                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1132                 :            :                 atomic64_inc(&alg->stats.compress.err_cnt);
    1133                 :            :         } else {
    1134                 :            :                 atomic64_inc(&alg->stats.compress.decompress_cnt);
    1135                 :            :                 atomic64_add(slen, &alg->stats.compress.decompress_tlen);
    1136                 :            :         }
    1137                 :            :         crypto_alg_put(alg);
    1138                 :            : }
    1139                 :            : EXPORT_SYMBOL_GPL(crypto_stats_decompress);
    1140                 :            : 
    1141                 :            : void crypto_stats_ahash_update(unsigned int nbytes, int ret,
    1142                 :            :                                struct crypto_alg *alg)
    1143                 :            : {
    1144                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY)
    1145                 :            :                 atomic64_inc(&alg->stats.hash.err_cnt);
    1146                 :            :         else
    1147                 :            :                 atomic64_add(nbytes, &alg->stats.hash.hash_tlen);
    1148                 :            :         crypto_alg_put(alg);
    1149                 :            : }
    1150                 :            : EXPORT_SYMBOL_GPL(crypto_stats_ahash_update);
    1151                 :            : 
    1152                 :            : void crypto_stats_ahash_final(unsigned int nbytes, int ret,
    1153                 :            :                               struct crypto_alg *alg)
    1154                 :            : {
    1155                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1156                 :            :                 atomic64_inc(&alg->stats.hash.err_cnt);
    1157                 :            :         } else {
    1158                 :            :                 atomic64_inc(&alg->stats.hash.hash_cnt);
    1159                 :            :                 atomic64_add(nbytes, &alg->stats.hash.hash_tlen);
    1160                 :            :         }
    1161                 :            :         crypto_alg_put(alg);
    1162                 :            : }
    1163                 :            : EXPORT_SYMBOL_GPL(crypto_stats_ahash_final);
    1164                 :            : 
    1165                 :            : void crypto_stats_kpp_set_secret(struct crypto_alg *alg, int ret)
    1166                 :            : {
    1167                 :            :         if (ret)
    1168                 :            :                 atomic64_inc(&alg->stats.kpp.err_cnt);
    1169                 :            :         else
    1170                 :            :                 atomic64_inc(&alg->stats.kpp.setsecret_cnt);
    1171                 :            :         crypto_alg_put(alg);
    1172                 :            : }
    1173                 :            : EXPORT_SYMBOL_GPL(crypto_stats_kpp_set_secret);
    1174                 :            : 
    1175                 :            : void crypto_stats_kpp_generate_public_key(struct crypto_alg *alg, int ret)
    1176                 :            : {
    1177                 :            :         if (ret)
    1178                 :            :                 atomic64_inc(&alg->stats.kpp.err_cnt);
    1179                 :            :         else
    1180                 :            :                 atomic64_inc(&alg->stats.kpp.generate_public_key_cnt);
    1181                 :            :         crypto_alg_put(alg);
    1182                 :            : }
    1183                 :            : EXPORT_SYMBOL_GPL(crypto_stats_kpp_generate_public_key);
    1184                 :            : 
    1185                 :            : void crypto_stats_kpp_compute_shared_secret(struct crypto_alg *alg, int ret)
    1186                 :            : {
    1187                 :            :         if (ret)
    1188                 :            :                 atomic64_inc(&alg->stats.kpp.err_cnt);
    1189                 :            :         else
    1190                 :            :                 atomic64_inc(&alg->stats.kpp.compute_shared_secret_cnt);
    1191                 :            :         crypto_alg_put(alg);
    1192                 :            : }
    1193                 :            : EXPORT_SYMBOL_GPL(crypto_stats_kpp_compute_shared_secret);
    1194                 :            : 
    1195                 :            : void crypto_stats_rng_seed(struct crypto_alg *alg, int ret)
    1196                 :            : {
    1197                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY)
    1198                 :            :                 atomic64_inc(&alg->stats.rng.err_cnt);
    1199                 :            :         else
    1200                 :            :                 atomic64_inc(&alg->stats.rng.seed_cnt);
    1201                 :            :         crypto_alg_put(alg);
    1202                 :            : }
    1203                 :            : EXPORT_SYMBOL_GPL(crypto_stats_rng_seed);
    1204                 :            : 
    1205                 :            : void crypto_stats_rng_generate(struct crypto_alg *alg, unsigned int dlen,
    1206                 :            :                                int ret)
    1207                 :            : {
    1208                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1209                 :            :                 atomic64_inc(&alg->stats.rng.err_cnt);
    1210                 :            :         } else {
    1211                 :            :                 atomic64_inc(&alg->stats.rng.generate_cnt);
    1212                 :            :                 atomic64_add(dlen, &alg->stats.rng.generate_tlen);
    1213                 :            :         }
    1214                 :            :         crypto_alg_put(alg);
    1215                 :            : }
    1216                 :            : EXPORT_SYMBOL_GPL(crypto_stats_rng_generate);
    1217                 :            : 
    1218                 :            : void crypto_stats_skcipher_encrypt(unsigned int cryptlen, int ret,
    1219                 :            :                                    struct crypto_alg *alg)
    1220                 :            : {
    1221                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1222                 :            :                 atomic64_inc(&alg->stats.cipher.err_cnt);
    1223                 :            :         } else {
    1224                 :            :                 atomic64_inc(&alg->stats.cipher.encrypt_cnt);
    1225                 :            :                 atomic64_add(cryptlen, &alg->stats.cipher.encrypt_tlen);
    1226                 :            :         }
    1227                 :            :         crypto_alg_put(alg);
    1228                 :            : }
    1229                 :            : EXPORT_SYMBOL_GPL(crypto_stats_skcipher_encrypt);
    1230                 :            : 
    1231                 :            : void crypto_stats_skcipher_decrypt(unsigned int cryptlen, int ret,
    1232                 :            :                                    struct crypto_alg *alg)
    1233                 :            : {
    1234                 :            :         if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
    1235                 :            :                 atomic64_inc(&alg->stats.cipher.err_cnt);
    1236                 :            :         } else {
    1237                 :            :                 atomic64_inc(&alg->stats.cipher.decrypt_cnt);
    1238                 :            :                 atomic64_add(cryptlen, &alg->stats.cipher.decrypt_tlen);
    1239                 :            :         }
    1240                 :            :         crypto_alg_put(alg);
    1241                 :            : }
    1242                 :            : EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt);
    1243                 :            : #endif
    1244                 :            : 
    1245                 :         28 : static int __init crypto_algapi_init(void)
    1246                 :            : {
    1247                 :         28 :         crypto_init_proc();
    1248                 :         28 :         return 0;
    1249                 :            : }
    1250                 :            : 
    1251                 :          0 : static void __exit crypto_algapi_exit(void)
    1252                 :            : {
    1253                 :          0 :         crypto_exit_proc();
    1254                 :          0 : }
    1255                 :            : 
    1256                 :            : module_init(crypto_algapi_init);
    1257                 :            : module_exit(crypto_algapi_exit);
    1258                 :            : 
    1259                 :            : MODULE_LICENSE("GPL");
    1260                 :            : MODULE_DESCRIPTION("Cryptographic algorithms API");

Generated by: LCOV version 1.14