xref: /openbsd-src/lib/libcrypto/des/des_enc.c (revision 37db8d9bb52c27295b815cc9c053c98e6cc37066)
1 /* $OpenBSD: des_enc.c,v 1.20 2024/08/31 16:17:13 jsing Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include "des_local.h"
60 
61 const DES_LONG DES_SPtrans[8][64] = {
62 	{
63 /* nibble 0 */
64 		0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
65 		0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
66 		0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
67 		0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
68 		0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
69 		0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
70 		0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
71 		0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
72 		0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
73 		0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
74 		0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
75 		0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
76 		0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
77 		0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
78 		0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
79 		0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
80 	}, {
81 /* nibble 1 */
82 		0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
83 		0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
84 		0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
85 		0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
86 		0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
87 		0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
88 		0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
89 		0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
90 		0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
91 		0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
92 		0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
93 		0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
94 		0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
95 		0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
96 		0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
97 		0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
98 	}, {
99 /* nibble 2 */
100 		0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
101 		0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
102 		0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
103 		0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
104 		0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
105 		0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
106 		0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
107 		0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
108 		0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
109 		0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
110 		0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
111 		0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
112 		0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
113 		0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
114 		0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
115 		0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
116 	}, {
117 /* nibble 3 */
118 		0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
119 		0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
120 		0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
121 		0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
122 		0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
123 		0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
124 		0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
125 		0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
126 		0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
127 		0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
128 		0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
129 		0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
130 		0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
131 		0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
132 		0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
133 		0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
134 	}, {
135 /* nibble 4 */
136 		0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
137 		0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
138 		0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
139 		0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
140 		0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
141 		0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
142 		0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
143 		0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
144 		0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
145 		0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
146 		0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
147 		0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
148 		0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
149 		0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
150 		0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
151 		0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
152 	}, {
153 /* nibble 5 */
154 		0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
155 		0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
156 		0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
157 		0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
158 		0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
159 		0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
160 		0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
161 		0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
162 		0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
163 		0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
164 		0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
165 		0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
166 		0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
167 		0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
168 		0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
169 		0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
170 	}, {
171 /* nibble 6 */
172 		0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
173 		0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
174 		0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
175 		0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
176 		0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
177 		0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
178 		0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
179 		0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
180 		0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
181 		0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
182 		0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
183 		0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
184 		0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
185 		0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
186 		0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
187 		0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
188 	}, {
189 /* nibble 7 */
190 		0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
191 		0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
192 		0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
193 		0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
194 		0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
195 		0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
196 		0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
197 		0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
198 		0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
199 		0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
200 		0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
201 		0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
202 		0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
203 		0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
204 		0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
205 		0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
206 	},
207 };
208 
209 void
210 DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
211 {
212 	DES_LONG l, r, t, u;
213 #ifndef DES_UNROLL
214 	int i;
215 #endif
216 	DES_LONG *s;
217 
218 	r = data[0];
219 	l = data[1];
220 
221 	IP(r, l);
222 	/* Things have been modified so that the initial rotate is
223 	 * done outside the loop.  This required the
224 	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
225 	 * One perl script later and things have a 5% speed up on a sparc2.
226 	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
227 	 * for pointing this out. */
228 	/* clear the top bits on machines with 8byte longs */
229 	/* shift left by 2 */
230 	r = ROTATE(r, 29) & 0xffffffffL;
231 	l = ROTATE(l, 29) & 0xffffffffL;
232 
233 	s = ks->ks->deslong;
234 	/* I don't know if it is worth the effort of loop unrolling the
235 	 * inner loop */
236 	if (enc) {
237 #ifdef DES_UNROLL
238 		D_ENCRYPT(l, r, 0); /*  1 */
239 		D_ENCRYPT(r, l, 2); /*  2 */
240 		D_ENCRYPT(l, r, 4); /*  3 */
241 		D_ENCRYPT(r, l, 6); /*  4 */
242 		D_ENCRYPT(l, r, 8); /*  5 */
243 		D_ENCRYPT(r, l, 10); /*  6 */
244 		D_ENCRYPT(l, r, 12); /*  7 */
245 		D_ENCRYPT(r, l, 14); /*  8 */
246 		D_ENCRYPT(l, r, 16); /*  9 */
247 		D_ENCRYPT(r, l, 18); /*  10 */
248 		D_ENCRYPT(l, r, 20); /*  11 */
249 		D_ENCRYPT(r, l, 22); /*  12 */
250 		D_ENCRYPT(l, r, 24); /*  13 */
251 		D_ENCRYPT(r, l, 26); /*  14 */
252 		D_ENCRYPT(l, r, 28); /*  15 */
253 		D_ENCRYPT(r, l, 30); /*  16 */
254 #else
255 		for (i = 0; i < 32; i += 4) {
256 			D_ENCRYPT(l, r, i + 0); /*  1 */
257 			D_ENCRYPT(r, l, i + 2); /*  2 */
258 		}
259 #endif
260 	} else {
261 #ifdef DES_UNROLL
262 		D_ENCRYPT(l, r, 30); /* 16 */
263 		D_ENCRYPT(r, l, 28); /* 15 */
264 		D_ENCRYPT(l, r, 26); /* 14 */
265 		D_ENCRYPT(r, l, 24); /* 13 */
266 		D_ENCRYPT(l, r, 22); /* 12 */
267 		D_ENCRYPT(r, l, 20); /* 11 */
268 		D_ENCRYPT(l, r, 18); /* 10 */
269 		D_ENCRYPT(r, l, 16); /*  9 */
270 		D_ENCRYPT(l, r, 14); /*  8 */
271 		D_ENCRYPT(r, l, 12); /*  7 */
272 		D_ENCRYPT(l, r, 10); /*  6 */
273 		D_ENCRYPT(r, l, 8); /*  5 */
274 		D_ENCRYPT(l, r, 6); /*  4 */
275 		D_ENCRYPT(r, l, 4); /*  3 */
276 		D_ENCRYPT(l, r, 2); /*  2 */
277 		D_ENCRYPT(r, l, 0); /*  1 */
278 #else
279 		for (i = 30; i > 0; i -= 4) {
280 			D_ENCRYPT(l, r, i - 0); /* 16 */
281 			D_ENCRYPT(r, l, i - 2); /* 15 */
282 		}
283 #endif
284 	}
285 
286 	/* rotate and clear the top bits on machines with 8byte longs */
287 	l = ROTATE(l, 3) & 0xffffffffL;
288 	r = ROTATE(r, 3) & 0xffffffffL;
289 
290 	FP(r, l);
291 	data[0] = l;
292 	data[1] = r;
293 	l = r = t = u = 0;
294 }
295 LCRYPTO_ALIAS(DES_encrypt1);
296 
297 void
298 DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
299 {
300 	DES_LONG l, r, t, u;
301 #ifndef DES_UNROLL
302 	int i;
303 #endif
304 	DES_LONG *s;
305 
306 	r = data[0];
307 	l = data[1];
308 
309 	/* Things have been modified so that the initial rotate is
310 	 * done outside the loop.  This required the
311 	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
312 	 * One perl script later and things have a 5% speed up on a sparc2.
313 	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
314 	 * for pointing this out. */
315 	/* clear the top bits on machines with 8byte longs */
316 	r = ROTATE(r, 29) & 0xffffffffL;
317 	l = ROTATE(l, 29) & 0xffffffffL;
318 
319 	s = ks->ks->deslong;
320 	/* I don't know if it is worth the effort of loop unrolling the
321 	 * inner loop */
322 	if (enc) {
323 #ifdef DES_UNROLL
324 		D_ENCRYPT(l, r, 0); /*  1 */
325 		D_ENCRYPT(r, l, 2); /*  2 */
326 		D_ENCRYPT(l, r, 4); /*  3 */
327 		D_ENCRYPT(r, l, 6); /*  4 */
328 		D_ENCRYPT(l, r, 8); /*  5 */
329 		D_ENCRYPT(r, l, 10); /*  6 */
330 		D_ENCRYPT(l, r, 12); /*  7 */
331 		D_ENCRYPT(r, l, 14); /*  8 */
332 		D_ENCRYPT(l, r, 16); /*  9 */
333 		D_ENCRYPT(r, l, 18); /*  10 */
334 		D_ENCRYPT(l, r, 20); /*  11 */
335 		D_ENCRYPT(r, l, 22); /*  12 */
336 		D_ENCRYPT(l, r, 24); /*  13 */
337 		D_ENCRYPT(r, l, 26); /*  14 */
338 		D_ENCRYPT(l, r, 28); /*  15 */
339 		D_ENCRYPT(r, l, 30); /*  16 */
340 #else
341 		for (i = 0; i < 32; i += 4) {
342 			D_ENCRYPT(l, r, i + 0); /*  1 */
343 			D_ENCRYPT(r, l, i + 2); /*  2 */
344 		}
345 #endif
346 	} else {
347 #ifdef DES_UNROLL
348 		D_ENCRYPT(l, r, 30); /* 16 */
349 		D_ENCRYPT(r, l, 28); /* 15 */
350 		D_ENCRYPT(l, r, 26); /* 14 */
351 		D_ENCRYPT(r, l, 24); /* 13 */
352 		D_ENCRYPT(l, r, 22); /* 12 */
353 		D_ENCRYPT(r, l, 20); /* 11 */
354 		D_ENCRYPT(l, r, 18); /* 10 */
355 		D_ENCRYPT(r, l, 16); /*  9 */
356 		D_ENCRYPT(l, r, 14); /*  8 */
357 		D_ENCRYPT(r, l, 12); /*  7 */
358 		D_ENCRYPT(l, r, 10); /*  6 */
359 		D_ENCRYPT(r, l, 8); /*  5 */
360 		D_ENCRYPT(l, r, 6); /*  4 */
361 		D_ENCRYPT(r, l, 4); /*  3 */
362 		D_ENCRYPT(l, r, 2); /*  2 */
363 		D_ENCRYPT(r, l, 0); /*  1 */
364 #else
365 		for (i = 30; i > 0; i -= 4) {
366 			D_ENCRYPT(l, r, i - 0); /* 16 */
367 			D_ENCRYPT(r, l, i - 2); /* 15 */
368 		}
369 #endif
370 	}
371 	/* rotate and clear the top bits on machines with 8byte longs */
372 	data[0] = ROTATE(l, 3) & 0xffffffffL;
373 	data[1] = ROTATE(r, 3) & 0xffffffffL;
374 	l = r = t = u = 0;
375 }
376 LCRYPTO_ALIAS(DES_encrypt2);
377 
378 void
379 DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
380     DES_key_schedule *ks2, DES_key_schedule *ks3)
381 {
382 	DES_LONG l, r;
383 
384 	l = data[0];
385 	r = data[1];
386 	IP(l, r);
387 	data[0] = l;
388 	data[1] = r;
389 	DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT);
390 	DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT);
391 	DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT);
392 	l = data[0];
393 	r = data[1];
394 	FP(r, l);
395 	data[0] = l;
396 	data[1] = r;
397 }
398 LCRYPTO_ALIAS(DES_encrypt3);
399 
400 void
401 DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
402     DES_key_schedule *ks2, DES_key_schedule *ks3)
403 {
404 	DES_LONG l, r;
405 
406 	l = data[0];
407 	r = data[1];
408 	IP(l, r);
409 	data[0] = l;
410 	data[1] = r;
411 	DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT);
412 	DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT);
413 	DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT);
414 	l = data[0];
415 	r = data[1];
416 	FP(r, l);
417 	data[0] = l;
418 	data[1] = r;
419 }
420 LCRYPTO_ALIAS(DES_decrypt3);
421 
422 #ifndef DES_DEFAULT_OPTIONS
423 
424 void
425 DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length,
426     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
427 {
428 	DES_LONG tin0, tin1;
429 	DES_LONG tout0, tout1, xor0, xor1;
430 	long l = length;
431 	DES_LONG tin[2];
432 	unsigned char *iv;
433 
434 	iv = &(*ivec)[0];
435 
436 	if (enc) {
437 		c2l(iv, tout0);
438 		c2l(iv, tout1);
439 		for (l -= 8; l >= 0; l -= 8) {
440 			c2l(in, tin0);
441 			c2l(in, tin1);
442 			tin0 ^= tout0;
443 			tin[0] = tin0;
444 			tin1 ^= tout1;
445 			tin[1] = tin1;
446 			DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
447 			tout0 = tin[0];
448 			l2c(tout0, out);
449 			tout1 = tin[1];
450 			l2c(tout1, out);
451 		}
452 		if (l != -8) {
453 			c2ln(in, tin0, tin1, l + 8);
454 			tin0 ^= tout0;
455 			tin[0] = tin0;
456 			tin1 ^= tout1;
457 			tin[1] = tin1;
458 			DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
459 			tout0 = tin[0];
460 			l2c(tout0, out);
461 			tout1 = tin[1];
462 			l2c(tout1, out);
463 		}
464 		iv = &(*ivec)[0];
465 		l2c(tout0, iv);
466 		l2c(tout1, iv);
467 	} else {
468 		c2l(iv, xor0);
469 		c2l(iv, xor1);
470 		for (l -= 8; l >= 0; l -= 8) {
471 			c2l(in, tin0);
472 			tin[0] = tin0;
473 			c2l(in, tin1);
474 			tin[1] = tin1;
475 			DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
476 			tout0 = tin[0] ^ xor0;
477 			tout1 = tin[1] ^ xor1;
478 			l2c(tout0, out);
479 			l2c(tout1, out);
480 			xor0 = tin0;
481 			xor1 = tin1;
482 		}
483 		if (l != -8) {
484 			c2l(in, tin0);
485 			tin[0] = tin0;
486 			c2l(in, tin1);
487 			tin[1] = tin1;
488 			DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
489 			tout0 = tin[0] ^ xor0;
490 			tout1 = tin[1] ^ xor1;
491 			l2cn(tout0, tout1, out, l + 8);
492 			xor0 = tin0;
493 			xor1 = tin1;
494 		}
495 		iv = &(*ivec)[0];
496 		l2c(xor0, iv);
497 		l2c(xor1, iv);
498 	}
499 	tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
500 	tin[0] = tin[1] = 0;
501 }
502 LCRYPTO_ALIAS(DES_ncbc_encrypt);
503 
504 void
505 DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
506     long length, DES_key_schedule *ks1,
507     DES_key_schedule *ks2, DES_key_schedule *ks3,
508     DES_cblock *ivec, int enc)
509 {
510 	DES_LONG tin0, tin1;
511 	DES_LONG tout0, tout1, xor0, xor1;
512 	const unsigned char *in;
513 	unsigned char *out;
514 	long l = length;
515 	DES_LONG tin[2];
516 	unsigned char *iv;
517 
518 	in = input;
519 	out = output;
520 	iv = &(*ivec)[0];
521 
522 	if (enc) {
523 		c2l(iv, tout0);
524 		c2l(iv, tout1);
525 		for (l -= 8; l >= 0; l -= 8) {
526 			c2l(in, tin0);
527 			c2l(in, tin1);
528 			tin0 ^= tout0;
529 			tin1 ^= tout1;
530 
531 			tin[0] = tin0;
532 			tin[1] = tin1;
533 			DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
534 			tout0 = tin[0];
535 			tout1 = tin[1];
536 
537 			l2c(tout0, out);
538 			l2c(tout1, out);
539 		}
540 		if (l != -8) {
541 			c2ln(in, tin0, tin1, l + 8);
542 			tin0 ^= tout0;
543 			tin1 ^= tout1;
544 
545 			tin[0] = tin0;
546 			tin[1] = tin1;
547 			DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
548 			tout0 = tin[0];
549 			tout1 = tin[1];
550 
551 			l2c(tout0, out);
552 			l2c(tout1, out);
553 		}
554 		iv = &(*ivec)[0];
555 		l2c(tout0, iv);
556 		l2c(tout1, iv);
557 	} else {
558 		DES_LONG t0, t1;
559 
560 		c2l(iv, xor0);
561 		c2l(iv, xor1);
562 		for (l -= 8; l >= 0; l -= 8) {
563 			c2l(in, tin0);
564 			c2l(in, tin1);
565 
566 			t0 = tin0;
567 			t1 = tin1;
568 
569 			tin[0] = tin0;
570 			tin[1] = tin1;
571 			DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
572 			tout0 = tin[0];
573 			tout1 = tin[1];
574 
575 			tout0 ^= xor0;
576 			tout1 ^= xor1;
577 			l2c(tout0, out);
578 			l2c(tout1, out);
579 			xor0 = t0;
580 			xor1 = t1;
581 		}
582 		if (l != -8) {
583 			c2l(in, tin0);
584 			c2l(in, tin1);
585 
586 			t0 = tin0;
587 			t1 = tin1;
588 
589 			tin[0] = tin0;
590 			tin[1] = tin1;
591 			DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
592 			tout0 = tin[0];
593 			tout1 = tin[1];
594 
595 			tout0 ^= xor0;
596 			tout1 ^= xor1;
597 			l2cn(tout0, tout1, out, l + 8);
598 			xor0 = t0;
599 			xor1 = t1;
600 		}
601 
602 		iv = &(*ivec)[0];
603 		l2c(xor0, iv);
604 		l2c(xor1, iv);
605 	}
606 	tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
607 	tin[0] = tin[1] = 0;
608 }
609 LCRYPTO_ALIAS(DES_ede3_cbc_encrypt);
610 
611 #endif /* DES_DEFAULT_OPTIONS */
612