/*
 * QEMU Crypto cipher libgcrypt 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/xts.h"
#include "cipherpriv.h"

#include <gcrypt.h>


bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
                             QCryptoCipherMode mode)
{
    switch (alg) {
    case QCRYPTO_CIPHER_ALG_DES_RFB:
    case QCRYPTO_CIPHER_ALG_3DES:
    case QCRYPTO_CIPHER_ALG_AES_128:
    case QCRYPTO_CIPHER_ALG_AES_192:
    case QCRYPTO_CIPHER_ALG_AES_256:
    case QCRYPTO_CIPHER_ALG_CAST5_128:
    case QCRYPTO_CIPHER_ALG_SERPENT_128:
    case QCRYPTO_CIPHER_ALG_SERPENT_192:
    case QCRYPTO_CIPHER_ALG_SERPENT_256:
    case QCRYPTO_CIPHER_ALG_TWOFISH_128:
    case QCRYPTO_CIPHER_ALG_TWOFISH_256:
        break;
    default:
        return false;
    }

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

typedef struct QCryptoCipherGcrypt QCryptoCipherGcrypt;
struct QCryptoCipherGcrypt {
    gcry_cipher_hd_t handle;
    gcry_cipher_hd_t tweakhandle;
    size_t blocksize;
    /* Initialization vector or Counter */
    uint8_t *iv;
};

static void
qcrypto_gcrypt_cipher_free_ctx(QCryptoCipherGcrypt *ctx,
                               QCryptoCipherMode mode)
{
    if (!ctx) {
        return;
    }

    gcry_cipher_close(ctx->handle);
    if (mode == QCRYPTO_CIPHER_MODE_XTS) {
        gcry_cipher_close(ctx->tweakhandle);
    }
    g_free(ctx->iv);
    g_free(ctx);
}


static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
                                                   QCryptoCipherMode mode,
                                                   const uint8_t *key,
                                                   size_t nkey,
                                                   Error **errp)
{
    QCryptoCipherGcrypt *ctx;
    gcry_error_t err;
    int gcryalg, gcrymode;

    switch (mode) {
    case QCRYPTO_CIPHER_MODE_ECB:
    case QCRYPTO_CIPHER_MODE_XTS:
        gcrymode = GCRY_CIPHER_MODE_ECB;
        break;
    case QCRYPTO_CIPHER_MODE_CBC:
        gcrymode = GCRY_CIPHER_MODE_CBC;
        break;
    case QCRYPTO_CIPHER_MODE_CTR:
        gcrymode = GCRY_CIPHER_MODE_CTR;
        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:
        gcryalg = GCRY_CIPHER_DES;
        break;

    case QCRYPTO_CIPHER_ALG_3DES:
        gcryalg = GCRY_CIPHER_3DES;
        break;

    case QCRYPTO_CIPHER_ALG_AES_128:
        gcryalg = GCRY_CIPHER_AES128;
        break;

    case QCRYPTO_CIPHER_ALG_AES_192:
        gcryalg = GCRY_CIPHER_AES192;
        break;

    case QCRYPTO_CIPHER_ALG_AES_256:
        gcryalg = GCRY_CIPHER_AES256;
        break;

    case QCRYPTO_CIPHER_ALG_CAST5_128:
        gcryalg = GCRY_CIPHER_CAST5;
        break;

    case QCRYPTO_CIPHER_ALG_SERPENT_128:
        gcryalg = GCRY_CIPHER_SERPENT128;
        break;

    case QCRYPTO_CIPHER_ALG_SERPENT_192:
        gcryalg = GCRY_CIPHER_SERPENT192;
        break;

    case QCRYPTO_CIPHER_ALG_SERPENT_256:
        gcryalg = GCRY_CIPHER_SERPENT256;
        break;

    case QCRYPTO_CIPHER_ALG_TWOFISH_128:
        gcryalg = GCRY_CIPHER_TWOFISH128;
        break;

    case QCRYPTO_CIPHER_ALG_TWOFISH_256:
        gcryalg = GCRY_CIPHER_TWOFISH;
        break;

    default:
        error_setg(errp, "Unsupported cipher algorithm %s",
                   QCryptoCipherAlgorithm_str(alg));
        return NULL;
    }

    ctx = g_new0(QCryptoCipherGcrypt, 1);

    err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0);
    if (err != 0) {
        error_setg(errp, "Cannot initialize cipher: %s",
                   gcry_strerror(err));
        goto error;
    }
    if (mode == QCRYPTO_CIPHER_MODE_XTS) {
        err = gcry_cipher_open(&ctx->tweakhandle, gcryalg, gcrymode, 0);
        if (err != 0) {
            error_setg(errp, "Cannot initialize cipher: %s",
                       gcry_strerror(err));
            goto error;
        }
    }

    if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) {
        /* We're using standard DES cipher from gcrypt, so we need
         * to munge the key so that the results are the same as the
         * bizarre RFB variant of DES :-)
         */
        uint8_t *rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
        err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
        g_free(rfbkey);
        ctx->blocksize = 8;
    } else {
        if (mode == QCRYPTO_CIPHER_MODE_XTS) {
            nkey /= 2;
            err = gcry_cipher_setkey(ctx->handle, key, nkey);
            if (err != 0) {
                error_setg(errp, "Cannot set key: %s",
                           gcry_strerror(err));
                goto error;
            }
            err = gcry_cipher_setkey(ctx->tweakhandle, key + nkey, nkey);
        } else {
            err = gcry_cipher_setkey(ctx->handle, key, nkey);
        }
        if (err != 0) {
            error_setg(errp, "Cannot set key: %s",
                       gcry_strerror(err));
            goto error;
        }
        switch (alg) {
        case QCRYPTO_CIPHER_ALG_AES_128:
        case QCRYPTO_CIPHER_ALG_AES_192:
        case QCRYPTO_CIPHER_ALG_AES_256:
        case QCRYPTO_CIPHER_ALG_SERPENT_128:
        case QCRYPTO_CIPHER_ALG_SERPENT_192:
        case QCRYPTO_CIPHER_ALG_SERPENT_256:
        case QCRYPTO_CIPHER_ALG_TWOFISH_128:
        case QCRYPTO_CIPHER_ALG_TWOFISH_256:
            ctx->blocksize = 16;
            break;
        case QCRYPTO_CIPHER_ALG_3DES:
        case QCRYPTO_CIPHER_ALG_CAST5_128:
            ctx->blocksize = 8;
            break;
        default:
            g_assert_not_reached();
        }
    }

    if (mode == QCRYPTO_CIPHER_MODE_XTS) {
        if (ctx->blocksize != XTS_BLOCK_SIZE) {
            error_setg(errp,
                       "Cipher block size %zu must equal XTS block size %d",
                       ctx->blocksize, XTS_BLOCK_SIZE);
            goto error;
        }
        ctx->iv = g_new0(uint8_t, ctx->blocksize);
    }

    return ctx;

 error:
    qcrypto_gcrypt_cipher_free_ctx(ctx, mode);
    return NULL;
}


static void
qcrypto_gcrypt_cipher_ctx_free(QCryptoCipher *cipher)
{
    qcrypto_gcrypt_cipher_free_ctx(cipher->opaque, cipher->mode);
}


static void qcrypto_gcrypt_xts_encrypt(const void *ctx,
                                       size_t length,
                                       uint8_t *dst,
                                       const uint8_t *src)
{
    gcry_error_t err;
    err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length);
    g_assert(err == 0);
}

static void qcrypto_gcrypt_xts_decrypt(const void *ctx,
                                       size_t length,
                                       uint8_t *dst,
                                       const uint8_t *src)
{
    gcry_error_t err;
    err = gcry_cipher_decrypt((gcry_cipher_hd_t)ctx, dst, length, src, length);
    g_assert(err == 0);
}

static int
qcrypto_gcrypt_cipher_encrypt(QCryptoCipher *cipher,
                              const void *in,
                              void *out,
                              size_t len,
                              Error **errp)
{
    QCryptoCipherGcrypt *ctx = cipher->opaque;
    gcry_error_t err;

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

    if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
        xts_encrypt(ctx->handle, ctx->tweakhandle,
                    qcrypto_gcrypt_xts_encrypt,
                    qcrypto_gcrypt_xts_decrypt,
                    ctx->iv, len, out, in);
    } else {
        err = gcry_cipher_encrypt(ctx->handle,
                                  out, len,
                                  in, len);
        if (err != 0) {
            error_setg(errp, "Cannot encrypt data: %s",
                       gcry_strerror(err));
            return -1;
        }
    }

    return 0;
}


static int
qcrypto_gcrypt_cipher_decrypt(QCryptoCipher *cipher,
                              const void *in,
                              void *out,
                              size_t len,
                              Error **errp)
{
    QCryptoCipherGcrypt *ctx = cipher->opaque;
    gcry_error_t err;

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

    if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
        xts_decrypt(ctx->handle, ctx->tweakhandle,
                    qcrypto_gcrypt_xts_encrypt,
                    qcrypto_gcrypt_xts_decrypt,
                    ctx->iv, len, out, in);
    } else {
        err = gcry_cipher_decrypt(ctx->handle,
                                  out, len,
                                  in, len);
        if (err != 0) {
            error_setg(errp, "Cannot decrypt data: %s",
                       gcry_strerror(err));
            return -1;
        }
    }

    return 0;
}

static int
qcrypto_gcrypt_cipher_setiv(QCryptoCipher *cipher,
                            const uint8_t *iv, size_t niv,
                            Error **errp)
{
    QCryptoCipherGcrypt *ctx = cipher->opaque;
    gcry_error_t err;

    if (niv != ctx->blocksize) {
        error_setg(errp, "Expected IV size %zu not %zu",
                   ctx->blocksize, niv);
        return -1;
    }

    if (ctx->iv) {
        memcpy(ctx->iv, iv, niv);
    } else {
        if (cipher->mode == QCRYPTO_CIPHER_MODE_CTR) {
            err = gcry_cipher_setctr(ctx->handle, iv, niv);
            if (err != 0) {
                error_setg(errp, "Cannot set Counter: %s",
                       gcry_strerror(err));
                return -1;
            }
        } else {
            gcry_cipher_reset(ctx->handle);
            err = gcry_cipher_setiv(ctx->handle, iv, niv);
            if (err != 0) {
                error_setg(errp, "Cannot set IV: %s",
                       gcry_strerror(err));
                return -1;
            }
        }
    }

    return 0;
}


static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
    .cipher_encrypt = qcrypto_gcrypt_cipher_encrypt,
    .cipher_decrypt = qcrypto_gcrypt_cipher_decrypt,
    .cipher_setiv = qcrypto_gcrypt_cipher_setiv,
    .cipher_free = qcrypto_gcrypt_cipher_ctx_free,
};
