1 /* 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>
58 #include <openssl/obj.h>
59
60 #include "internal.h"
61
62
63 #define c2l(c, l) \
64 (l = ((uint32_t)(*((c)++))), l |= ((uint32_t)(*((c)++))) << 8L, \
65 l |= ((uint32_t)(*((c)++))) << 16L, \
66 l |= ((uint32_t)(*((c)++))) << 24L)
67
68 #define c2ln(c, l1, l2, n) \
69 { \
70 c += n; \
71 l1 = l2 = 0; \
72 switch (n) { \
73 case 8: \
74 l2 = ((uint32_t)(*(--(c)))) << 24L; \
75 case 7: \
76 l2 |= ((uint32_t)(*(--(c)))) << 16L; \
77 case 6: \
78 l2 |= ((uint32_t)(*(--(c)))) << 8L; \
79 case 5: \
80 l2 |= ((uint32_t)(*(--(c)))); \
81 case 4: \
82 l1 = ((uint32_t)(*(--(c)))) << 24L; \
83 case 3: \
84 l1 |= ((uint32_t)(*(--(c)))) << 16L; \
85 case 2: \
86 l1 |= ((uint32_t)(*(--(c)))) << 8L; \
87 case 1: \
88 l1 |= ((uint32_t)(*(--(c)))); \
89 } \
90 }
91
92 #define l2c(l, c) \
93 (*((c)++) = (uint8_t)(((l)) & 0xff), \
94 *((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \
95 *((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \
96 *((c)++) = (uint8_t)(((l) >> 24L) & 0xff))
97
98 #define l2cn(l1, l2, c, n) \
99 { \
100 c += n; \
101 switch (n) { \
102 case 8: \
103 *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
104 case 7: \
105 *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
106 case 6: \
107 *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \
108 case 5: \
109 *(--(c)) = (uint8_t)(((l2)) & 0xff); \
110 case 4: \
111 *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
112 case 3: \
113 *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
114 case 2: \
115 *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \
116 case 1: \
117 *(--(c)) = (uint8_t)(((l1)) & 0xff); \
118 } \
119 }
120
121 typedef struct rc2_key_st { uint16_t data[64]; } RC2_KEY;
122
RC2_encrypt(uint32_t * d,RC2_KEY * key)123 static void RC2_encrypt(uint32_t *d, RC2_KEY *key) {
124 int i, n;
125 uint16_t *p0, *p1;
126 uint16_t x0, x1, x2, x3, t;
127 uint32_t l;
128
129 l = d[0];
130 x0 = (uint16_t)l & 0xffff;
131 x1 = (uint16_t)(l >> 16L);
132 l = d[1];
133 x2 = (uint16_t)l & 0xffff;
134 x3 = (uint16_t)(l >> 16L);
135
136 n = 3;
137 i = 5;
138
139 p0 = p1 = &key->data[0];
140 for (;;) {
141 t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff;
142 x0 = (t << 1) | (t >> 15);
143 t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff;
144 x1 = (t << 2) | (t >> 14);
145 t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff;
146 x2 = (t << 3) | (t >> 13);
147 t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff;
148 x3 = (t << 5) | (t >> 11);
149
150 if (--i == 0) {
151 if (--n == 0) {
152 break;
153 }
154 i = (n == 2) ? 6 : 5;
155
156 x0 += p1[x3 & 0x3f];
157 x1 += p1[x0 & 0x3f];
158 x2 += p1[x1 & 0x3f];
159 x3 += p1[x2 & 0x3f];
160 }
161 }
162
163 d[0] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L);
164 d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L);
165 }
166
RC2_decrypt(uint32_t * d,RC2_KEY * key)167 static void RC2_decrypt(uint32_t *d, RC2_KEY *key) {
168 int i, n;
169 uint16_t *p0, *p1;
170 uint16_t x0, x1, x2, x3, t;
171 uint32_t l;
172
173 l = d[0];
174 x0 = (uint16_t)l & 0xffff;
175 x1 = (uint16_t)(l >> 16L);
176 l = d[1];
177 x2 = (uint16_t)l & 0xffff;
178 x3 = (uint16_t)(l >> 16L);
179
180 n = 3;
181 i = 5;
182
183 p0 = &key->data[63];
184 p1 = &key->data[0];
185 for (;;) {
186 t = ((x3 << 11) | (x3 >> 5)) & 0xffff;
187 x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff;
188 t = ((x2 << 13) | (x2 >> 3)) & 0xffff;
189 x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff;
190 t = ((x1 << 14) | (x1 >> 2)) & 0xffff;
191 x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff;
192 t = ((x0 << 15) | (x0 >> 1)) & 0xffff;
193 x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff;
194
195 if (--i == 0) {
196 if (--n == 0) {
197 break;
198 }
199 i = (n == 2) ? 6 : 5;
200
201 x3 = (x3 - p1[x2 & 0x3f]) & 0xffff;
202 x2 = (x2 - p1[x1 & 0x3f]) & 0xffff;
203 x1 = (x1 - p1[x0 & 0x3f]) & 0xffff;
204 x0 = (x0 - p1[x3 & 0x3f]) & 0xffff;
205 }
206 }
207
208 d[0] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L);
209 d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L);
210 }
211
RC2_cbc_encrypt(const uint8_t * in,uint8_t * out,size_t length,RC2_KEY * ks,uint8_t * iv,int encrypt)212 static void RC2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
213 RC2_KEY *ks, uint8_t *iv, int encrypt) {
214 uint32_t tin0, tin1;
215 uint32_t tout0, tout1, xor0, xor1;
216 long l = length;
217 uint32_t tin[2];
218
219 if (encrypt) {
220 c2l(iv, tout0);
221 c2l(iv, tout1);
222 iv -= 8;
223 for (l -= 8; l >= 0; l -= 8) {
224 c2l(in, tin0);
225 c2l(in, tin1);
226 tin0 ^= tout0;
227 tin1 ^= tout1;
228 tin[0] = tin0;
229 tin[1] = tin1;
230 RC2_encrypt(tin, ks);
231 tout0 = tin[0];
232 l2c(tout0, out);
233 tout1 = tin[1];
234 l2c(tout1, out);
235 }
236 if (l != -8) {
237 c2ln(in, tin0, tin1, l + 8);
238 tin0 ^= tout0;
239 tin1 ^= tout1;
240 tin[0] = tin0;
241 tin[1] = tin1;
242 RC2_encrypt(tin, ks);
243 tout0 = tin[0];
244 l2c(tout0, out);
245 tout1 = tin[1];
246 l2c(tout1, out);
247 }
248 l2c(tout0, iv);
249 l2c(tout1, iv);
250 } else {
251 c2l(iv, xor0);
252 c2l(iv, xor1);
253 iv -= 8;
254 for (l -= 8; l >= 0; l -= 8) {
255 c2l(in, tin0);
256 tin[0] = tin0;
257 c2l(in, tin1);
258 tin[1] = tin1;
259 RC2_decrypt(tin, ks);
260 tout0 = tin[0] ^ xor0;
261 tout1 = tin[1] ^ xor1;
262 l2c(tout0, out);
263 l2c(tout1, out);
264 xor0 = tin0;
265 xor1 = tin1;
266 }
267 if (l != -8) {
268 c2l(in, tin0);
269 tin[0] = tin0;
270 c2l(in, tin1);
271 tin[1] = tin1;
272 RC2_decrypt(tin, ks);
273 tout0 = tin[0] ^ xor0;
274 tout1 = tin[1] ^ xor1;
275 l2cn(tout0, tout1, out, l + 8);
276 xor0 = tin0;
277 xor1 = tin1;
278 }
279 l2c(xor0, iv);
280 l2c(xor1, iv);
281 }
282 tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
283 tin[0] = tin[1] = 0;
284 }
285
286 static const uint8_t key_table[256] = {
287 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79,
288 0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
289 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5,
290 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
291 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22,
292 0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
293 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f,
294 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
295 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b,
296 0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
297 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde,
298 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
299 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e,
300 0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
301 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85,
302 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
303 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10,
304 0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
305 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b,
306 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
307 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68,
308 0xfe, 0x7f, 0xc1, 0xad,
309 };
310
RC2_set_key(RC2_KEY * key,int len,const uint8_t * data,int bits)311 static void RC2_set_key(RC2_KEY *key, int len, const uint8_t *data, int bits) {
312 int i, j;
313 uint8_t *k;
314 uint16_t *ki;
315 unsigned int c, d;
316
317 k = (uint8_t *)&key->data[0];
318 *k = 0; /* for if there is a zero length key */
319
320 if (len > 128) {
321 len = 128;
322 }
323 if (bits <= 0) {
324 bits = 1024;
325 }
326 if (bits > 1024) {
327 bits = 1024;
328 }
329
330 for (i = 0; i < len; i++) {
331 k[i] = data[i];
332 }
333
334 /* expand table */
335 d = k[len - 1];
336 j = 0;
337 for (i = len; i < 128; i++, j++) {
338 d = key_table[(k[j] + d) & 0xff];
339 k[i] = d;
340 }
341
342 /* hmm.... key reduction to 'bits' bits */
343
344 j = (bits + 7) >> 3;
345 i = 128 - j;
346 c = (0xff >> (-bits & 0x07));
347
348 d = key_table[k[i] & c];
349 k[i] = d;
350 while (i--) {
351 d = key_table[k[i + j] ^ d];
352 k[i] = d;
353 }
354
355 /* copy from bytes into uint16_t's */
356 ki = &(key->data[63]);
357 for (i = 127; i >= 0; i -= 2) {
358 *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff;
359 }
360 }
361
362 typedef struct {
363 int key_bits; /* effective key bits */
364 RC2_KEY ks; /* key schedule */
365 } EVP_RC2_KEY;
366
rc2_init_key(EVP_CIPHER_CTX * ctx,const uint8_t * key,const uint8_t * iv,int enc)367 static int rc2_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
368 const uint8_t *iv, int enc) {
369 EVP_RC2_KEY *rc2_key = (EVP_RC2_KEY *)ctx->cipher_data;
370 RC2_set_key(&rc2_key->ks, EVP_CIPHER_CTX_key_length(ctx), key,
371 rc2_key->key_bits);
372 return 1;
373 }
374
rc2_cbc_cipher(EVP_CIPHER_CTX * ctx,uint8_t * out,const uint8_t * in,size_t inl)375 static int rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
376 size_t inl) {
377 EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data;
378 static const size_t kChunkSize = 0x10000;
379
380 while (inl >= kChunkSize) {
381 RC2_cbc_encrypt(in, out, kChunkSize, &key->ks, ctx->iv, ctx->encrypt);
382 inl -= kChunkSize;
383 in += kChunkSize;
384 out += kChunkSize;
385 }
386 if (inl) {
387 RC2_cbc_encrypt(in, out, inl, &key->ks, ctx->iv, ctx->encrypt);
388 }
389 return 1;
390 }
391
rc2_ctrl(EVP_CIPHER_CTX * ctx,int type,int arg,void * ptr)392 static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) {
393 EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data;
394
395 switch (type) {
396 case EVP_CTRL_INIT:
397 key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
398 return 1;
399
400 default:
401 return -1;
402 }
403 }
404
405 static const EVP_CIPHER rc2_40_cbc_cipher = {
406 NID_rc2_40_cbc,
407 8 /* block size */,
408 5 /* 40 bit */,
409 8 /* iv len */,
410 sizeof(EVP_RC2_KEY),
411 EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
412 NULL /* app_data */,
413 rc2_init_key,
414 rc2_cbc_cipher,
415 NULL,
416 rc2_ctrl,
417 };
418
EVP_rc2_40_cbc()419 const EVP_CIPHER *EVP_rc2_40_cbc() {
420 return &rc2_40_cbc_cipher;
421 }
422