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 tin[0] = tin[1] = 0;
283 }
284
285 static const uint8_t key_table[256] = {
286 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79,
287 0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
288 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5,
289 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
290 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22,
291 0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
292 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f,
293 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
294 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b,
295 0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
296 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde,
297 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
298 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e,
299 0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
300 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85,
301 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
302 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10,
303 0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
304 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b,
305 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
306 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68,
307 0xfe, 0x7f, 0xc1, 0xad,
308 };
309
RC2_set_key(RC2_KEY * key,int len,const uint8_t * data,int bits)310 static void RC2_set_key(RC2_KEY *key, int len, const uint8_t *data, int bits) {
311 int i, j;
312 uint8_t *k;
313 uint16_t *ki;
314 unsigned int c, d;
315
316 k = (uint8_t *)&key->data[0];
317 *k = 0; /* for if there is a zero length key */
318
319 if (len > 128) {
320 len = 128;
321 }
322 if (bits <= 0) {
323 bits = 1024;
324 }
325 if (bits > 1024) {
326 bits = 1024;
327 }
328
329 for (i = 0; i < len; i++) {
330 k[i] = data[i];
331 }
332
333 /* expand table */
334 d = k[len - 1];
335 j = 0;
336 for (i = len; i < 128; i++, j++) {
337 d = key_table[(k[j] + d) & 0xff];
338 k[i] = d;
339 }
340
341 /* hmm.... key reduction to 'bits' bits */
342
343 j = (bits + 7) >> 3;
344 i = 128 - j;
345 c = (0xff >> (-bits & 0x07));
346
347 d = key_table[k[i] & c];
348 k[i] = d;
349 while (i--) {
350 d = key_table[k[i + j] ^ d];
351 k[i] = d;
352 }
353
354 /* copy from bytes into uint16_t's */
355 ki = &(key->data[63]);
356 for (i = 127; i >= 0; i -= 2) {
357 *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff;
358 }
359 }
360
361 typedef struct {
362 int key_bits; /* effective key bits */
363 RC2_KEY ks; /* key schedule */
364 } EVP_RC2_KEY;
365
rc2_init_key(EVP_CIPHER_CTX * ctx,const uint8_t * key,const uint8_t * iv,int enc)366 static int rc2_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
367 const uint8_t *iv, int enc) {
368 EVP_RC2_KEY *rc2_key = (EVP_RC2_KEY *)ctx->cipher_data;
369 RC2_set_key(&rc2_key->ks, EVP_CIPHER_CTX_key_length(ctx), key,
370 rc2_key->key_bits);
371 return 1;
372 }
373
rc2_cbc_cipher(EVP_CIPHER_CTX * ctx,uint8_t * out,const uint8_t * in,size_t inl)374 static int rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
375 size_t inl) {
376 EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data;
377 static const size_t kChunkSize = 0x10000;
378
379 while (inl >= kChunkSize) {
380 RC2_cbc_encrypt(in, out, kChunkSize, &key->ks, ctx->iv, ctx->encrypt);
381 inl -= kChunkSize;
382 in += kChunkSize;
383 out += kChunkSize;
384 }
385 if (inl) {
386 RC2_cbc_encrypt(in, out, inl, &key->ks, ctx->iv, ctx->encrypt);
387 }
388 return 1;
389 }
390
rc2_ctrl(EVP_CIPHER_CTX * ctx,int type,int arg,void * ptr)391 static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) {
392 EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data;
393
394 switch (type) {
395 case EVP_CTRL_INIT:
396 key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
397 return 1;
398
399 default:
400 return -1;
401 }
402 }
403
404 static const EVP_CIPHER rc2_40_cbc_cipher = {
405 NID_rc2_40_cbc,
406 8 /* block size */,
407 5 /* 40 bit */,
408 8 /* iv len */,
409 sizeof(EVP_RC2_KEY),
410 EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
411 NULL /* app_data */,
412 rc2_init_key,
413 rc2_cbc_cipher,
414 NULL,
415 rc2_ctrl,
416 };
417
EVP_rc2_40_cbc(void)418 const EVP_CIPHER *EVP_rc2_40_cbc(void) {
419 return &rc2_40_cbc_cipher;
420 }
421