des_enc.c revision 280304
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#include "spr.h"
61
62void 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
154void 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
239void 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
259void 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
284void 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 */
390