Home | History | Annotate | Download | only in des
      1 /* crypto/des/des_locl.h */
      2 /* Copyright (C) 1995-1997 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 #ifndef HEADER_DES_LOCL_H
     60 #define HEADER_DES_LOCL_H
     61 
     62 #include <openssl/e_os2.h>
     63 
     64 #if defined(OPENSSL_SYS_WIN32)
     65 #ifndef OPENSSL_SYS_MSDOS
     66 #define OPENSSL_SYS_MSDOS
     67 #endif
     68 #endif
     69 
     70 #include <stdio.h>
     71 #include <stdlib.h>
     72 
     73 #ifndef OPENSSL_SYS_MSDOS
     74 #if !defined(OPENSSL_SYS_VMS) || defined(__DECC)
     75 #ifdef OPENSSL_UNISTD
     76 # include OPENSSL_UNISTD
     77 #else
     78 # include <unistd.h>
     79 #endif
     80 #include <math.h>
     81 #endif
     82 #endif
     83 #include <openssl/des.h>
     84 
     85 #ifdef OPENSSL_SYS_MSDOS		/* Visual C++ 2.1 (Windows NT/95) */
     86 #include <stdlib.h>
     87 #include <errno.h>
     88 #include <time.h>
     89 #include <io.h>
     90 #endif
     91 
     92 #if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS)
     93 #include <string.h>
     94 #endif
     95 
     96 #ifdef OPENSSL_BUILD_SHLIBCRYPTO
     97 # undef OPENSSL_EXTERN
     98 # define OPENSSL_EXTERN OPENSSL_EXPORT
     99 #endif
    100 
    101 #define ITERATIONS 16
    102 #define HALF_ITERATIONS 8
    103 
    104 /* used in des_read and des_write */
    105 #define MAXWRITE	(1024*16)
    106 #define BSIZE		(MAXWRITE+4)
    107 
    108 #define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
    109 			 l|=((DES_LONG)(*((c)++)))<< 8L, \
    110 			 l|=((DES_LONG)(*((c)++)))<<16L, \
    111 			 l|=((DES_LONG)(*((c)++)))<<24L)
    112 
    113 /* NOTE - c is not incremented as per c2l */
    114 #define c2ln(c,l1,l2,n)	{ \
    115 			c+=n; \
    116 			l1=l2=0; \
    117 			switch (n) { \
    118 			case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
    119 			case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
    120 			case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
    121 			case 5: l2|=((DES_LONG)(*(--(c))));     \
    122 			case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
    123 			case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
    124 			case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
    125 			case 1: l1|=((DES_LONG)(*(--(c))));     \
    126 				} \
    127 			}
    128 
    129 #define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
    130 			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
    131 			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
    132 			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
    133 
    134 /* replacements for htonl and ntohl since I have no idea what to do
    135  * when faced with machines with 8 byte longs. */
    136 #define HDRSIZE 4
    137 
    138 #define n2l(c,l)	(l =((DES_LONG)(*((c)++)))<<24L, \
    139 			 l|=((DES_LONG)(*((c)++)))<<16L, \
    140 			 l|=((DES_LONG)(*((c)++)))<< 8L, \
    141 			 l|=((DES_LONG)(*((c)++))))
    142 
    143 #define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
    144 			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
    145 			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
    146 			 *((c)++)=(unsigned char)(((l)     )&0xff))
    147 
    148 /* NOTE - c is not incremented as per l2c */
    149 #define l2cn(l1,l2,c,n)	{ \
    150 			c+=n; \
    151 			switch (n) { \
    152 			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
    153 			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
    154 			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
    155 			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
    156 			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
    157 			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
    158 			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
    159 			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
    160 				} \
    161 			}
    162 
    163 #if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
    164 #define	ROTATE(a,n)	(_lrotr(a,n))
    165 #elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
    166 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
    167 #  define ROTATE(a,n)	({ register unsigned int ret;	\
    168 				asm ("rorl %1,%0"	\
    169 					: "=r"(ret)	\
    170 					: "I"(n),"0"(a)	\
    171 					: "cc");	\
    172 			   ret;				\
    173 			})
    174 # endif
    175 #endif
    176 #ifndef ROTATE
    177 #define	ROTATE(a,n)	(((a)>>(n))+((a)<<(32-(n))))
    178 #endif
    179 
    180 /* Don't worry about the LOAD_DATA() stuff, that is used by
    181  * fcrypt() to add it's little bit to the front */
    182 
    183 #ifdef DES_FCRYPT
    184 
    185 #define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
    186 	{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
    187 
    188 #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
    189 	t=R^(R>>16L); \
    190 	u=t&E0; t&=E1; \
    191 	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
    192 	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
    193 #else
    194 #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
    195 #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
    196 	u=R^s[S  ]; \
    197 	t=R^s[S+1]
    198 #endif
    199 
    200 /* The changes to this macro may help or hinder, depending on the
    201  * compiler and the architecture.  gcc2 always seems to do well :-).
    202  * Inspired by Dana How <how (at) isl.stanford.edu>
    203  * DO NOT use the alternative version on machines with 8 byte longs.
    204  * It does not seem to work on the Alpha, even when DES_LONG is 4
    205  * bytes, probably an issue of accessing non-word aligned objects :-( */
    206 #ifdef DES_PTR
    207 
    208 /* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
    209  * is no reason to not xor all the sub items together.  This potentially
    210  * saves a register since things can be xored directly into L */
    211 
    212 #if defined(DES_RISC1) || defined(DES_RISC2)
    213 #ifdef DES_RISC1
    214 #define D_ENCRYPT(LL,R,S) { \
    215 	unsigned int u1,u2,u3; \
    216 	LOAD_DATA(R,S,u,t,E0,E1,u1); \
    217 	u2=(int)u>>8L; \
    218 	u1=(int)u&0xfc; \
    219 	u2&=0xfc; \
    220 	t=ROTATE(t,4); \
    221 	u>>=16L; \
    222 	LL^= *(const DES_LONG *)(des_SP      +u1); \
    223 	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
    224 	u3=(int)(u>>8L); \
    225 	u1=(int)u&0xfc; \
    226 	u3&=0xfc; \
    227 	LL^= *(const DES_LONG *)(des_SP+0x400+u1); \
    228 	LL^= *(const DES_LONG *)(des_SP+0x600+u3); \
    229 	u2=(int)t>>8L; \
    230 	u1=(int)t&0xfc; \
    231 	u2&=0xfc; \
    232 	t>>=16L; \
    233 	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
    234 	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
    235 	u3=(int)t>>8L; \
    236 	u1=(int)t&0xfc; \
    237 	u3&=0xfc; \
    238 	LL^= *(const DES_LONG *)(des_SP+0x500+u1); \
    239 	LL^= *(const DES_LONG *)(des_SP+0x700+u3); }
    240 #endif
    241 #ifdef DES_RISC2
    242 #define D_ENCRYPT(LL,R,S) { \
    243 	unsigned int u1,u2,s1,s2; \
    244 	LOAD_DATA(R,S,u,t,E0,E1,u1); \
    245 	u2=(int)u>>8L; \
    246 	u1=(int)u&0xfc; \
    247 	u2&=0xfc; \
    248 	t=ROTATE(t,4); \
    249 	LL^= *(const DES_LONG *)(des_SP      +u1); \
    250 	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
    251 	s1=(int)(u>>16L); \
    252 	s2=(int)(u>>24L); \
    253 	s1&=0xfc; \
    254 	s2&=0xfc; \
    255 	LL^= *(const DES_LONG *)(des_SP+0x400+s1); \
    256 	LL^= *(const DES_LONG *)(des_SP+0x600+s2); \
    257 	u2=(int)t>>8L; \
    258 	u1=(int)t&0xfc; \
    259 	u2&=0xfc; \
    260 	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
    261 	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
    262 	s1=(int)(t>>16L); \
    263 	s2=(int)(t>>24L); \
    264 	s1&=0xfc; \
    265 	s2&=0xfc; \
    266 	LL^= *(const DES_LONG *)(des_SP+0x500+s1); \
    267 	LL^= *(const DES_LONG *)(des_SP+0x700+s2); }
    268 #endif
    269 #else
    270 #define D_ENCRYPT(LL,R,S) { \
    271 	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
    272 	t=ROTATE(t,4); \
    273 	LL^= \
    274 	*(const DES_LONG *)(des_SP      +((u     )&0xfc))^ \
    275 	*(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \
    276 	*(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \
    277 	*(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \
    278 	*(const DES_LONG *)(des_SP+0x100+((t     )&0xfc))^ \
    279 	*(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \
    280 	*(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \
    281 	*(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); }
    282 #endif
    283 
    284 #else /* original version */
    285 
    286 #if defined(DES_RISC1) || defined(DES_RISC2)
    287 #ifdef DES_RISC1
    288 #define D_ENCRYPT(LL,R,S) {\
    289 	unsigned int u1,u2,u3; \
    290 	LOAD_DATA(R,S,u,t,E0,E1,u1); \
    291 	u>>=2L; \
    292 	t=ROTATE(t,6); \
    293 	u2=(int)u>>8L; \
    294 	u1=(int)u&0x3f; \
    295 	u2&=0x3f; \
    296 	u>>=16L; \
    297 	LL^=DES_SPtrans[0][u1]; \
    298 	LL^=DES_SPtrans[2][u2]; \
    299 	u3=(int)u>>8L; \
    300 	u1=(int)u&0x3f; \
    301 	u3&=0x3f; \
    302 	LL^=DES_SPtrans[4][u1]; \
    303 	LL^=DES_SPtrans[6][u3]; \
    304 	u2=(int)t>>8L; \
    305 	u1=(int)t&0x3f; \
    306 	u2&=0x3f; \
    307 	t>>=16L; \
    308 	LL^=DES_SPtrans[1][u1]; \
    309 	LL^=DES_SPtrans[3][u2]; \
    310 	u3=(int)t>>8L; \
    311 	u1=(int)t&0x3f; \
    312 	u3&=0x3f; \
    313 	LL^=DES_SPtrans[5][u1]; \
    314 	LL^=DES_SPtrans[7][u3]; }
    315 #endif
    316 #ifdef DES_RISC2
    317 #define D_ENCRYPT(LL,R,S) {\
    318 	unsigned int u1,u2,s1,s2; \
    319 	LOAD_DATA(R,S,u,t,E0,E1,u1); \
    320 	u>>=2L; \
    321 	t=ROTATE(t,6); \
    322 	u2=(int)u>>8L; \
    323 	u1=(int)u&0x3f; \
    324 	u2&=0x3f; \
    325 	LL^=DES_SPtrans[0][u1]; \
    326 	LL^=DES_SPtrans[2][u2]; \
    327 	s1=(int)u>>16L; \
    328 	s2=(int)u>>24L; \
    329 	s1&=0x3f; \
    330 	s2&=0x3f; \
    331 	LL^=DES_SPtrans[4][s1]; \
    332 	LL^=DES_SPtrans[6][s2]; \
    333 	u2=(int)t>>8L; \
    334 	u1=(int)t&0x3f; \
    335 	u2&=0x3f; \
    336 	LL^=DES_SPtrans[1][u1]; \
    337 	LL^=DES_SPtrans[3][u2]; \
    338 	s1=(int)t>>16; \
    339 	s2=(int)t>>24L; \
    340 	s1&=0x3f; \
    341 	s2&=0x3f; \
    342 	LL^=DES_SPtrans[5][s1]; \
    343 	LL^=DES_SPtrans[7][s2]; }
    344 #endif
    345 
    346 #else
    347 
    348 #define D_ENCRYPT(LL,R,S) {\
    349 	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
    350 	t=ROTATE(t,4); \
    351 	LL^=\
    352 		DES_SPtrans[0][(u>> 2L)&0x3f]^ \
    353 		DES_SPtrans[2][(u>>10L)&0x3f]^ \
    354 		DES_SPtrans[4][(u>>18L)&0x3f]^ \
    355 		DES_SPtrans[6][(u>>26L)&0x3f]^ \
    356 		DES_SPtrans[1][(t>> 2L)&0x3f]^ \
    357 		DES_SPtrans[3][(t>>10L)&0x3f]^ \
    358 		DES_SPtrans[5][(t>>18L)&0x3f]^ \
    359 		DES_SPtrans[7][(t>>26L)&0x3f]; }
    360 #endif
    361 #endif
    362 
    363 	/* IP and FP
    364 	 * The problem is more of a geometric problem that random bit fiddling.
    365 	 0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
    366 	 8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
    367 	16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
    368 	24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
    369 
    370 	32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
    371 	40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
    372 	48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
    373 	56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
    374 
    375 	The output has been subject to swaps of the form
    376 	0 1 -> 3 1 but the odd and even bits have been put into
    377 	2 3    2 0
    378 	different words.  The main trick is to remember that
    379 	t=((l>>size)^r)&(mask);
    380 	r^=t;
    381 	l^=(t<<size);
    382 	can be used to swap and move bits between words.
    383 
    384 	So l =  0  1  2  3  r = 16 17 18 19
    385 	        4  5  6  7      20 21 22 23
    386 	        8  9 10 11      24 25 26 27
    387 	       12 13 14 15      28 29 30 31
    388 	becomes (for size == 2 and mask == 0x3333)
    389 	   t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
    390 		 6^20  7^21 -- --        4  5 20 21       6  7 22 23
    391 		10^24 11^25 -- --        8  9 24 25      10 11 24 25
    392 		14^28 15^29 -- --       12 13 28 29      14 15 28 29
    393 
    394 	Thanks for hints from Richard Outerbridge - he told me IP&FP
    395 	could be done in 15 xor, 10 shifts and 5 ands.
    396 	When I finally started to think of the problem in 2D
    397 	I first got ~42 operations without xors.  When I remembered
    398 	how to use xors :-) I got it to its final state.
    399 	*/
    400 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
    401 	(b)^=(t),\
    402 	(a)^=((t)<<(n)))
    403 
    404 #define IP(l,r) \
    405 	{ \
    406 	register DES_LONG tt; \
    407 	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
    408 	PERM_OP(l,r,tt,16,0x0000ffffL); \
    409 	PERM_OP(r,l,tt, 2,0x33333333L); \
    410 	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
    411 	PERM_OP(r,l,tt, 1,0x55555555L); \
    412 	}
    413 
    414 #define FP(l,r) \
    415 	{ \
    416 	register DES_LONG tt; \
    417 	PERM_OP(l,r,tt, 1,0x55555555L); \
    418 	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
    419 	PERM_OP(l,r,tt, 2,0x33333333L); \
    420 	PERM_OP(r,l,tt,16,0x0000ffffL); \
    421 	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
    422 	}
    423 
    424 extern const DES_LONG DES_SPtrans[8][64];
    425 
    426 void fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
    427 		 DES_LONG Eswap0, DES_LONG Eswap1);
    428 
    429 #ifdef OPENSSL_SMALL_FOOTPRINT
    430 #undef DES_UNROLL
    431 #endif
    432 #endif
    433