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 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 472 main(int argc, char **argv) 473 { 474 int failed = 0; 475 476 failed |= rc4_test(); 477 478 return failed; 479 } 480