Blame crypto/bf/bf_enc.c

Packit Service 084de1
/*
Packit Service 084de1
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
Packit Service 084de1
 *
Packit Service 084de1
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit Service 084de1
 * this file except in compliance with the License.  You can obtain a copy
Packit Service 084de1
 * in the file LICENSE in the source distribution or at
Packit Service 084de1
 * https://www.openssl.org/source/license.html
Packit Service 084de1
 */
Packit Service 084de1
Packit Service 084de1
#include <openssl/blowfish.h>
Packit Service 084de1
#include "bf_local.h"
Packit Service 084de1
Packit Service 084de1
/*
Packit Service 084de1
 * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From
Packit Service 084de1
 * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE
Packit Service 084de1
 * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
Packit Service 084de1
 */
Packit Service 084de1
Packit Service 084de1
#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
Packit Service 084de1
# error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
Packit Service 084de1
to modify the code.
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
void BF_encrypt(BF_LONG *data, const BF_KEY *key)
Packit Service 084de1
{
Packit Service 084de1
    register BF_LONG l, r;
Packit Service 084de1
    register const BF_LONG *p, *s;
Packit Service 084de1
Packit Service 084de1
    p = key->P;
Packit Service 084de1
    s = &(key->S[0]);
Packit Service 084de1
    l = data[0];
Packit Service 084de1
    r = data[1];
Packit Service 084de1
Packit Service 084de1
    l ^= p[0];
Packit Service 084de1
    BF_ENC(r, l, s, p[1]);
Packit Service 084de1
    BF_ENC(l, r, s, p[2]);
Packit Service 084de1
    BF_ENC(r, l, s, p[3]);
Packit Service 084de1
    BF_ENC(l, r, s, p[4]);
Packit Service 084de1
    BF_ENC(r, l, s, p[5]);
Packit Service 084de1
    BF_ENC(l, r, s, p[6]);
Packit Service 084de1
    BF_ENC(r, l, s, p[7]);
Packit Service 084de1
    BF_ENC(l, r, s, p[8]);
Packit Service 084de1
    BF_ENC(r, l, s, p[9]);
Packit Service 084de1
    BF_ENC(l, r, s, p[10]);
Packit Service 084de1
    BF_ENC(r, l, s, p[11]);
Packit Service 084de1
    BF_ENC(l, r, s, p[12]);
Packit Service 084de1
    BF_ENC(r, l, s, p[13]);
Packit Service 084de1
    BF_ENC(l, r, s, p[14]);
Packit Service 084de1
    BF_ENC(r, l, s, p[15]);
Packit Service 084de1
    BF_ENC(l, r, s, p[16]);
Packit Service 084de1
# if BF_ROUNDS == 20
Packit Service 084de1
    BF_ENC(r, l, s, p[17]);
Packit Service 084de1
    BF_ENC(l, r, s, p[18]);
Packit Service 084de1
    BF_ENC(r, l, s, p[19]);
Packit Service 084de1
    BF_ENC(l, r, s, p[20]);
Packit Service 084de1
# endif
Packit Service 084de1
    r ^= p[BF_ROUNDS + 1];
Packit Service 084de1
Packit Service 084de1
    data[1] = l & 0xffffffffU;
Packit Service 084de1
    data[0] = r & 0xffffffffU;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
void BF_decrypt(BF_LONG *data, const BF_KEY *key)
Packit Service 084de1
{
Packit Service 084de1
    register BF_LONG l, r;
Packit Service 084de1
    register const BF_LONG *p, *s;
Packit Service 084de1
Packit Service 084de1
    p = key->P;
Packit Service 084de1
    s = &(key->S[0]);
Packit Service 084de1
    l = data[0];
Packit Service 084de1
    r = data[1];
Packit Service 084de1
Packit Service 084de1
    l ^= p[BF_ROUNDS + 1];
Packit Service 084de1
#  if BF_ROUNDS == 20
Packit Service 084de1
    BF_ENC(r, l, s, p[20]);
Packit Service 084de1
    BF_ENC(l, r, s, p[19]);
Packit Service 084de1
    BF_ENC(r, l, s, p[18]);
Packit Service 084de1
    BF_ENC(l, r, s, p[17]);
Packit Service 084de1
#  endif
Packit Service 084de1
    BF_ENC(r, l, s, p[16]);
Packit Service 084de1
    BF_ENC(l, r, s, p[15]);
Packit Service 084de1
    BF_ENC(r, l, s, p[14]);
Packit Service 084de1
    BF_ENC(l, r, s, p[13]);
Packit Service 084de1
    BF_ENC(r, l, s, p[12]);
Packit Service 084de1
    BF_ENC(l, r, s, p[11]);
Packit Service 084de1
    BF_ENC(r, l, s, p[10]);
Packit Service 084de1
    BF_ENC(l, r, s, p[9]);
Packit Service 084de1
    BF_ENC(r, l, s, p[8]);
Packit Service 084de1
    BF_ENC(l, r, s, p[7]);
Packit Service 084de1
    BF_ENC(r, l, s, p[6]);
Packit Service 084de1
    BF_ENC(l, r, s, p[5]);
Packit Service 084de1
    BF_ENC(r, l, s, p[4]);
Packit Service 084de1
    BF_ENC(l, r, s, p[3]);
Packit Service 084de1
    BF_ENC(r, l, s, p[2]);
Packit Service 084de1
    BF_ENC(l, r, s, p[1]);
Packit Service 084de1
    r ^= p[0];
Packit Service 084de1
Packit Service 084de1
    data[1] = l & 0xffffffffU;
Packit Service 084de1
    data[0] = r & 0xffffffffU;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
Packit Service 084de1
                    const BF_KEY *schedule, unsigned char *ivec, int encrypt)
Packit Service 084de1
{
Packit Service 084de1
    register BF_LONG tin0, tin1;
Packit Service 084de1
    register BF_LONG tout0, tout1, xor0, xor1;
Packit Service 084de1
    register long l = length;
Packit Service 084de1
    BF_LONG tin[2];
Packit Service 084de1
Packit Service 084de1
    if (encrypt) {
Packit Service 084de1
        n2l(ivec, tout0);
Packit Service 084de1
        n2l(ivec, tout1);
Packit Service 084de1
        ivec -= 8;
Packit Service 084de1
        for (l -= 8; l >= 0; l -= 8) {
Packit Service 084de1
            n2l(in, tin0);
Packit Service 084de1
            n2l(in, tin1);
Packit Service 084de1
            tin0 ^= tout0;
Packit Service 084de1
            tin1 ^= tout1;
Packit Service 084de1
            tin[0] = tin0;
Packit Service 084de1
            tin[1] = tin1;
Packit Service 084de1
            BF_encrypt(tin, schedule);
Packit Service 084de1
            tout0 = tin[0];
Packit Service 084de1
            tout1 = tin[1];
Packit Service 084de1
            l2n(tout0, out);
Packit Service 084de1
            l2n(tout1, out);
Packit Service 084de1
        }
Packit Service 084de1
        if (l != -8) {
Packit Service 084de1
            n2ln(in, tin0, tin1, l + 8);
Packit Service 084de1
            tin0 ^= tout0;
Packit Service 084de1
            tin1 ^= tout1;
Packit Service 084de1
            tin[0] = tin0;
Packit Service 084de1
            tin[1] = tin1;
Packit Service 084de1
            BF_encrypt(tin, schedule);
Packit Service 084de1
            tout0 = tin[0];
Packit Service 084de1
            tout1 = tin[1];
Packit Service 084de1
            l2n(tout0, out);
Packit Service 084de1
            l2n(tout1, out);
Packit Service 084de1
        }
Packit Service 084de1
        l2n(tout0, ivec);
Packit Service 084de1
        l2n(tout1, ivec);
Packit Service 084de1
    } else {
Packit Service 084de1
        n2l(ivec, xor0);
Packit Service 084de1
        n2l(ivec, xor1);
Packit Service 084de1
        ivec -= 8;
Packit Service 084de1
        for (l -= 8; l >= 0; l -= 8) {
Packit Service 084de1
            n2l(in, tin0);
Packit Service 084de1
            n2l(in, tin1);
Packit Service 084de1
            tin[0] = tin0;
Packit Service 084de1
            tin[1] = tin1;
Packit Service 084de1
            BF_decrypt(tin, schedule);
Packit Service 084de1
            tout0 = tin[0] ^ xor0;
Packit Service 084de1
            tout1 = tin[1] ^ xor1;
Packit Service 084de1
            l2n(tout0, out);
Packit Service 084de1
            l2n(tout1, out);
Packit Service 084de1
            xor0 = tin0;
Packit Service 084de1
            xor1 = tin1;
Packit Service 084de1
        }
Packit Service 084de1
        if (l != -8) {
Packit Service 084de1
            n2l(in, tin0);
Packit Service 084de1
            n2l(in, tin1);
Packit Service 084de1
            tin[0] = tin0;
Packit Service 084de1
            tin[1] = tin1;
Packit Service 084de1
            BF_decrypt(tin, schedule);
Packit Service 084de1
            tout0 = tin[0] ^ xor0;
Packit Service 084de1
            tout1 = tin[1] ^ xor1;
Packit Service 084de1
            l2nn(tout0, tout1, out, l + 8);
Packit Service 084de1
            xor0 = tin0;
Packit Service 084de1
            xor1 = tin1;
Packit Service 084de1
        }
Packit Service 084de1
        l2n(xor0, ivec);
Packit Service 084de1
        l2n(xor1, ivec);
Packit Service 084de1
    }
Packit Service 084de1
    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
Packit Service 084de1
    tin[0] = tin[1] = 0;
Packit Service 084de1
}