Message ID | 20190609115509.26260-2-ard.biesheuvel@linaro.org |
---|---|
State | New |
Headers | show |
Series | crypto: rc4 cleanup | expand |
Just some bike shedding: On Sun, Jun 09, 2019 at 01:55:03PM +0200, Ard Biesheuvel wrote: > diff --git a/include/crypto/arc4.h b/include/crypto/arc4.h > index 5b2c24ab0139..62ac95ec6860 100644 > --- a/include/crypto/arc4.h > +++ b/include/crypto/arc4.h > @@ -6,8 +6,21 @@ > #ifndef _CRYPTO_ARC4_H > #define _CRYPTO_ARC4_H > > +#include <linux/types.h> > + > #define ARC4_MIN_KEY_SIZE 1 > #define ARC4_MAX_KEY_SIZE 256 > #define ARC4_BLOCK_SIZE 1 > > +struct crypto_arc4_ctx { > + u32 S[256]; > + u32 x, y; > +}; > + > +int crypto_arc4_set_key(struct crypto_arc4_ctx *ctx, const u8 *in_key, > + unsigned int key_len); > + > +void crypto_arc4_crypt(struct crypto_arc4_ctx *ctx, u8 *out, const u8 *in, > + unsigned int len); How about naming these just arc4_* instead of crypto_arc4_*? The crypto_* prefix is already used mostly for crypto API helper functions, i.e. functions that take take one of the abstract crypto API types like crypto_skcipher, shash_desc, etc. For lib functions, the bare name seems more appropriate. See e.g. sha256_update() vs. crypto_sha256_update(). > +++ b/lib/crypto/Makefile > @@ -0,0 +1,3 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +obj-$(CONFIG_CRYPTO_LIB_ARC4) += libarc4.o > diff --git a/lib/crypto/libarc4.c b/lib/crypto/libarc4.c > new file mode 100644 > index 000000000000..b828af2cc03b > --- /dev/null > +++ b/lib/crypto/libarc4.c > @@ -0,0 +1,74 @@ How about arc4.c instead of libarc4.c? The second "lib" is redundant, given that the file is already in the lib/ directory. - Eric
On Mon, 10 Jun 2019 at 18:06, Eric Biggers <ebiggers@kernel.org> wrote: > > Just some bike shedding: > > On Sun, Jun 09, 2019 at 01:55:03PM +0200, Ard Biesheuvel wrote: > > diff --git a/include/crypto/arc4.h b/include/crypto/arc4.h > > index 5b2c24ab0139..62ac95ec6860 100644 > > --- a/include/crypto/arc4.h > > +++ b/include/crypto/arc4.h > > @@ -6,8 +6,21 @@ > > #ifndef _CRYPTO_ARC4_H > > #define _CRYPTO_ARC4_H > > > > +#include <linux/types.h> > > + > > #define ARC4_MIN_KEY_SIZE 1 > > #define ARC4_MAX_KEY_SIZE 256 > > #define ARC4_BLOCK_SIZE 1 > > > > +struct crypto_arc4_ctx { > > + u32 S[256]; > > + u32 x, y; > > +}; > > + > > +int crypto_arc4_set_key(struct crypto_arc4_ctx *ctx, const u8 *in_key, > > + unsigned int key_len); > > + > > +void crypto_arc4_crypt(struct crypto_arc4_ctx *ctx, u8 *out, const u8 *in, > > + unsigned int len); > > How about naming these just arc4_* instead of crypto_arc4_*? The crypto_* > prefix is already used mostly for crypto API helper functions, i.e. functions > that take take one of the abstract crypto API types like crypto_skcipher, > shash_desc, etc. For lib functions, the bare name seems more appropriate. See > e.g. sha256_update() vs. crypto_sha256_update(). > That is also fine, although I am slightly concerned that we may run into trouble with other algorithms in the future. But I do agree it makes sense to make a clear distinction with the full blown API. > > +++ b/lib/crypto/Makefile > > @@ -0,0 +1,3 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > + > > +obj-$(CONFIG_CRYPTO_LIB_ARC4) += libarc4.o > > diff --git a/lib/crypto/libarc4.c b/lib/crypto/libarc4.c > > new file mode 100644 > > index 000000000000..b828af2cc03b > > --- /dev/null > > +++ b/lib/crypto/libarc4.c > > @@ -0,0 +1,74 @@ > > How about arc4.c instead of libarc4.c? The second "lib" is redundant, given > that the file is already in the lib/ directory. > The problem here is that we'll end up with two modules named arc4.ko, one in crypto/ and one in lib/crypto/. Perhaps we should rename the other one? (especially once it implements ecb(arc4) only.)
On Mon, Jun 10, 2019 at 06:10:41PM +0200, Ard Biesheuvel wrote: > On Mon, 10 Jun 2019 at 18:06, Eric Biggers <ebiggers@kernel.org> wrote: > > > > Just some bike shedding: > > > > On Sun, Jun 09, 2019 at 01:55:03PM +0200, Ard Biesheuvel wrote: > > > diff --git a/include/crypto/arc4.h b/include/crypto/arc4.h > > > index 5b2c24ab0139..62ac95ec6860 100644 > > > --- a/include/crypto/arc4.h > > > +++ b/include/crypto/arc4.h > > > @@ -6,8 +6,21 @@ > > > #ifndef _CRYPTO_ARC4_H > > > #define _CRYPTO_ARC4_H > > > > > > +#include <linux/types.h> > > > + > > > #define ARC4_MIN_KEY_SIZE 1 > > > #define ARC4_MAX_KEY_SIZE 256 > > > #define ARC4_BLOCK_SIZE 1 > > > > > > +struct crypto_arc4_ctx { > > > + u32 S[256]; > > > + u32 x, y; > > > +}; > > > + > > > +int crypto_arc4_set_key(struct crypto_arc4_ctx *ctx, const u8 *in_key, > > > + unsigned int key_len); > > > + > > > +void crypto_arc4_crypt(struct crypto_arc4_ctx *ctx, u8 *out, const u8 *in, > > > + unsigned int len); > > > > How about naming these just arc4_* instead of crypto_arc4_*? The crypto_* > > prefix is already used mostly for crypto API helper functions, i.e. functions > > that take take one of the abstract crypto API types like crypto_skcipher, > > shash_desc, etc. For lib functions, the bare name seems more appropriate. See > > e.g. sha256_update() vs. crypto_sha256_update(). > > > > That is also fine, although I am slightly concerned that we may run > into trouble with other algorithms in the future. But I do agree it > makes sense to make a clear distinction with the full blown API. > > > > +++ b/lib/crypto/Makefile > > > @@ -0,0 +1,3 @@ > > > +# SPDX-License-Identifier: GPL-2.0 > > > + > > > +obj-$(CONFIG_CRYPTO_LIB_ARC4) += libarc4.o > > > diff --git a/lib/crypto/libarc4.c b/lib/crypto/libarc4.c > > > new file mode 100644 > > > index 000000000000..b828af2cc03b > > > --- /dev/null > > > +++ b/lib/crypto/libarc4.c > > > @@ -0,0 +1,74 @@ > > > > How about arc4.c instead of libarc4.c? The second "lib" is redundant, given > > that the file is already in the lib/ directory. > > > > The problem here is that we'll end up with two modules named arc4.ko, > one in crypto/ and one in lib/crypto/. Perhaps we should rename the > other one? (especially once it implements ecb(arc4) only.) Another option is to do: obj-$(CONFIG_CRYPTO_LIB_ARC4) += libarc4.o libarc4-y := arc4.o Also, CONFIG_CRYPTO_LIB_ARC4 needs to actually be a tristate. It seems you accidentally made it a bool: > +config CRYPTO_LIB_ARC4 > + bool > + - Eric
diff --git a/MAINTAINERS b/MAINTAINERS index 57f496cff999..112f21066141 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4241,6 +4241,7 @@ F: crypto/ F: drivers/crypto/ F: include/crypto/ F: include/linux/crypto* +F: lib/crypto/ CRYPTOGRAPHIC RANDOM NUMBER GENERATOR M: Neil Horman <nhorman@tuxdriver.com> diff --git a/crypto/Kconfig b/crypto/Kconfig index 3d056e7da65f..310e2a5de59d 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1230,9 +1230,13 @@ config CRYPTO_ANUBIS <https://www.cosic.esat.kuleuven.be/nessie/reports/> <http://www.larc.usp.br/~pbarreto/AnubisPage.html> +config CRYPTO_LIB_ARC4 + bool + config CRYPTO_ARC4 tristate "ARC4 cipher algorithm" select CRYPTO_BLKCIPHER + select CRYPTO_LIB_ARC4 help ARC4 cipher algorithm. diff --git a/crypto/arc4.c b/crypto/arc4.c index a2120e06bf84..7f80623aa66a 100644 --- a/crypto/arc4.c +++ b/crypto/arc4.c @@ -13,33 +13,12 @@ #include <linux/init.h> #include <linux/module.h> -struct arc4_ctx { - u32 S[256]; - u32 x, y; -}; - static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len) { - struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); - int i, j = 0, k = 0; - - ctx->x = 1; - ctx->y = 0; - - for (i = 0; i < 256; i++) - ctx->S[i] = i; - - for (i = 0; i < 256; i++) { - u32 a = ctx->S[i]; - j = (j + in_key[k] + a) & 0xff; - ctx->S[i] = ctx->S[j]; - ctx->S[j] = a; - if (++k >= key_len) - k = 0; - } + struct crypto_arc4_ctx *ctx = crypto_tfm_ctx(tfm); - return 0; + return crypto_arc4_set_key(ctx, in_key, key_len); } static int arc4_set_key_skcipher(struct crypto_skcipher *tfm, const u8 *in_key, @@ -48,60 +27,23 @@ static int arc4_set_key_skcipher(struct crypto_skcipher *tfm, const u8 *in_key, return arc4_set_key(&tfm->base, in_key, key_len); } -static void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, - unsigned int len) -{ - u32 *const S = ctx->S; - u32 x, y, a, b; - u32 ty, ta, tb; - - if (len == 0) - return; - - x = ctx->x; - y = ctx->y; - - a = S[x]; - y = (y + a) & 0xff; - b = S[y]; - - do { - S[y] = a; - a = (a + b) & 0xff; - S[x] = b; - x = (x + 1) & 0xff; - ta = S[x]; - ty = (y + ta) & 0xff; - tb = S[ty]; - *out++ = *in++ ^ S[a]; - if (--len == 0) - break; - y = ty; - a = ta; - b = tb; - } while (true); - - ctx->x = x; - ctx->y = y; -} - static void arc4_crypt_one(struct crypto_tfm *tfm, u8 *out, const u8 *in) { - arc4_crypt(crypto_tfm_ctx(tfm), out, in, 1); + crypto_arc4_crypt(crypto_tfm_ctx(tfm), out, in, 1); } static int ecb_arc4_crypt(struct skcipher_request *req) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); - struct arc4_ctx *ctx = crypto_skcipher_ctx(tfm); + struct crypto_arc4_ctx *ctx = crypto_skcipher_ctx(tfm); struct skcipher_walk walk; int err; err = skcipher_walk_virt(&walk, req, false); while (walk.nbytes > 0) { - arc4_crypt(ctx, walk.dst.virt.addr, walk.src.virt.addr, - walk.nbytes); + crypto_arc4_crypt(ctx, walk.dst.virt.addr, walk.src.virt.addr, + walk.nbytes); err = skcipher_walk_done(&walk, 0); } @@ -112,7 +54,7 @@ static struct crypto_alg arc4_cipher = { .cra_name = "arc4", .cra_flags = CRYPTO_ALG_TYPE_CIPHER, .cra_blocksize = ARC4_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct arc4_ctx), + .cra_ctxsize = sizeof(struct crypto_arc4_ctx), .cra_module = THIS_MODULE, .cra_u = { .cipher = { @@ -129,7 +71,7 @@ static struct skcipher_alg arc4_skcipher = { .base.cra_name = "ecb(arc4)", .base.cra_priority = 100, .base.cra_blocksize = ARC4_BLOCK_SIZE, - .base.cra_ctxsize = sizeof(struct arc4_ctx), + .base.cra_ctxsize = sizeof(struct crypto_arc4_ctx), .base.cra_module = THIS_MODULE, .min_keysize = ARC4_MIN_KEY_SIZE, .max_keysize = ARC4_MAX_KEY_SIZE, diff --git a/include/crypto/arc4.h b/include/crypto/arc4.h index 5b2c24ab0139..62ac95ec6860 100644 --- a/include/crypto/arc4.h +++ b/include/crypto/arc4.h @@ -6,8 +6,21 @@ #ifndef _CRYPTO_ARC4_H #define _CRYPTO_ARC4_H +#include <linux/types.h> + #define ARC4_MIN_KEY_SIZE 1 #define ARC4_MAX_KEY_SIZE 256 #define ARC4_BLOCK_SIZE 1 +struct crypto_arc4_ctx { + u32 S[256]; + u32 x, y; +}; + +int crypto_arc4_set_key(struct crypto_arc4_ctx *ctx, const u8 *in_key, + unsigned int key_len); + +void crypto_arc4_crypt(struct crypto_arc4_ctx *ctx, u8 *out, const u8 *in, + unsigned int len); + #endif /* _CRYPTO_ARC4_H */ diff --git a/lib/Makefile b/lib/Makefile index fb7697031a79..d3daedf93c5a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -102,7 +102,7 @@ endif obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any) -obj-y += math/ +obj-y += math/ crypto/ obj-$(CONFIG_GENERIC_IOMAP) += iomap.o obj-$(CONFIG_GENERIC_PCI_IOMAP) += pci_iomap.o diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile new file mode 100644 index 000000000000..e375d150a547 --- /dev/null +++ b/lib/crypto/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_CRYPTO_LIB_ARC4) += libarc4.o diff --git a/lib/crypto/libarc4.c b/lib/crypto/libarc4.c new file mode 100644 index 000000000000..b828af2cc03b --- /dev/null +++ b/lib/crypto/libarc4.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Cryptographic API + * + * ARC4 Cipher Algorithm + * + * Jon Oberheide <jon@oberheide.org> + */ + +#include <crypto/arc4.h> +#include <linux/module.h> + +int crypto_arc4_set_key(struct crypto_arc4_ctx *ctx, const u8 *in_key, + unsigned int key_len) +{ + int i, j = 0, k = 0; + + ctx->x = 1; + ctx->y = 0; + + for (i = 0; i < 256; i++) + ctx->S[i] = i; + + for (i = 0; i < 256; i++) { + u32 a = ctx->S[i]; + + j = (j + in_key[k] + a) & 0xff; + ctx->S[i] = ctx->S[j]; + ctx->S[j] = a; + if (++k >= key_len) + k = 0; + } + + return 0; +} +EXPORT_SYMBOL(crypto_arc4_set_key); + +void crypto_arc4_crypt(struct crypto_arc4_ctx *ctx, u8 *out, const u8 *in, + unsigned int len) +{ + u32 *const S = ctx->S; + u32 x, y, a, b; + u32 ty, ta, tb; + + if (len == 0) + return; + + x = ctx->x; + y = ctx->y; + + a = S[x]; + y = (y + a) & 0xff; + b = S[y]; + + do { + S[y] = a; + a = (a + b) & 0xff; + S[x] = b; + x = (x + 1) & 0xff; + ta = S[x]; + ty = (y + ta) & 0xff; + tb = S[ty]; + *out++ = *in++ ^ S[a]; + if (--len == 0) + break; + y = ty; + a = ta; + b = tb; + } while (true); + + ctx->x = x; + ctx->y = y; +} +EXPORT_SYMBOL(crypto_arc4_crypt);
Refactor the core rc4 handling so we can move most users to a library interface, permitting us to drop the cipher interface entirely in a future patch. This is part of an effort to simplify the crypto API and improve its robustness against incorrect use. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- MAINTAINERS | 1 + crypto/Kconfig | 4 ++ crypto/arc4.c | 74 +++----------------- include/crypto/arc4.h | 13 ++++ lib/Makefile | 2 +- lib/crypto/Makefile | 3 + lib/crypto/libarc4.c | 74 ++++++++++++++++++++ 7 files changed, 104 insertions(+), 67 deletions(-) -- 2.20.1