POK
/home/jaouen/pok_official/pok/trunk/libpok/protocols/blowfish/bf_locl.h
00001 /*
00002  *                               POK header
00003  * 
00004  * The following file is a part of the POK project. Any modification should
00005  * made according to the POK licence. You CANNOT use this file or a part of
00006  * this file is this part of a file for your own project
00007  *
00008  * For more information on the POK licence, please see our LICENCE FILE
00009  *
00010  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
00011  *
00012  *                                      Copyright (c) 2007-2009 POK team 
00013  *
00014  * Created by julien on Fri Dec 11 16:32:31 2009 
00015  */
00016 
00017 /* crypto/bf/bf_locl.h */
00018 /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
00019  * All rights reserved.
00020  *
00021  * This package is an SSL implementation written
00022  * by Eric Young (eay@cryptsoft.com).
00023  * The implementation was written so as to conform with Netscapes SSL.
00024  * 
00025  * This library is free for commercial and non-commercial use as long as
00026  * the following conditions are aheared to.  The following conditions
00027  * apply to all code found in this distribution, be it the RC4, RSA,
00028  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
00029  * included with this distribution is covered by the same copyright terms
00030  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
00031  * 
00032  * Copyright remains Eric Young's, and as such any Copyright notices in
00033  * the code are not to be removed.
00034  * If this package is used in a product, Eric Young should be given attribution
00035  * as the author of the parts of the library used.
00036  * This can be in the form of a textual message at program startup or
00037  * in documentation (online or textual) provided with the package.
00038  * 
00039  * Redistribution and use in source and binary forms, with or without
00040  * modification, are permitted provided that the following conditions
00041  * are met:
00042  * 1. Redistributions of source code must retain the copyright
00043  *    notice, this list of conditions and the following disclaimer.
00044  * 2. Redistributions in binary form must reproduce the above copyright
00045  *    notice, this list of conditions and the following disclaimer in the
00046  *    documentation and/or other materials provided with the distribution.
00047  * 3. All advertising materials mentioning features or use of this software
00048  *    must display the following acknowledgement:
00049  *    "This product includes cryptographic software written by
00050  *     Eric Young (eay@cryptsoft.com)"
00051  *    The word 'cryptographic' can be left out if the rouines from the library
00052  *    being used are not cryptographic related :-).
00053  * 4. If you include any Windows specific code (or a derivative thereof) from 
00054  *    the apps directory (application code) you must include an acknowledgement:
00055  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
00056  * 
00057  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
00058  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00059  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00060  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00061  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00062  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00063  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00064  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00065  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00066  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00067  * SUCH DAMAGE.
00068  * 
00069  * The licence and distribution terms for any publically available version or
00070  * derivative of this code cannot be changed.  i.e. this code cannot simply be
00071  * copied and put under another distribution licence
00072  * [including the GNU Public Licence.]
00073  */
00074 
00075 #ifdef POK_NEEDS_PROTOCOLS_BLOWFISH
00076 
00077 #define BF_PTR2
00078 
00079 #ifndef HEADER_BF_LOCL_H
00080 #define HEADER_BF_LOCL_H
00081 
00082 #undef c2l
00083 #define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
00084                          l|=((unsigned long)(*((c)++)))<< 8L, \
00085                          l|=((unsigned long)(*((c)++)))<<16L, \
00086                          l|=((unsigned long)(*((c)++)))<<24L)
00087 
00088 /* NOTE - c is not incremented as per c2l */
00089 #undef c2ln
00090 #define c2ln(c,l1,l2,n) { \
00091                         c+=n; \
00092                         l1=l2=0; \
00093                         switch (n) { \
00094                         case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
00095                         case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
00096                         case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
00097                         case 5: l2|=((unsigned long)(*(--(c))));     \
00098                         case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
00099                         case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
00100                         case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
00101                         case 1: l1|=((unsigned long)(*(--(c))));     \
00102                                 } \
00103                         }
00104 
00105 #undef l2c
00106 #define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
00107                          *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
00108                          *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
00109                          *((c)++)=(unsigned char)(((l)>>24L)&0xff))
00110 
00111 /* NOTE - c is not incremented as per l2c */
00112 #undef l2cn
00113 #define l2cn(l1,l2,c,n) { \
00114                         c+=n; \
00115                         switch (n) { \
00116                         case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
00117                         case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
00118                         case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
00119                         case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
00120                         case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
00121                         case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
00122                         case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
00123                         case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
00124                                 } \
00125                         }
00126 
00127 /* NOTE - c is not incremented as per n2l */
00128 #define n2ln(c,l1,l2,n) { \
00129                         c+=n; \
00130                         l1=l2=0; \
00131                         switch (n) { \
00132                         case 8: l2 =((unsigned long)(*(--(c))))    ; \
00133                         case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
00134                         case 6: l2|=((unsigned long)(*(--(c))))<<16; \
00135                         case 5: l2|=((unsigned long)(*(--(c))))<<24; \
00136                         case 4: l1 =((unsigned long)(*(--(c))))    ; \
00137                         case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
00138                         case 2: l1|=((unsigned long)(*(--(c))))<<16; \
00139                         case 1: l1|=((unsigned long)(*(--(c))))<<24; \
00140                                 } \
00141                         }
00142 
00143 /* NOTE - c is not incremented as per l2n */
00144 #define l2nn(l1,l2,c,n) { \
00145                         c+=n; \
00146                         switch (n) { \
00147                         case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
00148                         case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
00149                         case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
00150                         case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
00151                         case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
00152                         case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
00153                         case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
00154                         case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
00155                                 } \
00156                         }
00157 
00158 #undef n2l
00159 #define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
00160                          l|=((unsigned long)(*((c)++)))<<16L, \
00161                          l|=((unsigned long)(*((c)++)))<< 8L, \
00162                          l|=((unsigned long)(*((c)++))))
00163 
00164 #undef l2n
00165 #define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
00166                          *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
00167                          *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
00168                          *((c)++)=(unsigned char)(((l)     )&0xff))
00169 
00170 /* This is actually a big endian algorithm, the most significant byte
00171  * is used to lookup array 0 */
00172 
00173 #if defined(BF_PTR2)
00174 
00175 /*
00176  * This is basically a special Intel version. Point is that Intel
00177  * doesn't have many registers, but offers a reach choice of addressing
00178  * modes. So we spare some registers by directly traversing BF_KEY
00179  * structure and hiring the most decorated addressing mode. The code
00180  * generated by EGCS is *perfectly* competitive with assembler
00181  * implementation!
00182  */
00183 #define BF_ENC(LL,R,KEY,Pi) (\
00184         LL^=KEY[Pi], \
00185         t=  KEY[BF_ROUNDS+2 +   0 + ((R>>24)&0xFF)], \
00186         t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \
00187         t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \
00188         t+= KEY[BF_ROUNDS+2 + 768 + ((R    )&0xFF)], \
00189         LL^=t \
00190         )
00191 
00192 #elif defined(BF_PTR)
00193 
00194 #ifndef BF_LONG_LOG2
00195 #define BF_LONG_LOG2  2       /* default to BF_LONG being 32 bits */
00196 #endif
00197 #define BF_M  (0xFF<<BF_LONG_LOG2)
00198 #define BF_0  (24-BF_LONG_LOG2)
00199 #define BF_1  (16-BF_LONG_LOG2)
00200 #define BF_2  ( 8-BF_LONG_LOG2)
00201 #define BF_3  BF_LONG_LOG2 /* left shift */
00202 
00203 /*
00204  * This is normally very good on RISC platforms where normally you
00205  * have to explicitly "multiply" array index by sizeof(BF_LONG)
00206  * in order to calculate the effective address. This implementation
00207  * excuses CPU from this extra work. Power[PC] uses should have most
00208  * fun as (R>>BF_i)&BF_M gets folded into a single instruction, namely
00209  * rlwinm. So let'em double-check if their compiler does it.
00210  */
00211 
00212 #define BF_ENC(LL,R,S,P) ( \
00213         LL^=P, \
00214         LL^= (((*(BF_LONG *)((unsigned char *)&(S[  0])+((R>>BF_0)&BF_M))+ \
00215                 *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \
00216                 *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
00217                 *(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M))) \
00218         )
00219 #else
00220 
00221 /*
00222  * This is a *generic* version. Seem to perform best on platforms that
00223  * offer explicit support for extraction of 8-bit nibbles preferably
00224  * complemented with "multiplying" of array index by sizeof(BF_LONG).
00225  * For the moment of this writing the list comprises Alpha CPU featuring
00226  * extbl and s[48]addq instructions.
00227  */
00228 
00229 #define BF_ENC(LL,R,S,P) ( \
00230         LL^=P, \
00231         LL^=((( S[       ((int)(R>>24)&0xff)] + \
00232                 S[0x0100+((int)(R>>16)&0xff)])^ \
00233                 S[0x0200+((int)(R>> 8)&0xff)])+ \
00234                 S[0x0300+((int)(R    )&0xff)])&0xffffffffL \
00235         )
00236 #endif
00237 
00238 #endif
00239 
00240 #endif /* POK_NEEDS_PROTOCOLS */