155714Skris/* crypto/des/des_locl.h */
255714Skris/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#ifndef HEADER_DES_LOCL_H
6055714Skris#define HEADER_DES_LOCL_H
6155714Skris
62109998Smarkm#include <openssl/e_os2.h>
63109998Smarkm
64238405Sjkim#if defined(OPENSSL_SYS_WIN32)
65109998Smarkm#ifndef OPENSSL_SYS_MSDOS
66109998Smarkm#define OPENSSL_SYS_MSDOS
6755714Skris#endif
6855714Skris#endif
6955714Skris
7055714Skris#include <stdio.h>
7155714Skris#include <stdlib.h>
7255714Skris
73109998Smarkm#ifndef OPENSSL_SYS_MSDOS
74109998Smarkm#if !defined(OPENSSL_SYS_VMS) || defined(__DECC)
7559191Skris#ifdef OPENSSL_UNISTD
7659191Skris# include OPENSSL_UNISTD
7759191Skris#else
7859191Skris# include <unistd.h>
7959191Skris#endif
8055714Skris#include <math.h>
8155714Skris#endif
8255714Skris#endif
8355714Skris#include <openssl/des.h>
8455714Skris
85109998Smarkm#ifdef OPENSSL_SYS_MSDOS		/* Visual C++ 2.1 (Windows NT/95) */
8655714Skris#include <stdlib.h>
8755714Skris#include <errno.h>
8855714Skris#include <time.h>
8955714Skris#include <io.h>
9055714Skris#endif
9155714Skris
92109998Smarkm#if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS)
9355714Skris#include <string.h>
9455714Skris#endif
9555714Skris
96109998Smarkm#ifdef OPENSSL_BUILD_SHLIBCRYPTO
97109998Smarkm# undef OPENSSL_EXTERN
98109998Smarkm# define OPENSSL_EXTERN OPENSSL_EXPORT
99109998Smarkm#endif
100109998Smarkm
10155714Skris#define ITERATIONS 16
10255714Skris#define HALF_ITERATIONS 8
10355714Skris
10455714Skris/* used in des_read and des_write */
10555714Skris#define MAXWRITE	(1024*16)
10655714Skris#define BSIZE		(MAXWRITE+4)
10755714Skris
10855714Skris#define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
10955714Skris			 l|=((DES_LONG)(*((c)++)))<< 8L, \
11055714Skris			 l|=((DES_LONG)(*((c)++)))<<16L, \
11155714Skris			 l|=((DES_LONG)(*((c)++)))<<24L)
11255714Skris
11355714Skris/* NOTE - c is not incremented as per c2l */
11455714Skris#define c2ln(c,l1,l2,n)	{ \
11555714Skris			c+=n; \
11655714Skris			l1=l2=0; \
11755714Skris			switch (n) { \
11855714Skris			case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
11955714Skris			case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
12055714Skris			case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
12155714Skris			case 5: l2|=((DES_LONG)(*(--(c))));     \
12255714Skris			case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
12355714Skris			case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
12455714Skris			case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
12555714Skris			case 1: l1|=((DES_LONG)(*(--(c))));     \
12655714Skris				} \
12755714Skris			}
12855714Skris
12955714Skris#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
13055714Skris			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
13155714Skris			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
13255714Skris			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
13355714Skris
13455714Skris/* replacements for htonl and ntohl since I have no idea what to do
13555714Skris * when faced with machines with 8 byte longs. */
13655714Skris#define HDRSIZE 4
13755714Skris
13855714Skris#define n2l(c,l)	(l =((DES_LONG)(*((c)++)))<<24L, \
13955714Skris			 l|=((DES_LONG)(*((c)++)))<<16L, \
14055714Skris			 l|=((DES_LONG)(*((c)++)))<< 8L, \
14155714Skris			 l|=((DES_LONG)(*((c)++))))
14255714Skris
14355714Skris#define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
14455714Skris			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
14555714Skris			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
14655714Skris			 *((c)++)=(unsigned char)(((l)     )&0xff))
14755714Skris
14855714Skris/* NOTE - c is not incremented as per l2c */
14955714Skris#define l2cn(l1,l2,c,n)	{ \
15055714Skris			c+=n; \
15155714Skris			switch (n) { \
15255714Skris			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
15355714Skris			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
15455714Skris			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
15555714Skris			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
15655714Skris			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
15755714Skris			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
15855714Skris			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
15955714Skris			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
16055714Skris				} \
16155714Skris			}
16255714Skris
163160814Ssimon#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
16455714Skris#define	ROTATE(a,n)	(_lrotr(a,n))
165111147Snectar#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
166109998Smarkm# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
167109998Smarkm#  define ROTATE(a,n)	({ register unsigned int ret;	\
168109998Smarkm				asm ("rorl %1,%0"	\
169109998Smarkm					: "=r"(ret)	\
170109998Smarkm					: "I"(n),"0"(a)	\
171109998Smarkm					: "cc");	\
172109998Smarkm			   ret;				\
173109998Smarkm			})
174109998Smarkm# endif
175109998Smarkm#endif
176109998Smarkm#ifndef ROTATE
17755714Skris#define	ROTATE(a,n)	(((a)>>(n))+((a)<<(32-(n))))
17855714Skris#endif
17955714Skris
18055714Skris/* Don't worry about the LOAD_DATA() stuff, that is used by
18155714Skris * fcrypt() to add it's little bit to the front */
18255714Skris
18355714Skris#ifdef DES_FCRYPT
18455714Skris
18555714Skris#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
18655714Skris	{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
18755714Skris
18855714Skris#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
18955714Skris	t=R^(R>>16L); \
19055714Skris	u=t&E0; t&=E1; \
19155714Skris	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
19255714Skris	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
19355714Skris#else
19455714Skris#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
19555714Skris#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
19655714Skris	u=R^s[S  ]; \
19755714Skris	t=R^s[S+1]
19855714Skris#endif
19955714Skris
20055714Skris/* The changes to this macro may help or hinder, depending on the
20159191Skris * compiler and the architecture.  gcc2 always seems to do well :-).
20255714Skris * Inspired by Dana How <how@isl.stanford.edu>
20355714Skris * DO NOT use the alternative version on machines with 8 byte longs.
20455714Skris * It does not seem to work on the Alpha, even when DES_LONG is 4
20555714Skris * bytes, probably an issue of accessing non-word aligned objects :-( */
20655714Skris#ifdef DES_PTR
20755714Skris
20859191Skris/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
20955714Skris * is no reason to not xor all the sub items together.  This potentially
21055714Skris * saves a register since things can be xored directly into L */
21155714Skris
21255714Skris#if defined(DES_RISC1) || defined(DES_RISC2)
21355714Skris#ifdef DES_RISC1
21455714Skris#define D_ENCRYPT(LL,R,S) { \
21555714Skris	unsigned int u1,u2,u3; \
21655714Skris	LOAD_DATA(R,S,u,t,E0,E1,u1); \
21755714Skris	u2=(int)u>>8L; \
21855714Skris	u1=(int)u&0xfc; \
21955714Skris	u2&=0xfc; \
22055714Skris	t=ROTATE(t,4); \
22155714Skris	u>>=16L; \
22255714Skris	LL^= *(const DES_LONG *)(des_SP      +u1); \
22355714Skris	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
22455714Skris	u3=(int)(u>>8L); \
22555714Skris	u1=(int)u&0xfc; \
22655714Skris	u3&=0xfc; \
22755714Skris	LL^= *(const DES_LONG *)(des_SP+0x400+u1); \
22855714Skris	LL^= *(const DES_LONG *)(des_SP+0x600+u3); \
22955714Skris	u2=(int)t>>8L; \
23055714Skris	u1=(int)t&0xfc; \
23155714Skris	u2&=0xfc; \
23255714Skris	t>>=16L; \
23355714Skris	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
23455714Skris	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
23555714Skris	u3=(int)t>>8L; \
23655714Skris	u1=(int)t&0xfc; \
23755714Skris	u3&=0xfc; \
23855714Skris	LL^= *(const DES_LONG *)(des_SP+0x500+u1); \
23955714Skris	LL^= *(const DES_LONG *)(des_SP+0x700+u3); }
24055714Skris#endif
24155714Skris#ifdef DES_RISC2
24255714Skris#define D_ENCRYPT(LL,R,S) { \
24355714Skris	unsigned int u1,u2,s1,s2; \
24455714Skris	LOAD_DATA(R,S,u,t,E0,E1,u1); \
24555714Skris	u2=(int)u>>8L; \
24655714Skris	u1=(int)u&0xfc; \
24755714Skris	u2&=0xfc; \
24855714Skris	t=ROTATE(t,4); \
24955714Skris	LL^= *(const DES_LONG *)(des_SP      +u1); \
25055714Skris	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
25155714Skris	s1=(int)(u>>16L); \
25255714Skris	s2=(int)(u>>24L); \
25355714Skris	s1&=0xfc; \
25455714Skris	s2&=0xfc; \
25555714Skris	LL^= *(const DES_LONG *)(des_SP+0x400+s1); \
25655714Skris	LL^= *(const DES_LONG *)(des_SP+0x600+s2); \
25755714Skris	u2=(int)t>>8L; \
25855714Skris	u1=(int)t&0xfc; \
25955714Skris	u2&=0xfc; \
26055714Skris	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
26155714Skris	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
26255714Skris	s1=(int)(t>>16L); \
26355714Skris	s2=(int)(t>>24L); \
26455714Skris	s1&=0xfc; \
26555714Skris	s2&=0xfc; \
26655714Skris	LL^= *(const DES_LONG *)(des_SP+0x500+s1); \
26755714Skris	LL^= *(const DES_LONG *)(des_SP+0x700+s2); }
26855714Skris#endif
26955714Skris#else
27055714Skris#define D_ENCRYPT(LL,R,S) { \
27155714Skris	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
27255714Skris	t=ROTATE(t,4); \
27355714Skris	LL^= \
27455714Skris	*(const DES_LONG *)(des_SP      +((u     )&0xfc))^ \
27555714Skris	*(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \
27655714Skris	*(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \
27755714Skris	*(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \
27855714Skris	*(const DES_LONG *)(des_SP+0x100+((t     )&0xfc))^ \
27955714Skris	*(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \
28055714Skris	*(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \
28155714Skris	*(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); }
28255714Skris#endif
28355714Skris
28455714Skris#else /* original version */
28555714Skris
28655714Skris#if defined(DES_RISC1) || defined(DES_RISC2)
28755714Skris#ifdef DES_RISC1
28855714Skris#define D_ENCRYPT(LL,R,S) {\
28955714Skris	unsigned int u1,u2,u3; \
29055714Skris	LOAD_DATA(R,S,u,t,E0,E1,u1); \
29155714Skris	u>>=2L; \
29255714Skris	t=ROTATE(t,6); \
29355714Skris	u2=(int)u>>8L; \
29455714Skris	u1=(int)u&0x3f; \
29555714Skris	u2&=0x3f; \
29655714Skris	u>>=16L; \
297109998Smarkm	LL^=DES_SPtrans[0][u1]; \
298109998Smarkm	LL^=DES_SPtrans[2][u2]; \
29955714Skris	u3=(int)u>>8L; \
30055714Skris	u1=(int)u&0x3f; \
30155714Skris	u3&=0x3f; \
302109998Smarkm	LL^=DES_SPtrans[4][u1]; \
303109998Smarkm	LL^=DES_SPtrans[6][u3]; \
30455714Skris	u2=(int)t>>8L; \
30555714Skris	u1=(int)t&0x3f; \
30655714Skris	u2&=0x3f; \
30755714Skris	t>>=16L; \
308109998Smarkm	LL^=DES_SPtrans[1][u1]; \
309109998Smarkm	LL^=DES_SPtrans[3][u2]; \
31055714Skris	u3=(int)t>>8L; \
31155714Skris	u1=(int)t&0x3f; \
31255714Skris	u3&=0x3f; \
313109998Smarkm	LL^=DES_SPtrans[5][u1]; \
314109998Smarkm	LL^=DES_SPtrans[7][u3]; }
31555714Skris#endif
31655714Skris#ifdef DES_RISC2
31755714Skris#define D_ENCRYPT(LL,R,S) {\
31855714Skris	unsigned int u1,u2,s1,s2; \
31955714Skris	LOAD_DATA(R,S,u,t,E0,E1,u1); \
32055714Skris	u>>=2L; \
32155714Skris	t=ROTATE(t,6); \
32255714Skris	u2=(int)u>>8L; \
32355714Skris	u1=(int)u&0x3f; \
32455714Skris	u2&=0x3f; \
325109998Smarkm	LL^=DES_SPtrans[0][u1]; \
326109998Smarkm	LL^=DES_SPtrans[2][u2]; \
32755714Skris	s1=(int)u>>16L; \
32855714Skris	s2=(int)u>>24L; \
32955714Skris	s1&=0x3f; \
33055714Skris	s2&=0x3f; \
331109998Smarkm	LL^=DES_SPtrans[4][s1]; \
332109998Smarkm	LL^=DES_SPtrans[6][s2]; \
33355714Skris	u2=(int)t>>8L; \
33455714Skris	u1=(int)t&0x3f; \
33555714Skris	u2&=0x3f; \
336109998Smarkm	LL^=DES_SPtrans[1][u1]; \
337109998Smarkm	LL^=DES_SPtrans[3][u2]; \
33855714Skris	s1=(int)t>>16; \
33955714Skris	s2=(int)t>>24L; \
34055714Skris	s1&=0x3f; \
34155714Skris	s2&=0x3f; \
342109998Smarkm	LL^=DES_SPtrans[5][s1]; \
343109998Smarkm	LL^=DES_SPtrans[7][s2]; }
34455714Skris#endif
34555714Skris
34655714Skris#else
34755714Skris
34855714Skris#define D_ENCRYPT(LL,R,S) {\
34955714Skris	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
35055714Skris	t=ROTATE(t,4); \
35155714Skris	LL^=\
352109998Smarkm		DES_SPtrans[0][(u>> 2L)&0x3f]^ \
353109998Smarkm		DES_SPtrans[2][(u>>10L)&0x3f]^ \
354109998Smarkm		DES_SPtrans[4][(u>>18L)&0x3f]^ \
355109998Smarkm		DES_SPtrans[6][(u>>26L)&0x3f]^ \
356109998Smarkm		DES_SPtrans[1][(t>> 2L)&0x3f]^ \
357109998Smarkm		DES_SPtrans[3][(t>>10L)&0x3f]^ \
358109998Smarkm		DES_SPtrans[5][(t>>18L)&0x3f]^ \
359109998Smarkm		DES_SPtrans[7][(t>>26L)&0x3f]; }
36055714Skris#endif
36155714Skris#endif
36255714Skris
36355714Skris	/* IP and FP
36455714Skris	 * The problem is more of a geometric problem that random bit fiddling.
36555714Skris	 0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
36655714Skris	 8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
36755714Skris	16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
36855714Skris	24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
36955714Skris
37055714Skris	32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
37155714Skris	40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
37255714Skris	48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
37355714Skris	56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
37455714Skris
37555714Skris	The output has been subject to swaps of the form
37655714Skris	0 1 -> 3 1 but the odd and even bits have been put into
37755714Skris	2 3    2 0
37855714Skris	different words.  The main trick is to remember that
37955714Skris	t=((l>>size)^r)&(mask);
38055714Skris	r^=t;
38155714Skris	l^=(t<<size);
38255714Skris	can be used to swap and move bits between words.
38355714Skris
38455714Skris	So l =  0  1  2  3  r = 16 17 18 19
38555714Skris	        4  5  6  7      20 21 22 23
38655714Skris	        8  9 10 11      24 25 26 27
38755714Skris	       12 13 14 15      28 29 30 31
38855714Skris	becomes (for size == 2 and mask == 0x3333)
38955714Skris	   t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
39055714Skris		 6^20  7^21 -- --        4  5 20 21       6  7 22 23
39155714Skris		10^24 11^25 -- --        8  9 24 25      10 11 24 25
39255714Skris		14^28 15^29 -- --       12 13 28 29      14 15 28 29
39355714Skris
39455714Skris	Thanks for hints from Richard Outerbridge - he told me IP&FP
39555714Skris	could be done in 15 xor, 10 shifts and 5 ands.
39655714Skris	When I finally started to think of the problem in 2D
39755714Skris	I first got ~42 operations without xors.  When I remembered
39855714Skris	how to use xors :-) I got it to its final state.
39955714Skris	*/
40055714Skris#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
40155714Skris	(b)^=(t),\
40255714Skris	(a)^=((t)<<(n)))
40355714Skris
40455714Skris#define IP(l,r) \
40555714Skris	{ \
40655714Skris	register DES_LONG tt; \
40755714Skris	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
40855714Skris	PERM_OP(l,r,tt,16,0x0000ffffL); \
40955714Skris	PERM_OP(r,l,tt, 2,0x33333333L); \
41055714Skris	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
41155714Skris	PERM_OP(r,l,tt, 1,0x55555555L); \
41255714Skris	}
41355714Skris
41455714Skris#define FP(l,r) \
41555714Skris	{ \
41655714Skris	register DES_LONG tt; \
41755714Skris	PERM_OP(l,r,tt, 1,0x55555555L); \
41855714Skris	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
41955714Skris	PERM_OP(l,r,tt, 2,0x33333333L); \
42055714Skris	PERM_OP(r,l,tt,16,0x0000ffffL); \
42155714Skris	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
42255714Skris	}
42355714Skris
424160814Ssimonextern const DES_LONG DES_SPtrans[8][64];
42555714Skris
426109998Smarkmvoid fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
427109998Smarkm		 DES_LONG Eswap0, DES_LONG Eswap1);
428238405Sjkim
429238405Sjkim#ifdef OPENSSL_SMALL_FOOTPRINT
430238405Sjkim#undef DES_UNROLL
43155714Skris#endif
432238405Sjkim#endif
433