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