summaryrefslogtreecommitdiff
path: root/usr.bin/ssh/rc4.c
blob: f85038daf68e14cace242515eff115eef60a4564 (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
/*

Alleged RC4 (based on the Usenet posting in Spring-95)

*/

#include "includes.h"
RCSID("$Id: rc4.c,v 1.1 1999/09/26 20:53:37 deraadt Exp $");

#include "rc4.h"

void rc4_init(RC4Context *ctx, const unsigned char *key, unsigned int key_len)
{
  unsigned int t, u;
  unsigned int keyindex;
  unsigned int stateindex;
  unsigned char* state;
  unsigned int counter;

  assert(key_len > 0);

  state = &ctx->state[0];
  ctx->x = 0;
  ctx->y = 0;
  for (counter = 0; counter < 256; counter++)
    state[counter] = counter;
  keyindex = 0;
  stateindex = 0;
  for (counter = 0; counter < 256; counter++)
    {
      t = state[counter];
      stateindex = (stateindex + key[keyindex] + t) & 0xff;
      u = state[stateindex];
      state[stateindex] = t;
      state[counter] = u;
      if (++keyindex >= key_len)
	keyindex = 0;
    }
}

inline unsigned int rc4_byte(RC4Context *ctx)
{
  unsigned int x;
  unsigned int y;
  unsigned int sx, sy;
  unsigned char *state;

  state = ctx->state;
  x = (ctx->x + 1) & 0xff;
  sx = state[x];
  y = (sx + ctx->y) & 0xff;
  sy = state[y];
  ctx->x = x;
  ctx->y = y;
  state[y] = sx;
  state[x] = sy;
  return state[(sx + sy) & 0xff];
}

void rc4_encrypt(RC4Context *ctx, unsigned char *dest, 
		 const unsigned char *src, unsigned int len)
{
  unsigned int i;
  for (i = 0; i < len; i++)
    dest[i] = src[i] ^ rc4_byte(ctx);
}

void rc4_decrypt(RC4Context *ctx, unsigned char *dest, 
		 const unsigned char *src, unsigned int len)
{
  rc4_encrypt(ctx, dest, src, len);
}