• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #ifdef HITLS_CRYPTO_PROVIDER
17 
18 #include "securec.h"
19 #include "crypt_provider.h"
20 #include "bsl_list.h"
21 #include "crypt_provider_local.h"
22 #include "crypt_errno.h"
23 #include "crypt_eal_entropy.h"
24 #include "bsl_err_internal.h"
25 #include "eal_entropy.h"
26 #include "crypt_drbg_local.h"
27 #include "crypt_drbg.h"
28 
29 static CRYPT_EAL_LibCtx *g_libCtx = NULL;
30 
CRYPT_EAL_GetGlobalLibCtx(void)31 CRYPT_EAL_LibCtx *CRYPT_EAL_GetGlobalLibCtx(void)
32 {
33     return g_libCtx;
34 }
35 
CRYPT_EAL_ProviderGetFuncs(CRYPT_EAL_LibCtx * libCtx,int32_t operaId,int32_t algId,const char * attribute,const CRYPT_EAL_Func ** funcs,void ** provCtx)36 int32_t CRYPT_EAL_ProviderGetFuncs(CRYPT_EAL_LibCtx *libCtx, int32_t operaId, int32_t algId,
37     const char *attribute, const CRYPT_EAL_Func **funcs, void **provCtx)
38 {
39     CRYPT_EAL_ProvMgrCtx *mgrCtx = NULL;
40     int32_t ret = CRYPT_EAL_ProviderGetFuncsAndMgrCtx(libCtx, operaId, algId, attribute, funcs, &mgrCtx);
41     if (ret != CRYPT_SUCCESS) {
42         BSL_ERR_PUSH_ERROR(ret);
43         return ret;
44     }
45     if (mgrCtx == NULL) {
46         BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_NOT_FOUND);
47         return CRYPT_PROVIDER_NOT_FOUND;
48     }
49     if (provCtx != NULL) {
50         *provCtx = mgrCtx->provCtx;
51     }
52     return CRYPT_SUCCESS;
53 }
54 
CRYPT_EAL_ProviderGetFuncsAndMgrCtx(CRYPT_EAL_LibCtx * libCtx,int32_t operaId,int32_t algId,const char * attribute,const CRYPT_EAL_Func ** funcs,CRYPT_EAL_ProvMgrCtx ** mgrCtx)55 int32_t CRYPT_EAL_ProviderGetFuncsAndMgrCtx(CRYPT_EAL_LibCtx *libCtx, int32_t operaId, int32_t algId,
56     const char *attribute, const CRYPT_EAL_Func **funcs, CRYPT_EAL_ProvMgrCtx **mgrCtx)
57 {
58     if (funcs == NULL || mgrCtx == NULL) {
59         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
60         return CRYPT_NULL_INPUT;
61     }
62     CRYPT_EAL_LibCtx *localCtx = libCtx;
63     if (localCtx == NULL) {
64         localCtx = g_libCtx;
65     }
66 
67     if (localCtx == NULL) {
68         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
69         return CRYPT_NULL_INPUT;
70     }
71     if (attribute != NULL && strlen(attribute) > (INT32_MAX >> 1)) {
72         BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_ERR_ATTRIBUTE);
73         return CRYPT_PROVIDER_ERR_ATTRIBUTE;
74     }
75 
76     return CRYPT_EAL_CompareAlgAndAttr(localCtx, operaId, algId, attribute, funcs, mgrCtx);
77 }
78 
CRYPT_EAL_ProvMgrCtrl(CRYPT_EAL_ProvMgrCtx * ctx,int32_t cmd,void * val,uint32_t valLen)79 int32_t CRYPT_EAL_ProvMgrCtrl(CRYPT_EAL_ProvMgrCtx *ctx, int32_t cmd, void *val, uint32_t valLen)
80 {
81     (void) valLen;
82     if (ctx == NULL || val == NULL) {
83         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
84         return CRYPT_INVALID_ARG;
85     }
86     switch (cmd) {
87         case CRYPT_EAL_MGR_GETSEEDCTX:
88             *(void **) val = ctx->providerSeed.seed;
89             return CRYPT_SUCCESS;
90         case CRYPT_EAL_MGR_GETLIBCTX:
91             *(void **) val = ctx->libCtx;
92             return CRYPT_SUCCESS;
93         default:
94             BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_NOT_FOUND);
95             return CRYPT_PROVIDER_NOT_FOUND;
96     }
97 }
98 
MountMgrMethod(CRYPT_EAL_Func * funcs,CRYPT_EAL_ProvMgrCtx * ctx)99 static void MountMgrMethod(CRYPT_EAL_Func *funcs, CRYPT_EAL_ProvMgrCtx *ctx)
100 {
101     // Mount function addresses to corresponding positions in mgr according to method definition
102     for (uint32_t i = 0; funcs[i].id != 0; i++) {
103         switch (funcs[i].id) {
104             case CRYPT_EAL_PROVCB_FREE:
105                 ctx->provFreeCb = (CRYPT_EAL_ProvFreeCb)funcs[i].func;
106                 break;
107             case CRYPT_EAL_PROVCB_QUERY:
108                 ctx->provQueryCb = (CRYPT_EAL_ProvQueryCb)funcs[i].func;
109                 break;
110             case CRYPT_EAL_PROVCB_CTRL:
111                 ctx->provCtrlCb = (CRYPT_EAL_ProvCtrlCb)funcs[i].func;
112                 break;
113             case CRYPT_EAL_PROVCB_GETCAPS:
114                 ctx->provGetCap = (CRYPT_EAL_ProvGetCapsCb)funcs[i].func;
115                 break;
116             default:
117                 break;
118         }
119     }
120 }
121 
122 #ifdef HITLS_CRYPTO_ENTROPY_DEFAULT
ProviderSeedDeinit(EAL_SeedDrbg * seedDrbg)123 static void ProviderSeedDeinit(EAL_SeedDrbg *seedDrbg)
124 {
125     if (seedDrbg == NULL) {
126         return;
127     }
128     if (seedDrbg->seed != NULL) {
129         EAL_SeedDrbgRandDeinit(seedDrbg->seed);
130         seedDrbg->seed = NULL;
131         CRYPT_EAL_SeedPoolFree(seedDrbg->seedCtx);
132         seedDrbg->seedCtx = NULL;
133         BSL_SAL_ReferencesFree(&(seedDrbg->references));
134         (void)memset_s(seedDrbg, sizeof(EAL_SeedDrbg), 0, sizeof(EAL_SeedDrbg));
135     }
136 }
137 #endif
138 
139 // Function to get provider methods
CRYPT_EAL_InitProviderMethod(CRYPT_EAL_ProvMgrCtx * ctx,BSL_Param * param,CRYPT_EAL_ImplProviderInit providerInit)140 int32_t CRYPT_EAL_InitProviderMethod(CRYPT_EAL_ProvMgrCtx *ctx, BSL_Param *param,
141     CRYPT_EAL_ImplProviderInit providerInit)
142 {
143     int32_t ret;
144 #ifdef HITLS_CRYPTO_ENTROPY_DEFAULT
145     CRYPT_RandSeedMethod meth = {0};
146     // The implementer of provider may not use the default entropy source
147     (void)EAL_SeedDrbgEntropyMeth(&meth);
148     ctx->providerSeed.id = HITLS_SEED_DRBG_INIT_RAND_ALG;
149     ret = EAL_SeedDrbgInit(&(ctx->providerSeed));
150     if (ret != CRYPT_SUCCESS) {
151         BSL_ERR_PUSH_ERROR(ret);
152         return ret;
153     }
154 #endif
155     // Construct input method structure array
156     CRYPT_EAL_Func capFuncs[] = {
157 #ifdef HITLS_CRYPTO_ENTROPY_DEFAULT
158         {CRYPT_EAL_CAP_GETENTROPY, (CRYPT_EAL_GetEntropyCb)meth.getEntropy},
159         {CRYPT_EAL_CAP_CLEANENTROPY, (CRYPT_EAL_CleanEntropyCb)meth.cleanEntropy},
160         {CRYPT_EAL_CAP_GETNONCE, (CRYPT_EAL_GetNonceCb)meth.getNonce},
161         {CRYPT_EAL_CAP_CLEANNONCE, (CRYPT_EAL_CleanNonceCb)meth.cleanNonce},
162 #endif
163         {CRYPT_EAL_CAP_MGRCTXCTRL, (CRYPT_EAL_ProvMgrCtrlCb)CRYPT_EAL_ProvMgrCtrl},
164         CRYPT_EAL_FUNC_END  // End marker
165     };
166 
167     CRYPT_EAL_Func *outFuncs = NULL;
168     // Call CRYPT_EAL_ImplProviderInit to get methods
169     ret = providerInit(ctx, param, capFuncs, &outFuncs, &ctx->provCtx);
170     if (ret != CRYPT_SUCCESS) {
171         BSL_ERR_PUSH_ERROR(ret);
172         goto ERR;
173     }
174     if (outFuncs == NULL) {
175         ret = CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL;
176         BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL);
177         goto ERR;
178     }
179     MountMgrMethod(outFuncs, ctx);
180 
181     if (ctx->provQueryCb == NULL) {
182         if (ctx->provFreeCb != NULL) {
183             ctx->provFreeCb(ctx->provCtx);
184             ctx->provCtx = NULL;
185         }
186         ret = CRYPT_PROVIDER_ERR_IMPL_NULL;
187         BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_ERR_IMPL_NULL);
188         goto ERR;
189     }
190 
191     return CRYPT_SUCCESS;
192 ERR:
193 #ifdef HITLS_CRYPTO_ENTROPY_DEFAULT
194     ProviderSeedDeinit(&(ctx->providerSeed));
195 #endif
196     return ret;
197 }
198 
CRYPT_EAL_LibCtxNewInternal(void)199 CRYPT_EAL_LibCtx *CRYPT_EAL_LibCtxNewInternal(void)
200 {
201     CRYPT_EAL_LibCtx *libCtx = (CRYPT_EAL_LibCtx *)BSL_SAL_Calloc(1, sizeof(CRYPT_EAL_LibCtx));
202     if (libCtx == NULL) {
203         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
204         return NULL;
205     }
206 
207     // Initialize providers list
208     libCtx->providers = BSL_LIST_New(sizeof(struct EAL_ProviderMgrCtx *));
209     if (libCtx->providers == NULL) {
210         goto ERR;
211     }
212 
213     // Initialize thread lock
214     if (BSL_SAL_ThreadLockNew(&libCtx->lock) != BSL_SUCCESS) {
215         BSL_LIST_FREE(libCtx->providers, NULL);
216         goto ERR;
217     }
218 
219     return libCtx;
220 ERR:
221     BSL_SAL_Free(libCtx);
222     libCtx = NULL;
223     return NULL;
224 }
225 
CRYPT_EAL_ProviderMgrCtxFree(CRYPT_EAL_ProvMgrCtx * ctx)226 void CRYPT_EAL_ProviderMgrCtxFree(CRYPT_EAL_ProvMgrCtx  *ctx)
227 {
228     if (ctx == NULL) {
229         return;
230     }
231     if (ctx->provFreeCb != NULL) {
232         ctx->provFreeCb(ctx->provCtx);
233         ctx->provCtx = NULL;
234     }
235     BSL_SAL_FREE(ctx->providerName);
236     BSL_SAL_FREE(ctx->providerPath);
237 
238     BSL_SAL_ReferencesFree(&(ctx->ref));
239 
240     if (ctx->handle != NULL) {
241         BSL_SAL_UnLoadLib(ctx->handle);
242         ctx->handle = NULL;
243     }
244 #ifdef HITLS_CRYPTO_ENTROPY_DEFAULT
245     ProviderSeedDeinit(&(ctx->providerSeed));
246 #endif
247     BSL_SAL_Free(ctx);
248 }
249 
CRYPT_EAL_LoadPreDefinedProvider(CRYPT_EAL_LibCtx * libCtx,const char * providerName,CRYPT_EAL_ProvMgrCtx ** ctx)250 int32_t CRYPT_EAL_LoadPreDefinedProvider(CRYPT_EAL_LibCtx *libCtx, const char* providerName,
251     CRYPT_EAL_ProvMgrCtx **ctx)
252 {
253     char *name = BSL_SAL_Dump(providerName, BSL_SAL_Strnlen(providerName, DEFAULT_PROVIDER_NAME_LEN_MAX) + 1);
254     if (name == NULL) {
255         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
256         return CRYPT_MEM_ALLOC_FAIL;
257     }
258     CRYPT_EAL_ProvMgrCtx *mgrCtx = (CRYPT_EAL_ProvMgrCtx *)BSL_SAL_Calloc(1, sizeof(CRYPT_EAL_ProvMgrCtx));
259     if (mgrCtx == NULL) {
260         BSL_SAL_Free(name);
261         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
262         return CRYPT_MEM_ALLOC_FAIL;
263     }
264     int32_t ret = BSL_SAL_ReferencesInit(&mgrCtx->ref);
265     if (ret != BSL_SUCCESS) {
266         BSL_SAL_Free(name);
267         BSL_SAL_Free(mgrCtx);
268         BSL_ERR_PUSH_ERROR(ret);
269         return ret;
270     }
271 
272     mgrCtx->libCtx = libCtx;
273     mgrCtx->providerName = name;
274     ret = CRYPT_EAL_InitProviderMethod(mgrCtx, NULL, CRYPT_EAL_DefaultProvInit);
275     if (ret == BSL_SUCCESS) {
276         ret = BSL_LIST_AddElement(libCtx->providers, mgrCtx, BSL_LIST_POS_END);
277         if (ctx != NULL) {
278             *ctx = mgrCtx;
279         }
280     }
281     if (ret != BSL_SUCCESS) {
282         CRYPT_EAL_ProviderMgrCtxFree(mgrCtx);
283     }
284     return ret;
285 }
286 
CRYPT_EAL_InitPreDefinedProviders(void)287 int32_t CRYPT_EAL_InitPreDefinedProviders(void)
288 {
289     CRYPT_EAL_LibCtx *libCtx = CRYPT_EAL_LibCtxNewInternal();
290     if (libCtx == NULL) {
291         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
292         return BSL_MALLOC_FAIL;
293     }
294     int32_t ret = CRYPT_EAL_LoadPreDefinedProvider(libCtx, CRYPT_EAL_DEFAULT_PROVIDER, NULL);
295     if (ret != CRYPT_SUCCESS) {
296         BSL_LIST_FREE(libCtx->providers, NULL);
297         BSL_SAL_ThreadLockFree(libCtx->lock);
298         BSL_SAL_FREE(libCtx);
299         return ret;
300     }
301     g_libCtx = libCtx;
302     return ret;
303 }
304 
CRYPT_EAL_FreePreDefinedProviders(void)305 void CRYPT_EAL_FreePreDefinedProviders(void)
306 {
307     CRYPT_EAL_LibCtx *libCtx = g_libCtx;
308     if (libCtx == NULL) {
309         return;
310     }
311 
312     if (libCtx->drbg != NULL) {
313         EAL_RandDeinit(libCtx->drbg);
314         libCtx->drbg = NULL;
315     }
316     // Free the providers list and each EAL_ProviderMgrCtx in it
317     if (libCtx->providers != NULL) {
318         BSL_LIST_FREE(libCtx->providers, (BSL_LIST_PFUNC_FREE)CRYPT_EAL_ProviderMgrCtxFree);
319     }
320 
321     BSL_SAL_FREE(libCtx->searchProviderPath);
322 
323     // Free thread lock
324     if (libCtx->lock != NULL) {
325         BSL_SAL_ThreadLockFree(libCtx->lock);
326         libCtx->lock = NULL;
327     }
328 
329     // Free the libctx structure itself
330     BSL_SAL_Free(libCtx);
331     g_libCtx = NULL;
332 }
333 
334 #endif /* HITLS_CRYPTO_PROVIDER */