1/*
2 * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10/*-
11 * #included by:
12 *    cbc_enc.c  (DES_cbc_encrypt)
13 *    des_enc.c  (DES_ncbc_encrypt)
14 */
15
16#include "des_local.h"
17
18#ifdef CBC_ENC_C__DONT_UPDATE_IV
19void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
20                     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
21#else
22void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out,
23                      long length, DES_key_schedule *_schedule,
24                      DES_cblock *ivec, int enc)
25#endif
26{
27    register DES_LONG tin0, tin1;
28    register DES_LONG tout0, tout1, xor0, xor1;
29    register long l = length;
30    DES_LONG tin[2];
31    unsigned char *iv;
32
33    iv = &(*ivec)[0];
34
35    if (enc) {
36        c2l(iv, tout0);
37        c2l(iv, tout1);
38        for (l -= 8; l >= 0; l -= 8) {
39            c2l(in, tin0);
40            c2l(in, tin1);
41            tin0 ^= tout0;
42            tin[0] = tin0;
43            tin1 ^= tout1;
44            tin[1] = tin1;
45            DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
46            tout0 = tin[0];
47            l2c(tout0, out);
48            tout1 = tin[1];
49            l2c(tout1, out);
50        }
51        if (l != -8) {
52            c2ln(in, tin0, tin1, l + 8);
53            tin0 ^= tout0;
54            tin[0] = tin0;
55            tin1 ^= tout1;
56            tin[1] = tin1;
57            DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
58            tout0 = tin[0];
59            l2c(tout0, out);
60            tout1 = tin[1];
61            l2c(tout1, out);
62        }
63#ifndef CBC_ENC_C__DONT_UPDATE_IV
64        iv = &(*ivec)[0];
65        l2c(tout0, iv);
66        l2c(tout1, iv);
67#endif
68    } else {
69        c2l(iv, xor0);
70        c2l(iv, xor1);
71        for (l -= 8; l >= 0; l -= 8) {
72            c2l(in, tin0);
73            tin[0] = tin0;
74            c2l(in, tin1);
75            tin[1] = tin1;
76            DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
77            tout0 = tin[0] ^ xor0;
78            tout1 = tin[1] ^ xor1;
79            l2c(tout0, out);
80            l2c(tout1, out);
81            xor0 = tin0;
82            xor1 = tin1;
83        }
84        if (l != -8) {
85            c2l(in, tin0);
86            tin[0] = tin0;
87            c2l(in, tin1);
88            tin[1] = tin1;
89            DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
90            tout0 = tin[0] ^ xor0;
91            tout1 = tin[1] ^ xor1;
92            l2cn(tout0, tout1, out, l + 8);
93#ifndef CBC_ENC_C__DONT_UPDATE_IV
94            xor0 = tin0;
95            xor1 = tin1;
96#endif
97        }
98#ifndef CBC_ENC_C__DONT_UPDATE_IV
99        iv = &(*ivec)[0];
100        l2c(xor0, iv);
101        l2c(xor1, iv);
102#endif
103    }
104    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
105    tin[0] = tin[1] = 0;
106}
107