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