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