Fix no-stdio build
[openssl.git] / crypto / des / des_enc.c
1 /* crypto/des/des_enc.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
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 (tjh@cryptsoft.com).
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 (eay@cryptsoft.com)"
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 (tjh@cryptsoft.com)"
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 #include <openssl/crypto.h>
60 #include "des_locl.h"
61 #include "spr.h"
62
63 void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
64 {
65     register DES_LONG l, r, t, u;
66 #ifdef DES_PTR
67     register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
68 #endif
69 #ifndef DES_UNROLL
70     register int i;
71 #endif
72     register DES_LONG *s;
73
74     r = data[0];
75     l = data[1];
76
77     IP(r, l);
78     /*
79      * Things have been modified so that the initial rotate is done outside
80      * the loop.  This required the DES_SPtrans values in sp.h to be rotated
81      * 1 bit to the right. One perl script later and things have a 5% speed
82      * up on a sparc2. Thanks to Richard Outerbridge
83      * <71755.204@CompuServe.COM> for pointing this out.
84      */
85     /* clear the top bits on machines with 8byte longs */
86     /* shift left by 2 */
87     r = ROTATE(r, 29) & 0xffffffffL;
88     l = ROTATE(l, 29) & 0xffffffffL;
89
90     s = ks->ks->deslong;
91     /*
92      * I don't know if it is worth the effort of loop unrolling the inner
93      * loop
94      */
95     if (enc) {
96 #ifdef DES_UNROLL
97         D_ENCRYPT(l, r, 0);     /* 1 */
98         D_ENCRYPT(r, l, 2);     /* 2 */
99         D_ENCRYPT(l, r, 4);     /* 3 */
100         D_ENCRYPT(r, l, 6);     /* 4 */
101         D_ENCRYPT(l, r, 8);     /* 5 */
102         D_ENCRYPT(r, l, 10);    /* 6 */
103         D_ENCRYPT(l, r, 12);    /* 7 */
104         D_ENCRYPT(r, l, 14);    /* 8 */
105         D_ENCRYPT(l, r, 16);    /* 9 */
106         D_ENCRYPT(r, l, 18);    /* 10 */
107         D_ENCRYPT(l, r, 20);    /* 11 */
108         D_ENCRYPT(r, l, 22);    /* 12 */
109         D_ENCRYPT(l, r, 24);    /* 13 */
110         D_ENCRYPT(r, l, 26);    /* 14 */
111         D_ENCRYPT(l, r, 28);    /* 15 */
112         D_ENCRYPT(r, l, 30);    /* 16 */
113 #else
114         for (i = 0; i < 32; i += 4) {
115             D_ENCRYPT(l, r, i + 0); /* 1 */
116             D_ENCRYPT(r, l, i + 2); /* 2 */
117         }
118 #endif
119     } else {
120 #ifdef DES_UNROLL
121         D_ENCRYPT(l, r, 30);    /* 16 */
122         D_ENCRYPT(r, l, 28);    /* 15 */
123         D_ENCRYPT(l, r, 26);    /* 14 */
124         D_ENCRYPT(r, l, 24);    /* 13 */
125         D_ENCRYPT(l, r, 22);    /* 12 */
126         D_ENCRYPT(r, l, 20);    /* 11 */
127         D_ENCRYPT(l, r, 18);    /* 10 */
128         D_ENCRYPT(r, l, 16);    /* 9 */
129         D_ENCRYPT(l, r, 14);    /* 8 */
130         D_ENCRYPT(r, l, 12);    /* 7 */
131         D_ENCRYPT(l, r, 10);    /* 6 */
132         D_ENCRYPT(r, l, 8);     /* 5 */
133         D_ENCRYPT(l, r, 6);     /* 4 */
134         D_ENCRYPT(r, l, 4);     /* 3 */
135         D_ENCRYPT(l, r, 2);     /* 2 */
136         D_ENCRYPT(r, l, 0);     /* 1 */
137 #else
138         for (i = 30; i > 0; i -= 4) {
139             D_ENCRYPT(l, r, i - 0); /* 16 */
140             D_ENCRYPT(r, l, i - 2); /* 15 */
141         }
142 #endif
143     }
144
145     /* rotate and clear the top bits on machines with 8byte longs */
146     l = ROTATE(l, 3) & 0xffffffffL;
147     r = ROTATE(r, 3) & 0xffffffffL;
148
149     FP(r, l);
150     data[0] = l;
151     data[1] = r;
152     l = r = t = u = 0;
153 }
154
155 void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
156 {
157     register DES_LONG l, r, t, u;
158 #ifdef DES_PTR
159     register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
160 #endif
161 #ifndef DES_UNROLL
162     register int i;
163 #endif
164     register DES_LONG *s;
165
166     r = data[0];
167     l = data[1];
168
169     /*
170      * Things have been modified so that the initial rotate is done outside
171      * the loop.  This required the DES_SPtrans values in sp.h to be rotated
172      * 1 bit to the right. One perl script later and things have a 5% speed
173      * up on a sparc2. Thanks to Richard Outerbridge
174      * <71755.204@CompuServe.COM> for pointing this out.
175      */
176     /* clear the top bits on machines with 8byte longs */
177     r = ROTATE(r, 29) & 0xffffffffL;
178     l = ROTATE(l, 29) & 0xffffffffL;
179
180     s = ks->ks->deslong;
181     /*
182      * I don't know if it is worth the effort of loop unrolling the inner
183      * loop
184      */
185     if (enc) {
186 #ifdef DES_UNROLL
187         D_ENCRYPT(l, r, 0);     /* 1 */
188         D_ENCRYPT(r, l, 2);     /* 2 */
189         D_ENCRYPT(l, r, 4);     /* 3 */
190         D_ENCRYPT(r, l, 6);     /* 4 */
191         D_ENCRYPT(l, r, 8);     /* 5 */
192         D_ENCRYPT(r, l, 10);    /* 6 */
193         D_ENCRYPT(l, r, 12);    /* 7 */
194         D_ENCRYPT(r, l, 14);    /* 8 */
195         D_ENCRYPT(l, r, 16);    /* 9 */
196         D_ENCRYPT(r, l, 18);    /* 10 */
197         D_ENCRYPT(l, r, 20);    /* 11 */
198         D_ENCRYPT(r, l, 22);    /* 12 */
199         D_ENCRYPT(l, r, 24);    /* 13 */
200         D_ENCRYPT(r, l, 26);    /* 14 */
201         D_ENCRYPT(l, r, 28);    /* 15 */
202         D_ENCRYPT(r, l, 30);    /* 16 */
203 #else
204         for (i = 0; i < 32; i += 4) {
205             D_ENCRYPT(l, r, i + 0); /* 1 */
206             D_ENCRYPT(r, l, i + 2); /* 2 */
207         }
208 #endif
209     } else {
210 #ifdef DES_UNROLL
211         D_ENCRYPT(l, r, 30);    /* 16 */
212         D_ENCRYPT(r, l, 28);    /* 15 */
213         D_ENCRYPT(l, r, 26);    /* 14 */
214         D_ENCRYPT(r, l, 24);    /* 13 */
215         D_ENCRYPT(l, r, 22);    /* 12 */
216         D_ENCRYPT(r, l, 20);    /* 11 */
217         D_ENCRYPT(l, r, 18);    /* 10 */
218         D_ENCRYPT(r, l, 16);    /* 9 */
219         D_ENCRYPT(l, r, 14);    /* 8 */
220         D_ENCRYPT(r, l, 12);    /* 7 */
221         D_ENCRYPT(l, r, 10);    /* 6 */
222         D_ENCRYPT(r, l, 8);     /* 5 */
223         D_ENCRYPT(l, r, 6);     /* 4 */
224         D_ENCRYPT(r, l, 4);     /* 3 */
225         D_ENCRYPT(l, r, 2);     /* 2 */
226         D_ENCRYPT(r, l, 0);     /* 1 */
227 #else
228         for (i = 30; i > 0; i -= 4) {
229             D_ENCRYPT(l, r, i - 0); /* 16 */
230             D_ENCRYPT(r, l, i - 2); /* 15 */
231         }
232 #endif
233     }
234     /* rotate and clear the top bits on machines with 8byte longs */
235     data[0] = ROTATE(l, 3) & 0xffffffffL;
236     data[1] = ROTATE(r, 3) & 0xffffffffL;
237     l = r = t = u = 0;
238 }
239
240 void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
241                   DES_key_schedule *ks2, DES_key_schedule *ks3)
242 {
243     register DES_LONG l, r;
244
245     l = data[0];
246     r = data[1];
247     IP(l, r);
248     data[0] = l;
249     data[1] = r;
250     DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT);
251     DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT);
252     DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT);
253     l = data[0];
254     r = data[1];
255     FP(r, l);
256     data[0] = l;
257     data[1] = r;
258 }
259
260 void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
261                   DES_key_schedule *ks2, DES_key_schedule *ks3)
262 {
263     register DES_LONG l, r;
264
265     l = data[0];
266     r = data[1];
267     IP(l, r);
268     data[0] = l;
269     data[1] = r;
270     DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT);
271     DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT);
272     DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT);
273     l = data[0];
274     r = data[1];
275     FP(r, l);
276     data[0] = l;
277     data[1] = r;
278 }
279
280 #ifndef DES_DEFAULT_OPTIONS
281
282 # undef CBC_ENC_C__DONT_UPDATE_IV
283 # include "ncbc_enc.c"          /* DES_ncbc_encrypt */
284
285 void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
286                           long length, DES_key_schedule *ks1,
287                           DES_key_schedule *ks2, DES_key_schedule *ks3,
288                           DES_cblock *ivec, int enc)
289 {
290     register DES_LONG tin0, tin1;
291     register DES_LONG tout0, tout1, xor0, xor1;
292     register const unsigned char *in;
293     unsigned char *out;
294     register long l = length;
295     DES_LONG tin[2];
296     unsigned char *iv;
297
298     in = input;
299     out = output;
300     iv = &(*ivec)[0];
301
302     if (enc) {
303         c2l(iv, tout0);
304         c2l(iv, tout1);
305         for (l -= 8; l >= 0; l -= 8) {
306             c2l(in, tin0);
307             c2l(in, tin1);
308             tin0 ^= tout0;
309             tin1 ^= tout1;
310
311             tin[0] = tin0;
312             tin[1] = tin1;
313             DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
314             tout0 = tin[0];
315             tout1 = tin[1];
316
317             l2c(tout0, out);
318             l2c(tout1, out);
319         }
320         if (l != -8) {
321             c2ln(in, tin0, tin1, l + 8);
322             tin0 ^= tout0;
323             tin1 ^= tout1;
324
325             tin[0] = tin0;
326             tin[1] = tin1;
327             DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
328             tout0 = tin[0];
329             tout1 = tin[1];
330
331             l2c(tout0, out);
332             l2c(tout1, out);
333         }
334         iv = &(*ivec)[0];
335         l2c(tout0, iv);
336         l2c(tout1, iv);
337     } else {
338         register DES_LONG t0, t1;
339
340         c2l(iv, xor0);
341         c2l(iv, xor1);
342         for (l -= 8; l >= 0; l -= 8) {
343             c2l(in, tin0);
344             c2l(in, tin1);
345
346             t0 = tin0;
347             t1 = tin1;
348
349             tin[0] = tin0;
350             tin[1] = tin1;
351             DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
352             tout0 = tin[0];
353             tout1 = tin[1];
354
355             tout0 ^= xor0;
356             tout1 ^= xor1;
357             l2c(tout0, out);
358             l2c(tout1, out);
359             xor0 = t0;
360             xor1 = t1;
361         }
362         if (l != -8) {
363             c2l(in, tin0);
364             c2l(in, tin1);
365
366             t0 = tin0;
367             t1 = tin1;
368
369             tin[0] = tin0;
370             tin[1] = tin1;
371             DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
372             tout0 = tin[0];
373             tout1 = tin[1];
374
375             tout0 ^= xor0;
376             tout1 ^= xor1;
377             l2cn(tout0, tout1, out, l + 8);
378             xor0 = t0;
379             xor1 = t1;
380         }
381
382         iv = &(*ivec)[0];
383         l2c(xor0, iv);
384         l2c(xor1, iv);
385     }
386     tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
387     tin[0] = tin[1] = 0;
388 }
389
390 #endif                          /* DES_DEFAULT_OPTIONS */