Added kernel MPPE patches (2.2.20 kernel only!) from Frank Cusack.
[ppp.git] / linux / mppe / arcfour.c
1 /*
2  * arcfour.c
3  * by Frank Cusack <frank@google.com>
4  * 100% public domain
5  *
6  * Implemented from the description in _Applied Cryptography_, 2nd ed.
7  *
8  * ** Distribution ** of this software is unlimited and unrestricted.
9  *
10  * ** Use ** of this software is almost certainly legal; however, refer
11  * to <http://theory.lcs.mit.edu/~rivest/faq.html>.
12  */
13
14 #include "arcfour.h"
15
16 #define swap(a, b)              \
17 {                               \
18     unsigned char t = b;        \
19     b = a;                      \
20     a = t;                      \
21 }
22
23 /*
24  * Initialize arcfour from a key.
25  */
26 void
27 arcfour_setkey(arcfour_context *context, const unsigned char *key,
28                unsigned keylen)
29 {
30     unsigned i, j;
31     unsigned char K[256];
32
33     context->i = context->j = 0;
34
35     for (i = 0; i < 256; i++) {
36         context->S[i] = i;
37         K[i] = key[i % keylen];
38     }
39
40     j = 0;
41     for (i = 0; i < 256; i++) {
42         j = (j + context->S[i] + K[i]) % 256;
43         swap(context->S[i], context->S[j]);
44     }
45
46     memset(K, 0, sizeof(K));
47 }
48
49 /*
50  * plaintext -> ciphertext (or vice versa)
51  */
52 void
53 arcfour_encrypt(arcfour_context *context, const unsigned char *in, unsigned len,
54                 unsigned char *out)
55 {
56     unsigned i = context->i;
57     unsigned j = context->j;
58     unsigned char *S = context->S;
59     unsigned char K;
60
61     while (len--) {
62         i = (i + 1) % 256;
63         j = (j + S[i]) % 256;
64         swap(S[i], S[j]);
65         K = S[(S[i] + S[j]) % 256];
66         *out++ = *in++ ^ K;
67     }
68
69     context->i = i;
70     context->j = j;
71 }
72