/*
 * QEMU Crypto cipher built-in algorithms
 *
 * Copyright (c) 2015 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "crypto/aes.h"
#include "crypto/desrfb.h"
#include "crypto/xts.h"
#include "cipherpriv.h"

typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext;
struct QCryptoCipherBuiltinAESContext {
    AES_KEY enc;
    AES_KEY dec;
};
typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
struct QCryptoCipherBuiltinAES {
    QCryptoCipherBuiltinAESContext key;
    QCryptoCipherBuiltinAESContext key_tweak;
    uint8_t iv[AES_BLOCK_SIZE];
};
typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
struct QCryptoCipherBuiltinDESRFB {
    uint8_t *key;
    size_t nkey;
};

typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin;
struct QCryptoCipherBuiltin {
    union {
        QCryptoCipherBuiltinAES aes;
        QCryptoCipherBuiltinDESRFB desrfb;
    } state;
    size_t blocksize;
    void (*free)(QCryptoCipher *cipher);
    int (*setiv)(QCryptoCipher *cipher,
                 const uint8_t *iv, size_t niv,
                 Error **errp);
    int (*encrypt)(QCryptoCipher *cipher,
                   const void *in,
                   void *out,
                   size_t len,
                   Error **errp);
    int (*decrypt)(QCryptoCipher *cipher,
                   const void *in,
                   void *out,
                   size_t len,
                   Error **errp);
};


static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;

    g_free(ctxt);
    cipher->opaque = NULL;
}


static void qcrypto_cipher_aes_ecb_encrypt(AES_KEY *key,
                                           const void *in,
                                           void *out,
                                           size_t len)
{
    const uint8_t *inptr = in;
    uint8_t *outptr = out;
    while (len) {
        if (len > AES_BLOCK_SIZE) {
            AES_encrypt(inptr, outptr, key);
            inptr += AES_BLOCK_SIZE;
            outptr += AES_BLOCK_SIZE;
            len -= AES_BLOCK_SIZE;
        } else {
            uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
            memcpy(tmp1, inptr, len);
            /* Fill with 0 to avoid valgrind uninitialized reads */
            memset(tmp1 + len, 0, sizeof(tmp1) - len);
            AES_encrypt(tmp1, tmp2, key);
            memcpy(outptr, tmp2, len);
            len = 0;
        }
    }
}


static void qcrypto_cipher_aes_ecb_decrypt(AES_KEY *key,
                                           const void *in,
                                           void *out,
                                           size_t len)
{
    const uint8_t *inptr = in;
    uint8_t *outptr = out;
    while (len) {
        if (len > AES_BLOCK_SIZE) {
            AES_decrypt(inptr, outptr, key);
            inptr += AES_BLOCK_SIZE;
            outptr += AES_BLOCK_SIZE;
            len -= AES_BLOCK_SIZE;
        } else {
            uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
            memcpy(tmp1, inptr, len);
            /* Fill with 0 to avoid valgrind uninitialized reads */
            memset(tmp1 + len, 0, sizeof(tmp1) - len);
            AES_decrypt(tmp1, tmp2, key);
            memcpy(outptr, tmp2, len);
            len = 0;
        }
    }
}


static void qcrypto_cipher_aes_xts_encrypt(const void *ctx,
                                           size_t length,
                                           uint8_t *dst,
                                           const uint8_t *src)
{
    const QCryptoCipherBuiltinAESContext *aesctx = ctx;

    qcrypto_cipher_aes_ecb_encrypt((AES_KEY *)&aesctx->enc,
                                   src, dst, length);
}


static void qcrypto_cipher_aes_xts_decrypt(const void *ctx,
                                           size_t length,
                                           uint8_t *dst,
                                           const uint8_t *src)
{
    const QCryptoCipherBuiltinAESContext *aesctx = ctx;

    qcrypto_cipher_aes_ecb_decrypt((AES_KEY *)&aesctx->dec,
                                   src, dst, length);
}


static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
                                      const void *in,
                                      void *out,
                                      size_t len,
                                      Error **errp)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;

    switch (cipher->mode) {
    case QCRYPTO_CIPHER_MODE_ECB:
        qcrypto_cipher_aes_ecb_encrypt(&ctxt->state.aes.key.enc,
                                       in, out, len);
        break;
    case QCRYPTO_CIPHER_MODE_CBC:
        AES_cbc_encrypt(in, out, len,
                        &ctxt->state.aes.key.enc,
                        ctxt->state.aes.iv, 1);
        break;
    case QCRYPTO_CIPHER_MODE_XTS:
        xts_encrypt(&ctxt->state.aes.key,
                    &ctxt->state.aes.key_tweak,
                    qcrypto_cipher_aes_xts_encrypt,
                    qcrypto_cipher_aes_xts_decrypt,
                    ctxt->state.aes.iv,
                    len, out, in);
        break;
    default:
        g_assert_not_reached();
    }

    return 0;
}


static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
                                      const void *in,
                                      void *out,
                                      size_t len,
                                      Error **errp)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;

    switch (cipher->mode) {
    case QCRYPTO_CIPHER_MODE_ECB:
        qcrypto_cipher_aes_ecb_decrypt(&ctxt->state.aes.key.dec,
                                       in, out, len);
        break;
    case QCRYPTO_CIPHER_MODE_CBC:
        AES_cbc_encrypt(in, out, len,
                        &ctxt->state.aes.key.dec,
                        ctxt->state.aes.iv, 0);
        break;
    case QCRYPTO_CIPHER_MODE_XTS:
        xts_decrypt(&ctxt->state.aes.key,
                    &ctxt->state.aes.key_tweak,
                    qcrypto_cipher_aes_xts_encrypt,
                    qcrypto_cipher_aes_xts_decrypt,
                    ctxt->state.aes.iv,
                    len, out, in);
        break;
    default:
        g_assert_not_reached();
    }

    return 0;
}

static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
                                     const uint8_t *iv, size_t niv,
                                     Error **errp)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;
    if (niv != AES_BLOCK_SIZE) {
        error_setg(errp, "IV must be %d bytes not %zu",
                   AES_BLOCK_SIZE, niv);
        return -1;
    }

    memcpy(ctxt->state.aes.iv, iv, AES_BLOCK_SIZE);

    return 0;
}




static QCryptoCipherBuiltin *
qcrypto_cipher_init_aes(QCryptoCipherMode mode,
                        const uint8_t *key, size_t nkey,
                        Error **errp)
{
    QCryptoCipherBuiltin *ctxt;

    if (mode != QCRYPTO_CIPHER_MODE_CBC &&
        mode != QCRYPTO_CIPHER_MODE_ECB &&
        mode != QCRYPTO_CIPHER_MODE_XTS) {
        error_setg(errp, "Unsupported cipher mode %s",
                   QCryptoCipherMode_str(mode));
        return NULL;
    }

    ctxt = g_new0(QCryptoCipherBuiltin, 1);

    if (mode == QCRYPTO_CIPHER_MODE_XTS) {
        if (AES_set_encrypt_key(key, nkey * 4, &ctxt->state.aes.key.enc) != 0) {
            error_setg(errp, "Failed to set encryption key");
            goto error;
        }

        if (AES_set_decrypt_key(key, nkey * 4, &ctxt->state.aes.key.dec) != 0) {
            error_setg(errp, "Failed to set decryption key");
            goto error;
        }

        if (AES_set_encrypt_key(key + (nkey / 2), nkey * 4,
                                &ctxt->state.aes.key_tweak.enc) != 0) {
            error_setg(errp, "Failed to set encryption key");
            goto error;
        }

        if (AES_set_decrypt_key(key + (nkey / 2), nkey * 4,
                                &ctxt->state.aes.key_tweak.dec) != 0) {
            error_setg(errp, "Failed to set decryption key");
            goto error;
        }
    } else {
        if (AES_set_encrypt_key(key, nkey * 8, &ctxt->state.aes.key.enc) != 0) {
            error_setg(errp, "Failed to set encryption key");
            goto error;
        }

        if (AES_set_decrypt_key(key, nkey * 8, &ctxt->state.aes.key.dec) != 0) {
            error_setg(errp, "Failed to set decryption key");
            goto error;
        }
    }

    ctxt->blocksize = AES_BLOCK_SIZE;
    ctxt->free = qcrypto_cipher_free_aes;
    ctxt->setiv = qcrypto_cipher_setiv_aes;
    ctxt->encrypt = qcrypto_cipher_encrypt_aes;
    ctxt->decrypt = qcrypto_cipher_decrypt_aes;

    return ctxt;

 error:
    g_free(ctxt);
    return NULL;
}


static void qcrypto_cipher_free_des_rfb(QCryptoCipher *cipher)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;

    g_free(ctxt->state.desrfb.key);
    g_free(ctxt);
    cipher->opaque = NULL;
}


static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
                                          const void *in,
                                          void *out,
                                          size_t len,
                                          Error **errp)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;
    size_t i;

    if (len % 8) {
        error_setg(errp, "Buffer size must be multiple of 8 not %zu",
                   len);
        return -1;
    }

    deskey(ctxt->state.desrfb.key, EN0);

    for (i = 0; i < len; i += 8) {
        des((void *)in + i, out + i);
    }

    return 0;
}


static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
                                          const void *in,
                                          void *out,
                                          size_t len,
                                          Error **errp)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;
    size_t i;

    if (len % 8) {
        error_setg(errp, "Buffer size must be multiple of 8 not %zu",
                   len);
        return -1;
    }

    deskey(ctxt->state.desrfb.key, DE1);

    for (i = 0; i < len; i += 8) {
        des((void *)in + i, out + i);
    }

    return 0;
}


static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher,
                                        const uint8_t *iv, size_t niv,
                                        Error **errp)
{
    error_setg(errp, "Setting IV is not supported");
    return -1;
}


static QCryptoCipherBuiltin *
qcrypto_cipher_init_des_rfb(QCryptoCipherMode mode,
                            const uint8_t *key, size_t nkey,
                            Error **errp)
{
    QCryptoCipherBuiltin *ctxt;

    if (mode != QCRYPTO_CIPHER_MODE_ECB) {
        error_setg(errp, "Unsupported cipher mode %s",
                   QCryptoCipherMode_str(mode));
        return NULL;
    }

    ctxt = g_new0(QCryptoCipherBuiltin, 1);

    ctxt->state.desrfb.key = g_new0(uint8_t, nkey);
    memcpy(ctxt->state.desrfb.key, key, nkey);
    ctxt->state.desrfb.nkey = nkey;

    ctxt->blocksize = 8;
    ctxt->free = qcrypto_cipher_free_des_rfb;
    ctxt->setiv = qcrypto_cipher_setiv_des_rfb;
    ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
    ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;

    return ctxt;
}


bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
                             QCryptoCipherMode mode)
{
    switch (alg) {
    case QCRYPTO_CIPHER_ALG_DES_RFB:
    case QCRYPTO_CIPHER_ALG_AES_128:
    case QCRYPTO_CIPHER_ALG_AES_192:
    case QCRYPTO_CIPHER_ALG_AES_256:
        break;
    default:
        return false;
    }

    switch (mode) {
    case QCRYPTO_CIPHER_MODE_ECB:
    case QCRYPTO_CIPHER_MODE_CBC:
    case QCRYPTO_CIPHER_MODE_XTS:
        return true;
    case QCRYPTO_CIPHER_MODE_CTR:
        return false;
    default:
        return false;
    }
}


static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
                                                    QCryptoCipherMode mode,
                                                    const uint8_t *key,
                                                    size_t nkey,
                                                    Error **errp)
{
    QCryptoCipherBuiltin *ctxt;

    switch (mode) {
    case QCRYPTO_CIPHER_MODE_ECB:
    case QCRYPTO_CIPHER_MODE_CBC:
    case QCRYPTO_CIPHER_MODE_XTS:
        break;
    default:
        error_setg(errp, "Unsupported cipher mode %s",
                   QCryptoCipherMode_str(mode));
        return NULL;
    }

    if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
        return NULL;
    }

    switch (alg) {
    case QCRYPTO_CIPHER_ALG_DES_RFB:
        ctxt = qcrypto_cipher_init_des_rfb(mode, key, nkey, errp);
        break;
    case QCRYPTO_CIPHER_ALG_AES_128:
    case QCRYPTO_CIPHER_ALG_AES_192:
    case QCRYPTO_CIPHER_ALG_AES_256:
        ctxt = qcrypto_cipher_init_aes(mode, key, nkey, errp);
        break;
    default:
        error_setg(errp,
                   "Unsupported cipher algorithm %s",
                   QCryptoCipherAlgorithm_str(alg));
        return NULL;
    }

    return ctxt;
}

static void
qcrypto_builtin_cipher_ctx_free(QCryptoCipher *cipher)
{
    QCryptoCipherBuiltin *ctxt;

    ctxt = cipher->opaque;
    ctxt->free(cipher);
}


static int
qcrypto_builtin_cipher_encrypt(QCryptoCipher *cipher,
                               const void *in,
                               void *out,
                               size_t len,
                               Error **errp)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;

    if (len % ctxt->blocksize) {
        error_setg(errp, "Length %zu must be a multiple of block size %zu",
                   len, ctxt->blocksize);
        return -1;
    }

    return ctxt->encrypt(cipher, in, out, len, errp);
}


static int
qcrypto_builtin_cipher_decrypt(QCryptoCipher *cipher,
                               const void *in,
                               void *out,
                               size_t len,
                               Error **errp)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;

    if (len % ctxt->blocksize) {
        error_setg(errp, "Length %zu must be a multiple of block size %zu",
                   len, ctxt->blocksize);
        return -1;
    }

    return ctxt->decrypt(cipher, in, out, len, errp);
}


static int
qcrypto_builtin_cipher_setiv(QCryptoCipher *cipher,
                             const uint8_t *iv, size_t niv,
                             Error **errp)
{
    QCryptoCipherBuiltin *ctxt = cipher->opaque;

    return ctxt->setiv(cipher, iv, niv, errp);
}


static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
    .cipher_encrypt = qcrypto_builtin_cipher_encrypt,
    .cipher_decrypt = qcrypto_builtin_cipher_decrypt,
    .cipher_setiv = qcrypto_builtin_cipher_setiv,
    .cipher_free = qcrypto_builtin_cipher_ctx_free,
};
