/* * Copyright 2019-2021 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 #include #include #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 propery 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 } };