POK
bf_locl.h
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Fri Dec 11 16:32:31 2009
15  */
16 
17 /* crypto/bf/bf_locl.h */
18 /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
19  * All rights reserved.
20  *
21  * This package is an SSL implementation written
22  * by Eric Young (eay@cryptsoft.com).
23  * The implementation was written so as to conform with Netscapes SSL.
24  *
25  * This library is free for commercial and non-commercial use as long as
26  * the following conditions are aheared to. The following conditions
27  * apply to all code found in this distribution, be it the RC4, RSA,
28  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
29  * included with this distribution is covered by the same copyright terms
30  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
31  *
32  * Copyright remains Eric Young's, and as such any Copyright notices in
33  * the code are not to be removed.
34  * If this package is used in a product, Eric Young should be given attribution
35  * as the author of the parts of the library used.
36  * This can be in the form of a textual message at program startup or
37  * in documentation (online or textual) provided with the package.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the copyright
43  * notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  * notice, this list of conditions and the following disclaimer in the
46  * documentation and/or other materials provided with the distribution.
47  * 3. All advertising materials mentioning features or use of this software
48  * must display the following acknowledgement:
49  * "This product includes cryptographic software written by
50  * Eric Young (eay@cryptsoft.com)"
51  * The word 'cryptographic' can be left out if the rouines from the library
52  * being used are not cryptographic related :-).
53  * 4. If you include any Windows specific code (or a derivative thereof) from
54  * the apps directory (application code) you must include an acknowledgement:
55  * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
56  *
57  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
58  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
61  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
67  * SUCH DAMAGE.
68  *
69  * The licence and distribution terms for any publically available version or
70  * derivative of this code cannot be changed. i.e. this code cannot simply be
71  * copied and put under another distribution licence
72  * [including the GNU Public Licence.]
73  */
74 
75 #ifdef POK_NEEDS_PROTOCOLS_BLOWFISH
76 
77 #define BF_PTR2
78 
79 #ifndef HEADER_BF_LOCL_H
80 #define HEADER_BF_LOCL_H
81 
82 #undef c2l
83 #define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
84  l|=((unsigned long)(*((c)++)))<< 8L, \
85  l|=((unsigned long)(*((c)++)))<<16L, \
86  l|=((unsigned long)(*((c)++)))<<24L)
87 
88 /* NOTE - c is not incremented as per c2l */
89 #undef c2ln
90 #define c2ln(c,l1,l2,n) { \
91  c+=n; \
92  l1=l2=0; \
93  switch (n) { \
94  case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
95  case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
96  case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
97  case 5: l2|=((unsigned long)(*(--(c)))); \
98  case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
99  case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
100  case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
101  case 1: l1|=((unsigned long)(*(--(c)))); \
102  } \
103  }
104 
105 #undef l2c
106 #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
107  *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
108  *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
109  *((c)++)=(unsigned char)(((l)>>24L)&0xff))
110 
111 /* NOTE - c is not incremented as per l2c */
112 #undef l2cn
113 #define l2cn(l1,l2,c,n) { \
114  c+=n; \
115  switch (n) { \
116  case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
117  case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
118  case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
119  case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
120  case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
121  case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
122  case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
123  case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
124  } \
125  }
126 
127 /* NOTE - c is not incremented as per n2l */
128 #define n2ln(c,l1,l2,n) { \
129  c+=n; \
130  l1=l2=0; \
131  switch (n) { \
132  case 8: l2 =((unsigned long)(*(--(c)))) ; \
133  case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
134  case 6: l2|=((unsigned long)(*(--(c))))<<16; \
135  case 5: l2|=((unsigned long)(*(--(c))))<<24; \
136  case 4: l1 =((unsigned long)(*(--(c)))) ; \
137  case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
138  case 2: l1|=((unsigned long)(*(--(c))))<<16; \
139  case 1: l1|=((unsigned long)(*(--(c))))<<24; \
140  } \
141  }
142 
143 /* NOTE - c is not incremented as per l2n */
144 #define l2nn(l1,l2,c,n) { \
145  c+=n; \
146  switch (n) { \
147  case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \
148  case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
149  case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
150  case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
151  case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \
152  case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
153  case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
154  case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
155  } \
156  }
157 
158 #undef n2l
159 #define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \
160  l|=((unsigned long)(*((c)++)))<<16L, \
161  l|=((unsigned long)(*((c)++)))<< 8L, \
162  l|=((unsigned long)(*((c)++))))
163 
164 #undef l2n
165 #define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
166  *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
167  *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
168  *((c)++)=(unsigned char)(((l) )&0xff))
169 
170 /* This is actually a big endian algorithm, the most significant byte
171  * is used to lookup array 0 */
172 
173 #if defined(BF_PTR2)
174 
175 /*
176  * This is basically a special Intel version. Point is that Intel
177  * doesn't have many registers, but offers a reach choice of addressing
178  * modes. So we spare some registers by directly traversing BF_KEY
179  * structure and hiring the most decorated addressing mode. The code
180  * generated by EGCS is *perfectly* competitive with assembler
181  * implementation!
182  */
183 #define BF_ENC(LL,R,KEY,Pi) (\
184  LL^=KEY[Pi], \
185  t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \
186  t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \
187  t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \
188  t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \
189  LL^=t \
190  )
191 
192 #elif defined(BF_PTR)
193 
194 #ifndef BF_LONG_LOG2
195 #define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */
196 #endif
197 #define BF_M (0xFF<<BF_LONG_LOG2)
198 #define BF_0 (24-BF_LONG_LOG2)
199 #define BF_1 (16-BF_LONG_LOG2)
200 #define BF_2 ( 8-BF_LONG_LOG2)
201 #define BF_3 BF_LONG_LOG2 /* left shift */
202 
203 /*
204  * This is normally very good on RISC platforms where normally you
205  * have to explicitly "multiply" array index by sizeof(BF_LONG)
206  * in order to calculate the effective address. This implementation
207  * excuses CPU from this extra work. Power[PC] uses should have most
208  * fun as (R>>BF_i)&BF_M gets folded into a single instruction, namely
209  * rlwinm. So let'em double-check if their compiler does it.
210  */
211 
212 #define BF_ENC(LL,R,S,P) ( \
213  LL^=P, \
214  LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \
215  *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \
216  *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
217  *(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M))) \
218  )
219 #else
220 
221 /*
222  * This is a *generic* version. Seem to perform best on platforms that
223  * offer explicit support for extraction of 8-bit nibbles preferably
224  * complemented with "multiplying" of array index by sizeof(BF_LONG).
225  * For the moment of this writing the list comprises Alpha CPU featuring
226  * extbl and s[48]addq instructions.
227  */
228 
229 #define BF_ENC(LL,R,S,P) ( \
230  LL^=P, \
231  LL^=((( S[ ((int)(R>>24)&0xff)] + \
232  S[0x0100+((int)(R>>16)&0xff)])^ \
233  S[0x0200+((int)(R>> 8)&0xff)])+ \
234  S[0x0300+((int)(R )&0xff)])&0xffffffffL \
235  )
236 #endif
237 
238 #endif
239 
240 #endif /* POK_NEEDS_PROTOCOLS */