/*
 * Copyright 2001-2021 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
 */

/*
 * IBM S390X support for AES modes ecb, cbc, ofb, cfb, ctr.
 * This file is included by cipher_aes_hw.c
 */

#include "s390x_arch.h"

#include <stdio.h>

#define s390x_aes_cbc_initkey    cipher_hw_aes_initkey
#define s390x_aes_cfb1_initkey   cipher_hw_aes_initkey
#define s390x_aes_ctr_initkey    cipher_hw_aes_initkey
#define s390x_aes_cbc_cipher_hw  ossl_cipher_hw_generic_cbc
#define s390x_aes_cfb1_cipher_hw ossl_cipher_hw_generic_cfb1
#define s390x_aes_ctr_cipher_hw  ossl_cipher_hw_generic_ctr

#define S390X_aes_128_ofb128_CAPABLE S390X_aes_128_ofb_CAPABLE
#define S390X_aes_192_ofb128_CAPABLE S390X_aes_192_ofb_CAPABLE
#define S390X_aes_256_ofb128_CAPABLE S390X_aes_256_ofb_CAPABLE
#define S390X_aes_128_cfb128_CAPABLE S390X_aes_128_cfb_CAPABLE
#define S390X_aes_192_cfb128_CAPABLE S390X_aes_192_cfb_CAPABLE
#define S390X_aes_256_cfb128_CAPABLE S390X_aes_256_cfb_CAPABLE

static int s390x_aes_ecb_initkey(PROV_CIPHER_CTX *dat,
                                 const unsigned char *key, size_t keylen)
{
    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;

    adat->plat.s390x.fc = S390X_AES_FC(keylen);
    memcpy(adat->plat.s390x.param.km.k, key, keylen);
    return 1;
}

static int s390x_aes_ecb_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
                                   const unsigned char *in, size_t len)
{
    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
    unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT;

    s390x_km(in, len, out, adat->plat.s390x.fc | modifier,
             &adat->plat.s390x.param.km);
    return 1;
}

static int s390x_aes_ofb128_initkey(PROV_CIPHER_CTX *dat,
                                    const unsigned char *key, size_t keylen)
{
    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;

    memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
    adat->plat.s390x.fc = S390X_AES_FC(keylen);
    adat->plat.s390x.res = 0;
    return 1;
}

static int s390x_aes_ofb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
                                      const unsigned char *in, size_t len)
{
    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
    int n = adat->plat.s390x.res;
    int rem;

    memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
    while (n && len) {
        *out = *in ^ adat->plat.s390x.param.kmo_kmf.cv[n];
        n = (n + 1) & 0xf;
        --len;
        ++in;
        ++out;
    }

    rem = len & 0xf;

    len &= ~(size_t)0xf;
    if (len) {
        s390x_kmo(in, len, out, adat->plat.s390x.fc,
                  &adat->plat.s390x.param.kmo_kmf);

        out += len;
        in += len;
    }

    if (rem) {
        s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16,
                 adat->plat.s390x.param.kmo_kmf.cv,
                 adat->plat.s390x.fc,
                 adat->plat.s390x.param.kmo_kmf.k);

        while (rem--) {
            out[n] = in[n] ^ adat->plat.s390x.param.kmo_kmf.cv[n];
            ++n;
        }
    }

    memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
    adat->plat.s390x.res = n;
    return 1;
}

static int s390x_aes_cfb128_initkey(PROV_CIPHER_CTX *dat,
                                    const unsigned char *key, size_t keylen)
{
    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;

    adat->plat.s390x.fc = S390X_AES_FC(keylen);
    adat->plat.s390x.fc |= 16 << 24;   /* 16 bytes cipher feedback */
    adat->plat.s390x.res = 0;
    memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
    return 1;
}

static int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
                                      const unsigned char *in, size_t len)
{
    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
    unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT;
    int n = adat->plat.s390x.res;
    int rem;
    unsigned char tmp;

    memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
    while (n && len) {
        tmp = *in;
        *out = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
        adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp;
        n = (n + 1) & 0xf;
        --len;
        ++in;
        ++out;
    }

    rem = len & 0xf;

    len &= ~(size_t)0xf;
    if (len) {
        s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier,
                  &adat->plat.s390x.param.kmo_kmf);

        out += len;
        in += len;
    }

    if (rem) {
        s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16,
                 adat->plat.s390x.param.kmo_kmf.cv,
                 S390X_AES_FC(dat->keylen),
                 adat->plat.s390x.param.kmo_kmf.k);

        while (rem--) {
            tmp = in[n];
            out[n] = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
            adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? out[n] : tmp;
            ++n;
        }
    }

    memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
    adat->plat.s390x.res = n;
    return 1;
}

static int s390x_aes_cfb8_initkey(PROV_CIPHER_CTX *dat,
                                  const unsigned char *key, size_t keylen)
{
    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;

    adat->plat.s390x.fc = S390X_AES_FC(keylen);
    adat->plat.s390x.fc |= 1 << 24;   /* 1 byte cipher feedback */
    memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
    return 1;
}

static int s390x_aes_cfb8_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
                                    const unsigned char *in, size_t len)
{
    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
    unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT;

    memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
    s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier,
              &adat->plat.s390x.param.kmo_kmf);
    memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
    return 1;
}

#define PROV_CIPHER_HW_declare(mode)                                           \
static const PROV_CIPHER_HW s390x_aes_##mode = {                               \
    s390x_aes_##mode##_initkey,                                                \
    s390x_aes_##mode##_cipher_hw,                                              \
    cipher_hw_aes_copyctx                                                      \
};
#define PROV_CIPHER_HW_select(mode)                                            \
if ((keybits == 128 && S390X_aes_128_##mode##_CAPABLE)                         \
     || (keybits == 192 && S390X_aes_192_##mode##_CAPABLE)                     \
     || (keybits == 256 && S390X_aes_256_##mode##_CAPABLE))                    \
    return &s390x_aes_##mode;

