1a61127c2SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 25068c7a8SSteffen Klassert /* 35068c7a8SSteffen Klassert * pcrypt - Parallel crypto wrapper. 45068c7a8SSteffen Klassert * 55068c7a8SSteffen Klassert * Copyright (C) 2009 secunet Security Networks AG 65068c7a8SSteffen Klassert * Copyright (C) 2009 Steffen Klassert <steffen.klassert@secunet.com> 75068c7a8SSteffen Klassert */ 85068c7a8SSteffen Klassert 95068c7a8SSteffen Klassert #include <crypto/algapi.h> 105068c7a8SSteffen Klassert #include <crypto/internal/aead.h> 11a5a22e57SHerbert Xu #include <linux/atomic.h> 125068c7a8SSteffen Klassert #include <linux/err.h> 135068c7a8SSteffen Klassert #include <linux/init.h> 145068c7a8SSteffen Klassert #include <linux/module.h> 155068c7a8SSteffen Klassert #include <linux/slab.h> 16a3fb1e33SDan Kruchinin #include <linux/kobject.h> 17d3f64e46SSteffen Klassert #include <linux/cpu.h> 185068c7a8SSteffen Klassert #include <crypto/pcrypt.h> 195068c7a8SSteffen Klassert 2063d35788SDaniel Jordan static struct padata_instance *pencrypt; 2163d35788SDaniel Jordan static struct padata_instance *pdecrypt; 22a3fb1e33SDan Kruchinin static struct kset *pcrypt_kset; 235068c7a8SSteffen Klassert 245068c7a8SSteffen Klassert struct pcrypt_instance_ctx { 2566d948e7SHerbert Xu struct crypto_aead_spawn spawn; 26bbefa1ddSHerbert Xu struct padata_shell *psenc; 27bbefa1ddSHerbert Xu struct padata_shell *psdec; 28a5a22e57SHerbert Xu atomic_t tfm_count; 295068c7a8SSteffen Klassert }; 305068c7a8SSteffen Klassert 315068c7a8SSteffen Klassert struct pcrypt_aead_ctx { 325068c7a8SSteffen Klassert struct crypto_aead *child; 335068c7a8SSteffen Klassert unsigned int cb_cpu; 345068c7a8SSteffen Klassert }; 355068c7a8SSteffen Klassert 36bbefa1ddSHerbert Xu static inline struct pcrypt_instance_ctx *pcrypt_tfm_ictx( 37bbefa1ddSHerbert Xu struct crypto_aead *tfm) 38bbefa1ddSHerbert Xu { 39bbefa1ddSHerbert Xu return aead_instance_ctx(aead_alg_instance(tfm)); 40bbefa1ddSHerbert Xu } 41bbefa1ddSHerbert Xu 425068c7a8SSteffen Klassert static int pcrypt_aead_setkey(struct crypto_aead *parent, 435068c7a8SSteffen Klassert const u8 *key, unsigned int keylen) 445068c7a8SSteffen Klassert { 455068c7a8SSteffen Klassert struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent); 465068c7a8SSteffen Klassert 475068c7a8SSteffen Klassert return crypto_aead_setkey(ctx->child, key, keylen); 485068c7a8SSteffen Klassert } 495068c7a8SSteffen Klassert 505068c7a8SSteffen Klassert static int pcrypt_aead_setauthsize(struct crypto_aead *parent, 515068c7a8SSteffen Klassert unsigned int authsize) 525068c7a8SSteffen Klassert { 535068c7a8SSteffen Klassert struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent); 545068c7a8SSteffen Klassert 555068c7a8SSteffen Klassert return crypto_aead_setauthsize(ctx->child, authsize); 565068c7a8SSteffen Klassert } 575068c7a8SSteffen Klassert 585068c7a8SSteffen Klassert static void pcrypt_aead_serial(struct padata_priv *padata) 595068c7a8SSteffen Klassert { 605068c7a8SSteffen Klassert struct pcrypt_request *preq = pcrypt_padata_request(padata); 615068c7a8SSteffen Klassert struct aead_request *req = pcrypt_request_ctx(preq); 625068c7a8SSteffen Klassert 635068c7a8SSteffen Klassert aead_request_complete(req->base.data, padata->info); 645068c7a8SSteffen Klassert } 655068c7a8SSteffen Klassert 665068c7a8SSteffen Klassert static void pcrypt_aead_done(struct crypto_async_request *areq, int err) 675068c7a8SSteffen Klassert { 685068c7a8SSteffen Klassert struct aead_request *req = areq->data; 695068c7a8SSteffen Klassert struct pcrypt_request *preq = aead_request_ctx(req); 705068c7a8SSteffen Klassert struct padata_priv *padata = pcrypt_request_padata(preq); 715068c7a8SSteffen Klassert 725068c7a8SSteffen Klassert padata->info = err; 735068c7a8SSteffen Klassert 745068c7a8SSteffen Klassert padata_do_serial(padata); 755068c7a8SSteffen Klassert } 765068c7a8SSteffen Klassert 775068c7a8SSteffen Klassert static void pcrypt_aead_enc(struct padata_priv *padata) 785068c7a8SSteffen Klassert { 795068c7a8SSteffen Klassert struct pcrypt_request *preq = pcrypt_padata_request(padata); 805068c7a8SSteffen Klassert struct aead_request *req = pcrypt_request_ctx(preq); 81*68b6dea8SDaniel Jordan int ret; 825068c7a8SSteffen Klassert 83*68b6dea8SDaniel Jordan ret = crypto_aead_encrypt(req); 845068c7a8SSteffen Klassert 85*68b6dea8SDaniel Jordan if (ret == -EINPROGRESS) 865068c7a8SSteffen Klassert return; 875068c7a8SSteffen Klassert 88*68b6dea8SDaniel Jordan padata->info = ret; 895068c7a8SSteffen Klassert padata_do_serial(padata); 905068c7a8SSteffen Klassert } 915068c7a8SSteffen Klassert 925068c7a8SSteffen Klassert static int pcrypt_aead_encrypt(struct aead_request *req) 935068c7a8SSteffen Klassert { 945068c7a8SSteffen Klassert int err; 955068c7a8SSteffen Klassert struct pcrypt_request *preq = aead_request_ctx(req); 965068c7a8SSteffen Klassert struct aead_request *creq = pcrypt_request_ctx(preq); 975068c7a8SSteffen Klassert struct padata_priv *padata = pcrypt_request_padata(preq); 985068c7a8SSteffen Klassert struct crypto_aead *aead = crypto_aead_reqtfm(req); 995068c7a8SSteffen Klassert struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(aead); 1005068c7a8SSteffen Klassert u32 flags = aead_request_flags(req); 101bbefa1ddSHerbert Xu struct pcrypt_instance_ctx *ictx; 102bbefa1ddSHerbert Xu 103bbefa1ddSHerbert Xu ictx = pcrypt_tfm_ictx(aead); 1045068c7a8SSteffen Klassert 1055068c7a8SSteffen Klassert memset(padata, 0, sizeof(struct padata_priv)); 1065068c7a8SSteffen Klassert 1075068c7a8SSteffen Klassert padata->parallel = pcrypt_aead_enc; 1085068c7a8SSteffen Klassert padata->serial = pcrypt_aead_serial; 1095068c7a8SSteffen Klassert 1105068c7a8SSteffen Klassert aead_request_set_tfm(creq, ctx->child); 1115068c7a8SSteffen Klassert aead_request_set_callback(creq, flags & ~CRYPTO_TFM_REQ_MAY_SLEEP, 1125068c7a8SSteffen Klassert pcrypt_aead_done, req); 1135068c7a8SSteffen Klassert aead_request_set_crypt(creq, req->src, req->dst, 1145068c7a8SSteffen Klassert req->cryptlen, req->iv); 1150496f560SHerbert Xu aead_request_set_ad(creq, req->assoclen); 1165068c7a8SSteffen Klassert 117bbefa1ddSHerbert Xu err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu); 11883f619f3SSteffen Klassert if (!err) 11983f619f3SSteffen Klassert return -EINPROGRESS; 1205068c7a8SSteffen Klassert 1215068c7a8SSteffen Klassert return err; 1225068c7a8SSteffen Klassert } 1235068c7a8SSteffen Klassert 1245068c7a8SSteffen Klassert static void pcrypt_aead_dec(struct padata_priv *padata) 1255068c7a8SSteffen Klassert { 1265068c7a8SSteffen Klassert struct pcrypt_request *preq = pcrypt_padata_request(padata); 1275068c7a8SSteffen Klassert struct aead_request *req = pcrypt_request_ctx(preq); 128*68b6dea8SDaniel Jordan int ret; 1295068c7a8SSteffen Klassert 130*68b6dea8SDaniel Jordan ret = crypto_aead_decrypt(req); 1315068c7a8SSteffen Klassert 132*68b6dea8SDaniel Jordan if (ret == -EINPROGRESS) 1335068c7a8SSteffen Klassert return; 1345068c7a8SSteffen Klassert 135*68b6dea8SDaniel Jordan padata->info = ret; 1365068c7a8SSteffen Klassert padata_do_serial(padata); 1375068c7a8SSteffen Klassert } 1385068c7a8SSteffen Klassert 1395068c7a8SSteffen Klassert static int pcrypt_aead_decrypt(struct aead_request *req) 1405068c7a8SSteffen Klassert { 1415068c7a8SSteffen Klassert int err; 1425068c7a8SSteffen Klassert struct pcrypt_request *preq = aead_request_ctx(req); 1435068c7a8SSteffen Klassert struct aead_request *creq = pcrypt_request_ctx(preq); 1445068c7a8SSteffen Klassert struct padata_priv *padata = pcrypt_request_padata(preq); 1455068c7a8SSteffen Klassert struct crypto_aead *aead = crypto_aead_reqtfm(req); 1465068c7a8SSteffen Klassert struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(aead); 1475068c7a8SSteffen Klassert u32 flags = aead_request_flags(req); 148bbefa1ddSHerbert Xu struct pcrypt_instance_ctx *ictx; 149bbefa1ddSHerbert Xu 150bbefa1ddSHerbert Xu ictx = pcrypt_tfm_ictx(aead); 1515068c7a8SSteffen Klassert 1525068c7a8SSteffen Klassert memset(padata, 0, sizeof(struct padata_priv)); 1535068c7a8SSteffen Klassert 1545068c7a8SSteffen Klassert padata->parallel = pcrypt_aead_dec; 1555068c7a8SSteffen Klassert padata->serial = pcrypt_aead_serial; 1565068c7a8SSteffen Klassert 1575068c7a8SSteffen Klassert aead_request_set_tfm(creq, ctx->child); 1585068c7a8SSteffen Klassert aead_request_set_callback(creq, flags & ~CRYPTO_TFM_REQ_MAY_SLEEP, 1595068c7a8SSteffen Klassert pcrypt_aead_done, req); 1605068c7a8SSteffen Klassert aead_request_set_crypt(creq, req->src, req->dst, 1615068c7a8SSteffen Klassert req->cryptlen, req->iv); 1620496f560SHerbert Xu aead_request_set_ad(creq, req->assoclen); 1635068c7a8SSteffen Klassert 164bbefa1ddSHerbert Xu err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu); 16583f619f3SSteffen Klassert if (!err) 16683f619f3SSteffen Klassert return -EINPROGRESS; 1675068c7a8SSteffen Klassert 1685068c7a8SSteffen Klassert return err; 1695068c7a8SSteffen Klassert } 1705068c7a8SSteffen Klassert 1710496f560SHerbert Xu static int pcrypt_aead_init_tfm(struct crypto_aead *tfm) 1725068c7a8SSteffen Klassert { 1735068c7a8SSteffen Klassert int cpu, cpu_index; 1740496f560SHerbert Xu struct aead_instance *inst = aead_alg_instance(tfm); 1750496f560SHerbert Xu struct pcrypt_instance_ctx *ictx = aead_instance_ctx(inst); 1760496f560SHerbert Xu struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(tfm); 1775068c7a8SSteffen Klassert struct crypto_aead *cipher; 1785068c7a8SSteffen Klassert 179a5a22e57SHerbert Xu cpu_index = (unsigned int)atomic_inc_return(&ictx->tfm_count) % 180a5a22e57SHerbert Xu cpumask_weight(cpu_online_mask); 1815068c7a8SSteffen Klassert 182fbf0ca1bSSteffen Klassert ctx->cb_cpu = cpumask_first(cpu_online_mask); 1835068c7a8SSteffen Klassert for (cpu = 0; cpu < cpu_index; cpu++) 184fbf0ca1bSSteffen Klassert ctx->cb_cpu = cpumask_next(ctx->cb_cpu, cpu_online_mask); 1855068c7a8SSteffen Klassert 1860496f560SHerbert Xu cipher = crypto_spawn_aead(&ictx->spawn); 1875068c7a8SSteffen Klassert 1885068c7a8SSteffen Klassert if (IS_ERR(cipher)) 1895068c7a8SSteffen Klassert return PTR_ERR(cipher); 1905068c7a8SSteffen Klassert 1915068c7a8SSteffen Klassert ctx->child = cipher; 1920496f560SHerbert Xu crypto_aead_set_reqsize(tfm, sizeof(struct pcrypt_request) + 1930496f560SHerbert Xu sizeof(struct aead_request) + 194fd0de978SHerbert Xu crypto_aead_reqsize(cipher)); 1955068c7a8SSteffen Klassert 1965068c7a8SSteffen Klassert return 0; 1975068c7a8SSteffen Klassert } 1985068c7a8SSteffen Klassert 1990496f560SHerbert Xu static void pcrypt_aead_exit_tfm(struct crypto_aead *tfm) 2005068c7a8SSteffen Klassert { 2010496f560SHerbert Xu struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(tfm); 2025068c7a8SSteffen Klassert 2035068c7a8SSteffen Klassert crypto_free_aead(ctx->child); 2045068c7a8SSteffen Klassert } 2055068c7a8SSteffen Klassert 206d76c6810SEric Biggers static void pcrypt_free(struct aead_instance *inst) 207d76c6810SEric Biggers { 208d76c6810SEric Biggers struct pcrypt_instance_ctx *ctx = aead_instance_ctx(inst); 209d76c6810SEric Biggers 210d76c6810SEric Biggers crypto_drop_aead(&ctx->spawn); 211bbefa1ddSHerbert Xu padata_free_shell(ctx->psdec); 212bbefa1ddSHerbert Xu padata_free_shell(ctx->psenc); 213d76c6810SEric Biggers kfree(inst); 214d76c6810SEric Biggers } 215d76c6810SEric Biggers 21666d948e7SHerbert Xu static int pcrypt_init_instance(struct crypto_instance *inst, 21766d948e7SHerbert Xu struct crypto_alg *alg) 2185068c7a8SSteffen Klassert { 2195068c7a8SSteffen Klassert if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, 2205068c7a8SSteffen Klassert "pcrypt(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) 22166d948e7SHerbert Xu return -ENAMETOOLONG; 2225068c7a8SSteffen Klassert 2235068c7a8SSteffen Klassert memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); 2245068c7a8SSteffen Klassert 2255068c7a8SSteffen Klassert inst->alg.cra_priority = alg->cra_priority + 100; 2265068c7a8SSteffen Klassert inst->alg.cra_blocksize = alg->cra_blocksize; 2275068c7a8SSteffen Klassert inst->alg.cra_alignmask = alg->cra_alignmask; 2285068c7a8SSteffen Klassert 22966d948e7SHerbert Xu return 0; 2305068c7a8SSteffen Klassert } 2315068c7a8SSteffen Klassert 2320496f560SHerbert Xu static int pcrypt_create_aead(struct crypto_template *tmpl, struct rtattr **tb, 2337bcb2c99SEric Biggers struct crypto_attr_type *algt) 2345068c7a8SSteffen Klassert { 23566d948e7SHerbert Xu struct pcrypt_instance_ctx *ctx; 2360496f560SHerbert Xu struct aead_instance *inst; 2370496f560SHerbert Xu struct aead_alg *alg; 2387bcb2c99SEric Biggers u32 mask = crypto_algt_inherited_mask(algt); 23966d948e7SHerbert Xu int err; 2405068c7a8SSteffen Klassert 24166d948e7SHerbert Xu inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); 24266d948e7SHerbert Xu if (!inst) 2430496f560SHerbert Xu return -ENOMEM; 24466d948e7SHerbert Xu 245bbefa1ddSHerbert Xu err = -ENOMEM; 246bbefa1ddSHerbert Xu 2470496f560SHerbert Xu ctx = aead_instance_ctx(inst); 248bbefa1ddSHerbert Xu ctx->psenc = padata_alloc_shell(pencrypt); 249bbefa1ddSHerbert Xu if (!ctx->psenc) 25007b24c7cSEric Biggers goto err_free_inst; 251bbefa1ddSHerbert Xu 252bbefa1ddSHerbert Xu ctx->psdec = padata_alloc_shell(pdecrypt); 253bbefa1ddSHerbert Xu if (!ctx->psdec) 25407b24c7cSEric Biggers goto err_free_inst; 255bbefa1ddSHerbert Xu 256cd900f0cSEric Biggers err = crypto_grab_aead(&ctx->spawn, aead_crypto_instance(inst), 2577bcb2c99SEric Biggers crypto_attr_alg_name(tb[1]), 0, mask); 25866d948e7SHerbert Xu if (err) 25907b24c7cSEric Biggers goto err_free_inst; 26066d948e7SHerbert Xu 2610496f560SHerbert Xu alg = crypto_spawn_aead_alg(&ctx->spawn); 2620496f560SHerbert Xu err = pcrypt_init_instance(aead_crypto_instance(inst), &alg->base); 26366d948e7SHerbert Xu if (err) 26407b24c7cSEric Biggers goto err_free_inst; 2655068c7a8SSteffen Klassert 2667bcb2c99SEric Biggers inst->alg.base.cra_flags |= CRYPTO_ALG_ASYNC; 267846f97dfSHerbert Xu 2680496f560SHerbert Xu inst->alg.ivsize = crypto_aead_alg_ivsize(alg); 2690496f560SHerbert Xu inst->alg.maxauthsize = crypto_aead_alg_maxauthsize(alg); 2705068c7a8SSteffen Klassert 2710496f560SHerbert Xu inst->alg.base.cra_ctxsize = sizeof(struct pcrypt_aead_ctx); 2725068c7a8SSteffen Klassert 2730496f560SHerbert Xu inst->alg.init = pcrypt_aead_init_tfm; 2740496f560SHerbert Xu inst->alg.exit = pcrypt_aead_exit_tfm; 2755068c7a8SSteffen Klassert 2760496f560SHerbert Xu inst->alg.setkey = pcrypt_aead_setkey; 2770496f560SHerbert Xu inst->alg.setauthsize = pcrypt_aead_setauthsize; 2780496f560SHerbert Xu inst->alg.encrypt = pcrypt_aead_encrypt; 2790496f560SHerbert Xu inst->alg.decrypt = pcrypt_aead_decrypt; 2805068c7a8SSteffen Klassert 281d76c6810SEric Biggers inst->free = pcrypt_free; 282d76c6810SEric Biggers 2830496f560SHerbert Xu err = aead_register_instance(tmpl, inst); 28407b24c7cSEric Biggers if (err) { 28507b24c7cSEric Biggers err_free_inst: 28607b24c7cSEric Biggers pcrypt_free(inst); 28707b24c7cSEric Biggers } 2880496f560SHerbert Xu return err; 2895068c7a8SSteffen Klassert } 2905068c7a8SSteffen Klassert 2910496f560SHerbert Xu static int pcrypt_create(struct crypto_template *tmpl, struct rtattr **tb) 2925068c7a8SSteffen Klassert { 2935068c7a8SSteffen Klassert struct crypto_attr_type *algt; 2945068c7a8SSteffen Klassert 2955068c7a8SSteffen Klassert algt = crypto_get_attr_type(tb); 2965068c7a8SSteffen Klassert if (IS_ERR(algt)) 2970496f560SHerbert Xu return PTR_ERR(algt); 2985068c7a8SSteffen Klassert 2995068c7a8SSteffen Klassert switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) { 3005068c7a8SSteffen Klassert case CRYPTO_ALG_TYPE_AEAD: 3017bcb2c99SEric Biggers return pcrypt_create_aead(tmpl, tb, algt); 3025068c7a8SSteffen Klassert } 3035068c7a8SSteffen Klassert 3040496f560SHerbert Xu return -EINVAL; 3055068c7a8SSteffen Klassert } 3065068c7a8SSteffen Klassert 307a3fb1e33SDan Kruchinin static int pcrypt_sysfs_add(struct padata_instance *pinst, const char *name) 308a3fb1e33SDan Kruchinin { 309a3fb1e33SDan Kruchinin int ret; 310a3fb1e33SDan Kruchinin 311a3fb1e33SDan Kruchinin pinst->kobj.kset = pcrypt_kset; 312b1e3874cSColin Ian King ret = kobject_add(&pinst->kobj, NULL, "%s", name); 313a3fb1e33SDan Kruchinin if (!ret) 314a3fb1e33SDan Kruchinin kobject_uevent(&pinst->kobj, KOBJ_ADD); 315a3fb1e33SDan Kruchinin 316a3fb1e33SDan Kruchinin return ret; 317a3fb1e33SDan Kruchinin } 318a3fb1e33SDan Kruchinin 31963d35788SDaniel Jordan static int pcrypt_init_padata(struct padata_instance **pinst, const char *name) 320e15bacbeSDan Kruchinin { 321e15bacbeSDan Kruchinin int ret = -ENOMEM; 322e15bacbeSDan Kruchinin 3233f257191SDaniel Jordan *pinst = padata_alloc(name); 32463d35788SDaniel Jordan if (!*pinst) 325e15bacbeSDan Kruchinin return ret; 326d3f64e46SSteffen Klassert 32763d35788SDaniel Jordan ret = pcrypt_sysfs_add(*pinst, name); 32863d35788SDaniel Jordan if (ret) 32963d35788SDaniel Jordan padata_free(*pinst); 33063d35788SDaniel Jordan 331e15bacbeSDan Kruchinin return ret; 332e15bacbeSDan Kruchinin } 333e15bacbeSDan Kruchinin 3345068c7a8SSteffen Klassert static struct crypto_template pcrypt_tmpl = { 3355068c7a8SSteffen Klassert .name = "pcrypt", 3360496f560SHerbert Xu .create = pcrypt_create, 3375068c7a8SSteffen Klassert .module = THIS_MODULE, 3385068c7a8SSteffen Klassert }; 3395068c7a8SSteffen Klassert 3405068c7a8SSteffen Klassert static int __init pcrypt_init(void) 3415068c7a8SSteffen Klassert { 342a3fb1e33SDan Kruchinin int err = -ENOMEM; 343a3fb1e33SDan Kruchinin 344a3fb1e33SDan Kruchinin pcrypt_kset = kset_create_and_add("pcrypt", NULL, kernel_kobj); 345a3fb1e33SDan Kruchinin if (!pcrypt_kset) 346a3fb1e33SDan Kruchinin goto err; 347e15bacbeSDan Kruchinin 348c57e842eSSteffen Klassert err = pcrypt_init_padata(&pencrypt, "pencrypt"); 349e15bacbeSDan Kruchinin if (err) 350a3fb1e33SDan Kruchinin goto err_unreg_kset; 3515068c7a8SSteffen Klassert 352c57e842eSSteffen Klassert err = pcrypt_init_padata(&pdecrypt, "pdecrypt"); 3534c879170SSteffen Klassert if (err) 354e15bacbeSDan Kruchinin goto err_deinit_pencrypt; 3554c879170SSteffen Klassert 3565068c7a8SSteffen Klassert return crypto_register_template(&pcrypt_tmpl); 3575068c7a8SSteffen Klassert 358e15bacbeSDan Kruchinin err_deinit_pencrypt: 359350ef051SDaniel Jordan padata_free(pencrypt); 360a3fb1e33SDan Kruchinin err_unreg_kset: 361a3fb1e33SDan Kruchinin kset_unregister(pcrypt_kset); 3625068c7a8SSteffen Klassert err: 3634c879170SSteffen Klassert return err; 3645068c7a8SSteffen Klassert } 3655068c7a8SSteffen Klassert 3665068c7a8SSteffen Klassert static void __exit pcrypt_exit(void) 3675068c7a8SSteffen Klassert { 36807bfd9bdSHerbert Xu crypto_unregister_template(&pcrypt_tmpl); 36907bfd9bdSHerbert Xu 370350ef051SDaniel Jordan padata_free(pencrypt); 371350ef051SDaniel Jordan padata_free(pdecrypt); 3725068c7a8SSteffen Klassert 373a3fb1e33SDan Kruchinin kset_unregister(pcrypt_kset); 3745068c7a8SSteffen Klassert } 3755068c7a8SSteffen Klassert 376c4741b23SEric Biggers subsys_initcall(pcrypt_init); 3775068c7a8SSteffen Klassert module_exit(pcrypt_exit); 3785068c7a8SSteffen Klassert 3795068c7a8SSteffen Klassert MODULE_LICENSE("GPL"); 3805068c7a8SSteffen Klassert MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>"); 3815068c7a8SSteffen Klassert MODULE_DESCRIPTION("Parallel crypto wrapper"); 3824943ba16SKees Cook MODULE_ALIAS_CRYPTO("pcrypt"); 383