Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: arc4 - refactor arc4 core code into separate library

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>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Ard Biesheuvel and committed by
Herbert Xu
dc51f257 192125ed

+95 -60
+1
MAINTAINERS
··· 4229 4229 F: drivers/crypto/ 4230 4230 F: include/crypto/ 4231 4231 F: include/linux/crypto* 4232 + F: lib/crypto/ 4232 4233 4233 4234 CRYPTOGRAPHIC RANDOM NUMBER GENERATOR 4234 4235 M: Neil Horman <nhorman@tuxdriver.com>
+4
crypto/Kconfig
··· 1237 1237 <https://www.cosic.esat.kuleuven.be/nessie/reports/> 1238 1238 <http://www.larc.usp.br/~pbarreto/AnubisPage.html> 1239 1239 1240 + config CRYPTO_LIB_ARC4 1241 + tristate 1242 + 1240 1243 config CRYPTO_ARC4 1241 1244 tristate "ARC4 cipher algorithm" 1242 1245 select CRYPTO_BLKCIPHER 1246 + select CRYPTO_LIB_ARC4 1243 1247 help 1244 1248 ARC4 cipher algorithm. 1245 1249
+1 -59
crypto/arc4.c
··· 18 18 #include <linux/init.h> 19 19 #include <linux/module.h> 20 20 21 - struct arc4_ctx { 22 - u32 S[256]; 23 - u32 x, y; 24 - }; 25 - 26 21 static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, 27 22 unsigned int key_len) 28 23 { 29 24 struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); 30 - int i, j = 0, k = 0; 31 25 32 - ctx->x = 1; 33 - ctx->y = 0; 34 - 35 - for (i = 0; i < 256; i++) 36 - ctx->S[i] = i; 37 - 38 - for (i = 0; i < 256; i++) { 39 - u32 a = ctx->S[i]; 40 - j = (j + in_key[k] + a) & 0xff; 41 - ctx->S[i] = ctx->S[j]; 42 - ctx->S[j] = a; 43 - if (++k >= key_len) 44 - k = 0; 45 - } 46 - 47 - return 0; 26 + return arc4_setkey(ctx, in_key, key_len); 48 27 } 49 28 50 29 static int arc4_set_key_skcipher(struct crypto_skcipher *tfm, const u8 *in_key, 51 30 unsigned int key_len) 52 31 { 53 32 return arc4_set_key(&tfm->base, in_key, key_len); 54 - } 55 - 56 - static void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, 57 - unsigned int len) 58 - { 59 - u32 *const S = ctx->S; 60 - u32 x, y, a, b; 61 - u32 ty, ta, tb; 62 - 63 - if (len == 0) 64 - return; 65 - 66 - x = ctx->x; 67 - y = ctx->y; 68 - 69 - a = S[x]; 70 - y = (y + a) & 0xff; 71 - b = S[y]; 72 - 73 - do { 74 - S[y] = a; 75 - a = (a + b) & 0xff; 76 - S[x] = b; 77 - x = (x + 1) & 0xff; 78 - ta = S[x]; 79 - ty = (y + ta) & 0xff; 80 - tb = S[ty]; 81 - *out++ = *in++ ^ S[a]; 82 - if (--len == 0) 83 - break; 84 - y = ty; 85 - a = ta; 86 - b = tb; 87 - } while (true); 88 - 89 - ctx->x = x; 90 - ctx->y = y; 91 33 } 92 34 93 35 static void arc4_crypt_one(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+10
include/crypto/arc4.h
··· 6 6 #ifndef _CRYPTO_ARC4_H 7 7 #define _CRYPTO_ARC4_H 8 8 9 + #include <linux/types.h> 10 + 9 11 #define ARC4_MIN_KEY_SIZE 1 10 12 #define ARC4_MAX_KEY_SIZE 256 11 13 #define ARC4_BLOCK_SIZE 1 14 + 15 + struct arc4_ctx { 16 + u32 S[256]; 17 + u32 x, y; 18 + }; 19 + 20 + int arc4_setkey(struct arc4_ctx *ctx, const u8 *in_key, unsigned int key_len); 21 + void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int len); 12 22 13 23 #endif /* _CRYPTO_ARC4_H */
+1 -1
lib/Makefile
··· 102 102 obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o 103 103 CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any) 104 104 105 - obj-y += math/ 105 + obj-y += math/ crypto/ 106 106 107 107 obj-$(CONFIG_GENERIC_IOMAP) += iomap.o 108 108 obj-$(CONFIG_GENERIC_PCI_IOMAP) += pci_iomap.o
+4
lib/crypto/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + obj-$(CONFIG_CRYPTO_LIB_ARC4) += libarc4.o 4 + libarc4-y := arc4.o
+74
lib/crypto/arc4.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Cryptographic API 4 + * 5 + * ARC4 Cipher Algorithm 6 + * 7 + * Jon Oberheide <jon@oberheide.org> 8 + */ 9 + 10 + #include <crypto/arc4.h> 11 + #include <linux/module.h> 12 + 13 + int arc4_setkey(struct arc4_ctx *ctx, const u8 *in_key, unsigned int key_len) 14 + { 15 + int i, j = 0, k = 0; 16 + 17 + ctx->x = 1; 18 + ctx->y = 0; 19 + 20 + for (i = 0; i < 256; i++) 21 + ctx->S[i] = i; 22 + 23 + for (i = 0; i < 256; i++) { 24 + u32 a = ctx->S[i]; 25 + 26 + j = (j + in_key[k] + a) & 0xff; 27 + ctx->S[i] = ctx->S[j]; 28 + ctx->S[j] = a; 29 + if (++k >= key_len) 30 + k = 0; 31 + } 32 + 33 + return 0; 34 + } 35 + EXPORT_SYMBOL(arc4_setkey); 36 + 37 + void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int len) 38 + { 39 + u32 *const S = ctx->S; 40 + u32 x, y, a, b; 41 + u32 ty, ta, tb; 42 + 43 + if (len == 0) 44 + return; 45 + 46 + x = ctx->x; 47 + y = ctx->y; 48 + 49 + a = S[x]; 50 + y = (y + a) & 0xff; 51 + b = S[y]; 52 + 53 + do { 54 + S[y] = a; 55 + a = (a + b) & 0xff; 56 + S[x] = b; 57 + x = (x + 1) & 0xff; 58 + ta = S[x]; 59 + ty = (y + ta) & 0xff; 60 + tb = S[ty]; 61 + *out++ = *in++ ^ S[a]; 62 + if (--len == 0) 63 + break; 64 + y = ty; 65 + a = ta; 66 + b = tb; 67 + } while (true); 68 + 69 + ctx->x = x; 70 + ctx->y = y; 71 + } 72 + EXPORT_SYMBOL(arc4_crypt); 73 + 74 + MODULE_LICENSE("GPL");