/* * This file is part of the openHiTLS project. * * openHiTLS is licensed under the Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ #include "bsl_sal.h" #include "bsl_list.h" #include "crypt_errno.h" #include "crypt_params_key.h" #include "crypt_eal_provider.h" #include "crypt_eal_implprovider.h" #include "crypt_eal_codecs.h" #include "crypt_eal_pkey.h" #include "bsl_types.h" #include "crypt_types.h" #include "provider_test_utils.h" #include #include #define RSA_MAX_MODULUS_BITS 16384 #define RSA_MAX_MODULUS_LEN (RSA_MAX_MODULUS_BITS / 8) #define PARAMISNULL(a) ((a) == NULL || (a)->value == NULL) #define PARAMISNULLLENIS0(a) ((a) == NULL || (a)->value == NULL || (a)->valueLen == 0) /* JSON to PEM decoder context */ typedef struct { const char *outFormat; const char *outType; } JSON_PEM_DecoderCtx; /* JSON to PEM decoder implementation */ static void *JSON_PEM_NewCtx(void *provCtx) { (void)provCtx; JSON_PEM_DecoderCtx *ctx = calloc(1, sizeof(JSON_PEM_DecoderCtx)); if (ctx == NULL) { return NULL; } ctx->outFormat = "PEM"; ctx->outType = NULL; return ctx; } static int32_t JSON_PEM_SetParam(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } return CRYPT_SUCCESS; } static int32_t JSON_PEM_GetParam(void *ctx, BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } JSON_PEM_DecoderCtx *decoderCtx = (JSON_PEM_DecoderCtx *)ctx; BSL_Param *param1 = TestFindParam(param, CRYPT_PARAM_DECODE_OUTPUT_TYPE); if (param1 != NULL) { if (param1->valueType != BSL_PARAM_TYPE_OCTETS_PTR) { return CRYPT_INVALID_ARG; } param1->value = (void *)(uintptr_t)decoderCtx->outType; } BSL_Param *param2 = TestFindParam(param, CRYPT_PARAM_DECODE_OUTPUT_FORMAT); if (param2 != NULL) { if (param2->valueType != BSL_PARAM_TYPE_OCTETS_PTR) { return CRYPT_INVALID_ARG; } param2->value = (void *)(uintptr_t)decoderCtx->outFormat; } return CRYPT_SUCCESS; } static int32_t JSON_PEM_Decode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam) { if (ctx == NULL || inParam == NULL || outParam == NULL) { return CRYPT_NULL_INPUT; } uint8_t *pemData = NULL; uint32_t pemLen = 0; uint8_t *jsonData = NULL; BSL_Param *resultParam = NULL; JSON_PEM_DecoderCtx *decoderCtx = (JSON_PEM_DecoderCtx *)ctx; const BSL_Param *param1 = TestFindConstParam(inParam, CRYPT_PARAM_DECODE_BUFFER_DATA); if (param1 == NULL) { return CRYPT_NULL_INPUT; } /* Get input data */ if (param1->valueType != BSL_PARAM_TYPE_OCTETS || param1->value == NULL || param1->valueLen == 0) { return CRYPT_INVALID_ARG; } jsonData = (uint8_t *)(uintptr_t)param1->value; uint8_t *pemHeader = strstr(jsonData, "{"); if (pemHeader == NULL) { return CRYPT_INVALID_ARG; } uint8_t *pemFooter = strstr(pemHeader, "}"); if (pemFooter == NULL) { return CRYPT_INVALID_ARG; } /* Convert JSON to PEM format */ pemLen = pemFooter - pemHeader + 1; pemData = (uint8_t *)malloc(pemLen); if (pemData == NULL) { return CRYPT_MEM_ALLOC_FAIL; } memcpy(pemData, pemHeader, pemLen); pemData[pemLen - 1] = '\0'; /* Create output parameter */ resultParam = calloc(2, sizeof(BSL_Param)); if (resultParam == NULL) { free(pemData); return CRYPT_MEM_ALLOC_FAIL; } resultParam[0].key = CRYPT_PARAM_DECODE_BUFFER_DATA; resultParam[0].valueType = BSL_PARAM_TYPE_OCTETS; resultParam[0].value = pemData; resultParam[0].valueLen = pemLen; *outParam = resultParam; return CRYPT_SUCCESS; } static void JSON_PEM_FreeOutData(void *ctx, BSL_Param *outData) { if (ctx == NULL || outData == NULL) { return; } free(outData->value); free(outData); } static void JSON_PEM_FreeCtx(void *ctx) { if (ctx == NULL) { return; } free(ctx); } /* RSA key management context */ typedef struct { uint32_t bits; // RSA key length uint8_t e[RSA_MAX_MODULUS_LEN]; // Public key uint8_t eLen; // Public key length uint8_t n[RSA_MAX_MODULUS_LEN]; // Public key uint32_t nLen; // Public key length uint8_t d[RSA_MAX_MODULUS_LEN]; // Private key uint32_t dLen; // Private key length uint8_t p[RSA_MAX_MODULUS_LEN]; // Private key uint32_t pLen; // Private key length uint8_t q[RSA_MAX_MODULUS_LEN]; // Private key uint32_t qLen; // Private key length uint8_t dp[RSA_MAX_MODULUS_LEN]; // Private key uint32_t dpLen; // Private key length uint8_t dq[RSA_MAX_MODULUS_LEN]; // Private key uint32_t dqLen; // Private key length uint8_t qInv[RSA_MAX_MODULUS_LEN]; // Private key uint32_t qInvLen; // Private key length int32_t mdId; // MD ID int32_t mgf1Id; // MGF1 ID int32_t saltLen; // Salt length } TestRsaCtx; /* RSA key management implementation */ static void *TestPkeyMgmtRsaNewCtx(void *provCtx) { (void)provCtx; TestRsaCtx *ctx = calloc(1, sizeof(TestRsaCtx)); if (ctx == NULL) { return NULL; } return ctx; } static void TestRsaFreeCtx(void *ctx) { if (ctx == NULL) { return; } free(ctx); } static int32_t TestRsaSetParam(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } const BSL_Param *e = TestFindConstParam(param, CRYPT_PARAM_RSA_E); const BSL_Param *bits = TestFindConstParam(param, CRYPT_PARAM_RSA_BITS); if (PARAMISNULL(e) || PARAMISNULL(bits)) { return CRYPT_NULL_INPUT; } if (e->valueType != BSL_PARAM_TYPE_OCTETS || bits->valueType != BSL_PARAM_TYPE_UINT32) { return CRYPT_INVALID_ARG; } TestRsaCtx *rsaCtx = (TestRsaCtx *)ctx; rsaCtx->bits = *(uint32_t *)bits->value; memcpy(rsaCtx->e, e->value, e->valueLen); rsaCtx->eLen = e->valueLen; return CRYPT_SUCCESS; } static int32_t TestRsaSetPubKey(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } const BSL_Param *e = TestFindConstParam(param, CRYPT_PARAM_RSA_E); const BSL_Param *n = TestFindConstParam(param, CRYPT_PARAM_RSA_N); if (PARAMISNULL(e) || PARAMISNULL(n)) { return CRYPT_NULL_INPUT; } TestRsaCtx *rsaCtx = (TestRsaCtx *)ctx; memcpy(rsaCtx->e, e->value, e->valueLen); memcpy(rsaCtx->n, n->value, n->valueLen); rsaCtx->eLen = e->valueLen; rsaCtx->nLen = n->valueLen; return CRYPT_SUCCESS; } static int32_t TestRsaSetPrvKey(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } const BSL_Param *n = TestFindConstParam(param, CRYPT_PARAM_RSA_N); const BSL_Param *d = TestFindConstParam(param, CRYPT_PARAM_RSA_D); const BSL_Param *p = TestFindConstParam(param, CRYPT_PARAM_RSA_P); const BSL_Param *q = TestFindConstParam(param, CRYPT_PARAM_RSA_Q); const BSL_Param *dp = TestFindConstParam(param, CRYPT_PARAM_RSA_DP); const BSL_Param *dq = TestFindConstParam(param, CRYPT_PARAM_RSA_DQ); const BSL_Param *qInv = TestFindConstParam(param, CRYPT_PARAM_RSA_QINV); if (PARAMISNULLLENIS0(n) || PARAMISNULLLENIS0(d) || n->valueType != BSL_PARAM_TYPE_OCTETS || d->valueType != BSL_PARAM_TYPE_OCTETS) { return CRYPT_NULL_INPUT; } if (n->valueLen > RSA_MAX_MODULUS_LEN) { return CRYPT_RSA_ERR_KEY_BITS; } // prv->p\q and prv->dP\dQ\qInv must be both empty or not. // If prv->p is empty, prv->dP must be empty. if ((PARAMISNULL(p) != PARAMISNULL(q)) || (PARAMISNULL(p) && !PARAMISNULL(dp))) { return CRYPT_RSA_NO_KEY_INFO; } if ((PARAMISNULL(dp) || PARAMISNULL(dq) || PARAMISNULL(qInv)) && (!PARAMISNULL(dp) || !PARAMISNULL(dq) || !PARAMISNULL(qInv))) { return CRYPT_RSA_NO_KEY_INFO; } TestRsaCtx *rsaCtx = (TestRsaCtx *)ctx; memcpy(rsaCtx->n, n->value, n->valueLen); rsaCtx->nLen = n->valueLen; memcpy(rsaCtx->d, d->value, d->valueLen); rsaCtx->dLen = d->valueLen; if (!PARAMISNULL(p)) { memcpy(rsaCtx->p, p->value, p->valueLen); rsaCtx->pLen = p->valueLen; } if (!PARAMISNULL(q)) { memcpy(rsaCtx->q, q->value, q->valueLen); rsaCtx->qLen = q->valueLen; } if (!PARAMISNULL(dp)) { memcpy(rsaCtx->dp, dp->value, dp->valueLen); rsaCtx->dpLen = dp->valueLen; } if (!PARAMISNULL(dq)) { memcpy(rsaCtx->dq, dq->value, dq->valueLen); rsaCtx->dqLen = dq->valueLen; } if (!PARAMISNULL(qInv)) { memcpy(rsaCtx->qInv, qInv->value, qInv->valueLen); rsaCtx->qInvLen = qInv->valueLen; } return CRYPT_SUCCESS; } static int32_t TestRsaImport(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } int32_t ret = CRYPT_SUCCESS; TestRsaCtx *rsaCtx = (TestRsaCtx *)ctx; const BSL_Param *e = TestFindConstParam(param, CRYPT_PARAM_RSA_E); const BSL_Param *n = TestFindConstParam(param, CRYPT_PARAM_RSA_N); if (!PARAMISNULL(e) && !PARAMISNULL(n)) { ret = TestRsaSetPubKey(ctx, param); if (ret != CRYPT_SUCCESS) { return ret; } } const BSL_Param *d = TestFindConstParam(param, CRYPT_PARAM_RSA_D); const BSL_Param *p = TestFindConstParam(param, CRYPT_PARAM_RSA_P); const BSL_Param *q = TestFindConstParam(param, CRYPT_PARAM_RSA_Q); const BSL_Param *dp = TestFindConstParam(param, CRYPT_PARAM_RSA_DP); const BSL_Param *dq = TestFindConstParam(param, CRYPT_PARAM_RSA_DQ); const BSL_Param *qInv = TestFindConstParam(param, CRYPT_PARAM_RSA_QINV); if (!PARAMISNULL(n) && !PARAMISNULL(d) && (PARAMISNULL(p) == PARAMISNULL(q)) && (PARAMISNULL(dp) == PARAMISNULL(dq)) && PARAMISNULL(dq) == PARAMISNULL(qInv)) { ret = TestRsaSetPrvKey(ctx, param); if (ret != CRYPT_SUCCESS) { return ret; } } const BSL_Param *mdIdParam = TestFindConstParam(param, CRYPT_PARAM_RSA_MD_ID); const BSL_Param *mgf1IdParam = TestFindConstParam(param, CRYPT_PARAM_RSA_MGF1_ID); const BSL_Param *saltLenParam = TestFindConstParam(param, CRYPT_PARAM_RSA_SALTLEN); if (mdIdParam != NULL && mdIdParam->valueType == BSL_PARAM_TYPE_INT32 && mdIdParam->valueLen == sizeof(int32_t) && mgf1IdParam != NULL && mgf1IdParam->valueType == BSL_PARAM_TYPE_INT32 && mgf1IdParam->valueLen == sizeof(int32_t) && saltLenParam != NULL && saltLenParam->valueType == BSL_PARAM_TYPE_INT32 && saltLenParam->valueLen == sizeof(int32_t)) { rsaCtx->mdId = *(int32_t *)mdIdParam->value; rsaCtx->mgf1Id = *(int32_t *)mgf1IdParam->value; rsaCtx->saltLen = *(int32_t *)saltLenParam->value; } else if (mdIdParam != NULL && mdIdParam->valueType == BSL_PARAM_TYPE_INT32 && mdIdParam->valueLen == sizeof(int32_t)) { rsaCtx->mdId = *(int32_t *)mdIdParam->value; } if (ret != CRYPT_SUCCESS) { return ret; } return CRYPT_SUCCESS; } /* Provider implementation */ static const CRYPT_EAL_Func g_jsonPemDecoderFuncs[] = { {CRYPT_DECODER_IMPL_NEWCTX, (void *)JSON_PEM_NewCtx}, {CRYPT_DECODER_IMPL_SETPARAM, (void *)JSON_PEM_SetParam}, {CRYPT_DECODER_IMPL_GETPARAM, (void *)JSON_PEM_GetParam}, {CRYPT_DECODER_IMPL_DECODE, (void *)JSON_PEM_Decode}, {CRYPT_DECODER_IMPL_FREEOUTDATA, (void *)JSON_PEM_FreeOutData}, {CRYPT_DECODER_IMPL_FREECTX, (void *)JSON_PEM_FreeCtx}, {0, NULL} }; /* Provider registration */ static const CRYPT_EAL_AlgInfo g_testDecode[] = { {BSL_CID_DECODE_UNKNOWN, g_jsonPemDecoderFuncs, "provider=test_decoder, inFormat=JSON, outFormat=PEM"}, CRYPT_EAL_ALGINFO_END }; /* SM2 key management context */ typedef struct { uint8_t prvKey[32]; // Private key uint32_t prvKeyLen; // Private key length uint8_t pubKey[72]; // Public key uint32_t pubKeyLen; // Public key length } TestSm2OrEd25519Ctx; /* SM2 key management implementation */ static void *TestPkeyMgmtSm2OrEd25519NewCtx(void *provCtx) { (void)provCtx; TestSm2OrEd25519Ctx *ctx = calloc(1, sizeof(TestSm2OrEd25519Ctx)); if (ctx == NULL) { return NULL; } return ctx; } static void TestSm2OrEd25519FreeCtx(void *ctx) { if (ctx == NULL) { return; } free(ctx); } static int32_t TestSm2SetPubKey(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } const BSL_Param *pubKey = TestFindConstParam(param, CRYPT_PARAM_EC_PUBKEY); if (PARAMISNULL(pubKey)) { return CRYPT_NULL_INPUT; } if (pubKey->valueType != BSL_PARAM_TYPE_OCTETS || pubKey->valueLen < 65) { return CRYPT_INVALID_ARG; } TestSm2OrEd25519Ctx *sm2Ctx = (TestSm2OrEd25519Ctx *)ctx; memcpy(sm2Ctx->pubKey, pubKey->value, pubKey->valueLen); sm2Ctx->pubKeyLen = pubKey->valueLen; return CRYPT_SUCCESS; } static int32_t TestSm2SetPrvKey(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } const BSL_Param *prvKey = TestFindConstParam(param, CRYPT_PARAM_EC_PRVKEY); if (PARAMISNULL(prvKey)) { return CRYPT_NULL_INPUT; } if (prvKey->valueType != BSL_PARAM_TYPE_OCTETS || prvKey->valueLen != 32) { return CRYPT_INVALID_ARG; } TestSm2OrEd25519Ctx *sm2Ctx = (TestSm2OrEd25519Ctx *)ctx; memcpy(sm2Ctx->prvKey, prvKey->value, prvKey->valueLen); sm2Ctx->prvKeyLen = prvKey->valueLen; return CRYPT_SUCCESS; } static int32_t TestSm2Import(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } int32_t ret; TestSm2OrEd25519Ctx *sm2Ctx = (TestSm2OrEd25519Ctx *)ctx; const BSL_Param *pubKey = TestFindConstParam(param, CRYPT_PARAM_EC_PUBKEY); if (!PARAMISNULL(pubKey)) { ret = TestSm2SetPubKey(ctx, param); if (ret != CRYPT_SUCCESS) { return ret; } } const BSL_Param *prvKey = TestFindConstParam(param, CRYPT_PARAM_EC_PRVKEY); if (!PARAMISNULL(prvKey)) { ret = TestSm2SetPrvKey(ctx, param); if (ret != CRYPT_SUCCESS) { return ret; } } return CRYPT_SUCCESS; } /* ED25519 key management context */ static int32_t TestEd25519SetPubKey(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } const BSL_Param *pubKey = TestFindConstParam(param, CRYPT_PARAM_CURVE25519_PUBKEY); if (PARAMISNULL(pubKey)) { return CRYPT_NULL_INPUT; } if (pubKey->valueType != BSL_PARAM_TYPE_OCTETS || pubKey->valueLen != 32) { return CRYPT_INVALID_ARG; } TestSm2OrEd25519Ctx *ed25519Ctx = (TestSm2OrEd25519Ctx *)ctx; memcpy(ed25519Ctx->pubKey, pubKey->value, pubKey->valueLen); ed25519Ctx->pubKeyLen = pubKey->valueLen; return CRYPT_SUCCESS; } static int32_t TestEd25519SetPrvKey(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } const BSL_Param *prvKey = TestFindConstParam(param, CRYPT_PARAM_CURVE25519_PRVKEY); if (PARAMISNULL(prvKey)) { return CRYPT_NULL_INPUT; } if (prvKey->valueType != BSL_PARAM_TYPE_OCTETS || prvKey->valueLen != 32) { return CRYPT_INVALID_ARG; } TestSm2OrEd25519Ctx *ed25519Ctx = (TestSm2OrEd25519Ctx *)ctx; memcpy(ed25519Ctx->prvKey, prvKey->value, prvKey->valueLen); ed25519Ctx->prvKeyLen = prvKey->valueLen; return CRYPT_SUCCESS; } static int32_t TestEd25519Import(void *ctx, const BSL_Param *param) { if (ctx == NULL || param == NULL) { return CRYPT_NULL_INPUT; } int32_t ret; TestSm2OrEd25519Ctx *ed25519Ctx = (TestSm2OrEd25519Ctx *)ctx; const BSL_Param *pubKey = TestFindConstParam(param, CRYPT_PARAM_CURVE25519_PUBKEY); if (!PARAMISNULL(pubKey)) { ret = TestEd25519SetPubKey(ctx, param); if (ret != CRYPT_SUCCESS) { return ret; } } const BSL_Param *prvKey = TestFindConstParam(param, CRYPT_PARAM_CURVE25519_PRVKEY); if (!PARAMISNULL(prvKey)) { ret = TestEd25519SetPrvKey(ctx, param); if (ret != CRYPT_SUCCESS) { return ret; } } return CRYPT_SUCCESS; } const CRYPT_EAL_Func g_testKeyMgmtRsa[] = { {CRYPT_EAL_IMPLPKEYMGMT_NEWCTX, (CRYPT_EAL_ImplPkeyMgmtNewCtx)TestPkeyMgmtRsaNewCtx}, {CRYPT_EAL_IMPLPKEYMGMT_SETPARAM, (CRYPT_EAL_ImplPkeyMgmtSetParam)TestRsaSetParam}, {CRYPT_EAL_IMPLPKEYMGMT_SETPRV, (CRYPT_EAL_ImplPkeyMgmtSetPrv)TestRsaSetPrvKey}, {CRYPT_EAL_IMPLPKEYMGMT_SETPUB, (CRYPT_EAL_ImplPkeyMgmtSetPub)TestRsaSetPubKey}, {CRYPT_EAL_IMPLPKEYMGMT_FREECTX, (CRYPT_EAL_ImplPkeyMgmtFreeCtx)TestRsaFreeCtx}, {CRYPT_EAL_IMPLPKEYMGMT_IMPORT, (CRYPT_EAL_ImplPkeyMgmtImport)TestRsaImport}, CRYPT_EAL_FUNC_END, }; const CRYPT_EAL_Func g_testKeyMgmtSm2[] = { {CRYPT_EAL_IMPLPKEYMGMT_NEWCTX, (CRYPT_EAL_ImplPkeyMgmtNewCtx)TestPkeyMgmtSm2OrEd25519NewCtx}, {CRYPT_EAL_IMPLPKEYMGMT_SETPRV, (CRYPT_EAL_ImplPkeyMgmtSetPrv)TestSm2SetPrvKey}, {CRYPT_EAL_IMPLPKEYMGMT_SETPUB, (CRYPT_EAL_ImplPkeyMgmtSetPub)TestSm2SetPubKey}, {CRYPT_EAL_IMPLPKEYMGMT_FREECTX, (CRYPT_EAL_ImplPkeyMgmtFreeCtx)TestSm2OrEd25519FreeCtx}, {CRYPT_EAL_IMPLPKEYMGMT_IMPORT, (CRYPT_EAL_ImplPkeyMgmtImport)TestSm2Import}, CRYPT_EAL_FUNC_END, }; const CRYPT_EAL_Func g_testKeyMgmtEd25519[] = { {CRYPT_EAL_IMPLPKEYMGMT_NEWCTX, (CRYPT_EAL_ImplPkeyMgmtNewCtx)TestPkeyMgmtSm2OrEd25519NewCtx}, {CRYPT_EAL_IMPLPKEYMGMT_SETPRV, (CRYPT_EAL_ImplPkeyMgmtSetPrv)TestEd25519SetPrvKey}, {CRYPT_EAL_IMPLPKEYMGMT_SETPUB, (CRYPT_EAL_ImplPkeyMgmtSetPub)TestEd25519SetPubKey}, {CRYPT_EAL_IMPLPKEYMGMT_FREECTX, (CRYPT_EAL_ImplPkeyMgmtFreeCtx)TestSm2OrEd25519FreeCtx}, {CRYPT_EAL_IMPLPKEYMGMT_IMPORT, (CRYPT_EAL_ImplPkeyMgmtImport)TestEd25519Import}, CRYPT_EAL_FUNC_END, }; static const CRYPT_EAL_AlgInfo g_testKeyMgmt[] = { {CRYPT_PKEY_RSA, g_testKeyMgmtRsa, "provider=test_decoder"}, {CRYPT_PKEY_SM2, g_testKeyMgmtSm2, "provider=test_decoder"}, {CRYPT_PKEY_ED25519, g_testKeyMgmtEd25519, "provider=test_decoder"}, CRYPT_EAL_ALGINFO_END }; static int32_t TestProvQuery(void *provCtx, int32_t operaId, CRYPT_EAL_AlgInfo **algInfos) { (void)provCtx; int32_t ret = CRYPT_SUCCESS; switch (operaId) { case CRYPT_EAL_OPERAID_KEYMGMT: *algInfos = (CRYPT_EAL_AlgInfo *)(uintptr_t)g_testKeyMgmt; break; case CRYPT_EAL_OPERAID_DECODER: *algInfos = (CRYPT_EAL_AlgInfo *)(uintptr_t)g_testDecode; break; default: return CRYPT_NOT_SUPPORT; } return CRYPT_SUCCESS; } static int32_t TestProvFree(void *provCtx) { if (provCtx != NULL) { free(provCtx); } return CRYPT_SUCCESS; } static CRYPT_EAL_Func g_testProvOutFuncs[] = { {CRYPT_EAL_PROVCB_QUERY, TestProvQuery}, {CRYPT_EAL_PROVCB_FREE, TestProvFree}, {CRYPT_EAL_PROVCB_CTRL, NULL}, {CRYPT_EAL_PROVCB_GETCAPS, NULL}, CRYPT_EAL_FUNC_END }; int32_t CRYPT_EAL_ProviderInit(CRYPT_EAL_ProvMgrCtx *mgrCtx, BSL_Param *param, CRYPT_EAL_Func *capFuncs, CRYPT_EAL_Func **outFuncs, void **provCtx) { *outFuncs = g_testProvOutFuncs; return CRYPT_SUCCESS; }