1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * This implemments a dummy key manager for legacy KDFs that still support the 12e1051a39Sopenharmony_ci * old way of performing a KDF via EVP_PKEY_derive(). New KDFs should not be 13e1051a39Sopenharmony_ci * implemented this way. In reality there is no key data for such KDFs, so this 14e1051a39Sopenharmony_ci * key manager does very little. 15e1051a39Sopenharmony_ci */ 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 18e1051a39Sopenharmony_ci#include <openssl/core_names.h> 19e1051a39Sopenharmony_ci#include <openssl/err.h> 20e1051a39Sopenharmony_ci#include "prov/implementations.h" 21e1051a39Sopenharmony_ci#include "prov/providercommon.h" 22e1051a39Sopenharmony_ci#include "prov/provider_ctx.h" 23e1051a39Sopenharmony_ci#include "prov/kdfexchange.h" 24e1051a39Sopenharmony_ci 25e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_new_fn kdf_newdata; 26e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_free_fn kdf_freedata; 27e1051a39Sopenharmony_cistatic OSSL_FUNC_keymgmt_has_fn kdf_has; 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_ciKDF_DATA *ossl_kdf_data_new(void *provctx) 30e1051a39Sopenharmony_ci{ 31e1051a39Sopenharmony_ci KDF_DATA *kdfdata; 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 34e1051a39Sopenharmony_ci return NULL; 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ci kdfdata = OPENSSL_zalloc(sizeof(*kdfdata)); 37e1051a39Sopenharmony_ci if (kdfdata == NULL) 38e1051a39Sopenharmony_ci return NULL; 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci kdfdata->lock = CRYPTO_THREAD_lock_new(); 41e1051a39Sopenharmony_ci if (kdfdata->lock == NULL) { 42e1051a39Sopenharmony_ci OPENSSL_free(kdfdata); 43e1051a39Sopenharmony_ci return NULL; 44e1051a39Sopenharmony_ci } 45e1051a39Sopenharmony_ci kdfdata->libctx = PROV_LIBCTX_OF(provctx); 46e1051a39Sopenharmony_ci kdfdata->refcnt = 1; 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_ci return kdfdata; 49e1051a39Sopenharmony_ci} 50e1051a39Sopenharmony_ci 51e1051a39Sopenharmony_civoid ossl_kdf_data_free(KDF_DATA *kdfdata) 52e1051a39Sopenharmony_ci{ 53e1051a39Sopenharmony_ci int ref = 0; 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ci if (kdfdata == NULL) 56e1051a39Sopenharmony_ci return; 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ci CRYPTO_DOWN_REF(&kdfdata->refcnt, &ref, kdfdata->lock); 59e1051a39Sopenharmony_ci if (ref > 0) 60e1051a39Sopenharmony_ci return; 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(kdfdata->lock); 63e1051a39Sopenharmony_ci OPENSSL_free(kdfdata); 64e1051a39Sopenharmony_ci} 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_ciint ossl_kdf_data_up_ref(KDF_DATA *kdfdata) 67e1051a39Sopenharmony_ci{ 68e1051a39Sopenharmony_ci int ref = 0; 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci /* This is effectively doing a new operation on the KDF_DATA and should be 71e1051a39Sopenharmony_ci * adequately guarded again modules' error states. However, both current 72e1051a39Sopenharmony_ci * calls here are guarded propery in exchange/kdf_exch.c. Thus, it 73e1051a39Sopenharmony_ci * could be removed here. The concern is that something in the future 74e1051a39Sopenharmony_ci * might call this function without adequate guards. It's a cheap call, 75e1051a39Sopenharmony_ci * it seems best to leave it even though it is currently redundant. 76e1051a39Sopenharmony_ci */ 77e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 78e1051a39Sopenharmony_ci return 0; 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ci CRYPTO_UP_REF(&kdfdata->refcnt, &ref, kdfdata->lock); 81e1051a39Sopenharmony_ci return 1; 82e1051a39Sopenharmony_ci} 83e1051a39Sopenharmony_ci 84e1051a39Sopenharmony_cistatic void *kdf_newdata(void *provctx) 85e1051a39Sopenharmony_ci{ 86e1051a39Sopenharmony_ci return ossl_kdf_data_new(provctx); 87e1051a39Sopenharmony_ci} 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_cistatic void kdf_freedata(void *kdfdata) 90e1051a39Sopenharmony_ci{ 91e1051a39Sopenharmony_ci ossl_kdf_data_free(kdfdata); 92e1051a39Sopenharmony_ci} 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_cistatic int kdf_has(const void *keydata, int selection) 95e1051a39Sopenharmony_ci{ 96e1051a39Sopenharmony_ci return 1; /* nothing is missing */ 97e1051a39Sopenharmony_ci} 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_kdf_keymgmt_functions[] = { 100e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))kdf_newdata }, 101e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))kdf_freedata }, 102e1051a39Sopenharmony_ci { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))kdf_has }, 103e1051a39Sopenharmony_ci { 0, NULL } 104e1051a39Sopenharmony_ci}; 105