Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * ECB: Electronic CodeBook mode
0004  *
0005  * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
0006  */
0007 
0008 #include <crypto/algapi.h>
0009 #include <crypto/internal/cipher.h>
0010 #include <crypto/internal/skcipher.h>
0011 #include <linux/err.h>
0012 #include <linux/init.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 
0016 static int crypto_ecb_crypt(struct skcipher_request *req,
0017                 struct crypto_cipher *cipher,
0018                 void (*fn)(struct crypto_tfm *, u8 *, const u8 *))
0019 {
0020     const unsigned int bsize = crypto_cipher_blocksize(cipher);
0021     struct skcipher_walk walk;
0022     unsigned int nbytes;
0023     int err;
0024 
0025     err = skcipher_walk_virt(&walk, req, false);
0026 
0027     while ((nbytes = walk.nbytes) != 0) {
0028         const u8 *src = walk.src.virt.addr;
0029         u8 *dst = walk.dst.virt.addr;
0030 
0031         do {
0032             fn(crypto_cipher_tfm(cipher), dst, src);
0033 
0034             src += bsize;
0035             dst += bsize;
0036         } while ((nbytes -= bsize) >= bsize);
0037 
0038         err = skcipher_walk_done(&walk, nbytes);
0039     }
0040 
0041     return err;
0042 }
0043 
0044 static int crypto_ecb_encrypt(struct skcipher_request *req)
0045 {
0046     struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
0047     struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
0048 
0049     return crypto_ecb_crypt(req, cipher,
0050                 crypto_cipher_alg(cipher)->cia_encrypt);
0051 }
0052 
0053 static int crypto_ecb_decrypt(struct skcipher_request *req)
0054 {
0055     struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
0056     struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
0057 
0058     return crypto_ecb_crypt(req, cipher,
0059                 crypto_cipher_alg(cipher)->cia_decrypt);
0060 }
0061 
0062 static int crypto_ecb_create(struct crypto_template *tmpl, struct rtattr **tb)
0063 {
0064     struct skcipher_instance *inst;
0065     int err;
0066 
0067     inst = skcipher_alloc_instance_simple(tmpl, tb);
0068     if (IS_ERR(inst))
0069         return PTR_ERR(inst);
0070 
0071     inst->alg.ivsize = 0; /* ECB mode doesn't take an IV */
0072 
0073     inst->alg.encrypt = crypto_ecb_encrypt;
0074     inst->alg.decrypt = crypto_ecb_decrypt;
0075 
0076     err = skcipher_register_instance(tmpl, inst);
0077     if (err)
0078         inst->free(inst);
0079 
0080     return err;
0081 }
0082 
0083 static struct crypto_template crypto_ecb_tmpl = {
0084     .name = "ecb",
0085     .create = crypto_ecb_create,
0086     .module = THIS_MODULE,
0087 };
0088 
0089 static int __init crypto_ecb_module_init(void)
0090 {
0091     return crypto_register_template(&crypto_ecb_tmpl);
0092 }
0093 
0094 static void __exit crypto_ecb_module_exit(void)
0095 {
0096     crypto_unregister_template(&crypto_ecb_tmpl);
0097 }
0098 
0099 subsys_initcall(crypto_ecb_module_init);
0100 module_exit(crypto_ecb_module_exit);
0101 
0102 MODULE_LICENSE("GPL");
0103 MODULE_DESCRIPTION("ECB block cipher mode of operation");
0104 MODULE_ALIAS_CRYPTO("ecb");