• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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