]> git.ozlabs.org Git - ppp.git/blob - linux/mppe/arcfour.c
97ae00659b1e1ad870879e1e0d412410ead5c977
[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 #if defined(__linux__)
16 #include <linux/string.h>
17 #endif
18
19 #define swap(a, b)              \
20 {                               \
21     unsigned char t = b;        \
22     b = a;                      \
23     a = t;                      \
24 }
25
26 /*
27  * Initialize arcfour from a key.
28  */
29 void
30 arcfour_setkey(arcfour_context *context, const unsigned char *key,
31                unsigned keylen)
32 {
33     unsigned i, j;
34     unsigned char K[256];
35
36     context->i = context->j = 0;
37
38     for (i = 0; i < 256; i++) {
39         context->S[i] = i;
40         K[i] = key[i % keylen];
41     }
42
43     j = 0;
44     for (i = 0; i < 256; i++) {
45         j = (j + context->S[i] + K[i]) % 256;
46         swap(context->S[i], context->S[j]);
47     }
48
49     memset(K, 0, sizeof(K));
50 }
51
52 /*
53  * plaintext -> ciphertext (or vice versa)
54  */
55 void
56 arcfour_encrypt(arcfour_context *context, const unsigned char *in, unsigned len,
57                 unsigned char *out)
58 {
59     unsigned i = context->i;
60     unsigned j = context->j;
61     unsigned char *S = context->S;
62     unsigned char K;
63
64     while (len--) {
65         i = (i + 1) % 256;
66         j = (j + S[i]) % 256;
67         swap(S[i], S[j]);
68         K = S[(S[i] + S[j]) % 256];
69         *out++ = *in++ ^ K;
70     }
71
72     context->i = i;
73     context->j = j;
74 }
75