Revision f61cf8decb37e7244247129163bf69b45dd3b1cd authored by Linus Torvalds on 14 December 2019, 20:49:20 UTC, committed by Linus Torvalds on 14 December 2019, 20:49:20 UTC
Pull char/misc driver fixes from Greg KH:
 "Here are six small fixes for some reported char/misc driver issues:

   - fix build warnings with new 'awk' with the raid6 code

   - four interconnect driver bugfixes

   - binder fix for reported problem

  All of these except the binder fix have been in linux-next with no
  reported issues. The binder fix is "new" but Todd says it is good as
  he has tested it :)"

* tag 'char-misc-5.5-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  binder: fix incorrect calculation for num_valid
  interconnect: qcom: msm8974: Walk the list safely on node removal
  interconnect: qcom: qcs404: Walk the list safely on node removal
  interconnect: qcom: sdm845: Walk the list safely on node removal
  interconnect: qcom: Fix Kconfig indentation
  lib: raid6: fix awk build warnings
2 parent s 894554c + 1698174
Raw File
ecb.c
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * ECB: Electronic CodeBook mode
 *
 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
 */

#include <crypto/algapi.h>
#include <crypto/internal/skcipher.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

static int crypto_ecb_crypt(struct skcipher_request *req,
			    struct crypto_cipher *cipher,
			    void (*fn)(struct crypto_tfm *, u8 *, const u8 *))
{
	const unsigned int bsize = crypto_cipher_blocksize(cipher);
	struct skcipher_walk walk;
	unsigned int nbytes;
	int err;

	err = skcipher_walk_virt(&walk, req, false);

	while ((nbytes = walk.nbytes) != 0) {
		const u8 *src = walk.src.virt.addr;
		u8 *dst = walk.dst.virt.addr;

		do {
			fn(crypto_cipher_tfm(cipher), dst, src);

			src += bsize;
			dst += bsize;
		} while ((nbytes -= bsize) >= bsize);

		err = skcipher_walk_done(&walk, nbytes);
	}

	return err;
}

static int crypto_ecb_encrypt(struct skcipher_request *req)
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
	struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);

	return crypto_ecb_crypt(req, cipher,
				crypto_cipher_alg(cipher)->cia_encrypt);
}

static int crypto_ecb_decrypt(struct skcipher_request *req)
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
	struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);

	return crypto_ecb_crypt(req, cipher,
				crypto_cipher_alg(cipher)->cia_decrypt);
}

static int crypto_ecb_create(struct crypto_template *tmpl, struct rtattr **tb)
{
	struct skcipher_instance *inst;
	struct crypto_alg *alg;
	int err;

	inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
	if (IS_ERR(inst))
		return PTR_ERR(inst);

	inst->alg.ivsize = 0; /* ECB mode doesn't take an IV */

	inst->alg.encrypt = crypto_ecb_encrypt;
	inst->alg.decrypt = crypto_ecb_decrypt;

	err = skcipher_register_instance(tmpl, inst);
	if (err)
		inst->free(inst);
	crypto_mod_put(alg);
	return err;
}

static struct crypto_template crypto_ecb_tmpl = {
	.name = "ecb",
	.create = crypto_ecb_create,
	.module = THIS_MODULE,
};

static int __init crypto_ecb_module_init(void)
{
	return crypto_register_template(&crypto_ecb_tmpl);
}

static void __exit crypto_ecb_module_exit(void)
{
	crypto_unregister_template(&crypto_ecb_tmpl);
}

subsys_initcall(crypto_ecb_module_init);
module_exit(crypto_ecb_module_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ECB block cipher mode of operation");
MODULE_ALIAS_CRYPTO("ecb");
back to top