/*
 * QEMU Crypto af_alg-backend cipher support
 *
 * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
 *
 * Authors:
 *    Longpeng(Mike) <longpeng2@huawei.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * (at your option) any later version.  See the COPYING file in the
 * top-level directory.
 */
#include "qemu/osdep.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "crypto/cipher.h"
#include "cipherpriv.h"


static char *
qcrypto_afalg_cipher_format_name(QCryptoCipherAlgo alg,
                                 QCryptoCipherMode mode,
                                 Error **errp)
{
    char *name;
    const char *alg_name;
    const char *mode_name;

    switch (alg) {
    case QCRYPTO_CIPHER_ALGO_AES_128:
    case QCRYPTO_CIPHER_ALGO_AES_192:
    case QCRYPTO_CIPHER_ALGO_AES_256:
        alg_name = "aes";
        break;
    case QCRYPTO_CIPHER_ALGO_CAST5_128:
        alg_name = "cast5";
        break;
    case QCRYPTO_CIPHER_ALGO_SERPENT_128:
    case QCRYPTO_CIPHER_ALGO_SERPENT_192:
    case QCRYPTO_CIPHER_ALGO_SERPENT_256:
        alg_name = "serpent";
        break;
    case QCRYPTO_CIPHER_ALGO_TWOFISH_128:
    case QCRYPTO_CIPHER_ALGO_TWOFISH_192:
    case QCRYPTO_CIPHER_ALGO_TWOFISH_256:
        alg_name = "twofish";
        break;

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

    mode_name = QCryptoCipherMode_str(mode);
    name = g_strdup_printf("%s(%s)", mode_name, alg_name);

    return name;
}

static const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver;

QCryptoCipher *
qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgo alg,
                             QCryptoCipherMode mode,
                             const uint8_t *key,
                             size_t nkey, Error **errp)
{
    QCryptoAFAlgo *afalg;
    size_t expect_niv;
    char *name;

    name = qcrypto_afalg_cipher_format_name(alg, mode, errp);
    if (!name) {
        return NULL;
    }

    afalg = qcrypto_afalg_comm_alloc(AFALG_TYPE_CIPHER, name, errp);
    if (!afalg) {
        g_free(name);
        return NULL;
    }

    g_free(name);

    /* setkey */
    if (setsockopt(afalg->tfmfd, SOL_ALG, ALG_SET_KEY, key,
                   nkey) != 0) {
        error_setg_errno(errp, errno, "Set key failed");
        qcrypto_afalg_comm_free(afalg);
        return NULL;
    }

    /* prepare msg header */
    afalg->msg = g_new0(struct msghdr, 1);
    afalg->msg->msg_controllen += CMSG_SPACE(ALG_OPTYPE_LEN);
    expect_niv = qcrypto_cipher_get_iv_len(alg, mode);
    if (expect_niv) {
        afalg->msg->msg_controllen += CMSG_SPACE(ALG_MSGIV_LEN(expect_niv));
    }
    afalg->msg->msg_control = g_new0(uint8_t, afalg->msg->msg_controllen);

    /* We use 1st msghdr for crypto-info and 2nd msghdr for IV-info */
    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
    afalg->cmsg->cmsg_type = ALG_SET_OP;
    afalg->cmsg->cmsg_len = CMSG_SPACE(ALG_OPTYPE_LEN);
    if (expect_niv) {
        afalg->cmsg = CMSG_NXTHDR(afalg->msg, afalg->cmsg);
        afalg->cmsg->cmsg_type = ALG_SET_IV;
        afalg->cmsg->cmsg_len = CMSG_SPACE(ALG_MSGIV_LEN(expect_niv));
    }
    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);

    afalg->base.driver = &qcrypto_cipher_afalg_driver;
    return &afalg->base;
}

static int
qcrypto_afalg_cipher_setiv(QCryptoCipher *cipher,
                           const uint8_t *iv,
                           size_t niv, Error **errp)
{
    QCryptoAFAlgo *afalg = container_of(cipher, QCryptoAFAlgo, base);
    struct af_alg_iv *alg_iv;
    size_t expect_niv;

    expect_niv = qcrypto_cipher_get_iv_len(cipher->alg, cipher->mode);
    if (niv != expect_niv) {
        error_setg(errp, "Set IV len(%zu) not match expected(%zu)",
                   niv, expect_niv);
        return -1;
    }

    /* move ->cmsg to next msghdr, for IV-info */
    afalg->cmsg = CMSG_NXTHDR(afalg->msg, afalg->cmsg);

    /* build setiv msg */
    afalg->cmsg->cmsg_level = SOL_ALG;
    alg_iv = (struct af_alg_iv *)CMSG_DATA(afalg->cmsg);
    alg_iv->ivlen = niv;
    memcpy(alg_iv->iv, iv, niv);

    return 0;
}

static int
qcrypto_afalg_cipher_op(QCryptoAFAlgo *afalg,
                        const void *in, void *out,
                        size_t len, bool do_encrypt,
                        Error **errp)
{
    uint32_t *type = NULL;
    struct iovec iov;
    size_t ret, rlen, done = 0;
    uint32_t origin_controllen;

    origin_controllen = afalg->msg->msg_controllen;
    /* movev ->cmsg to first header, for crypto-info */
    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);

    /* build encrypt msg */
    afalg->cmsg->cmsg_level = SOL_ALG;
    afalg->msg->msg_iov = &iov;
    afalg->msg->msg_iovlen = 1;
    type = (uint32_t *)CMSG_DATA(afalg->cmsg);
    if (do_encrypt) {
        *type = ALG_OP_ENCRYPT;
    } else {
        *type = ALG_OP_DECRYPT;
    }

    do {
        iov.iov_base = (void *)in + done;
        iov.iov_len = len - done;

        /* send info to AF_ALG core */
        ret = sendmsg(afalg->opfd, afalg->msg, 0);
        if (ret == -1) {
            error_setg_errno(errp, errno, "Send data to AF_ALG core failed");
            return -1;
        }

        /* encrypto && get result */
        rlen = read(afalg->opfd, out, ret);
        if (rlen == -1) {
            error_setg_errno(errp, errno, "Get result from AF_ALG core failed");
            return -1;
        }
        assert(rlen == ret);

        /* do not update IV for following chunks */
        afalg->msg->msg_controllen = 0;
        done += ret;
    } while (done < len);

    afalg->msg->msg_controllen = origin_controllen;

    return 0;
}

static int
qcrypto_afalg_cipher_encrypt(QCryptoCipher *cipher,
                             const void *in, void *out,
                             size_t len, Error **errp)
{
    QCryptoAFAlgo *afalg = container_of(cipher, QCryptoAFAlgo, base);

    return qcrypto_afalg_cipher_op(afalg, in, out, len, true, errp);
}

static int
qcrypto_afalg_cipher_decrypt(QCryptoCipher *cipher,
                             const void *in, void *out,
                             size_t len, Error **errp)
{
    QCryptoAFAlgo *afalg = container_of(cipher, QCryptoAFAlgo, base);

    return qcrypto_afalg_cipher_op(afalg, in, out, len, false, errp);
}

static void qcrypto_afalg_comm_ctx_free(QCryptoCipher *cipher)
{
    QCryptoAFAlgo *afalg = container_of(cipher, QCryptoAFAlgo, base);

    qcrypto_afalg_comm_free(afalg);
}

static const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver = {
    .cipher_encrypt = qcrypto_afalg_cipher_encrypt,
    .cipher_decrypt = qcrypto_afalg_cipher_decrypt,
    .cipher_setiv = qcrypto_afalg_cipher_setiv,
    .cipher_free = qcrypto_afalg_comm_ctx_free,
};
