162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * pcrypt - Parallel crypto wrapper. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2009 secunet Security Networks AG 662306a36Sopenharmony_ci * Copyright (C) 2009 Steffen Klassert <steffen.klassert@secunet.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <crypto/algapi.h> 1062306a36Sopenharmony_ci#include <crypto/internal/aead.h> 1162306a36Sopenharmony_ci#include <linux/atomic.h> 1262306a36Sopenharmony_ci#include <linux/err.h> 1362306a36Sopenharmony_ci#include <linux/init.h> 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci#include <linux/slab.h> 1662306a36Sopenharmony_ci#include <linux/kobject.h> 1762306a36Sopenharmony_ci#include <linux/cpu.h> 1862306a36Sopenharmony_ci#include <crypto/pcrypt.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic struct padata_instance *pencrypt; 2162306a36Sopenharmony_cistatic struct padata_instance *pdecrypt; 2262306a36Sopenharmony_cistatic struct kset *pcrypt_kset; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistruct pcrypt_instance_ctx { 2562306a36Sopenharmony_ci struct crypto_aead_spawn spawn; 2662306a36Sopenharmony_ci struct padata_shell *psenc; 2762306a36Sopenharmony_ci struct padata_shell *psdec; 2862306a36Sopenharmony_ci atomic_t tfm_count; 2962306a36Sopenharmony_ci}; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistruct pcrypt_aead_ctx { 3262306a36Sopenharmony_ci struct crypto_aead *child; 3362306a36Sopenharmony_ci unsigned int cb_cpu; 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic inline struct pcrypt_instance_ctx *pcrypt_tfm_ictx( 3762306a36Sopenharmony_ci struct crypto_aead *tfm) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci return aead_instance_ctx(aead_alg_instance(tfm)); 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic int pcrypt_aead_setkey(struct crypto_aead *parent, 4362306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci return crypto_aead_setkey(ctx->child, key, keylen); 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistatic int pcrypt_aead_setauthsize(struct crypto_aead *parent, 5162306a36Sopenharmony_ci unsigned int authsize) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci return crypto_aead_setauthsize(ctx->child, authsize); 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic void pcrypt_aead_serial(struct padata_priv *padata) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci struct pcrypt_request *preq = pcrypt_padata_request(padata); 6162306a36Sopenharmony_ci struct aead_request *req = pcrypt_request_ctx(preq); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci aead_request_complete(req->base.data, padata->info); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic void pcrypt_aead_done(void *data, int err) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci struct aead_request *req = data; 6962306a36Sopenharmony_ci struct pcrypt_request *preq = aead_request_ctx(req); 7062306a36Sopenharmony_ci struct padata_priv *padata = pcrypt_request_padata(preq); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci padata->info = err; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci padata_do_serial(padata); 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic void pcrypt_aead_enc(struct padata_priv *padata) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci struct pcrypt_request *preq = pcrypt_padata_request(padata); 8062306a36Sopenharmony_ci struct aead_request *req = pcrypt_request_ctx(preq); 8162306a36Sopenharmony_ci int ret; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci ret = crypto_aead_encrypt(req); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci if (ret == -EINPROGRESS) 8662306a36Sopenharmony_ci return; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci padata->info = ret; 8962306a36Sopenharmony_ci padata_do_serial(padata); 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistatic int pcrypt_aead_encrypt(struct aead_request *req) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci int err; 9562306a36Sopenharmony_ci struct pcrypt_request *preq = aead_request_ctx(req); 9662306a36Sopenharmony_ci struct aead_request *creq = pcrypt_request_ctx(preq); 9762306a36Sopenharmony_ci struct padata_priv *padata = pcrypt_request_padata(preq); 9862306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 9962306a36Sopenharmony_ci struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(aead); 10062306a36Sopenharmony_ci u32 flags = aead_request_flags(req); 10162306a36Sopenharmony_ci struct pcrypt_instance_ctx *ictx; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci ictx = pcrypt_tfm_ictx(aead); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci memset(padata, 0, sizeof(struct padata_priv)); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci padata->parallel = pcrypt_aead_enc; 10862306a36Sopenharmony_ci padata->serial = pcrypt_aead_serial; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci aead_request_set_tfm(creq, ctx->child); 11162306a36Sopenharmony_ci aead_request_set_callback(creq, flags & ~CRYPTO_TFM_REQ_MAY_SLEEP, 11262306a36Sopenharmony_ci pcrypt_aead_done, req); 11362306a36Sopenharmony_ci aead_request_set_crypt(creq, req->src, req->dst, 11462306a36Sopenharmony_ci req->cryptlen, req->iv); 11562306a36Sopenharmony_ci aead_request_set_ad(creq, req->assoclen); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu); 11862306a36Sopenharmony_ci if (!err) 11962306a36Sopenharmony_ci return -EINPROGRESS; 12062306a36Sopenharmony_ci if (err == -EBUSY) 12162306a36Sopenharmony_ci return -EAGAIN; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci return err; 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic void pcrypt_aead_dec(struct padata_priv *padata) 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci struct pcrypt_request *preq = pcrypt_padata_request(padata); 12962306a36Sopenharmony_ci struct aead_request *req = pcrypt_request_ctx(preq); 13062306a36Sopenharmony_ci int ret; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci ret = crypto_aead_decrypt(req); 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci if (ret == -EINPROGRESS) 13562306a36Sopenharmony_ci return; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci padata->info = ret; 13862306a36Sopenharmony_ci padata_do_serial(padata); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic int pcrypt_aead_decrypt(struct aead_request *req) 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci int err; 14462306a36Sopenharmony_ci struct pcrypt_request *preq = aead_request_ctx(req); 14562306a36Sopenharmony_ci struct aead_request *creq = pcrypt_request_ctx(preq); 14662306a36Sopenharmony_ci struct padata_priv *padata = pcrypt_request_padata(preq); 14762306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 14862306a36Sopenharmony_ci struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(aead); 14962306a36Sopenharmony_ci u32 flags = aead_request_flags(req); 15062306a36Sopenharmony_ci struct pcrypt_instance_ctx *ictx; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci ictx = pcrypt_tfm_ictx(aead); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci memset(padata, 0, sizeof(struct padata_priv)); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci padata->parallel = pcrypt_aead_dec; 15762306a36Sopenharmony_ci padata->serial = pcrypt_aead_serial; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci aead_request_set_tfm(creq, ctx->child); 16062306a36Sopenharmony_ci aead_request_set_callback(creq, flags & ~CRYPTO_TFM_REQ_MAY_SLEEP, 16162306a36Sopenharmony_ci pcrypt_aead_done, req); 16262306a36Sopenharmony_ci aead_request_set_crypt(creq, req->src, req->dst, 16362306a36Sopenharmony_ci req->cryptlen, req->iv); 16462306a36Sopenharmony_ci aead_request_set_ad(creq, req->assoclen); 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu); 16762306a36Sopenharmony_ci if (!err) 16862306a36Sopenharmony_ci return -EINPROGRESS; 16962306a36Sopenharmony_ci if (err == -EBUSY) 17062306a36Sopenharmony_ci return -EAGAIN; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci return err; 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cistatic int pcrypt_aead_init_tfm(struct crypto_aead *tfm) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci int cpu, cpu_index; 17862306a36Sopenharmony_ci struct aead_instance *inst = aead_alg_instance(tfm); 17962306a36Sopenharmony_ci struct pcrypt_instance_ctx *ictx = aead_instance_ctx(inst); 18062306a36Sopenharmony_ci struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(tfm); 18162306a36Sopenharmony_ci struct crypto_aead *cipher; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci cpu_index = (unsigned int)atomic_inc_return(&ictx->tfm_count) % 18462306a36Sopenharmony_ci cpumask_weight(cpu_online_mask); 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci ctx->cb_cpu = cpumask_first(cpu_online_mask); 18762306a36Sopenharmony_ci for (cpu = 0; cpu < cpu_index; cpu++) 18862306a36Sopenharmony_ci ctx->cb_cpu = cpumask_next(ctx->cb_cpu, cpu_online_mask); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci cipher = crypto_spawn_aead(&ictx->spawn); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci if (IS_ERR(cipher)) 19362306a36Sopenharmony_ci return PTR_ERR(cipher); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci ctx->child = cipher; 19662306a36Sopenharmony_ci crypto_aead_set_reqsize(tfm, sizeof(struct pcrypt_request) + 19762306a36Sopenharmony_ci sizeof(struct aead_request) + 19862306a36Sopenharmony_ci crypto_aead_reqsize(cipher)); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci return 0; 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistatic void pcrypt_aead_exit_tfm(struct crypto_aead *tfm) 20462306a36Sopenharmony_ci{ 20562306a36Sopenharmony_ci struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(tfm); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci crypto_free_aead(ctx->child); 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cistatic void pcrypt_free(struct aead_instance *inst) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci struct pcrypt_instance_ctx *ctx = aead_instance_ctx(inst); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci crypto_drop_aead(&ctx->spawn); 21562306a36Sopenharmony_ci padata_free_shell(ctx->psdec); 21662306a36Sopenharmony_ci padata_free_shell(ctx->psenc); 21762306a36Sopenharmony_ci kfree(inst); 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistatic int pcrypt_init_instance(struct crypto_instance *inst, 22162306a36Sopenharmony_ci struct crypto_alg *alg) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, 22462306a36Sopenharmony_ci "pcrypt(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) 22562306a36Sopenharmony_ci return -ENAMETOOLONG; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci inst->alg.cra_priority = alg->cra_priority + 100; 23062306a36Sopenharmony_ci inst->alg.cra_blocksize = alg->cra_blocksize; 23162306a36Sopenharmony_ci inst->alg.cra_alignmask = alg->cra_alignmask; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci return 0; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic int pcrypt_create_aead(struct crypto_template *tmpl, struct rtattr **tb, 23762306a36Sopenharmony_ci struct crypto_attr_type *algt) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci struct pcrypt_instance_ctx *ctx; 24062306a36Sopenharmony_ci struct aead_instance *inst; 24162306a36Sopenharmony_ci struct aead_alg *alg; 24262306a36Sopenharmony_ci u32 mask = crypto_algt_inherited_mask(algt); 24362306a36Sopenharmony_ci int err; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); 24662306a36Sopenharmony_ci if (!inst) 24762306a36Sopenharmony_ci return -ENOMEM; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci err = -ENOMEM; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci ctx = aead_instance_ctx(inst); 25262306a36Sopenharmony_ci ctx->psenc = padata_alloc_shell(pencrypt); 25362306a36Sopenharmony_ci if (!ctx->psenc) 25462306a36Sopenharmony_ci goto err_free_inst; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci ctx->psdec = padata_alloc_shell(pdecrypt); 25762306a36Sopenharmony_ci if (!ctx->psdec) 25862306a36Sopenharmony_ci goto err_free_inst; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci err = crypto_grab_aead(&ctx->spawn, aead_crypto_instance(inst), 26162306a36Sopenharmony_ci crypto_attr_alg_name(tb[1]), 0, mask); 26262306a36Sopenharmony_ci if (err) 26362306a36Sopenharmony_ci goto err_free_inst; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci alg = crypto_spawn_aead_alg(&ctx->spawn); 26662306a36Sopenharmony_ci err = pcrypt_init_instance(aead_crypto_instance(inst), &alg->base); 26762306a36Sopenharmony_ci if (err) 26862306a36Sopenharmony_ci goto err_free_inst; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci inst->alg.base.cra_flags |= CRYPTO_ALG_ASYNC; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci inst->alg.ivsize = crypto_aead_alg_ivsize(alg); 27362306a36Sopenharmony_ci inst->alg.maxauthsize = crypto_aead_alg_maxauthsize(alg); 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci inst->alg.base.cra_ctxsize = sizeof(struct pcrypt_aead_ctx); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci inst->alg.init = pcrypt_aead_init_tfm; 27862306a36Sopenharmony_ci inst->alg.exit = pcrypt_aead_exit_tfm; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci inst->alg.setkey = pcrypt_aead_setkey; 28162306a36Sopenharmony_ci inst->alg.setauthsize = pcrypt_aead_setauthsize; 28262306a36Sopenharmony_ci inst->alg.encrypt = pcrypt_aead_encrypt; 28362306a36Sopenharmony_ci inst->alg.decrypt = pcrypt_aead_decrypt; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci inst->free = pcrypt_free; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci err = aead_register_instance(tmpl, inst); 28862306a36Sopenharmony_ci if (err) { 28962306a36Sopenharmony_cierr_free_inst: 29062306a36Sopenharmony_ci pcrypt_free(inst); 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci return err; 29362306a36Sopenharmony_ci} 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_cistatic int pcrypt_create(struct crypto_template *tmpl, struct rtattr **tb) 29662306a36Sopenharmony_ci{ 29762306a36Sopenharmony_ci struct crypto_attr_type *algt; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci algt = crypto_get_attr_type(tb); 30062306a36Sopenharmony_ci if (IS_ERR(algt)) 30162306a36Sopenharmony_ci return PTR_ERR(algt); 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) { 30462306a36Sopenharmony_ci case CRYPTO_ALG_TYPE_AEAD: 30562306a36Sopenharmony_ci return pcrypt_create_aead(tmpl, tb, algt); 30662306a36Sopenharmony_ci } 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci return -EINVAL; 30962306a36Sopenharmony_ci} 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_cistatic int pcrypt_sysfs_add(struct padata_instance *pinst, const char *name) 31262306a36Sopenharmony_ci{ 31362306a36Sopenharmony_ci int ret; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci pinst->kobj.kset = pcrypt_kset; 31662306a36Sopenharmony_ci ret = kobject_add(&pinst->kobj, NULL, "%s", name); 31762306a36Sopenharmony_ci if (!ret) 31862306a36Sopenharmony_ci kobject_uevent(&pinst->kobj, KOBJ_ADD); 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci return ret; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_cistatic int pcrypt_init_padata(struct padata_instance **pinst, const char *name) 32462306a36Sopenharmony_ci{ 32562306a36Sopenharmony_ci int ret = -ENOMEM; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci *pinst = padata_alloc(name); 32862306a36Sopenharmony_ci if (!*pinst) 32962306a36Sopenharmony_ci return ret; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci ret = pcrypt_sysfs_add(*pinst, name); 33262306a36Sopenharmony_ci if (ret) 33362306a36Sopenharmony_ci padata_free(*pinst); 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci return ret; 33662306a36Sopenharmony_ci} 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_cistatic struct crypto_template pcrypt_tmpl = { 33962306a36Sopenharmony_ci .name = "pcrypt", 34062306a36Sopenharmony_ci .create = pcrypt_create, 34162306a36Sopenharmony_ci .module = THIS_MODULE, 34262306a36Sopenharmony_ci}; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_cistatic int __init pcrypt_init(void) 34562306a36Sopenharmony_ci{ 34662306a36Sopenharmony_ci int err = -ENOMEM; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci pcrypt_kset = kset_create_and_add("pcrypt", NULL, kernel_kobj); 34962306a36Sopenharmony_ci if (!pcrypt_kset) 35062306a36Sopenharmony_ci goto err; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci err = pcrypt_init_padata(&pencrypt, "pencrypt"); 35362306a36Sopenharmony_ci if (err) 35462306a36Sopenharmony_ci goto err_unreg_kset; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci err = pcrypt_init_padata(&pdecrypt, "pdecrypt"); 35762306a36Sopenharmony_ci if (err) 35862306a36Sopenharmony_ci goto err_deinit_pencrypt; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci return crypto_register_template(&pcrypt_tmpl); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_cierr_deinit_pencrypt: 36362306a36Sopenharmony_ci padata_free(pencrypt); 36462306a36Sopenharmony_cierr_unreg_kset: 36562306a36Sopenharmony_ci kset_unregister(pcrypt_kset); 36662306a36Sopenharmony_cierr: 36762306a36Sopenharmony_ci return err; 36862306a36Sopenharmony_ci} 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_cistatic void __exit pcrypt_exit(void) 37162306a36Sopenharmony_ci{ 37262306a36Sopenharmony_ci crypto_unregister_template(&pcrypt_tmpl); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci padata_free(pencrypt); 37562306a36Sopenharmony_ci padata_free(pdecrypt); 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci kset_unregister(pcrypt_kset); 37862306a36Sopenharmony_ci} 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_cisubsys_initcall(pcrypt_init); 38162306a36Sopenharmony_cimodule_exit(pcrypt_exit); 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 38462306a36Sopenharmony_ciMODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>"); 38562306a36Sopenharmony_ciMODULE_DESCRIPTION("Parallel crypto wrapper"); 38662306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("pcrypt"); 387