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