@@ -561,7 +561,7 @@ config CRYPTO_ANUBIS
config CRYPTO_ARC4
tristate "ARC4 cipher algorithm"
- select CRYPTO_ALGAPI
+ select CRYPTO_BLKCIPHER
help
ARC4 cipher algorithm.
@@ -1,4 +1,4 @@
-/*
+/*
* Cryptographic API
*
* ARC4 Cipher Algorithm
@@ -13,76 +13,124 @@
*/
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/crypto.h>
+#include <crypto/algapi.h>
#define ARC4_MIN_KEY_SIZE 1
#define ARC4_MAX_KEY_SIZE 256
#define ARC4_BLOCK_SIZE 1
-struct arc4_ctx {
+struct arc4_iv {
u8 S[256];
u8 x, y;
};
+struct arc4_ctx {
+ struct arc4_iv iv;
+ u8 new_key;
+};
+
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;
+ ctx->iv.x = 1;
+ ctx->iv.y = 0;
- for(i = 0; i < 256; i++)
- ctx->S[i] = i;
+ for (i = 0; i < 256; i++)
+ ctx->iv.S[i] = i;
- for(i = 0; i < 256; i++)
+ for (i = 0; i < 256; i++)
{
- u8 a = ctx->S[i];
+ u8 a = ctx->iv.S[i];
j = (j + in_key[k] + a) & 0xff;
- ctx->S[i] = ctx->S[j];
- ctx->S[j] = a;
- if(++k >= key_len)
+ ctx->iv.S[i] = ctx->iv.S[j];
+ ctx->iv.S[j] = a;
+ if (++k >= key_len)
k = 0;
}
-
+ ctx->new_key = 1;
return 0;
}
-static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+static void arc4_ivsetup(struct arc4_ctx *ctx, u8 *iv)
{
- struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
+ if (unlikely(!ctx->new_key))
+ return;
+ memcpy(iv, &ctx->iv, sizeof(ctx->iv));
+ ctx->new_key = 0;
+}
- u8 *const S = ctx->S;
- u8 x = ctx->x;
- u8 y = ctx->y;
+static int arc4_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+ struct crypto_blkcipher *tfm = desc->tfm;
+ struct arc4_ctx *ctx = crypto_blkcipher_ctx(tfm);
+ struct arc4_iv *iv;
+ u8 *S;
+ u8 x;
+ u8 y;
u8 a, b;
+ int ret;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ ret = blkcipher_walk_virt(desc, &walk);
+ if (ret)
+ return ret;
+
+ arc4_ivsetup(ctx, walk.iv);
+
+ iv = (struct arc4_iv *)walk.iv;
+
+ S = iv->S;
+ x = iv->x;
+ y = iv->y;
+
+ while (walk.nbytes) {
+ u8 *in = walk.src.virt.addr;
+ u8 *out = walk.dst.virt.addr;
+ u32 i;
+
+ for (i = 0; i < walk.nbytes; i++) {
+ a = S[x];
+ y = (y + a) & 0xff;
+ b = S[y];
+ S[x] = b;
+ S[y] = a;
+ x = (x + 1) & 0xff;
+ *out = *in ^ S[(a + b) & 0xff];
+
+ in++;
+ out++;
+ }
+ ret = blkcipher_walk_done(desc, &walk, 0);
+ WARN_ON(ret < 0);
+ }
- a = S[x];
- y = (y + a) & 0xff;
- b = S[y];
- S[x] = b;
- S[y] = a;
- x = (x + 1) & 0xff;
- *out++ = *in ^ S[(a + b) & 0xff];
-
- ctx->x = x;
- ctx->y = y;
+ iv->x = x;
+ iv->y = y;
+ return ret;
}
static struct crypto_alg arc4_alg = {
- .cra_name = "arc4",
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_name = "ecb(arc4)",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_blocksize = ARC4_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct arc4_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_alignmask = 3,
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(arc4_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = ARC4_MIN_KEY_SIZE,
- .cia_max_keysize = ARC4_MAX_KEY_SIZE,
- .cia_setkey = arc4_set_key,
- .cia_encrypt = arc4_crypt,
- .cia_decrypt = arc4_crypt } }
+ .cra_u = { .blkcipher = {
+ .min_keysize = ARC4_MIN_KEY_SIZE,
+ .max_keysize = ARC4_MAX_KEY_SIZE,
+ .ivsize = sizeof(struct arc4_iv),
+ .setkey = arc4_set_key,
+ .encrypt = arc4_crypt,
+ .decrypt = arc4_crypt } }
};
static int __init arc4_init(void)
@@ -24,7 +24,8 @@
#define MAX_TAP 8
#define MAX_KEYLEN 56
-#define MAX_IVLEN 32
+/* sizeof arc4_iv */
+#define MAX_IVLEN 260
struct hash_testvec {
/* only used with keyed hash algorithms */
@@ -3076,7 +3076,6 @@ config PPP_MPPE
select CRYPTO
select CRYPTO_SHA1
select CRYPTO_ARC4
- select CRYPTO_ECB
---help---
Support for the MPPE Encryption protocol, as employed by the
Microsoft Point-to-Point Tunneling Protocol.
@@ -5,10 +5,8 @@ config HOSTAP
select WEXT_PRIV
select CRYPTO
select CRYPTO_ARC4
- select CRYPTO_ECB
select CRYPTO_AES
select CRYPTO_MICHAEL_MIC
- select CRYPTO_ECB
select CRC32
select LIB80211
select LIB80211_CRYPT_WEP
@@ -159,10 +159,8 @@ config LIBIPW
select WEXT_SPY
select CRYPTO
select CRYPTO_ARC4
- select CRYPTO_ECB
select CRYPTO_AES
select CRYPTO_MICHAEL_MIC
- select CRYPTO_ECB
select CRC32
select LIB80211
select LIB80211_CRYPT_WEP
@@ -2,7 +2,6 @@ config MAC80211
tristate "Generic IEEE 802.11 Networking Stack (mac80211)"
depends on CFG80211
select CRYPTO
- select CRYPTO_ECB
select CRYPTO_ARC4
select CRYPTO_AES
select CRC32