POK
bf_enc.c
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_enc.c */
18 /* Copyright (C) 1995-1998 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 #include "blowfish.h"
78 #include "bf_locl.h"
79 
80 /* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
81  * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
82  * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
83  */
84 
85 #if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
86 #error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
87 to modify the code.
88 #endif
89 
90 void BF_encrypt(BF_LONG *data, const BF_KEY *key)
91  {
92 #ifndef BF_PTR2
93  register BF_LONG l,r;
94  register const BF_LONG *p,*s;
95 
96  p=key->P;
97  s= &(key->S[0]);
98  l=data[0];
99  r=data[1];
100 
101  l^=p[0];
102  BF_ENC(r,l,s,p[ 1]);
103  BF_ENC(l,r,s,p[ 2]);
104  BF_ENC(r,l,s,p[ 3]);
105  BF_ENC(l,r,s,p[ 4]);
106  BF_ENC(r,l,s,p[ 5]);
107  BF_ENC(l,r,s,p[ 6]);
108  BF_ENC(r,l,s,p[ 7]);
109  BF_ENC(l,r,s,p[ 8]);
110  BF_ENC(r,l,s,p[ 9]);
111  BF_ENC(l,r,s,p[10]);
112  BF_ENC(r,l,s,p[11]);
113  BF_ENC(l,r,s,p[12]);
114  BF_ENC(r,l,s,p[13]);
115  BF_ENC(l,r,s,p[14]);
116  BF_ENC(r,l,s,p[15]);
117  BF_ENC(l,r,s,p[16]);
118 #if BF_ROUNDS == 20
119  BF_ENC(r,l,s,p[17]);
120  BF_ENC(l,r,s,p[18]);
121  BF_ENC(r,l,s,p[19]);
122  BF_ENC(l,r,s,p[20]);
123 #endif
124  r^=p[BF_ROUNDS+1];
125 
126  data[1]=l&0xffffffffL;
127  data[0]=r&0xffffffffL;
128 #else
129  register BF_LONG l,r,t,*k;
130 
131  l=data[0];
132  r=data[1];
133  k=(BF_LONG*)key;
134 
135  l^=k[0];
136  BF_ENC(r,l,k, 1);
137  BF_ENC(l,r,k, 2);
138  BF_ENC(r,l,k, 3);
139  BF_ENC(l,r,k, 4);
140  BF_ENC(r,l,k, 5);
141  BF_ENC(l,r,k, 6);
142  BF_ENC(r,l,k, 7);
143  BF_ENC(l,r,k, 8);
144  BF_ENC(r,l,k, 9);
145  BF_ENC(l,r,k,10);
146  BF_ENC(r,l,k,11);
147  BF_ENC(l,r,k,12);
148  BF_ENC(r,l,k,13);
149  BF_ENC(l,r,k,14);
150  BF_ENC(r,l,k,15);
151  BF_ENC(l,r,k,16);
152 #if BF_ROUNDS == 20
153  BF_ENC(r,l,k,17);
154  BF_ENC(l,r,k,18);
155  BF_ENC(r,l,k,19);
156  BF_ENC(l,r,k,20);
157 #endif
158  r^=k[BF_ROUNDS+1];
159 
160  data[1]=l&0xffffffffL;
161  data[0]=r&0xffffffffL;
162 #endif
163  }
164 
165 #ifndef BF_DEFAULT_OPTIONS
166 
167 void BF_decrypt(BF_LONG *data, const BF_KEY *key)
168  {
169 #ifndef BF_PTR2
170  register BF_LONG l,r;
171  register const BF_LONG *p,*s;
172 
173  p=key->P;
174  s= &(key->S[0]);
175  l=data[0];
176  r=data[1];
177 
178  l^=p[BF_ROUNDS+1];
179 #if BF_ROUNDS == 20
180  BF_ENC(r,l,s,p[20]);
181  BF_ENC(l,r,s,p[19]);
182  BF_ENC(r,l,s,p[18]);
183  BF_ENC(l,r,s,p[17]);
184 #endif
185  BF_ENC(r,l,s,p[16]);
186  BF_ENC(l,r,s,p[15]);
187  BF_ENC(r,l,s,p[14]);
188  BF_ENC(l,r,s,p[13]);
189  BF_ENC(r,l,s,p[12]);
190  BF_ENC(l,r,s,p[11]);
191  BF_ENC(r,l,s,p[10]);
192  BF_ENC(l,r,s,p[ 9]);
193  BF_ENC(r,l,s,p[ 8]);
194  BF_ENC(l,r,s,p[ 7]);
195  BF_ENC(r,l,s,p[ 6]);
196  BF_ENC(l,r,s,p[ 5]);
197  BF_ENC(r,l,s,p[ 4]);
198  BF_ENC(l,r,s,p[ 3]);
199  BF_ENC(r,l,s,p[ 2]);
200  BF_ENC(l,r,s,p[ 1]);
201  r^=p[0];
202 
203  data[1]=l&0xffffffffL;
204  data[0]=r&0xffffffffL;
205 #else
206  register BF_LONG l,r,t,*k;
207 
208  l=data[0];
209  r=data[1];
210  k=(BF_LONG *)key;
211 
212  l^=k[BF_ROUNDS+1];
213 #if BF_ROUNDS == 20
214  BF_ENC(r,l,k,20);
215  BF_ENC(l,r,k,19);
216  BF_ENC(r,l,k,18);
217  BF_ENC(l,r,k,17);
218 #endif
219  BF_ENC(r,l,k,16);
220  BF_ENC(l,r,k,15);
221  BF_ENC(r,l,k,14);
222  BF_ENC(l,r,k,13);
223  BF_ENC(r,l,k,12);
224  BF_ENC(l,r,k,11);
225  BF_ENC(r,l,k,10);
226  BF_ENC(l,r,k, 9);
227  BF_ENC(r,l,k, 8);
228  BF_ENC(l,r,k, 7);
229  BF_ENC(r,l,k, 6);
230  BF_ENC(l,r,k, 5);
231  BF_ENC(r,l,k, 4);
232  BF_ENC(l,r,k, 3);
233  BF_ENC(r,l,k, 2);
234  BF_ENC(l,r,k, 1);
235  r^=k[0];
236 
237  data[1]=l&0xffffffffL;
238  data[0]=r&0xffffffffL;
239 #endif
240  }
241 
242 void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
243  const BF_KEY *schedule, unsigned char *ivec, int encrypt)
244  {
245  register BF_LONG tin0,tin1;
246  register BF_LONG tout0,tout1,xor0,xor1;
247  register long l=length;
248  BF_LONG tin[2];
249 
250  if (encrypt)
251  {
252  n2l(ivec,tout0);
253  n2l(ivec,tout1);
254  ivec-=8;
255  for (l-=8; l>=0; l-=8)
256  {
257  n2l(in,tin0);
258  n2l(in,tin1);
259  tin0^=tout0;
260  tin1^=tout1;
261  tin[0]=tin0;
262  tin[1]=tin1;
263  BF_encrypt(tin,schedule);
264  tout0=tin[0];
265  tout1=tin[1];
266  l2n(tout0,out);
267  l2n(tout1,out);
268  }
269  if (l != -8)
270  {
271  n2ln(in,tin0,tin1,l+8);
272  tin0^=tout0;
273  tin1^=tout1;
274  tin[0]=tin0;
275  tin[1]=tin1;
276  BF_encrypt(tin,schedule);
277  tout0=tin[0];
278  tout1=tin[1];
279  l2n(tout0,out);
280  l2n(tout1,out);
281  }
282  l2n(tout0,ivec);
283  l2n(tout1,ivec);
284  }
285  else
286  {
287  n2l(ivec,xor0);
288  n2l(ivec,xor1);
289  ivec-=8;
290  for (l-=8; l>=0; l-=8)
291  {
292  n2l(in,tin0);
293  n2l(in,tin1);
294  tin[0]=tin0;
295  tin[1]=tin1;
296  BF_decrypt(tin,schedule);
297  tout0=tin[0]^xor0;
298  tout1=tin[1]^xor1;
299  l2n(tout0,out);
300  l2n(tout1,out);
301  xor0=tin0;
302  xor1=tin1;
303  }
304  if (l != -8)
305  {
306  n2l(in,tin0);
307  n2l(in,tin1);
308  tin[0]=tin0;
309  tin[1]=tin1;
310  BF_decrypt(tin,schedule);
311  tout0=tin[0]^xor0;
312  tout1=tin[1]^xor1;
313  l2nn(tout0,tout1,out,l+8);
314  xor0=tin0;
315  xor1=tin1;
316  }
317  l2n(xor0,ivec);
318  l2n(xor1,ivec);
319  }
320  tin0=tin1=tout0=tout1=xor0=xor1=0;
321  tin[0]=tin[1]=0;
322  }
323 
324 
325 void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
326  const BF_KEY *key, int encrypt)
327 {
328  BF_LONG l,d[2];
329 
330  n2l(in,l); d[0]=l;
331  n2l(in,l); d[1]=l;
332  if (encrypt)
333  BF_encrypt(d,key);
334  else
335  BF_decrypt(d,key);
336  l=d[0]; l2n(l,out);
337  l=d[1]; l2n(l,out);
338  l=d[0]=d[1]=0;
339 }
340 
341 
342 #endif
343 
344 #endif /* POK_NEEDS_PROTOCOLS */