Eneboo - Documentación para desarrolladores
|
00001 /* crypto/des/des_locl.h */ 00002 /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) 00003 * All rights reserved. 00004 * 00005 * This package is an SSL implementation written 00006 * by Eric Young (eay@cryptsoft.com). 00007 * The implementation was written so as to conform with Netscapes SSL. 00008 * 00009 * This library is free for commercial and non-commercial use as long as 00010 * the following conditions are aheared to. The following conditions 00011 * apply to all code found in this distribution, be it the RC4, RSA, 00012 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 00013 * included with this distribution is covered by the same copyright terms 00014 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 00015 * 00016 * Copyright remains Eric Young's, and as such any Copyright notices in 00017 * the code are not to be removed. 00018 * If this package is used in a product, Eric Young should be given attribution 00019 * as the author of the parts of the library used. 00020 * This can be in the form of a textual message at program startup or 00021 * in documentation (online or textual) provided with the package. 00022 * 00023 * Redistribution and use in source and binary forms, with or without 00024 * modification, are permitted provided that the following conditions 00025 * are met: 00026 * 1. Redistributions of source code must retain the copyright 00027 * notice, this list of conditions and the following disclaimer. 00028 * 2. Redistributions in binary form must reproduce the above copyright 00029 * notice, this list of conditions and the following disclaimer in the 00030 * documentation and/or other materials provided with the distribution. 00031 * 3. All advertising materials mentioning features or use of this software 00032 * must display the following acknowledgement: 00033 * "This product includes cryptographic software written by 00034 * Eric Young (eay@cryptsoft.com)" 00035 * The word 'cryptographic' can be left out if the rouines from the library 00036 * being used are not cryptographic related :-). 00037 * 4. If you include any Windows specific code (or a derivative thereof) from 00038 * the apps directory (application code) you must include an acknowledgement: 00039 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 00040 * 00041 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 00042 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00043 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00044 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 00045 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00046 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00047 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00048 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00049 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00050 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00051 * SUCH DAMAGE. 00052 * 00053 * The licence and distribution terms for any publically available version or 00054 * derivative of this code cannot be changed. i.e. this code cannot simply be 00055 * copied and put under another distribution licence 00056 * [including the GNU Public Licence.] 00057 */ 00058 00059 #ifndef HEADER_DES_LOCL_H 00060 #define HEADER_DES_LOCL_H 00061 00062 #include <openssl/e_os2.h> 00063 00064 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) 00065 #ifndef OPENSSL_SYS_MSDOS 00066 #define OPENSSL_SYS_MSDOS 00067 #endif 00068 #endif 00069 00070 #include <stdio.h> 00071 #include <stdlib.h> 00072 00073 #ifndef OPENSSL_SYS_MSDOS 00074 #if !defined(OPENSSL_SYS_VMS) || defined(__DECC) 00075 #ifdef OPENSSL_UNISTD 00076 # include OPENSSL_UNISTD 00077 #else 00078 # include <unistd.h> 00079 #endif 00080 #include <math.h> 00081 #endif 00082 #endif 00083 #include <openssl/des.h> 00084 00085 #ifdef OPENSSL_SYS_MSDOS /* Visual C++ 2.1 (Windows NT/95) */ 00086 #include <stdlib.h> 00087 #include <errno.h> 00088 #include <time.h> 00089 #include <io.h> 00090 #endif 00091 00092 #if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS) 00093 #include <string.h> 00094 #endif 00095 00096 #ifdef OPENSSL_BUILD_SHLIBCRYPTO 00097 # undef OPENSSL_EXTERN 00098 # define OPENSSL_EXTERN OPENSSL_EXPORT 00099 #endif 00100 00101 #define ITERATIONS 16 00102 #define HALF_ITERATIONS 8 00103 00104 /* used in des_read and des_write */ 00105 #define MAXWRITE (1024*16) 00106 #define BSIZE (MAXWRITE+4) 00107 00108 #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ 00109 l|=((DES_LONG)(*((c)++)))<< 8L, \ 00110 l|=((DES_LONG)(*((c)++)))<<16L, \ 00111 l|=((DES_LONG)(*((c)++)))<<24L) 00112 00113 /* NOTE - c is not incremented as per c2l */ 00114 #define c2ln(c,l1,l2,n) { \ 00115 c+=n; \ 00116 l1=l2=0; \ 00117 switch (n) { \ 00118 case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ 00119 case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ 00120 case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ 00121 case 5: l2|=((DES_LONG)(*(--(c)))); \ 00122 case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ 00123 case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ 00124 case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ 00125 case 1: l1|=((DES_LONG)(*(--(c)))); \ 00126 } \ 00127 } 00128 00129 #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 00130 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 00131 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 00132 *((c)++)=(unsigned char)(((l)>>24L)&0xff)) 00133 00134 /* replacements for htonl and ntohl since I have no idea what to do 00135 * when faced with machines with 8 byte longs. */ 00136 #define HDRSIZE 4 00137 00138 #define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ 00139 l|=((DES_LONG)(*((c)++)))<<16L, \ 00140 l|=((DES_LONG)(*((c)++)))<< 8L, \ 00141 l|=((DES_LONG)(*((c)++)))) 00142 00143 #define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ 00144 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 00145 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 00146 *((c)++)=(unsigned char)(((l) )&0xff)) 00147 00148 /* NOTE - c is not incremented as per l2c */ 00149 #define l2cn(l1,l2,c,n) { \ 00150 c+=n; \ 00151 switch (n) { \ 00152 case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ 00153 case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ 00154 case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ 00155 case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ 00156 case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ 00157 case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ 00158 case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ 00159 case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ 00160 } \ 00161 } 00162 00163 #if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC) 00164 #define ROTATE(a,n) (_lrotr(a,n)) 00165 #elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) 00166 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) 00167 # define ROTATE(a,n) ({ register unsigned int ret; \ 00168 asm ("rorl %1,%0" \ 00169 : "=r"(ret) \ 00170 : "I"(n),"0"(a) \ 00171 : "cc"); \ 00172 ret; \ 00173 }) 00174 # endif 00175 #endif 00176 #ifndef ROTATE 00177 #define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) 00178 #endif 00179 00180 /* Don't worry about the LOAD_DATA() stuff, that is used by 00181 * fcrypt() to add it's little bit to the front */ 00182 00183 #ifdef DES_FCRYPT 00184 00185 #define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ 00186 { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } 00187 00188 #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ 00189 t=R^(R>>16L); \ 00190 u=t&E0; t&=E1; \ 00191 tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ 00192 tmp=(t<<16); t^=R^s[S+1]; t^=tmp 00193 #else 00194 #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) 00195 #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ 00196 u=R^s[S ]; \ 00197 t=R^s[S+1] 00198 #endif 00199 00200 /* The changes to this macro may help or hinder, depending on the 00201 * compiler and the architecture. gcc2 always seems to do well :-). 00202 * Inspired by Dana How <how@isl.stanford.edu> 00203 * DO NOT use the alternative version on machines with 8 byte longs. 00204 * It does not seem to work on the Alpha, even when DES_LONG is 4 00205 * bytes, probably an issue of accessing non-word aligned objects :-( */ 00206 #ifdef DES_PTR 00207 00208 /* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there 00209 * is no reason to not xor all the sub items together. This potentially 00210 * saves a register since things can be xored directly into L */ 00211 00212 #if defined(DES_RISC1) || defined(DES_RISC2) 00213 #ifdef DES_RISC1 00214 #define D_ENCRYPT(LL,R,S) { \ 00215 unsigned int u1,u2,u3; \ 00216 LOAD_DATA(R,S,u,t,E0,E1,u1); \ 00217 u2=(int)u>>8L; \ 00218 u1=(int)u&0xfc; \ 00219 u2&=0xfc; \ 00220 t=ROTATE(t,4); \ 00221 u>>=16L; \ 00222 LL^= *(const DES_LONG *)(des_SP +u1); \ 00223 LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ 00224 u3=(int)(u>>8L); \ 00225 u1=(int)u&0xfc; \ 00226 u3&=0xfc; \ 00227 LL^= *(const DES_LONG *)(des_SP+0x400+u1); \ 00228 LL^= *(const DES_LONG *)(des_SP+0x600+u3); \ 00229 u2=(int)t>>8L; \ 00230 u1=(int)t&0xfc; \ 00231 u2&=0xfc; \ 00232 t>>=16L; \ 00233 LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ 00234 LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ 00235 u3=(int)t>>8L; \ 00236 u1=(int)t&0xfc; \ 00237 u3&=0xfc; \ 00238 LL^= *(const DES_LONG *)(des_SP+0x500+u1); \ 00239 LL^= *(const DES_LONG *)(des_SP+0x700+u3); } 00240 #endif 00241 #ifdef DES_RISC2 00242 #define D_ENCRYPT(LL,R,S) { \ 00243 unsigned int u1,u2,s1,s2; \ 00244 LOAD_DATA(R,S,u,t,E0,E1,u1); \ 00245 u2=(int)u>>8L; \ 00246 u1=(int)u&0xfc; \ 00247 u2&=0xfc; \ 00248 t=ROTATE(t,4); \ 00249 LL^= *(const DES_LONG *)(des_SP +u1); \ 00250 LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ 00251 s1=(int)(u>>16L); \ 00252 s2=(int)(u>>24L); \ 00253 s1&=0xfc; \ 00254 s2&=0xfc; \ 00255 LL^= *(const DES_LONG *)(des_SP+0x400+s1); \ 00256 LL^= *(const DES_LONG *)(des_SP+0x600+s2); \ 00257 u2=(int)t>>8L; \ 00258 u1=(int)t&0xfc; \ 00259 u2&=0xfc; \ 00260 LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ 00261 LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ 00262 s1=(int)(t>>16L); \ 00263 s2=(int)(t>>24L); \ 00264 s1&=0xfc; \ 00265 s2&=0xfc; \ 00266 LL^= *(const DES_LONG *)(des_SP+0x500+s1); \ 00267 LL^= *(const DES_LONG *)(des_SP+0x700+s2); } 00268 #endif 00269 #else 00270 #define D_ENCRYPT(LL,R,S) { \ 00271 LOAD_DATA_tmp(R,S,u,t,E0,E1); \ 00272 t=ROTATE(t,4); \ 00273 LL^= \ 00274 *(const DES_LONG *)(des_SP +((u )&0xfc))^ \ 00275 *(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \ 00276 *(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \ 00277 *(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \ 00278 *(const DES_LONG *)(des_SP+0x100+((t )&0xfc))^ \ 00279 *(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \ 00280 *(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \ 00281 *(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); } 00282 #endif 00283 00284 #else /* original version */ 00285 00286 #if defined(DES_RISC1) || defined(DES_RISC2) 00287 #ifdef DES_RISC1 00288 #define D_ENCRYPT(LL,R,S) {\ 00289 unsigned int u1,u2,u3; \ 00290 LOAD_DATA(R,S,u,t,E0,E1,u1); \ 00291 u>>=2L; \ 00292 t=ROTATE(t,6); \ 00293 u2=(int)u>>8L; \ 00294 u1=(int)u&0x3f; \ 00295 u2&=0x3f; \ 00296 u>>=16L; \ 00297 LL^=DES_SPtrans[0][u1]; \ 00298 LL^=DES_SPtrans[2][u2]; \ 00299 u3=(int)u>>8L; \ 00300 u1=(int)u&0x3f; \ 00301 u3&=0x3f; \ 00302 LL^=DES_SPtrans[4][u1]; \ 00303 LL^=DES_SPtrans[6][u3]; \ 00304 u2=(int)t>>8L; \ 00305 u1=(int)t&0x3f; \ 00306 u2&=0x3f; \ 00307 t>>=16L; \ 00308 LL^=DES_SPtrans[1][u1]; \ 00309 LL^=DES_SPtrans[3][u2]; \ 00310 u3=(int)t>>8L; \ 00311 u1=(int)t&0x3f; \ 00312 u3&=0x3f; \ 00313 LL^=DES_SPtrans[5][u1]; \ 00314 LL^=DES_SPtrans[7][u3]; } 00315 #endif 00316 #ifdef DES_RISC2 00317 #define D_ENCRYPT(LL,R,S) {\ 00318 unsigned int u1,u2,s1,s2; \ 00319 LOAD_DATA(R,S,u,t,E0,E1,u1); \ 00320 u>>=2L; \ 00321 t=ROTATE(t,6); \ 00322 u2=(int)u>>8L; \ 00323 u1=(int)u&0x3f; \ 00324 u2&=0x3f; \ 00325 LL^=DES_SPtrans[0][u1]; \ 00326 LL^=DES_SPtrans[2][u2]; \ 00327 s1=(int)u>>16L; \ 00328 s2=(int)u>>24L; \ 00329 s1&=0x3f; \ 00330 s2&=0x3f; \ 00331 LL^=DES_SPtrans[4][s1]; \ 00332 LL^=DES_SPtrans[6][s2]; \ 00333 u2=(int)t>>8L; \ 00334 u1=(int)t&0x3f; \ 00335 u2&=0x3f; \ 00336 LL^=DES_SPtrans[1][u1]; \ 00337 LL^=DES_SPtrans[3][u2]; \ 00338 s1=(int)t>>16; \ 00339 s2=(int)t>>24L; \ 00340 s1&=0x3f; \ 00341 s2&=0x3f; \ 00342 LL^=DES_SPtrans[5][s1]; \ 00343 LL^=DES_SPtrans[7][s2]; } 00344 #endif 00345 00346 #else 00347 00348 #define D_ENCRYPT(LL,R,S) {\ 00349 LOAD_DATA_tmp(R,S,u,t,E0,E1); \ 00350 t=ROTATE(t,4); \ 00351 LL^=\ 00352 DES_SPtrans[0][(u>> 2L)&0x3f]^ \ 00353 DES_SPtrans[2][(u>>10L)&0x3f]^ \ 00354 DES_SPtrans[4][(u>>18L)&0x3f]^ \ 00355 DES_SPtrans[6][(u>>26L)&0x3f]^ \ 00356 DES_SPtrans[1][(t>> 2L)&0x3f]^ \ 00357 DES_SPtrans[3][(t>>10L)&0x3f]^ \ 00358 DES_SPtrans[5][(t>>18L)&0x3f]^ \ 00359 DES_SPtrans[7][(t>>26L)&0x3f]; } 00360 #endif 00361 #endif 00362 00363 /* IP and FP 00364 * The problem is more of a geometric problem that random bit fiddling. 00365 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 00366 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 00367 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 00368 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 00369 00370 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 00371 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 00372 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 00373 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 00374 00375 The output has been subject to swaps of the form 00376 0 1 -> 3 1 but the odd and even bits have been put into 00377 2 3 2 0 00378 different words. The main trick is to remember that 00379 t=((l>>size)^r)&(mask); 00380 r^=t; 00381 l^=(t<<size); 00382 can be used to swap and move bits between words. 00383 00384 So l = 0 1 2 3 r = 16 17 18 19 00385 4 5 6 7 20 21 22 23 00386 8 9 10 11 24 25 26 27 00387 12 13 14 15 28 29 30 31 00388 becomes (for size == 2 and mask == 0x3333) 00389 t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19 00390 6^20 7^21 -- -- 4 5 20 21 6 7 22 23 00391 10^24 11^25 -- -- 8 9 24 25 10 11 24 25 00392 14^28 15^29 -- -- 12 13 28 29 14 15 28 29 00393 00394 Thanks for hints from Richard Outerbridge - he told me IP&FP 00395 could be done in 15 xor, 10 shifts and 5 ands. 00396 When I finally started to think of the problem in 2D 00397 I first got ~42 operations without xors. When I remembered 00398 how to use xors :-) I got it to its final state. 00399 */ 00400 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ 00401 (b)^=(t),\ 00402 (a)^=((t)<<(n))) 00403 00404 #define IP(l,r) \ 00405 { \ 00406 register DES_LONG tt; \ 00407 PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ 00408 PERM_OP(l,r,tt,16,0x0000ffffL); \ 00409 PERM_OP(r,l,tt, 2,0x33333333L); \ 00410 PERM_OP(l,r,tt, 8,0x00ff00ffL); \ 00411 PERM_OP(r,l,tt, 1,0x55555555L); \ 00412 } 00413 00414 #define FP(l,r) \ 00415 { \ 00416 register DES_LONG tt; \ 00417 PERM_OP(l,r,tt, 1,0x55555555L); \ 00418 PERM_OP(r,l,tt, 8,0x00ff00ffL); \ 00419 PERM_OP(l,r,tt, 2,0x33333333L); \ 00420 PERM_OP(r,l,tt,16,0x0000ffffL); \ 00421 PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ 00422 } 00423 00424 extern const DES_LONG DES_SPtrans[8][64]; 00425 00426 void fcrypt_body(DES_LONG *out,DES_key_schedule *ks, 00427 DES_LONG Eswap0, DES_LONG Eswap1); 00428 #endif