155714Skris/* crypto/des/des_enc.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296341Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296341Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296341Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296341Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296341Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include "des_locl.h"
60238405Sjkim#include "spr.h"
6155714Skris
62109998Smarkmvoid DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
63296341Sdelphij{
64296341Sdelphij    register DES_LONG l, r, t, u;
6555714Skris#ifdef DES_PTR
66296341Sdelphij    register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
6755714Skris#endif
6855714Skris#ifndef DES_UNROLL
69296341Sdelphij    register int i;
7055714Skris#endif
71296341Sdelphij    register DES_LONG *s;
7255714Skris
73296341Sdelphij    r = data[0];
74296341Sdelphij    l = data[1];
7555714Skris
76296341Sdelphij    IP(r, l);
77296341Sdelphij    /*
78296341Sdelphij     * Things have been modified so that the initial rotate is done outside
79296341Sdelphij     * the loop.  This required the DES_SPtrans values in sp.h to be rotated
80296341Sdelphij     * 1 bit to the right. One perl script later and things have a 5% speed
81296341Sdelphij     * up on a sparc2. Thanks to Richard Outerbridge
82296341Sdelphij     * <71755.204@CompuServe.COM> for pointing this out.
83296341Sdelphij     */
84296341Sdelphij    /* clear the top bits on machines with 8byte longs */
85296341Sdelphij    /* shift left by 2 */
86296341Sdelphij    r = ROTATE(r, 29) & 0xffffffffL;
87296341Sdelphij    l = ROTATE(l, 29) & 0xffffffffL;
8855714Skris
89296341Sdelphij    s = ks->ks->deslong;
90296341Sdelphij    /*
91296341Sdelphij     * I don't know if it is worth the effort of loop unrolling the inner
92296341Sdelphij     * loop
93296341Sdelphij     */
94296341Sdelphij    if (enc) {
9555714Skris#ifdef DES_UNROLL
96296341Sdelphij        D_ENCRYPT(l, r, 0);     /* 1 */
97296341Sdelphij        D_ENCRYPT(r, l, 2);     /* 2 */
98296341Sdelphij        D_ENCRYPT(l, r, 4);     /* 3 */
99296341Sdelphij        D_ENCRYPT(r, l, 6);     /* 4 */
100296341Sdelphij        D_ENCRYPT(l, r, 8);     /* 5 */
101296341Sdelphij        D_ENCRYPT(r, l, 10);    /* 6 */
102296341Sdelphij        D_ENCRYPT(l, r, 12);    /* 7 */
103296341Sdelphij        D_ENCRYPT(r, l, 14);    /* 8 */
104296341Sdelphij        D_ENCRYPT(l, r, 16);    /* 9 */
105296341Sdelphij        D_ENCRYPT(r, l, 18);    /* 10 */
106296341Sdelphij        D_ENCRYPT(l, r, 20);    /* 11 */
107296341Sdelphij        D_ENCRYPT(r, l, 22);    /* 12 */
108296341Sdelphij        D_ENCRYPT(l, r, 24);    /* 13 */
109296341Sdelphij        D_ENCRYPT(r, l, 26);    /* 14 */
110296341Sdelphij        D_ENCRYPT(l, r, 28);    /* 15 */
111296341Sdelphij        D_ENCRYPT(r, l, 30);    /* 16 */
11255714Skris#else
113296341Sdelphij        for (i = 0; i < 32; i += 4) {
114296341Sdelphij            D_ENCRYPT(l, r, i + 0); /* 1 */
115296341Sdelphij            D_ENCRYPT(r, l, i + 2); /* 2 */
116296341Sdelphij        }
11755714Skris#endif
118296341Sdelphij    } else {
11955714Skris#ifdef DES_UNROLL
120296341Sdelphij        D_ENCRYPT(l, r, 30);    /* 16 */
121296341Sdelphij        D_ENCRYPT(r, l, 28);    /* 15 */
122296341Sdelphij        D_ENCRYPT(l, r, 26);    /* 14 */
123296341Sdelphij        D_ENCRYPT(r, l, 24);    /* 13 */
124296341Sdelphij        D_ENCRYPT(l, r, 22);    /* 12 */
125296341Sdelphij        D_ENCRYPT(r, l, 20);    /* 11 */
126296341Sdelphij        D_ENCRYPT(l, r, 18);    /* 10 */
127296341Sdelphij        D_ENCRYPT(r, l, 16);    /* 9 */
128296341Sdelphij        D_ENCRYPT(l, r, 14);    /* 8 */
129296341Sdelphij        D_ENCRYPT(r, l, 12);    /* 7 */
130296341Sdelphij        D_ENCRYPT(l, r, 10);    /* 6 */
131296341Sdelphij        D_ENCRYPT(r, l, 8);     /* 5 */
132296341Sdelphij        D_ENCRYPT(l, r, 6);     /* 4 */
133296341Sdelphij        D_ENCRYPT(r, l, 4);     /* 3 */
134296341Sdelphij        D_ENCRYPT(l, r, 2);     /* 2 */
135296341Sdelphij        D_ENCRYPT(r, l, 0);     /* 1 */
13655714Skris#else
137296341Sdelphij        for (i = 30; i > 0; i -= 4) {
138296341Sdelphij            D_ENCRYPT(l, r, i - 0); /* 16 */
139296341Sdelphij            D_ENCRYPT(r, l, i - 2); /* 15 */
140296341Sdelphij        }
14155714Skris#endif
142296341Sdelphij    }
14355714Skris
144296341Sdelphij    /* rotate and clear the top bits on machines with 8byte longs */
145296341Sdelphij    l = ROTATE(l, 3) & 0xffffffffL;
146296341Sdelphij    r = ROTATE(r, 3) & 0xffffffffL;
14755714Skris
148296341Sdelphij    FP(r, l);
149296341Sdelphij    data[0] = l;
150296341Sdelphij    data[1] = r;
151296341Sdelphij    l = r = t = u = 0;
152296341Sdelphij}
15355714Skris
154109998Smarkmvoid DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
155296341Sdelphij{
156296341Sdelphij    register DES_LONG l, r, t, u;
15755714Skris#ifdef DES_PTR
158296341Sdelphij    register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans;
15955714Skris#endif
16055714Skris#ifndef DES_UNROLL
161296341Sdelphij    register int i;
16255714Skris#endif
163296341Sdelphij    register DES_LONG *s;
16455714Skris
165296341Sdelphij    r = data[0];
166296341Sdelphij    l = data[1];
16755714Skris
168296341Sdelphij    /*
169296341Sdelphij     * Things have been modified so that the initial rotate is done outside
170296341Sdelphij     * the loop.  This required the DES_SPtrans values in sp.h to be rotated
171296341Sdelphij     * 1 bit to the right. One perl script later and things have a 5% speed
172296341Sdelphij     * up on a sparc2. Thanks to Richard Outerbridge
173296341Sdelphij     * <71755.204@CompuServe.COM> for pointing this out.
174296341Sdelphij     */
175296341Sdelphij    /* clear the top bits on machines with 8byte longs */
176296341Sdelphij    r = ROTATE(r, 29) & 0xffffffffL;
177296341Sdelphij    l = ROTATE(l, 29) & 0xffffffffL;
17855714Skris
179296341Sdelphij    s = ks->ks->deslong;
180296341Sdelphij    /*
181296341Sdelphij     * I don't know if it is worth the effort of loop unrolling the inner
182296341Sdelphij     * loop
183296341Sdelphij     */
184296341Sdelphij    if (enc) {
18555714Skris#ifdef DES_UNROLL
186296341Sdelphij        D_ENCRYPT(l, r, 0);     /* 1 */
187296341Sdelphij        D_ENCRYPT(r, l, 2);     /* 2 */
188296341Sdelphij        D_ENCRYPT(l, r, 4);     /* 3 */
189296341Sdelphij        D_ENCRYPT(r, l, 6);     /* 4 */
190296341Sdelphij        D_ENCRYPT(l, r, 8);     /* 5 */
191296341Sdelphij        D_ENCRYPT(r, l, 10);    /* 6 */
192296341Sdelphij        D_ENCRYPT(l, r, 12);    /* 7 */
193296341Sdelphij        D_ENCRYPT(r, l, 14);    /* 8 */
194296341Sdelphij        D_ENCRYPT(l, r, 16);    /* 9 */
195296341Sdelphij        D_ENCRYPT(r, l, 18);    /* 10 */
196296341Sdelphij        D_ENCRYPT(l, r, 20);    /* 11 */
197296341Sdelphij        D_ENCRYPT(r, l, 22);    /* 12 */
198296341Sdelphij        D_ENCRYPT(l, r, 24);    /* 13 */
199296341Sdelphij        D_ENCRYPT(r, l, 26);    /* 14 */
200296341Sdelphij        D_ENCRYPT(l, r, 28);    /* 15 */
201296341Sdelphij        D_ENCRYPT(r, l, 30);    /* 16 */
20255714Skris#else
203296341Sdelphij        for (i = 0; i < 32; i += 4) {
204296341Sdelphij            D_ENCRYPT(l, r, i + 0); /* 1 */
205296341Sdelphij            D_ENCRYPT(r, l, i + 2); /* 2 */
206296341Sdelphij        }
20755714Skris#endif
208296341Sdelphij    } else {
20955714Skris#ifdef DES_UNROLL
210296341Sdelphij        D_ENCRYPT(l, r, 30);    /* 16 */
211296341Sdelphij        D_ENCRYPT(r, l, 28);    /* 15 */
212296341Sdelphij        D_ENCRYPT(l, r, 26);    /* 14 */
213296341Sdelphij        D_ENCRYPT(r, l, 24);    /* 13 */
214296341Sdelphij        D_ENCRYPT(l, r, 22);    /* 12 */
215296341Sdelphij        D_ENCRYPT(r, l, 20);    /* 11 */
216296341Sdelphij        D_ENCRYPT(l, r, 18);    /* 10 */
217296341Sdelphij        D_ENCRYPT(r, l, 16);    /* 9 */
218296341Sdelphij        D_ENCRYPT(l, r, 14);    /* 8 */
219296341Sdelphij        D_ENCRYPT(r, l, 12);    /* 7 */
220296341Sdelphij        D_ENCRYPT(l, r, 10);    /* 6 */
221296341Sdelphij        D_ENCRYPT(r, l, 8);     /* 5 */
222296341Sdelphij        D_ENCRYPT(l, r, 6);     /* 4 */
223296341Sdelphij        D_ENCRYPT(r, l, 4);     /* 3 */
224296341Sdelphij        D_ENCRYPT(l, r, 2);     /* 2 */
225296341Sdelphij        D_ENCRYPT(r, l, 0);     /* 1 */
22655714Skris#else
227296341Sdelphij        for (i = 30; i > 0; i -= 4) {
228296341Sdelphij            D_ENCRYPT(l, r, i - 0); /* 16 */
229296341Sdelphij            D_ENCRYPT(r, l, i - 2); /* 15 */
230296341Sdelphij        }
23155714Skris#endif
232296341Sdelphij    }
233296341Sdelphij    /* rotate and clear the top bits on machines with 8byte longs */
234296341Sdelphij    data[0] = ROTATE(l, 3) & 0xffffffffL;
235296341Sdelphij    data[1] = ROTATE(r, 3) & 0xffffffffL;
236296341Sdelphij    l = r = t = u = 0;
237296341Sdelphij}
23855714Skris
239109998Smarkmvoid DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
240296341Sdelphij                  DES_key_schedule *ks2, DES_key_schedule *ks3)
241296341Sdelphij{
242296341Sdelphij    register DES_LONG l, r;
24355714Skris
244296341Sdelphij    l = data[0];
245296341Sdelphij    r = data[1];
246296341Sdelphij    IP(l, r);
247296341Sdelphij    data[0] = l;
248296341Sdelphij    data[1] = r;
249296341Sdelphij    DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT);
250296341Sdelphij    DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT);
251296341Sdelphij    DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT);
252296341Sdelphij    l = data[0];
253296341Sdelphij    r = data[1];
254296341Sdelphij    FP(r, l);
255296341Sdelphij    data[0] = l;
256296341Sdelphij    data[1] = r;
257296341Sdelphij}
25855714Skris
259109998Smarkmvoid DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
260296341Sdelphij                  DES_key_schedule *ks2, DES_key_schedule *ks3)
261296341Sdelphij{
262296341Sdelphij    register DES_LONG l, r;
26355714Skris
264296341Sdelphij    l = data[0];
265296341Sdelphij    r = data[1];
266296341Sdelphij    IP(l, r);
267296341Sdelphij    data[0] = l;
268296341Sdelphij    data[1] = r;
269296341Sdelphij    DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT);
270296341Sdelphij    DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT);
271296341Sdelphij    DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT);
272296341Sdelphij    l = data[0];
273296341Sdelphij    r = data[1];
274296341Sdelphij    FP(r, l);
275296341Sdelphij    data[0] = l;
276296341Sdelphij    data[1] = r;
277296341Sdelphij}
27855714Skris
27955714Skris#ifndef DES_DEFAULT_OPTIONS
28055714Skris
281296341Sdelphij# undef CBC_ENC_C__DONT_UPDATE_IV
282296341Sdelphij# include "ncbc_enc.c"          /* DES_ncbc_encrypt */
28355714Skris
284109998Smarkmvoid DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
285296341Sdelphij                          long length, DES_key_schedule *ks1,
286296341Sdelphij                          DES_key_schedule *ks2, DES_key_schedule *ks3,
287296341Sdelphij                          DES_cblock *ivec, int enc)
288296341Sdelphij{
289296341Sdelphij    register DES_LONG tin0, tin1;
290296341Sdelphij    register DES_LONG tout0, tout1, xor0, xor1;
291296341Sdelphij    register const unsigned char *in;
292296341Sdelphij    unsigned char *out;
293296341Sdelphij    register long l = length;
294296341Sdelphij    DES_LONG tin[2];
295296341Sdelphij    unsigned char *iv;
29655714Skris
297296341Sdelphij    in = input;
298296341Sdelphij    out = output;
299296341Sdelphij    iv = &(*ivec)[0];
30055714Skris
301296341Sdelphij    if (enc) {
302296341Sdelphij        c2l(iv, tout0);
303296341Sdelphij        c2l(iv, tout1);
304296341Sdelphij        for (l -= 8; l >= 0; l -= 8) {
305296341Sdelphij            c2l(in, tin0);
306296341Sdelphij            c2l(in, tin1);
307296341Sdelphij            tin0 ^= tout0;
308296341Sdelphij            tin1 ^= tout1;
30955714Skris
310296341Sdelphij            tin[0] = tin0;
311296341Sdelphij            tin[1] = tin1;
312296341Sdelphij            DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
313296341Sdelphij            tout0 = tin[0];
314296341Sdelphij            tout1 = tin[1];
31555714Skris
316296341Sdelphij            l2c(tout0, out);
317296341Sdelphij            l2c(tout1, out);
318296341Sdelphij        }
319296341Sdelphij        if (l != -8) {
320296341Sdelphij            c2ln(in, tin0, tin1, l + 8);
321296341Sdelphij            tin0 ^= tout0;
322296341Sdelphij            tin1 ^= tout1;
32355714Skris
324296341Sdelphij            tin[0] = tin0;
325296341Sdelphij            tin[1] = tin1;
326296341Sdelphij            DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
327296341Sdelphij            tout0 = tin[0];
328296341Sdelphij            tout1 = tin[1];
32955714Skris
330296341Sdelphij            l2c(tout0, out);
331296341Sdelphij            l2c(tout1, out);
332296341Sdelphij        }
333296341Sdelphij        iv = &(*ivec)[0];
334296341Sdelphij        l2c(tout0, iv);
335296341Sdelphij        l2c(tout1, iv);
336296341Sdelphij    } else {
337296341Sdelphij        register DES_LONG t0, t1;
33855714Skris
339296341Sdelphij        c2l(iv, xor0);
340296341Sdelphij        c2l(iv, xor1);
341296341Sdelphij        for (l -= 8; l >= 0; l -= 8) {
342296341Sdelphij            c2l(in, tin0);
343296341Sdelphij            c2l(in, tin1);
34455714Skris
345296341Sdelphij            t0 = tin0;
346296341Sdelphij            t1 = tin1;
34755714Skris
348296341Sdelphij            tin[0] = tin0;
349296341Sdelphij            tin[1] = tin1;
350296341Sdelphij            DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
351296341Sdelphij            tout0 = tin[0];
352296341Sdelphij            tout1 = tin[1];
35355714Skris
354296341Sdelphij            tout0 ^= xor0;
355296341Sdelphij            tout1 ^= xor1;
356296341Sdelphij            l2c(tout0, out);
357296341Sdelphij            l2c(tout1, out);
358296341Sdelphij            xor0 = t0;
359296341Sdelphij            xor1 = t1;
360296341Sdelphij        }
361296341Sdelphij        if (l != -8) {
362296341Sdelphij            c2l(in, tin0);
363296341Sdelphij            c2l(in, tin1);
36455714Skris
365296341Sdelphij            t0 = tin0;
366296341Sdelphij            t1 = tin1;
36755714Skris
368296341Sdelphij            tin[0] = tin0;
369296341Sdelphij            tin[1] = tin1;
370296341Sdelphij            DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
371296341Sdelphij            tout0 = tin[0];
372296341Sdelphij            tout1 = tin[1];
37355714Skris
374296341Sdelphij            tout0 ^= xor0;
375296341Sdelphij            tout1 ^= xor1;
376296341Sdelphij            l2cn(tout0, tout1, out, l + 8);
377296341Sdelphij            xor0 = t0;
378296341Sdelphij            xor1 = t1;
379296341Sdelphij        }
380296341Sdelphij
381296341Sdelphij        iv = &(*ivec)[0];
382296341Sdelphij        l2c(xor0, iv);
383296341Sdelphij        l2c(xor1, iv);
384296341Sdelphij    }
385296341Sdelphij    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
386296341Sdelphij    tin[0] = tin[1] = 0;
387296341Sdelphij}
388296341Sdelphij
389296341Sdelphij#endif                          /* DES_DEFAULT_OPTIONS */
390