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