1 /* $OpenBSD: rc4_test.c,v 1.6 2022/11/09 12:10:17 joshua Exp $ */
2 /*
3 * Copyright (c) 2022 Joshua Sing <joshua@hypera.dev>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <openssl/evp.h>
19 #include <openssl/rc4.h>
20
21 #include <stdint.h>
22 #include <string.h>
23
24 struct rc4_test {
25 const uint8_t key[32];
26 const int key_len;
27 const int len;
28 const uint8_t in[512];
29 const uint8_t out[512];
30 };
31
32 static const struct rc4_test rc4_tests[] = {
33 /*
34 * Test vectors from RFC 6229, with 40 and 128-bit keys.
35 * Note that this only uses the first 32 bytes of each test vector due
36 * to stream offsets.
37 */
38 {
39 .key = {
40 0x01, 0x02, 0x03, 0x04, 0x05,
41 },
42 .key_len = 5,
43 .len = 32,
44 .in = {
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 },
50 .out = {
51 0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27,
52 0xcc, 0xc3, 0x52, 0x4a, 0x0a, 0x11, 0x18, 0xa8,
53 0x69, 0x82, 0x94, 0x4f, 0x18, 0xfc, 0x82, 0xd5,
54 0x89, 0xc4, 0x03, 0xa4, 0x7a, 0x0d, 0x09, 0x19,
55 },
56 },
57 {
58 .key = {
59 0x83, 0x32, 0x22, 0x77, 0x2a,
60 },
61 .key_len = 5,
62 .len = 32,
63 .in = {
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 },
69 .out = {
70 0x80, 0xad, 0x97, 0xbd, 0xc9, 0x73, 0xdf, 0x8a,
71 0x2e, 0x87, 0x9e, 0x92, 0xa4, 0x97, 0xef, 0xda,
72 0x20, 0xf0, 0x60, 0xc2, 0xf2, 0xe5, 0x12, 0x65,
73 0x01, 0xd3, 0xd4, 0xfe, 0xa1, 0x0d, 0x5f, 0xc0,
74 },
75 },
76 {
77 .key = {
78 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
79 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
80 },
81 .key_len = 16,
82 .len = 32,
83 .in = {
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 },
89 .out = {
90 0x9a, 0xc7, 0xcc, 0x9a, 0x60, 0x9d, 0x1e, 0xf7,
91 0xb2, 0x93, 0x28, 0x99, 0xcd, 0xe4, 0x1b, 0x97,
92 0x52, 0x48, 0xc4, 0x95, 0x90, 0x14, 0x12, 0x6a,
93 0x6e, 0x8a, 0x84, 0xf1, 0x1d, 0x1a, 0x9e, 0x1c,
94 },
95 },
96 {
97 .key = {
98 0xeb, 0xb4, 0x62, 0x27, 0xc6, 0xcc, 0x8b, 0x37,
99 0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a,
100 },
101 .key_len = 16,
102 .len = 32,
103 .in = {
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 },
109 .out = {
110 0x72, 0x0c, 0x94, 0xb6, 0x3e, 0xdf, 0x44, 0xe1,
111 0x31, 0xd9, 0x50, 0xca, 0x21, 0x1a, 0x5a, 0x30,
112 0xc3, 0x66, 0xfd, 0xea, 0xcf, 0x9c, 0xa8, 0x04,
113 0x36, 0xbe, 0x7c, 0x35, 0x84, 0x24, 0xd2, 0x0b,
114 },
115 },
116
117 /*
118 * Test vectors from the original cypherpunk posting of ARC4:
119 * https://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0?pli=1
120 */
121 {
122 .key = {
123 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
124 },
125 .key_len = 8,
126 .len = 8,
127 .in = {
128 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
129 },
130 .out = {
131 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96,
132 },
133 },
134 {
135 .key = {
136 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
137 },
138 .key_len = 8,
139 .len = 8,
140 .in = {
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 },
143 .out = {
144 0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79,
145 },
146 },
147 {
148 .key = {
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 },
151 .key_len = 8,
152 .len = 8,
153 .in = {
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 },
156 .out = {
157 0xde, 0x18, 0x89, 0x41, 0xa3, 0x37, 0x5d, 0x3a,
158 },
159 },
160 {
161 .key = {
162 0xef, 0x01, 0x23, 0x45,
163 },
164 .key_len = 4,
165 .len = 10,
166 .in = {
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00,
169 },
170 .out = {
171 0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf,
172 0xbd, 0x61,
173 },
174 },
175 {
176 .key = {
177 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
178 },
179 .key_len = 8,
180 .len = 512,
181 .in = {
182 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
183 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
184 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
185 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
186 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
187 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
188 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
189 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
190 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
191 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
192 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
193 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
194 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
195 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
196 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
197 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
198 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
199 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
200 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
201 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
202 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
203 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
204 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
205 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
206 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
207 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
208 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
209 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
210 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
211 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
212 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
213 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
214 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
215 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
216 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
217 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
218 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
219 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
220 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
221 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
222 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
223 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
224 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
225 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
226 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
227 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
228 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
229 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
230 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
231 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
232 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
233 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
234 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
235 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
236 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
237 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
238 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
239 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
240 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
241 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
242 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
243 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
244 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
245 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
246 },
247 .out = {
248 0x75, 0x95, 0xc3, 0xe6, 0x11, 0x4a, 0x09, 0x78,
249 0x0c, 0x4a, 0xd4, 0x52, 0x33, 0x8e, 0x1f, 0xfd,
250 0x9a, 0x1b, 0xe9, 0x49, 0x8f, 0x81, 0x3d, 0x76,
251 0x53, 0x34, 0x49, 0xb6, 0x77, 0x8d, 0xca, 0xd8,
252 0xc7, 0x8a, 0x8d, 0x2b, 0xa9, 0xac, 0x66, 0x08,
253 0x5d, 0x0e, 0x53, 0xd5, 0x9c, 0x26, 0xc2, 0xd1,
254 0xc4, 0x90, 0xc1, 0xeb, 0xbe, 0x0c, 0xe6, 0x6d,
255 0x1b, 0x6b, 0x1b, 0x13, 0xb6, 0xb9, 0x19, 0xb8,
256 0x47, 0xc2, 0x5a, 0x91, 0x44, 0x7a, 0x95, 0xe7,
257 0x5e, 0x4e, 0xf1, 0x67, 0x79, 0xcd, 0xe8, 0xbf,
258 0x0a, 0x95, 0x85, 0x0e, 0x32, 0xaf, 0x96, 0x89,
259 0x44, 0x4f, 0xd3, 0x77, 0x10, 0x8f, 0x98, 0xfd,
260 0xcb, 0xd4, 0xe7, 0x26, 0x56, 0x75, 0x00, 0x99,
261 0x0b, 0xcc, 0x7e, 0x0c, 0xa3, 0xc4, 0xaa, 0xa3,
262 0x04, 0xa3, 0x87, 0xd2, 0x0f, 0x3b, 0x8f, 0xbb,
263 0xcd, 0x42, 0xa1, 0xbd, 0x31, 0x1d, 0x7a, 0x43,
264 0x03, 0xdd, 0xa5, 0xab, 0x07, 0x88, 0x96, 0xae,
265 0x80, 0xc1, 0x8b, 0x0a, 0xf6, 0x6d, 0xff, 0x31,
266 0x96, 0x16, 0xeb, 0x78, 0x4e, 0x49, 0x5a, 0xd2,
267 0xce, 0x90, 0xd7, 0xf7, 0x72, 0xa8, 0x17, 0x47,
268 0xb6, 0x5f, 0x62, 0x09, 0x3b, 0x1e, 0x0d, 0xb9,
269 0xe5, 0xba, 0x53, 0x2f, 0xaf, 0xec, 0x47, 0x50,
270 0x83, 0x23, 0xe6, 0x71, 0x32, 0x7d, 0xf9, 0x44,
271 0x44, 0x32, 0xcb, 0x73, 0x67, 0xce, 0xc8, 0x2f,
272 0x5d, 0x44, 0xc0, 0xd0, 0x0b, 0x67, 0xd6, 0x50,
273 0xa0, 0x75, 0xcd, 0x4b, 0x70, 0xde, 0xdd, 0x77,
274 0xeb, 0x9b, 0x10, 0x23, 0x1b, 0x6b, 0x5b, 0x74,
275 0x13, 0x47, 0x39, 0x6d, 0x62, 0x89, 0x74, 0x21,
276 0xd4, 0x3d, 0xf9, 0xb4, 0x2e, 0x44, 0x6e, 0x35,
277 0x8e, 0x9c, 0x11, 0xa9, 0xb2, 0x18, 0x4e, 0xcb,
278 0xef, 0x0c, 0xd8, 0xe7, 0xa8, 0x77, 0xef, 0x96,
279 0x8f, 0x13, 0x90, 0xec, 0x9b, 0x3d, 0x35, 0xa5,
280 0x58, 0x5c, 0xb0, 0x09, 0x29, 0x0e, 0x2f, 0xcd,
281 0xe7, 0xb5, 0xec, 0x66, 0xd9, 0x08, 0x4b, 0xe4,
282 0x40, 0x55, 0xa6, 0x19, 0xd9, 0xdd, 0x7f, 0xc3,
283 0x16, 0x6f, 0x94, 0x87, 0xf7, 0xcb, 0x27, 0x29,
284 0x12, 0x42, 0x64, 0x45, 0x99, 0x85, 0x14, 0xc1,
285 0x5d, 0x53, 0xa1, 0x8c, 0x86, 0x4c, 0xe3, 0xa2,
286 0xb7, 0x55, 0x57, 0x93, 0x98, 0x81, 0x26, 0x52,
287 0x0e, 0xac, 0xf2, 0xe3, 0x06, 0x6e, 0x23, 0x0c,
288 0x91, 0xbe, 0xe4, 0xdd, 0x53, 0x04, 0xf5, 0xfd,
289 0x04, 0x05, 0xb3, 0x5b, 0xd9, 0x9c, 0x73, 0x13,
290 0x5d, 0x3d, 0x9b, 0xc3, 0x35, 0xee, 0x04, 0x9e,
291 0xf6, 0x9b, 0x38, 0x67, 0xbf, 0x2d, 0x7b, 0xd1,
292 0xea, 0xa5, 0x95, 0xd8, 0xbf, 0xc0, 0x06, 0x6f,
293 0xf8, 0xd3, 0x15, 0x09, 0xeb, 0x0c, 0x6c, 0xaa,
294 0x00, 0x6c, 0x80, 0x7a, 0x62, 0x3e, 0xf8, 0x4c,
295 0x3d, 0x33, 0xc1, 0x95, 0xd2, 0x3e, 0xe3, 0x20,
296 0xc4, 0x0d, 0xe0, 0x55, 0x81, 0x57, 0xc8, 0x22,
297 0xd4, 0xb8, 0xc5, 0x69, 0xd8, 0x49, 0xae, 0xd5,
298 0x9d, 0x4e, 0x0f, 0xd7, 0xf3, 0x79, 0x58, 0x6b,
299 0x4b, 0x7f, 0xf6, 0x84, 0xed, 0x6a, 0x18, 0x9f,
300 0x74, 0x86, 0xd4, 0x9b, 0x9c, 0x4b, 0xad, 0x9b,
301 0xa2, 0x4b, 0x96, 0xab, 0xf9, 0x24, 0x37, 0x2c,
302 0x8a, 0x8f, 0xff, 0xb1, 0x0d, 0x55, 0x35, 0x49,
303 0x00, 0xa7, 0x7a, 0x3d, 0xb5, 0xf2, 0x05, 0xe1,
304 0xb9, 0x9f, 0xcd, 0x86, 0x60, 0x86, 0x3a, 0x15,
305 0x9a, 0xd4, 0xab, 0xe4, 0x0f, 0xa4, 0x89, 0x34,
306 0x16, 0x3d, 0xdd, 0xe5, 0x42, 0xa6, 0x58, 0x55,
307 0x40, 0xfd, 0x68, 0x3c, 0xbf, 0xd8, 0xc0, 0x0f,
308 0x12, 0x12, 0x9a, 0x28, 0x4d, 0xea, 0xcc, 0x4c,
309 0xde, 0xfe, 0x58, 0xbe, 0x71, 0x37, 0x54, 0x1c,
310 0x04, 0x71, 0x26, 0xc8, 0xd4, 0x9e, 0x27, 0x55,
311 0xab, 0x18, 0x1a, 0xb7, 0xe9, 0x40, 0xb0, 0xc0,
312 },
313 },
314 };
315
316 #define N_RC4_TESTS (sizeof(rc4_tests) / sizeof(rc4_tests[0]))
317
318 static int
rc4_test(void)319 rc4_test(void)
320 {
321 const struct rc4_test *rt;
322 RC4_KEY key;
323 EVP_CIPHER_CTX *ctx = NULL;
324 const EVP_CIPHER *cipher;
325 uint8_t out[512];
326 int in_len, out_len, total_len;
327 size_t i;
328 int j;
329 int failed = 1;
330
331 if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
332 fprintf(stderr, "FAIL: EVP_CIPHER_CTX_new() failed\n");
333 goto failed;
334 }
335
336 for (i = 0; i < N_RC4_TESTS; i++) {
337 rt = &rc4_tests[i];
338
339 /* Encryption */
340 memset(out, 0, sizeof(out));
341 RC4_set_key(&key, rt->key_len, rt->key);
342 RC4(&key, rt->len, rt->in, out);
343
344 if (memcmp(rt->out, out, rt->len) != 0) {
345 fprintf(stderr, "FAIL: encryption mismatch\n");
346 goto failed;
347 }
348
349 /* Decryption */
350 memset(out, 0, sizeof(out));
351 RC4_set_key(&key, rt->key_len, rt->key);
352 RC4(&key, rt->len, rt->out, out);
353
354 if (memcmp(rt->in, out, rt->len) != 0) {
355 fprintf(stderr, "FAIL: decryption mismatch\n");
356 goto failed;
357 }
358
359 /*
360 * EVP tests
361 */
362 if (rt->key_len == 5) {
363 cipher = EVP_rc4_40();
364 } else if (rt->key_len == 16) {
365 cipher = EVP_rc4();
366 } else {
367 /* EVP does not support this key length */
368 continue;
369 }
370
371 /* EVP encryption */
372 total_len = 0;
373 memset(out, 0, sizeof(out));
374 if (!EVP_EncryptInit(ctx, cipher, rt->key, NULL)) {
375 fprintf(stderr, "FAIL: EVP_EncryptInit failed\n");
376 goto failed;
377 }
378
379 for (j = 0; j < rt->len;) {
380 in_len = arc4random_uniform(rt->len / 2);
381 if (in_len > rt->len - j)
382 in_len = rt->len - j;
383
384 if (!EVP_EncryptUpdate(ctx, out + total_len, &out_len,
385 rt->in + j, in_len)) {
386 fprintf(stderr,
387 "FAIL: EVP_EncryptUpdate failed\n");
388 goto failed;
389 }
390
391 j += in_len;
392 total_len += out_len;
393 }
394
395 if (!EVP_EncryptFinal_ex(ctx, out + total_len, &out_len)) {
396 fprintf(stderr, "FAIL: EVP_EncryptFinal_ex failed\n");
397 goto failed;
398 }
399 total_len += out_len;
400
401 if (!EVP_CIPHER_CTX_reset(ctx)) {
402 fprintf(stderr, "FAIL: EVP_CIPHER_CTX_reset failed\n");
403 goto failed;
404 }
405
406 if (total_len != rt->len) {
407 fprintf(stderr,
408 "FAIL: EVP encryption length mismatch\n");
409 goto failed;
410 }
411
412 if (memcmp(rt->out, out, rt->len) != 0) {
413 fprintf(stderr, "FAIL: EVP encryption mismatch\n");
414 goto failed;
415 }
416
417 /* EVP decryption */
418 total_len = 0;
419 memset(out, 0, sizeof(out));
420 if (!EVP_DecryptInit(ctx, cipher, rt->key, NULL)) {
421 fprintf(stderr, "FAIL: EVP_DecryptInit failed\n");
422 goto failed;
423 }
424
425 for (j = 0; j < rt->len;) {
426 in_len = arc4random_uniform(rt->len / 2);
427 if (in_len > rt->len - j)
428 in_len = rt->len - j;
429
430 if (!EVP_DecryptUpdate(ctx, out + total_len, &out_len,
431 rt->in + j, in_len)) {
432 fprintf(stderr,
433 "FAIL: EVP_DecryptUpdate failed\n");
434 goto failed;
435 }
436
437 j += in_len;
438 total_len += out_len;
439 }
440
441 if (!EVP_DecryptFinal_ex(ctx, out + total_len, &out_len)) {
442 fprintf(stderr, "FAIL: EVP_DecryptFinal_ex failed\n");
443 goto failed;
444 }
445 total_len += out_len;
446
447 if (!EVP_CIPHER_CTX_reset(ctx)) {
448 fprintf(stderr, "FAIL: EVP_CIPHER_CTX_reset failed\n");
449 goto failed;
450 }
451
452 if (total_len != rt->len) {
453 fprintf(stderr,
454 "FAIL: EVP decryption length mismatch\n");
455 goto failed;
456 }
457
458 if (memcmp(rt->out, out, rt->len) != 0) {
459 fprintf(stderr, "FAIL: EVP decryption mismatch\n");
460 goto failed;
461 }
462 }
463
464 failed = 0;
465
466 failed:
467 EVP_CIPHER_CTX_free(ctx);
468 return failed;
469 }
470
471 int
main(int argc,char ** argv)472 main(int argc, char **argv)
473 {
474 int failed = 0;
475
476 failed |= rc4_test();
477
478 return failed;
479 }
480