1 | /* |
---|
2 | |
---|
3 | ARCFOUR cipher (based on a cipher posted on the Usenet in Spring-95). |
---|
4 | This cipher is widely believed and has been tested to be equivalent |
---|
5 | with the RC4 cipher from RSA Data Security, Inc. (RC4 is a trademark |
---|
6 | of RSA Data Security) |
---|
7 | |
---|
8 | */ |
---|
9 | |
---|
10 | /* |
---|
11 | * $Id: arcfour.c,v 1.1.1.2 1999-03-08 17:43:20 danw Exp $ |
---|
12 | * $Log: not supported by cvs2svn $ |
---|
13 | * Revision 1.1.1.1 1996/02/18 21:38:11 ylo |
---|
14 | * Imported ssh-1.2.13. |
---|
15 | * |
---|
16 | * Revision 1.2 1995/07/13 01:29:59 ylo |
---|
17 | * Added cvs log. |
---|
18 | * |
---|
19 | * $Endlog$ |
---|
20 | */ |
---|
21 | |
---|
22 | #include "includes.h" |
---|
23 | #include "arcfour.h" |
---|
24 | |
---|
25 | void arcfour_init(ArcfourContext *ctx, const unsigned char *key, |
---|
26 | unsigned int key_len) |
---|
27 | { |
---|
28 | unsigned int t, u; |
---|
29 | unsigned int keyindex; |
---|
30 | unsigned int stateindex; |
---|
31 | unsigned char* state; |
---|
32 | unsigned int counter; |
---|
33 | |
---|
34 | assert(key_len > 0); |
---|
35 | |
---|
36 | state = &ctx->state[0]; |
---|
37 | ctx->x = 0; |
---|
38 | ctx->y = 0; |
---|
39 | for (counter = 0; counter < 256; counter++) |
---|
40 | state[counter] = counter; |
---|
41 | keyindex = 0; |
---|
42 | stateindex = 0; |
---|
43 | for (counter = 0; counter < 256; counter++) |
---|
44 | { |
---|
45 | t = state[counter]; |
---|
46 | stateindex = (stateindex + key[keyindex] + t) & 0xff; |
---|
47 | u = state[stateindex]; |
---|
48 | state[stateindex] = t; |
---|
49 | state[counter] = u; |
---|
50 | if (++keyindex >= key_len) |
---|
51 | keyindex = 0; |
---|
52 | } |
---|
53 | } |
---|
54 | |
---|
55 | inline unsigned int arcfour_byte(ArcfourContext *ctx) |
---|
56 | { |
---|
57 | unsigned int x; |
---|
58 | unsigned int y; |
---|
59 | unsigned int sx, sy; |
---|
60 | unsigned char *state; |
---|
61 | |
---|
62 | state = ctx->state; |
---|
63 | x = (ctx->x + 1) & 0xff; |
---|
64 | sx = state[x]; |
---|
65 | y = (sx + ctx->y) & 0xff; |
---|
66 | sy = state[y]; |
---|
67 | ctx->x = x; |
---|
68 | ctx->y = y; |
---|
69 | state[y] = sx; |
---|
70 | state[x] = sy; |
---|
71 | return state[(sx + sy) & 0xff]; |
---|
72 | } |
---|
73 | |
---|
74 | void arcfour_encrypt(ArcfourContext *ctx, unsigned char *dest, |
---|
75 | const unsigned char *src, unsigned int len) |
---|
76 | { |
---|
77 | unsigned int i; |
---|
78 | for (i = 0; i < len; i++) |
---|
79 | dest[i] = src[i] ^ arcfour_byte(ctx); |
---|
80 | } |
---|
81 | |
---|
82 | void arcfour_decrypt(ArcfourContext *ctx, unsigned char *dest, |
---|
83 | const unsigned char *src, unsigned int len) |
---|
84 | { |
---|
85 | arcfour_encrypt(ctx, dest, src, len); |
---|
86 | } |
---|