blob: dc42dd59962428fc95c617905744b90d27f6c6f0 [file] [log] [blame]
Adam Langleycc8fcf42014-08-21 10:48:32 -07001/* 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 Benjamin98193672016-03-25 18:07:11 -040058#include <openssl/nid.h>
Adam Langleycc8fcf42014-08-21 10:48:32 -070059
Adam Langleycc8fcf42014-08-21 10:48:32 -070060
David Benjaminb1133e92016-10-18 13:05:01 -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 Langleycc8fcf42014-08-21 10:48:32 -070068
David Benjaminb1133e92016-10-18 13:05:01 -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 Langleycc8fcf42014-08-21 10:48:32 -070092
David Benjaminb1133e92016-10-18 13:05:01 -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 Langleycc8fcf42014-08-21 10:48:32 -0700100
David Benjaminb1133e92016-10-18 13:05:01 -0400101#define l2cn(l1, l2, c, n) \
102 do { \
103 (c) += (n); \
104 switch (n) { \
105 case 8: \
Adam Langleycc8fcf42014-08-21 10:48:32 -0700106 *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
David Benjaminb1133e92016-10-18 13:05:01 -0400107 case 7: \
Adam Langleycc8fcf42014-08-21 10:48:32 -0700108 *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
David Benjaminb1133e92016-10-18 13:05:01 -0400109 case 6: \
Adam Langleycc8fcf42014-08-21 10:48:32 -0700110 *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \
David Benjaminb1133e92016-10-18 13:05:01 -0400111 case 5: \
Adam Langleycc8fcf42014-08-21 10:48:32 -0700112 *(--(c)) = (uint8_t)(((l2)) & 0xff); \
David Benjaminb1133e92016-10-18 13:05:01 -0400113 case 4: \
Adam Langleycc8fcf42014-08-21 10:48:32 -0700114 *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
David Benjaminb1133e92016-10-18 13:05:01 -0400115 case 3: \
Adam Langleycc8fcf42014-08-21 10:48:32 -0700116 *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
David Benjaminb1133e92016-10-18 13:05:01 -0400117 case 2: \
Adam Langleycc8fcf42014-08-21 10:48:32 -0700118 *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \
David Benjaminb1133e92016-10-18 13:05:01 -0400119 case 1: \
Adam Langleycc8fcf42014-08-21 10:48:32 -0700120 *(--(c)) = (uint8_t)(((l1)) & 0xff); \
David Benjaminb1133e92016-10-18 13:05:01 -0400121 } \
122 } while (0)
Adam Langleycc8fcf42014-08-21 10:48:32 -0700123
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 }
Adam Langleycc8fcf42014-08-21 10:48:32 -0700285 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];
David Benjamin808f8322017-08-18 14:06:02 -0400320 *k = 0; // for if there is a zero length key
Adam Langleycc8fcf42014-08-21 10:48:32 -0700321
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
David Benjamin808f8322017-08-18 14:06:02 -0400336 // expand table
Adam Langleycc8fcf42014-08-21 10:48:32 -0700337 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
David Benjamin808f8322017-08-18 14:06:02 -0400344 // hmm.... key reduction to 'bits' bits
Adam Langleycc8fcf42014-08-21 10:48:32 -0700345
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
David Benjamin808f8322017-08-18 14:06:02 -0400357 // copy from bytes into uint16_t's
Adam Langleycc8fcf42014-08-21 10:48:32 -0700358 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 {
David Benjamin808f8322017-08-18 14:06:02 -0400365 int key_bits; // effective key bits
366 RC2_KEY ks; // key schedule
Adam Langleycc8fcf42014-08-21 10:48:32 -0700367} 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;
Matt Braithwaitef92930e2015-08-04 14:44:53 -0700401 case EVP_CTRL_SET_RC2_KEY_BITS:
David Benjamin808f8322017-08-18 14:06:02 -0400402 // Should be overridden by later call to |EVP_CTRL_INIT|, but
403 // people call it, so it may as well work.
Matt Braithwaitef92930e2015-08-04 14:44:53 -0700404 key->key_bits = arg;
405 return 1;
Adam Langleycc8fcf42014-08-21 10:48:32 -0700406
407 default:
408 return -1;
409 }
410}
411
Matt Braithwaitef92930e2015-08-04 14:44:53 -0700412static const EVP_CIPHER rc2_40_cbc = {
Adam Langleycc8fcf42014-08-21 10:48:32 -0700413 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
Brian Smithefed2212015-01-28 16:20:02 -0800426const EVP_CIPHER *EVP_rc2_40_cbc(void) {
Matt Braithwaitef92930e2015-08-04 14:44:53 -0700427 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 Langleycc8fcf42014-08-21 10:48:32 -0700446}