1 /*
2 * Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License); you may
5 * not use this file except in compliance with the License.
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 */
9
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <gmssl/rc4.h>
15
rc4_init(RC4_STATE * state,const uint8_t * key,size_t keylen)16 void rc4_init(RC4_STATE *state, const uint8_t *key, size_t keylen)
17 {
18 int i, j;
19 uint8_t *s = state->d;
20 uint8_t k[256];
21 uint8_t temp;
22
23 /* expand key */
24 for (i = 0; i < keylen; i++) {
25 k[i] = key[i];
26 }
27 for (i = keylen; i < 256; i++) {
28 k[i] = key[i % keylen];
29 }
30
31 /* init state */
32 for (i = 0; i < 256; i++) {
33 s[i] = i;
34 }
35
36 /* shuffle state with key */
37 j = 0;
38 for (i = 0; i < 256; i++) {
39 j = (j + s[i] + k[i]) % 256;
40
41 /* swap(s[i], s[j]) */
42 temp = s[j];
43 s[j] = s[i];
44 s[i] = temp;
45 }
46
47 /* clean expanded temp key */
48 memset(k, 0, sizeof(k));
49 }
50
rc4_generate_keystream(RC4_STATE * state,size_t outlen,uint8_t * out)51 void rc4_generate_keystream(RC4_STATE *state, size_t outlen, uint8_t *out)
52 {
53 int i = 0, j = 0;
54 uint8_t *s = state->d;
55 int oi;
56 int temp;
57
58 while (outlen > 0) {
59 i = (i + 1) % 256;
60 j = (j + s[i]) % 256;
61
62 /* swap(s[i], s[j]) */
63 temp = s[j];
64 s[j] = s[i];
65 s[i] = temp;
66
67 oi = (s[i] + s[j]) % 256;
68 *out++ = s[oi];
69
70 outlen--;
71 }
72 }
73
rc4_generate_keybyte(RC4_STATE * state)74 uint8_t rc4_generate_keybyte(RC4_STATE *state)
75 {
76 uint8_t out[1];
77 rc4_generate_keystream(state, 1, out);
78 return out[0];
79 }
80