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