/*
 * Copyright 2019-2022 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
 */

/*
 * This implemments a dummy key manager for legacy KDFs that still support the
 * old way of performing a KDF via EVP_PKEY_derive(). New KDFs should not be
 * implemented this way. In reality there is no key data for such KDFs, so this
 * key manager does very little.
 */

#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "prov/kdfexchange.h"

static OSSL_FUNC_keymgmt_new_fn kdf_newdata;
static OSSL_FUNC_keymgmt_free_fn kdf_freedata;
static OSSL_FUNC_keymgmt_has_fn kdf_has;

KDF_DATA *ossl_kdf_data_new(void *provctx)
{
    KDF_DATA *kdfdata;

    if (!ossl_prov_is_running())
        return NULL;

    kdfdata = OPENSSL_zalloc(sizeof(*kdfdata));
    if (kdfdata == NULL)
        return NULL;

    kdfdata->lock = CRYPTO_THREAD_lock_new();
    if (kdfdata->lock == NULL) {
        OPENSSL_free(kdfdata);
        return NULL;
    }
    kdfdata->libctx = PROV_LIBCTX_OF(provctx);
    kdfdata->refcnt = 1;

    return kdfdata;
}

void ossl_kdf_data_free(KDF_DATA *kdfdata)
{
    int ref = 0;

    if (kdfdata == NULL)
        return;

    CRYPTO_DOWN_REF(&kdfdata->refcnt, &ref, kdfdata->lock);
    if (ref > 0)
        return;

    CRYPTO_THREAD_lock_free(kdfdata->lock);
    OPENSSL_free(kdfdata);
}

int ossl_kdf_data_up_ref(KDF_DATA *kdfdata)
{
    int ref = 0;

    /* This is effectively doing a new operation on the KDF_DATA and should be
     * adequately guarded again modules' error states.  However, both current
     * calls here are guarded properly in exchange/kdf_exch.c.  Thus, it
     * could be removed here.  The concern is that something in the future
     * might call this function without adequate guards.  It's a cheap call,
     * it seems best to leave it even though it is currently redundant.
     */
    if (!ossl_prov_is_running())
        return 0;

    CRYPTO_UP_REF(&kdfdata->refcnt, &ref, kdfdata->lock);
    return 1;
}

static void *kdf_newdata(void *provctx)
{
    return ossl_kdf_data_new(provctx);
}

static void kdf_freedata(void *kdfdata)
{
    ossl_kdf_data_free(kdfdata);
}

static int kdf_has(const void *keydata, int selection)
{
    return 1; /* nothing is missing */
}

const OSSL_DISPATCH ossl_kdf_keymgmt_functions[] = {
    { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))kdf_newdata },
    { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))kdf_freedata },
    { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))kdf_has },
    { 0, NULL }
};
