18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * CTR: Counter mode 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <crypto/algapi.h> 98c2ecf20Sopenharmony_ci#include <crypto/ctr.h> 108c2ecf20Sopenharmony_ci#include <crypto/internal/skcipher.h> 118c2ecf20Sopenharmony_ci#include <linux/err.h> 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/kernel.h> 148c2ecf20Sopenharmony_ci#include <linux/module.h> 158c2ecf20Sopenharmony_ci#include <linux/slab.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistruct crypto_rfc3686_ctx { 188c2ecf20Sopenharmony_ci struct crypto_skcipher *child; 198c2ecf20Sopenharmony_ci u8 nonce[CTR_RFC3686_NONCE_SIZE]; 208c2ecf20Sopenharmony_ci}; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistruct crypto_rfc3686_req_ctx { 238c2ecf20Sopenharmony_ci u8 iv[CTR_RFC3686_BLOCK_SIZE]; 248c2ecf20Sopenharmony_ci struct skcipher_request subreq CRYPTO_MINALIGN_ATTR; 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic void crypto_ctr_crypt_final(struct skcipher_walk *walk, 288c2ecf20Sopenharmony_ci struct crypto_cipher *tfm) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci unsigned int bsize = crypto_cipher_blocksize(tfm); 318c2ecf20Sopenharmony_ci unsigned long alignmask = crypto_cipher_alignmask(tfm); 328c2ecf20Sopenharmony_ci u8 *ctrblk = walk->iv; 338c2ecf20Sopenharmony_ci u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK]; 348c2ecf20Sopenharmony_ci u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1); 358c2ecf20Sopenharmony_ci u8 *src = walk->src.virt.addr; 368c2ecf20Sopenharmony_ci u8 *dst = walk->dst.virt.addr; 378c2ecf20Sopenharmony_ci unsigned int nbytes = walk->nbytes; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci crypto_cipher_encrypt_one(tfm, keystream, ctrblk); 408c2ecf20Sopenharmony_ci crypto_xor_cpy(dst, keystream, src, nbytes); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci crypto_inc(ctrblk, bsize); 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic int crypto_ctr_crypt_segment(struct skcipher_walk *walk, 468c2ecf20Sopenharmony_ci struct crypto_cipher *tfm) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = 498c2ecf20Sopenharmony_ci crypto_cipher_alg(tfm)->cia_encrypt; 508c2ecf20Sopenharmony_ci unsigned int bsize = crypto_cipher_blocksize(tfm); 518c2ecf20Sopenharmony_ci u8 *ctrblk = walk->iv; 528c2ecf20Sopenharmony_ci u8 *src = walk->src.virt.addr; 538c2ecf20Sopenharmony_ci u8 *dst = walk->dst.virt.addr; 548c2ecf20Sopenharmony_ci unsigned int nbytes = walk->nbytes; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci do { 578c2ecf20Sopenharmony_ci /* create keystream */ 588c2ecf20Sopenharmony_ci fn(crypto_cipher_tfm(tfm), dst, ctrblk); 598c2ecf20Sopenharmony_ci crypto_xor(dst, src, bsize); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* increment counter in counterblock */ 628c2ecf20Sopenharmony_ci crypto_inc(ctrblk, bsize); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci src += bsize; 658c2ecf20Sopenharmony_ci dst += bsize; 668c2ecf20Sopenharmony_ci } while ((nbytes -= bsize) >= bsize); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return nbytes; 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic int crypto_ctr_crypt_inplace(struct skcipher_walk *walk, 728c2ecf20Sopenharmony_ci struct crypto_cipher *tfm) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = 758c2ecf20Sopenharmony_ci crypto_cipher_alg(tfm)->cia_encrypt; 768c2ecf20Sopenharmony_ci unsigned int bsize = crypto_cipher_blocksize(tfm); 778c2ecf20Sopenharmony_ci unsigned long alignmask = crypto_cipher_alignmask(tfm); 788c2ecf20Sopenharmony_ci unsigned int nbytes = walk->nbytes; 798c2ecf20Sopenharmony_ci u8 *ctrblk = walk->iv; 808c2ecf20Sopenharmony_ci u8 *src = walk->src.virt.addr; 818c2ecf20Sopenharmony_ci u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK]; 828c2ecf20Sopenharmony_ci u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci do { 858c2ecf20Sopenharmony_ci /* create keystream */ 868c2ecf20Sopenharmony_ci fn(crypto_cipher_tfm(tfm), keystream, ctrblk); 878c2ecf20Sopenharmony_ci crypto_xor(src, keystream, bsize); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci /* increment counter in counterblock */ 908c2ecf20Sopenharmony_ci crypto_inc(ctrblk, bsize); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci src += bsize; 938c2ecf20Sopenharmony_ci } while ((nbytes -= bsize) >= bsize); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci return nbytes; 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic int crypto_ctr_crypt(struct skcipher_request *req) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 1018c2ecf20Sopenharmony_ci struct crypto_cipher *cipher = skcipher_cipher_simple(tfm); 1028c2ecf20Sopenharmony_ci const unsigned int bsize = crypto_cipher_blocksize(cipher); 1038c2ecf20Sopenharmony_ci struct skcipher_walk walk; 1048c2ecf20Sopenharmony_ci unsigned int nbytes; 1058c2ecf20Sopenharmony_ci int err; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci while (walk.nbytes >= bsize) { 1108c2ecf20Sopenharmony_ci if (walk.src.virt.addr == walk.dst.virt.addr) 1118c2ecf20Sopenharmony_ci nbytes = crypto_ctr_crypt_inplace(&walk, cipher); 1128c2ecf20Sopenharmony_ci else 1138c2ecf20Sopenharmony_ci nbytes = crypto_ctr_crypt_segment(&walk, cipher); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci err = skcipher_walk_done(&walk, nbytes); 1168c2ecf20Sopenharmony_ci } 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci if (walk.nbytes) { 1198c2ecf20Sopenharmony_ci crypto_ctr_crypt_final(&walk, cipher); 1208c2ecf20Sopenharmony_ci err = skcipher_walk_done(&walk, 0); 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci return err; 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic int crypto_ctr_create(struct crypto_template *tmpl, struct rtattr **tb) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci struct skcipher_instance *inst; 1298c2ecf20Sopenharmony_ci struct crypto_alg *alg; 1308c2ecf20Sopenharmony_ci int err; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci inst = skcipher_alloc_instance_simple(tmpl, tb); 1338c2ecf20Sopenharmony_ci if (IS_ERR(inst)) 1348c2ecf20Sopenharmony_ci return PTR_ERR(inst); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci alg = skcipher_ialg_simple(inst); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci /* Block size must be >= 4 bytes. */ 1398c2ecf20Sopenharmony_ci err = -EINVAL; 1408c2ecf20Sopenharmony_ci if (alg->cra_blocksize < 4) 1418c2ecf20Sopenharmony_ci goto out_free_inst; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci /* If this is false we'd fail the alignment of crypto_inc. */ 1448c2ecf20Sopenharmony_ci if (alg->cra_blocksize % 4) 1458c2ecf20Sopenharmony_ci goto out_free_inst; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci /* CTR mode is a stream cipher. */ 1488c2ecf20Sopenharmony_ci inst->alg.base.cra_blocksize = 1; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci /* 1518c2ecf20Sopenharmony_ci * To simplify the implementation, configure the skcipher walk to only 1528c2ecf20Sopenharmony_ci * give a partial block at the very end, never earlier. 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_ci inst->alg.chunksize = alg->cra_blocksize; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci inst->alg.encrypt = crypto_ctr_crypt; 1578c2ecf20Sopenharmony_ci inst->alg.decrypt = crypto_ctr_crypt; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci err = skcipher_register_instance(tmpl, inst); 1608c2ecf20Sopenharmony_ci if (err) { 1618c2ecf20Sopenharmony_ciout_free_inst: 1628c2ecf20Sopenharmony_ci inst->free(inst); 1638c2ecf20Sopenharmony_ci } 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci return err; 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistatic int crypto_rfc3686_setkey(struct crypto_skcipher *parent, 1698c2ecf20Sopenharmony_ci const u8 *key, unsigned int keylen) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(parent); 1728c2ecf20Sopenharmony_ci struct crypto_skcipher *child = ctx->child; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci /* the nonce is stored in bytes at end of key */ 1758c2ecf20Sopenharmony_ci if (keylen < CTR_RFC3686_NONCE_SIZE) 1768c2ecf20Sopenharmony_ci return -EINVAL; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci memcpy(ctx->nonce, key + (keylen - CTR_RFC3686_NONCE_SIZE), 1798c2ecf20Sopenharmony_ci CTR_RFC3686_NONCE_SIZE); 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci keylen -= CTR_RFC3686_NONCE_SIZE; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); 1848c2ecf20Sopenharmony_ci crypto_skcipher_set_flags(child, crypto_skcipher_get_flags(parent) & 1858c2ecf20Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 1868c2ecf20Sopenharmony_ci return crypto_skcipher_setkey(child, key, keylen); 1878c2ecf20Sopenharmony_ci} 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cistatic int crypto_rfc3686_crypt(struct skcipher_request *req) 1908c2ecf20Sopenharmony_ci{ 1918c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 1928c2ecf20Sopenharmony_ci struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(tfm); 1938c2ecf20Sopenharmony_ci struct crypto_skcipher *child = ctx->child; 1948c2ecf20Sopenharmony_ci unsigned long align = crypto_skcipher_alignmask(tfm); 1958c2ecf20Sopenharmony_ci struct crypto_rfc3686_req_ctx *rctx = 1968c2ecf20Sopenharmony_ci (void *)PTR_ALIGN((u8 *)skcipher_request_ctx(req), align + 1); 1978c2ecf20Sopenharmony_ci struct skcipher_request *subreq = &rctx->subreq; 1988c2ecf20Sopenharmony_ci u8 *iv = rctx->iv; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* set up counter block */ 2018c2ecf20Sopenharmony_ci memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); 2028c2ecf20Sopenharmony_ci memcpy(iv + CTR_RFC3686_NONCE_SIZE, req->iv, CTR_RFC3686_IV_SIZE); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci /* initialize counter portion of counter block */ 2058c2ecf20Sopenharmony_ci *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) = 2068c2ecf20Sopenharmony_ci cpu_to_be32(1); 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci skcipher_request_set_tfm(subreq, child); 2098c2ecf20Sopenharmony_ci skcipher_request_set_callback(subreq, req->base.flags, 2108c2ecf20Sopenharmony_ci req->base.complete, req->base.data); 2118c2ecf20Sopenharmony_ci skcipher_request_set_crypt(subreq, req->src, req->dst, 2128c2ecf20Sopenharmony_ci req->cryptlen, iv); 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci return crypto_skcipher_encrypt(subreq); 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_cistatic int crypto_rfc3686_init_tfm(struct crypto_skcipher *tfm) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci struct skcipher_instance *inst = skcipher_alg_instance(tfm); 2208c2ecf20Sopenharmony_ci struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst); 2218c2ecf20Sopenharmony_ci struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(tfm); 2228c2ecf20Sopenharmony_ci struct crypto_skcipher *cipher; 2238c2ecf20Sopenharmony_ci unsigned long align; 2248c2ecf20Sopenharmony_ci unsigned int reqsize; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci cipher = crypto_spawn_skcipher(spawn); 2278c2ecf20Sopenharmony_ci if (IS_ERR(cipher)) 2288c2ecf20Sopenharmony_ci return PTR_ERR(cipher); 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci ctx->child = cipher; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci align = crypto_skcipher_alignmask(tfm); 2338c2ecf20Sopenharmony_ci align &= ~(crypto_tfm_ctx_alignment() - 1); 2348c2ecf20Sopenharmony_ci reqsize = align + sizeof(struct crypto_rfc3686_req_ctx) + 2358c2ecf20Sopenharmony_ci crypto_skcipher_reqsize(cipher); 2368c2ecf20Sopenharmony_ci crypto_skcipher_set_reqsize(tfm, reqsize); 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci return 0; 2398c2ecf20Sopenharmony_ci} 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_cistatic void crypto_rfc3686_exit_tfm(struct crypto_skcipher *tfm) 2428c2ecf20Sopenharmony_ci{ 2438c2ecf20Sopenharmony_ci struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(tfm); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci crypto_free_skcipher(ctx->child); 2468c2ecf20Sopenharmony_ci} 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_cistatic void crypto_rfc3686_free(struct skcipher_instance *inst) 2498c2ecf20Sopenharmony_ci{ 2508c2ecf20Sopenharmony_ci struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci crypto_drop_skcipher(spawn); 2538c2ecf20Sopenharmony_ci kfree(inst); 2548c2ecf20Sopenharmony_ci} 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_cistatic int crypto_rfc3686_create(struct crypto_template *tmpl, 2578c2ecf20Sopenharmony_ci struct rtattr **tb) 2588c2ecf20Sopenharmony_ci{ 2598c2ecf20Sopenharmony_ci struct skcipher_instance *inst; 2608c2ecf20Sopenharmony_ci struct skcipher_alg *alg; 2618c2ecf20Sopenharmony_ci struct crypto_skcipher_spawn *spawn; 2628c2ecf20Sopenharmony_ci u32 mask; 2638c2ecf20Sopenharmony_ci int err; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask); 2668c2ecf20Sopenharmony_ci if (err) 2678c2ecf20Sopenharmony_ci return err; 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 2708c2ecf20Sopenharmony_ci if (!inst) 2718c2ecf20Sopenharmony_ci return -ENOMEM; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci spawn = skcipher_instance_ctx(inst); 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst), 2768c2ecf20Sopenharmony_ci crypto_attr_alg_name(tb[1]), 0, mask); 2778c2ecf20Sopenharmony_ci if (err) 2788c2ecf20Sopenharmony_ci goto err_free_inst; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci alg = crypto_spawn_skcipher_alg(spawn); 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci /* We only support 16-byte blocks. */ 2838c2ecf20Sopenharmony_ci err = -EINVAL; 2848c2ecf20Sopenharmony_ci if (crypto_skcipher_alg_ivsize(alg) != CTR_RFC3686_BLOCK_SIZE) 2858c2ecf20Sopenharmony_ci goto err_free_inst; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci /* Not a stream cipher? */ 2888c2ecf20Sopenharmony_ci if (alg->base.cra_blocksize != 1) 2898c2ecf20Sopenharmony_ci goto err_free_inst; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci err = -ENAMETOOLONG; 2928c2ecf20Sopenharmony_ci if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, 2938c2ecf20Sopenharmony_ci "rfc3686(%s)", alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME) 2948c2ecf20Sopenharmony_ci goto err_free_inst; 2958c2ecf20Sopenharmony_ci if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, 2968c2ecf20Sopenharmony_ci "rfc3686(%s)", alg->base.cra_driver_name) >= 2978c2ecf20Sopenharmony_ci CRYPTO_MAX_ALG_NAME) 2988c2ecf20Sopenharmony_ci goto err_free_inst; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci inst->alg.base.cra_priority = alg->base.cra_priority; 3018c2ecf20Sopenharmony_ci inst->alg.base.cra_blocksize = 1; 3028c2ecf20Sopenharmony_ci inst->alg.base.cra_alignmask = alg->base.cra_alignmask; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci inst->alg.ivsize = CTR_RFC3686_IV_SIZE; 3058c2ecf20Sopenharmony_ci inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg); 3068c2ecf20Sopenharmony_ci inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) + 3078c2ecf20Sopenharmony_ci CTR_RFC3686_NONCE_SIZE; 3088c2ecf20Sopenharmony_ci inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) + 3098c2ecf20Sopenharmony_ci CTR_RFC3686_NONCE_SIZE; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci inst->alg.setkey = crypto_rfc3686_setkey; 3128c2ecf20Sopenharmony_ci inst->alg.encrypt = crypto_rfc3686_crypt; 3138c2ecf20Sopenharmony_ci inst->alg.decrypt = crypto_rfc3686_crypt; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci inst->alg.init = crypto_rfc3686_init_tfm; 3188c2ecf20Sopenharmony_ci inst->alg.exit = crypto_rfc3686_exit_tfm; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci inst->free = crypto_rfc3686_free; 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci err = skcipher_register_instance(tmpl, inst); 3238c2ecf20Sopenharmony_ci if (err) { 3248c2ecf20Sopenharmony_cierr_free_inst: 3258c2ecf20Sopenharmony_ci crypto_rfc3686_free(inst); 3268c2ecf20Sopenharmony_ci } 3278c2ecf20Sopenharmony_ci return err; 3288c2ecf20Sopenharmony_ci} 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_cistatic struct crypto_template crypto_ctr_tmpls[] = { 3318c2ecf20Sopenharmony_ci { 3328c2ecf20Sopenharmony_ci .name = "ctr", 3338c2ecf20Sopenharmony_ci .create = crypto_ctr_create, 3348c2ecf20Sopenharmony_ci .module = THIS_MODULE, 3358c2ecf20Sopenharmony_ci }, { 3368c2ecf20Sopenharmony_ci .name = "rfc3686", 3378c2ecf20Sopenharmony_ci .create = crypto_rfc3686_create, 3388c2ecf20Sopenharmony_ci .module = THIS_MODULE, 3398c2ecf20Sopenharmony_ci }, 3408c2ecf20Sopenharmony_ci}; 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_cistatic int __init crypto_ctr_module_init(void) 3438c2ecf20Sopenharmony_ci{ 3448c2ecf20Sopenharmony_ci return crypto_register_templates(crypto_ctr_tmpls, 3458c2ecf20Sopenharmony_ci ARRAY_SIZE(crypto_ctr_tmpls)); 3468c2ecf20Sopenharmony_ci} 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cistatic void __exit crypto_ctr_module_exit(void) 3498c2ecf20Sopenharmony_ci{ 3508c2ecf20Sopenharmony_ci crypto_unregister_templates(crypto_ctr_tmpls, 3518c2ecf20Sopenharmony_ci ARRAY_SIZE(crypto_ctr_tmpls)); 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_cisubsys_initcall(crypto_ctr_module_init); 3558c2ecf20Sopenharmony_cimodule_exit(crypto_ctr_module_exit); 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 3588c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("CTR block cipher mode of operation"); 3598c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("rfc3686"); 3608c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("ctr"); 361