/*
 * Copyright 2020 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 <string.h>
#include <openssl/crypto.h>
#include <openssl/core_dispatch.h>
#include "prov/implementations.h"
#include "prov/ciphercommon.h"
#include "prov/providercommonerr.h"

typedef struct prov_cipher_null_ctx_st {
    int enc;
    size_t tlsmacsize;
    const unsigned char *tlsmac;
} PROV_CIPHER_NULL_CTX;

static OSSL_FUNC_cipher_newctx_fn null_newctx;
static void *null_newctx(void *provctx)
{
    return OPENSSL_zalloc(sizeof(PROV_CIPHER_NULL_CTX));
}

static OSSL_FUNC_cipher_freectx_fn null_freectx;
static void null_freectx(void *vctx)
{
    OPENSSL_free(vctx);
}

static OSSL_FUNC_cipher_encrypt_init_fn null_einit;
static int null_einit(void *vctx, const unsigned char *key, size_t keylen,
                      const unsigned char *iv, size_t ivlen)
{
    PROV_CIPHER_NULL_CTX *ctx = (PROV_CIPHER_NULL_CTX *)vctx;

    ctx->enc = 1;
    return 1;
}

static OSSL_FUNC_cipher_decrypt_init_fn null_dinit;
static int null_dinit(void *vctx, const unsigned char *key, size_t keylen,
                      const unsigned char *iv, size_t ivlen)
{
    return 1;
}

static OSSL_FUNC_cipher_cipher_fn null_cipher;
static int null_cipher(void *vctx, unsigned char *out, size_t *outl,
                       size_t outsize, const unsigned char *in, size_t inl)
{
    PROV_CIPHER_NULL_CTX *ctx = (PROV_CIPHER_NULL_CTX *)vctx;

    if (!ctx->enc && ctx->tlsmacsize > 0) {
        /*
         * TLS NULL cipher as per:
         * https://tools.ietf.org/html/rfc5246#section-6.2.3.1
         */
        if (inl < ctx->tlsmacsize)
            return 0;
        ctx->tlsmac = in + inl - ctx->tlsmacsize;
        inl -= ctx->tlsmacsize;
    }
    if (outsize < inl)
        return 0;
    if (in != out)
        memcpy(out, in, inl);
    *outl = inl;
    return 1;
}

static OSSL_FUNC_cipher_final_fn null_final;
static int null_final(void *vctx, unsigned char *out, size_t *outl,
                      size_t outsize)
{
    *outl = 0;
    return 1;
}

static OSSL_FUNC_cipher_get_params_fn null_get_params;
static int null_get_params(OSSL_PARAM params[])
{
    return cipher_generic_get_params(params, 0, 0, 0, 8, 0);
}

static const OSSL_PARAM null_known_gettable_ctx_params[] = {
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
    { OSSL_CIPHER_PARAM_TLS_MAC, OSSL_PARAM_OCTET_PTR, NULL, 0, OSSL_PARAM_UNMODIFIED },
    OSSL_PARAM_END
};

static OSSL_FUNC_cipher_gettable_ctx_params_fn null_gettable_ctx_params;
static const OSSL_PARAM *null_gettable_ctx_params(void)
{
    return null_known_gettable_ctx_params;
}

static OSSL_FUNC_cipher_get_ctx_params_fn null_get_ctx_params;
static int null_get_ctx_params(void *vctx, OSSL_PARAM params[])
{
    PROV_CIPHER_NULL_CTX *ctx = (PROV_CIPHER_NULL_CTX *)vctx;
    OSSL_PARAM *p;

    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
    if (p != NULL && !OSSL_PARAM_set_size_t(p, 0)) {
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
        return 0;
    }
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
    if (p != NULL && !OSSL_PARAM_set_size_t(p, 0)) {
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
        return 0;
    }
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS_MAC);
    if (p != NULL
        && !OSSL_PARAM_set_octet_ptr(p, ctx->tlsmac, ctx->tlsmacsize)) {
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
        return 0;
    }
    return 1;
}

static const OSSL_PARAM null_known_settable_ctx_params[] = {
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, NULL),
    OSSL_PARAM_END
};

static OSSL_FUNC_cipher_settable_ctx_params_fn null_settable_ctx_params;
static const OSSL_PARAM *null_settable_ctx_params(void)
{
    return null_known_settable_ctx_params;
}


static OSSL_FUNC_cipher_set_ctx_params_fn null_set_ctx_params;
static int null_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
    PROV_CIPHER_NULL_CTX *ctx = (PROV_CIPHER_NULL_CTX *)vctx;
    const OSSL_PARAM *p;

    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_MAC_SIZE);
    if (p != NULL) {
        if (!OSSL_PARAM_get_size_t(p, &ctx->tlsmacsize)) {
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
            return 0;
        }
    }

    return 1;
}

const OSSL_DISPATCH null_functions[] = {
    { OSSL_FUNC_CIPHER_NEWCTX,
      (void (*)(void)) null_newctx },
    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) null_freectx },
    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) null_newctx },
    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))null_einit },
    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))null_dinit },
    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))null_cipher },
    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))null_final },
    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))null_cipher },
    { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void)) null_get_params },
    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,
        (void (*)(void))cipher_generic_gettable_params },
    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))null_get_ctx_params },
    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,
      (void (*)(void))null_gettable_ctx_params },
    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (void (*)(void))null_set_ctx_params },
    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,
      (void (*)(void))null_settable_ctx_params },
    { 0, NULL }
};
