Eneboo - Documentación para desarrolladores
src/libdigidoc/openssl/crypto/des/des_locl.h
Ir a la documentación de este archivo.
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
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'