xref: /freebsd/crypto/openssl/crypto/rc2/rc2_cbc.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1 /*
2  * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /*
11  * RC2 low level APIs are deprecated for public use, but still ok for internal
12  * use.
13  */
14 #include "internal/deprecated.h"
15 
16 #include <openssl/rc2.h>
17 #include "rc2_local.h"
18 
RC2_cbc_encrypt(const unsigned char * in,unsigned char * out,long length,RC2_KEY * ks,unsigned char * iv,int encrypt)19 void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
20                      RC2_KEY *ks, unsigned char *iv, int encrypt)
21 {
22     register unsigned long tin0, tin1;
23     register unsigned long tout0, tout1, xor0, xor1;
24     register long l = length;
25     unsigned long tin[2];
26 
27     if (encrypt) {
28         c2l(iv, tout0);
29         c2l(iv, tout1);
30         iv -= 8;
31         for (l -= 8; l >= 0; l -= 8) {
32             c2l(in, tin0);
33             c2l(in, tin1);
34             tin0 ^= tout0;
35             tin1 ^= tout1;
36             tin[0] = tin0;
37             tin[1] = tin1;
38             RC2_encrypt(tin, ks);
39             tout0 = tin[0];
40             l2c(tout0, out);
41             tout1 = tin[1];
42             l2c(tout1, out);
43         }
44         if (l != -8) {
45             c2ln(in, tin0, tin1, l + 8);
46             tin0 ^= tout0;
47             tin1 ^= tout1;
48             tin[0] = tin0;
49             tin[1] = tin1;
50             RC2_encrypt(tin, ks);
51             tout0 = tin[0];
52             l2c(tout0, out);
53             tout1 = tin[1];
54             l2c(tout1, out);
55         }
56         l2c(tout0, iv);
57         l2c(tout1, iv);
58     } else {
59         c2l(iv, xor0);
60         c2l(iv, xor1);
61         iv -= 8;
62         for (l -= 8; l >= 0; l -= 8) {
63             c2l(in, tin0);
64             tin[0] = tin0;
65             c2l(in, tin1);
66             tin[1] = tin1;
67             RC2_decrypt(tin, ks);
68             tout0 = tin[0] ^ xor0;
69             tout1 = tin[1] ^ xor1;
70             l2c(tout0, out);
71             l2c(tout1, out);
72             xor0 = tin0;
73             xor1 = tin1;
74         }
75         if (l != -8) {
76             c2l(in, tin0);
77             tin[0] = tin0;
78             c2l(in, tin1);
79             tin[1] = tin1;
80             RC2_decrypt(tin, ks);
81             tout0 = tin[0] ^ xor0;
82             tout1 = tin[1] ^ xor1;
83             l2cn(tout0, tout1, out, l + 8);
84             xor0 = tin0;
85             xor1 = tin1;
86         }
87         l2c(xor0, iv);
88         l2c(xor1, iv);
89     }
90     tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
91     tin[0] = tin[1] = 0;
92 }
93 
RC2_encrypt(unsigned long * d,RC2_KEY * key)94 void RC2_encrypt(unsigned long *d, RC2_KEY *key)
95 {
96     int i, n;
97     register RC2_INT *p0, *p1;
98     register RC2_INT x0, x1, x2, x3, t;
99     unsigned long l;
100 
101     l = d[0];
102     x0 = (RC2_INT) l & 0xffff;
103     x1 = (RC2_INT) (l >> 16L);
104     l = d[1];
105     x2 = (RC2_INT) l & 0xffff;
106     x3 = (RC2_INT) (l >> 16L);
107 
108     n = 3;
109     i = 5;
110 
111     p0 = p1 = &(key->data[0]);
112     for (;;) {
113         t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff;
114         x0 = (t << 1) | (t >> 15);
115         t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff;
116         x1 = (t << 2) | (t >> 14);
117         t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff;
118         x2 = (t << 3) | (t >> 13);
119         t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff;
120         x3 = (t << 5) | (t >> 11);
121 
122         if (--i == 0) {
123             if (--n == 0)
124                 break;
125             i = (n == 2) ? 6 : 5;
126 
127             x0 += p1[x3 & 0x3f];
128             x1 += p1[x0 & 0x3f];
129             x2 += p1[x1 & 0x3f];
130             x3 += p1[x2 & 0x3f];
131         }
132     }
133 
134     d[0] =
135         (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L);
136     d[1] =
137         (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L);
138 }
139 
RC2_decrypt(unsigned long * d,RC2_KEY * key)140 void RC2_decrypt(unsigned long *d, RC2_KEY *key)
141 {
142     int i, n;
143     register RC2_INT *p0, *p1;
144     register RC2_INT x0, x1, x2, x3, t;
145     unsigned long l;
146 
147     l = d[0];
148     x0 = (RC2_INT) l & 0xffff;
149     x1 = (RC2_INT) (l >> 16L);
150     l = d[1];
151     x2 = (RC2_INT) l & 0xffff;
152     x3 = (RC2_INT) (l >> 16L);
153 
154     n = 3;
155     i = 5;
156 
157     p0 = &(key->data[63]);
158     p1 = &(key->data[0]);
159     for (;;) {
160         t = ((x3 << 11) | (x3 >> 5)) & 0xffff;
161         x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff;
162         t = ((x2 << 13) | (x2 >> 3)) & 0xffff;
163         x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff;
164         t = ((x1 << 14) | (x1 >> 2)) & 0xffff;
165         x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff;
166         t = ((x0 << 15) | (x0 >> 1)) & 0xffff;
167         x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff;
168 
169         if (--i == 0) {
170             if (--n == 0)
171                 break;
172             i = (n == 2) ? 6 : 5;
173 
174             x3 = (x3 - p1[x2 & 0x3f]) & 0xffff;
175             x2 = (x2 - p1[x1 & 0x3f]) & 0xffff;
176             x1 = (x1 - p1[x0 & 0x3f]) & 0xffff;
177             x0 = (x0 - p1[x3 & 0x3f]) & 0xffff;
178         }
179     }
180 
181     d[0] =
182         (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L);
183     d[1] =
184         (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L);
185 }
186