diff options
Diffstat (limited to 'providers/implementations/keymgmt/kdf_legacy_kmgmt.c')
-rw-r--r-- | providers/implementations/keymgmt/kdf_legacy_kmgmt.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/providers/implementations/keymgmt/kdf_legacy_kmgmt.c b/providers/implementations/keymgmt/kdf_legacy_kmgmt.c new file mode 100644 index 000000000000..0b301c333b09 --- /dev/null +++ b/providers/implementations/keymgmt/kdf_legacy_kmgmt.c @@ -0,0 +1,104 @@ +/* + * 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 <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 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 } +}; |