1 /* $OpenBSD: rc2_test.c,v 1.1 2022/09/06 15:36:25 tb 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 int len; 30 const uint8_t in[8]; 31 const uint8_t out[8]; 32 }; 33 34 static const struct rc2_test rc2_tests[] = { 35 /* ECB (Test vectors from RFC 2268) */ 36 { 37 .mode = NID_rc2_ecb, 38 .key = { 39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 }, 41 .key_len = 8, 42 .key_bits = 63, 43 .len = 8, 44 .in = { 45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 }, 47 .out = { 48 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff, 49 }, 50 }, 51 { 52 .mode = NID_rc2_ecb, 53 .key = { 54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 55 }, 56 .key_len = 8, 57 .key_bits = 64, 58 .len = 8, 59 .in = { 60 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 61 }, 62 .out = { 63 0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49, 64 }, 65 }, 66 { 67 .mode = NID_rc2_ecb, 68 .key = { 69 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 }, 71 .key_len = 8, 72 .key_bits = 64, 73 .len = 8, 74 .in = { 75 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 76 }, 77 .out = { 78 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2, 79 }, 80 }, 81 { 82 .mode = NID_rc2_ecb, 83 .key = { 84 0x88, 85 }, 86 .key_len = 1, 87 .key_bits = 64, 88 .len = 8, 89 .in = { 90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 }, 92 .out = { 93 0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0, 94 }, 95 }, 96 { 97 .mode = NID_rc2_ecb, 98 .key = { 99 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 100 }, 101 .key_len = 7, 102 .key_bits = 64, 103 .len = 8, 104 .in = { 105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 106 }, 107 .out = { 108 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f, 109 }, 110 }, 111 { 112 .mode = NID_rc2_ecb, 113 .key = { 114 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, 115 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2, 116 }, 117 .key_len = 16, 118 .key_bits = 64, 119 .len = 8, 120 .in = { 121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 122 }, 123 .out = { 124 0x1a, 0x80, 0x7d, 0x27, 0x2b, 0xbe, 0x5d, 0xb1, 125 }, 126 }, 127 { 128 .mode = NID_rc2_ecb, 129 .key = { 130 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, 131 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2, 132 }, 133 .key_len = 16, 134 .key_bits = 128, 135 .len = 8, 136 .in = { 137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 }, 139 .out = { 140 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6, 141 }, 142 }, 143 { 144 .mode = NID_rc2_ecb, 145 .key = { 146 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, 147 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2, 148 0x16, 0xf8, 0x0a, 0x6f, 0x85, 0x92, 0x05, 0x84, 149 0xc4, 0x2f, 0xce, 0xb0, 0xbe, 0x25, 0x5d, 0xaf, 150 0x1e, 151 }, 152 .key_len = 33, 153 .key_bits = 129, 154 .len = 8, 155 .in = { 156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 157 }, 158 .out = { 159 0x5b, 0x78, 0xd3, 0xa4, 0x3d, 0xff, 0xf1, 0xf1, 160 }, 161 }, 162 163 /* ECB (Test vectors from http://websites.umich.edu/~x509/ssleay/rrc2.html) */ 164 { 165 .mode = NID_rc2_ecb, 166 .key = { 167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169 }, 170 .key_len = 16, 171 .len = 8, 172 .in = { 173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 174 }, 175 .out = { 176 0x1c, 0x19, 0x8a, 0x83, 0x8d, 0xf0, 0x28, 0xb7, 177 }, 178 }, 179 { 180 .mode = NID_rc2_ecb, 181 .key = { 182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 184 }, 185 .key_len = 16, 186 .len = 8, 187 .in = { 188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 189 }, 190 .out = { 191 0x21, 0x82, 0x9C, 0x78, 0xA9, 0xF9, 0xC0, 0x74, 192 }, 193 }, 194 { 195 .mode = NID_rc2_ecb, 196 .key = { 197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 199 }, 200 .key_len = 16, 201 .len = 8, 202 .in = { 203 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 204 }, 205 .out = { 206 0x13, 0xdb, 0x35, 0x17, 0xd3, 0x21, 0x86, 0x9e, 207 }, 208 }, 209 { 210 .mode = NID_rc2_ecb, 211 .key = { 212 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 213 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 214 }, 215 .key_len = 16, 216 .len = 8, 217 .in = { 218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 219 }, 220 .out = { 221 0x50, 0xdc, 0x01, 0x62, 0xbd, 0x75, 0x7f, 0x31, 222 }, 223 }, 224 }; 225 226 #define N_RC2_TESTS (sizeof(rc2_tests) / sizeof(rc2_tests[0])) 227 228 static int 229 rc2_ecb_test(size_t test_number, const struct rc2_test *rt) 230 { 231 RC2_KEY key; 232 uint8_t out[8]; 233 234 /* Encryption */ 235 memset(out, 0, sizeof(out)); 236 RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); 237 RC2_ecb_encrypt(rt->in, out, &key, 1); 238 239 if (memcmp(rt->out, out, rt->len) != 0) { 240 fprintf(stderr, "FAIL (%s:%zu): encryption mismatch\n", 241 SN_rc2_ecb, test_number); 242 return 0; 243 } 244 245 /* Decryption */ 246 memset(out, 0, sizeof(out)); 247 RC2_set_key(&key, rt->key_len, rt->key, rt->key_bits); 248 RC2_ecb_encrypt(rt->out, out, &key, 0); 249 250 if (memcmp(rt->in, out, rt->len) != 0) { 251 fprintf(stderr, "FAIL (%s:%zu): decryption mismatch\n", 252 SN_rc2_ecb, test_number); 253 return 0; 254 } 255 256 return 1; 257 } 258 259 static int 260 rc2_test(void) 261 { 262 const struct rc2_test *rt; 263 size_t i; 264 int failed = 1; 265 266 for (i = 0; i < N_RC2_TESTS; i++) { 267 rt = &rc2_tests[i]; 268 switch (rt->mode) { 269 case NID_rc2_ecb: 270 if (!rc2_ecb_test(i, rt)) 271 goto failed; 272 break; 273 default: 274 fprintf(stderr, "FAIL: unknown mode (%d)\n", 275 rt->mode); 276 goto failed; 277 } 278 } 279 280 failed = 0; 281 282 failed: 283 return failed; 284 } 285 286 int 287 main(int argc, char **argv) 288 { 289 int failed = 0; 290 291 failed |= rc2_test(); 292 293 return failed; 294 } 295