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