aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/arc4.c109
1 files changed, 87 insertions, 22 deletions
diff --git a/crypto/arc4.c b/crypto/arc4.c
index 0d12a96da1d8..07913fc52c4e 100644
--- a/crypto/arc4.c
+++ b/crypto/arc4.c
@@ -11,9 +11,11 @@
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 */ 13 */
14
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/init.h> 16#include <linux/init.h>
16#include <linux/crypto.h> 17#include <linux/crypto.h>
18#include <crypto/algapi.h>
17 19
18#define ARC4_MIN_KEY_SIZE 1 20#define ARC4_MIN_KEY_SIZE 1
19#define ARC4_MAX_KEY_SIZE 256 21#define ARC4_MAX_KEY_SIZE 256
@@ -48,51 +50,114 @@ static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key,
48 return 0; 50 return 0;
49} 51}
50 52
51static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 53static void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in,
54 unsigned int len)
52{ 55{
53 struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
54
55 u8 *const S = ctx->S; 56 u8 *const S = ctx->S;
56 u8 x = ctx->x; 57 u8 x, y, a, b;
57 u8 y = ctx->y; 58 u8 ty, ta, tb;
58 u8 a, b; 59
60 if (len == 0)
61 return;
62
63 x = ctx->x;
64 y = ctx->y;
59 65
60 a = S[x]; 66 a = S[x];
61 y = (y + a) & 0xff; 67 y = (y + a) & 0xff;
62 b = S[y]; 68 b = S[y];
63 S[x] = b; 69
64 S[y] = a; 70 do {
65 x = (x + 1) & 0xff; 71 S[y] = a;
66 *out++ = *in ^ S[(a + b) & 0xff]; 72 a = (a + b) & 0xff;
73 S[x] = b;
74 x = (x + 1) & 0xff;
75 ta = S[x];
76 ty = (y + ta) & 0xff;
77 tb = S[ty];
78 *out++ = *in++ ^ S[a];
79 if (--len == 0)
80 break;
81 y = ty;
82 a = ta;
83 b = tb;
84 } while (true);
67 85
68 ctx->x = x; 86 ctx->x = x;
69 ctx->y = y; 87 ctx->y = y;
70} 88}
71 89
72static struct crypto_alg arc4_alg = { 90static void arc4_crypt_one(struct crypto_tfm *tfm, u8 *out, const u8 *in)
91{
92 arc4_crypt(crypto_tfm_ctx(tfm), out, in, 1);
93}
94
95static int ecb_arc4_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
96 struct scatterlist *src, unsigned int nbytes)
97{
98 struct arc4_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
99 struct blkcipher_walk walk;
100 int err;
101
102 blkcipher_walk_init(&walk, dst, src, nbytes);
103
104 err = blkcipher_walk_virt(desc, &walk);
105
106 while (walk.nbytes > 0) {
107 u8 *wsrc = walk.src.virt.addr;
108 u8 *wdst = walk.dst.virt.addr;
109
110 arc4_crypt(ctx, wdst, wsrc, walk.nbytes);
111
112 err = blkcipher_walk_done(desc, &walk, 0);
113 }
114
115 return err;
116}
117
118static struct crypto_alg arc4_algs[2] = { {
73 .cra_name = "arc4", 119 .cra_name = "arc4",
74 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 120 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
75 .cra_blocksize = ARC4_BLOCK_SIZE, 121 .cra_blocksize = ARC4_BLOCK_SIZE,
76 .cra_ctxsize = sizeof(struct arc4_ctx), 122 .cra_ctxsize = sizeof(struct arc4_ctx),
77 .cra_module = THIS_MODULE, 123 .cra_module = THIS_MODULE,
78 .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list), 124 .cra_u = {
79 .cra_u = { .cipher = { 125 .cipher = {
80 .cia_min_keysize = ARC4_MIN_KEY_SIZE, 126 .cia_min_keysize = ARC4_MIN_KEY_SIZE,
81 .cia_max_keysize = ARC4_MAX_KEY_SIZE, 127 .cia_max_keysize = ARC4_MAX_KEY_SIZE,
82 .cia_setkey = arc4_set_key, 128 .cia_setkey = arc4_set_key,
83 .cia_encrypt = arc4_crypt, 129 .cia_encrypt = arc4_crypt_one,
84 .cia_decrypt = arc4_crypt } } 130 .cia_decrypt = arc4_crypt_one,
85}; 131 },
132 },
133}, {
134 .cra_name = "ecb(arc4)",
135 .cra_priority = 100,
136 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
137 .cra_blocksize = ARC4_BLOCK_SIZE,
138 .cra_ctxsize = sizeof(struct arc4_ctx),
139 .cra_alignmask = 0,
140 .cra_type = &crypto_blkcipher_type,
141 .cra_module = THIS_MODULE,
142 .cra_u = {
143 .blkcipher = {
144 .min_keysize = ARC4_MIN_KEY_SIZE,
145 .max_keysize = ARC4_MAX_KEY_SIZE,
146 .setkey = arc4_set_key,
147 .encrypt = ecb_arc4_crypt,
148 .decrypt = ecb_arc4_crypt,
149 },
150 },
151} };
86 152
87static int __init arc4_init(void) 153static int __init arc4_init(void)
88{ 154{
89 return crypto_register_alg(&arc4_alg); 155 return crypto_register_algs(arc4_algs, ARRAY_SIZE(arc4_algs));
90} 156}
91 157
92
93static void __exit arc4_exit(void) 158static void __exit arc4_exit(void)
94{ 159{
95 crypto_unregister_alg(&arc4_alg); 160 crypto_unregister_algs(arc4_algs, ARRAY_SIZE(arc4_algs));
96} 161}
97 162
98module_init(arc4_init); 163module_init(arc4_init);