libtomcrypt/rc4.c
2010-06-16 12:37:49 +02:00

98 lines
1.7 KiB
C

#include "mycrypt.h"
#ifdef RC4
const struct _prng_descriptor rc4_desc =
{
"rc4",
&rc4_start,
&rc4_add_entropy,
&rc4_ready,
&rc4_read
};
int rc4_start(prng_state *prng)
{
_ARGCHK(prng != NULL);
/* set keysize to zero */
prng->rc4.x = 0;
return CRYPT_OK;
}
int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
{
_ARGCHK(buf != NULL);
_ARGCHK(prng != NULL);
if (prng->rc4.x + len > 256) {
return CRYPT_INVALID_KEYSIZE;
}
while (len--) {
prng->rc4.buf[prng->rc4.x++] = *buf++;
}
return CRYPT_OK;
}
int rc4_ready(prng_state *prng)
{
unsigned char key[256], tmp;
int keylen, x, y;
_ARGCHK(prng != NULL);
/* extract the key */
memcpy(key, prng->rc4.buf, 256);
keylen = prng->rc4.x;
/* make RC4 perm and shuffle */
for (x = 0; x < 256; x++) {
prng->rc4.buf[x] = x;
}
for (x = y = 0; x < 256; x++) {
y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255;
tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp;
}
prng->rc4.x = x;
prng->rc4.y = y;
#ifdef CLEAN_STACK
zeromem(key, sizeof(key));
#endif
return CRYPT_OK;
}
unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng)
{
int x, y;
unsigned char *s, tmp;
unsigned long n;
_ARGCHK(buf != NULL);
_ARGCHK(prng != NULL);
n = len;
x = prng->rc4.x;
y = prng->rc4.y;
s = prng->rc4.buf;
while (len--) {
x = (x + 1) & 255;
y = (y + s[x]) & 255;
tmp = s[x]; s[x] = s[y]; s[y] = tmp;
tmp = (s[x] + s[y]) & 255;
*buf++ ^= s[tmp];
}
prng->rc4.x = x;
prng->rc4.y = y;
return n;
}
#endif