| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 | /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License").  You may not use * this file except in compliance with the License.  You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */#include <openssl/rc2.h>#include "rc2_locl.h"void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,                     RC2_KEY *ks, unsigned char *iv, int encrypt){    register unsigned long tin0, tin1;    register unsigned long tout0, tout1, xor0, xor1;    register long l = length;    unsigned long tin[2];    if (encrypt) {        c2l(iv, tout0);        c2l(iv, tout1);        iv -= 8;        for (l -= 8; l >= 0; l -= 8) {            c2l(in, tin0);            c2l(in, tin1);            tin0 ^= tout0;            tin1 ^= tout1;            tin[0] = tin0;            tin[1] = tin1;            RC2_encrypt(tin, ks);            tout0 = tin[0];            l2c(tout0, out);            tout1 = tin[1];            l2c(tout1, out);        }        if (l != -8) {            c2ln(in, tin0, tin1, l + 8);            tin0 ^= tout0;            tin1 ^= tout1;            tin[0] = tin0;            tin[1] = tin1;            RC2_encrypt(tin, ks);            tout0 = tin[0];            l2c(tout0, out);            tout1 = tin[1];            l2c(tout1, out);        }        l2c(tout0, iv);        l2c(tout1, iv);    } else {        c2l(iv, xor0);        c2l(iv, xor1);        iv -= 8;        for (l -= 8; l >= 0; l -= 8) {            c2l(in, tin0);            tin[0] = tin0;            c2l(in, tin1);            tin[1] = tin1;            RC2_decrypt(tin, ks);            tout0 = tin[0] ^ xor0;            tout1 = tin[1] ^ xor1;            l2c(tout0, out);            l2c(tout1, out);            xor0 = tin0;            xor1 = tin1;        }        if (l != -8) {            c2l(in, tin0);            tin[0] = tin0;            c2l(in, tin1);            tin[1] = tin1;            RC2_decrypt(tin, ks);            tout0 = tin[0] ^ xor0;            tout1 = tin[1] ^ xor1;            l2cn(tout0, tout1, out, l + 8);            xor0 = tin0;            xor1 = tin1;        }        l2c(xor0, iv);        l2c(xor1, iv);    }    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;    tin[0] = tin[1] = 0;}void RC2_encrypt(unsigned long *d, RC2_KEY *key){    int i, n;    register RC2_INT *p0, *p1;    register RC2_INT x0, x1, x2, x3, t;    unsigned long l;    l = d[0];    x0 = (RC2_INT) l & 0xffff;    x1 = (RC2_INT) (l >> 16L);    l = d[1];    x2 = (RC2_INT) l & 0xffff;    x3 = (RC2_INT) (l >> 16L);    n = 3;    i = 5;    p0 = p1 = &(key->data[0]);    for (;;) {        t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff;        x0 = (t << 1) | (t >> 15);        t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff;        x1 = (t << 2) | (t >> 14);        t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff;        x2 = (t << 3) | (t >> 13);        t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff;        x3 = (t << 5) | (t >> 11);        if (--i == 0) {            if (--n == 0)                break;            i = (n == 2) ? 6 : 5;            x0 += p1[x3 & 0x3f];            x1 += p1[x0 & 0x3f];            x2 += p1[x1 & 0x3f];            x3 += p1[x2 & 0x3f];        }    }    d[0] =        (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L);    d[1] =        (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L);}void RC2_decrypt(unsigned long *d, RC2_KEY *key){    int i, n;    register RC2_INT *p0, *p1;    register RC2_INT x0, x1, x2, x3, t;    unsigned long l;    l = d[0];    x0 = (RC2_INT) l & 0xffff;    x1 = (RC2_INT) (l >> 16L);    l = d[1];    x2 = (RC2_INT) l & 0xffff;    x3 = (RC2_INT) (l >> 16L);    n = 3;    i = 5;    p0 = &(key->data[63]);    p1 = &(key->data[0]);    for (;;) {        t = ((x3 << 11) | (x3 >> 5)) & 0xffff;        x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff;        t = ((x2 << 13) | (x2 >> 3)) & 0xffff;        x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff;        t = ((x1 << 14) | (x1 >> 2)) & 0xffff;        x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff;        t = ((x0 << 15) | (x0 >> 1)) & 0xffff;        x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff;        if (--i == 0) {            if (--n == 0)                break;            i = (n == 2) ? 6 : 5;            x3 = (x3 - p1[x2 & 0x3f]) & 0xffff;            x2 = (x2 - p1[x1 & 0x3f]) & 0xffff;            x1 = (x1 - p1[x0 & 0x3f]) & 0xffff;            x0 = (x0 - p1[x3 & 0x3f]) & 0xffff;        }    }    d[0] =        (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L);    d[1] =        (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L);}
 |