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