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