xref: /openbmc/linux/crypto/ecb.c (revision 0eb76ba2)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2db131ef9SHerbert Xu /*
3db131ef9SHerbert Xu  * ECB: Electronic CodeBook mode
4db131ef9SHerbert Xu  *
5db131ef9SHerbert Xu  * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
6db131ef9SHerbert Xu  */
7db131ef9SHerbert Xu 
8db131ef9SHerbert Xu #include <crypto/algapi.h>
9*0eb76ba2SArd Biesheuvel #include <crypto/internal/cipher.h>
1052e9368fSEric Biggers #include <crypto/internal/skcipher.h>
11db131ef9SHerbert Xu #include <linux/err.h>
12db131ef9SHerbert Xu #include <linux/init.h>
13db131ef9SHerbert Xu #include <linux/kernel.h>
14db131ef9SHerbert Xu #include <linux/module.h>
15db131ef9SHerbert Xu 
crypto_ecb_crypt(struct skcipher_request * req,struct crypto_cipher * cipher,void (* fn)(struct crypto_tfm *,u8 *,const u8 *))1652e9368fSEric Biggers static int crypto_ecb_crypt(struct skcipher_request *req,
1752e9368fSEric Biggers 			    struct crypto_cipher *cipher,
18db131ef9SHerbert Xu 			    void (*fn)(struct crypto_tfm *, u8 *, const u8 *))
19db131ef9SHerbert Xu {
2052e9368fSEric Biggers 	const unsigned int bsize = crypto_cipher_blocksize(cipher);
2152e9368fSEric Biggers 	struct skcipher_walk walk;
22db131ef9SHerbert Xu 	unsigned int nbytes;
23db131ef9SHerbert Xu 	int err;
24db131ef9SHerbert Xu 
2552e9368fSEric Biggers 	err = skcipher_walk_virt(&walk, req, false);
26db131ef9SHerbert Xu 
2752e9368fSEric Biggers 	while ((nbytes = walk.nbytes) != 0) {
2852e9368fSEric Biggers 		const u8 *src = walk.src.virt.addr;
2952e9368fSEric Biggers 		u8 *dst = walk.dst.virt.addr;
30db131ef9SHerbert Xu 
31db131ef9SHerbert Xu 		do {
3252e9368fSEric Biggers 			fn(crypto_cipher_tfm(cipher), dst, src);
33db131ef9SHerbert Xu 
3452e9368fSEric Biggers 			src += bsize;
3552e9368fSEric Biggers 			dst += bsize;
36db131ef9SHerbert Xu 		} while ((nbytes -= bsize) >= bsize);
37db131ef9SHerbert Xu 
3852e9368fSEric Biggers 		err = skcipher_walk_done(&walk, nbytes);
39db131ef9SHerbert Xu 	}
40db131ef9SHerbert Xu 
41db131ef9SHerbert Xu 	return err;
42db131ef9SHerbert Xu }
43db131ef9SHerbert Xu 
crypto_ecb_encrypt(struct skcipher_request * req)4452e9368fSEric Biggers static int crypto_ecb_encrypt(struct skcipher_request *req)
45db131ef9SHerbert Xu {
4652e9368fSEric Biggers 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
4752e9368fSEric Biggers 	struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
48db131ef9SHerbert Xu 
4952e9368fSEric Biggers 	return crypto_ecb_crypt(req, cipher,
5052e9368fSEric Biggers 				crypto_cipher_alg(cipher)->cia_encrypt);
51db131ef9SHerbert Xu }
52db131ef9SHerbert Xu 
crypto_ecb_decrypt(struct skcipher_request * req)5352e9368fSEric Biggers static int crypto_ecb_decrypt(struct skcipher_request *req)
54db131ef9SHerbert Xu {
5552e9368fSEric Biggers 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
5652e9368fSEric Biggers 	struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
57db131ef9SHerbert Xu 
5852e9368fSEric Biggers 	return crypto_ecb_crypt(req, cipher,
5952e9368fSEric Biggers 				crypto_cipher_alg(cipher)->cia_decrypt);
60db131ef9SHerbert Xu }
61db131ef9SHerbert Xu 
crypto_ecb_create(struct crypto_template * tmpl,struct rtattr ** tb)6252e9368fSEric Biggers static int crypto_ecb_create(struct crypto_template *tmpl, struct rtattr **tb)
63db131ef9SHerbert Xu {
6452e9368fSEric Biggers 	struct skcipher_instance *inst;
65ebc610e5SHerbert Xu 	int err;
66db131ef9SHerbert Xu 
67b3c16bfcSHerbert Xu 	inst = skcipher_alloc_instance_simple(tmpl, tb);
68db131ef9SHerbert Xu 	if (IS_ERR(inst))
6952e9368fSEric Biggers 		return PTR_ERR(inst);
70db131ef9SHerbert Xu 
7152e9368fSEric Biggers 	inst->alg.ivsize = 0; /* ECB mode doesn't take an IV */
72db131ef9SHerbert Xu 
7352e9368fSEric Biggers 	inst->alg.encrypt = crypto_ecb_encrypt;
7452e9368fSEric Biggers 	inst->alg.decrypt = crypto_ecb_decrypt;
75db131ef9SHerbert Xu 
7652e9368fSEric Biggers 	err = skcipher_register_instance(tmpl, inst);
7752e9368fSEric Biggers 	if (err)
7852e9368fSEric Biggers 		inst->free(inst);
79b3c16bfcSHerbert Xu 
8052e9368fSEric Biggers 	return err;
81db131ef9SHerbert Xu }
82db131ef9SHerbert Xu 
83db131ef9SHerbert Xu static struct crypto_template crypto_ecb_tmpl = {
84db131ef9SHerbert Xu 	.name = "ecb",
8552e9368fSEric Biggers 	.create = crypto_ecb_create,
86db131ef9SHerbert Xu 	.module = THIS_MODULE,
87db131ef9SHerbert Xu };
88db131ef9SHerbert Xu 
crypto_ecb_module_init(void)89db131ef9SHerbert Xu static int __init crypto_ecb_module_init(void)
90db131ef9SHerbert Xu {
91db131ef9SHerbert Xu 	return crypto_register_template(&crypto_ecb_tmpl);
92db131ef9SHerbert Xu }
93db131ef9SHerbert Xu 
crypto_ecb_module_exit(void)94db131ef9SHerbert Xu static void __exit crypto_ecb_module_exit(void)
95db131ef9SHerbert Xu {
96db131ef9SHerbert Xu 	crypto_unregister_template(&crypto_ecb_tmpl);
97db131ef9SHerbert Xu }
98db131ef9SHerbert Xu 
99c4741b23SEric Biggers subsys_initcall(crypto_ecb_module_init);
100db131ef9SHerbert Xu module_exit(crypto_ecb_module_exit);
101db131ef9SHerbert Xu 
102db131ef9SHerbert Xu MODULE_LICENSE("GPL");
10352e9368fSEric Biggers MODULE_DESCRIPTION("ECB block cipher mode of operation");
1044943ba16SKees Cook MODULE_ALIAS_CRYPTO("ecb");
105