162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * CTR: Counter mode 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <crypto/algapi.h> 962306a36Sopenharmony_ci#include <crypto/ctr.h> 1062306a36Sopenharmony_ci#include <crypto/internal/cipher.h> 1162306a36Sopenharmony_ci#include <crypto/internal/skcipher.h> 1262306a36Sopenharmony_ci#include <linux/err.h> 1362306a36Sopenharmony_ci#include <linux/init.h> 1462306a36Sopenharmony_ci#include <linux/kernel.h> 1562306a36Sopenharmony_ci#include <linux/module.h> 1662306a36Sopenharmony_ci#include <linux/slab.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistruct crypto_rfc3686_ctx { 1962306a36Sopenharmony_ci struct crypto_skcipher *child; 2062306a36Sopenharmony_ci u8 nonce[CTR_RFC3686_NONCE_SIZE]; 2162306a36Sopenharmony_ci}; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistruct crypto_rfc3686_req_ctx { 2462306a36Sopenharmony_ci u8 iv[CTR_RFC3686_BLOCK_SIZE]; 2562306a36Sopenharmony_ci struct skcipher_request subreq CRYPTO_MINALIGN_ATTR; 2662306a36Sopenharmony_ci}; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic void crypto_ctr_crypt_final(struct skcipher_walk *walk, 2962306a36Sopenharmony_ci struct crypto_cipher *tfm) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci unsigned int bsize = crypto_cipher_blocksize(tfm); 3262306a36Sopenharmony_ci unsigned long alignmask = crypto_cipher_alignmask(tfm); 3362306a36Sopenharmony_ci u8 *ctrblk = walk->iv; 3462306a36Sopenharmony_ci u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK]; 3562306a36Sopenharmony_ci u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1); 3662306a36Sopenharmony_ci u8 *src = walk->src.virt.addr; 3762306a36Sopenharmony_ci u8 *dst = walk->dst.virt.addr; 3862306a36Sopenharmony_ci unsigned int nbytes = walk->nbytes; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci crypto_cipher_encrypt_one(tfm, keystream, ctrblk); 4162306a36Sopenharmony_ci crypto_xor_cpy(dst, keystream, src, nbytes); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci crypto_inc(ctrblk, bsize); 4462306a36Sopenharmony_ci} 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic int crypto_ctr_crypt_segment(struct skcipher_walk *walk, 4762306a36Sopenharmony_ci struct crypto_cipher *tfm) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = 5062306a36Sopenharmony_ci crypto_cipher_alg(tfm)->cia_encrypt; 5162306a36Sopenharmony_ci unsigned int bsize = crypto_cipher_blocksize(tfm); 5262306a36Sopenharmony_ci u8 *ctrblk = walk->iv; 5362306a36Sopenharmony_ci u8 *src = walk->src.virt.addr; 5462306a36Sopenharmony_ci u8 *dst = walk->dst.virt.addr; 5562306a36Sopenharmony_ci unsigned int nbytes = walk->nbytes; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci do { 5862306a36Sopenharmony_ci /* create keystream */ 5962306a36Sopenharmony_ci fn(crypto_cipher_tfm(tfm), dst, ctrblk); 6062306a36Sopenharmony_ci crypto_xor(dst, src, bsize); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci /* increment counter in counterblock */ 6362306a36Sopenharmony_ci crypto_inc(ctrblk, bsize); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci src += bsize; 6662306a36Sopenharmony_ci dst += bsize; 6762306a36Sopenharmony_ci } while ((nbytes -= bsize) >= bsize); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci return nbytes; 7062306a36Sopenharmony_ci} 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistatic int crypto_ctr_crypt_inplace(struct skcipher_walk *walk, 7362306a36Sopenharmony_ci struct crypto_cipher *tfm) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = 7662306a36Sopenharmony_ci crypto_cipher_alg(tfm)->cia_encrypt; 7762306a36Sopenharmony_ci unsigned int bsize = crypto_cipher_blocksize(tfm); 7862306a36Sopenharmony_ci unsigned long alignmask = crypto_cipher_alignmask(tfm); 7962306a36Sopenharmony_ci unsigned int nbytes = walk->nbytes; 8062306a36Sopenharmony_ci u8 *ctrblk = walk->iv; 8162306a36Sopenharmony_ci u8 *src = walk->src.virt.addr; 8262306a36Sopenharmony_ci u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK]; 8362306a36Sopenharmony_ci u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci do { 8662306a36Sopenharmony_ci /* create keystream */ 8762306a36Sopenharmony_ci fn(crypto_cipher_tfm(tfm), keystream, ctrblk); 8862306a36Sopenharmony_ci crypto_xor(src, keystream, bsize); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci /* increment counter in counterblock */ 9162306a36Sopenharmony_ci crypto_inc(ctrblk, bsize); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci src += bsize; 9462306a36Sopenharmony_ci } while ((nbytes -= bsize) >= bsize); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci return nbytes; 9762306a36Sopenharmony_ci} 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_cistatic int crypto_ctr_crypt(struct skcipher_request *req) 10062306a36Sopenharmony_ci{ 10162306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 10262306a36Sopenharmony_ci struct crypto_cipher *cipher = skcipher_cipher_simple(tfm); 10362306a36Sopenharmony_ci const unsigned int bsize = crypto_cipher_blocksize(cipher); 10462306a36Sopenharmony_ci struct skcipher_walk walk; 10562306a36Sopenharmony_ci unsigned int nbytes; 10662306a36Sopenharmony_ci int err; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci while (walk.nbytes >= bsize) { 11162306a36Sopenharmony_ci if (walk.src.virt.addr == walk.dst.virt.addr) 11262306a36Sopenharmony_ci nbytes = crypto_ctr_crypt_inplace(&walk, cipher); 11362306a36Sopenharmony_ci else 11462306a36Sopenharmony_ci nbytes = crypto_ctr_crypt_segment(&walk, cipher); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci err = skcipher_walk_done(&walk, nbytes); 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci if (walk.nbytes) { 12062306a36Sopenharmony_ci crypto_ctr_crypt_final(&walk, cipher); 12162306a36Sopenharmony_ci err = skcipher_walk_done(&walk, 0); 12262306a36Sopenharmony_ci } 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci return err; 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistatic int crypto_ctr_create(struct crypto_template *tmpl, struct rtattr **tb) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci struct skcipher_instance *inst; 13062306a36Sopenharmony_ci struct crypto_alg *alg; 13162306a36Sopenharmony_ci int err; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci inst = skcipher_alloc_instance_simple(tmpl, tb); 13462306a36Sopenharmony_ci if (IS_ERR(inst)) 13562306a36Sopenharmony_ci return PTR_ERR(inst); 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci alg = skcipher_ialg_simple(inst); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci /* Block size must be >= 4 bytes. */ 14062306a36Sopenharmony_ci err = -EINVAL; 14162306a36Sopenharmony_ci if (alg->cra_blocksize < 4) 14262306a36Sopenharmony_ci goto out_free_inst; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci /* If this is false we'd fail the alignment of crypto_inc. */ 14562306a36Sopenharmony_ci if (alg->cra_blocksize % 4) 14662306a36Sopenharmony_ci goto out_free_inst; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci /* CTR mode is a stream cipher. */ 14962306a36Sopenharmony_ci inst->alg.base.cra_blocksize = 1; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci /* 15262306a36Sopenharmony_ci * To simplify the implementation, configure the skcipher walk to only 15362306a36Sopenharmony_ci * give a partial block at the very end, never earlier. 15462306a36Sopenharmony_ci */ 15562306a36Sopenharmony_ci inst->alg.chunksize = alg->cra_blocksize; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci inst->alg.encrypt = crypto_ctr_crypt; 15862306a36Sopenharmony_ci inst->alg.decrypt = crypto_ctr_crypt; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci err = skcipher_register_instance(tmpl, inst); 16162306a36Sopenharmony_ci if (err) { 16262306a36Sopenharmony_ciout_free_inst: 16362306a36Sopenharmony_ci inst->free(inst); 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci return err; 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic int crypto_rfc3686_setkey(struct crypto_skcipher *parent, 17062306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(parent); 17362306a36Sopenharmony_ci struct crypto_skcipher *child = ctx->child; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci /* the nonce is stored in bytes at end of key */ 17662306a36Sopenharmony_ci if (keylen < CTR_RFC3686_NONCE_SIZE) 17762306a36Sopenharmony_ci return -EINVAL; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci memcpy(ctx->nonce, key + (keylen - CTR_RFC3686_NONCE_SIZE), 18062306a36Sopenharmony_ci CTR_RFC3686_NONCE_SIZE); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci keylen -= CTR_RFC3686_NONCE_SIZE; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); 18562306a36Sopenharmony_ci crypto_skcipher_set_flags(child, crypto_skcipher_get_flags(parent) & 18662306a36Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 18762306a36Sopenharmony_ci return crypto_skcipher_setkey(child, key, keylen); 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistatic int crypto_rfc3686_crypt(struct skcipher_request *req) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 19362306a36Sopenharmony_ci struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(tfm); 19462306a36Sopenharmony_ci struct crypto_skcipher *child = ctx->child; 19562306a36Sopenharmony_ci unsigned long align = crypto_skcipher_alignmask(tfm); 19662306a36Sopenharmony_ci struct crypto_rfc3686_req_ctx *rctx = 19762306a36Sopenharmony_ci (void *)PTR_ALIGN((u8 *)skcipher_request_ctx(req), align + 1); 19862306a36Sopenharmony_ci struct skcipher_request *subreq = &rctx->subreq; 19962306a36Sopenharmony_ci u8 *iv = rctx->iv; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci /* set up counter block */ 20262306a36Sopenharmony_ci memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); 20362306a36Sopenharmony_ci memcpy(iv + CTR_RFC3686_NONCE_SIZE, req->iv, CTR_RFC3686_IV_SIZE); 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci /* initialize counter portion of counter block */ 20662306a36Sopenharmony_ci *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) = 20762306a36Sopenharmony_ci cpu_to_be32(1); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci skcipher_request_set_tfm(subreq, child); 21062306a36Sopenharmony_ci skcipher_request_set_callback(subreq, req->base.flags, 21162306a36Sopenharmony_ci req->base.complete, req->base.data); 21262306a36Sopenharmony_ci skcipher_request_set_crypt(subreq, req->src, req->dst, 21362306a36Sopenharmony_ci req->cryptlen, iv); 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci return crypto_skcipher_encrypt(subreq); 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_cistatic int crypto_rfc3686_init_tfm(struct crypto_skcipher *tfm) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci struct skcipher_instance *inst = skcipher_alg_instance(tfm); 22162306a36Sopenharmony_ci struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst); 22262306a36Sopenharmony_ci struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(tfm); 22362306a36Sopenharmony_ci struct crypto_skcipher *cipher; 22462306a36Sopenharmony_ci unsigned long align; 22562306a36Sopenharmony_ci unsigned int reqsize; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci cipher = crypto_spawn_skcipher(spawn); 22862306a36Sopenharmony_ci if (IS_ERR(cipher)) 22962306a36Sopenharmony_ci return PTR_ERR(cipher); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci ctx->child = cipher; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci align = crypto_skcipher_alignmask(tfm); 23462306a36Sopenharmony_ci align &= ~(crypto_tfm_ctx_alignment() - 1); 23562306a36Sopenharmony_ci reqsize = align + sizeof(struct crypto_rfc3686_req_ctx) + 23662306a36Sopenharmony_ci crypto_skcipher_reqsize(cipher); 23762306a36Sopenharmony_ci crypto_skcipher_set_reqsize(tfm, reqsize); 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci return 0; 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistatic void crypto_rfc3686_exit_tfm(struct crypto_skcipher *tfm) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(tfm); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci crypto_free_skcipher(ctx->child); 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic void crypto_rfc3686_free(struct skcipher_instance *inst) 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci crypto_drop_skcipher(spawn); 25462306a36Sopenharmony_ci kfree(inst); 25562306a36Sopenharmony_ci} 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistatic int crypto_rfc3686_create(struct crypto_template *tmpl, 25862306a36Sopenharmony_ci struct rtattr **tb) 25962306a36Sopenharmony_ci{ 26062306a36Sopenharmony_ci struct skcipher_instance *inst; 26162306a36Sopenharmony_ci struct skcipher_alg *alg; 26262306a36Sopenharmony_ci struct crypto_skcipher_spawn *spawn; 26362306a36Sopenharmony_ci u32 mask; 26462306a36Sopenharmony_ci int err; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask); 26762306a36Sopenharmony_ci if (err) 26862306a36Sopenharmony_ci return err; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 27162306a36Sopenharmony_ci if (!inst) 27262306a36Sopenharmony_ci return -ENOMEM; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci spawn = skcipher_instance_ctx(inst); 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst), 27762306a36Sopenharmony_ci crypto_attr_alg_name(tb[1]), 0, mask); 27862306a36Sopenharmony_ci if (err) 27962306a36Sopenharmony_ci goto err_free_inst; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci alg = crypto_spawn_skcipher_alg(spawn); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci /* We only support 16-byte blocks. */ 28462306a36Sopenharmony_ci err = -EINVAL; 28562306a36Sopenharmony_ci if (crypto_skcipher_alg_ivsize(alg) != CTR_RFC3686_BLOCK_SIZE) 28662306a36Sopenharmony_ci goto err_free_inst; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci /* Not a stream cipher? */ 28962306a36Sopenharmony_ci if (alg->base.cra_blocksize != 1) 29062306a36Sopenharmony_ci goto err_free_inst; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci err = -ENAMETOOLONG; 29362306a36Sopenharmony_ci if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, 29462306a36Sopenharmony_ci "rfc3686(%s)", alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME) 29562306a36Sopenharmony_ci goto err_free_inst; 29662306a36Sopenharmony_ci if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, 29762306a36Sopenharmony_ci "rfc3686(%s)", alg->base.cra_driver_name) >= 29862306a36Sopenharmony_ci CRYPTO_MAX_ALG_NAME) 29962306a36Sopenharmony_ci goto err_free_inst; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci inst->alg.base.cra_priority = alg->base.cra_priority; 30262306a36Sopenharmony_ci inst->alg.base.cra_blocksize = 1; 30362306a36Sopenharmony_ci inst->alg.base.cra_alignmask = alg->base.cra_alignmask; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci inst->alg.ivsize = CTR_RFC3686_IV_SIZE; 30662306a36Sopenharmony_ci inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg); 30762306a36Sopenharmony_ci inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) + 30862306a36Sopenharmony_ci CTR_RFC3686_NONCE_SIZE; 30962306a36Sopenharmony_ci inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) + 31062306a36Sopenharmony_ci CTR_RFC3686_NONCE_SIZE; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci inst->alg.setkey = crypto_rfc3686_setkey; 31362306a36Sopenharmony_ci inst->alg.encrypt = crypto_rfc3686_crypt; 31462306a36Sopenharmony_ci inst->alg.decrypt = crypto_rfc3686_crypt; 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx); 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci inst->alg.init = crypto_rfc3686_init_tfm; 31962306a36Sopenharmony_ci inst->alg.exit = crypto_rfc3686_exit_tfm; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci inst->free = crypto_rfc3686_free; 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci err = skcipher_register_instance(tmpl, inst); 32462306a36Sopenharmony_ci if (err) { 32562306a36Sopenharmony_cierr_free_inst: 32662306a36Sopenharmony_ci crypto_rfc3686_free(inst); 32762306a36Sopenharmony_ci } 32862306a36Sopenharmony_ci return err; 32962306a36Sopenharmony_ci} 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_cistatic struct crypto_template crypto_ctr_tmpls[] = { 33262306a36Sopenharmony_ci { 33362306a36Sopenharmony_ci .name = "ctr", 33462306a36Sopenharmony_ci .create = crypto_ctr_create, 33562306a36Sopenharmony_ci .module = THIS_MODULE, 33662306a36Sopenharmony_ci }, { 33762306a36Sopenharmony_ci .name = "rfc3686", 33862306a36Sopenharmony_ci .create = crypto_rfc3686_create, 33962306a36Sopenharmony_ci .module = THIS_MODULE, 34062306a36Sopenharmony_ci }, 34162306a36Sopenharmony_ci}; 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistatic int __init crypto_ctr_module_init(void) 34462306a36Sopenharmony_ci{ 34562306a36Sopenharmony_ci return crypto_register_templates(crypto_ctr_tmpls, 34662306a36Sopenharmony_ci ARRAY_SIZE(crypto_ctr_tmpls)); 34762306a36Sopenharmony_ci} 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_cistatic void __exit crypto_ctr_module_exit(void) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci crypto_unregister_templates(crypto_ctr_tmpls, 35262306a36Sopenharmony_ci ARRAY_SIZE(crypto_ctr_tmpls)); 35362306a36Sopenharmony_ci} 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_cisubsys_initcall(crypto_ctr_module_init); 35662306a36Sopenharmony_cimodule_exit(crypto_ctr_module_exit); 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 35962306a36Sopenharmony_ciMODULE_DESCRIPTION("CTR block cipher mode of operation"); 36062306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("rfc3686"); 36162306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("ctr"); 36262306a36Sopenharmony_ciMODULE_IMPORT_NS(CRYPTO_INTERNAL); 363