Misc:arcfour
From Amar
- include "crypt.h"
/* key is the state that should be allocated by the caller */
- define STATE key->state
- define I key->i
- define J key->j
int rc4_set_key(arcfour_key * key, byte * key_data, int key_len) {
register int tmp, j, i;
byte *state = STATE;
int ivindex;
for (i = 0; i < 256; i++)
state[i] = i;
I = 0;
J = 0;
ivindex = 0;
for (j = i = 0; i < 256; i++) {
j += state[i] + key_data[i % key_len];
j &= 0xff;
swap_byte(state[i], state[j]);
}
return 0;
}
void rc4_encrypt(arcfour_key * key, byte * buffer_ptr, int buffer_len) {
register int tmp;
register int counter;
register int i = I, j = J;
byte *state = STATE;
for (counter = 0; counter < buffer_len; counter++) {
i++;
i &= 0xff;
j += state[i];
j &= 0xff;
/* swap state[i] and state[j] */
swap_byte(state[i], state[j]);
buffer_ptr[counter] ^= state[(state[i] + tmp) & 0xff];
}
J = j;
I = i;
}
void arcfour_init(ArcfourContext *ctx, const unsigned char *key, unsigned int key_len) {
unsigned int t, u;
unsigned int keyindex;
unsigned int stateindex;
unsigned char* state;
unsigned int counter;
state = &ctx->state[0];
ctx->x = 0;
ctx->y = 0;
for (counter = 0; counter < 256; counter++)
state[counter] = counter;
keyindex = 0;
stateindex = 0;
for (counter = 0; counter < 256; counter++) {
t = state[counter];
stateindex = (stateindex + key[keyindex] + t) & 0xff;
u = state[stateindex];
state[stateindex] = t;
state[counter] = u;
if (++keyindex >= key_len)
keyindex = 0;
}
}
unsigned int arcfour_byte(ArcfourContext *ctx) {
unsigned int x;
unsigned int y;
unsigned int sx, sy;
unsigned char *state;
state = ctx->state;
x = (ctx->x + 1) & 0xff;
sx = state[x];
y = (sx + ctx->y) & 0xff;
sy = state[y];
ctx->x = x;
ctx->y = y;
state[y] = sx;
ctx->y = y;
state[y] = sx;
state[x] = sy;
return state[(sx + sy) & 0xff];
}
void arcfour_encrypt(ArcfourContext *ctx, unsigned char *dest, const unsigned char *src, unsigned int len) {
register unsigned int i;
for (i = 0; i < len; i++)
dest[i] = src[i] ^ arcfour_byte(ctx);
}
void arcfour_decrypt(ArcfourContext *ctx, unsigned char *dest, const unsigned char *src, unsigned int len) {
arcfour_encrypt(ctx, dest, src, len);
}