Linux Audio

Check our new training course

Loading...
v4.6
 
  1/*
  2 * Cryptographic API
  3 *
  4 * ARC4 Cipher Algorithm
  5 *
  6 * Jon Oberheide <jon@oberheide.org>
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License as published by
 10 * the Free Software Foundation; either version 2 of the License, or
 11 * (at your option) any later version.
 12 *
 13 */
 14
 15#include <linux/module.h>
 16#include <linux/init.h>
 17#include <linux/crypto.h>
 18#include <crypto/algapi.h>
 
 
 
 
 
 
 19
 20#define ARC4_MIN_KEY_SIZE	1
 21#define ARC4_MAX_KEY_SIZE	256
 22#define ARC4_BLOCK_SIZE		1
 23
 24struct arc4_ctx {
 25	u32 S[256];
 26	u32 x, y;
 27};
 28
 29static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key,
 30			unsigned int key_len)
 31{
 32	struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
 33	int i, j = 0, k = 0;
 34
 35	ctx->x = 1;
 36	ctx->y = 0;
 37
 38	for (i = 0; i < 256; i++)
 39		ctx->S[i] = i;
 40
 41	for (i = 0; i < 256; i++) {
 42		u32 a = ctx->S[i];
 43		j = (j + in_key[k] + a) & 0xff;
 44		ctx->S[i] = ctx->S[j];
 45		ctx->S[j] = a;
 46		if (++k >= key_len)
 47			k = 0;
 48	}
 49
 50	return 0;
 51}
 52
 53static void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in,
 54		       unsigned int len)
 55{
 56	u32 *const S = ctx->S;
 57	u32 x, y, a, b;
 58	u32 ty, ta, tb;
 59
 60	if (len == 0)
 61		return;
 62
 63	x = ctx->x;
 64	y = ctx->y;
 65
 66	a = S[x];
 67	y = (y + a) & 0xff;
 68	b = S[y];
 69
 70	do {
 71		S[y] = a;
 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);
 85
 86	ctx->x = x;
 87	ctx->y = y;
 88}
 89
 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] = { {
119	.cra_name		=	"arc4",
120	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
121	.cra_blocksize		=	ARC4_BLOCK_SIZE,
122	.cra_ctxsize		=	sizeof(struct arc4_ctx),
123	.cra_module		=	THIS_MODULE,
124	.cra_u			=	{
125		.cipher = {
126			.cia_min_keysize	=	ARC4_MIN_KEY_SIZE,
127			.cia_max_keysize	=	ARC4_MAX_KEY_SIZE,
128			.cia_setkey		=	arc4_set_key,
129			.cia_encrypt		=	arc4_crypt_one,
130			.cia_decrypt		=	arc4_crypt_one,
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} };
152
153static int __init arc4_init(void)
154{
155	return crypto_register_algs(arc4_algs, ARRAY_SIZE(arc4_algs));
156}
157
158static void __exit arc4_exit(void)
159{
160	crypto_unregister_algs(arc4_algs, ARRAY_SIZE(arc4_algs));
161}
162
163module_init(arc4_init);
164module_exit(arc4_exit);
165
166MODULE_LICENSE("GPL");
167MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
168MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
169MODULE_ALIAS_CRYPTO("arc4");
v6.2
 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/algapi.h>
11#include <crypto/arc4.h>
12#include <crypto/internal/skcipher.h>
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/sched.h>
17
18static int crypto_arc4_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
19			      unsigned int key_len)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20{
21	struct arc4_ctx *ctx = crypto_skcipher_ctx(tfm);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
23	return arc4_setkey(ctx, in_key, key_len);
 
24}
25
26static int crypto_arc4_crypt(struct skcipher_request *req)
27{
28	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
29	struct arc4_ctx *ctx = crypto_skcipher_ctx(tfm);
30	struct skcipher_walk walk;
 
 
 
 
 
31	int err;
32
33	err = skcipher_walk_virt(&walk, req, false);
 
 
34
35	while (walk.nbytes > 0) {
36		arc4_crypt(ctx, walk.dst.virt.addr, walk.src.virt.addr,
37			   walk.nbytes);
38		err = skcipher_walk_done(&walk, 0);
 
 
 
39	}
40
41	return err;
42}
43
44static int crypto_arc4_init(struct crypto_skcipher *tfm)
45{
46	pr_warn_ratelimited("\"%s\" (%ld) uses obsolete ecb(arc4) skcipher\n",
47			    current->comm, (unsigned long)current->pid);
48
49	return 0;
50}
51
52static struct skcipher_alg arc4_alg = {
53	/*
54	 * For legacy reasons, this is named "ecb(arc4)", not "arc4".
55	 * Nevertheless it's actually a stream cipher, not a block cipher.
56	 */
57	.base.cra_name		=	"ecb(arc4)",
58	.base.cra_driver_name	=	"ecb(arc4)-generic",
59	.base.cra_priority	=	100,
60	.base.cra_blocksize	=	ARC4_BLOCK_SIZE,
61	.base.cra_ctxsize	=	sizeof(struct arc4_ctx),
62	.base.cra_module	=	THIS_MODULE,
63	.min_keysize		=	ARC4_MIN_KEY_SIZE,
64	.max_keysize		=	ARC4_MAX_KEY_SIZE,
65	.setkey			=	crypto_arc4_setkey,
66	.encrypt		=	crypto_arc4_crypt,
67	.decrypt		=	crypto_arc4_crypt,
68	.init			=	crypto_arc4_init,
69};
 
 
 
 
 
 
 
 
70
71static int __init arc4_init(void)
72{
73	return crypto_register_skcipher(&arc4_alg);
74}
75
76static void __exit arc4_exit(void)
77{
78	crypto_unregister_skcipher(&arc4_alg);
79}
80
81subsys_initcall(arc4_init);
82module_exit(arc4_exit);
83
84MODULE_LICENSE("GPL");
85MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
86MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
87MODULE_ALIAS_CRYPTO("ecb(arc4)");