xref: /openbsd/lib/libcrypto/des/des_enc.c (revision 5dea098c)
1 /* $OpenBSD: des_enc.c,v 1.16 2024/03/29 01:47:29 joshua 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 #include "spr.h"
61 
62 #ifndef OPENBSD_DES_ASM
63 
64 void
65 DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
66 {
67 	DES_LONG l, r, t, u;
68 #ifdef DES_PTR
69 	const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
70 #endif
71 #ifndef DES_UNROLL
72 	int i;
73 #endif
74 	DES_LONG *s;
75 
76 	r = data[0];
77 	l = data[1];
78 
79 	IP(r, l);
80 	/* Things have been modified so that the initial rotate is
81 	 * done outside the loop.  This required the
82 	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
83 	 * One perl script later and things have a 5% speed up on a sparc2.
84 	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
85 	 * for pointing this out. */
86 	/* clear the top bits on machines with 8byte longs */
87 	/* shift left by 2 */
88 	r = ROTATE(r, 29) & 0xffffffffL;
89 	l = ROTATE(l, 29) & 0xffffffffL;
90 
91 	s = ks->ks->deslong;
92 	/* I don't know if it is worth the effort of loop unrolling the
93 	 * inner loop */
94 	if (enc) {
95 #ifdef DES_UNROLL
96 		D_ENCRYPT(l, r, 0); /*  1 */
97 		D_ENCRYPT(r, l, 2); /*  2 */
98 		D_ENCRYPT(l, r, 4); /*  3 */
99 		D_ENCRYPT(r, l, 6); /*  4 */
100 		D_ENCRYPT(l, r, 8); /*  5 */
101 		D_ENCRYPT(r, l, 10); /*  6 */
102 		D_ENCRYPT(l, r, 12); /*  7 */
103 		D_ENCRYPT(r, l, 14); /*  8 */
104 		D_ENCRYPT(l, r, 16); /*  9 */
105 		D_ENCRYPT(r, l, 18); /*  10 */
106 		D_ENCRYPT(l, r, 20); /*  11 */
107 		D_ENCRYPT(r, l, 22); /*  12 */
108 		D_ENCRYPT(l, r, 24); /*  13 */
109 		D_ENCRYPT(r, l, 26); /*  14 */
110 		D_ENCRYPT(l, r, 28); /*  15 */
111 		D_ENCRYPT(r, l, 30); /*  16 */
112 #else
113 		for (i = 0; i < 32; i += 4) {
114 			D_ENCRYPT(l, r, i + 0); /*  1 */
115 			D_ENCRYPT(r, l, i + 2); /*  2 */
116 		}
117 #endif
118 	} else {
119 #ifdef DES_UNROLL
120 		D_ENCRYPT(l, r, 30); /* 16 */
121 		D_ENCRYPT(r, l, 28); /* 15 */
122 		D_ENCRYPT(l, r, 26); /* 14 */
123 		D_ENCRYPT(r, l, 24); /* 13 */
124 		D_ENCRYPT(l, r, 22); /* 12 */
125 		D_ENCRYPT(r, l, 20); /* 11 */
126 		D_ENCRYPT(l, r, 18); /* 10 */
127 		D_ENCRYPT(r, l, 16); /*  9 */
128 		D_ENCRYPT(l, r, 14); /*  8 */
129 		D_ENCRYPT(r, l, 12); /*  7 */
130 		D_ENCRYPT(l, r, 10); /*  6 */
131 		D_ENCRYPT(r, l, 8); /*  5 */
132 		D_ENCRYPT(l, r, 6); /*  4 */
133 		D_ENCRYPT(r, l, 4); /*  3 */
134 		D_ENCRYPT(l, r, 2); /*  2 */
135 		D_ENCRYPT(r, l, 0); /*  1 */
136 #else
137 		for (i = 30; i > 0; i -= 4) {
138 			D_ENCRYPT(l, r, i - 0); /* 16 */
139 			D_ENCRYPT(r, l, i - 2); /* 15 */
140 		}
141 #endif
142 	}
143 
144 	/* rotate and clear the top bits on machines with 8byte longs */
145 	l = ROTATE(l, 3) & 0xffffffffL;
146 	r = ROTATE(r, 3) & 0xffffffffL;
147 
148 	FP(r, l);
149 	data[0] = l;
150 	data[1] = r;
151 	l = r = t = u = 0;
152 }
153 LCRYPTO_ALIAS(DES_encrypt1);
154 
155 void
156 DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
157 {
158 	DES_LONG l, r, t, u;
159 #ifdef DES_PTR
160 	const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
161 #endif
162 #ifndef DES_UNROLL
163 	int i;
164 #endif
165 	DES_LONG *s;
166 
167 	r = data[0];
168 	l = data[1];
169 
170 	/* Things have been modified so that the initial rotate is
171 	 * done outside the loop.  This required the
172 	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
173 	 * One perl script later and things have a 5% speed up on a sparc2.
174 	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
175 	 * for pointing this out. */
176 	/* clear the top bits on machines with 8byte longs */
177 	r = ROTATE(r, 29) & 0xffffffffL;
178 	l = ROTATE(l, 29) & 0xffffffffL;
179 
180 	s = ks->ks->deslong;
181 	/* I don't know if it is worth the effort of loop unrolling the
182 	 * inner loop */
183 	if (enc) {
184 #ifdef DES_UNROLL
185 		D_ENCRYPT(l, r, 0); /*  1 */
186 		D_ENCRYPT(r, l, 2); /*  2 */
187 		D_ENCRYPT(l, r, 4); /*  3 */
188 		D_ENCRYPT(r, l, 6); /*  4 */
189 		D_ENCRYPT(l, r, 8); /*  5 */
190 		D_ENCRYPT(r, l, 10); /*  6 */
191 		D_ENCRYPT(l, r, 12); /*  7 */
192 		D_ENCRYPT(r, l, 14); /*  8 */
193 		D_ENCRYPT(l, r, 16); /*  9 */
194 		D_ENCRYPT(r, l, 18); /*  10 */
195 		D_ENCRYPT(l, r, 20); /*  11 */
196 		D_ENCRYPT(r, l, 22); /*  12 */
197 		D_ENCRYPT(l, r, 24); /*  13 */
198 		D_ENCRYPT(r, l, 26); /*  14 */
199 		D_ENCRYPT(l, r, 28); /*  15 */
200 		D_ENCRYPT(r, l, 30); /*  16 */
201 #else
202 		for (i = 0; i < 32; i += 4) {
203 			D_ENCRYPT(l, r, i + 0); /*  1 */
204 			D_ENCRYPT(r, l, i + 2); /*  2 */
205 		}
206 #endif
207 	} else {
208 #ifdef DES_UNROLL
209 		D_ENCRYPT(l, r, 30); /* 16 */
210 		D_ENCRYPT(r, l, 28); /* 15 */
211 		D_ENCRYPT(l, r, 26); /* 14 */
212 		D_ENCRYPT(r, l, 24); /* 13 */
213 		D_ENCRYPT(l, r, 22); /* 12 */
214 		D_ENCRYPT(r, l, 20); /* 11 */
215 		D_ENCRYPT(l, r, 18); /* 10 */
216 		D_ENCRYPT(r, l, 16); /*  9 */
217 		D_ENCRYPT(l, r, 14); /*  8 */
218 		D_ENCRYPT(r, l, 12); /*  7 */
219 		D_ENCRYPT(l, r, 10); /*  6 */
220 		D_ENCRYPT(r, l, 8); /*  5 */
221 		D_ENCRYPT(l, r, 6); /*  4 */
222 		D_ENCRYPT(r, l, 4); /*  3 */
223 		D_ENCRYPT(l, r, 2); /*  2 */
224 		D_ENCRYPT(r, l, 0); /*  1 */
225 #else
226 		for (i = 30; i > 0; i -= 4) {
227 			D_ENCRYPT(l, r, i - 0); /* 16 */
228 			D_ENCRYPT(r, l, i - 2); /* 15 */
229 		}
230 #endif
231 	}
232 	/* rotate and clear the top bits on machines with 8byte longs */
233 	data[0] = ROTATE(l, 3) & 0xffffffffL;
234 	data[1] = ROTATE(r, 3) & 0xffffffffL;
235 	l = r = t = u = 0;
236 }
237 LCRYPTO_ALIAS(DES_encrypt2);
238 
239 #endif /* OPENBSD_DES_ASM */
240 
241 void
242 DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
243     DES_key_schedule *ks2, DES_key_schedule *ks3)
244 {
245 	DES_LONG l, r;
246 
247 	l = data[0];
248 	r = data[1];
249 	IP(l, r);
250 	data[0] = l;
251 	data[1] = r;
252 	DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT);
253 	DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT);
254 	DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT);
255 	l = data[0];
256 	r = data[1];
257 	FP(r, l);
258 	data[0] = l;
259 	data[1] = r;
260 }
261 LCRYPTO_ALIAS(DES_encrypt3);
262 
263 void
264 DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
265     DES_key_schedule *ks2, DES_key_schedule *ks3)
266 {
267 	DES_LONG l, r;
268 
269 	l = data[0];
270 	r = data[1];
271 	IP(l, r);
272 	data[0] = l;
273 	data[1] = r;
274 	DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT);
275 	DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT);
276 	DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT);
277 	l = data[0];
278 	r = data[1];
279 	FP(r, l);
280 	data[0] = l;
281 	data[1] = r;
282 }
283 LCRYPTO_ALIAS(DES_decrypt3);
284 
285 #ifndef DES_DEFAULT_OPTIONS
286 
287 #undef CBC_ENC_C__DONT_UPDATE_IV
288 #include "ncbc_enc.c" /* DES_ncbc_encrypt */
289 
290 void
291 DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
292     long length, DES_key_schedule *ks1,
293     DES_key_schedule *ks2, DES_key_schedule *ks3,
294     DES_cblock *ivec, int enc)
295 {
296 	DES_LONG tin0, tin1;
297 	DES_LONG tout0, tout1, xor0, xor1;
298 	const unsigned char *in;
299 	unsigned char *out;
300 	long l = length;
301 	DES_LONG tin[2];
302 	unsigned char *iv;
303 
304 	in = input;
305 	out = output;
306 	iv = &(*ivec)[0];
307 
308 	if (enc) {
309 		c2l(iv, tout0);
310 		c2l(iv, tout1);
311 		for (l -= 8; l >= 0; l -= 8) {
312 			c2l(in, tin0);
313 			c2l(in, tin1);
314 			tin0 ^= tout0;
315 			tin1 ^= tout1;
316 
317 			tin[0] = tin0;
318 			tin[1] = tin1;
319 			DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
320 			tout0 = tin[0];
321 			tout1 = tin[1];
322 
323 			l2c(tout0, out);
324 			l2c(tout1, out);
325 		}
326 		if (l != -8) {
327 			c2ln(in, tin0, tin1, l + 8);
328 			tin0 ^= tout0;
329 			tin1 ^= tout1;
330 
331 			tin[0] = tin0;
332 			tin[1] = tin1;
333 			DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
334 			tout0 = tin[0];
335 			tout1 = tin[1];
336 
337 			l2c(tout0, out);
338 			l2c(tout1, out);
339 		}
340 		iv = &(*ivec)[0];
341 		l2c(tout0, iv);
342 		l2c(tout1, iv);
343 	} else {
344 		DES_LONG t0, t1;
345 
346 		c2l(iv, xor0);
347 		c2l(iv, xor1);
348 		for (l -= 8; l >= 0; l -= 8) {
349 			c2l(in, tin0);
350 			c2l(in, tin1);
351 
352 			t0 = tin0;
353 			t1 = tin1;
354 
355 			tin[0] = tin0;
356 			tin[1] = tin1;
357 			DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
358 			tout0 = tin[0];
359 			tout1 = tin[1];
360 
361 			tout0 ^= xor0;
362 			tout1 ^= xor1;
363 			l2c(tout0, out);
364 			l2c(tout1, out);
365 			xor0 = t0;
366 			xor1 = t1;
367 		}
368 		if (l != -8) {
369 			c2l(in, tin0);
370 			c2l(in, tin1);
371 
372 			t0 = tin0;
373 			t1 = tin1;
374 
375 			tin[0] = tin0;
376 			tin[1] = tin1;
377 			DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
378 			tout0 = tin[0];
379 			tout1 = tin[1];
380 
381 			tout0 ^= xor0;
382 			tout1 ^= xor1;
383 			l2cn(tout0, tout1, out, l + 8);
384 			xor0 = t0;
385 			xor1 = t1;
386 		}
387 
388 		iv = &(*ivec)[0];
389 		l2c(xor0, iv);
390 		l2c(xor1, iv);
391 	}
392 	tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
393 	tin[0] = tin[1] = 0;
394 }
395 LCRYPTO_ALIAS(DES_ede3_cbc_encrypt);
396 
397 #endif /* DES_DEFAULT_OPTIONS */
398