1/*	$KAME: des_enc.c,v 1.1 2001/09/10 04:03:58 itojun Exp $	*/
2
3/* crypto/des/des_enc.c */
4
5/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
6 * All rights reserved.
7 *
8 * This package is an SSL implementation written
9 * by Eric Young (eay@cryptsoft.com).
10 * The implementation was written so as to conform with Netscapes SSL.
11 *
12 * This library is free for commercial and non-commercial use as long as
13 * the following conditions are aheared to.  The following conditions
14 * apply to all code found in this distribution, be it the RC4, RSA,
15 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
16 * included with this distribution is covered by the same copyright terms
17 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18 *
19 * Copyright remains Eric Young's, and as such any Copyright notices in
20 * the code are not to be removed.
21 * If this package is used in a product, Eric Young should be given attribution
22 * as the author of the parts of the library used.
23 * This can be in the form of a textual message at program startup or
24 * in documentation (online or textual) provided with the package.
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
28 * are met:
29 * 1. Redistributions of source code must retain the copyright
30 *    notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 *    notice, this list of conditions and the following disclaimer in the
33 *    documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 *    must display the following acknowledgement:
36 *    "This product includes cryptographic software written by
37 *     Eric Young (eay@cryptsoft.com)"
38 *    The word 'cryptographic' can be left out if the rouines from the library
39 *    being used are not cryptographic related :-).
40 * 4. If you include any Windows specific code (or a derivative thereof) from
41 *    the apps directory (application code) you must include an acknowledgement:
42 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
43 *
44 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 *
56 * The licence and distribution terms for any publically available version or
57 * derivative of this code cannot be changed.  i.e. this code cannot simply be
58 * copied and put under another distribution licence
59 * [including the GNU Public Licence.]
60 */
61
62#include <sys/cdefs.h>
63__FBSDID("$FreeBSD$");
64
65#include <sys/types.h>
66#include <crypto/des/des_locl.h>
67
68extern	const DES_LONG des_SPtrans[8][64];
69
70void des_encrypt1(DES_LONG *data, des_key_schedule ks, int enc)
71{
72	register DES_LONG l,r,t,u;
73#ifdef DES_PTR
74	register const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
75#endif
76#ifndef DES_UNROLL
77	register int i;
78#endif
79	register DES_LONG *s;
80
81	r=data[0];
82	l=data[1];
83
84	IP(r,l);
85	/* Things have been modified so that the initial rotate is
86	 * done outside the loop.  This required the
87	 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
88	 * One perl script later and things have a 5% speed up on a sparc2.
89	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
90	 * for pointing this out. */
91	/* clear the top bits on machines with 8byte longs */
92	/* shift left by 2 */
93	r=ROTATE(r,29)&0xffffffffL;
94	l=ROTATE(l,29)&0xffffffffL;
95
96	s=ks->ks.deslong;
97	/* I don't know if it is worth the effort of loop unrolling the
98	 * inner loop */
99	if (enc)
100		{
101#ifdef DES_UNROLL
102		D_ENCRYPT(l,r, 0); /*  1 */
103		D_ENCRYPT(r,l, 2); /*  2 */
104		D_ENCRYPT(l,r, 4); /*  3 */
105		D_ENCRYPT(r,l, 6); /*  4 */
106		D_ENCRYPT(l,r, 8); /*  5 */
107		D_ENCRYPT(r,l,10); /*  6 */
108		D_ENCRYPT(l,r,12); /*  7 */
109		D_ENCRYPT(r,l,14); /*  8 */
110		D_ENCRYPT(l,r,16); /*  9 */
111		D_ENCRYPT(r,l,18); /*  10 */
112		D_ENCRYPT(l,r,20); /*  11 */
113		D_ENCRYPT(r,l,22); /*  12 */
114		D_ENCRYPT(l,r,24); /*  13 */
115		D_ENCRYPT(r,l,26); /*  14 */
116		D_ENCRYPT(l,r,28); /*  15 */
117		D_ENCRYPT(r,l,30); /*  16 */
118#else
119		for (i=0; i<32; i+=8)
120			{
121			D_ENCRYPT(l,r,i+0); /*  1 */
122			D_ENCRYPT(r,l,i+2); /*  2 */
123			D_ENCRYPT(l,r,i+4); /*  3 */
124			D_ENCRYPT(r,l,i+6); /*  4 */
125			}
126#endif
127		}
128	else
129		{
130#ifdef DES_UNROLL
131		D_ENCRYPT(l,r,30); /* 16 */
132		D_ENCRYPT(r,l,28); /* 15 */
133		D_ENCRYPT(l,r,26); /* 14 */
134		D_ENCRYPT(r,l,24); /* 13 */
135		D_ENCRYPT(l,r,22); /* 12 */
136		D_ENCRYPT(r,l,20); /* 11 */
137		D_ENCRYPT(l,r,18); /* 10 */
138		D_ENCRYPT(r,l,16); /*  9 */
139		D_ENCRYPT(l,r,14); /*  8 */
140		D_ENCRYPT(r,l,12); /*  7 */
141		D_ENCRYPT(l,r,10); /*  6 */
142		D_ENCRYPT(r,l, 8); /*  5 */
143		D_ENCRYPT(l,r, 6); /*  4 */
144		D_ENCRYPT(r,l, 4); /*  3 */
145		D_ENCRYPT(l,r, 2); /*  2 */
146		D_ENCRYPT(r,l, 0); /*  1 */
147#else
148		for (i=30; i>0; i-=8)
149			{
150			D_ENCRYPT(l,r,i-0); /* 16 */
151			D_ENCRYPT(r,l,i-2); /* 15 */
152			D_ENCRYPT(l,r,i-4); /* 14 */
153			D_ENCRYPT(r,l,i-6); /* 13 */
154			}
155#endif
156		}
157
158	/* rotate and clear the top bits on machines with 8byte longs */
159	l=ROTATE(l,3)&0xffffffffL;
160	r=ROTATE(r,3)&0xffffffffL;
161
162	FP(r,l);
163	data[0]=l;
164	data[1]=r;
165	l=r=t=u=0;
166}
167
168void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
169{
170	register DES_LONG l,r,t,u;
171#ifdef DES_PTR
172	register const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
173#endif
174#ifndef DES_UNROLL
175	register int i;
176#endif
177	register DES_LONG *s;
178
179	r=data[0];
180	l=data[1];
181
182	/* Things have been modified so that the initial rotate is
183	 * done outside the loop.  This required the
184	 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
185	 * One perl script later and things have a 5% speed up on a sparc2.
186	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
187	 * for pointing this out. */
188	/* clear the top bits on machines with 8byte longs */
189	r=ROTATE(r,29)&0xffffffffL;
190	l=ROTATE(l,29)&0xffffffffL;
191
192	s=ks->ks.deslong;
193	/* I don't know if it is worth the effort of loop unrolling the
194	 * inner loop */
195	if (enc)
196		{
197#ifdef DES_UNROLL
198		D_ENCRYPT(l,r, 0); /*  1 */
199		D_ENCRYPT(r,l, 2); /*  2 */
200		D_ENCRYPT(l,r, 4); /*  3 */
201		D_ENCRYPT(r,l, 6); /*  4 */
202		D_ENCRYPT(l,r, 8); /*  5 */
203		D_ENCRYPT(r,l,10); /*  6 */
204		D_ENCRYPT(l,r,12); /*  7 */
205		D_ENCRYPT(r,l,14); /*  8 */
206		D_ENCRYPT(l,r,16); /*  9 */
207		D_ENCRYPT(r,l,18); /*  10 */
208		D_ENCRYPT(l,r,20); /*  11 */
209		D_ENCRYPT(r,l,22); /*  12 */
210		D_ENCRYPT(l,r,24); /*  13 */
211		D_ENCRYPT(r,l,26); /*  14 */
212		D_ENCRYPT(l,r,28); /*  15 */
213		D_ENCRYPT(r,l,30); /*  16 */
214#else
215		for (i=0; i<32; i+=8)
216			{
217			D_ENCRYPT(l,r,i+0); /*  1 */
218			D_ENCRYPT(r,l,i+2); /*  2 */
219			D_ENCRYPT(l,r,i+4); /*  3 */
220			D_ENCRYPT(r,l,i+6); /*  4 */
221			}
222#endif
223		}
224	else
225		{
226#ifdef DES_UNROLL
227		D_ENCRYPT(l,r,30); /* 16 */
228		D_ENCRYPT(r,l,28); /* 15 */
229		D_ENCRYPT(l,r,26); /* 14 */
230		D_ENCRYPT(r,l,24); /* 13 */
231		D_ENCRYPT(l,r,22); /* 12 */
232		D_ENCRYPT(r,l,20); /* 11 */
233		D_ENCRYPT(l,r,18); /* 10 */
234		D_ENCRYPT(r,l,16); /*  9 */
235		D_ENCRYPT(l,r,14); /*  8 */
236		D_ENCRYPT(r,l,12); /*  7 */
237		D_ENCRYPT(l,r,10); /*  6 */
238		D_ENCRYPT(r,l, 8); /*  5 */
239		D_ENCRYPT(l,r, 6); /*  4 */
240		D_ENCRYPT(r,l, 4); /*  3 */
241		D_ENCRYPT(l,r, 2); /*  2 */
242		D_ENCRYPT(r,l, 0); /*  1 */
243#else
244		for (i=30; i>0; i-=8)
245			{
246			D_ENCRYPT(l,r,i-0); /* 16 */
247			D_ENCRYPT(r,l,i-2); /* 15 */
248			D_ENCRYPT(l,r,i-4); /* 14 */
249			D_ENCRYPT(r,l,i-6); /* 13 */
250			}
251#endif
252		}
253	/* rotate and clear the top bits on machines with 8byte longs */
254	data[0]=ROTATE(l,3)&0xffffffffL;
255	data[1]=ROTATE(r,3)&0xffffffffL;
256	l=r=t=u=0;
257}
258
259void des_encrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2,
260	     des_key_schedule ks3)
261{
262	register DES_LONG l,r;
263
264	l=data[0];
265	r=data[1];
266	IP(l,r);
267	data[0]=l;
268	data[1]=r;
269	des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
270	des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
271	des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
272	l=data[0];
273	r=data[1];
274	FP(r,l);
275	data[0]=l;
276	data[1]=r;
277}
278
279void des_decrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2,
280	     des_key_schedule ks3)
281{
282	register DES_LONG l,r;
283
284	l=data[0];
285	r=data[1];
286	IP(l,r);
287	data[0]=l;
288	data[1]=r;
289	des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
290	des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
291	des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
292	l=data[0];
293	r=data[1];
294	FP(r,l);
295	data[0]=l;
296	data[1]=r;
297}
298