cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
desenc.c
Go to the documentation of this file.
1 /* crypto/des/des_enc.c */
2 /* Copyright (C) 1995-1998 Eric Young ([email protected])
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young ([email protected]).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to. The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson ([email protected]).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  * notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  * notice, this list of conditions and the following disclaimer in the
30  * documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  * must display the following acknowledgement:
33  * "This product includes cryptographic software written by
34  * Eric Young ([email protected])"
35  * The word 'cryptographic' can be left out if the rouines from the library
36  * being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  * the apps directory (application code) you must include an acknowledgement:
39  * "This product includes software written by Tim Hudson ([email protected])"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed. i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #define CHECK_ENDIANNESS /* One-off sanity check for osconfig.h */
60 #if defined( INC_ALL )
61  #include "osconfig.h"
62  #include "des.h"
63  #include "deslocl.h"
64 #else
65  #include "crypt/osconfig.h"
66  #include "crypt/des.h"
67  #include "crypt/deslocl.h"
68 #endif /* Compiler-specific includes */
69 
70 #ifndef USE_ASM
71 
72 /* OpenSSL includes some sort of Configure-based versioning mechanism which
73  includes an attribution notice in the code, since cryptlib doesn't use
74  Configure (or the OpenSSL config) we hardcode in the following which
75  should have the same effect */
76 
77 char *version1="This product includes cryptographic software written by Eric Young ([email protected])";
78 char *version2="This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/)";
79 
81  {
82  register DES_LONG l,r,t,u;
83 #ifdef DES_PTR
84  register const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
85 #endif
86 #ifndef DES_UNROLL
87  register int i;
88 #endif
89  register DES_LONG *s;
90 
91  r=data[0];
92  l=data[1];
93 
94  IP(r,l);
95  /* Things have been modified so that the initial rotate is
96  * done outside the loop. This required the
97  * des_SPtrans values in sp.h to be rotated 1 bit to the right.
98  * One perl script later and things have a 5% speed up on a sparc2.
99  * Thanks to Richard Outerbridge <[email protected]>
100  * for pointing this out. */
101  /* clear the top bits on machines with 8byte longs */
102  /* shift left by 2 */
103  r=ROTATE(r,29)&0xffffffffL;
104  l=ROTATE(l,29)&0xffffffffL;
105 
106  s=ks->ks.deslong;
107  /* I don't know if it is worth the effort of loop unrolling the
108  * inner loop */
109  if (enc)
110  {
111 #ifdef DES_UNROLL
112  D_ENCRYPT(l,r, 0); /* 1 */
113  D_ENCRYPT(r,l, 2); /* 2 */
114  D_ENCRYPT(l,r, 4); /* 3 */
115  D_ENCRYPT(r,l, 6); /* 4 */
116  D_ENCRYPT(l,r, 8); /* 5 */
117  D_ENCRYPT(r,l,10); /* 6 */
118  D_ENCRYPT(l,r,12); /* 7 */
119  D_ENCRYPT(r,l,14); /* 8 */
120  D_ENCRYPT(l,r,16); /* 9 */
121  D_ENCRYPT(r,l,18); /* 10 */
122  D_ENCRYPT(l,r,20); /* 11 */
123  D_ENCRYPT(r,l,22); /* 12 */
124  D_ENCRYPT(l,r,24); /* 13 */
125  D_ENCRYPT(r,l,26); /* 14 */
126  D_ENCRYPT(l,r,28); /* 15 */
127  D_ENCRYPT(r,l,30); /* 16 */
128 #else
129  for (i=0; i<32; i+=8)
130  {
131  D_ENCRYPT(l,r,i+0); /* 1 */
132  D_ENCRYPT(r,l,i+2); /* 2 */
133  D_ENCRYPT(l,r,i+4); /* 3 */
134  D_ENCRYPT(r,l,i+6); /* 4 */
135  }
136 #endif
137  }
138  else
139  {
140 #ifdef DES_UNROLL
141  D_ENCRYPT(l,r,30); /* 16 */
142  D_ENCRYPT(r,l,28); /* 15 */
143  D_ENCRYPT(l,r,26); /* 14 */
144  D_ENCRYPT(r,l,24); /* 13 */
145  D_ENCRYPT(l,r,22); /* 12 */
146  D_ENCRYPT(r,l,20); /* 11 */
147  D_ENCRYPT(l,r,18); /* 10 */
148  D_ENCRYPT(r,l,16); /* 9 */
149  D_ENCRYPT(l,r,14); /* 8 */
150  D_ENCRYPT(r,l,12); /* 7 */
151  D_ENCRYPT(l,r,10); /* 6 */
152  D_ENCRYPT(r,l, 8); /* 5 */
153  D_ENCRYPT(l,r, 6); /* 4 */
154  D_ENCRYPT(r,l, 4); /* 3 */
155  D_ENCRYPT(l,r, 2); /* 2 */
156  D_ENCRYPT(r,l, 0); /* 1 */
157 #else
158  for (i=30; i>0; i-=8)
159  {
160  D_ENCRYPT(l,r,i-0); /* 16 */
161  D_ENCRYPT(r,l,i-2); /* 15 */
162  D_ENCRYPT(l,r,i-4); /* 14 */
163  D_ENCRYPT(r,l,i-6); /* 13 */
164  }
165 #endif
166  }
167 
168  /* rotate and clear the top bits on machines with 8byte longs */
169  l=ROTATE(l,3)&0xffffffffL;
170  r=ROTATE(r,3)&0xffffffffL;
171 
172  FP(r,l);
173  data[0]=l;
174  data[1]=r;
175  l=r=t=u=0;
176  }
177 
179  {
180  register DES_LONG l,r,t,u;
181 #ifdef DES_PTR
182  register const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
183 #endif
184 #ifndef DES_UNROLL
185  register int i;
186 #endif
187  register DES_LONG *s;
188 
189  r=data[0];
190  l=data[1];
191 
192  /* Things have been modified so that the initial rotate is
193  * done outside the loop. This required the
194  * des_SPtrans values in sp.h to be rotated 1 bit to the right.
195  * One perl script later and things have a 5% speed up on a sparc2.
196  * Thanks to Richard Outerbridge <[email protected]>
197  * for pointing this out. */
198  /* clear the top bits on machines with 8byte longs */
199  r=ROTATE(r,29)&0xffffffffL;
200  l=ROTATE(l,29)&0xffffffffL;
201 
202  s=ks->ks.deslong;
203  /* I don't know if it is worth the effort of loop unrolling the
204  * inner loop */
205  if (enc)
206  {
207 #ifdef DES_UNROLL
208  D_ENCRYPT(l,r, 0); /* 1 */
209  D_ENCRYPT(r,l, 2); /* 2 */
210  D_ENCRYPT(l,r, 4); /* 3 */
211  D_ENCRYPT(r,l, 6); /* 4 */
212  D_ENCRYPT(l,r, 8); /* 5 */
213  D_ENCRYPT(r,l,10); /* 6 */
214  D_ENCRYPT(l,r,12); /* 7 */
215  D_ENCRYPT(r,l,14); /* 8 */
216  D_ENCRYPT(l,r,16); /* 9 */
217  D_ENCRYPT(r,l,18); /* 10 */
218  D_ENCRYPT(l,r,20); /* 11 */
219  D_ENCRYPT(r,l,22); /* 12 */
220  D_ENCRYPT(l,r,24); /* 13 */
221  D_ENCRYPT(r,l,26); /* 14 */
222  D_ENCRYPT(l,r,28); /* 15 */
223  D_ENCRYPT(r,l,30); /* 16 */
224 #else
225  for (i=0; i<32; i+=8)
226  {
227  D_ENCRYPT(l,r,i+0); /* 1 */
228  D_ENCRYPT(r,l,i+2); /* 2 */
229  D_ENCRYPT(l,r,i+4); /* 3 */
230  D_ENCRYPT(r,l,i+6); /* 4 */
231  }
232 #endif
233  }
234  else
235  {
236 #ifdef DES_UNROLL
237  D_ENCRYPT(l,r,30); /* 16 */
238  D_ENCRYPT(r,l,28); /* 15 */
239  D_ENCRYPT(l,r,26); /* 14 */
240  D_ENCRYPT(r,l,24); /* 13 */
241  D_ENCRYPT(l,r,22); /* 12 */
242  D_ENCRYPT(r,l,20); /* 11 */
243  D_ENCRYPT(l,r,18); /* 10 */
244  D_ENCRYPT(r,l,16); /* 9 */
245  D_ENCRYPT(l,r,14); /* 8 */
246  D_ENCRYPT(r,l,12); /* 7 */
247  D_ENCRYPT(l,r,10); /* 6 */
248  D_ENCRYPT(r,l, 8); /* 5 */
249  D_ENCRYPT(l,r, 6); /* 4 */
250  D_ENCRYPT(r,l, 4); /* 3 */
251  D_ENCRYPT(l,r, 2); /* 2 */
252  D_ENCRYPT(r,l, 0); /* 1 */
253 #else
254  for (i=30; i>0; i-=8)
255  {
256  D_ENCRYPT(l,r,i-0); /* 16 */
257  D_ENCRYPT(r,l,i-2); /* 15 */
258  D_ENCRYPT(l,r,i-4); /* 14 */
259  D_ENCRYPT(r,l,i-6); /* 13 */
260  }
261 #endif
262  }
263  /* rotate and clear the top bits on machines with 8byte longs */
264  data[0]=ROTATE(l,3)&0xffffffffL;
265  data[1]=ROTATE(r,3)&0xffffffffL;
266  l=r=t=u=0;
267  }
268 
270  des_key_schedule ks3)
271  {
272  register DES_LONG l,r;
273 
274  l=data[0];
275  r=data[1];
276  IP(l,r);
277  data[0]=l;
278  data[1]=r;
279  des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
280  des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
281  des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
282  l=data[0];
283  r=data[1];
284  FP(r,l);
285  data[0]=l;
286  data[1]=r;
287  }
288 
290  des_key_schedule ks3)
291  {
292  register DES_LONG l,r;
293 
294  l=data[0];
295  r=data[1];
296  IP(l,r);
297  data[0]=l;
298  data[1]=r;
299  des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
300  des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
301  des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
302  l=data[0];
303  r=data[1];
304  FP(r,l);
305  data[0]=l;
306  data[1]=r;
307  }
308 
309 #ifndef DES_DEFAULT_OPTIONS
310 
311 #undef CBC_ENC_C__DONT_UPDATE_IV
312 
313 void des_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
315  des_key_schedule ks3, des_cblock *ivec, int enc)
316  {
317  register DES_LONG tin0,tin1;
318  register DES_LONG tout0,tout1,xor0,xor1;
319  register const unsigned char *in;
320  unsigned char *out;
321  register long l=length;
322  DES_LONG tin[2];
323  unsigned char *iv;
324 
325  in=input;
326  out=output;
327  iv = &(*ivec)[0];
328 
329  if (enc)
330  {
331  c2l(iv,tout0);
332  c2l(iv,tout1);
333  for (l-=8; l>=0; l-=8)
334  {
335  c2l(in,tin0);
336  c2l(in,tin1);
337  tin0^=tout0;
338  tin1^=tout1;
339 
340  tin[0]=tin0;
341  tin[1]=tin1;
342  des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
343  tout0=tin[0];
344  tout1=tin[1];
345 
346  l2c(tout0,out);
347  l2c(tout1,out);
348  }
349  if (l != -8)
350  {
351  c2ln(in,tin0,tin1,l+8);
352  tin0^=tout0;
353  tin1^=tout1;
354 
355  tin[0]=tin0;
356  tin[1]=tin1;
357  des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
358  tout0=tin[0];
359  tout1=tin[1];
360 
361  l2c(tout0,out);
362  l2c(tout1,out);
363  }
364  iv = &(*ivec)[0];
365  l2c(tout0,iv);
366  l2c(tout1,iv);
367  }
368  else
369  {
370  register DES_LONG t0,t1;
371 
372  c2l(iv,xor0);
373  c2l(iv,xor1);
374  for (l-=8; l>=0; l-=8)
375  {
376  c2l(in,tin0);
377  c2l(in,tin1);
378 
379  t0=tin0;
380  t1=tin1;
381 
382  tin[0]=tin0;
383  tin[1]=tin1;
384  des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
385  tout0=tin[0];
386  tout1=tin[1];
387 
388  tout0^=xor0;
389  tout1^=xor1;
390  l2c(tout0,out);
391  l2c(tout1,out);
392  xor0=t0;
393  xor1=t1;
394  }
395  if (l != -8)
396  {
397  c2l(in,tin0);
398  c2l(in,tin1);
399 
400  t0=tin0;
401  t1=tin1;
402 
403  tin[0]=tin0;
404  tin[1]=tin1;
405  des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
406  tout0=tin[0];
407  tout1=tin[1];
408 
409  tout0^=xor0;
410  tout1^=xor1;
411  l2cn(tout0,tout1,out,l+8);
412  xor0=t0;
413  xor1=t1;
414  }
415 
416  iv = &(*ivec)[0];
417  l2c(xor0,iv);
418  l2c(xor1,iv);
419  }
420  tin0=tin1=tout0=tout1=xor0=xor1=0;
421  tin[0]=tin[1]=0;
422  }
423 
424 #endif /* DES_DEFAULT_OPTIONS */
425 
426 #endif /* USE_ASM */