/*
 * 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/cast.h>
#include "cast_lcl.h"

void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key)
{
    register CAST_LONG l, r, t;
    const register CAST_LONG *k;

    k = &(key->data[0]);
    l = data[0];
    r = data[1];

    E_CAST(0, k, l, r, +, ^, -);
    E_CAST(1, k, r, l, ^, -, +);
    E_CAST(2, k, l, r, -, +, ^);
    E_CAST(3, k, r, l, +, ^, -);
    E_CAST(4, k, l, r, ^, -, +);
    E_CAST(5, k, r, l, -, +, ^);
    E_CAST(6, k, l, r, +, ^, -);
    E_CAST(7, k, r, l, ^, -, +);
    E_CAST(8, k, l, r, -, +, ^);
    E_CAST(9, k, r, l, +, ^, -);
    E_CAST(10, k, l, r, ^, -, +);
    E_CAST(11, k, r, l, -, +, ^);
    if (!key->short_key) {
        E_CAST(12, k, l, r, +, ^, -);
        E_CAST(13, k, r, l, ^, -, +);
        E_CAST(14, k, l, r, -, +, ^);
        E_CAST(15, k, r, l, +, ^, -);
    }

    data[1] = l & 0xffffffffL;
    data[0] = r & 0xffffffffL;
}

void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key)
{
    register CAST_LONG l, r, t;
    const register CAST_LONG *k;

    k = &(key->data[0]);
    l = data[0];
    r = data[1];

    if (!key->short_key) {
        E_CAST(15, k, l, r, +, ^, -);
        E_CAST(14, k, r, l, -, +, ^);
        E_CAST(13, k, l, r, ^, -, +);
        E_CAST(12, k, r, l, +, ^, -);
    }
    E_CAST(11, k, l, r, -, +, ^);
    E_CAST(10, k, r, l, ^, -, +);
    E_CAST(9, k, l, r, +, ^, -);
    E_CAST(8, k, r, l, -, +, ^);
    E_CAST(7, k, l, r, ^, -, +);
    E_CAST(6, k, r, l, +, ^, -);
    E_CAST(5, k, l, r, -, +, ^);
    E_CAST(4, k, r, l, ^, -, +);
    E_CAST(3, k, l, r, +, ^, -);
    E_CAST(2, k, r, l, -, +, ^);
    E_CAST(1, k, l, r, ^, -, +);
    E_CAST(0, k, r, l, +, ^, -);

    data[1] = l & 0xffffffffL;
    data[0] = r & 0xffffffffL;
}

void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out,
                      long length, const CAST_KEY *ks, unsigned char *iv,
                      int enc)
{
    register CAST_LONG tin0, tin1;
    register CAST_LONG tout0, tout1, xor0, xor1;
    register long l = length;
    CAST_LONG tin[2];

    if (enc) {
        n2l(iv, tout0);
        n2l(iv, tout1);
        iv -= 8;
        for (l -= 8; l >= 0; l -= 8) {
            n2l(in, tin0);
            n2l(in, tin1);
            tin0 ^= tout0;
            tin1 ^= tout1;
            tin[0] = tin0;
            tin[1] = tin1;
            CAST_encrypt(tin, ks);
            tout0 = tin[0];
            tout1 = tin[1];
            l2n(tout0, out);
            l2n(tout1, out);
        }
        if (l != -8) {
            n2ln(in, tin0, tin1, l + 8);
            tin0 ^= tout0;
            tin1 ^= tout1;
            tin[0] = tin0;
            tin[1] = tin1;
            CAST_encrypt(tin, ks);
            tout0 = tin[0];
            tout1 = tin[1];
            l2n(tout0, out);
            l2n(tout1, out);
        }
        l2n(tout0, iv);
        l2n(tout1, iv);
    } else {
        n2l(iv, xor0);
        n2l(iv, xor1);
        iv -= 8;
        for (l -= 8; l >= 0; l -= 8) {
            n2l(in, tin0);
            n2l(in, tin1);
            tin[0] = tin0;
            tin[1] = tin1;
            CAST_decrypt(tin, ks);
            tout0 = tin[0] ^ xor0;
            tout1 = tin[1] ^ xor1;
            l2n(tout0, out);
            l2n(tout1, out);
            xor0 = tin0;
            xor1 = tin1;
        }
        if (l != -8) {
            n2l(in, tin0);
            n2l(in, tin1);
            tin[0] = tin0;
            tin[1] = tin1;
            CAST_decrypt(tin, ks);
            tout0 = tin[0] ^ xor0;
            tout1 = tin[1] ^ xor1;
            l2nn(tout0, tout1, out, l + 8);
            xor0 = tin0;
            xor1 = tin1;
        }
        l2n(xor0, iv);
        l2n(xor1, iv);
    }
    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
    tin[0] = tin[1] = 0;
}
