/*
 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (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 "prov/ciphercommon.h"

/*-
 * The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
 * Used if there is no special hardware implementations.
 */
int cipher_hw_generic_cbc(PROV_CIPHER_CTX *dat, unsigned char *out,
                          const unsigned char *in, size_t len)
{
    if (dat->stream.cbc)
        (*dat->stream.cbc) (in, out, len, dat->ks, dat->iv, dat->enc);
    else if (dat->enc)
        CRYPTO_cbc128_encrypt(in, out, len, dat->ks, dat->iv, dat->block);
    else
        CRYPTO_cbc128_decrypt(in, out, len, dat->ks, dat->iv, dat->block);

    return 1;
}

int cipher_hw_generic_ecb(PROV_CIPHER_CTX *dat, unsigned char *out,
                          const unsigned char *in, size_t len)
{
    size_t i, bl = dat->blocksize;

    if (len < bl)
        return 1;

    if (dat->stream.ecb) {
        (*dat->stream.ecb) (in, out, len, dat->ks, dat->enc);
    }
    else {
        for (i = 0, len -= bl; i <= len; i += bl)
            (*dat->block) (in + i, out + i, dat->ks);
    }

    return 1;
}

int cipher_hw_generic_ofb128(PROV_CIPHER_CTX *dat, unsigned char *out,
                             const unsigned char *in, size_t len)
{
    int num = dat->num;

    CRYPTO_ofb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->block);
    dat->num = num;

    return 1;
}

int cipher_hw_generic_cfb128(PROV_CIPHER_CTX *dat, unsigned char *out,
                             const unsigned char *in, size_t len)
{
    int num = dat->num;

    CRYPTO_cfb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc,
                          dat->block);
    dat->num = num;

    return 1;
}

int cipher_hw_generic_cfb8(PROV_CIPHER_CTX *dat, unsigned char *out,
                           const unsigned char *in, size_t len)
{
    int num = dat->num;

    CRYPTO_cfb128_8_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc,
                            dat->block);
    dat->num = num;

    return 1;
}

int cipher_hw_generic_cfb1(PROV_CIPHER_CTX *dat, unsigned char *out,
                           const unsigned char *in, size_t len)
{
    int num = dat->num;

    if ((dat->flags & EVP_CIPH_FLAG_LENGTH_BITS) != 0) {
        CRYPTO_cfb128_1_encrypt(in, out, len, dat->ks, dat->iv, &num,
                                dat->enc, dat->block);
        dat->num = num;
        return 1;
    }

    while (len >= MAXBITCHUNK) {
        CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, dat->ks,
                                dat->iv, &num, dat->enc, dat->block);
        len -= MAXBITCHUNK;
        out += MAXBITCHUNK;
        in  += MAXBITCHUNK;
    }
    if (len)
        CRYPTO_cfb128_1_encrypt(in, out, len * 8, dat->ks, dat->iv, &num,
                                dat->enc, dat->block);

    dat->num = num;

    return 1;
}

int cipher_hw_generic_ctr(PROV_CIPHER_CTX *dat, unsigned char *out,
                          const unsigned char *in, size_t len)
{
    unsigned int num = dat->num;

    if (dat->stream.ctr)
        CRYPTO_ctr128_encrypt_ctr32(in, out, len, dat->ks, dat->iv, dat->buf,
                                    &num, dat->stream.ctr);
    else
        CRYPTO_ctr128_encrypt(in, out, len, dat->ks, dat->iv, dat->buf,
                              &num, dat->block);
    dat->num = num;

    return 1;
}

/*-
 * The chunked cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
 * Used if there is no special hardware implementations.
 */

int cipher_hw_chunked_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
                          const unsigned char *in, size_t inl)
{
    while (inl >= MAXCHUNK) {
        cipher_hw_generic_cbc(ctx, out, in, MAXCHUNK);
        inl -= MAXCHUNK;
        in  += MAXCHUNK;
        out += MAXCHUNK;
    }
    if (inl > 0)
        cipher_hw_generic_cbc(ctx, out, in, inl);
    return 1;
}

int cipher_hw_chunked_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out,
                           const unsigned char *in, size_t inl)
{
    size_t chunk = MAXCHUNK;

    if (inl < chunk)
        chunk = inl;
    while (inl > 0 && inl >= chunk) {
        cipher_hw_generic_cfb8(ctx, out, in, inl);
        inl -= chunk;
        in += chunk;
        out += chunk;
        if (inl < chunk)
            chunk = inl;
    }
    return 1;
}

int cipher_hw_chunked_cfb128(PROV_CIPHER_CTX *ctx, unsigned char *out,
                             const unsigned char *in, size_t inl)
{
    size_t chunk = MAXCHUNK;

    if (inl < chunk)
        chunk = inl;
    while (inl > 0 && inl >= chunk) {
        cipher_hw_generic_cfb128(ctx, out, in, inl);
        inl -= chunk;
        in += chunk;
        out += chunk;
        if (inl < chunk)
            chunk = inl;
    }
    return 1;
}

int cipher_hw_chunked_ofb128(PROV_CIPHER_CTX *ctx, unsigned char *out,
                             const unsigned char *in, size_t inl)
{
    while (inl >= MAXCHUNK) {
        cipher_hw_generic_ofb128(ctx, out, in, MAXCHUNK);
        inl -= MAXCHUNK;
        in  += MAXCHUNK;
        out += MAXCHUNK;
    }
    if (inl > 0)
        cipher_hw_generic_ofb128(ctx, out, in, inl);
    return 1;
}
