1*1dcdf01fSchristos /*
2*1dcdf01fSchristos  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
360662d10Schristos  *
4*1dcdf01fSchristos  * Licensed under the OpenSSL license (the "License").  You may not use
5*1dcdf01fSchristos  * this file except in compliance with the License.  You can obtain a copy
6*1dcdf01fSchristos  * in the file LICENSE in the source distribution or at
7*1dcdf01fSchristos  * https://www.openssl.org/source/license.html
860662d10Schristos  */
960662d10Schristos 
10*1dcdf01fSchristos #include "des_local.h"
1160662d10Schristos 
1260662d10Schristos /* RSA's DESX */
1360662d10Schristos 
DES_xcbc_encrypt(const unsigned char * in,unsigned char * out,long length,DES_key_schedule * schedule,DES_cblock * ivec,const_DES_cblock * inw,const_DES_cblock * outw,int enc)1460662d10Schristos void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out,
1560662d10Schristos                       long length, DES_key_schedule *schedule,
1660662d10Schristos                       DES_cblock *ivec, const_DES_cblock *inw,
1760662d10Schristos                       const_DES_cblock *outw, int enc)
1860662d10Schristos {
1960662d10Schristos     register DES_LONG tin0, tin1;
2060662d10Schristos     register DES_LONG tout0, tout1, xor0, xor1;
2160662d10Schristos     register DES_LONG inW0, inW1, outW0, outW1;
2260662d10Schristos     register const unsigned char *in2;
2360662d10Schristos     register long l = length;
2460662d10Schristos     DES_LONG tin[2];
2560662d10Schristos     unsigned char *iv;
2660662d10Schristos 
2760662d10Schristos     in2 = &(*inw)[0];
2860662d10Schristos     c2l(in2, inW0);
2960662d10Schristos     c2l(in2, inW1);
3060662d10Schristos     in2 = &(*outw)[0];
3160662d10Schristos     c2l(in2, outW0);
3260662d10Schristos     c2l(in2, outW1);
3360662d10Schristos 
3460662d10Schristos     iv = &(*ivec)[0];
3560662d10Schristos 
3660662d10Schristos     if (enc) {
3760662d10Schristos         c2l(iv, tout0);
3860662d10Schristos         c2l(iv, tout1);
3960662d10Schristos         for (l -= 8; l >= 0; l -= 8) {
4060662d10Schristos             c2l(in, tin0);
4160662d10Schristos             c2l(in, tin1);
4260662d10Schristos             tin0 ^= tout0 ^ inW0;
4360662d10Schristos             tin[0] = tin0;
4460662d10Schristos             tin1 ^= tout1 ^ inW1;
4560662d10Schristos             tin[1] = tin1;
4660662d10Schristos             DES_encrypt1(tin, schedule, DES_ENCRYPT);
4760662d10Schristos             tout0 = tin[0] ^ outW0;
4860662d10Schristos             l2c(tout0, out);
4960662d10Schristos             tout1 = tin[1] ^ outW1;
5060662d10Schristos             l2c(tout1, out);
5160662d10Schristos         }
5260662d10Schristos         if (l != -8) {
5360662d10Schristos             c2ln(in, tin0, tin1, l + 8);
5460662d10Schristos             tin0 ^= tout0 ^ inW0;
5560662d10Schristos             tin[0] = tin0;
5660662d10Schristos             tin1 ^= tout1 ^ inW1;
5760662d10Schristos             tin[1] = tin1;
5860662d10Schristos             DES_encrypt1(tin, schedule, DES_ENCRYPT);
5960662d10Schristos             tout0 = tin[0] ^ outW0;
6060662d10Schristos             l2c(tout0, out);
6160662d10Schristos             tout1 = tin[1] ^ outW1;
6260662d10Schristos             l2c(tout1, out);
6360662d10Schristos         }
6460662d10Schristos         iv = &(*ivec)[0];
6560662d10Schristos         l2c(tout0, iv);
6660662d10Schristos         l2c(tout1, iv);
6760662d10Schristos     } else {
6860662d10Schristos         c2l(iv, xor0);
6960662d10Schristos         c2l(iv, xor1);
7060662d10Schristos         for (l -= 8; l > 0; l -= 8) {
7160662d10Schristos             c2l(in, tin0);
7260662d10Schristos             tin[0] = tin0 ^ outW0;
7360662d10Schristos             c2l(in, tin1);
7460662d10Schristos             tin[1] = tin1 ^ outW1;
7560662d10Schristos             DES_encrypt1(tin, schedule, DES_DECRYPT);
7660662d10Schristos             tout0 = tin[0] ^ xor0 ^ inW0;
7760662d10Schristos             tout1 = tin[1] ^ xor1 ^ inW1;
7860662d10Schristos             l2c(tout0, out);
7960662d10Schristos             l2c(tout1, out);
8060662d10Schristos             xor0 = tin0;
8160662d10Schristos             xor1 = tin1;
8260662d10Schristos         }
8360662d10Schristos         if (l != -8) {
8460662d10Schristos             c2l(in, tin0);
8560662d10Schristos             tin[0] = tin0 ^ outW0;
8660662d10Schristos             c2l(in, tin1);
8760662d10Schristos             tin[1] = tin1 ^ outW1;
8860662d10Schristos             DES_encrypt1(tin, schedule, DES_DECRYPT);
8960662d10Schristos             tout0 = tin[0] ^ xor0 ^ inW0;
9060662d10Schristos             tout1 = tin[1] ^ xor1 ^ inW1;
9160662d10Schristos             l2cn(tout0, tout1, out, l + 8);
9260662d10Schristos             xor0 = tin0;
9360662d10Schristos             xor1 = tin1;
9460662d10Schristos         }
9560662d10Schristos 
9660662d10Schristos         iv = &(*ivec)[0];
9760662d10Schristos         l2c(xor0, iv);
9860662d10Schristos         l2c(xor1, iv);
9960662d10Schristos     }
10060662d10Schristos     tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
10160662d10Schristos     inW0 = inW1 = outW0 = outW1 = 0;
10260662d10Schristos     tin[0] = tin[1] = 0;
10360662d10Schristos }
104