]> pd.if.org Git - zpackage/blob - rc4_stream.c
178489d723acfd402ef68b9bbd5601fffd509250
[zpackage] / rc4_stream.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9
10 #include "tomcrypt.h"
11
12 #ifdef LTC_RC4_STREAM
13
14 /**
15    Initialize an RC4 context (only the key)
16    @param st        [out] The destination of the RC4 state
17    @param key       The secret key
18    @param keylen    The length of the secret key (8 - 256 bytes)
19    @return CRYPT_OK if successful
20 */
21 int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen)
22 {
23    unsigned char tmp, *s;
24    int x, y;
25    unsigned long j;
26
27    LTC_ARGCHK(st  != NULL);
28    LTC_ARGCHK(key != NULL);
29    LTC_ARGCHK(keylen >= 5); /* 40-2048 bits */
30
31    s = st->buf;
32    for (x = 0; x < 256; x++) {
33       s[x] = x;
34    }
35
36    for (j = x = y = 0; x < 256; x++) {
37       y = (y + s[x] + key[j++]) & 255;
38       if (j == keylen) {
39          j = 0;
40       }
41       tmp = s[x]; s[x] = s[y]; s[y] = tmp;
42    }
43    st->x = 0;
44    st->y = 0;
45
46    return CRYPT_OK;
47 }
48
49 /**
50    Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4
51    @param st      The RC4 state
52    @param in      The plaintext (or ciphertext)
53    @param inlen   The length of the input (octets)
54    @param out     [out] The ciphertext (or plaintext), length inlen
55    @return CRYPT_OK if successful
56 */
57 int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
58 {
59    unsigned char x, y, *s, tmp;
60
61    LTC_ARGCHK(st  != NULL);
62    LTC_ARGCHK(in  != NULL);
63    LTC_ARGCHK(out != NULL);
64
65    x = st->x;
66    y = st->y;
67    s = st->buf;
68    while (inlen--) {
69       x = (x + 1) & 255;
70       y = (y + s[x]) & 255;
71       tmp = s[x]; s[x] = s[y]; s[y] = tmp;
72       tmp = (s[x] + s[y]) & 255;
73       *out++ = *in++ ^ s[tmp];
74    }
75    st->x = x;
76    st->y = y;
77    return CRYPT_OK;
78 }
79
80 /**
81   Generate a stream of random bytes via RC4
82   @param st      The RC420 state
83   @param out     [out] The output buffer
84   @param outlen  The output length
85   @return CRYPT_OK on success
86  */
87 int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen)
88 {
89    if (outlen == 0) return CRYPT_OK; /* nothing to do */
90    LTC_ARGCHK(out != NULL);
91    XMEMSET(out, 0, outlen);
92    return rc4_stream_crypt(st, out, outlen, out);
93 }
94
95 /**
96   Terminate and clear RC4 state
97   @param st      The RC4 state
98   @return CRYPT_OK on success
99 */
100 int rc4_stream_done(rc4_state *st)
101 {
102    LTC_ARGCHK(st != NULL);
103    XMEMSET(st, 0, sizeof(rc4_state));
104    return CRYPT_OK;
105 }
106
107 #endif
108
109 /* ref:         $Format:%D$ */
110 /* git commit:  $Format:%H$ */
111 /* commit time: $Format:%ai$ */