ARC4: A lightweight encryption algorithm

Background
There are several applications that need to securely communicate that run on platforms that do not have the processing capability required for conventional encryption algorithms. This note describes how to use ARC4, a public, lightweight, shared secret key encryption algorithm that provides sufficient security and can be supported on low end platforms. It assumes that the encryption key is available to both parties. A simple PKI based key distribution mechanism is described separately.

The ARC4 cipher
RC4 is a fast shared key stream cipher. It generates a sequence of bytes which can be simply XORed with sensitive plaintext to encrypt it. The same mechanism is used to decrypt the encrypted text. It was designed by Ron Rivest, who is one of the developers of the RSA algorithm. It is used in WEP, WPA, and is an option for TLS and SSH. Except for its name, RC4 is in the public domain. It is henceforth referred to as ARC4. ARC4 has been analyzed extensively and its weaknesses have been documented. There are a few other fast encryption algorithms, but none of them have been analyzed as well. It is better to use an algorithm with known issues than one with possible unknown issues. A property of ARC4 is that, given the same key, it will generate the same stream. This property can be exploited by attackers to deduce & record the key stream using a known plaintext attack. This key stream can then be used to decrypt subsequent messages. One way to avoid this vulnerability is to add a random salt (nonce) to the key. This nonce should be selected by the encrypting party and sent in the clear to the decrypting party. The Usage Guidelines section describes how to work around the known issues in ARC4 and the following source code implements the relevant guidelines.

Usage Guidelines
1. A random salt (nonce) must be used for each session. It should be of the same length as the key. It should contain genuinely random bits and should be sent unencrypted from the encrypting party to the decrypting party. Both ends should XOR this salt with the key before ARC4 initialization. [ref] 2. The first 768 (or up to 3072) bytes generated by ARC4 should be discarded by both ends after initialization. This avoids some key correlation attacks. [ref] 3. The state of the ARC4 “engine” must be saved and reused throughout the session, i.e., ARC4 must not be reinitialized for each transaction or packet. Besides being more efficient, this avoids a known weakness. 4. Encryption may be limited to only sensitive fields, and not the whole transaction. 5. Each application must have its own unique key. The key must not be shared by more than two parties. 6. Keys, passwords & PINs should be at least 8 characters.

ARC4 Encryption

Rajaram Pejaver

1/6

return S[(si + sj) & 255]. i < 256. not guidelines compliant // file: arc4. int key_length) { unsigned char si. i < 256. j = (si + j + (key[k])) & 255. j = (j + si) & 255. } // arc4crypt: encrypt or decrypt using stream cipher void arc4crypt(unsigned char *pdata. S[i] = sj. // static private state table S // static private counters // arc4_init: key-scheduling algorithm void arc4_init(unsigned char *key. // index into key & salt for (i = 0.c static unsigned char S[256]. unsigned char arc4_gen(). for (i = j = 0. si = S[i].Source Code (in C): Not thread-safe. sj = S[j]. sj.> 0) *pdata++ ^= arc4gen(). si = S[i]. i = (i + 1) & 255. S[i] = S[j]. // XOR in place } // reset static counters // swap S[i] & S[j] ARC4 Encryption Rajaram Pejaver 2/6 . // swap S[i] & S[j] S[j] = si. } i = j = 0. j. S[j] = si. } // arc4gen: pseudo-random stream cipher generation unsigned char arc4gen() { unsigned char si. int len) { while (len-. k++) { if (k >= key_length) // k = k % key_length k = 0. i++) S[i] = i. static unsigned int i. // holds S[i] int k = 0. i++.

However. int len). It is used for both encrypting and decrypting a byte of data by XORing the value as follows. enc_byte = clear_byte ^ arc4gen().ARC4 man page NAME arc4init. arc4gen_r. The arc4init() function initializes the encryption state and must be called once before encrypting or decrypting data. sizeof(sensitive_field1)). These functions may not be suitable in some applications where two peers are exchanging encrypted traffic if the encryption states of the traffic in the two directions are different. It does not follow the guidelines and does not protect against known attacks. unsigned char arc4gen(). void arc4crypt(unsigned char *ptr. arc4crypt – ARC4 encryption SYNOPSIS void arc4init(unsigned char *key. It updates the encryption state table. The arc4gen() function returns one byte which is the next value in the pseudo random stream. arc4gen. arc4free_r ARC4 Encryption Rajaram Pejaver 3/6 . DIAGNOSTIC MESSAGES None SEE ALSO arc4init_r. arc4_crypt(sensitive_field1. The arc4crypt() function is used to encrypt or decrypt an array of bytes. int key_length). they can be used in simple communicating applications where data is encrypted and decrypted in a lock-step manner. key_length). arc4crypt_r. arc4init(key. This version of the functions is not reentrant or thread safe since the encryption state is stored as a static table. DESCRIPTION These functions provide basic encryption and decryption using ARC4.

unsigned char si. return context void *arc4init_r(unsigned char *key. } ARC4 Encryption Rajaram Pejaver 4/6 . j. pi = ap->S. unsigned char arc4gen_r(struct arc4 *ap). int key_length. j = (si + j + ks)) & 255. return (ap). for (i = j = 0. i < 768. char *pi. pi++) { if (k >= key_length) // k = k % key_length k = 0. si = *pi. // counters }. // reset counters if (skip) // discard first few bytes for (i = 0. int skip) { struct arc4 *ap. ++i) (void) arc4_gen(ap). unsigned char *salt. // arc4init_r: key-scheduling algorithm. k++.Thread-safe Source Code (in C) // file: arc4_r. pi++) *pi = i. // boom. i++. ap = (struct arc4 *) malloc(sizeof *ap). ks = key[k]. if (ap == 0) return 0. if (salt) ks ^= salt[k]. // index into key & salt int i.c Thread safe struct arc4 { unsigned char S[256]. i < 256. // swap S[i] & S[j] ap->S[j] = si. // holds S[i] unsigned char ks. *pi = ap->S[j]. i++. i < 256. // state table S unsigned int i. pi = ap->S. like that for (i = 0. // key byte int k = 0. } ap->i = ap->j = 0. j.

void *ap. 1).// arc4gen_r: pseudo-random stream cipher generation unsigned char arc4gen_r(struct arc4 *ap) { unsigned char si. unsigned char *ptr. unsigned char arc4gen_r(void *ap). If skip is non-zero. int salt_length = strlen(passwd). sj. int skip). int len). si = ap->S[ap->i]. } ARC4_r man page NAME arc4init_r. return ap->S[(si + sj) & 255]. The salt must be sent to the other party so that it can be passed to arc4init_r() at that end. If used. i < salt_length. arc4crypt_r. salt. ap->S[ap->i] = sj. The arc4init_r() function initializes the encryption state and must be called once before encrypting or decrypting data. arc4gen_r. to protect against key correlation attacks. // swap S[i] & S[j] ap->S[ap->j] = si. ++i) salt[i] = random(). ap->j = (ap->j + si) & 255. key_length. void arc4free_r(void *ap). sj = ap->S[ap->j]. This version of the functions is reentrant and thread safe since the encryption state is stored in blob of memory that is returned by arc4init_r(). then specify a null pointer or an array of zeros. ap->i = (ap->i + 1) & 255. then the first 768 bytes of the stream are discarded. If salt is not desired. ap = arc4init(key. This version also follows the guidelines and supports skipping of the first few bytes of the stream cipher. unsigned char *salt. salt is an array of random values and must be of the same length as the key. for (int i = 0. The memory must be released eventually via arc4free_r(). DESCRIPTION These functions provide encryption and decryption using ARC4. void arc4crypt_r(void *ap. arc4free_r – ARC4 encryption SYNOPSIS void *arc4init_r(unsigned char *key. unsigned char salt[128]. int key_length. ARC4 Encryption Rajaram Pejaver 5/6 .

It updates the encryption state table referenced by its parameter ap. arc4_crypt_r(ap. enc_byte = clear_byte ^ arc4gen_r(ap).org/wiki/RC4 ARC4 Encryption Rajaram Pejaver 6/6 .wikipedia. sizeof(sensitive_fld1)). SEE ALSO arc4init. DIAGNOSTIC MESSAGES arc4init_r() returns null if it cannot allocate memory for encryption state. arc4gen. The arc4crypt_r() function is used to encrypt or decrypt an array of bytes. It is used for both encrypting and decrypting a byte of data by XORing the value as follows. arc4crypt References http://en. sensitive_fld1.The arc4gen_r() function returns one byte which is the next value in the pseudo random stream.

Sign up to vote on this title
UsefulNot useful