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 #include "hitls_build.h"
17 #ifdef HITLS_CRYPTO_PROVIDER
18
19 #include <stdlib.h>
20 #include "securec.h"
21 #include "crypt_utils.h"
22 #include "crypt_errno.h"
23 #include "bsl_sal.h"
24 #include "bsl_err_internal.h"
25
26 #include "crypt_eal_provider.h"
27 #include "crypt_eal_implprovider.h"
28 #include "crypt_provider_local.h"
29 #include "crypt_provider.h"
30 #include "crypt_drbg_local.h"
31
32 // Name of the dl initialization function
33 #define PROVIDER_INIT_FUNC "CRYPT_EAL_ProviderInit"
34
35 // Maximum length of search path
36 #define DEFAULT_PROVIDER_PATH_LEN_MAX 4095
37 static uint32_t g_threadRunOnce = 0;
38
39
CRYPT_EAL_LibCtxNew(void)40 CRYPT_EAL_LibCtx *CRYPT_EAL_LibCtxNew(void)
41 {
42 return CRYPT_EAL_LibCtxNewInternal();
43 }
44
45 // Free EAL_LibCtx context
CRYPT_EAL_LibCtxFree(CRYPT_EAL_LibCtx * libCtx)46 void CRYPT_EAL_LibCtxFree(CRYPT_EAL_LibCtx *libCtx)
47 {
48 if (libCtx == NULL) {
49 return;
50 }
51
52 if (libCtx->drbg != NULL) {
53 EAL_RandDeinit(libCtx->drbg);
54 libCtx->drbg = NULL;
55 }
56 if (libCtx->providers != NULL) {
57 BSL_LIST_FREE(libCtx->providers, (BSL_LIST_PFUNC_FREE)CRYPT_EAL_ProviderMgrCtxFree);
58 }
59
60 if (libCtx->lock != NULL) {
61 BSL_SAL_ThreadLockFree(libCtx->lock);
62 }
63
64 BSL_SAL_FREE(libCtx->searchProviderPath);
65
66 BSL_SAL_Free(libCtx);
67 }
68
InitPreDefinedProviders(void)69 static void InitPreDefinedProviders(void)
70 {
71 CRYPT_EAL_LibCtx *globalCtx = CRYPT_EAL_GetGlobalLibCtx();
72 if (globalCtx == NULL) {
73 int32_t ret = CRYPT_EAL_InitPreDefinedProviders();
74 if (ret != CRYPT_SUCCESS) {
75 BSL_ERR_PUSH_ERROR(ret);
76 }
77 }
78 }
79
GetCurrentProviderLibCtx(CRYPT_EAL_LibCtx * libCtx)80 static CRYPT_EAL_LibCtx *GetCurrentProviderLibCtx(CRYPT_EAL_LibCtx *libCtx)
81 {
82 CRYPT_EAL_LibCtx *curLibCtx = libCtx;
83 if (curLibCtx == NULL) {
84 int32_t ret = BSL_SAL_ThreadRunOnce(&g_threadRunOnce, InitPreDefinedProviders);
85 if (ret != CRYPT_SUCCESS) {
86 BSL_ERR_PUSH_ERROR(ret);
87 return NULL;
88 }
89 curLibCtx = CRYPT_EAL_GetGlobalLibCtx();
90 }
91
92 return curLibCtx;
93 }
94
95 // Write a function to search for providers according to BSL_LIST_Search requirements,
96 // comparing the input providerName with the providerName in EAL_ProviderMgrCtx for an exact match
ListCompareProvider(const void * a,const void * b)97 static int32_t ListCompareProvider(const void *a, const void *b)
98 {
99 const CRYPT_EAL_ProvMgrCtx *ctx = (const CRYPT_EAL_ProvMgrCtx *)a;
100 const char *providerName = (const char *)b;
101 return (strcmp(ctx->providerName, providerName) == 0) ? 0 : 1;
102 }
103
104 // Function to mount parameters of EAL_ProviderMgrCtx structure
MountEalProviderMgrCtxParams(CRYPT_EAL_LibCtx * libCtx,void * handle,const char * providerName,const char * providerPath,BSL_Param * param,CRYPT_EAL_ProvMgrCtx * ctx)105 static int32_t MountEalProviderMgrCtxParams(CRYPT_EAL_LibCtx *libCtx, void *handle, const char *providerName,
106 const char *providerPath, BSL_Param *param, CRYPT_EAL_ProvMgrCtx *ctx)
107 {
108 ctx->handle = handle;
109 ctx->libCtx = libCtx;
110
111 int32_t ret = BSL_SAL_ReferencesInit(&(ctx->ref));
112 if (ret != BSL_SUCCESS) {
113 BSL_ERR_PUSH_ERROR(ret);
114 return ret;
115 }
116
117 ctx->providerName = BSL_SAL_Dump(providerName,
118 BSL_SAL_Strnlen(providerName, DEFAULT_PROVIDER_NAME_LEN_MAX) + 1);
119 if (ctx->providerName == NULL) {
120 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
121 return CRYPT_MEM_ALLOC_FAIL;
122 }
123
124 if (providerPath != NULL) {
125 ctx->providerPath = BSL_SAL_Dump(providerPath,
126 BSL_SAL_Strnlen(providerPath, DEFAULT_PROVIDER_PATH_LEN_MAX) + 1);
127 if (ctx->providerPath == NULL) {
128 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
129 return CRYPT_MEM_ALLOC_FAIL;
130 }
131 }
132
133 // Get the address of the initialization function
134 ret = BSL_SAL_GetFuncAddress(handle, PROVIDER_INIT_FUNC, (void **)&ctx->provInitFunc);
135 if (ret != BSL_SUCCESS) {
136 BSL_ERR_PUSH_ERROR(ret);
137 return ret;
138 }
139
140 // Call the initialization function
141 return CRYPT_EAL_InitProviderMethod(ctx, param, ctx->provInitFunc);
142 }
143
CheckProviderLoaded(CRYPT_EAL_LibCtx * libCtx,const char * providerName,CRYPT_EAL_ProvMgrCtx ** providerMgr)144 static int32_t CheckProviderLoaded(CRYPT_EAL_LibCtx *libCtx, const char *providerName,
145 CRYPT_EAL_ProvMgrCtx **providerMgr)
146 {
147 int32_t ret = BSL_SAL_ThreadReadLock(libCtx->lock);
148 if (ret != BSL_SUCCESS) {
149 BSL_ERR_PUSH_ERROR(ret);
150 return ret;
151 }
152
153 CRYPT_EAL_ProvMgrCtx *tempProviderMgr =
154 (CRYPT_EAL_ProvMgrCtx *)BSL_LIST_Search(libCtx->providers, providerName, ListCompareProvider, NULL);
155 if (tempProviderMgr != NULL) {
156 // Provider is already loaded, increase the reference count
157 int32_t tempCount = 0;
158 ret = BSL_SAL_AtomicUpReferences(&tempProviderMgr->ref, &tempCount);
159 if (ret != BSL_SUCCESS) {
160 BSL_ERR_PUSH_ERROR(ret);
161 (void)BSL_SAL_ThreadUnlock(libCtx->lock);
162 return ret;
163 }
164 }
165 (void)BSL_SAL_ThreadUnlock(libCtx->lock);
166
167 *providerMgr = tempProviderMgr;
168 return CRYPT_SUCCESS;
169 }
170
171 // Add provider to the list
AddProviderToList(CRYPT_EAL_LibCtx * libCtx,CRYPT_EAL_ProvMgrCtx * providerMgr)172 static int32_t AddProviderToList(CRYPT_EAL_LibCtx *libCtx, CRYPT_EAL_ProvMgrCtx *providerMgr)
173 {
174 int32_t ret = BSL_SAL_ThreadWriteLock(libCtx->lock);
175 if (ret != BSL_SUCCESS) {
176 BSL_ERR_PUSH_ERROR(ret);
177 return ret;
178 }
179
180 ret = BSL_LIST_AddElement(libCtx->providers, providerMgr, BSL_LIST_POS_END);
181 (void)BSL_SAL_ThreadUnlock(libCtx->lock);
182 if (ret != BSL_SUCCESS) {
183 BSL_ERR_PUSH_ERROR(ret);
184 }
185
186 return ret;
187 }
188
IsEalPreDefinedProvider(const char * providerName)189 static bool IsEalPreDefinedProvider(const char *providerName)
190 {
191 const char *preProvider[] = {CRYPT_EAL_DEFAULT_PROVIDER};
192 for (size_t i = 0; i < sizeof(preProvider) / sizeof(preProvider[0]); i++) {
193 if (strcmp(preProvider[i], providerName) == 0) {
194 return true;
195 }
196 }
197 return false;
198 }
199
200 // Create a new mgr context and initialize various parameters
EalProviderMgrCtxNew(CRYPT_EAL_LibCtx * libCtx,char * providerName,BSL_Param * param,CRYPT_EAL_ProvMgrCtx ** ctx)201 static int32_t EalProviderMgrCtxNew(CRYPT_EAL_LibCtx *libCtx, char *providerName, BSL_Param *param,
202 CRYPT_EAL_ProvMgrCtx **ctx)
203 {
204 int32_t ret;
205 uint32_t pathLen = BSL_SAL_Strnlen(providerName, DEFAULT_PROVIDER_NAME_LEN_MAX) +
206 BSL_SAL_Strnlen(libCtx->searchProviderPath, DEFAULT_PROVIDER_PATH_LEN_MAX) + 1;
207 if (pathLen > DEFAULT_PROVIDER_PATH_LEN_MAX) {
208 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
209 return CRYPT_INVALID_ARG;
210 }
211
212 char *providerPath = providerName;
213 // Construct the full path of the provider
214 if (libCtx->searchProviderPath != NULL) {
215 providerPath = (char *)BSL_SAL_Calloc(pathLen + 1, sizeof(char));
216 if (providerPath == NULL) {
217 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
218 return CRYPT_MEM_ALLOC_FAIL;
219 }
220 ret = snprintf_s(providerPath, pathLen + 1, pathLen, "%s/%s", libCtx->searchProviderPath, providerName);
221 if (ret < 0) {
222 BSL_SAL_Free(providerPath);
223 BSL_ERR_PUSH_ERROR(ret);
224 return ret;
225 }
226 }
227 // Attempt to load the dynamic library
228 void *handle = NULL;
229 ret = BSL_SAL_LoadLib(providerPath, &handle);
230 if (libCtx->searchProviderPath != NULL) {
231 BSL_SAL_Free(providerPath);
232 }
233 if (ret != BSL_SUCCESS) {
234 BSL_ERR_PUSH_ERROR(ret);
235 return ret;
236 }
237 CRYPT_EAL_ProvMgrCtx *tempCtx = (CRYPT_EAL_ProvMgrCtx *)BSL_SAL_Calloc(1, sizeof(CRYPT_EAL_ProvMgrCtx));
238 if (tempCtx == NULL) {
239 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
240 return CRYPT_MEM_ALLOC_FAIL;
241 }
242
243 // mount parameters of EAL_ProviderMgrCtx structure
244 ret = MountEalProviderMgrCtxParams(libCtx, handle, providerName, libCtx->searchProviderPath, param, tempCtx);
245 if (ret != CRYPT_SUCCESS) {
246 CRYPT_EAL_ProviderMgrCtxFree(tempCtx);
247 return ret;
248 }
249
250 *ctx = tempCtx;
251 return CRYPT_SUCCESS;
252 }
253
254 // Load provider dynamic library
CRYPT_EAL_ProviderLoad(CRYPT_EAL_LibCtx * libCtx,BSL_SAL_LibFmtCmd cmd,const char * providerName,BSL_Param * param,CRYPT_EAL_ProvMgrCtx ** mgrCtx)255 int32_t CRYPT_EAL_ProviderLoad(CRYPT_EAL_LibCtx *libCtx, BSL_SAL_LibFmtCmd cmd,
256 const char *providerName, BSL_Param *param, CRYPT_EAL_ProvMgrCtx **mgrCtx)
257 {
258 if (providerName == NULL) {
259 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
260 return CRYPT_NULL_INPUT;
261 }
262 CRYPT_EAL_LibCtx *localCtx = GetCurrentProviderLibCtx(libCtx);
263 if (localCtx == NULL) {
264 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_INVALID_LIB_CTX);
265 return CRYPT_PROVIDER_INVALID_LIB_CTX;
266 }
267
268 CRYPT_EAL_ProvMgrCtx *providerMgr = NULL;
269 char *providerFullName = NULL;
270 int32_t ret = BSL_SAL_LibNameFormat(cmd, providerName, &providerFullName);
271 if (ret != BSL_SUCCESS) {
272 BSL_ERR_PUSH_ERROR(ret);
273 return ret;
274 }
275
276 // Check if the provider is already loaded
277 ret = CheckProviderLoaded(localCtx, providerFullName, &providerMgr);
278 if (ret != CRYPT_SUCCESS) {
279 BSL_SAL_Free(providerFullName);
280 return ret;
281 }
282 if (providerMgr != NULL) {
283 BSL_SAL_Free(providerFullName);
284 if (mgrCtx != NULL) {
285 *mgrCtx = providerMgr;
286 }
287 return CRYPT_SUCCESS;
288 }
289 if (IsEalPreDefinedProvider(providerFullName)) {
290 ret = CRYPT_EAL_LoadPreDefinedProvider(libCtx, providerFullName, &providerMgr);
291 BSL_SAL_Free(providerFullName);
292 if (ret != CRYPT_SUCCESS) {
293 BSL_ERR_PUSH_ERROR(ret);
294 return ret;
295 }
296 if (mgrCtx != NULL) {
297 *mgrCtx = providerMgr;
298 }
299 return ret;
300 }
301 // Create and initialize EAL_ProviderMgrCtx
302 ret = EalProviderMgrCtxNew(localCtx, providerFullName, param, &providerMgr);
303 BSL_SAL_Free(providerFullName);
304 if (ret != CRYPT_SUCCESS) {
305 return ret;
306 }
307
308 // Add provider to the list
309 ret = AddProviderToList(localCtx, providerMgr);
310 if (ret != CRYPT_SUCCESS) {
311 CRYPT_EAL_ProviderMgrCtxFree(providerMgr);
312 providerMgr = NULL;
313 return ret;
314 }
315
316 if (mgrCtx != NULL) {
317 *mgrCtx = providerMgr;
318 }
319 return CRYPT_SUCCESS;
320 }
321
322 // Remove provider from the list
RemoveAndFreeProvider(BslList * providers,CRYPT_EAL_ProvMgrCtx * providerMgr)323 static void RemoveAndFreeProvider(BslList *providers, CRYPT_EAL_ProvMgrCtx *providerMgr)
324 {
325 BslListNode *node = BSL_LIST_FirstNode(providers);
326 while (node != NULL) {
327 if (BSL_LIST_GetData(node) == providerMgr) {
328 BSL_LIST_DetachNode(providers, &node);
329 break;
330 }
331 node = BSL_LIST_GetNextNode(providers, node);
332 }
333 CRYPT_EAL_ProviderMgrCtxFree(providerMgr);
334 }
335
336 // Unload provider
CRYPT_EAL_ProviderUnload(CRYPT_EAL_LibCtx * libCtx,BSL_SAL_LibFmtCmd cmd,const char * providerName)337 int32_t CRYPT_EAL_ProviderUnload(CRYPT_EAL_LibCtx *libCtx, BSL_SAL_LibFmtCmd cmd, const char *providerName)
338 {
339 if (providerName == NULL) {
340 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
341 return CRYPT_NULL_INPUT;
342 }
343
344 CRYPT_EAL_LibCtx *localCtx = libCtx;
345 if (localCtx == NULL) {
346 localCtx = CRYPT_EAL_GetGlobalLibCtx();
347 }
348 if (localCtx == NULL) {
349 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_INVALID_LIB_CTX);
350 return CRYPT_PROVIDER_INVALID_LIB_CTX;
351 }
352
353 char *providerFullName = NULL;
354 int32_t ret = BSL_SAL_LibNameFormat(cmd, providerName, &providerFullName);
355 if (ret != BSL_SUCCESS) {
356 BSL_ERR_PUSH_ERROR(ret);
357 return ret;
358 }
359
360 // Search for the specified provider
361 ret = BSL_SAL_ThreadReadLock(localCtx->lock);
362 if (ret != BSL_SUCCESS) {
363 BSL_ERR_PUSH_ERROR(ret);
364 BSL_SAL_FREE(providerFullName);
365 return ret;
366 }
367 CRYPT_EAL_ProvMgrCtx *providerMgr =
368 (CRYPT_EAL_ProvMgrCtx *)BSL_LIST_Search(localCtx->providers, providerFullName, ListCompareProvider, NULL);
369 BSL_SAL_FREE(providerFullName);
370 if (providerMgr == NULL) {
371 (void)BSL_SAL_ThreadUnlock(localCtx->lock);
372 return CRYPT_SUCCESS;
373 }
374 // Decrease reference count
375 int refCount = 0;
376 ret = BSL_SAL_AtomicDownReferences(&providerMgr->ref, &refCount);
377 if (ret != BSL_SUCCESS) {
378 (void)BSL_SAL_ThreadUnlock(localCtx->lock);
379 BSL_ERR_PUSH_ERROR(ret);
380 return ret;
381 }
382
383 if (refCount <= 0) {
384 RemoveAndFreeProvider(localCtx->providers, providerMgr);
385 }
386 (void)BSL_SAL_ThreadUnlock(localCtx->lock);
387 return CRYPT_SUCCESS;
388 }
389
390 // Set the path for loading providers
CRYPT_EAL_ProviderSetLoadPath(CRYPT_EAL_LibCtx * libCtx,const char * searchPath)391 int32_t CRYPT_EAL_ProviderSetLoadPath(CRYPT_EAL_LibCtx *libCtx, const char *searchPath)
392 {
393 if (BSL_SAL_Strnlen(searchPath, DEFAULT_PROVIDER_PATH_LEN_MAX) >= DEFAULT_PROVIDER_PATH_LEN_MAX) {
394 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
395 return CRYPT_INVALID_ARG;
396 }
397 CRYPT_EAL_LibCtx *localCtx = GetCurrentProviderLibCtx(libCtx);
398 if (localCtx == NULL) {
399 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_INVALID_LIB_CTX);
400 return CRYPT_PROVIDER_INVALID_LIB_CTX;
401 }
402
403 char *tempPath = NULL;
404 if (searchPath != NULL) {
405 tempPath = BSL_SAL_Dump(searchPath, BSL_SAL_Strnlen(searchPath, DEFAULT_PROVIDER_PATH_LEN_MAX) + 1);
406 if (tempPath == NULL) {
407 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
408 return CRYPT_MEM_ALLOC_FAIL;
409 }
410 }
411 BSL_SAL_FREE(localCtx->searchProviderPath);
412 localCtx->searchProviderPath = tempPath;
413 return CRYPT_SUCCESS;
414 }
415
GetProviderUserCtx(CRYPT_EAL_ProvMgrCtx * ctx,void ** val)416 static int32_t GetProviderUserCtx(CRYPT_EAL_ProvMgrCtx *ctx, void **val)
417 {
418 if (val == NULL) {
419 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
420 return CRYPT_NULL_INPUT;
421 }
422 *val = ctx->provCtx;
423 return CRYPT_SUCCESS;
424 }
425
CRYPT_EAL_ProviderCtrl(CRYPT_EAL_ProvMgrCtx * ctx,int32_t cmd,void * val,uint32_t valLen)426 int32_t CRYPT_EAL_ProviderCtrl(CRYPT_EAL_ProvMgrCtx *ctx, int32_t cmd, void *val, uint32_t valLen)
427 {
428 if (ctx == NULL) {
429 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
430 return CRYPT_NULL_INPUT;
431 }
432 if (cmd == CRYPT_PROVIDER_GET_USER_CTX) {
433 return GetProviderUserCtx(ctx, val);
434 }
435 if (ctx->provCtrlCb == NULL) {
436 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_NOT_SUPPORT);
437 return CRYPT_PROVIDER_NOT_SUPPORT;
438 }
439 return ctx->provCtrlCb(ctx->provCtx, cmd, val, valLen);
440 }
441
CRYPT_EAL_ProviderGetCaps(CRYPT_EAL_ProvMgrCtx * ctx,int32_t cmd,CRYPT_EAL_ProcessFuncCb cb,void * args)442 int32_t CRYPT_EAL_ProviderGetCaps(CRYPT_EAL_ProvMgrCtx *ctx, int32_t cmd, CRYPT_EAL_ProcessFuncCb cb, void *args)
443 {
444 if (ctx == NULL) {
445 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
446 return CRYPT_NULL_INPUT;
447 }
448 if (ctx->provGetCap == NULL) {
449 return CRYPT_SUCCESS;
450 }
451 return ctx->provGetCap(ctx->provCtx, cmd, cb, args);
452 }
453
CRYPT_EAL_ProviderProcessAll(CRYPT_EAL_LibCtx * ctx,CRYPT_EAL_ProviderProcessCb cb,void * args)454 int32_t CRYPT_EAL_ProviderProcessAll(CRYPT_EAL_LibCtx *ctx, CRYPT_EAL_ProviderProcessCb cb, void *args)
455 {
456 if (cb == NULL) {
457 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
458 return CRYPT_NULL_INPUT;
459 }
460 CRYPT_EAL_LibCtx *localCtx = ctx;
461 if (localCtx == NULL) {
462 localCtx = CRYPT_EAL_GetGlobalLibCtx();
463 }
464 if (localCtx == NULL) {
465 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_INVALID_LIB_CTX);
466 return CRYPT_PROVIDER_INVALID_LIB_CTX;
467 }
468 BslListNode *node = BSL_LIST_FirstNode(localCtx->providers);
469 while (node != NULL) {
470 CRYPT_EAL_ProvMgrCtx *providerMgr = (CRYPT_EAL_ProvMgrCtx *)BSL_LIST_GetData(node);
471 int32_t ret = cb(providerMgr, args);
472 if (ret != CRYPT_SUCCESS) {
473 BSL_ERR_PUSH_ERROR(ret);
474 return ret;
475 }
476 node = BSL_LIST_GetNextNode(localCtx->providers, node);
477 }
478 return CRYPT_SUCCESS;
479 }
480
CRYPT_EAL_ProviderQuery(CRYPT_EAL_ProvMgrCtx * ctx,int32_t operaId,CRYPT_EAL_AlgInfo ** algInfos)481 int32_t CRYPT_EAL_ProviderQuery(CRYPT_EAL_ProvMgrCtx *ctx, int32_t operaId, CRYPT_EAL_AlgInfo **algInfos)
482 {
483 if (ctx == NULL || algInfos == NULL) {
484 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
485 return CRYPT_NULL_INPUT;
486 }
487 if (ctx->provQueryCb == NULL) {
488 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_NOT_SUPPORT);
489 return CRYPT_PROVIDER_NOT_SUPPORT;
490 }
491 return ctx->provQueryCb(ctx->provCtx, operaId, algInfos);
492 }
493 #endif // HITLS_CRYPTO_PROVIDER
494