Linux Audio

Check our new training course

Loading...
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * CBC: Cipher Block Chaining mode
  4 *
  5 * Copyright (c) 2006-2016 Herbert Xu <herbert@gondor.apana.org.au>
  6 */
  7
  8#include <crypto/algapi.h>
  9#include <crypto/cbc.h>
 10#include <crypto/internal/skcipher.h>
 11#include <linux/err.h>
 12#include <linux/init.h>
 13#include <linux/kernel.h>
 14#include <linux/log2.h>
 15#include <linux/module.h>
 16
 17static inline void crypto_cbc_encrypt_one(struct crypto_skcipher *tfm,
 18					  const u8 *src, u8 *dst)
 19{
 20	crypto_cipher_encrypt_one(skcipher_cipher_simple(tfm), dst, src);
 21}
 22
 23static int crypto_cbc_encrypt(struct skcipher_request *req)
 24{
 25	return crypto_cbc_encrypt_walk(req, crypto_cbc_encrypt_one);
 26}
 27
 28static inline void crypto_cbc_decrypt_one(struct crypto_skcipher *tfm,
 29					  const u8 *src, u8 *dst)
 30{
 31	crypto_cipher_decrypt_one(skcipher_cipher_simple(tfm), dst, src);
 32}
 33
 34static int crypto_cbc_decrypt(struct skcipher_request *req)
 35{
 36	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 37	struct skcipher_walk walk;
 38	int err;
 39
 40	err = skcipher_walk_virt(&walk, req, false);
 41
 42	while (walk.nbytes) {
 43		err = crypto_cbc_decrypt_blocks(&walk, tfm,
 44						crypto_cbc_decrypt_one);
 45		err = skcipher_walk_done(&walk, err);
 46	}
 47
 48	return err;
 49}
 50
 51static int crypto_cbc_create(struct crypto_template *tmpl, struct rtattr **tb)
 52{
 53	struct skcipher_instance *inst;
 54	struct crypto_alg *alg;
 55	int err;
 56
 57	inst = skcipher_alloc_instance_simple(tmpl, tb);
 58	if (IS_ERR(inst))
 59		return PTR_ERR(inst);
 60
 61	alg = skcipher_ialg_simple(inst);
 62
 63	err = -EINVAL;
 64	if (!is_power_of_2(alg->cra_blocksize))
 65		goto out_free_inst;
 66
 67	inst->alg.encrypt = crypto_cbc_encrypt;
 68	inst->alg.decrypt = crypto_cbc_decrypt;
 69
 70	err = skcipher_register_instance(tmpl, inst);
 71	if (err) {
 72out_free_inst:
 73		inst->free(inst);
 74	}
 75
 76	return err;
 77}
 78
 79static struct crypto_template crypto_cbc_tmpl = {
 80	.name = "cbc",
 81	.create = crypto_cbc_create,
 82	.module = THIS_MODULE,
 83};
 84
 85static int __init crypto_cbc_module_init(void)
 86{
 87	return crypto_register_template(&crypto_cbc_tmpl);
 88}
 89
 90static void __exit crypto_cbc_module_exit(void)
 91{
 92	crypto_unregister_template(&crypto_cbc_tmpl);
 93}
 94
 95subsys_initcall(crypto_cbc_module_init);
 96module_exit(crypto_cbc_module_exit);
 97
 98MODULE_LICENSE("GPL");
 99MODULE_DESCRIPTION("CBC block cipher mode of operation");
100MODULE_ALIAS_CRYPTO("cbc");