EVP_KEYEXCH *EVP_KEYEXCH_fetch(OPENSSL_CTX *ctx, const char *algorithm,
                               const char *properties)
{
    EVP_KEYEXCH *keyexch =
        evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties,
                          evp_keyexch_from_dispatch,
                          (int (*)(void *))EVP_KEYEXCH_up_ref,
                          (void (*)(void *))EVP_KEYEXCH_free);
    if (keyexch->keymgmt == NULL) {
        EVP_KEYMGMT *keymgmt = EVP_KEYMGMT_fetch(ctx, algorithm, properties);
        if (keymgmt == NULL
            || (EVP_KEYEXCH_provider(keyexch)
                != EVP_KEYMGMT_provider(keymgmt))) {
            EVP_KEYEXCH_free(keyexch);
            EVP_KEYMGMT_free(keymgmt);
            EVPerr(EVP_F_EVP_KEYEXCH_FETCH, EVP_R_NO_KEYMGMT_PRESENT);
            return NULL;
        }
        keyexch->keymgmt = keymgmt;
    }
    return keyexch;
}
['EVP_KEYEXCH *EVP_KEYEXCH_fetch(OPENSSL_CTX *ctx, const char *algorithm,\n                               const char *properties)\n{\n    EVP_KEYEXCH *keyexch =\n        evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties,\n                          evp_keyexch_from_dispatch,\n                          (int (*)(void *))EVP_KEYEXCH_up_ref,\n                          (void (*)(void *))EVP_KEYEXCH_free);\n    if (keyexch->keymgmt == NULL) {\n        EVP_KEYMGMT *keymgmt = EVP_KEYMGMT_fetch(ctx, algorithm, properties);\n        if (keymgmt == NULL\n            || (EVP_KEYEXCH_provider(keyexch)\n                != EVP_KEYMGMT_provider(keymgmt))) {\n            EVP_KEYEXCH_free(keyexch);\n            EVP_KEYMGMT_free(keymgmt);\n            EVPerr(EVP_F_EVP_KEYEXCH_FETCH, EVP_R_NO_KEYMGMT_PRESENT);\n            return NULL;\n        }\n        keyexch->keymgmt = keymgmt;\n    }\n    return keyexch;\n}', 'void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,\n                        const char *name, const char *properties,\n                        void *(*new_method)(const char *name,\n                                            const OSSL_DISPATCH *fns,\n                                            OSSL_PROVIDER *prov),\n                        int (*up_ref_method)(void *),\n                        void (*free_method)(void *))\n{\n    OSSL_METHOD_STORE *store = get_default_method_store(libctx);\n    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);\n    int nameid = 0;\n    uint32_t methid = 0;\n    void *method = NULL;\n    if (store == NULL || namemap == NULL)\n        return NULL;\n    if (!ossl_assert(operation_id > 0))\n        return NULL;\n    if ((nameid = ossl_namemap_name2num(namemap, name)) != 0\n        && (methid = method_id(operation_id, nameid)) == 0)\n        return NULL;\n    if (nameid == 0\n        || !ossl_method_store_cache_get(store, methid, properties,\n                                        &method)) {\n        OSSL_METHOD_CONSTRUCT_METHOD mcm = {\n            alloc_tmp_method_store,\n            dealloc_tmp_method_store,\n            get_method_from_store,\n            put_method_in_store,\n            construct_method,\n            destruct_method\n        };\n        struct method_data_st mcmdata;\n        mcmdata.mcm = &mcm;\n        mcmdata.libctx = libctx;\n        mcmdata.name = name;\n        mcmdata.method_from_dispatch = new_method;\n        mcmdata.destruct_method = free_method;\n        mcmdata.refcnt_up_method = up_ref_method;\n        mcmdata.destruct_method = free_method;\n        if ((method = ossl_method_construct(libctx, operation_id, name,\n                                            properties, 0  ,\n                                            &mcm, &mcmdata)) != NULL) {\n            nameid = ossl_namemap_name2num(namemap, name);\n            methid = method_id(operation_id, nameid);\n            ossl_method_store_cache_set(store, methid, properties, method);\n        }\n    } else {\n        up_ref_method(method);\n    }\n    return method;\n}', 'static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx)\n{\n    return openssl_ctx_get_data(libctx, OPENSSL_CTX_DEFAULT_METHOD_STORE_INDEX,\n                                &default_method_store_method);\n}', 'void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index,\n                           const OPENSSL_CTX_METHOD *meth)\n{\n    void *data = NULL;\n    int dynidx;\n    ctx = openssl_ctx_get_concrete(ctx);\n    if (ctx == NULL)\n        return NULL;\n    CRYPTO_THREAD_read_lock(ctx->lock);\n    dynidx = ctx->dyn_indexes[index];\n    CRYPTO_THREAD_unlock(ctx->lock);\n    if (dynidx != -1) {\n        CRYPTO_THREAD_read_lock(ctx->index_locks[index]);\n        data = CRYPTO_get_ex_data(&ctx->data, dynidx);\n        CRYPTO_THREAD_unlock(ctx->index_locks[index]);\n        return data;\n    }\n    CRYPTO_THREAD_write_lock(ctx->index_locks[index]);\n    CRYPTO_THREAD_write_lock(ctx->lock);\n    dynidx = ctx->dyn_indexes[index];\n    if (dynidx != -1) {\n        CRYPTO_THREAD_unlock(ctx->lock);\n        data = CRYPTO_get_ex_data(&ctx->data, dynidx);\n        CRYPTO_THREAD_unlock(ctx->index_locks[index]);\n        return data;\n    }\n    if (!openssl_ctx_init_index(ctx, index, meth)) {\n        CRYPTO_THREAD_unlock(ctx->lock);\n        CRYPTO_THREAD_unlock(ctx->index_locks[index]);\n        return NULL;\n    }\n    CRYPTO_THREAD_unlock(ctx->lock);\n    if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,\n                             &ctx->data, ctx->dyn_indexes[index]))\n        data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]);\n    CRYPTO_THREAD_unlock(ctx->index_locks[index]);\n    return data;\n}', 'OPENSSL_CTX *openssl_ctx_get_concrete(OPENSSL_CTX *ctx)\n{\n#ifndef FIPS_MODE\n    if (ctx == NULL) {\n        if (!RUN_ONCE(&default_context_init, do_default_context_init))\n            return 0;\n        return default_context;\n    }\n#endif\n    return ctx;\n}', 'OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx)\n{\n    return openssl_ctx_get_data(libctx, OPENSSL_CTX_NAMEMAP_INDEX,\n                                &stored_namemap_method);\n}']