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#include <string.h>
11e1051a39Sopenharmony_ci#include <openssl/err.h>
12e1051a39Sopenharmony_ci#include <openssl/cryptoerr.h>
13e1051a39Sopenharmony_ci#include <openssl/provider.h>
14e1051a39Sopenharmony_ci#include <openssl/core_names.h>
15e1051a39Sopenharmony_ci#include "internal/provider.h"
16e1051a39Sopenharmony_ci#include "provider_local.h"
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ciOSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name,
19e1051a39Sopenharmony_ci                                      int retain_fallbacks)
20e1051a39Sopenharmony_ci{
21e1051a39Sopenharmony_ci    OSSL_PROVIDER *prov = NULL, *actual;
22e1051a39Sopenharmony_ci    int isnew = 0;
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ci    /* Find it or create it */
25e1051a39Sopenharmony_ci    if ((prov = ossl_provider_find(libctx, name, 0)) == NULL) {
26e1051a39Sopenharmony_ci        if ((prov = ossl_provider_new(libctx, name, NULL, 0)) == NULL)
27e1051a39Sopenharmony_ci            return NULL;
28e1051a39Sopenharmony_ci        isnew = 1;
29e1051a39Sopenharmony_ci    }
30e1051a39Sopenharmony_ci
31e1051a39Sopenharmony_ci    if (!ossl_provider_activate(prov, 1, 0)) {
32e1051a39Sopenharmony_ci        ossl_provider_free(prov);
33e1051a39Sopenharmony_ci        return NULL;
34e1051a39Sopenharmony_ci    }
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_ci    actual = prov;
37e1051a39Sopenharmony_ci    if (isnew && !ossl_provider_add_to_store(prov, &actual, retain_fallbacks)) {
38e1051a39Sopenharmony_ci        ossl_provider_deactivate(prov, 1);
39e1051a39Sopenharmony_ci        ossl_provider_free(prov);
40e1051a39Sopenharmony_ci        return NULL;
41e1051a39Sopenharmony_ci    }
42e1051a39Sopenharmony_ci    if (actual != prov) {
43e1051a39Sopenharmony_ci        if (!ossl_provider_activate(actual, 1, 0)) {
44e1051a39Sopenharmony_ci            ossl_provider_free(actual);
45e1051a39Sopenharmony_ci            return NULL;
46e1051a39Sopenharmony_ci        }
47e1051a39Sopenharmony_ci    }
48e1051a39Sopenharmony_ci
49e1051a39Sopenharmony_ci    return actual;
50e1051a39Sopenharmony_ci}
51e1051a39Sopenharmony_ci
52e1051a39Sopenharmony_ciOSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name)
53e1051a39Sopenharmony_ci{
54e1051a39Sopenharmony_ci    /* Any attempt to load a provider disables auto-loading of defaults */
55e1051a39Sopenharmony_ci    if (ossl_provider_disable_fallback_loading(libctx))
56e1051a39Sopenharmony_ci        return OSSL_PROVIDER_try_load(libctx, name, 0);
57e1051a39Sopenharmony_ci    return NULL;
58e1051a39Sopenharmony_ci}
59e1051a39Sopenharmony_ci
60e1051a39Sopenharmony_ciint OSSL_PROVIDER_unload(OSSL_PROVIDER *prov)
61e1051a39Sopenharmony_ci{
62e1051a39Sopenharmony_ci    if (!ossl_provider_deactivate(prov, 1))
63e1051a39Sopenharmony_ci        return 0;
64e1051a39Sopenharmony_ci    ossl_provider_free(prov);
65e1051a39Sopenharmony_ci    return 1;
66e1051a39Sopenharmony_ci}
67e1051a39Sopenharmony_ci
68e1051a39Sopenharmony_ciconst OSSL_PARAM *OSSL_PROVIDER_gettable_params(const OSSL_PROVIDER *prov)
69e1051a39Sopenharmony_ci{
70e1051a39Sopenharmony_ci    return ossl_provider_gettable_params(prov);
71e1051a39Sopenharmony_ci}
72e1051a39Sopenharmony_ci
73e1051a39Sopenharmony_ciint OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
74e1051a39Sopenharmony_ci{
75e1051a39Sopenharmony_ci    return ossl_provider_get_params(prov, params);
76e1051a39Sopenharmony_ci}
77e1051a39Sopenharmony_ci
78e1051a39Sopenharmony_ciconst OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov,
79e1051a39Sopenharmony_ci                                                    int operation_id,
80e1051a39Sopenharmony_ci                                                    int *no_cache)
81e1051a39Sopenharmony_ci{
82e1051a39Sopenharmony_ci    return ossl_provider_query_operation(prov, operation_id, no_cache);
83e1051a39Sopenharmony_ci}
84e1051a39Sopenharmony_ci
85e1051a39Sopenharmony_civoid OSSL_PROVIDER_unquery_operation(const OSSL_PROVIDER *prov,
86e1051a39Sopenharmony_ci                                     int operation_id,
87e1051a39Sopenharmony_ci                                     const OSSL_ALGORITHM *algs)
88e1051a39Sopenharmony_ci{
89e1051a39Sopenharmony_ci    ossl_provider_unquery_operation(prov, operation_id, algs);
90e1051a39Sopenharmony_ci}
91e1051a39Sopenharmony_ci
92e1051a39Sopenharmony_civoid *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov)
93e1051a39Sopenharmony_ci{
94e1051a39Sopenharmony_ci    return ossl_provider_prov_ctx(prov);
95e1051a39Sopenharmony_ci}
96e1051a39Sopenharmony_ci
97e1051a39Sopenharmony_ciconst OSSL_DISPATCH *OSSL_PROVIDER_get0_dispatch(const OSSL_PROVIDER *prov)
98e1051a39Sopenharmony_ci{
99e1051a39Sopenharmony_ci    return ossl_provider_get0_dispatch(prov);
100e1051a39Sopenharmony_ci}
101e1051a39Sopenharmony_ci
102e1051a39Sopenharmony_ciint OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov)
103e1051a39Sopenharmony_ci{
104e1051a39Sopenharmony_ci    return ossl_provider_self_test(prov);
105e1051a39Sopenharmony_ci}
106e1051a39Sopenharmony_ci
107e1051a39Sopenharmony_ciint OSSL_PROVIDER_get_capabilities(const OSSL_PROVIDER *prov,
108e1051a39Sopenharmony_ci                                   const char *capability,
109e1051a39Sopenharmony_ci                                   OSSL_CALLBACK *cb,
110e1051a39Sopenharmony_ci                                   void *arg)
111e1051a39Sopenharmony_ci{
112e1051a39Sopenharmony_ci    return ossl_provider_get_capabilities(prov, capability, cb, arg);
113e1051a39Sopenharmony_ci}
114e1051a39Sopenharmony_ci
115e1051a39Sopenharmony_ciint OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *libctx, const char *name,
116e1051a39Sopenharmony_ci                              OSSL_provider_init_fn *init_fn)
117e1051a39Sopenharmony_ci{
118e1051a39Sopenharmony_ci    OSSL_PROVIDER_INFO entry;
119e1051a39Sopenharmony_ci
120e1051a39Sopenharmony_ci    if (name == NULL || init_fn == NULL) {
121e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
122e1051a39Sopenharmony_ci        return 0;
123e1051a39Sopenharmony_ci    }
124e1051a39Sopenharmony_ci    memset(&entry, 0, sizeof(entry));
125e1051a39Sopenharmony_ci    entry.name = OPENSSL_strdup(name);
126e1051a39Sopenharmony_ci    if (entry.name == NULL) {
127e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
128e1051a39Sopenharmony_ci        return 0;
129e1051a39Sopenharmony_ci    }
130e1051a39Sopenharmony_ci    entry.init = init_fn;
131e1051a39Sopenharmony_ci    if (!ossl_provider_info_add_to_store(libctx, &entry)) {
132e1051a39Sopenharmony_ci        ossl_provider_info_clear(&entry);
133e1051a39Sopenharmony_ci        return 0;
134e1051a39Sopenharmony_ci    }
135e1051a39Sopenharmony_ci    return 1;
136e1051a39Sopenharmony_ci}
137e1051a39Sopenharmony_ci
138e1051a39Sopenharmony_ciconst char *OSSL_PROVIDER_get0_name(const OSSL_PROVIDER *prov)
139e1051a39Sopenharmony_ci{
140e1051a39Sopenharmony_ci    return ossl_provider_name(prov);
141e1051a39Sopenharmony_ci}
142e1051a39Sopenharmony_ci
143e1051a39Sopenharmony_ciint OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx,
144e1051a39Sopenharmony_ci                         int (*cb)(OSSL_PROVIDER *provider,
145e1051a39Sopenharmony_ci                                   void *cbdata),
146e1051a39Sopenharmony_ci                         void *cbdata)
147e1051a39Sopenharmony_ci{
148e1051a39Sopenharmony_ci    return ossl_provider_doall_activated(ctx, cb, cbdata);
149e1051a39Sopenharmony_ci}
150