comparison rc4.c @ 143:5d99163f7e32 libtomcrypt-orig

import of libtomcrypt 0.99
author Matt Johnston <matt@ucc.asn.au>
date Sun, 19 Dec 2004 11:34:45 +0000
parents 7faae8f46238
children
comparison
equal deleted inserted replaced
15:6362d3854bb4 143:5d99163f7e32
12 12
13 #ifdef RC4 13 #ifdef RC4
14 14
15 const struct _prng_descriptor rc4_desc = 15 const struct _prng_descriptor rc4_desc =
16 { 16 {
17 "rc4", 17 "rc4", 32,
18 &rc4_start, 18 &rc4_start,
19 &rc4_add_entropy, 19 &rc4_add_entropy,
20 &rc4_ready, 20 &rc4_ready,
21 &rc4_read 21 &rc4_read,
22 &rc4_done,
23 &rc4_export,
24 &rc4_import,
25 &rc4_test
22 }; 26 };
23 27
24 int rc4_start(prng_state *prng) 28 int rc4_start(prng_state *prng)
25 { 29 {
26 _ARGCHK(prng != NULL); 30 _ARGCHK(prng != NULL);
31 return CRYPT_OK; 35 return CRYPT_OK;
32 } 36 }
33 37
34 int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) 38 int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
35 { 39 {
36 _ARGCHK(buf != NULL); 40 _ARGCHK(buf != NULL);
37 _ARGCHK(prng != NULL); 41 _ARGCHK(prng != NULL);
38 42
43 /* trim as required */
39 if (prng->rc4.x + len > 256) { 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... */
47 return CRYPT_OK;
48 } else {
49 /* only accept part of it */
50 len = 256 - prng->rc4.x;
51 }
41 } 52 }
42 53
43 while (len--) { 54 while (len--) {
44 prng->rc4.buf[prng->rc4.x++] = *buf++; 55 prng->rc4.buf[prng->rc4.x++] = *buf++;
45 } 56 }
48 59
49 } 60 }
50 61
51 int rc4_ready(prng_state *prng) 62 int rc4_ready(prng_state *prng)
52 { 63 {
53 unsigned char key[256], tmp; 64 unsigned char key[256], tmp, *s;
54 int keylen, x, y; 65 int keylen, x, y, j;
55 66
56 _ARGCHK(prng != NULL); 67 _ARGCHK(prng != NULL);
57 68
58 /* extract the key */ 69 /* extract the key */
59 memcpy(key, prng->rc4.buf, 256); 70 s = prng->rc4.buf;
71 XMEMCPY(key, s, 256);
60 keylen = prng->rc4.x; 72 keylen = prng->rc4.x;
61 73
62 /* make RC4 perm and shuffle */ 74 /* make RC4 perm and shuffle */
63 for (x = 0; x < 256; x++) { 75 for (x = 0; x < 256; x++) {
64 prng->rc4.buf[x] = x; 76 s[x] = x;
65 } 77 }
66 78
67 for (x = y = 0; x < 256; x++) { 79 for (j = x = y = 0; x < 256; x++) {
68 y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255; 80 y = (y + prng->rc4.buf[x] + key[j++]) & 255;
69 tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp; 81 if (j == keylen) {
70 } 82 j = 0;
71 prng->rc4.x = x; 83 }
72 prng->rc4.y = y; 84 tmp = s[x]; s[x] = s[y]; s[y] = tmp;
85 }
86 prng->rc4.x = 0;
87 prng->rc4.y = 0;
73 88
74 #ifdef CLEAN_STACK 89 #ifdef CLEAN_STACK
75 zeromem(key, sizeof(key)); 90 zeromem(key, sizeof(key));
76 #endif 91 #endif
77 92
78 return CRYPT_OK; 93 return CRYPT_OK;
79 } 94 }
80 95
81 unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng) 96 unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng)
82 { 97 {
83 int x, y; 98 unsigned char x, y, *s, tmp;
84 unsigned char *s, tmp;
85 unsigned long n; 99 unsigned long n;
86 100
87 _ARGCHK(buf != NULL); 101 _ARGCHK(buf != NULL);
88 _ARGCHK(prng != NULL); 102 _ARGCHK(prng != NULL);
89 103
101 prng->rc4.x = x; 115 prng->rc4.x = x;
102 prng->rc4.y = y; 116 prng->rc4.y = y;
103 return n; 117 return n;
104 } 118 }
105 119
106 #endif 120 int rc4_done(prng_state *prng)
107 121 {
122 _ARGCHK(prng != NULL);
123 return CRYPT_OK;
124 }
125
126 int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
127 {
128 _ARGCHK(outlen != NULL);
129 _ARGCHK(out != NULL);
130 _ARGCHK(prng != NULL);
131
132 if (*outlen < 32) {
133 return CRYPT_BUFFER_OVERFLOW;
134 }
135
136 if (rc4_read(out, 32, prng) != 32) {
137 return CRYPT_ERROR_READPRNG;
138 }
139 *outlen = 32;
140
141 return CRYPT_OK;
142 }
143
144 int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
145 {
146 int err;
147 _ARGCHK(in != NULL);
148 _ARGCHK(prng != NULL);
149
150 if (inlen != 32) {
151 return CRYPT_INVALID_ARG;
152 }
153
154 if ((err = rc4_start(prng)) != CRYPT_OK) {
155 return err;
156 }
157 return rc4_add_entropy(in, 32, prng);
158 }
159
160 int rc4_test(void)
161 {
162 #ifndef LTC_TEST
163 return CRYPT_NOP;
164 #else
165 static const struct {
166 unsigned char key[8], pt[8], ct[8];
167 } tests[] = {
168 {
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 }
172 }
173 };
174 prng_state prng;
175 unsigned char dst[8];
176 int err, x;
177
178 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
179 if ((err = rc4_start(&prng)) != CRYPT_OK) {
180 return err;
181 }
182 if ((err = rc4_add_entropy(tests[x].key, 8, &prng)) != CRYPT_OK) {
183 return err;
184 }
185 if ((err = rc4_ready(&prng)) != CRYPT_OK) {
186 return err;
187 }
188 XMEMCPY(dst, tests[x].pt, 8);
189 if (rc4_read(dst, 8, &prng) != 8) {
190 return CRYPT_ERROR_READPRNG;
191 }
192 rc4_done(&prng);
193 if (memcmp(dst, tests[x].ct, 8)) {
194 #if 0
195 int y;
196 printf("\n\nRC4 failed, I got:\n");
197 for (y = 0; y < 8; y++) printf("%02x ", dst[y]);
198 printf("\n");
199 #endif
200 return CRYPT_FAIL_TESTVECTOR;
201 }
202 }
203 return CRYPT_OK;
204 #endif
205 }
206
207 #endif
208