crypto: incorporate C implementation of ARC4
PATCH 1/1 crypto: incorporate C implementation of ARC4
Incorporate the LGPL v2.1 licensed implementation of ARC4, taken from the Nettle project (https://git.lysator.liu.se/nettle/nettle.git,
commit 3e7a480a1e351884), and tweak it a bit so we don't have to operate on a skip buffer to fast forward the stream cipher, but can simply invoke it with NULL dst or src arguments to achieve the same.
This removes the dependency [via libell] on the OS's implementation of ecb(arc4), which may be going away, and which is not usually accelerated in the first place.
--- src/crypto.c | 82 ++++++++++++++++++++++++++++++----------------- src/main.c | 8 ----- unit/test-eapol.c | 3 +- 3 files changed, 53 insertions(+), 40 deletions(-)
src/crypto.c +52 -30
@@ -18,6 +18,8 @@* License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * +* (contains ARC4 implementation copyright (c) 2001 Niels Möller) +* */ #ifdef HAVE_CONFIG_H
@@ -34,6 +36,16 @@#include "src/missing.h" #include "src/crypto.h" +#define ARC4_MIN_KEY_SIZE 1 +#define ARC4_MAX_KEY_SIZE 256 +#define ARC4_KEY_SIZE 16 + +struct arc4_ctx { +uint8_t S[256 ]; +uint8_t i; +uint8_t j; +}; +/* RFC 3526, Section 2 */ const unsigned char crypto_dh5_prime[] = {0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xff ,0xc9 ,0x0f ,0xda ,0xa2 ,
@@ -415,44 +427,54 @@ free_ctr:return false; } -bool arc4_skip (const uint8_t *key,size_t key_len,size_t skip, -const uint8_t *in,size_t len,uint8_t *out) -{ -char skip_buf[1024 ]; -struct l_cipher *cipher; -struct iovec in_vec[2 ]; -struct iovec out_vec[2 ]; -bool r; - - cipher =l_cipher_new (L_CIPHER_ARC4 , key, key_len); -if (!cipher) -return false; +#define SWAP (a,b) do { int _t = a; a = b; b = _t; } while (0) -/* This is not strictly necessary, but keeps valgrind happy */ -memset (skip_buf,0 ,sizeof (skip_buf)); +static void arc4_set_key (struct arc4_ctx *ctx,unsigned length, +const uint8_t *key) +{ +unsigned int i, j, k; -while (skip >sizeof (skip_buf)) { -size_t to_skip = - skip >sizeof (skip_buf) ?sizeof (skip_buf) : skip; +/* Initialize context */ +for (i =0 ; i <256 ; i++) + ctx->S[i] = i; -l_cipher_decrypt (cipher, skip_buf, skip_buf, to_skip); - skip -= to_skip; +for (i = j = k =0 ; i <256 ; i++) { + j += ctx->S[i] + key[k]; j &=0xff ; +SWAP (ctx->S[i], ctx->S[j]); +/* Repeat key as needed */ + k = (k +1 ) % length; } + ctx->i = ctx->j =0 ; +} - in_vec[0 ].iov_base = skip_buf; - in_vec[0 ].iov_len = skip; - in_vec[1 ].iov_base = (void *) in; - in_vec[1 ].iov_len = len; +static void arc4_crypt (struct arc4_ctx *ctx,unsigned length,uint8_t *dst, +const uint8_t *src) +{ +uint8_t i, j; + + i = ctx->i; j = ctx->j; +while (length--) { + i++; i &=0xff ; + j += ctx->S[i]; j &=0xff ; +SWAP (ctx->S[i], ctx->S[j]); +if (!dst || !src) +continue ; + *dst++ = *src++ ^ ctx->S[ (ctx->S[i] + ctx->S[j]) &0xff ]; + } + ctx->i = i; ctx->j = j; +} - out_vec[0 ].iov_base = skip_buf; - out_vec[0 ].iov_len = skip; - out_vec[1 ].iov_base = out; - out_vec[1 ].iov_len = len; +bool arc4_skip (const uint8_t *key,size_t key_len,size_t skip, +const uint8_t *in,size_t len,uint8_t *out) +{ +struct arc4_ctx cipher; - r =l_cipher_decryptv (cipher, in_vec,2 , out_vec,2 ); -l_cipher_free (cipher); +arc4_set_key (&cipher, key_len, key); +arc4_crypt (&cipher, skip,NULL ,NULL ); +arc4_crypt (&cipher, len, out, in); +explicit_bzero (&cipher,sizeof (cipher)); -return r; +return true; }/* 802.11, Section 11.6.2, Table 11-4 */
src/main.c +0 -8
@@ -277,14 +277,6 @@ static int check_crypto()ADD_OPTIONAL ("CONFIG_CRYPTO_SHA512_SSSE3" ); } -if (!l_cipher_is_supported (L_CIPHER_ARC4 )) { - r = -ENOTSUP ; -l_error ("RC4 support not found" ); -ADD_MISSING ("CONFIG_CRYPTO_USER_API_SKCIPHER" ); -ADD_MISSING ("CONFIG_CRYPTO_ARC4" ); -ADD_MISSING ("CONFIG_CRYPTO_ECB" ); - } -if (!l_cipher_is_supported (L_CIPHER_DES ) || !l_cipher_is_supported (L_CIPHER_DES3_EDE_CBC )) { r = -ENOTSUP ;
unit/test-eapol.c +1 -2
@@ -3600,8 +3600,7 @@ int main(int argc, char *argv[])l_test_add ("/EAPoL Key/Calculate MIC Test 1" , eapol_calculate_mic_test, &eapol_calculate_mic_test_1); -if (!l_cipher_is_supported (L_CIPHER_AES ) || - !l_cipher_is_supported (L_CIPHER_ARC4 )) +if (!l_cipher_is_supported (L_CIPHER_AES )) goto done; l_test_add("EAPoL/WPA2 4-Way Handshake",
Signature · 1 line
2.20.1
Denis Kenzior
AppliedHi Ard,
Quoted 11 lines · Ard Biesheuvel
Incorporate the LGPL v2.1 licensed implementation of ARC4, taken from the Nettle project (https://git.lysator.liu.se/nettle/nettle.git,
commit3e7a480a1e351884), and tweak it a bit so we don't have to operate on a skip buffer to fast forward the stream cipher, but can simply invoke it with NULL dst or src arguments to achieve the same.This removes the dependency [via libell] on the OS's implementation of ecb(arc4), which may be going away, and which is not usually accelerated in the first place.
Signed-off-by Ard Biesheuvel <[email protected]>
We don't use S-o-B tags, so I dropped this one
Quoted 6 lines
--- src/crypto.c | 82 ++++++++++++++++++++++++++++++----------------- src/main.c | 8 ----- unit/test-eapol.c | 3 +- 3 files changed, 53 insertions(+), 40 deletions(-)
Applied, thanks.
Regards,
-Denis