xref: /onnv-gate/usr/src/common/openssl/crypto/des/des_locl.h (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/des/des_locl.h */
20Sstevel@tonic-gate /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #ifndef HEADER_DES_LOCL_H
600Sstevel@tonic-gate #define HEADER_DES_LOCL_H
610Sstevel@tonic-gate 
620Sstevel@tonic-gate #include <openssl/e_os2.h>
630Sstevel@tonic-gate 
640Sstevel@tonic-gate #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
650Sstevel@tonic-gate #ifndef OPENSSL_SYS_MSDOS
660Sstevel@tonic-gate #define OPENSSL_SYS_MSDOS
670Sstevel@tonic-gate #endif
680Sstevel@tonic-gate #endif
690Sstevel@tonic-gate 
700Sstevel@tonic-gate #include <stdio.h>
710Sstevel@tonic-gate #include <stdlib.h>
720Sstevel@tonic-gate 
730Sstevel@tonic-gate #ifndef OPENSSL_SYS_MSDOS
740Sstevel@tonic-gate #if !defined(OPENSSL_SYS_VMS) || defined(__DECC)
750Sstevel@tonic-gate #ifdef OPENSSL_UNISTD
760Sstevel@tonic-gate # include OPENSSL_UNISTD
770Sstevel@tonic-gate #else
780Sstevel@tonic-gate # include <unistd.h>
790Sstevel@tonic-gate #endif
800Sstevel@tonic-gate #include <math.h>
810Sstevel@tonic-gate #endif
820Sstevel@tonic-gate #endif
830Sstevel@tonic-gate #include <openssl/des.h>
840Sstevel@tonic-gate 
850Sstevel@tonic-gate #ifdef OPENSSL_SYS_MSDOS		/* Visual C++ 2.1 (Windows NT/95) */
860Sstevel@tonic-gate #include <stdlib.h>
870Sstevel@tonic-gate #include <errno.h>
880Sstevel@tonic-gate #include <time.h>
890Sstevel@tonic-gate #include <io.h>
900Sstevel@tonic-gate #endif
910Sstevel@tonic-gate 
920Sstevel@tonic-gate #if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS)
930Sstevel@tonic-gate #include <string.h>
940Sstevel@tonic-gate #endif
950Sstevel@tonic-gate 
960Sstevel@tonic-gate #ifdef OPENSSL_BUILD_SHLIBCRYPTO
970Sstevel@tonic-gate # undef OPENSSL_EXTERN
980Sstevel@tonic-gate # define OPENSSL_EXTERN OPENSSL_EXPORT
990Sstevel@tonic-gate #endif
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate #define ITERATIONS 16
1020Sstevel@tonic-gate #define HALF_ITERATIONS 8
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate /* used in des_read and des_write */
1050Sstevel@tonic-gate #define MAXWRITE	(1024*16)
1060Sstevel@tonic-gate #define BSIZE		(MAXWRITE+4)
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate #define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
1090Sstevel@tonic-gate 			 l|=((DES_LONG)(*((c)++)))<< 8L, \
1100Sstevel@tonic-gate 			 l|=((DES_LONG)(*((c)++)))<<16L, \
1110Sstevel@tonic-gate 			 l|=((DES_LONG)(*((c)++)))<<24L)
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate /* NOTE - c is not incremented as per c2l */
1140Sstevel@tonic-gate #define c2ln(c,l1,l2,n)	{ \
1150Sstevel@tonic-gate 			c+=n; \
1160Sstevel@tonic-gate 			l1=l2=0; \
1170Sstevel@tonic-gate 			switch (n) { \
1180Sstevel@tonic-gate 			case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
1190Sstevel@tonic-gate 			case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
1200Sstevel@tonic-gate 			case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
1210Sstevel@tonic-gate 			case 5: l2|=((DES_LONG)(*(--(c))));     \
1220Sstevel@tonic-gate 			case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
1230Sstevel@tonic-gate 			case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
1240Sstevel@tonic-gate 			case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
1250Sstevel@tonic-gate 			case 1: l1|=((DES_LONG)(*(--(c))));     \
1260Sstevel@tonic-gate 				} \
1270Sstevel@tonic-gate 			}
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate #define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
1300Sstevel@tonic-gate 			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
1310Sstevel@tonic-gate 			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
1320Sstevel@tonic-gate 			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate /* replacements for htonl and ntohl since I have no idea what to do
1350Sstevel@tonic-gate  * when faced with machines with 8 byte longs. */
1360Sstevel@tonic-gate #define HDRSIZE 4
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate #define n2l(c,l)	(l =((DES_LONG)(*((c)++)))<<24L, \
1390Sstevel@tonic-gate 			 l|=((DES_LONG)(*((c)++)))<<16L, \
1400Sstevel@tonic-gate 			 l|=((DES_LONG)(*((c)++)))<< 8L, \
1410Sstevel@tonic-gate 			 l|=((DES_LONG)(*((c)++))))
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate #define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
1440Sstevel@tonic-gate 			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
1450Sstevel@tonic-gate 			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
1460Sstevel@tonic-gate 			 *((c)++)=(unsigned char)(((l)     )&0xff))
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate /* NOTE - c is not incremented as per l2c */
1490Sstevel@tonic-gate #define l2cn(l1,l2,c,n)	{ \
1500Sstevel@tonic-gate 			c+=n; \
1510Sstevel@tonic-gate 			switch (n) { \
1520Sstevel@tonic-gate 			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
1530Sstevel@tonic-gate 			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
1540Sstevel@tonic-gate 			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
1550Sstevel@tonic-gate 			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
1560Sstevel@tonic-gate 			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
1570Sstevel@tonic-gate 			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
1580Sstevel@tonic-gate 			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
1590Sstevel@tonic-gate 			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
1600Sstevel@tonic-gate 				} \
1610Sstevel@tonic-gate 			}
1620Sstevel@tonic-gate 
163*2139Sjp161948 #if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
1640Sstevel@tonic-gate #define	ROTATE(a,n)	(_lrotr(a,n))
1650Sstevel@tonic-gate #elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
1660Sstevel@tonic-gate # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
1670Sstevel@tonic-gate #  define ROTATE(a,n)	({ register unsigned int ret;	\
168*2139Sjp161948 				__asm__ ("rorl %1,%0"	\
1690Sstevel@tonic-gate 					: "=r"(ret)	\
1700Sstevel@tonic-gate 					: "I"(n),"0"(a)	\
1710Sstevel@tonic-gate 					: "cc");	\
1720Sstevel@tonic-gate 			   ret;				\
1730Sstevel@tonic-gate 			})
1740Sstevel@tonic-gate # endif
1750Sstevel@tonic-gate #endif
1760Sstevel@tonic-gate #ifndef ROTATE
1770Sstevel@tonic-gate #define	ROTATE(a,n)	(((a)>>(n))+((a)<<(32-(n))))
1780Sstevel@tonic-gate #endif
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate /* Don't worry about the LOAD_DATA() stuff, that is used by
1810Sstevel@tonic-gate  * fcrypt() to add it's little bit to the front */
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate #ifdef DES_FCRYPT
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate #define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
1860Sstevel@tonic-gate 	{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
1890Sstevel@tonic-gate 	t=R^(R>>16L); \
1900Sstevel@tonic-gate 	u=t&E0; t&=E1; \
1910Sstevel@tonic-gate 	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
1920Sstevel@tonic-gate 	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
1930Sstevel@tonic-gate #else
1940Sstevel@tonic-gate #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
1950Sstevel@tonic-gate #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
1960Sstevel@tonic-gate 	u=R^s[S  ]; \
1970Sstevel@tonic-gate 	t=R^s[S+1]
1980Sstevel@tonic-gate #endif
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate /* The changes to this macro may help or hinder, depending on the
2010Sstevel@tonic-gate  * compiler and the architecture.  gcc2 always seems to do well :-).
2020Sstevel@tonic-gate  * Inspired by Dana How <how@isl.stanford.edu>
2030Sstevel@tonic-gate  * DO NOT use the alternative version on machines with 8 byte longs.
2040Sstevel@tonic-gate  * It does not seem to work on the Alpha, even when DES_LONG is 4
2050Sstevel@tonic-gate  * bytes, probably an issue of accessing non-word aligned objects :-( */
2060Sstevel@tonic-gate #ifdef DES_PTR
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate /* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
2090Sstevel@tonic-gate  * is no reason to not xor all the sub items together.  This potentially
2100Sstevel@tonic-gate  * saves a register since things can be xored directly into L */
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate #if defined(DES_RISC1) || defined(DES_RISC2)
2130Sstevel@tonic-gate #ifdef DES_RISC1
2140Sstevel@tonic-gate #define D_ENCRYPT(LL,R,S) { \
2150Sstevel@tonic-gate 	unsigned int u1,u2,u3; \
2160Sstevel@tonic-gate 	LOAD_DATA(R,S,u,t,E0,E1,u1); \
2170Sstevel@tonic-gate 	u2=(int)u>>8L; \
2180Sstevel@tonic-gate 	u1=(int)u&0xfc; \
2190Sstevel@tonic-gate 	u2&=0xfc; \
2200Sstevel@tonic-gate 	t=ROTATE(t,4); \
2210Sstevel@tonic-gate 	u>>=16L; \
2220Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP      +u1); \
2230Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
2240Sstevel@tonic-gate 	u3=(int)(u>>8L); \
2250Sstevel@tonic-gate 	u1=(int)u&0xfc; \
2260Sstevel@tonic-gate 	u3&=0xfc; \
2270Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x400+u1); \
2280Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x600+u3); \
2290Sstevel@tonic-gate 	u2=(int)t>>8L; \
2300Sstevel@tonic-gate 	u1=(int)t&0xfc; \
2310Sstevel@tonic-gate 	u2&=0xfc; \
2320Sstevel@tonic-gate 	t>>=16L; \
2330Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
2340Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
2350Sstevel@tonic-gate 	u3=(int)t>>8L; \
2360Sstevel@tonic-gate 	u1=(int)t&0xfc; \
2370Sstevel@tonic-gate 	u3&=0xfc; \
2380Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x500+u1); \
2390Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x700+u3); }
2400Sstevel@tonic-gate #endif
2410Sstevel@tonic-gate #ifdef DES_RISC2
2420Sstevel@tonic-gate #define D_ENCRYPT(LL,R,S) { \
2430Sstevel@tonic-gate 	unsigned int u1,u2,s1,s2; \
2440Sstevel@tonic-gate 	LOAD_DATA(R,S,u,t,E0,E1,u1); \
2450Sstevel@tonic-gate 	u2=(int)u>>8L; \
2460Sstevel@tonic-gate 	u1=(int)u&0xfc; \
2470Sstevel@tonic-gate 	u2&=0xfc; \
2480Sstevel@tonic-gate 	t=ROTATE(t,4); \
2490Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP      +u1); \
2500Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
2510Sstevel@tonic-gate 	s1=(int)(u>>16L); \
2520Sstevel@tonic-gate 	s2=(int)(u>>24L); \
2530Sstevel@tonic-gate 	s1&=0xfc; \
2540Sstevel@tonic-gate 	s2&=0xfc; \
2550Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x400+s1); \
2560Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x600+s2); \
2570Sstevel@tonic-gate 	u2=(int)t>>8L; \
2580Sstevel@tonic-gate 	u1=(int)t&0xfc; \
2590Sstevel@tonic-gate 	u2&=0xfc; \
2600Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
2610Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
2620Sstevel@tonic-gate 	s1=(int)(t>>16L); \
2630Sstevel@tonic-gate 	s2=(int)(t>>24L); \
2640Sstevel@tonic-gate 	s1&=0xfc; \
2650Sstevel@tonic-gate 	s2&=0xfc; \
2660Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x500+s1); \
2670Sstevel@tonic-gate 	LL^= *(const DES_LONG *)(des_SP+0x700+s2); }
2680Sstevel@tonic-gate #endif
2690Sstevel@tonic-gate #else
2700Sstevel@tonic-gate #define D_ENCRYPT(LL,R,S) { \
2710Sstevel@tonic-gate 	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
2720Sstevel@tonic-gate 	t=ROTATE(t,4); \
2730Sstevel@tonic-gate 	LL^= \
2740Sstevel@tonic-gate 	*(const DES_LONG *)(des_SP      +((u     )&0xfc))^ \
2750Sstevel@tonic-gate 	*(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \
2760Sstevel@tonic-gate 	*(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \
2770Sstevel@tonic-gate 	*(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \
2780Sstevel@tonic-gate 	*(const DES_LONG *)(des_SP+0x100+((t     )&0xfc))^ \
2790Sstevel@tonic-gate 	*(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \
2800Sstevel@tonic-gate 	*(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \
2810Sstevel@tonic-gate 	*(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); }
2820Sstevel@tonic-gate #endif
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate #else /* original version */
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate #if defined(DES_RISC1) || defined(DES_RISC2)
2870Sstevel@tonic-gate #ifdef DES_RISC1
2880Sstevel@tonic-gate #define D_ENCRYPT(LL,R,S) {\
2890Sstevel@tonic-gate 	unsigned int u1,u2,u3; \
2900Sstevel@tonic-gate 	LOAD_DATA(R,S,u,t,E0,E1,u1); \
2910Sstevel@tonic-gate 	u>>=2L; \
2920Sstevel@tonic-gate 	t=ROTATE(t,6); \
2930Sstevel@tonic-gate 	u2=(int)u>>8L; \
2940Sstevel@tonic-gate 	u1=(int)u&0x3f; \
2950Sstevel@tonic-gate 	u2&=0x3f; \
2960Sstevel@tonic-gate 	u>>=16L; \
2970Sstevel@tonic-gate 	LL^=DES_SPtrans[0][u1]; \
2980Sstevel@tonic-gate 	LL^=DES_SPtrans[2][u2]; \
2990Sstevel@tonic-gate 	u3=(int)u>>8L; \
3000Sstevel@tonic-gate 	u1=(int)u&0x3f; \
3010Sstevel@tonic-gate 	u3&=0x3f; \
3020Sstevel@tonic-gate 	LL^=DES_SPtrans[4][u1]; \
3030Sstevel@tonic-gate 	LL^=DES_SPtrans[6][u3]; \
3040Sstevel@tonic-gate 	u2=(int)t>>8L; \
3050Sstevel@tonic-gate 	u1=(int)t&0x3f; \
3060Sstevel@tonic-gate 	u2&=0x3f; \
3070Sstevel@tonic-gate 	t>>=16L; \
3080Sstevel@tonic-gate 	LL^=DES_SPtrans[1][u1]; \
3090Sstevel@tonic-gate 	LL^=DES_SPtrans[3][u2]; \
3100Sstevel@tonic-gate 	u3=(int)t>>8L; \
3110Sstevel@tonic-gate 	u1=(int)t&0x3f; \
3120Sstevel@tonic-gate 	u3&=0x3f; \
3130Sstevel@tonic-gate 	LL^=DES_SPtrans[5][u1]; \
3140Sstevel@tonic-gate 	LL^=DES_SPtrans[7][u3]; }
3150Sstevel@tonic-gate #endif
3160Sstevel@tonic-gate #ifdef DES_RISC2
3170Sstevel@tonic-gate #define D_ENCRYPT(LL,R,S) {\
3180Sstevel@tonic-gate 	unsigned int u1,u2,s1,s2; \
3190Sstevel@tonic-gate 	LOAD_DATA(R,S,u,t,E0,E1,u1); \
3200Sstevel@tonic-gate 	u>>=2L; \
3210Sstevel@tonic-gate 	t=ROTATE(t,6); \
3220Sstevel@tonic-gate 	u2=(int)u>>8L; \
3230Sstevel@tonic-gate 	u1=(int)u&0x3f; \
3240Sstevel@tonic-gate 	u2&=0x3f; \
3250Sstevel@tonic-gate 	LL^=DES_SPtrans[0][u1]; \
3260Sstevel@tonic-gate 	LL^=DES_SPtrans[2][u2]; \
3270Sstevel@tonic-gate 	s1=(int)u>>16L; \
3280Sstevel@tonic-gate 	s2=(int)u>>24L; \
3290Sstevel@tonic-gate 	s1&=0x3f; \
3300Sstevel@tonic-gate 	s2&=0x3f; \
3310Sstevel@tonic-gate 	LL^=DES_SPtrans[4][s1]; \
3320Sstevel@tonic-gate 	LL^=DES_SPtrans[6][s2]; \
3330Sstevel@tonic-gate 	u2=(int)t>>8L; \
3340Sstevel@tonic-gate 	u1=(int)t&0x3f; \
3350Sstevel@tonic-gate 	u2&=0x3f; \
3360Sstevel@tonic-gate 	LL^=DES_SPtrans[1][u1]; \
3370Sstevel@tonic-gate 	LL^=DES_SPtrans[3][u2]; \
3380Sstevel@tonic-gate 	s1=(int)t>>16; \
3390Sstevel@tonic-gate 	s2=(int)t>>24L; \
3400Sstevel@tonic-gate 	s1&=0x3f; \
3410Sstevel@tonic-gate 	s2&=0x3f; \
3420Sstevel@tonic-gate 	LL^=DES_SPtrans[5][s1]; \
3430Sstevel@tonic-gate 	LL^=DES_SPtrans[7][s2]; }
3440Sstevel@tonic-gate #endif
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate #else
3470Sstevel@tonic-gate 
3480Sstevel@tonic-gate #define D_ENCRYPT(LL,R,S) {\
3490Sstevel@tonic-gate 	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
3500Sstevel@tonic-gate 	t=ROTATE(t,4); \
3510Sstevel@tonic-gate 	LL^=\
3520Sstevel@tonic-gate 		DES_SPtrans[0][(u>> 2L)&0x3f]^ \
3530Sstevel@tonic-gate 		DES_SPtrans[2][(u>>10L)&0x3f]^ \
3540Sstevel@tonic-gate 		DES_SPtrans[4][(u>>18L)&0x3f]^ \
3550Sstevel@tonic-gate 		DES_SPtrans[6][(u>>26L)&0x3f]^ \
3560Sstevel@tonic-gate 		DES_SPtrans[1][(t>> 2L)&0x3f]^ \
3570Sstevel@tonic-gate 		DES_SPtrans[3][(t>>10L)&0x3f]^ \
3580Sstevel@tonic-gate 		DES_SPtrans[5][(t>>18L)&0x3f]^ \
3590Sstevel@tonic-gate 		DES_SPtrans[7][(t>>26L)&0x3f]; }
3600Sstevel@tonic-gate #endif
3610Sstevel@tonic-gate #endif
3620Sstevel@tonic-gate 
3630Sstevel@tonic-gate 	/* IP and FP
3640Sstevel@tonic-gate 	 * The problem is more of a geometric problem that random bit fiddling.
3650Sstevel@tonic-gate 	 0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
3660Sstevel@tonic-gate 	 8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
3670Sstevel@tonic-gate 	16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
3680Sstevel@tonic-gate 	24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate 	32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
3710Sstevel@tonic-gate 	40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
3720Sstevel@tonic-gate 	48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
3730Sstevel@tonic-gate 	56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate 	The output has been subject to swaps of the form
3760Sstevel@tonic-gate 	0 1 -> 3 1 but the odd and even bits have been put into
3770Sstevel@tonic-gate 	2 3    2 0
3780Sstevel@tonic-gate 	different words.  The main trick is to remember that
3790Sstevel@tonic-gate 	t=((l>>size)^r)&(mask);
3800Sstevel@tonic-gate 	r^=t;
3810Sstevel@tonic-gate 	l^=(t<<size);
3820Sstevel@tonic-gate 	can be used to swap and move bits between words.
3830Sstevel@tonic-gate 
3840Sstevel@tonic-gate 	So l =  0  1  2  3  r = 16 17 18 19
3850Sstevel@tonic-gate 	        4  5  6  7      20 21 22 23
3860Sstevel@tonic-gate 	        8  9 10 11      24 25 26 27
3870Sstevel@tonic-gate 	       12 13 14 15      28 29 30 31
3880Sstevel@tonic-gate 	becomes (for size == 2 and mask == 0x3333)
3890Sstevel@tonic-gate 	   t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
3900Sstevel@tonic-gate 		 6^20  7^21 -- --        4  5 20 21       6  7 22 23
3910Sstevel@tonic-gate 		10^24 11^25 -- --        8  9 24 25      10 11 24 25
3920Sstevel@tonic-gate 		14^28 15^29 -- --       12 13 28 29      14 15 28 29
3930Sstevel@tonic-gate 
3940Sstevel@tonic-gate 	Thanks for hints from Richard Outerbridge - he told me IP&FP
3950Sstevel@tonic-gate 	could be done in 15 xor, 10 shifts and 5 ands.
3960Sstevel@tonic-gate 	When I finally started to think of the problem in 2D
3970Sstevel@tonic-gate 	I first got ~42 operations without xors.  When I remembered
3980Sstevel@tonic-gate 	how to use xors :-) I got it to its final state.
3990Sstevel@tonic-gate 	*/
4000Sstevel@tonic-gate #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
4010Sstevel@tonic-gate 	(b)^=(t),\
4020Sstevel@tonic-gate 	(a)^=((t)<<(n)))
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate #define IP(l,r) \
4050Sstevel@tonic-gate 	{ \
4060Sstevel@tonic-gate 	register DES_LONG tt; \
4070Sstevel@tonic-gate 	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
4080Sstevel@tonic-gate 	PERM_OP(l,r,tt,16,0x0000ffffL); \
4090Sstevel@tonic-gate 	PERM_OP(r,l,tt, 2,0x33333333L); \
4100Sstevel@tonic-gate 	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
4110Sstevel@tonic-gate 	PERM_OP(r,l,tt, 1,0x55555555L); \
4120Sstevel@tonic-gate 	}
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate #define FP(l,r) \
4150Sstevel@tonic-gate 	{ \
4160Sstevel@tonic-gate 	register DES_LONG tt; \
4170Sstevel@tonic-gate 	PERM_OP(l,r,tt, 1,0x55555555L); \
4180Sstevel@tonic-gate 	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
4190Sstevel@tonic-gate 	PERM_OP(l,r,tt, 2,0x33333333L); \
4200Sstevel@tonic-gate 	PERM_OP(r,l,tt,16,0x0000ffffL); \
4210Sstevel@tonic-gate 	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
4220Sstevel@tonic-gate 	}
4230Sstevel@tonic-gate 
424*2139Sjp161948 extern const DES_LONG DES_SPtrans[8][64];
4250Sstevel@tonic-gate 
4260Sstevel@tonic-gate void fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
4270Sstevel@tonic-gate 		 DES_LONG Eswap0, DES_LONG Eswap1);
4280Sstevel@tonic-gate #endif
429