1 /*
2 * arc4.c : Implementation for the Alleged-RC4 stream cipher
3 *
4 * Part of the Python Cryptography Toolkit
5 *
6 * Originally written by: A.M. Kuchling
7 *
8 * ===================================================================
9 * The contents of this file are dedicated to the public domain. To
10 * the extent that dedication to the public domain is not available,
11 * everyone is granted a worldwide, perpetual, royalty-free,
12 * non-exclusive license to exercise all rights associated with the
13 * contents of this file for any purpose whatsoever.
14 * No rights are reserved.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 * ===================================================================
25 *
26 */
27
28 #include "common.h"
29
30 FAKE_INIT(ARC4)
31
32 typedef struct
33 {
34 uint8_t state[256];
35 uint8_t x,y;
36 } stream_state;
37
ARC4_stream_encrypt(stream_state * rc4State,const uint8_t in[],uint8_t out[],size_t len)38 EXPORT_SYM int ARC4_stream_encrypt(stream_state *rc4State, const uint8_t in[], uint8_t out[], size_t len)
39 {
40 unsigned i;
41 unsigned x=rc4State->x, y=rc4State->y;
42
43 for (i=0; i<len; i++)
44 {
45 x = (x + 1) % 256;
46 y = (y + rc4State->state[x]) % 256;
47 {
48 unsigned t; /* Exchange state[x] and state[y] */
49 t = rc4State->state[x];
50 rc4State->state[x] = rc4State->state[y];
51 rc4State->state[y] = (uint8_t)t;
52 }
53 {
54 unsigned xorIndex; /* XOR the data with the stream data */
55 xorIndex=(rc4State->state[x]+rc4State->state[y]) % 256;
56 out[i] = in[i] ^ rc4State->state[xorIndex];
57 }
58 }
59 rc4State->x=(uint8_t)x;
60 rc4State->y=(uint8_t)y;
61 return 0;
62 }
63
ARC4_stream_init(uint8_t * key,size_t keylen,stream_state ** pRc4State)64 EXPORT_SYM int ARC4_stream_init(uint8_t *key, size_t keylen, stream_state **pRc4State)
65 {
66 unsigned i;
67 unsigned index1, index2;
68 stream_state *rc4State;
69
70 if (NULL == pRc4State || NULL == key)
71 return ERR_NULL;
72
73 *pRc4State = rc4State = calloc(1, sizeof(stream_state));
74 if (NULL == rc4State)
75 return ERR_MEMORY;
76
77 for(i=0; i<256; i++)
78 rc4State->state[i]=(uint8_t)i;
79
80 rc4State->x=0;
81 rc4State->y=0;
82
83 index1=0;
84 index2=0;
85 for(i=0; i<256; i++)
86 {
87 unsigned t;
88 index2 = ( (unsigned)key[index1] + rc4State->state[i] + index2) % 256;
89 t = rc4State->state[i];
90 rc4State->state[i] = rc4State->state[index2];
91 rc4State->state[index2] = (uint8_t)t;
92 index1 = (index1 + 1) % (unsigned)keylen;
93 }
94 return 0;
95 }
96
ARC4_stream_destroy(stream_state * rc4State)97 EXPORT_SYM int ARC4_stream_destroy(stream_state *rc4State)
98 {
99 free(rc4State);
100 return 0;
101 }
102