xref: /openbsd-src/regress/lib/libcrypto/rc2/rc2_test.c (revision 75a38c89436cfd7541af75d29a2fa225b9b40cfa)
1 /*	$OpenBSD: rc2_test.c,v 1.6 2022/11/09 12:13:08 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/rc2.h>
20 
21 #include <stdint.h>
22 #include <string.h>
23 
24 struct rc2_test {
25 	const int mode;
26 	const uint8_t key[64];
27 	const int key_len;
28 	const int key_bits;
29 	const uint8_t iv[64];
30 	const int iv_len;
31 	const uint8_t in[64];
32 	const int in_len;
33 	const uint8_t out[64];
34 	const int out_len;
35 	const int padding;
36 };
37 
38 static const struct rc2_test rc2_tests[] = {
39 	/* ECB (Test vectors from RFC 2268) */
40 	{
41 		.mode = NID_rc2_ecb,
42 		.key = {
43 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 		},
45 		.key_len = 8,
46 		.key_bits = 63,
47 		.in = {
48 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 		},
50 		.in_len = 8,
51 		.out = {
52 			0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff,
53 		},
54 		.out_len = 8,
55 	},
56 	{
57 		.mode = NID_rc2_ecb,
58 		.key = {
59 			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
60 		},
61 		.key_len = 8,
62 		.key_bits = 64,
63 		.in = {
64 			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
65 		},
66 		.in_len = 8,
67 		.out = {
68 			0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49,
69 		},
70 		.out_len = 8,
71 	},
72 	{
73 		.mode = NID_rc2_ecb,
74 		.key = {
75 			0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 		},
77 		.key_len = 8,
78 		.key_bits = 64,
79 		.in = {
80 			0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
81 		},
82 		.in_len = 8,
83 		.out = {
84 			0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2,
85 		},
86 		.out_len = 8,
87 	},
88 	{
89 		.mode = NID_rc2_ecb,
90 		.key = {
91 			0x88,
92 		},
93 		.key_len = 1,
94 		.key_bits = 64,
95 		.in = {
96 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 		},
98 		.in_len = 8,
99 		.out = {
100 			0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0,
101 		},
102 		.out_len = 8,
103 	},
104 	{
105 		.mode = NID_rc2_ecb,
106 		.key = {
107 			0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a,
108 		},
109 		.key_len = 7,
110 		.key_bits = 64,
111 		.in = {
112 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 		},
114 		.in_len = 8,
115 		.out = {
116 			0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f,
117 		},
118 		.out_len = 8,
119 	},
120 	{
121 		.mode = NID_rc2_ecb,
122 		.key = {
123 			0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
124 			0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2,
125 		},
126 		.key_len = 16,
127 		.key_bits = 64,
128 		.in = {
129 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 		},
131 		.in_len = 8,
132 		.out = {
133 			0x1a, 0x80, 0x7d, 0x27, 0x2b, 0xbe, 0x5d, 0xb1,
134 		},
135 		.out_len = 8,
136 	},
137 	{
138 		.mode = NID_rc2_ecb,
139 		.key = {
140 			0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
141 			0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2,
142 		},
143 		.key_len = 16,
144 		.key_bits = 128,
145 		.in = {
146 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 		},
148 		.in_len = 8,
149 		.out = {
150 			0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6,
151 		},
152 		.out_len = 8,
153 	},
154 	{
155 		.mode = NID_rc2_ecb,
156 		.key = {
157 			0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
158 			0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2,
159 			0x16, 0xf8, 0x0a, 0x6f, 0x85, 0x92, 0x05, 0x84,
160 			0xc4, 0x2f, 0xce, 0xb0, 0xbe, 0x25, 0x5d, 0xaf,
161 			0x1e,
162 		},
163 		.key_len = 33,
164 		.key_bits = 129,
165 		.in = {
166 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 		},
168 		.in_len = 8,
169 		.out = {
170 			0x5b, 0x78, 0xd3, 0xa4, 0x3d, 0xff, 0xf1, 0xf1,
171 		},
172 		.out_len = 8,
173 	},
174 
175 	/* ECB (Test vectors from http://websites.umich.edu/~x509/ssleay/rrc2.html) */
176 	{
177 		.mode = NID_rc2_ecb,
178 		.key = {
179 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 		},
182 		.key_len = 16,
183 		.key_bits = 1024,
184 		.in = {
185 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 		},
187 		.in_len = 8,
188 		.out = {
189 			0x1c, 0x19, 0x8a, 0x83, 0x8d, 0xf0, 0x28, 0xb7,
190 		},
191 		.out_len = 8,
192 	},
193 	{
194 		.mode = NID_rc2_ecb,
195 		.key = {
196 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
198 		},
199 		.key_len = 16,
200 		.key_bits = 1024,
201 		.in = {
202 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 		},
204 		.in_len = 8,
205 		.out = {
206 			0x21, 0x82, 0x9C, 0x78, 0xA9, 0xF9, 0xC0, 0x74,
207 		},
208 		.out_len = 8,
209 	},
210 	{
211 		.mode = NID_rc2_ecb,
212 		.key = {
213 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 		},
216 		.key_len = 16,
217 		.key_bits = 1024,
218 		.in = {
219 			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
220 		},
221 		.in_len = 8,
222 		.out = {
223 			0x13, 0xdb, 0x35, 0x17, 0xd3, 0x21, 0x86, 0x9e,
224 		},
225 		.out_len = 8,
226 	},
227 	{
228 		.mode = NID_rc2_ecb,
229 		.key = {
230 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
231 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
232 		},
233 		.key_len = 16,
234 		.key_bits = 1024,
235 		.in = {
236 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 		},
238 		.in_len = 8,
239 		.out = {
240 			0x50, 0xdc, 0x01, 0x62, 0xbd, 0x75, 0x7f, 0x31,
241 		},
242 		.out_len = 8,
243 	},
244 
245 	/* CBC (generated using https://github.com/joshuasing/libressl-test-gen) */
246 	{
247 		.mode = NID_rc2_cbc,
248 		.key = {
249 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 		},
251 		.key_len = 8,
252 		.key_bits = 64,
253 		.iv = {
254 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 		},
256 		.iv_len = 8,
257 		.in = {
258 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 		},
261 		.in_len = 16,
262 		.out = {
263 			0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff,
264 			0xf0, 0x51, 0x77, 0x8b, 0x65, 0xdb, 0x13, 0x57,
265 		},
266 		.out_len = 16,
267 	},
268 	{
269 		.mode = NID_rc2_cbc,
270 		.key = {
271 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
272 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
273 		},
274 		.key_len = 16,
275 		.key_bits = 128,
276 		.iv = {
277 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278 		},
279 		.iv_len = 8,
280 		.in = {
281 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
283 		},
284 		.in_len = 16,
285 		.out = {
286 			0x9c, 0x4b, 0xfe, 0x6d, 0xfe, 0x73, 0x9c, 0x2b,
287 			0x52, 0x8f, 0xc8, 0x47, 0x2b, 0x66, 0xf9, 0x70,
288 		},
289 		.out_len = 16,
290 	},
291 	{
292 		.mode = NID_rc2_cbc,
293 		.key = {
294 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
295 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
296 		},
297 		.key_len = 16,
298 		.key_bits = 128,
299 		.iv = {
300 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 		},
302 		.iv_len = 8,
303 		.in = {
304 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
305 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
306 		},
307 		.in_len = 16,
308 		.out = {
309 			0x8b, 0x11, 0x08, 0x1c, 0xf0, 0xa0, 0x86, 0xe9,
310 			0x60, 0x57, 0x69, 0x5d, 0xdd, 0x42, 0x38, 0xe3,
311 		},
312 		.out_len = 16,
313 	},
314 	{
315 		.mode = NID_rc2_cbc,
316 		.key = {
317 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
318 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
319 		},
320 		.key_len = 16,
321 		.key_bits = 128,
322 		.iv = {
323 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
324 		},
325 		.iv_len = 8,
326 		.in = {
327 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
328 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
329 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
330 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
331 		},
332 		.in_len = 32,
333 		.out = {
334 			0x9c, 0x4b, 0xfe, 0x6d, 0xfe, 0x73, 0x9c, 0x2b,
335 			0x29, 0xf1, 0x7a, 0xd2, 0x16, 0xa0, 0xb2, 0xc6,
336 			0xd1, 0xa2, 0x31, 0xbe, 0xa3, 0x94, 0xc6, 0xb0,
337 			0x81, 0x22, 0x27, 0x17, 0x5b, 0xd4, 0x6d, 0x29,
338 		},
339 		.out_len = 32,
340 	},
341 
342 	/* CFB64 (generated using https://github.com/joshuasing/libressl-test-gen) */
343 	{
344 		.mode = NID_rc2_cfb64,
345 		.key = {
346 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 		},
348 		.key_len = 8,
349 		.key_bits = 64,
350 		.iv = {
351 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 		},
353 		.iv_len = 8,
354 		.in = {
355 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 		},
358 		.in_len = 16,
359 		.out = {
360 			0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff,
361 			0xf0, 0x51, 0x77, 0x8b, 0x65, 0xdb, 0x13, 0x57,
362 		},
363 		.out_len = 16,
364 	},
365 	{
366 		.mode = NID_rc2_cfb64,
367 		.key = {
368 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
369 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
370 		},
371 		.key_len = 16,
372 		.key_bits = 128,
373 		.iv = {
374 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 		},
376 		.iv_len = 8,
377 		.in = {
378 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 		},
381 		.in_len = 16,
382 		.out = {
383 			0x9c, 0x4b, 0xfe, 0x6d, 0xfe, 0x73, 0x9c, 0x2b,
384 			0x52, 0x8f, 0xc8, 0x47, 0x2b, 0x66, 0xf9, 0x70,
385 		},
386 		.out_len = 16,
387 	},
388 	{
389 		.mode = NID_rc2_cfb64,
390 		.key = {
391 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
392 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
393 		},
394 		.key_len = 16,
395 		.key_bits = 128,
396 		.iv = {
397 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 		},
399 		.iv_len = 8,
400 		.in = {
401 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
402 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
403 		},
404 		.in_len = 16,
405 		.out = {
406 			0x9c, 0x4a, 0xfc, 0x6e, 0xfa, 0x76, 0x9a, 0x2c,
407 			0xeb, 0xdf, 0x25, 0xb0, 0x15, 0x8b, 0x6a, 0x2a,
408 		},
409 		.out_len = 16,
410 	},
411 	{
412 		.mode = NID_rc2_cfb64,
413 		.key = {
414 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
415 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
416 		},
417 		.key_len = 16,
418 		.key_bits = 128,
419 		.iv = {
420 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
421 		},
422 		.iv_len = 8,
423 		.in = {
424 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
425 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
426 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
427 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
428 		},
429 		.in_len = 32,
430 		.out = {
431 			0x8b, 0x10, 0x0a, 0x1f, 0xf4, 0xa5, 0x80, 0xee,
432 			0x94, 0x4d, 0xc3, 0xcd, 0x26, 0x79, 0x81, 0xc0,
433 			0xe9, 0x3e, 0x20, 0x85, 0x11, 0x71, 0x61, 0x2a,
434 			0x1d, 0x4c, 0x8a, 0xe2, 0xb7, 0x0a, 0xa8, 0xcf,
435 		},
436 		.out_len = 32,
437 	},
438 
439 	/* OFB64 (generated using https://github.com/joshuasing/libressl-test-gen) */
440 	{
441 		.mode = NID_rc2_ofb64,
442 		.key = {
443 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 		},
445 		.key_len = 8,
446 		.key_bits = 64,
447 		.iv = {
448 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 		},
450 		.iv_len = 8,
451 		.in = {
452 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 		},
455 		.in_len = 16,
456 		.out = {
457 			0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff,
458 			0xf0, 0x51, 0x77, 0x8b, 0x65, 0xdb, 0x13, 0x57,
459 		},
460 		.out_len = 16,
461 	},
462 	{
463 		.mode = NID_rc2_ofb64,
464 		.key = {
465 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
466 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
467 		},
468 		.key_len = 16,
469 		.key_bits = 128,
470 		.iv = {
471 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472 		},
473 		.iv_len = 8,
474 		.in = {
475 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 		},
478 		.in_len = 16,
479 		.out = {
480 			0x9c, 0x4b, 0xfe, 0x6d, 0xfe, 0x73, 0x9c, 0x2b,
481 			0x52, 0x8f, 0xc8, 0x47, 0x2b, 0x66, 0xf9, 0x70,
482 		},
483 		.out_len = 16,
484 	},
485 	{
486 		.mode = NID_rc2_ofb64,
487 		.key = {
488 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
489 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
490 		},
491 		.key_len = 16,
492 		.key_bits = 128,
493 		.iv = {
494 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 		},
496 		.iv_len = 8,
497 		.in = {
498 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
499 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
500 		},
501 		.in_len = 16,
502 		.out = {
503 			0x9c, 0x4a, 0xfc, 0x6e, 0xfa, 0x76, 0x9a, 0x2c,
504 			0x5a, 0x86, 0xc2, 0x4c, 0x27, 0x6b, 0xf7, 0x7f,
505 		},
506 		.out_len = 16,
507 	},
508 	{
509 		.mode = NID_rc2_ofb64,
510 		.key = {
511 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
512 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
513 		},
514 		.key_len = 16,
515 		.key_bits = 128,
516 		.iv = {
517 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
518 		},
519 		.iv_len = 8,
520 		.in = {
521 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
522 			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
523 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
524 			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
525 		},
526 		.in_len = 32,
527 		.out = {
528 			0x8b, 0x10, 0x0a, 0x1f, 0xf4, 0xa5, 0x80, 0xee,
529 			0xfa, 0x1d, 0x1a, 0x7c, 0xb2, 0x93, 0x00, 0x9d,
530 			0x36, 0xa1, 0xff, 0x3a, 0x77, 0x1d, 0x00, 0x9b,
531 			0x20, 0xde, 0x5f, 0x93, 0xcc, 0x3e, 0x51, 0xaa,
532 		},
533 		.out_len = 32,
534 	},
535 };
536 
537 #define N_RC2_TESTS (sizeof(rc2_tests) / sizeof(rc2_tests[0]))
538 
539 static int
rc2_ecb_test(size_t test_number,const struct rc2_test * rt)540 rc2_ecb_test(size_t test_number, const struct rc2_test *rt)
541 {
542 	RC2_KEY key;
543 	uint8_t out[8];
544 
545 	/* Encryption */
546 	memset(out, 0, sizeof(out));
547 	RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits);
548 	RC2_ecb_encrypt(rt->in, out, &key, 1);
549 
550 	if (memcmp(rt->out, out, rt->out_len) != 0) {
551 		fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n",
552 		    SN_rc2_ecb, test_number);
553 		return 0;
554 	}
555 
556 	/* Decryption */
557 	memset(out, 0, sizeof(out));
558 	RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits);
559 	RC2_ecb_encrypt(rt->out, out, &key, 0);
560 
561 	if (memcmp(rt->in, out, rt->in_len) != 0) {
562 		fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n",
563 		    SN_rc2_ecb, test_number);
564 		return 0;
565 	}
566 
567 	return 1;
568 }
569 
570 static int
rc2_cbc_test(size_t test_number,const struct rc2_test * rt)571 rc2_cbc_test(size_t test_number, const struct rc2_test *rt)
572 {
573 	RC2_KEY key;
574 	uint8_t out[512];
575 	uint8_t iv[64];
576 
577 	/* Encryption */
578 	memset(out, 0, sizeof(out));
579 	memcpy(iv, rt->iv, rt->iv_len);
580 	RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits);
581 	RC2_cbc_encrypt(rt->in, out, rt->in_len, &key, iv, 1);
582 
583 	if (memcmp(rt->out, out, rt->out_len) != 0) {
584 		fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n",
585 		    SN_rc2_cbc, test_number);
586 		return 0;
587 	}
588 
589 	/* Decryption */
590 	memset(out, 0, sizeof(out));
591 	memcpy(iv, rt->iv, rt->iv_len);
592 	RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits);
593 	RC2_cbc_encrypt(rt->out, out, rt->out_len, &key, iv, 0);
594 
595 	if (memcmp(rt->in, out, rt->in_len) != 0) {
596 		fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n",
597 		    SN_rc2_cbc, test_number);
598 		return 0;
599 	}
600 
601 	return 1;
602 }
603 
604 static int
rc2_cfb64_test(size_t test_number,const struct rc2_test * rt)605 rc2_cfb64_test(size_t test_number, const struct rc2_test *rt)
606 {
607 	RC2_KEY key;
608 	uint8_t out[512];
609 	uint8_t iv[64];
610 	int remainder = 0;
611 
612 	/* Encryption */
613 	memset(out, 0, sizeof(out));
614 	memcpy(iv, rt->iv, rt->iv_len);
615 	RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits);
616 	RC2_cfb64_encrypt(rt->in, out, rt->in_len * 8, &key, iv, &remainder, 1);
617 
618 	if (memcmp(rt->out, out, rt->out_len) != 0) {
619 		fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n",
620 		    SN_rc2_cbc, test_number);
621 		return 0;
622 	}
623 
624 	/* Decryption */
625 	memset(out, 0, sizeof(out));
626 	memcpy(iv, rt->iv, rt->iv_len);
627 	RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits);
628 	RC2_cfb64_encrypt(rt->out, out, rt->out_len, &key, iv, &remainder, 0);
629 
630 	if (memcmp(rt->in, out, rt->in_len) != 0) {
631 		fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n",
632 		    SN_rc2_cbc, test_number);
633 		return 0;
634 	}
635 
636 	return 1;
637 }
638 
639 static int
rc2_ofb64_test(size_t test_number,const struct rc2_test * rt)640 rc2_ofb64_test(size_t test_number, const struct rc2_test *rt)
641 {
642 	RC2_KEY key;
643 	uint8_t out[512];
644 	uint8_t iv[64];
645 	int remainder = 0;
646 
647 	/* Encryption */
648 	memset(out, 0, sizeof(out));
649 	memcpy(iv, rt->iv, rt->iv_len);
650 	RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits);
651 	RC2_ofb64_encrypt(rt->in, out, rt->in_len, &key, iv, &remainder);
652 
653 	if (memcmp(rt->out, out, rt->out_len) != 0) {
654 		fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n",
655 		    SN_rc2_cbc, test_number);
656 		return 0;
657 	}
658 
659 	/* Decryption */
660 	memset(out, 0, sizeof(out));
661 	memcpy(iv, rt->iv, rt->iv_len);
662 	RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits);
663 	RC2_ofb64_encrypt(rt->out, out, rt->out_len, &key, iv, &remainder);
664 
665 	if (memcmp(rt->in, out, rt->in_len) != 0) {
666 		fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n",
667 		    SN_rc2_cbc, test_number);
668 		return 0;
669 	}
670 
671 	return 1;
672 }
673 
674 static int
rc2_evp_test(size_t test_number,const struct rc2_test * rt,const char * label,const EVP_CIPHER * cipher)675 rc2_evp_test(size_t test_number, const struct rc2_test *rt, const char *label,
676     const EVP_CIPHER *cipher)
677 {
678 	EVP_CIPHER_CTX *ctx;
679 	uint8_t out[512];
680 	int in_len, out_len, total_len;
681 	int i;
682 	int success = 0;
683 
684 	if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
685 		fprintf(stderr, "FAIL (%s:%zu): EVP_CIPHER_CTX_new failed\n",
686 		    label, test_number);
687 		goto failed;
688 	}
689 
690 	/* EVP encryption */
691 	total_len = 0;
692 	memset(out, 0, sizeof(out));
693 	if (!EVP_EncryptInit(ctx, cipher, NULL, NULL)) {
694 		fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptInit failed\n",
695 		    label, test_number);
696 		goto failed;
697 	}
698 
699 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS,
700 	    rt->key_bits, NULL) <= 0) {
701 		fprintf(stderr, "FAIL (%s:%zu): EVP_CIPHER_CTX_ctrl failed\n",
702 		    label, test_number);
703 		goto failed;
704 	}
705 
706 	if (!EVP_CIPHER_CTX_set_key_length(ctx, rt->key_len)) {
707 		fprintf(stderr,
708 		    "FAIL (%s:%zu): EVP_CIPHER_CTX_set_key_length failed\n",
709 		    label, test_number);
710 		goto failed;
711 	}
712 
713 	if (!EVP_CIPHER_CTX_set_padding(ctx, rt->padding)) {
714 		fprintf(stderr,
715 		    "FAIL (%s:%zu): EVP_CIPHER_CTX_set_padding failed\n",
716 		    label, test_number);
717 		goto failed;
718 	}
719 
720 	if (!EVP_EncryptInit(ctx, NULL, rt->key, rt->iv)) {
721 		fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptInit failed\n",
722 		    label, test_number);
723 		goto failed;
724 	}
725 
726 	for (i = 0; i < rt->in_len;) {
727 		in_len = arc4random_uniform(rt->in_len / 2);
728 		if (in_len > rt->in_len - i)
729 			in_len = rt->in_len - i;
730 
731 		if (!EVP_EncryptUpdate(ctx, out + total_len, &out_len,
732 		    rt->in + i, in_len)) {
733 			fprintf(stderr,
734 			    "FAIL (%s:%zu): EVP_EncryptUpdate failed\n",
735 			    label, test_number);
736 			goto failed;
737 		}
738 
739 		i += in_len;
740 		total_len += out_len;
741 	}
742 
743 	if (!EVP_EncryptFinal_ex(ctx, out + out_len, &out_len)) {
744 		fprintf(stderr, "FAIL (%s:%zu): EVP_EncryptFinal_ex failed\n",
745 		    label, test_number);
746 		goto failed;
747 	}
748 	total_len += out_len;
749 
750 	if (!EVP_CIPHER_CTX_reset(ctx)) {
751 		fprintf(stderr,
752 		    "FAIL (%s:%zu): EVP_CIPHER_CTX_reset failed\n",
753 		    label, test_number);
754 		goto failed;
755 	}
756 
757 	if (total_len != rt->out_len) {
758 		fprintf(stderr,
759 		    "FAIL (%s:%zu): EVP encryption length mismatch\n",
760 		    label, test_number);
761 		goto failed;
762 	}
763 
764 	if (memcmp(rt->out, out, rt->out_len) != 0) {
765 		fprintf(stderr, "FAIL (%s:%zu): EVP encryption mismatch\n",
766 		    label, test_number);
767 		goto failed;
768 	}
769 
770 	/* EVP decryption */
771 	total_len = 0;
772 	memset(out, 0, sizeof(out));
773 	if (!EVP_DecryptInit(ctx, cipher, NULL, NULL)) {
774 		fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptInit failed\n",
775 		    label, test_number);
776 		goto failed;
777 	}
778 
779 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS,
780 	    rt->key_bits, NULL) <= 0) {
781 		fprintf(stderr, "FAIL (%s:%zu): EVP_CIPHER_CTX_ctrl failed\n",
782 		    label, test_number);
783 		goto failed;
784 	}
785 
786 	if (!EVP_CIPHER_CTX_set_key_length(ctx, rt->key_len)) {
787 		fprintf(stderr,
788 		    "FAIL (%s:%zu): EVP_CIPHER_CTX_set_key_length failed\n",
789 		    label, test_number);
790 		goto failed;
791 	}
792 
793 	if (!EVP_CIPHER_CTX_set_padding(ctx, rt->padding)) {
794 		fprintf(stderr,
795 		    "FAIL (%s:%zu): EVP_CIPHER_CTX_set_padding failed\n",
796 		    label, test_number);
797 		goto failed;
798 	}
799 
800 	if (!EVP_DecryptInit(ctx, NULL, rt->key, rt->iv)) {
801 		fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptInit failed\n",
802 		    label, test_number);
803 		goto failed;
804 	}
805 
806 	for (i = 0; i < rt->out_len;) {
807 		in_len = arc4random_uniform(rt->out_len / 2);
808 		if (in_len > rt->out_len - i)
809 			in_len = rt->out_len - i;
810 
811 		if (!EVP_DecryptUpdate(ctx, out + total_len, &out_len,
812 		    rt->out + i, in_len)) {
813 			fprintf(stderr,
814 			    "FAIL (%s:%zu): EVP_DecryptUpdate failed\n",
815 			    label, test_number);
816 			goto failed;
817 		}
818 
819 		i += in_len;
820 		total_len += out_len;
821 	}
822 
823 	if (!EVP_DecryptFinal_ex(ctx, out + total_len, &out_len)) {
824 		fprintf(stderr, "FAIL (%s:%zu): EVP_DecryptFinal_ex failed\n",
825 		    label, test_number);
826 		goto failed;
827 	}
828 	total_len += out_len;
829 
830 	if (!EVP_CIPHER_CTX_reset(ctx)) {
831 		fprintf(stderr,
832 		    "FAIL (%s:%zu): EVP_CIPHER_CTX_reset failed\n",
833 		    label, test_number);
834 		goto failed;
835 	}
836 
837 	if (total_len != rt->in_len) {
838 		fprintf(stderr,
839 		    "FAIL (%s:%zu): EVP decryption length mismatch\n",
840 		    label, test_number);
841 		goto failed;
842 	}
843 
844 	if (memcmp(rt->in, out, rt->in_len) != 0) {
845 		fprintf(stderr, "FAIL (%s:%zu): EVP decryption mismatch\n",
846 		    label, test_number);
847 		goto failed;
848 	}
849 
850 	success = 1;
851 
852  failed:
853 	EVP_CIPHER_CTX_free(ctx);
854 	return success;
855 }
856 
857 static int
rc2_test(void)858 rc2_test(void)
859 {
860 	const struct rc2_test *rt;
861 	const char *label;
862 	const EVP_CIPHER *cipher;
863 	size_t i;
864 	int failed = 1;
865 
866 	for (i = 0; i < N_RC2_TESTS; i++) {
867 		rt = &rc2_tests[i];
868 		switch (rt->mode) {
869 		case NID_rc2_ecb:
870 			label = SN_rc2_ecb;
871 			cipher = EVP_rc2_ecb();
872 			if (!rc2_ecb_test(i, rt))
873 				goto failed;
874 			break;
875 		case NID_rc2_cbc:
876 			label = SN_rc2_cbc;
877 			cipher = EVP_rc2_cbc();
878 			if (!rc2_cbc_test(i, rt))
879 				goto failed;
880 			break;
881 		case NID_rc2_cfb64:
882 			label = SN_rc2_cfb64;
883 			cipher = EVP_rc2_cfb64();
884 			if (!rc2_cfb64_test(i, rt))
885 				goto failed;
886 			break;
887 		case NID_rc2_ofb64:
888 			label = SN_rc2_ofb64;
889 			cipher = EVP_rc2_ofb();
890 			if (!rc2_ofb64_test(i, rt))
891 				goto failed;
892 			break;
893 		default:
894 			fprintf(stderr, "FAIL: unknown mode (%d)\n",
895 			    rt->mode);
896 			goto failed;
897 		}
898 
899 		if (!rc2_evp_test(i, rt, label, cipher))
900 			goto failed;
901 	}
902 
903 	failed = 0;
904 
905  failed:
906 	return failed;
907 }
908 
909 int
main(int argc,char ** argv)910 main(int argc, char **argv)
911 {
912 	int failed = 0;
913 
914 	failed |= rc2_test();
915 
916 	return failed;
917 }
918