blob: a18229c9e0a80798d4cbab750871b37c6fc576aa [file] [log] [blame]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57#include <openssl/cipher.h>
David Benjamin4969cc92016-04-22 15:02:23 -040058#include <openssl/nid.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080059
Adam Langleyd9e397b2015-01-22 14:27:53 -080060
David Benjamin95add822016-10-19 01:09:12 -040061#define c2l(c, l) \
62 do { \
63 (l) = ((uint32_t)(*((c)++))); \
64 (l) |= ((uint32_t)(*((c)++))) << 8L; \
65 (l) |= ((uint32_t)(*((c)++))) << 16L; \
66 (l) |= ((uint32_t)(*((c)++))) << 24L; \
67 } while (0)
Adam Langleyd9e397b2015-01-22 14:27:53 -080068
David Benjamin95add822016-10-19 01:09:12 -040069#define c2ln(c, l1, l2, n) \
70 do { \
71 (c) += (n); \
72 (l1) = (l2) = 0; \
73 switch (n) { \
74 case 8: \
75 (l2) = ((uint32_t)(*(--(c)))) << 24L; \
76 case 7: \
77 (l2) |= ((uint32_t)(*(--(c)))) << 16L; \
78 case 6: \
79 (l2) |= ((uint32_t)(*(--(c)))) << 8L; \
80 case 5: \
81 (l2) |= ((uint32_t)(*(--(c)))); \
82 case 4: \
83 (l1) = ((uint32_t)(*(--(c)))) << 24L; \
84 case 3: \
85 (l1) |= ((uint32_t)(*(--(c)))) << 16L; \
86 case 2: \
87 (l1) |= ((uint32_t)(*(--(c)))) << 8L; \
88 case 1: \
89 (l1) |= ((uint32_t)(*(--(c)))); \
90 } \
91 } while (0)
Adam Langleyd9e397b2015-01-22 14:27:53 -080092
David Benjamin95add822016-10-19 01:09:12 -040093#define l2c(l, c) \
94 do { \
95 *((c)++) = (uint8_t)(((l)) & 0xff); \
96 *((c)++) = (uint8_t)(((l) >> 8L) & 0xff); \
97 *((c)++) = (uint8_t)(((l) >> 16L) & 0xff); \
98 *((c)++) = (uint8_t)(((l) >> 24L) & 0xff); \
99 } while (0)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800100
David Benjamin95add822016-10-19 01:09:12 -0400101#define l2cn(l1, l2, c, n) \
102 do { \
103 (c) += (n); \
104 switch (n) { \
105 case 8: \
Adam Langleyd9e397b2015-01-22 14:27:53 -0800106 *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
David Benjamin95add822016-10-19 01:09:12 -0400107 case 7: \
Adam Langleyd9e397b2015-01-22 14:27:53 -0800108 *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
David Benjamin95add822016-10-19 01:09:12 -0400109 case 6: \
Adam Langleyd9e397b2015-01-22 14:27:53 -0800110 *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \
David Benjamin95add822016-10-19 01:09:12 -0400111 case 5: \
Adam Langleyd9e397b2015-01-22 14:27:53 -0800112 *(--(c)) = (uint8_t)(((l2)) & 0xff); \
David Benjamin95add822016-10-19 01:09:12 -0400113 case 4: \
Adam Langleyd9e397b2015-01-22 14:27:53 -0800114 *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
David Benjamin95add822016-10-19 01:09:12 -0400115 case 3: \
Adam Langleyd9e397b2015-01-22 14:27:53 -0800116 *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
David Benjamin95add822016-10-19 01:09:12 -0400117 case 2: \
Adam Langleyd9e397b2015-01-22 14:27:53 -0800118 *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \
David Benjamin95add822016-10-19 01:09:12 -0400119 case 1: \
Adam Langleyd9e397b2015-01-22 14:27:53 -0800120 *(--(c)) = (uint8_t)(((l1)) & 0xff); \
David Benjamin95add822016-10-19 01:09:12 -0400121 } \
122 } while (0)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800123
124typedef struct rc2_key_st { uint16_t data[64]; } RC2_KEY;
125
126static void RC2_encrypt(uint32_t *d, RC2_KEY *key) {
127 int i, n;
128 uint16_t *p0, *p1;
129 uint16_t x0, x1, x2, x3, t;
130 uint32_t l;
131
132 l = d[0];
133 x0 = (uint16_t)l & 0xffff;
134 x1 = (uint16_t)(l >> 16L);
135 l = d[1];
136 x2 = (uint16_t)l & 0xffff;
137 x3 = (uint16_t)(l >> 16L);
138
139 n = 3;
140 i = 5;
141
142 p0 = p1 = &key->data[0];
143 for (;;) {
144 t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff;
145 x0 = (t << 1) | (t >> 15);
146 t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff;
147 x1 = (t << 2) | (t >> 14);
148 t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff;
149 x2 = (t << 3) | (t >> 13);
150 t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff;
151 x3 = (t << 5) | (t >> 11);
152
153 if (--i == 0) {
154 if (--n == 0) {
155 break;
156 }
157 i = (n == 2) ? 6 : 5;
158
159 x0 += p1[x3 & 0x3f];
160 x1 += p1[x0 & 0x3f];
161 x2 += p1[x1 & 0x3f];
162 x3 += p1[x2 & 0x3f];
163 }
164 }
165
166 d[0] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L);
167 d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L);
168}
169
170static void RC2_decrypt(uint32_t *d, RC2_KEY *key) {
171 int i, n;
172 uint16_t *p0, *p1;
173 uint16_t x0, x1, x2, x3, t;
174 uint32_t l;
175
176 l = d[0];
177 x0 = (uint16_t)l & 0xffff;
178 x1 = (uint16_t)(l >> 16L);
179 l = d[1];
180 x2 = (uint16_t)l & 0xffff;
181 x3 = (uint16_t)(l >> 16L);
182
183 n = 3;
184 i = 5;
185
186 p0 = &key->data[63];
187 p1 = &key->data[0];
188 for (;;) {
189 t = ((x3 << 11) | (x3 >> 5)) & 0xffff;
190 x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff;
191 t = ((x2 << 13) | (x2 >> 3)) & 0xffff;
192 x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff;
193 t = ((x1 << 14) | (x1 >> 2)) & 0xffff;
194 x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff;
195 t = ((x0 << 15) | (x0 >> 1)) & 0xffff;
196 x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff;
197
198 if (--i == 0) {
199 if (--n == 0) {
200 break;
201 }
202 i = (n == 2) ? 6 : 5;
203
204 x3 = (x3 - p1[x2 & 0x3f]) & 0xffff;
205 x2 = (x2 - p1[x1 & 0x3f]) & 0xffff;
206 x1 = (x1 - p1[x0 & 0x3f]) & 0xffff;
207 x0 = (x0 - p1[x3 & 0x3f]) & 0xffff;
208 }
209 }
210
211 d[0] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L);
212 d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L);
213}
214
215static void RC2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
216 RC2_KEY *ks, uint8_t *iv, int encrypt) {
217 uint32_t tin0, tin1;
218 uint32_t tout0, tout1, xor0, xor1;
219 long l = length;
220 uint32_t tin[2];
221
222 if (encrypt) {
223 c2l(iv, tout0);
224 c2l(iv, tout1);
225 iv -= 8;
226 for (l -= 8; l >= 0; l -= 8) {
227 c2l(in, tin0);
228 c2l(in, tin1);
229 tin0 ^= tout0;
230 tin1 ^= tout1;
231 tin[0] = tin0;
232 tin[1] = tin1;
233 RC2_encrypt(tin, ks);
234 tout0 = tin[0];
235 l2c(tout0, out);
236 tout1 = tin[1];
237 l2c(tout1, out);
238 }
239 if (l != -8) {
240 c2ln(in, tin0, tin1, l + 8);
241 tin0 ^= tout0;
242 tin1 ^= tout1;
243 tin[0] = tin0;
244 tin[1] = tin1;
245 RC2_encrypt(tin, ks);
246 tout0 = tin[0];
247 l2c(tout0, out);
248 tout1 = tin[1];
249 l2c(tout1, out);
250 }
251 l2c(tout0, iv);
252 l2c(tout1, iv);
253 } else {
254 c2l(iv, xor0);
255 c2l(iv, xor1);
256 iv -= 8;
257 for (l -= 8; l >= 0; l -= 8) {
258 c2l(in, tin0);
259 tin[0] = tin0;
260 c2l(in, tin1);
261 tin[1] = tin1;
262 RC2_decrypt(tin, ks);
263 tout0 = tin[0] ^ xor0;
264 tout1 = tin[1] ^ xor1;
265 l2c(tout0, out);
266 l2c(tout1, out);
267 xor0 = tin0;
268 xor1 = tin1;
269 }
270 if (l != -8) {
271 c2l(in, tin0);
272 tin[0] = tin0;
273 c2l(in, tin1);
274 tin[1] = tin1;
275 RC2_decrypt(tin, ks);
276 tout0 = tin[0] ^ xor0;
277 tout1 = tin[1] ^ xor1;
278 l2cn(tout0, tout1, out, l + 8);
279 xor0 = tin0;
280 xor1 = tin1;
281 }
282 l2c(xor0, iv);
283 l2c(xor1, iv);
284 }
285 tin[0] = tin[1] = 0;
286}
287
288static const uint8_t key_table[256] = {
289 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79,
290 0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
291 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5,
292 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
293 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22,
294 0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
295 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f,
296 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
297 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b,
298 0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
299 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde,
300 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
301 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e,
302 0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
303 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85,
304 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
305 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10,
306 0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
307 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b,
308 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
309 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68,
310 0xfe, 0x7f, 0xc1, 0xad,
311};
312
313static void RC2_set_key(RC2_KEY *key, int len, const uint8_t *data, int bits) {
314 int i, j;
315 uint8_t *k;
316 uint16_t *ki;
317 unsigned int c, d;
318
319 k = (uint8_t *)&key->data[0];
320 *k = 0; /* for if there is a zero length key */
321
322 if (len > 128) {
323 len = 128;
324 }
325 if (bits <= 0) {
326 bits = 1024;
327 }
328 if (bits > 1024) {
329 bits = 1024;
330 }
331
332 for (i = 0; i < len; i++) {
333 k[i] = data[i];
334 }
335
336 /* expand table */
337 d = k[len - 1];
338 j = 0;
339 for (i = len; i < 128; i++, j++) {
340 d = key_table[(k[j] + d) & 0xff];
341 k[i] = d;
342 }
343
344 /* hmm.... key reduction to 'bits' bits */
345
346 j = (bits + 7) >> 3;
347 i = 128 - j;
348 c = (0xff >> (-bits & 0x07));
349
350 d = key_table[k[i] & c];
351 k[i] = d;
352 while (i--) {
353 d = key_table[k[i + j] ^ d];
354 k[i] = d;
355 }
356
357 /* copy from bytes into uint16_t's */
358 ki = &(key->data[63]);
359 for (i = 127; i >= 0; i -= 2) {
360 *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff;
361 }
362}
363
364typedef struct {
365 int key_bits; /* effective key bits */
366 RC2_KEY ks; /* key schedule */
367} EVP_RC2_KEY;
368
369static int rc2_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
370 const uint8_t *iv, int enc) {
371 EVP_RC2_KEY *rc2_key = (EVP_RC2_KEY *)ctx->cipher_data;
372 RC2_set_key(&rc2_key->ks, EVP_CIPHER_CTX_key_length(ctx), key,
373 rc2_key->key_bits);
374 return 1;
375}
376
377static int rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
378 size_t inl) {
379 EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data;
380 static const size_t kChunkSize = 0x10000;
381
382 while (inl >= kChunkSize) {
383 RC2_cbc_encrypt(in, out, kChunkSize, &key->ks, ctx->iv, ctx->encrypt);
384 inl -= kChunkSize;
385 in += kChunkSize;
386 out += kChunkSize;
387 }
388 if (inl) {
389 RC2_cbc_encrypt(in, out, inl, &key->ks, ctx->iv, ctx->encrypt);
390 }
391 return 1;
392}
393
394static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) {
395 EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data;
396
397 switch (type) {
398 case EVP_CTRL_INIT:
399 key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
400 return 1;
Kenny Rootb8494592015-09-25 02:29:14 +0000401 case EVP_CTRL_SET_RC2_KEY_BITS:
402 /* Should be overridden by later call to |EVP_CTRL_INIT|, but
403 * people call it, so it may as well work. */
404 key->key_bits = arg;
405 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800406
407 default:
408 return -1;
409 }
410}
411
Kenny Rootb8494592015-09-25 02:29:14 +0000412static const EVP_CIPHER rc2_40_cbc = {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800413 NID_rc2_40_cbc,
414 8 /* block size */,
415 5 /* 40 bit */,
416 8 /* iv len */,
417 sizeof(EVP_RC2_KEY),
418 EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
419 NULL /* app_data */,
420 rc2_init_key,
421 rc2_cbc_cipher,
422 NULL,
423 rc2_ctrl,
424};
425
426const EVP_CIPHER *EVP_rc2_40_cbc(void) {
Kenny Rootb8494592015-09-25 02:29:14 +0000427 return &rc2_40_cbc;
428}
429
430static const EVP_CIPHER rc2_cbc = {
431 NID_rc2_cbc,
432 8 /* block size */,
433 16 /* 128 bit */,
434 8 /* iv len */,
435 sizeof(EVP_RC2_KEY),
436 EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
437 NULL /* app_data */,
438 rc2_init_key,
439 rc2_cbc_cipher,
440 NULL,
441 rc2_ctrl,
442};
443
444const EVP_CIPHER *EVP_rc2_cbc(void) {
445 return &rc2_cbc;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800446}