Professional Documents
Culture Documents
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.
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
// arc4_init: key-scheduling algorithm void arc4_init(unsigned char *key, int key_length) { unsigned char si; // holds S[i] int k = 0; // index into key & salt for (i = 0; i < 256; i++) S[i] = i; for (i = j = 0; i < 256; i++, k++) { if (k >= key_length) // k = k % key_length k = 0; si = S[i]; j = (si + j + (key[k])) & 255; S[i] = S[j]; // swap S[i] & S[j] S[j] = si; } i = j = 0; } // arc4gen: pseudo-random stream cipher generation unsigned char arc4gen() { unsigned char si, sj; i = (i + 1) & 255; si = S[i]; j = (j + si) & 255; sj = S[j]; S[i] = sj; S[j] = si; return S[(si + sj) & 255]; } // arc4crypt: encrypt or decrypt using stream cipher void arc4crypt(unsigned char *pdata, int len) { while (len-- > 0) *pdata++ ^= arc4gen(); // XOR in place } // reset static counters
ARC4 Encryption
Rajaram Pejaver
2/6
SYNOPSIS
void arc4init(unsigned char *key, int key_length); unsigned char arc4gen(); void arc4crypt(unsigned char *ptr, int len);
DESCRIPTION
These functions provide basic encryption and decryption using ARC4. This version of the functions is not reentrant or thread safe since the encryption state is stored as a static table. It does not follow the guidelines and does not protect against known attacks. The arc4init() function initializes the encryption state and must be called once before encrypting or decrypting data.
arc4init(key, key_length);
The arc4gen() function returns one byte which is the next value in the pseudo random stream. It updates the encryption state table. It is used for both encrypting and decrypting a byte of data by XORing the value as follows.
enc_byte = clear_byte ^ arc4gen();
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. However, they can be used in simple communicating applications where data is encrypted and decrypted in a lock-step manner.
DIAGNOSTIC MESSAGES
None
SEE ALSO
arc4init_r, arc4gen_r, arc4crypt_r, arc4free_r
ARC4 Encryption
Rajaram Pejaver
3/6
ARC4 Encryption
Rajaram Pejaver
4/6
// arc4gen_r: pseudo-random stream cipher generation unsigned char arc4gen_r(struct arc4 *ap) { unsigned char si, sj; ap->i = (ap->i + 1) & 255; si = ap->S[ap->i]; ap->j = (ap->j + si) & 255; sj = ap->S[ap->j]; ap->S[ap->i] = sj; // swap S[i] & S[j] ap->S[ap->j] = si; return ap->S[(si + sj) & 255]; }
SYNOPSIS
void *arc4init_r(unsigned char *key, int key_length, unsigned char *salt, int skip); unsigned char arc4gen_r(void *ap); void arc4crypt_r(void *ap, unsigned char *ptr, int len); void arc4free_r(void *ap);
DESCRIPTION
These functions provide encryption and decryption using ARC4. 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(). The memory must be released eventually via arc4free_r(). This version also follows the guidelines and supports skipping of the first few bytes of the stream cipher, to protect against key correlation attacks. The arc4init_r() function initializes the encryption state and must be called once before encrypting or decrypting data. If used, salt is an array of random values and must be of the same length as the key. If salt is not desired, then specify a null pointer or an array of zeros. The salt must be sent to the other party so that it can be passed to arc4init_r() at that end. If skip is non-zero, then the first 768 bytes of the stream are discarded.
void *ap; unsigned char salt[128]; int salt_length = strlen(passwd); for (int i = 0; i < salt_length; ++i) salt[i] = random(); ap = arc4init(key, key_length, salt, 1);
ARC4 Encryption
Rajaram Pejaver
5/6
The arc4gen_r() function returns one byte which is the next value in the pseudo random stream. It updates the encryption state table referenced by its parameter ap. It is used for both encrypting and decrypting a byte of data by XORing the value as follows.
enc_byte = clear_byte ^ arc4gen_r(ap);
DIAGNOSTIC MESSAGES
arc4init_r() returns null if it cannot allocate memory for encryption state.
SEE ALSO
arc4init, arc4gen, arc4crypt
References
http://en.wikipedia.org/wiki/RC4
ARC4 Encryption
Rajaram Pejaver
6/6