diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index 0c643b3b49fc6f57b81a5a782cfe0acb60ecd4fb..0112036263c7e6b7e2175205baf0cdebea2acf2f 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -101,15 +101,22 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) if (pk->keymgmt == keymgmt) return pk->keydata; - /* If this key is already exported to |keymgmt|, no more to do */ CRYPTO_THREAD_read_lock(pk->lock); - i = evp_keymgmt_util_find_operation_cache_index(pk, keymgmt); - if (i < OSSL_NELEM(pk->operation_cache) - && pk->operation_cache[i].keymgmt != NULL) { - void *ret = pk->operation_cache[i].keydata; + /* + * If the provider native "origin" hasn't changed since last time, we + * try to find our keymgmt in the operation cache. If it has changed, + * |i| remains zero, and we will clear the cache further down. + */ + if (pk->dirty_cnt == pk->dirty_cnt_copy) { + /* If this key is already exported to |keymgmt|, no more to do */ + i = evp_keymgmt_util_find_operation_cache_index(pk, keymgmt); + if (i < OSSL_NELEM(pk->operation_cache) + && pk->operation_cache[i].keymgmt != NULL) { + void *ret = pk->operation_cache[i].keydata; - CRYPTO_THREAD_unlock(pk->lock); - return ret; + CRYPTO_THREAD_unlock(pk->lock); + return ret; + } } CRYPTO_THREAD_unlock(pk->lock); @@ -177,12 +184,22 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) return ret; } + /* + * If the dirty counter changed since last time, then clear the + * operation cache. In that case, we know that |i| is zero. + */ + if (pk->dirty_cnt != pk->dirty_cnt_copy) + evp_keymgmt_util_clear_operation_cache(pk, 0); + /* Add the new export to the operation cache */ if (!evp_keymgmt_util_cache_keydata(pk, i, keymgmt, import_data.keydata)) { evp_keymgmt_freedata(keymgmt, import_data.keydata); return NULL; } + /* Synchronize the dirty count */ + pk->dirty_cnt_copy = pk->dirty_cnt; + CRYPTO_THREAD_unlock(pk->lock); return import_data.keydata; diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 558f3781689649ed75d97e6cb4ebf6bab3d0d8f1..b97a8d16fa2833a482ff7ff3acfb9449f6068e41 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -2228,11 +2228,12 @@ const OSSL_PARAM *EVP_PKEY_settable_params(EVP_PKEY *pkey) int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[]) { - if (pkey == NULL - || pkey->keymgmt == NULL - || pkey->keydata == NULL) + if (pkey == NULL) return 0; - return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params); + + pkey->dirty_cnt++; + return evp_pkey_is_provided(pkey) + && evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params); } #ifndef FIPS_MODULE