// //crypt-a4.c // //Implements the ARCFOUR (Alleged RC-4) encyption method. // // //-UserX 2001/12/09 #include #include "crypt/arcfour.h" #include "base/mem.h" #define SWAP(x, y) {x ^= y; y ^= x; x ^= y;} ArcfourContext *arcfourMake(void) { ArcfourContext *a4 = memAlloc(sizeof(ArcfourContext), "ARC4", NULL);//ximalloc(sizeof(ArcfourContext)); arcfourReset(a4); return a4; } void arcfourFree(ArcfourContext *a4) { memFree(a4);//xifree(a4); } void arcfourReset(ArcfourContext *a4) { int i; a4->i = 0; a4->j = 0; for(i = 0; i < 256; i++) { a4->S[i] = i; } a4->ki = 0; a4->kj = 0; //memset(a4->K, 0, 256); } //apply the encryption/decryption void arcfourCrypt(ArcfourContext *a4, uint8 *buffer, int length) { int i; for(i = 0; i < length; i++) { a4->i = (a4->i + 1) & 0xff; a4->j = (a4->j + a4->S[a4->i]) & 0xff; SWAP(a4->S[a4->i], a4->S[a4->j]); buffer[i] ^= a4->S[(a4->S[a4->i] + a4->S[a4->j]) & 0xff]; } } //generate a buffer of output void arcfourBuffer(ArcfourContext *a4, uint8 *buffer, int length) { //do it the lazy way memset(buffer, 0, length); arcfourCrypt(a4, buffer, length); } //Sets the key. //note does not reset the context's state before adding the key void arcfourKey(ArcfourContext *a4, uint8 *buffer, int keylength) { int k; for(k = 256; k > keylength; k -= keylength) { arcfourAddKey(a4, buffer, keylength); } arcfourAddKey(a4, buffer, k); } //Normally called by arcfourKey to do the actual keying of the context // //note: Could be used for adding a small amounts of new key material //after it has keyed normally. The actual security of such key adding //should be consider suspect. void arcfourAddKey(ArcfourContext *a4, uint8 *buffer, int keylength) { int k; for(k = 0; k < keylength; k++) { a4->ki = (a4->ki + 1) & 0xff; a4->kj = (a4->kj + a4->S[a4->ki] + buffer[k]) & 0xff; SWAP(a4->S[a4->ki], a4->S[a4->kj]); } }