LCOV - code coverage report
Current view: top level - crypto - algapi.c (source / functions) Hit Total Coverage
Test: Real Lines: 187 405 46.2 %
Date: 2020-10-17 15:46:16 Functions: 0 47 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

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

Generated by: LCOV version 1.14