Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later 2 : : /* 3 : : * ECB: Electronic CodeBook mode 4 : : * 5 : : * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 6 : : */ 7 : : 8 : : #include <crypto/algapi.h> 9 : : #include <crypto/internal/skcipher.h> 10 : : #include <linux/err.h> 11 : : #include <linux/init.h> 12 : : #include <linux/kernel.h> 13 : : #include <linux/module.h> 14 : : 15 : 0 : static int crypto_ecb_crypt(struct skcipher_request *req, 16 : : struct crypto_cipher *cipher, 17 : : void (*fn)(struct crypto_tfm *, u8 *, const u8 *)) 18 : : { 19 : : const unsigned int bsize = crypto_cipher_blocksize(cipher); 20 : : struct skcipher_walk walk; 21 : : unsigned int nbytes; 22 : : int err; 23 : : 24 : 0 : err = skcipher_walk_virt(&walk, req, false); 25 : : 26 [ # # ]: 0 : while ((nbytes = walk.nbytes) != 0) { 27 : 0 : const u8 *src = walk.src.virt.addr; 28 : 0 : u8 *dst = walk.dst.virt.addr; 29 : : 30 : : do { 31 : 0 : fn(crypto_cipher_tfm(cipher), dst, src); 32 : : 33 : 0 : src += bsize; 34 : 0 : dst += bsize; 35 [ # # ]: 0 : } while ((nbytes -= bsize) >= bsize); 36 : : 37 : 0 : err = skcipher_walk_done(&walk, nbytes); 38 : : } 39 : : 40 : 0 : return err; 41 : : } 42 : : 43 : 0 : static int crypto_ecb_encrypt(struct skcipher_request *req) 44 : : { 45 : : struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 46 : : struct crypto_cipher *cipher = skcipher_cipher_simple(tfm); 47 : : 48 : 0 : return crypto_ecb_crypt(req, cipher, 49 : : crypto_cipher_alg(cipher)->cia_encrypt); 50 : : } 51 : : 52 : 0 : static int crypto_ecb_decrypt(struct skcipher_request *req) 53 : : { 54 : : struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 55 : : struct crypto_cipher *cipher = skcipher_cipher_simple(tfm); 56 : : 57 : 0 : return crypto_ecb_crypt(req, cipher, 58 : : crypto_cipher_alg(cipher)->cia_decrypt); 59 : : } 60 : : 61 : 0 : static int crypto_ecb_create(struct crypto_template *tmpl, struct rtattr **tb) 62 : : { 63 : : struct skcipher_instance *inst; 64 : : struct crypto_alg *alg; 65 : : int err; 66 : : 67 : 0 : inst = skcipher_alloc_instance_simple(tmpl, tb, &alg); 68 [ # # ]: 0 : if (IS_ERR(inst)) 69 : 0 : return PTR_ERR(inst); 70 : : 71 : 0 : inst->alg.ivsize = 0; /* ECB mode doesn't take an IV */ 72 : : 73 : 0 : inst->alg.encrypt = crypto_ecb_encrypt; 74 : 0 : inst->alg.decrypt = crypto_ecb_decrypt; 75 : : 76 : 0 : err = skcipher_register_instance(tmpl, inst); 77 [ # # ]: 0 : if (err) 78 : 0 : inst->free(inst); 79 : 0 : crypto_mod_put(alg); 80 : 0 : return err; 81 : : } 82 : : 83 : : static struct crypto_template crypto_ecb_tmpl = { 84 : : .name = "ecb", 85 : : .create = crypto_ecb_create, 86 : : .module = THIS_MODULE, 87 : : }; 88 : : 89 : 207 : static int __init crypto_ecb_module_init(void) 90 : : { 91 : 207 : return crypto_register_template(&crypto_ecb_tmpl); 92 : : } 93 : : 94 : 0 : static void __exit crypto_ecb_module_exit(void) 95 : : { 96 : 0 : crypto_unregister_template(&crypto_ecb_tmpl); 97 : 0 : } 98 : : 99 : : subsys_initcall(crypto_ecb_module_init); 100 : : module_exit(crypto_ecb_module_exit); 101 : : 102 : : MODULE_LICENSE("GPL"); 103 : : MODULE_DESCRIPTION("ECB block cipher mode of operation"); 104 : : MODULE_ALIAS_CRYPTO("ecb");