summaryrefslogtreecommitdiff
path: root/other/wrez/isolation/cipher-rc4.c
blob: 1196cb7a051a9a9e80deb45492c58db3341d37c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/* rc4 */

#include "cipher-rc4.h"


static void swap_byte (unsigned char *a, unsigned char *b);

void
rc4_prepare_key (unsigned char *key_data_ptr, int key_data_len, rc4_key *key)
{
	unsigned char	i1, i2;
	unsigned char *	s;
	short		c;

	s = &key->state[0];
	for (c = 0; c < 256; c++)
		s[c] = c;

	key->x = key->y = 0;
	i1 = i2 = 0;

	for (c = 0; c < 256; c++) {
		i2 = (key_data_ptr[i1] + s[c] + i2) % 256;
		swap_byte (&s[c], &s[i2]);
		i1 = (i1 + 1) % key_data_len;
	}
}


void
rc4_encipher (unsigned char *buffer, unsigned long int buffer_len,
	unsigned char *key, int key_len)
{
	rc4_key		key_r;

	if (key == NULL || buffer == NULL || buffer_len == 0)
		return;

	rc4_prepare_key (key, key_len, &key_r);
	rc4_cipher (buffer, buffer_len, &key_r);

	return;
}


void
rc4_cipher (unsigned char *buffer_ptr, int buffer_len, rc4_key *key)
{ 
	unsigned char	x;
	unsigned char	y;
	unsigned char	*state;
	unsigned char	xi;
	unsigned int	counter;
   
	x = key->x;
	y = key->y;
   
	state = &key->state[0];
	for(counter = 0; counter < buffer_len; counter ++) {
		x = (x + 1) % 256;
		y = (state[x] + y) % 256;
		swap_byte(&state[x], &state[y]);
		xi = (state[x] + state[y]) % 256;
		buffer_ptr[counter] ^= state[xi];
	}

	key->x = x;
	key->y = y;
}


static void
swap_byte (unsigned char *a, unsigned char *b)
{
	unsigned char	sb; 

	sb = *a;
	*a = *b;
	*b = sb;
}