brintos

brintos / linux-shallow public Read only

0
0
Text · 6.0 KiB · e3a6778 Raw
229 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * ECB: Electronic CodeBook mode4 *5 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>6 */7 8#include <crypto/internal/cipher.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#include <linux/slab.h>15 16static int crypto_ecb_crypt(struct crypto_cipher *cipher, const u8 *src,17			    u8 *dst, unsigned nbytes, bool final,18			    void (*fn)(struct crypto_tfm *, u8 *, const u8 *))19{20	const unsigned int bsize = crypto_cipher_blocksize(cipher);21 22	while (nbytes >= bsize) {23		fn(crypto_cipher_tfm(cipher), dst, src);24 25		src += bsize;26		dst += bsize;27 28		nbytes -= bsize;29	}30 31	return nbytes && final ? -EINVAL : nbytes;32}33 34static int crypto_ecb_encrypt2(struct crypto_lskcipher *tfm, const u8 *src,35			       u8 *dst, unsigned len, u8 *iv, u32 flags)36{37	struct crypto_cipher **ctx = crypto_lskcipher_ctx(tfm);38	struct crypto_cipher *cipher = *ctx;39 40	return crypto_ecb_crypt(cipher, src, dst, len,41				flags & CRYPTO_LSKCIPHER_FLAG_FINAL,42				crypto_cipher_alg(cipher)->cia_encrypt);43}44 45static int crypto_ecb_decrypt2(struct crypto_lskcipher *tfm, const u8 *src,46			       u8 *dst, unsigned len, u8 *iv, u32 flags)47{48	struct crypto_cipher **ctx = crypto_lskcipher_ctx(tfm);49	struct crypto_cipher *cipher = *ctx;50 51	return crypto_ecb_crypt(cipher, src, dst, len,52				flags & CRYPTO_LSKCIPHER_FLAG_FINAL,53				crypto_cipher_alg(cipher)->cia_decrypt);54}55 56static int lskcipher_setkey_simple2(struct crypto_lskcipher *tfm,57				    const u8 *key, unsigned int keylen)58{59	struct crypto_cipher **ctx = crypto_lskcipher_ctx(tfm);60	struct crypto_cipher *cipher = *ctx;61 62	crypto_cipher_clear_flags(cipher, CRYPTO_TFM_REQ_MASK);63	crypto_cipher_set_flags(cipher, crypto_lskcipher_get_flags(tfm) &64				CRYPTO_TFM_REQ_MASK);65	return crypto_cipher_setkey(cipher, key, keylen);66}67 68static int lskcipher_init_tfm_simple2(struct crypto_lskcipher *tfm)69{70	struct lskcipher_instance *inst = lskcipher_alg_instance(tfm);71	struct crypto_cipher **ctx = crypto_lskcipher_ctx(tfm);72	struct crypto_cipher_spawn *spawn;73	struct crypto_cipher *cipher;74 75	spawn = lskcipher_instance_ctx(inst);76	cipher = crypto_spawn_cipher(spawn);77	if (IS_ERR(cipher))78		return PTR_ERR(cipher);79 80	*ctx = cipher;81	return 0;82}83 84static void lskcipher_exit_tfm_simple2(struct crypto_lskcipher *tfm)85{86	struct crypto_cipher **ctx = crypto_lskcipher_ctx(tfm);87 88	crypto_free_cipher(*ctx);89}90 91static void lskcipher_free_instance_simple2(struct lskcipher_instance *inst)92{93	crypto_drop_cipher(lskcipher_instance_ctx(inst));94	kfree(inst);95}96 97static struct lskcipher_instance *lskcipher_alloc_instance_simple2(98	struct crypto_template *tmpl, struct rtattr **tb)99{100	struct crypto_cipher_spawn *spawn;101	struct lskcipher_instance *inst;102	struct crypto_alg *cipher_alg;103	u32 mask;104	int err;105 106	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_LSKCIPHER, &mask);107	if (err)108		return ERR_PTR(err);109 110	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);111	if (!inst)112		return ERR_PTR(-ENOMEM);113	spawn = lskcipher_instance_ctx(inst);114 115	err = crypto_grab_cipher(spawn, lskcipher_crypto_instance(inst),116				 crypto_attr_alg_name(tb[1]), 0, mask);117	if (err)118		goto err_free_inst;119	cipher_alg = crypto_spawn_cipher_alg(spawn);120 121	err = crypto_inst_setname(lskcipher_crypto_instance(inst), tmpl->name,122				  cipher_alg);123	if (err)124		goto err_free_inst;125 126	inst->free = lskcipher_free_instance_simple2;127 128	/* Default algorithm properties, can be overridden */129	inst->alg.co.base.cra_blocksize = cipher_alg->cra_blocksize;130	inst->alg.co.base.cra_alignmask = cipher_alg->cra_alignmask;131	inst->alg.co.base.cra_priority = cipher_alg->cra_priority;132	inst->alg.co.min_keysize = cipher_alg->cra_cipher.cia_min_keysize;133	inst->alg.co.max_keysize = cipher_alg->cra_cipher.cia_max_keysize;134	inst->alg.co.ivsize = cipher_alg->cra_blocksize;135 136	/* Use struct crypto_cipher * by default, can be overridden */137	inst->alg.co.base.cra_ctxsize = sizeof(struct crypto_cipher *);138	inst->alg.setkey = lskcipher_setkey_simple2;139	inst->alg.init = lskcipher_init_tfm_simple2;140	inst->alg.exit = lskcipher_exit_tfm_simple2;141 142	return inst;143 144err_free_inst:145	lskcipher_free_instance_simple2(inst);146	return ERR_PTR(err);147}148 149static int crypto_ecb_create2(struct crypto_template *tmpl, struct rtattr **tb)150{151	struct lskcipher_instance *inst;152	int err;153 154	inst = lskcipher_alloc_instance_simple2(tmpl, tb);155	if (IS_ERR(inst))156		return PTR_ERR(inst);157 158	/* ECB mode doesn't take an IV */159	inst->alg.co.ivsize = 0;160 161	inst->alg.encrypt = crypto_ecb_encrypt2;162	inst->alg.decrypt = crypto_ecb_decrypt2;163 164	err = lskcipher_register_instance(tmpl, inst);165	if (err)166		inst->free(inst);167 168	return err;169}170 171static int crypto_ecb_create(struct crypto_template *tmpl, struct rtattr **tb)172{173	struct crypto_lskcipher_spawn *spawn;174	struct lskcipher_alg *cipher_alg;175	struct lskcipher_instance *inst;176	int err;177 178	inst = lskcipher_alloc_instance_simple(tmpl, tb);179	if (IS_ERR(inst)) {180		err = crypto_ecb_create2(tmpl, tb);181		return err;182	}183 184	spawn = lskcipher_instance_ctx(inst);185	cipher_alg = crypto_lskcipher_spawn_alg(spawn);186 187	/* ECB mode doesn't take an IV */188	inst->alg.co.ivsize = 0;189	if (cipher_alg->co.ivsize)190		return -EINVAL;191 192	inst->alg.co.base.cra_ctxsize = cipher_alg->co.base.cra_ctxsize;193	inst->alg.setkey = cipher_alg->setkey;194	inst->alg.encrypt = cipher_alg->encrypt;195	inst->alg.decrypt = cipher_alg->decrypt;196	inst->alg.init = cipher_alg->init;197	inst->alg.exit = cipher_alg->exit;198 199	err = lskcipher_register_instance(tmpl, inst);200	if (err)201		inst->free(inst);202 203	return err;204}205 206static struct crypto_template crypto_ecb_tmpl = {207	.name = "ecb",208	.create = crypto_ecb_create,209	.module = THIS_MODULE,210};211 212static int __init crypto_ecb_module_init(void)213{214	return crypto_register_template(&crypto_ecb_tmpl);215}216 217static void __exit crypto_ecb_module_exit(void)218{219	crypto_unregister_template(&crypto_ecb_tmpl);220}221 222subsys_initcall(crypto_ecb_module_init);223module_exit(crypto_ecb_module_exit);224 225MODULE_LICENSE("GPL");226MODULE_DESCRIPTION("ECB block cipher mode of operation");227MODULE_ALIAS_CRYPTO("ecb");228MODULE_IMPORT_NS(CRYPTO_INTERNAL);229