xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/crypto/des/des.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/des.h>
58 
59 #include <stdlib.h>
60 
61 #include "internal.h"
62 
63 
64 /* IP and FP
65  * The problem is more of a geometric problem that random bit fiddling.
66  0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
67  8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
68 16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
69 24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
70 
71 32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
72 40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
73 48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
74 56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
75 
76 The output has been subject to swaps of the form
77 0 1 -> 3 1 but the odd and even bits have been put into
78 2 3    2 0
79 different words.  The main trick is to remember that
80 t=((l>>size)^r)&(mask);
81 r^=t;
82 l^=(t<<size);
83 can be used to swap and move bits between words.
84 
85 So l =  0  1  2  3  r = 16 17 18 19
86         4  5  6  7      20 21 22 23
87         8  9 10 11      24 25 26 27
88        12 13 14 15      28 29 30 31
89 becomes (for size == 2 and mask == 0x3333)
90    t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
91          6^20  7^21 -- --        4  5 20 21       6  7 22 23
92         10^24 11^25 -- --        8  9 24 25      10 11 24 25
93         14^28 15^29 -- --       12 13 28 29      14 15 28 29
94 
95 Thanks for hints from Richard Outerbridge - he told me IP&FP
96 could be done in 15 xor, 10 shifts and 5 ands.
97 When I finally started to think of the problem in 2D
98 I first got ~42 operations without xors.  When I remembered
99 how to use xors :-) I got it to its final state.
100 */
101 #define PERM_OP(a, b, t, n, m)          \
102   do {                                  \
103     (t) = ((((a) >> (n)) ^ (b)) & (m)); \
104     (b) ^= (t);                         \
105     (a) ^= ((t) << (n));                \
106   } while (0)
107 
108 #define IP(l, r)                        \
109   do {                                  \
110     uint32_t tt;                        \
111     PERM_OP(r, l, tt, 4, 0x0f0f0f0fL);  \
112     PERM_OP(l, r, tt, 16, 0x0000ffffL); \
113     PERM_OP(r, l, tt, 2, 0x33333333L);  \
114     PERM_OP(l, r, tt, 8, 0x00ff00ffL);  \
115     PERM_OP(r, l, tt, 1, 0x55555555L);  \
116   } while (0)
117 
118 #define FP(l, r)                        \
119   do {                                  \
120     uint32_t tt;                        \
121     PERM_OP(l, r, tt, 1, 0x55555555L);  \
122     PERM_OP(r, l, tt, 8, 0x00ff00ffL);  \
123     PERM_OP(l, r, tt, 2, 0x33333333L);  \
124     PERM_OP(r, l, tt, 16, 0x0000ffffL); \
125     PERM_OP(l, r, tt, 4, 0x0f0f0f0fL);  \
126   } while (0)
127 
128 #define LOAD_DATA(ks, R, S, u, t, E0, E1) \
129   do {                                    \
130     (u) = (R) ^ (ks)->subkeys[S][0];      \
131     (t) = (R) ^ (ks)->subkeys[S][1];      \
132   } while (0)
133 
134 #define D_ENCRYPT(ks, LL, R, S)                                                \
135   do {                                                                         \
136     LOAD_DATA(ks, R, S, u, t, E0, E1);                                         \
137     t = CRYPTO_rotr_u32(t, 4);                                                 \
138     (LL) ^=                                                                    \
139         DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \
140         DES_SPtrans[4][(u >> 18L) & 0x3f] ^                                    \
141         DES_SPtrans[6][(u >> 26L) & 0x3f] ^ DES_SPtrans[1][(t >> 2L) & 0x3f] ^ \
142         DES_SPtrans[3][(t >> 10L) & 0x3f] ^                                    \
143         DES_SPtrans[5][(t >> 18L) & 0x3f] ^ DES_SPtrans[7][(t >> 26L) & 0x3f]; \
144   } while (0)
145 
146 #define ITERATIONS 16
147 #define HALF_ITERATIONS 8
148 
149 static const uint32_t des_skb[8][64] = {
150     {  // for C bits (numbered as per FIPS 46) 1 2 3 4 5 6
151      0x00000000, 0x00000010, 0x20000000, 0x20000010, 0x00010000,
152      0x00010010, 0x20010000, 0x20010010, 0x00000800, 0x00000810,
153      0x20000800, 0x20000810, 0x00010800, 0x00010810, 0x20010800,
154      0x20010810, 0x00000020, 0x00000030, 0x20000020, 0x20000030,
155      0x00010020, 0x00010030, 0x20010020, 0x20010030, 0x00000820,
156      0x00000830, 0x20000820, 0x20000830, 0x00010820, 0x00010830,
157      0x20010820, 0x20010830, 0x00080000, 0x00080010, 0x20080000,
158      0x20080010, 0x00090000, 0x00090010, 0x20090000, 0x20090010,
159      0x00080800, 0x00080810, 0x20080800, 0x20080810, 0x00090800,
160      0x00090810, 0x20090800, 0x20090810, 0x00080020, 0x00080030,
161      0x20080020, 0x20080030, 0x00090020, 0x00090030, 0x20090020,
162      0x20090030, 0x00080820, 0x00080830, 0x20080820, 0x20080830,
163      0x00090820, 0x00090830, 0x20090820, 0x20090830, },
164     {  // for C bits (numbered as per FIPS 46) 7 8 10 11 12 13
165      0x00000000, 0x02000000, 0x00002000, 0x02002000, 0x00200000,
166      0x02200000, 0x00202000, 0x02202000, 0x00000004, 0x02000004,
167      0x00002004, 0x02002004, 0x00200004, 0x02200004, 0x00202004,
168      0x02202004, 0x00000400, 0x02000400, 0x00002400, 0x02002400,
169      0x00200400, 0x02200400, 0x00202400, 0x02202400, 0x00000404,
170      0x02000404, 0x00002404, 0x02002404, 0x00200404, 0x02200404,
171      0x00202404, 0x02202404, 0x10000000, 0x12000000, 0x10002000,
172      0x12002000, 0x10200000, 0x12200000, 0x10202000, 0x12202000,
173      0x10000004, 0x12000004, 0x10002004, 0x12002004, 0x10200004,
174      0x12200004, 0x10202004, 0x12202004, 0x10000400, 0x12000400,
175      0x10002400, 0x12002400, 0x10200400, 0x12200400, 0x10202400,
176      0x12202400, 0x10000404, 0x12000404, 0x10002404, 0x12002404,
177      0x10200404, 0x12200404, 0x10202404, 0x12202404, },
178     {  // for C bits (numbered as per FIPS 46) 14 15 16 17 19 20
179      0x00000000, 0x00000001, 0x00040000, 0x00040001, 0x01000000,
180      0x01000001, 0x01040000, 0x01040001, 0x00000002, 0x00000003,
181      0x00040002, 0x00040003, 0x01000002, 0x01000003, 0x01040002,
182      0x01040003, 0x00000200, 0x00000201, 0x00040200, 0x00040201,
183      0x01000200, 0x01000201, 0x01040200, 0x01040201, 0x00000202,
184      0x00000203, 0x00040202, 0x00040203, 0x01000202, 0x01000203,
185      0x01040202, 0x01040203, 0x08000000, 0x08000001, 0x08040000,
186      0x08040001, 0x09000000, 0x09000001, 0x09040000, 0x09040001,
187      0x08000002, 0x08000003, 0x08040002, 0x08040003, 0x09000002,
188      0x09000003, 0x09040002, 0x09040003, 0x08000200, 0x08000201,
189      0x08040200, 0x08040201, 0x09000200, 0x09000201, 0x09040200,
190      0x09040201, 0x08000202, 0x08000203, 0x08040202, 0x08040203,
191      0x09000202, 0x09000203, 0x09040202, 0x09040203, },
192     {  // for C bits (numbered as per FIPS 46) 21 23 24 26 27 28
193      0x00000000, 0x00100000, 0x00000100, 0x00100100, 0x00000008,
194      0x00100008, 0x00000108, 0x00100108, 0x00001000, 0x00101000,
195      0x00001100, 0x00101100, 0x00001008, 0x00101008, 0x00001108,
196      0x00101108, 0x04000000, 0x04100000, 0x04000100, 0x04100100,
197      0x04000008, 0x04100008, 0x04000108, 0x04100108, 0x04001000,
198      0x04101000, 0x04001100, 0x04101100, 0x04001008, 0x04101008,
199      0x04001108, 0x04101108, 0x00020000, 0x00120000, 0x00020100,
200      0x00120100, 0x00020008, 0x00120008, 0x00020108, 0x00120108,
201      0x00021000, 0x00121000, 0x00021100, 0x00121100, 0x00021008,
202      0x00121008, 0x00021108, 0x00121108, 0x04020000, 0x04120000,
203      0x04020100, 0x04120100, 0x04020008, 0x04120008, 0x04020108,
204      0x04120108, 0x04021000, 0x04121000, 0x04021100, 0x04121100,
205      0x04021008, 0x04121008, 0x04021108, 0x04121108, },
206     {  // for D bits (numbered as per FIPS 46) 1 2 3 4 5 6
207      0x00000000, 0x10000000, 0x00010000, 0x10010000, 0x00000004,
208      0x10000004, 0x00010004, 0x10010004, 0x20000000, 0x30000000,
209      0x20010000, 0x30010000, 0x20000004, 0x30000004, 0x20010004,
210      0x30010004, 0x00100000, 0x10100000, 0x00110000, 0x10110000,
211      0x00100004, 0x10100004, 0x00110004, 0x10110004, 0x20100000,
212      0x30100000, 0x20110000, 0x30110000, 0x20100004, 0x30100004,
213      0x20110004, 0x30110004, 0x00001000, 0x10001000, 0x00011000,
214      0x10011000, 0x00001004, 0x10001004, 0x00011004, 0x10011004,
215      0x20001000, 0x30001000, 0x20011000, 0x30011000, 0x20001004,
216      0x30001004, 0x20011004, 0x30011004, 0x00101000, 0x10101000,
217      0x00111000, 0x10111000, 0x00101004, 0x10101004, 0x00111004,
218      0x10111004, 0x20101000, 0x30101000, 0x20111000, 0x30111000,
219      0x20101004, 0x30101004, 0x20111004, 0x30111004, },
220     {  // for D bits (numbered as per FIPS 46) 8 9 11 12 13 14
221      0x00000000, 0x08000000, 0x00000008, 0x08000008, 0x00000400,
222      0x08000400, 0x00000408, 0x08000408, 0x00020000, 0x08020000,
223      0x00020008, 0x08020008, 0x00020400, 0x08020400, 0x00020408,
224      0x08020408, 0x00000001, 0x08000001, 0x00000009, 0x08000009,
225      0x00000401, 0x08000401, 0x00000409, 0x08000409, 0x00020001,
226      0x08020001, 0x00020009, 0x08020009, 0x00020401, 0x08020401,
227      0x00020409, 0x08020409, 0x02000000, 0x0A000000, 0x02000008,
228      0x0A000008, 0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
229      0x02020000, 0x0A020000, 0x02020008, 0x0A020008, 0x02020400,
230      0x0A020400, 0x02020408, 0x0A020408, 0x02000001, 0x0A000001,
231      0x02000009, 0x0A000009, 0x02000401, 0x0A000401, 0x02000409,
232      0x0A000409, 0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
233      0x02020401, 0x0A020401, 0x02020409, 0x0A020409, },
234     {  // for D bits (numbered as per FIPS 46) 16 17 18 19 20 21
235      0x00000000, 0x00000100, 0x00080000, 0x00080100, 0x01000000,
236      0x01000100, 0x01080000, 0x01080100, 0x00000010, 0x00000110,
237      0x00080010, 0x00080110, 0x01000010, 0x01000110, 0x01080010,
238      0x01080110, 0x00200000, 0x00200100, 0x00280000, 0x00280100,
239      0x01200000, 0x01200100, 0x01280000, 0x01280100, 0x00200010,
240      0x00200110, 0x00280010, 0x00280110, 0x01200010, 0x01200110,
241      0x01280010, 0x01280110, 0x00000200, 0x00000300, 0x00080200,
242      0x00080300, 0x01000200, 0x01000300, 0x01080200, 0x01080300,
243      0x00000210, 0x00000310, 0x00080210, 0x00080310, 0x01000210,
244      0x01000310, 0x01080210, 0x01080310, 0x00200200, 0x00200300,
245      0x00280200, 0x00280300, 0x01200200, 0x01200300, 0x01280200,
246      0x01280300, 0x00200210, 0x00200310, 0x00280210, 0x00280310,
247      0x01200210, 0x01200310, 0x01280210, 0x01280310, },
248     {  // for D bits (numbered as per FIPS 46) 22 23 24 25 27 28
249      0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000002,
250      0x04000002, 0x00040002, 0x04040002, 0x00002000, 0x04002000,
251      0x00042000, 0x04042000, 0x00002002, 0x04002002, 0x00042002,
252      0x04042002, 0x00000020, 0x04000020, 0x00040020, 0x04040020,
253      0x00000022, 0x04000022, 0x00040022, 0x04040022, 0x00002020,
254      0x04002020, 0x00042020, 0x04042020, 0x00002022, 0x04002022,
255      0x00042022, 0x04042022, 0x00000800, 0x04000800, 0x00040800,
256      0x04040800, 0x00000802, 0x04000802, 0x00040802, 0x04040802,
257      0x00002800, 0x04002800, 0x00042800, 0x04042800, 0x00002802,
258      0x04002802, 0x00042802, 0x04042802, 0x00000820, 0x04000820,
259      0x00040820, 0x04040820, 0x00000822, 0x04000822, 0x00040822,
260      0x04040822, 0x00002820, 0x04002820, 0x00042820, 0x04042820,
261      0x00002822, 0x04002822, 0x00042822, 0x04042822, }};
262 
263 static const uint32_t DES_SPtrans[8][64] = {
264     {  // nibble 0
265      0x02080800, 0x00080000, 0x02000002, 0x02080802, 0x02000000,
266      0x00080802, 0x00080002, 0x02000002, 0x00080802, 0x02080800,
267      0x02080000, 0x00000802, 0x02000802, 0x02000000, 0x00000000,
268      0x00080002, 0x00080000, 0x00000002, 0x02000800, 0x00080800,
269      0x02080802, 0x02080000, 0x00000802, 0x02000800, 0x00000002,
270      0x00000800, 0x00080800, 0x02080002, 0x00000800, 0x02000802,
271      0x02080002, 0x00000000, 0x00000000, 0x02080802, 0x02000800,
272      0x00080002, 0x02080800, 0x00080000, 0x00000802, 0x02000800,
273      0x02080002, 0x00000800, 0x00080800, 0x02000002, 0x00080802,
274      0x00000002, 0x02000002, 0x02080000, 0x02080802, 0x00080800,
275      0x02080000, 0x02000802, 0x02000000, 0x00000802, 0x00080002,
276      0x00000000, 0x00080000, 0x02000000, 0x02000802, 0x02080800,
277      0x00000002, 0x02080002, 0x00000800, 0x00080802, },
278     {  // nibble 1
279      0x40108010, 0x00000000, 0x00108000, 0x40100000, 0x40000010,
280      0x00008010, 0x40008000, 0x00108000, 0x00008000, 0x40100010,
281      0x00000010, 0x40008000, 0x00100010, 0x40108000, 0x40100000,
282      0x00000010, 0x00100000, 0x40008010, 0x40100010, 0x00008000,
283      0x00108010, 0x40000000, 0x00000000, 0x00100010, 0x40008010,
284      0x00108010, 0x40108000, 0x40000010, 0x40000000, 0x00100000,
285      0x00008010, 0x40108010, 0x00100010, 0x40108000, 0x40008000,
286      0x00108010, 0x40108010, 0x00100010, 0x40000010, 0x00000000,
287      0x40000000, 0x00008010, 0x00100000, 0x40100010, 0x00008000,
288      0x40000000, 0x00108010, 0x40008010, 0x40108000, 0x00008000,
289      0x00000000, 0x40000010, 0x00000010, 0x40108010, 0x00108000,
290      0x40100000, 0x40100010, 0x00100000, 0x00008010, 0x40008000,
291      0x40008010, 0x00000010, 0x40100000, 0x00108000, },
292     {  // nibble 2
293      0x04000001, 0x04040100, 0x00000100, 0x04000101, 0x00040001,
294      0x04000000, 0x04000101, 0x00040100, 0x04000100, 0x00040000,
295      0x04040000, 0x00000001, 0x04040101, 0x00000101, 0x00000001,
296      0x04040001, 0x00000000, 0x00040001, 0x04040100, 0x00000100,
297      0x00000101, 0x04040101, 0x00040000, 0x04000001, 0x04040001,
298      0x04000100, 0x00040101, 0x04040000, 0x00040100, 0x00000000,
299      0x04000000, 0x00040101, 0x04040100, 0x00000100, 0x00000001,
300      0x00040000, 0x00000101, 0x00040001, 0x04040000, 0x04000101,
301      0x00000000, 0x04040100, 0x00040100, 0x04040001, 0x00040001,
302      0x04000000, 0x04040101, 0x00000001, 0x00040101, 0x04000001,
303      0x04000000, 0x04040101, 0x00040000, 0x04000100, 0x04000101,
304      0x00040100, 0x04000100, 0x00000000, 0x04040001, 0x00000101,
305      0x04000001, 0x00040101, 0x00000100, 0x04040000, },
306     {  // nibble 3
307      0x00401008, 0x10001000, 0x00000008, 0x10401008, 0x00000000,
308      0x10400000, 0x10001008, 0x00400008, 0x10401000, 0x10000008,
309      0x10000000, 0x00001008, 0x10000008, 0x00401008, 0x00400000,
310      0x10000000, 0x10400008, 0x00401000, 0x00001000, 0x00000008,
311      0x00401000, 0x10001008, 0x10400000, 0x00001000, 0x00001008,
312      0x00000000, 0x00400008, 0x10401000, 0x10001000, 0x10400008,
313      0x10401008, 0x00400000, 0x10400008, 0x00001008, 0x00400000,
314      0x10000008, 0x00401000, 0x10001000, 0x00000008, 0x10400000,
315      0x10001008, 0x00000000, 0x00001000, 0x00400008, 0x00000000,
316      0x10400008, 0x10401000, 0x00001000, 0x10000000, 0x10401008,
317      0x00401008, 0x00400000, 0x10401008, 0x00000008, 0x10001000,
318      0x00401008, 0x00400008, 0x00401000, 0x10400000, 0x10001008,
319      0x00001008, 0x10000000, 0x10000008, 0x10401000, },
320     {  // nibble 4
321      0x08000000, 0x00010000, 0x00000400, 0x08010420, 0x08010020,
322      0x08000400, 0x00010420, 0x08010000, 0x00010000, 0x00000020,
323      0x08000020, 0x00010400, 0x08000420, 0x08010020, 0x08010400,
324      0x00000000, 0x00010400, 0x08000000, 0x00010020, 0x00000420,
325      0x08000400, 0x00010420, 0x00000000, 0x08000020, 0x00000020,
326      0x08000420, 0x08010420, 0x00010020, 0x08010000, 0x00000400,
327      0x00000420, 0x08010400, 0x08010400, 0x08000420, 0x00010020,
328      0x08010000, 0x00010000, 0x00000020, 0x08000020, 0x08000400,
329      0x08000000, 0x00010400, 0x08010420, 0x00000000, 0x00010420,
330      0x08000000, 0x00000400, 0x00010020, 0x08000420, 0x00000400,
331      0x00000000, 0x08010420, 0x08010020, 0x08010400, 0x00000420,
332      0x00010000, 0x00010400, 0x08010020, 0x08000400, 0x00000420,
333      0x00000020, 0x00010420, 0x08010000, 0x08000020, },
334     {  // nibble 5
335      0x80000040, 0x00200040, 0x00000000, 0x80202000, 0x00200040,
336      0x00002000, 0x80002040, 0x00200000, 0x00002040, 0x80202040,
337      0x00202000, 0x80000000, 0x80002000, 0x80000040, 0x80200000,
338      0x00202040, 0x00200000, 0x80002040, 0x80200040, 0x00000000,
339      0x00002000, 0x00000040, 0x80202000, 0x80200040, 0x80202040,
340      0x80200000, 0x80000000, 0x00002040, 0x00000040, 0x00202000,
341      0x00202040, 0x80002000, 0x00002040, 0x80000000, 0x80002000,
342      0x00202040, 0x80202000, 0x00200040, 0x00000000, 0x80002000,
343      0x80000000, 0x00002000, 0x80200040, 0x00200000, 0x00200040,
344      0x80202040, 0x00202000, 0x00000040, 0x80202040, 0x00202000,
345      0x00200000, 0x80002040, 0x80000040, 0x80200000, 0x00202040,
346      0x00000000, 0x00002000, 0x80000040, 0x80002040, 0x80202000,
347      0x80200000, 0x00002040, 0x00000040, 0x80200040, },
348     {  // nibble 6
349      0x00004000, 0x00000200, 0x01000200, 0x01000004, 0x01004204,
350      0x00004004, 0x00004200, 0x00000000, 0x01000000, 0x01000204,
351      0x00000204, 0x01004000, 0x00000004, 0x01004200, 0x01004000,
352      0x00000204, 0x01000204, 0x00004000, 0x00004004, 0x01004204,
353      0x00000000, 0x01000200, 0x01000004, 0x00004200, 0x01004004,
354      0x00004204, 0x01004200, 0x00000004, 0x00004204, 0x01004004,
355      0x00000200, 0x01000000, 0x00004204, 0x01004000, 0x01004004,
356      0x00000204, 0x00004000, 0x00000200, 0x01000000, 0x01004004,
357      0x01000204, 0x00004204, 0x00004200, 0x00000000, 0x00000200,
358      0x01000004, 0x00000004, 0x01000200, 0x00000000, 0x01000204,
359      0x01000200, 0x00004200, 0x00000204, 0x00004000, 0x01004204,
360      0x01000000, 0x01004200, 0x00000004, 0x00004004, 0x01004204,
361      0x01000004, 0x01004200, 0x01004000, 0x00004004, },
362     {  // nibble 7
363      0x20800080, 0x20820000, 0x00020080, 0x00000000, 0x20020000,
364      0x00800080, 0x20800000, 0x20820080, 0x00000080, 0x20000000,
365      0x00820000, 0x00020080, 0x00820080, 0x20020080, 0x20000080,
366      0x20800000, 0x00020000, 0x00820080, 0x00800080, 0x20020000,
367      0x20820080, 0x20000080, 0x00000000, 0x00820000, 0x20000000,
368      0x00800000, 0x20020080, 0x20800080, 0x00800000, 0x00020000,
369      0x20820000, 0x00000080, 0x00800000, 0x00020000, 0x20000080,
370      0x20820080, 0x00020080, 0x20000000, 0x00000000, 0x00820000,
371      0x20800080, 0x20020080, 0x20020000, 0x00800080, 0x20820000,
372      0x00000080, 0x00800080, 0x20020000, 0x20820080, 0x00800000,
373      0x20800000, 0x20000080, 0x00820000, 0x00020080, 0x20020080,
374      0x20800000, 0x00000080, 0x20820000, 0x00820080, 0x00000000,
375      0x20000000, 0x20800080, 0x00020000, 0x00820080, }};
376 
377 #define HPERM_OP(a, t, n, m)                  \
378   ((t) = ((((a) << (16 - (n))) ^ (a)) & (m)), \
379    (a) = (a) ^ (t) ^ ((t) >> (16 - (n))))
380 
DES_set_key(const DES_cblock * key,DES_key_schedule * schedule)381 void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) {
382   DES_set_key_ex(key->bytes, schedule);
383 }
384 
DES_set_key_ex(const uint8_t key[8],DES_key_schedule * schedule)385 void DES_set_key_ex(const uint8_t key[8], DES_key_schedule *schedule) {
386   static const int shifts2[16] = {0, 0, 1, 1, 1, 1, 1, 1,
387                                   0, 1, 1, 1, 1, 1, 1, 0};
388   uint32_t c, d, t, s, t2;
389   const uint8_t *in;
390   int i;
391 
392   in = key;
393 
394   c2l(in, c);
395   c2l(in, d);
396 
397   // do PC1 in 47 simple operations :-)
398   // Thanks to John Fletcher ([email protected])
399   // for the inspiration. :-)
400   PERM_OP(d, c, t, 4, 0x0f0f0f0f);
401   HPERM_OP(c, t, -2, 0xcccc0000);
402   HPERM_OP(d, t, -2, 0xcccc0000);
403   PERM_OP(d, c, t, 1, 0x55555555);
404   PERM_OP(c, d, t, 8, 0x00ff00ff);
405   PERM_OP(d, c, t, 1, 0x55555555);
406   d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
407        ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
408   c &= 0x0fffffff;
409 
410   for (i = 0; i < ITERATIONS; i++) {
411     if (shifts2[i]) {
412       c = ((c >> 2) | (c << 26));
413       d = ((d >> 2) | (d << 26));
414     } else {
415       c = ((c >> 1) | (c << 27));
416       d = ((d >> 1) | (d << 27));
417     }
418     c &= 0x0fffffff;
419     d &= 0x0fffffff;
420     // could be a few less shifts but I am to lazy at this
421     // point in time to investigate
422     s = des_skb[0][(c) & 0x3f] |
423         des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
424         des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
425         des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) |
426                    ((c >> 22) & 0x38)];
427     t = des_skb[4][(d) & 0x3f] |
428         des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
429         des_skb[6][(d >> 15) & 0x3f] |
430         des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];
431 
432     // table contained 0213 4657
433     t2 = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
434     schedule->subkeys[i][0] = CRYPTO_rotr_u32(t2, 30);
435 
436     t2 = ((s >> 16) | (t & 0xffff0000));
437     schedule->subkeys[i][1] = CRYPTO_rotr_u32(t2, 26);
438   }
439 }
440 
441 static const uint8_t kOddParity[256] = {
442     1,   1,   2,   2,   4,   4,   7,   7,   8,   8,   11,  11,  13,  13,  14,
443     14,  16,  16,  19,  19,  21,  21,  22,  22,  25,  25,  26,  26,  28,  28,
444     31,  31,  32,  32,  35,  35,  37,  37,  38,  38,  41,  41,  42,  42,  44,
445     44,  47,  47,  49,  49,  50,  50,  52,  52,  55,  55,  56,  56,  59,  59,
446     61,  61,  62,  62,  64,  64,  67,  67,  69,  69,  70,  70,  73,  73,  74,
447     74,  76,  76,  79,  79,  81,  81,  82,  82,  84,  84,  87,  87,  88,  88,
448     91,  91,  93,  93,  94,  94,  97,  97,  98,  98,  100, 100, 103, 103, 104,
449     104, 107, 107, 109, 109, 110, 110, 112, 112, 115, 115, 117, 117, 118, 118,
450     121, 121, 122, 122, 124, 124, 127, 127, 128, 128, 131, 131, 133, 133, 134,
451     134, 137, 137, 138, 138, 140, 140, 143, 143, 145, 145, 146, 146, 148, 148,
452     151, 151, 152, 152, 155, 155, 157, 157, 158, 158, 161, 161, 162, 162, 164,
453     164, 167, 167, 168, 168, 171, 171, 173, 173, 174, 174, 176, 176, 179, 179,
454     181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191, 191, 193, 193, 194,
455     194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206, 206, 208, 208,
456     211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223, 223, 224,
457     224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239, 239,
458     241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254,
459     254
460 };
461 
DES_set_odd_parity(DES_cblock * key)462 void DES_set_odd_parity(DES_cblock *key) {
463   unsigned i;
464 
465   for (i = 0; i < DES_KEY_SZ; i++) {
466     key->bytes[i] = kOddParity[key->bytes[i]];
467   }
468 }
469 
DES_encrypt1(uint32_t data[2],const DES_key_schedule * ks,int enc)470 static void DES_encrypt1(uint32_t data[2], const DES_key_schedule *ks,
471                          int enc) {
472   uint32_t l, r, t, u;
473 
474   r = data[0];
475   l = data[1];
476 
477   IP(r, l);
478   // Things have been modified so that the initial rotate is done outside
479   // the loop.  This required the DES_SPtrans values in sp.h to be
480   // rotated 1 bit to the right. One perl script later and things have a
481   // 5% speed up on a sparc2. Thanks to Richard Outerbridge
482   // <[email protected]> for pointing this out.
483   // clear the top bits on machines with 8byte longs
484   // shift left by 2
485   r = CRYPTO_rotr_u32(r, 29);
486   l = CRYPTO_rotr_u32(l, 29);
487 
488   // I don't know if it is worth the effort of loop unrolling the
489   // inner loop
490   if (enc) {
491     D_ENCRYPT(ks, l, r, 0);
492     D_ENCRYPT(ks, r, l, 1);
493     D_ENCRYPT(ks, l, r, 2);
494     D_ENCRYPT(ks, r, l, 3);
495     D_ENCRYPT(ks, l, r, 4);
496     D_ENCRYPT(ks, r, l, 5);
497     D_ENCRYPT(ks, l, r, 6);
498     D_ENCRYPT(ks, r, l, 7);
499     D_ENCRYPT(ks, l, r, 8);
500     D_ENCRYPT(ks, r, l, 9);
501     D_ENCRYPT(ks, l, r, 10);
502     D_ENCRYPT(ks, r, l, 11);
503     D_ENCRYPT(ks, l, r, 12);
504     D_ENCRYPT(ks, r, l, 13);
505     D_ENCRYPT(ks, l, r, 14);
506     D_ENCRYPT(ks, r, l, 15);
507   } else {
508     D_ENCRYPT(ks, l, r, 15);
509     D_ENCRYPT(ks, r, l, 14);
510     D_ENCRYPT(ks, l, r, 13);
511     D_ENCRYPT(ks, r, l, 12);
512     D_ENCRYPT(ks, l, r, 11);
513     D_ENCRYPT(ks, r, l, 10);
514     D_ENCRYPT(ks, l, r, 9);
515     D_ENCRYPT(ks, r, l, 8);
516     D_ENCRYPT(ks, l, r, 7);
517     D_ENCRYPT(ks, r, l, 6);
518     D_ENCRYPT(ks, l, r, 5);
519     D_ENCRYPT(ks, r, l, 4);
520     D_ENCRYPT(ks, l, r, 3);
521     D_ENCRYPT(ks, r, l, 2);
522     D_ENCRYPT(ks, l, r, 1);
523     D_ENCRYPT(ks, r, l, 0);
524   }
525 
526   // rotate and clear the top bits on machines with 8byte longs
527   l = CRYPTO_rotr_u32(l, 3);
528   r = CRYPTO_rotr_u32(r, 3);
529 
530   FP(r, l);
531   data[0] = l;
532   data[1] = r;
533 }
534 
DES_encrypt2(uint32_t data[2],const DES_key_schedule * ks,int enc)535 static void DES_encrypt2(uint32_t data[2], const DES_key_schedule *ks,
536                          int enc) {
537   uint32_t l, r, t, u;
538 
539   r = data[0];
540   l = data[1];
541 
542   // Things have been modified so that the initial rotate is done outside the
543   // loop.  This required the DES_SPtrans values in sp.h to be rotated 1 bit to
544   // the right. One perl script later and things have a 5% speed up on a
545   // sparc2. Thanks to Richard Outerbridge <[email protected]> for
546   // pointing this out.
547   // clear the top bits on machines with 8byte longs
548   r = CRYPTO_rotr_u32(r, 29);
549   l = CRYPTO_rotr_u32(l, 29);
550 
551   // I don't know if it is worth the effort of loop unrolling the
552   // inner loop
553   if (enc) {
554     D_ENCRYPT(ks, l, r, 0);
555     D_ENCRYPT(ks, r, l, 1);
556     D_ENCRYPT(ks, l, r, 2);
557     D_ENCRYPT(ks, r, l, 3);
558     D_ENCRYPT(ks, l, r, 4);
559     D_ENCRYPT(ks, r, l, 5);
560     D_ENCRYPT(ks, l, r, 6);
561     D_ENCRYPT(ks, r, l, 7);
562     D_ENCRYPT(ks, l, r, 8);
563     D_ENCRYPT(ks, r, l, 9);
564     D_ENCRYPT(ks, l, r, 10);
565     D_ENCRYPT(ks, r, l, 11);
566     D_ENCRYPT(ks, l, r, 12);
567     D_ENCRYPT(ks, r, l, 13);
568     D_ENCRYPT(ks, l, r, 14);
569     D_ENCRYPT(ks, r, l, 15);
570   } else {
571     D_ENCRYPT(ks, l, r, 15);
572     D_ENCRYPT(ks, r, l, 14);
573     D_ENCRYPT(ks, l, r, 13);
574     D_ENCRYPT(ks, r, l, 12);
575     D_ENCRYPT(ks, l, r, 11);
576     D_ENCRYPT(ks, r, l, 10);
577     D_ENCRYPT(ks, l, r, 9);
578     D_ENCRYPT(ks, r, l, 8);
579     D_ENCRYPT(ks, l, r, 7);
580     D_ENCRYPT(ks, r, l, 6);
581     D_ENCRYPT(ks, l, r, 5);
582     D_ENCRYPT(ks, r, l, 4);
583     D_ENCRYPT(ks, l, r, 3);
584     D_ENCRYPT(ks, r, l, 2);
585     D_ENCRYPT(ks, l, r, 1);
586     D_ENCRYPT(ks, r, l, 0);
587   }
588   // rotate and clear the top bits on machines with 8byte longs
589   data[0] = CRYPTO_rotr_u32(l, 3);
590   data[1] = CRYPTO_rotr_u32(r, 3);
591 }
592 
DES_encrypt3(uint32_t data[2],const DES_key_schedule * ks1,const DES_key_schedule * ks2,const DES_key_schedule * ks3)593 void DES_encrypt3(uint32_t data[2], const DES_key_schedule *ks1,
594                   const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
595   uint32_t l, r;
596 
597   l = data[0];
598   r = data[1];
599   IP(l, r);
600   data[0] = l;
601   data[1] = r;
602   DES_encrypt2(data, ks1, DES_ENCRYPT);
603   DES_encrypt2(data, ks2, DES_DECRYPT);
604   DES_encrypt2(data, ks3, DES_ENCRYPT);
605   l = data[0];
606   r = data[1];
607   FP(r, l);
608   data[0] = l;
609   data[1] = r;
610 }
611 
DES_decrypt3(uint32_t data[2],const DES_key_schedule * ks1,const DES_key_schedule * ks2,const DES_key_schedule * ks3)612 void DES_decrypt3(uint32_t data[2], const DES_key_schedule *ks1,
613                   const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
614   uint32_t l, r;
615 
616   l = data[0];
617   r = data[1];
618   IP(l, r);
619   data[0] = l;
620   data[1] = r;
621   DES_encrypt2(data, ks3, DES_DECRYPT);
622   DES_encrypt2(data, ks2, DES_ENCRYPT);
623   DES_encrypt2(data, ks1, DES_DECRYPT);
624   l = data[0];
625   r = data[1];
626   FP(r, l);
627   data[0] = l;
628   data[1] = r;
629 }
630 
DES_ecb_encrypt(const DES_cblock * in_block,DES_cblock * out_block,const DES_key_schedule * schedule,int is_encrypt)631 void DES_ecb_encrypt(const DES_cblock *in_block, DES_cblock *out_block,
632                      const DES_key_schedule *schedule, int is_encrypt) {
633   DES_ecb_encrypt_ex(in_block->bytes, out_block->bytes, schedule, is_encrypt);
634 }
635 
DES_ecb_encrypt_ex(const uint8_t in[8],uint8_t out[8],const DES_key_schedule * schedule,int is_encrypt)636 void DES_ecb_encrypt_ex(const uint8_t in[8], uint8_t out[8],
637                         const DES_key_schedule *schedule, int is_encrypt) {
638   uint32_t ll[2];
639   ll[0] = CRYPTO_load_u32_le(in);
640   ll[1] = CRYPTO_load_u32_le(in + 4);
641   DES_encrypt1(ll, schedule, is_encrypt);
642   CRYPTO_store_u32_le(out, ll[0]);
643   CRYPTO_store_u32_le(out + 4, ll[1]);
644 }
645 
DES_ncbc_encrypt(const uint8_t * in,uint8_t * out,size_t len,const DES_key_schedule * schedule,DES_cblock * ivec,int enc)646 void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
647                       const DES_key_schedule *schedule, DES_cblock *ivec,
648                       int enc) {
649   DES_ncbc_encrypt_ex(in, out, len, schedule, ivec->bytes, enc);
650 }
651 
DES_ncbc_encrypt_ex(const uint8_t * in,uint8_t * out,size_t len,const DES_key_schedule * schedule,uint8_t ivec[8],int enc)652 void DES_ncbc_encrypt_ex(const uint8_t *in, uint8_t *out, size_t len,
653                          const DES_key_schedule *schedule, uint8_t ivec[8],
654                          int enc) {
655   uint32_t tin0, tin1;
656   uint32_t tout0, tout1, xor0, xor1;
657   uint32_t tin[2];
658   unsigned char *iv;
659 
660   iv = ivec;
661 
662   if (enc) {
663     c2l(iv, tout0);
664     c2l(iv, tout1);
665     for (; len >= 8; len -= 8) {
666       c2l(in, tin0);
667       c2l(in, tin1);
668       tin0 ^= tout0;
669       tin[0] = tin0;
670       tin1 ^= tout1;
671       tin[1] = tin1;
672       DES_encrypt1(tin, schedule, DES_ENCRYPT);
673       tout0 = tin[0];
674       l2c(tout0, out);
675       tout1 = tin[1];
676       l2c(tout1, out);
677     }
678     if (len != 0) {
679       c2ln(in, tin0, tin1, len);
680       tin0 ^= tout0;
681       tin[0] = tin0;
682       tin1 ^= tout1;
683       tin[1] = tin1;
684       DES_encrypt1(tin, schedule, DES_ENCRYPT);
685       tout0 = tin[0];
686       l2c(tout0, out);
687       tout1 = tin[1];
688       l2c(tout1, out);
689     }
690     iv = ivec;
691     l2c(tout0, iv);
692     l2c(tout1, iv);
693   } else {
694     c2l(iv, xor0);
695     c2l(iv, xor1);
696     for (; len >= 8; len -= 8) {
697       c2l(in, tin0);
698       tin[0] = tin0;
699       c2l(in, tin1);
700       tin[1] = tin1;
701       DES_encrypt1(tin, schedule, DES_DECRYPT);
702       tout0 = tin[0] ^ xor0;
703       tout1 = tin[1] ^ xor1;
704       l2c(tout0, out);
705       l2c(tout1, out);
706       xor0 = tin0;
707       xor1 = tin1;
708     }
709     if (len != 0) {
710       c2l(in, tin0);
711       tin[0] = tin0;
712       c2l(in, tin1);
713       tin[1] = tin1;
714       DES_encrypt1(tin, schedule, DES_DECRYPT);
715       tout0 = tin[0] ^ xor0;
716       tout1 = tin[1] ^ xor1;
717       l2cn(tout0, tout1, out, len);
718       xor0 = tin0;
719       xor1 = tin1;
720     }
721     iv = ivec;
722     l2c(xor0, iv);
723     l2c(xor1, iv);
724   }
725   tin[0] = tin[1] = 0;
726 }
727 
DES_ecb3_encrypt(const DES_cblock * input,DES_cblock * output,const DES_key_schedule * ks1,const DES_key_schedule * ks2,const DES_key_schedule * ks3,int enc)728 void DES_ecb3_encrypt(const DES_cblock *input, DES_cblock *output,
729                       const DES_key_schedule *ks1, const DES_key_schedule *ks2,
730                       const DES_key_schedule *ks3, int enc) {
731   DES_ecb3_encrypt_ex(input->bytes, output->bytes, ks1, ks2, ks3, enc);
732 }
733 
DES_ecb3_encrypt_ex(const uint8_t in[8],uint8_t out[8],const DES_key_schedule * ks1,const DES_key_schedule * ks2,const DES_key_schedule * ks3,int enc)734 void DES_ecb3_encrypt_ex(const uint8_t in[8], uint8_t out[8],
735                          const DES_key_schedule *ks1,
736                          const DES_key_schedule *ks2,
737                          const DES_key_schedule *ks3, int enc) {
738   uint32_t ll[2];
739   ll[0] = CRYPTO_load_u32_le(in);
740   ll[1] = CRYPTO_load_u32_le(in + 4);
741   if (enc) {
742     DES_encrypt3(ll, ks1, ks2, ks3);
743   } else {
744     DES_decrypt3(ll, ks1, ks2, ks3);
745   }
746   CRYPTO_store_u32_le(out, ll[0]);
747   CRYPTO_store_u32_le(out + 4, ll[1]);
748 }
749 
DES_ede3_cbc_encrypt(const uint8_t * in,uint8_t * out,size_t len,const DES_key_schedule * ks1,const DES_key_schedule * ks2,const DES_key_schedule * ks3,DES_cblock * ivec,int enc)750 void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
751                           const DES_key_schedule *ks1,
752                           const DES_key_schedule *ks2,
753                           const DES_key_schedule *ks3, DES_cblock *ivec,
754                           int enc) {
755   DES_ede3_cbc_encrypt_ex(in, out, len, ks1, ks2, ks3, ivec->bytes, enc);
756 }
757 
DES_ede3_cbc_encrypt_ex(const uint8_t * in,uint8_t * out,size_t len,const DES_key_schedule * ks1,const DES_key_schedule * ks2,const DES_key_schedule * ks3,uint8_t ivec[8],int enc)758 void DES_ede3_cbc_encrypt_ex(const uint8_t *in, uint8_t *out, size_t len,
759                              const DES_key_schedule *ks1,
760                              const DES_key_schedule *ks2,
761                              const DES_key_schedule *ks3, uint8_t ivec[8],
762                              int enc) {
763   uint32_t tin0, tin1;
764   uint32_t tout0, tout1, xor0, xor1;
765   uint32_t tin[2];
766   uint8_t *iv;
767 
768   iv = ivec;
769 
770   if (enc) {
771     c2l(iv, tout0);
772     c2l(iv, tout1);
773     for (; len >= 8; len -= 8) {
774       c2l(in, tin0);
775       c2l(in, tin1);
776       tin0 ^= tout0;
777       tin1 ^= tout1;
778 
779       tin[0] = tin0;
780       tin[1] = tin1;
781       DES_encrypt3(tin, ks1, ks2, ks3);
782       tout0 = tin[0];
783       tout1 = tin[1];
784 
785       l2c(tout0, out);
786       l2c(tout1, out);
787     }
788     if (len != 0) {
789       c2ln(in, tin0, tin1, len);
790       tin0 ^= tout0;
791       tin1 ^= tout1;
792 
793       tin[0] = tin0;
794       tin[1] = tin1;
795       DES_encrypt3(tin, ks1, ks2, ks3);
796       tout0 = tin[0];
797       tout1 = tin[1];
798 
799       l2c(tout0, out);
800       l2c(tout1, out);
801     }
802     iv = ivec;
803     l2c(tout0, iv);
804     l2c(tout1, iv);
805   } else {
806     uint32_t t0, t1;
807 
808     c2l(iv, xor0);
809     c2l(iv, xor1);
810     for (; len >= 8; len -= 8) {
811       c2l(in, tin0);
812       c2l(in, tin1);
813 
814       t0 = tin0;
815       t1 = tin1;
816 
817       tin[0] = tin0;
818       tin[1] = tin1;
819       DES_decrypt3(tin, ks1, ks2, ks3);
820       tout0 = tin[0];
821       tout1 = tin[1];
822 
823       tout0 ^= xor0;
824       tout1 ^= xor1;
825       l2c(tout0, out);
826       l2c(tout1, out);
827       xor0 = t0;
828       xor1 = t1;
829     }
830     if (len != 0) {
831       c2l(in, tin0);
832       c2l(in, tin1);
833 
834       t0 = tin0;
835       t1 = tin1;
836 
837       tin[0] = tin0;
838       tin[1] = tin1;
839       DES_decrypt3(tin, ks1, ks2, ks3);
840       tout0 = tin[0];
841       tout1 = tin[1];
842 
843       tout0 ^= xor0;
844       tout1 ^= xor1;
845       l2cn(tout0, tout1, out, len);
846       xor0 = t0;
847       xor1 = t1;
848     }
849 
850     iv = ivec;
851     l2c(xor0, iv);
852     l2c(xor1, iv);
853   }
854 
855   tin[0] = tin[1] = 0;
856 }
857 
DES_ede2_cbc_encrypt(const uint8_t * in,uint8_t * out,size_t len,const DES_key_schedule * ks1,const DES_key_schedule * ks2,DES_cblock * ivec,int enc)858 void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
859                           const DES_key_schedule *ks1,
860                           const DES_key_schedule *ks2,
861                           DES_cblock *ivec,
862                           int enc) {
863   DES_ede3_cbc_encrypt(in, out, len, ks1, ks2, ks1, ivec, enc);
864 }
865 
866 
867 // Deprecated functions.
868 
DES_set_key_unchecked(const DES_cblock * key,DES_key_schedule * schedule)869 void DES_set_key_unchecked(const DES_cblock *key, DES_key_schedule *schedule) {
870   DES_set_key(key, schedule);
871 }
872