191671Sume/*	$KAME: des_enc.c,v 1.1 2001/09/10 04:03:58 itojun Exp $	*/
291671Sume
391671Sume/* crypto/des/des_enc.c */
4130443Sobrien
591671Sume/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
691671Sume * All rights reserved.
791671Sume *
891671Sume * This package is an SSL implementation written
991671Sume * by Eric Young (eay@cryptsoft.com).
1091671Sume * The implementation was written so as to conform with Netscapes SSL.
1191671Sume *
1291671Sume * This library is free for commercial and non-commercial use as long as
1391671Sume * the following conditions are aheared to.  The following conditions
1491671Sume * apply to all code found in this distribution, be it the RC4, RSA,
1591671Sume * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1691671Sume * included with this distribution is covered by the same copyright terms
1791671Sume * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1891671Sume *
1991671Sume * Copyright remains Eric Young's, and as such any Copyright notices in
2091671Sume * the code are not to be removed.
2191671Sume * If this package is used in a product, Eric Young should be given attribution
2291671Sume * as the author of the parts of the library used.
2391671Sume * This can be in the form of a textual message at program startup or
2491671Sume * in documentation (online or textual) provided with the package.
2591671Sume *
2691671Sume * Redistribution and use in source and binary forms, with or without
2791671Sume * modification, are permitted provided that the following conditions
2891671Sume * are met:
2991671Sume * 1. Redistributions of source code must retain the copyright
3091671Sume *    notice, this list of conditions and the following disclaimer.
3191671Sume * 2. Redistributions in binary form must reproduce the above copyright
3291671Sume *    notice, this list of conditions and the following disclaimer in the
3391671Sume *    documentation and/or other materials provided with the distribution.
3491671Sume * 3. All advertising materials mentioning features or use of this software
3591671Sume *    must display the following acknowledgement:
3691671Sume *    "This product includes cryptographic software written by
3791671Sume *     Eric Young (eay@cryptsoft.com)"
3891671Sume *    The word 'cryptographic' can be left out if the rouines from the library
3991671Sume *    being used are not cryptographic related :-).
4091671Sume * 4. If you include any Windows specific code (or a derivative thereof) from
4191671Sume *    the apps directory (application code) you must include an acknowledgement:
4291671Sume *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4391671Sume *
4491671Sume * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4591671Sume * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4691671Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4791671Sume * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4891671Sume * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4991671Sume * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5091671Sume * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5191671Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5291671Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5391671Sume * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5491671Sume * SUCH DAMAGE.
5591671Sume *
5691671Sume * The licence and distribution terms for any publically available version or
5791671Sume * derivative of this code cannot be changed.  i.e. this code cannot simply be
5891671Sume * copied and put under another distribution licence
5991671Sume * [including the GNU Public Licence.]
6091671Sume */
6191671Sume
62130443Sobrien#include <sys/cdefs.h>
63130443Sobrien__FBSDID("$FreeBSD$");
64130443Sobrien
6591671Sume#include <sys/types.h>
6691671Sume#include <crypto/des/des_locl.h>
6791671Sume
6891671Sumeextern	const DES_LONG des_SPtrans[8][64];
6991671Sume
7091671Sumevoid des_encrypt1(DES_LONG *data, des_key_schedule ks, int enc)
7191671Sume{
7291671Sume	register DES_LONG l,r,t,u;
7391671Sume#ifdef DES_PTR
7491671Sume	register const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
7591671Sume#endif
7691671Sume#ifndef DES_UNROLL
7791671Sume	register int i;
7891671Sume#endif
7991671Sume	register DES_LONG *s;
8091671Sume
8191671Sume	r=data[0];
8291671Sume	l=data[1];
8391671Sume
8491671Sume	IP(r,l);
8591671Sume	/* Things have been modified so that the initial rotate is
8691671Sume	 * done outside the loop.  This required the
8791671Sume	 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
8891671Sume	 * One perl script later and things have a 5% speed up on a sparc2.
8991671Sume	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
9091671Sume	 * for pointing this out. */
9191671Sume	/* clear the top bits on machines with 8byte longs */
9291671Sume	/* shift left by 2 */
9391671Sume	r=ROTATE(r,29)&0xffffffffL;
9491671Sume	l=ROTATE(l,29)&0xffffffffL;
9591671Sume
9691671Sume	s=ks->ks.deslong;
9791671Sume	/* I don't know if it is worth the effort of loop unrolling the
9891671Sume	 * inner loop */
9991671Sume	if (enc)
10091671Sume		{
10191671Sume#ifdef DES_UNROLL
10291671Sume		D_ENCRYPT(l,r, 0); /*  1 */
10391671Sume		D_ENCRYPT(r,l, 2); /*  2 */
10491671Sume		D_ENCRYPT(l,r, 4); /*  3 */
10591671Sume		D_ENCRYPT(r,l, 6); /*  4 */
10691671Sume		D_ENCRYPT(l,r, 8); /*  5 */
10791671Sume		D_ENCRYPT(r,l,10); /*  6 */
10891671Sume		D_ENCRYPT(l,r,12); /*  7 */
10991671Sume		D_ENCRYPT(r,l,14); /*  8 */
11091671Sume		D_ENCRYPT(l,r,16); /*  9 */
11191671Sume		D_ENCRYPT(r,l,18); /*  10 */
11291671Sume		D_ENCRYPT(l,r,20); /*  11 */
11391671Sume		D_ENCRYPT(r,l,22); /*  12 */
11491671Sume		D_ENCRYPT(l,r,24); /*  13 */
11591671Sume		D_ENCRYPT(r,l,26); /*  14 */
11691671Sume		D_ENCRYPT(l,r,28); /*  15 */
11791671Sume		D_ENCRYPT(r,l,30); /*  16 */
11891671Sume#else
11991671Sume		for (i=0; i<32; i+=8)
12091671Sume			{
12191671Sume			D_ENCRYPT(l,r,i+0); /*  1 */
12291671Sume			D_ENCRYPT(r,l,i+2); /*  2 */
12391671Sume			D_ENCRYPT(l,r,i+4); /*  3 */
12491671Sume			D_ENCRYPT(r,l,i+6); /*  4 */
12591671Sume			}
12691671Sume#endif
12791671Sume		}
12891671Sume	else
12991671Sume		{
13091671Sume#ifdef DES_UNROLL
13191671Sume		D_ENCRYPT(l,r,30); /* 16 */
13291671Sume		D_ENCRYPT(r,l,28); /* 15 */
13391671Sume		D_ENCRYPT(l,r,26); /* 14 */
13491671Sume		D_ENCRYPT(r,l,24); /* 13 */
13591671Sume		D_ENCRYPT(l,r,22); /* 12 */
13691671Sume		D_ENCRYPT(r,l,20); /* 11 */
13791671Sume		D_ENCRYPT(l,r,18); /* 10 */
13891671Sume		D_ENCRYPT(r,l,16); /*  9 */
13991671Sume		D_ENCRYPT(l,r,14); /*  8 */
14091671Sume		D_ENCRYPT(r,l,12); /*  7 */
14191671Sume		D_ENCRYPT(l,r,10); /*  6 */
14291671Sume		D_ENCRYPT(r,l, 8); /*  5 */
14391671Sume		D_ENCRYPT(l,r, 6); /*  4 */
14491671Sume		D_ENCRYPT(r,l, 4); /*  3 */
14591671Sume		D_ENCRYPT(l,r, 2); /*  2 */
14691671Sume		D_ENCRYPT(r,l, 0); /*  1 */
14791671Sume#else
14891671Sume		for (i=30; i>0; i-=8)
14991671Sume			{
15091671Sume			D_ENCRYPT(l,r,i-0); /* 16 */
15191671Sume			D_ENCRYPT(r,l,i-2); /* 15 */
15291671Sume			D_ENCRYPT(l,r,i-4); /* 14 */
15391671Sume			D_ENCRYPT(r,l,i-6); /* 13 */
15491671Sume			}
15591671Sume#endif
15691671Sume		}
15791671Sume
15891671Sume	/* rotate and clear the top bits on machines with 8byte longs */
15991671Sume	l=ROTATE(l,3)&0xffffffffL;
16091671Sume	r=ROTATE(r,3)&0xffffffffL;
16191671Sume
16291671Sume	FP(r,l);
16391671Sume	data[0]=l;
16491671Sume	data[1]=r;
16591671Sume	l=r=t=u=0;
16691671Sume}
16791671Sume
16891671Sumevoid des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
16991671Sume{
17091671Sume	register DES_LONG l,r,t,u;
17191671Sume#ifdef DES_PTR
17291671Sume	register const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
17391671Sume#endif
17491671Sume#ifndef DES_UNROLL
17591671Sume	register int i;
17691671Sume#endif
17791671Sume	register DES_LONG *s;
17891671Sume
17991671Sume	r=data[0];
18091671Sume	l=data[1];
18191671Sume
18291671Sume	/* Things have been modified so that the initial rotate is
18391671Sume	 * done outside the loop.  This required the
18491671Sume	 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18591671Sume	 * One perl script later and things have a 5% speed up on a sparc2.
18691671Sume	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18791671Sume	 * for pointing this out. */
18891671Sume	/* clear the top bits on machines with 8byte longs */
18991671Sume	r=ROTATE(r,29)&0xffffffffL;
19091671Sume	l=ROTATE(l,29)&0xffffffffL;
19191671Sume
19291671Sume	s=ks->ks.deslong;
19391671Sume	/* I don't know if it is worth the effort of loop unrolling the
19491671Sume	 * inner loop */
19591671Sume	if (enc)
19691671Sume		{
19791671Sume#ifdef DES_UNROLL
19891671Sume		D_ENCRYPT(l,r, 0); /*  1 */
19991671Sume		D_ENCRYPT(r,l, 2); /*  2 */
20091671Sume		D_ENCRYPT(l,r, 4); /*  3 */
20191671Sume		D_ENCRYPT(r,l, 6); /*  4 */
20291671Sume		D_ENCRYPT(l,r, 8); /*  5 */
20391671Sume		D_ENCRYPT(r,l,10); /*  6 */
20491671Sume		D_ENCRYPT(l,r,12); /*  7 */
20591671Sume		D_ENCRYPT(r,l,14); /*  8 */
20691671Sume		D_ENCRYPT(l,r,16); /*  9 */
20791671Sume		D_ENCRYPT(r,l,18); /*  10 */
20891671Sume		D_ENCRYPT(l,r,20); /*  11 */
20991671Sume		D_ENCRYPT(r,l,22); /*  12 */
21091671Sume		D_ENCRYPT(l,r,24); /*  13 */
21191671Sume		D_ENCRYPT(r,l,26); /*  14 */
21291671Sume		D_ENCRYPT(l,r,28); /*  15 */
21391671Sume		D_ENCRYPT(r,l,30); /*  16 */
21491671Sume#else
21591671Sume		for (i=0; i<32; i+=8)
21691671Sume			{
21791671Sume			D_ENCRYPT(l,r,i+0); /*  1 */
21891671Sume			D_ENCRYPT(r,l,i+2); /*  2 */
21991671Sume			D_ENCRYPT(l,r,i+4); /*  3 */
22091671Sume			D_ENCRYPT(r,l,i+6); /*  4 */
22191671Sume			}
22291671Sume#endif
22391671Sume		}
22491671Sume	else
22591671Sume		{
22691671Sume#ifdef DES_UNROLL
22791671Sume		D_ENCRYPT(l,r,30); /* 16 */
22891671Sume		D_ENCRYPT(r,l,28); /* 15 */
22991671Sume		D_ENCRYPT(l,r,26); /* 14 */
23091671Sume		D_ENCRYPT(r,l,24); /* 13 */
23191671Sume		D_ENCRYPT(l,r,22); /* 12 */
23291671Sume		D_ENCRYPT(r,l,20); /* 11 */
23391671Sume		D_ENCRYPT(l,r,18); /* 10 */
23491671Sume		D_ENCRYPT(r,l,16); /*  9 */
23591671Sume		D_ENCRYPT(l,r,14); /*  8 */
23691671Sume		D_ENCRYPT(r,l,12); /*  7 */
23791671Sume		D_ENCRYPT(l,r,10); /*  6 */
23891671Sume		D_ENCRYPT(r,l, 8); /*  5 */
23991671Sume		D_ENCRYPT(l,r, 6); /*  4 */
24091671Sume		D_ENCRYPT(r,l, 4); /*  3 */
24191671Sume		D_ENCRYPT(l,r, 2); /*  2 */
24291671Sume		D_ENCRYPT(r,l, 0); /*  1 */
24391671Sume#else
24491671Sume		for (i=30; i>0; i-=8)
24591671Sume			{
24691671Sume			D_ENCRYPT(l,r,i-0); /* 16 */
24791671Sume			D_ENCRYPT(r,l,i-2); /* 15 */
24891671Sume			D_ENCRYPT(l,r,i-4); /* 14 */
24991671Sume			D_ENCRYPT(r,l,i-6); /* 13 */
25091671Sume			}
25191671Sume#endif
25291671Sume		}
25391671Sume	/* rotate and clear the top bits on machines with 8byte longs */
25491671Sume	data[0]=ROTATE(l,3)&0xffffffffL;
25591671Sume	data[1]=ROTATE(r,3)&0xffffffffL;
25691671Sume	l=r=t=u=0;
25791671Sume}
25891671Sume
25991671Sumevoid des_encrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2,
26091671Sume	     des_key_schedule ks3)
26191671Sume{
26291671Sume	register DES_LONG l,r;
26391671Sume
26491671Sume	l=data[0];
26591671Sume	r=data[1];
26691671Sume	IP(l,r);
26791671Sume	data[0]=l;
26891671Sume	data[1]=r;
26991671Sume	des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
27091671Sume	des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
27191671Sume	des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
27291671Sume	l=data[0];
27391671Sume	r=data[1];
27491671Sume	FP(r,l);
27591671Sume	data[0]=l;
27691671Sume	data[1]=r;
27791671Sume}
27891671Sume
27991671Sumevoid des_decrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2,
28091671Sume	     des_key_schedule ks3)
28191671Sume{
28291671Sume	register DES_LONG l,r;
28391671Sume
28491671Sume	l=data[0];
28591671Sume	r=data[1];
28691671Sume	IP(l,r);
28791671Sume	data[0]=l;
28891671Sume	data[1]=r;
28991671Sume	des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
29091671Sume	des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
29191671Sume	des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
29291671Sume	l=data[0];
29391671Sume	r=data[1];
29491671Sume	FP(r,l);
29591671Sume	data[0]=l;
29691671Sume	data[1]=r;
29791671Sume}
298