34
38
int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
37
41
_ARGCHK(prng != NULL);
43
/* trim as required */
39
44
if (prng->rc4.x + len > 256) {
40
return CRYPT_INVALID_KEYSIZE;
45
if (prng->rc4.x == 256) {
46
/* I can't possibly accept another byte, ok maybe a mint wafer... */
49
/* only accept part of it */
50
len = 256 - prng->rc4.x;
51
62
int rc4_ready(prng_state *prng)
53
unsigned char key[256], tmp;
64
unsigned char key[256], tmp, *s;
56
67
_ARGCHK(prng != NULL);
58
69
/* extract the key */
59
memcpy(key, prng->rc4.buf, 256);
60
72
keylen = prng->rc4.x;
62
74
/* make RC4 perm and shuffle */
63
75
for (x = 0; x < 256; x++) {
67
for (x = y = 0; x < 256; x++) {
68
y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255;
69
tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp;
79
for (j = x = y = 0; x < 256; x++) {
80
y = (y + prng->rc4.buf[x] + key[j++]) & 255;
84
tmp = s[x]; s[x] = s[y]; s[y] = tmp;
75
90
zeromem(key, sizeof(key));
120
int rc4_done(prng_state *prng)
122
_ARGCHK(prng != NULL);
126
int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
128
_ARGCHK(outlen != NULL);
129
_ARGCHK(out != NULL);
130
_ARGCHK(prng != NULL);
133
return CRYPT_BUFFER_OVERFLOW;
136
if (rc4_read(out, 32, prng) != 32) {
137
return CRYPT_ERROR_READPRNG;
144
int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
148
_ARGCHK(prng != NULL);
151
return CRYPT_INVALID_ARG;
154
if ((err = rc4_start(prng)) != CRYPT_OK) {
157
return rc4_add_entropy(in, 32, prng);
165
static const struct {
166
unsigned char key[8], pt[8], ct[8];
169
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
170
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
171
{ 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 }
175
unsigned char dst[8];
178
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
179
if ((err = rc4_start(&prng)) != CRYPT_OK) {
182
if ((err = rc4_add_entropy(tests[x].key, 8, &prng)) != CRYPT_OK) {
185
if ((err = rc4_ready(&prng)) != CRYPT_OK) {
188
XMEMCPY(dst, tests[x].pt, 8);
189
if (rc4_read(dst, 8, &prng) != 8) {
190
return CRYPT_ERROR_READPRNG;
193
if (memcmp(dst, tests[x].ct, 8)) {
196
printf("\n\nRC4 failed, I got:\n");
197
for (y = 0; y < 8; y++) printf("%02x ", dst[y]);
200
return CRYPT_FAIL_TESTVECTOR;