Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
* Herbert Xu | 2010-02-23 08:32:39 [+0800]: If you can find a way that allows arc4 to be used by multiple threads at the same time while storing less than 258 bytes in each thread, please let me know :) :) No, what you could do is structure the IV differently based on the flag: struct arc4_iv { union { struct key { u8 key[256]; u16 keylen; }; struct iv { u8 S[256]; u8 x, y; }; }; u8 type; }; This relies on the fact that we never use more than 256 bytes in the key so limiting its length is OK. Okay. So so are we talking about something like that below then? This is untested and I break other users bexcept lib80211_crypt_tkip. the state has been moved from ctx into iv. That way encrypt()/decrypt() can deliver the same result for a given IV. If the IV is supplied as a plain key then it wil be converted into a different internal state. The name is now arc4. Signed-off-by: Sebastian Andrzej Siewior sebast...@breakpoint.cc --- crypto/Kconfig |2 +- crypto/arc4.c| 131 +++--- crypto/testmgr.h |3 +- drivers/net/Kconfig |1 - drivers/net/wireless/hostap/Kconfig |2 - drivers/net/wireless/ipw2x00/Kconfig |2 - include/crypto/arc4.h| 26 +++ net/mac80211/Kconfig |1 - net/wireless/lib80211_crypt_tkip.c | 10 ++- 9 files changed, 123 insertions(+), 55 deletions(-) create mode 100644 include/crypto/arc4.h diff --git a/crypto/Kconfig b/crypto/Kconfig index 81c185a..5fab1c3 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -561,7 +561,7 @@ config CRYPTO_ANUBIS config CRYPTO_ARC4 tristate ARC4 cipher algorithm - select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER help ARC4 cipher algorithm. diff --git a/crypto/arc4.c b/crypto/arc4.c index 8be47e1..1b20463 100644 --- a/crypto/arc4.c +++ b/crypto/arc4.c @@ -1,4 +1,4 @@ -/* +/* * Cryptographic API * * ARC4 Cipher Algorithm @@ -13,76 +13,122 @@ */ #include linux/module.h #include linux/init.h -#include linux/crypto.h +#include crypto/algapi.h +#include crypto/arc4.h #define ARC4_MIN_KEY_SIZE 1 #define ARC4_MAX_KEY_SIZE 256 #define ARC4_BLOCK_SIZE1 -struct arc4_ctx { - u8 S[256]; - u8 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); + /* +* ARC4 is special: The user should supply an IV as struct arc4_iv and +* fill either the key or the iv. +*/ + return -EOPNOTSUPP; +} + +static void arc4_key_to_iv(const u8 *in_key, u32 key_len, struct arc4_iv *iv) +{ int i, j = 0, k = 0; - ctx-x = 1; - ctx-y = 0; + iv-iv.x = 1; + iv-iv.y = 0; - for(i = 0; i 256; i++) - ctx-S[i] = i; + for (i = 0; i 256; i++) + iv-iv.S[i] = i; - for(i = 0; i 256; i++) + for (i = 0; i 256; i++) { - u8 a = ctx-S[i]; + u8 a = iv-iv.S[i]; j = (j + in_key[k] + a) 0xff; - ctx-S[i] = ctx-S[j]; - ctx-S[j] = a; - if(++k = key_len) + iv-iv.S[i] = iv-iv.S[j]; + iv-iv.S[j] = a; + if (++k = key_len) k = 0; } - - return 0; } -static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void arc4_ivsetup(struct arc4_iv *iv) { - struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); + struct arc4_iv tmp_iv; - u8 *const S = ctx-S; - u8 x = ctx-x; - u8 y = ctx-y; - u8 a, b; + if (iv-type == ARC4_TYPE_IV) + return; - 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]; + memcpy(tmp_iv, iv, sizeof(tmp_iv)); + arc4_key_to_iv(tmp_iv.key.key, tmp_iv.key.key_len, iv); + iv-type = ARC4_TYPE_IV; +} + +static int arc4_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct blkcipher_walk walk; + struct arc4_iv *aiv; + 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; + + aiv = (struct arc4_iv *)walk.iv; + arc4_ivsetup(aiv); + + S = aiv-iv.S; + x = aiv-iv.x; + y = aiv-iv.y; + + while (walk.nbytes) { + u8 *in = walk.src.virt.addr; + u8 *out =
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
On Sun, Mar 14, 2010 at 09:24:32AM +0100, Sebastian Andrzej Siewior wrote: Okay. So so are we talking about something like that below then? This is Pretty much. untested and I break other users bexcept lib80211_crypt_tkip. For the sake of compatibility please do this as a 3-step dance. First add a new arc4 blkcipher, then convert the users, and finally delete the old arc4. 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); + /* + * ARC4 is special: The user should supply an IV as struct arc4_iv and + * fill either the key or the iv. + */ + return -EOPNOTSUPP; +} You should return 0 here. You should also set the min/max key size to zero. The new arc4 no longer has a key as far as the API is concerned. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
On Tue, 16 Feb 2010, Herbert Xu wrote: On Fri, Feb 12, 2010 at 09:42:28AM +0100, Sebastian Andrzej Siewior wrote: -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; Sorry, but this doesn't work. A ctx is supposed to be reentrant. That is, while one thread is working away with a given ctx I should be able to use that same ctx in a different thread without them clobbering each other. So that means (in general) you must not modify the ctx in any function other than setkey. This also brings up the bigger question of how we transition to this new arc4. I don't think we need to maintain exactly the same behaviour as the existing ecb(arc4). So what we could do is simply add a new blkcipher arc4, alongside the existing cipher arc4. Then we can convert the existing users across, and finally remove the old arc4. arc4 can't be used as a block cipher --- see this paper http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps , it says that initialization vectors on RC4 are unreliable, if you use (unknown key concatenated with known IV) or (known IV concatenated with unknown key) as a RC4 key, the RC4 state can be exposed and the cipher is broken. If you want to avoid this attack, you'd have to do this for each sector: - take the secret key and the IV and hash them cryptographically - use this hash as a RC4 key (to avoid the above related-key attack) - discard the first 256 bytes from the RC4 output (to avoid another problem with RC4 --- the beginning of the output is biased) - use the resulting RC4 state to encrypt a single 512-byte sector Now, the question is, if RC4 with all this dance around its problems would be still faster than AES. I doubt. I think there is not much sense in writing code to allow arc4 to be used for disk encryption. You should just ban it. Mikulas -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
* Herbert Xu | 2010-02-22 08:52:17 [+0800]: On Mon, Feb 22, 2010 at 08:45:47AM +0800, Herbert Xu wrote: How about this? You extend the IV by one more byte, and use that byte as a boolean flag to indicate whether the IV is valid. All So I trick the crypto api to allocate more bytes than -ivsize says. users that cannot supply their own IVs can then set the IV to zero. which works fine with kzalloc() When you see the zero flag in the IV, you reinitialise the IV per the key. Okay. When we have to re-key and the user calls setkey() without re-allocating thr cipher then I would not notice this. So I need a counter. And all this will make it work but I still think it is fishy. Plus we waste 258bytes. In fact for arc4 we could just drop the key altogether since it plays no part after setting the initial state. Since I'm not allowed to kfree() the ctx in encrypt() are you proposing tfm-setup_iv(iv, key)? salsa also does not stick to plan here. ctx-input[6-9] is initialized in encrypt() path. So two threads sharing a ctx are going to clobber their state. Salsa should also be fixed. I saw that comming. And I complaind back then that the assembly code was not pretty enough... and removing the assembly is probably not option :) For Salsa on the other hand the key is rather useful since all we need is a two-byte IV that's just a sequence number. No it's 8 bytes. Berstein's U8TO32_LITTLE() is actually a cpu_to_be32(). Not sure if he knows it :) However I'm not sure where you going with this. salsa is fine besides the clobber thing, isn't it? Cheers, Sebastian -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
On Mon, Feb 22, 2010 at 02:40:49PM -0500, Mikulas Patocka wrote: So what we could do is simply add a new blkcipher arc4, alongside the existing cipher arc4. Then we can convert the existing users across, and finally remove the old arc4. arc4 can't be used as a block cipher --- see this paper http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps , it says that initialization vectors on RC4 are unreliable, if you use (unknown key concatenated with known IV) or (known IV concatenated with unknown key) as a RC4 key, the RC4 state can be exposed and the cipher is broken. What we call a blkcipher is not really a block cipher. In fact, what we call cipher is really a block cipher. So we're actually changing arc4 so that it doesn't get used as a block cipher, i.e., you will no longer be able to say cbc(arc4) or some such. I know it's confusing and perhaps one day we will rename blkcipher to skcipher and cipher to blkcipher. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
On Mon, Feb 22, 2010 at 11:08:35PM +0100, Sebastian Andrzej Siewior wrote: * Herbert Xu | 2010-02-22 08:52:17 [+0800]: On Mon, Feb 22, 2010 at 08:45:47AM +0800, Herbert Xu wrote: How about this? You extend the IV by one more byte, and use that byte as a boolean flag to indicate whether the IV is valid. All So I trick the crypto api to allocate more bytes than -ivsize says. No tricks needed, just add the flag to the struct. struct arc4_iv { u8 S[256]; u8 x, y; u8 valid; }; Okay. When we have to re-key and the user calls setkey() without re-allocating thr cipher then I would not notice this. So I need a counter. And all this will make it work but I still think it is fishy. Plus we waste 258bytes. No you don't need to refresh the IV when the key changes. The key should only be consulted when the valid flag in the IV is zero. You need the 258 + flag bytes because that's just the amount of state carried between the encrypt/decrypt operation. So it isn't really wasted. If you can find a way that allows arc4 to be used by multiple threads at the same time while storing less than 258 bytes in each thread, please let me know :) In fact for arc4 we could just drop the key altogether since it plays no part after setting the initial state. Since I'm not allowed to kfree() the ctx in encrypt() are you proposing tfm-setup_iv(iv, key)? No, what you could do is structure the IV differently based on the flag: struct arc4_iv { union { struct key { u8 key[256]; u16 keylen; }; struct iv { u8 S[256]; u8 x, y; }; }; u8 type; }; This relies on the fact that we never use more than 256 bytes in the key so limiting its length is OK. Salsa should also be fixed. I saw that comming. And I complaind back then that the assembly code was not pretty enough... and removing the assembly is probably not option :) Well if nobody steps in to fix the assembly then removing it is the only option. For Salsa on the other hand the key is rather useful since all we need is a two-byte IV that's just a sequence number. No it's 8 bytes. Berstein's U8TO32_LITTLE() is actually a cpu_to_be32(). Not sure if he knows it :) Right. However I'm not sure where you going with this. salsa is fine besides the clobber thing, isn't it? I don't know of any other problems. Basically salsa should look pretty much like CTR from the outside when it's fixed. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
* Herbert Xu | 2010-02-16 20:51:25 [+0800]: On Fri, Feb 12, 2010 at 09:42:28AM +0100, Sebastian Andrzej Siewior wrote: -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; Sorry, but this doesn't work. A ctx is supposed to be reentrant. That is, while one thread is working away with a given ctx I should be able to use that same ctx in a different thread without them clobbering each other. I also destroy the user supplied IV. You don't care about that? :) So I have to know that someone called setkey() on this ctx but I can't leave hints. salsa also does not stick to plan here. ctx-input[6-9] is initialized in encrypt() path. So two threads sharing a ctx are going to clobber their state. What about a new api for the stream cipher? We would merge the ctx part and the iv into one handle. So the user would call setup_iv() instead of setkey(). The difference would be that I can access the iv from within setkey(). And the algorithm can fully express himself since he is no longer trapped in the wrong body :) So that means (in general) you must not modify the ctx in any function other than setkey. That is hard because I have a new state after encryption which I am only allowed to save in the iv. And the new state may be reset in setkey() where I can't touch the iv. salsa does not keep/update its state. So the input[6-9] problem could be fixed. Who/where is it used anyway? I can't see any user besides the possible once (i.e. dm-crypt/ipsec). This also brings up the bigger question of how we transition to this new arc4. I don't think we need to maintain exactly the same behaviour as the existing ecb(arc4). So what we could do is simply add a new blkcipher arc4, alongside the existing cipher arc4. Then we can convert the existing users across, and finally remove the old arc4. This has worked out before, lets stick to this :) Cheers, Sebastian -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
On Sun, Feb 21, 2010 at 09:01:40PM +0100, Sebastian Andrzej Siewior wrote: I also destroy the user supplied IV. You don't care about that? :) So I have to know that someone called setkey() on this ctx but I can't leave hints. How about this? You extend the IV by one more byte, and use that byte as a boolean flag to indicate whether the IV is valid. All users that cannot supply their own IVs can then set the IV to zero. When you see the zero flag in the IV, you reinitialise the IV per the key. salsa also does not stick to plan here. ctx-input[6-9] is initialized in encrypt() path. So two threads sharing a ctx are going to clobber their state. Salsa should also be fixed. What about a new api for the stream cipher? We would merge the ctx part and the iv into one handle. So the user would call setup_iv() instead of setkey(). The difference would be that I can access the iv from within setkey(). And the algorithm can fully express himself since he is no longer trapped in the wrong body :) There is some merit in that, but as the current API can be made to do the same thing (see above) I'm not convinced that this is worth the cost for the moment. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
On Mon, Feb 22, 2010 at 08:45:47AM +0800, Herbert Xu wrote: How about this? You extend the IV by one more byte, and use that byte as a boolean flag to indicate whether the IV is valid. All users that cannot supply their own IVs can then set the IV to zero. When you see the zero flag in the IV, you reinitialise the IV per the key. In fact for arc4 we could just drop the key altogether since it plays no part after setting the initial state. salsa also does not stick to plan here. ctx-input[6-9] is initialized in encrypt() path. So two threads sharing a ctx are going to clobber their state. Salsa should also be fixed. For Salsa on the other hand the key is rather useful since all we need is a two-byte IV that's just a sequence number. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
On Fri, Feb 12, 2010 at 09:42:28AM +0100, Sebastian Andrzej Siewior wrote: -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; Sorry, but this doesn't work. A ctx is supposed to be reentrant. That is, while one thread is working away with a given ctx I should be able to use that same ctx in a different thread without them clobbering each other. So that means (in general) you must not modify the ctx in any function other than setkey. This also brings up the bigger question of how we transition to this new arc4. I don't think we need to maintain exactly the same behaviour as the existing ecb(arc4). So what we could do is simply add a new blkcipher arc4, alongside the existing cipher arc4. Then we can convert the existing users across, and finally remove the old arc4. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
* Herbert Xu | 2010-02-15 08:10:08 [+0800]: How about we just remove it? It's not on a hot path anyway. Sure. I can do this when integrating the patch so you don't have to resend. Okay, thanks. Thanks, Sebastian -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
* Sebastian Andrzej Siewior | 2010-02-12 09:42:28 [+0100]: +static void arc4_ivsetup(struct arc4_ctx *ctx, u8 *iv) { - struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); + if (unlikely(!ctx-new_key)) That should be likely(). Do you want me resend the whole thing? Haven't noticed anything else :) + return; + memcpy(iv, ctx-iv, sizeof(ctx-iv)); + ctx-new_key = 0; +} Sebastian -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
On Sun, Feb 14, 2010 at 09:42:54PM +0100, Sebastian Andrzej Siewior wrote: * Sebastian Andrzej Siewior | 2010-02-12 09:42:28 [+0100]: +static void arc4_ivsetup(struct arc4_ctx *ctx, u8 *iv) { -struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); +if (unlikely(!ctx-new_key)) That should be likely(). Do you want me resend the whole thing? Haven't noticed anything else :) How about we just remove it? It's not on a hot path anyway. I can do this when integrating the patch so you don't have to resend. Thanks, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} herb...@gondor.apana.org.au Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] crypto/arc4: convert this stream cipher into a block cipher
the state has been moved from ctx into iv. That way encrypt()/decrypt() can deliver the same result for a given IV. This patch makes the cipher work with dm-crypt not that it is a good thing. However, the performance may have improved :) The name is still ecb(aes) but since this is provided by the blkcipher itself, I removed the select statement. Signed-off-by: Sebastian Andrzej Siewior sebast...@breakpoint.cc --- I had it run with wireless and dm-crypt. No problems so far. Not sure if it makes sense to rename it to arc4 and strip the ecb prefix. It would make it consistent with salsa but would require another patch. crypto/Kconfig |2 +- crypto/arc4.c| 120 -- crypto/testmgr.h |3 +- drivers/net/Kconfig |1 - drivers/net/wireless/hostap/Kconfig |2 - drivers/net/wireless/ipw2x00/Kconfig |2 - net/mac80211/Kconfig |1 - 7 files changed, 87 insertions(+), 44 deletions(-) diff --git a/crypto/Kconfig b/crypto/Kconfig index 81c185a..5fab1c3 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -561,7 +561,7 @@ config CRYPTO_ANUBIS config CRYPTO_ARC4 tristate ARC4 cipher algorithm - select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER help ARC4 cipher algorithm. diff --git a/crypto/arc4.c b/crypto/arc4.c index 8be47e1..b67b656 100644 --- a/crypto/arc4.c +++ b/crypto/arc4.c @@ -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_SIZE1 -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 =
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
Hi, Sebastian Andrzej Siewior schrieb: the state has been moved from ctx into iv. That way encrypt()/decrypt() can deliver the same result for a given IV. This patch makes the cipher work with dm-crypt not that it is a good thing. However, the performance may have improved :) The name is still ecb(aes) but since this is provided by the blkcipher itself, Just to avoid any confusion you meant ecb(arc4) not ecb(aes) here right? -Adrian -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto/arc4: convert this stream cipher into a block cipher
* Adrian-Ken Rueegsegger | 2010-02-12 10:34:27 [+0100]: Hi, Hi, Sebastian Andrzej Siewior schrieb: The name is still ecb(aes) but since this is provided by the blkcipher itself, Just to avoid any confusion you meant ecb(arc4) not ecb(aes) here right? Yes, I do. Not sure how I got aes in there. I did not mix it up in the patch :) -Adrian Sebastian -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html