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