diff options
| author | Eric Biggers <ebiggers@kernel.org> | 2026-05-22 00:07:36 -0500 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-09 17:03:03 -0700 |
| commit | 1967bfaf7ba15dc179a7e3325e880736efbcdf62 (patch) | |
| tree | 799edffc502b773693bb3d0e06778b080bc460c3 /crypto | |
| parent | 374efbdc85d027814f6b26a8d641dc062f9017c0 (diff) | |
crypto: pcbc - Remove support for PCBC mode
The only user of PCBC mode (Propagating Cipher Block Chaining mode) was
net/rxrpc/rxkad.c, which now uses local code instead.
While PCBC was an interesting cryptographic experiment, it has largely
been relegated to the history books and academic exercises. It is
non-parallelizable (i.e., very slow) and doesn't actually achieve the
integrity properties it was apparently intended to achieve.
Remove support for it from the crypto API.
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> # m68k
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Tested-by: Marc Dionne <marc.dionne@auristor.com>
Link: https://patch.msgid.link/20260522050740.84561-6-ebiggers@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/Kconfig | 9 | ||||
| -rw-r--r-- | crypto/Makefile | 1 | ||||
| -rw-r--r-- | crypto/pcbc.c | 195 |
3 files changed, 0 insertions, 205 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index 0727cd5877da..f8d5801a4d5e 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -703,15 +703,6 @@ config CRYPTO_LRW See https://people.csail.mit.edu/rivest/pubs/LRW02.pdf -config CRYPTO_PCBC - tristate "PCBC (Propagating Cipher Block Chaining)" - select CRYPTO_SKCIPHER - select CRYPTO_MANAGER - help - PCBC (Propagating Cipher Block Chaining) mode - - This block cipher mode is required for RxRPC. - config CRYPTO_XCTR tristate select CRYPTO_SKCIPHER diff --git a/crypto/Makefile b/crypto/Makefile index 1827f84192e6..9081ed10ce61 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -89,7 +89,6 @@ CFLAGS_wp512.o := $(call cc-option,-fno-schedule-insns) # https://gcc.gnu.org/b obj-$(CONFIG_CRYPTO_BLAKE2B) += blake2b.o obj-$(CONFIG_CRYPTO_ECB) += ecb.o obj-$(CONFIG_CRYPTO_CBC) += cbc.o -obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o obj-$(CONFIG_CRYPTO_CTS) += cts.o obj-$(CONFIG_CRYPTO_LRW) += lrw.o obj-$(CONFIG_CRYPTO_XTS) += xts.o diff --git a/crypto/pcbc.c b/crypto/pcbc.c deleted file mode 100644 index d092717ea4fc..000000000000 --- a/crypto/pcbc.c +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * PCBC: Propagating Cipher Block Chaining mode - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * Derived from cbc.c - * - Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> - */ - -#include <crypto/algapi.h> -#include <crypto/internal/cipher.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_pcbc_encrypt_segment(struct skcipher_request *req, - struct skcipher_walk *walk, - struct crypto_cipher *tfm) -{ - int bsize = crypto_cipher_blocksize(tfm); - const u8 *src = walk->src.virt.addr; - unsigned int nbytes = walk->nbytes; - u8 *dst = walk->dst.virt.addr; - u8 * const iv = walk->iv; - - do { - crypto_xor(iv, src, bsize); - crypto_cipher_encrypt_one(tfm, dst, iv); - crypto_xor_cpy(iv, dst, src, bsize); - - src += bsize; - dst += bsize; - } while ((nbytes -= bsize) >= bsize); - - return nbytes; -} - -static int crypto_pcbc_encrypt_inplace(struct skcipher_request *req, - struct skcipher_walk *walk, - struct crypto_cipher *tfm) -{ - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *dst = walk->dst.virt.addr; - u8 * const iv = walk->iv; - u8 tmpbuf[MAX_CIPHER_BLOCKSIZE]; - - do { - memcpy(tmpbuf, dst, bsize); - crypto_xor(iv, dst, bsize); - crypto_cipher_encrypt_one(tfm, dst, iv); - crypto_xor_cpy(iv, tmpbuf, dst, bsize); - - dst += bsize; - } while ((nbytes -= bsize) >= bsize); - - return nbytes; -} - -static int crypto_pcbc_encrypt(struct skcipher_request *req) -{ - struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); - struct crypto_cipher *cipher = skcipher_cipher_simple(tfm); - struct skcipher_walk walk; - unsigned int nbytes; - int err; - - err = skcipher_walk_virt(&walk, req, false); - - while (walk.nbytes) { - if (walk.src.virt.addr == walk.dst.virt.addr) - nbytes = crypto_pcbc_encrypt_inplace(req, &walk, - cipher); - else - nbytes = crypto_pcbc_encrypt_segment(req, &walk, - cipher); - err = skcipher_walk_done(&walk, nbytes); - } - - return err; -} - -static int crypto_pcbc_decrypt_segment(struct skcipher_request *req, - struct skcipher_walk *walk, - struct crypto_cipher *tfm) -{ - int bsize = crypto_cipher_blocksize(tfm); - const u8 *src = walk->src.virt.addr; - unsigned int nbytes = walk->nbytes; - u8 *dst = walk->dst.virt.addr; - u8 * const iv = walk->iv; - - do { - crypto_cipher_decrypt_one(tfm, dst, src); - crypto_xor(dst, iv, bsize); - crypto_xor_cpy(iv, dst, src, bsize); - - src += bsize; - dst += bsize; - } while ((nbytes -= bsize) >= bsize); - - return nbytes; -} - -static int crypto_pcbc_decrypt_inplace(struct skcipher_request *req, - struct skcipher_walk *walk, - struct crypto_cipher *tfm) -{ - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *dst = walk->dst.virt.addr; - u8 * const iv = walk->iv; - u8 tmpbuf[MAX_CIPHER_BLOCKSIZE] __aligned(__alignof__(u32)); - - do { - memcpy(tmpbuf, dst, bsize); - crypto_cipher_decrypt_one(tfm, dst, dst); - crypto_xor(dst, iv, bsize); - crypto_xor_cpy(iv, dst, tmpbuf, bsize); - - dst += bsize; - } while ((nbytes -= bsize) >= bsize); - - return nbytes; -} - -static int crypto_pcbc_decrypt(struct skcipher_request *req) -{ - struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); - struct crypto_cipher *cipher = skcipher_cipher_simple(tfm); - struct skcipher_walk walk; - unsigned int nbytes; - int err; - - err = skcipher_walk_virt(&walk, req, false); - - while (walk.nbytes) { - if (walk.src.virt.addr == walk.dst.virt.addr) - nbytes = crypto_pcbc_decrypt_inplace(req, &walk, - cipher); - else - nbytes = crypto_pcbc_decrypt_segment(req, &walk, - cipher); - err = skcipher_walk_done(&walk, nbytes); - } - - return err; -} - -static int crypto_pcbc_create(struct crypto_template *tmpl, struct rtattr **tb) -{ - struct skcipher_instance *inst; - int err; - - inst = skcipher_alloc_instance_simple(tmpl, tb); - if (IS_ERR(inst)) - return PTR_ERR(inst); - - inst->alg.encrypt = crypto_pcbc_encrypt; - inst->alg.decrypt = crypto_pcbc_decrypt; - - err = skcipher_register_instance(tmpl, inst); - if (err) - inst->free(inst); - - return err; -} - -static struct crypto_template crypto_pcbc_tmpl = { - .name = "pcbc", - .create = crypto_pcbc_create, - .module = THIS_MODULE, -}; - -static int __init crypto_pcbc_module_init(void) -{ - return crypto_register_template(&crypto_pcbc_tmpl); -} - -static void __exit crypto_pcbc_module_exit(void) -{ - crypto_unregister_template(&crypto_pcbc_tmpl); -} - -module_init(crypto_pcbc_module_init); -module_exit(crypto_pcbc_module_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("PCBC block cipher mode of operation"); -MODULE_ALIAS_CRYPTO("pcbc"); -MODULE_IMPORT_NS("CRYPTO_INTERNAL"); |
