• 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 #include "crypt_eal_provider.h"
17 #include <stdbool.h>
18 #include <stdio.h>
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include "bsl_obj.h"
23 #include "bsl_err.h"
24 #include "bsl_params.h"
25 #include "bsl_asn1.h"
26 #include "bsl_obj_internal.h"
27 #include "crypt_encode_decode_key.h"
28 #include "crypt_errno.h"
29 #include "crypt_params_key.h"
30 #include "crypt_eal_implprovider.h"
31 #include "hitls_type.h"
32 #include "crypt_params_key.h"
33 #include "provider_test_utils.h"
34 
35 #define NEW_PARA_ALGID (BSL_CID_MAX + 5)
36 #define NEW_PKEY_ALGID (BSL_CID_MAX + 6)
37 #define NEW_SIGN_HASH_ALGID (BSL_CID_MAX + 7)
38 #define NEW_HASH_ALGID (BSL_CID_MAX + 8)
39 #define TEST_CRYPT_DEFAULT_SIGNLEN 68
40 #define UINT8_MAX_NUM 255
41 
42 #define CRYPT_PARAM_NEW_KEY_BASE        3000
43 #define CRYPT_PARAM_NEW_KEY_PRVKEY      (CRYPT_PARAM_NEW_KEY_BASE + 1)
44 #define CRYPT_PARAM_NEW_KEY_PUBKEY      (CRYPT_PARAM_NEW_KEY_BASE + 2)
45 #define CRYPT_PARAM_NEW_KEY_GROUP       (CRYPT_PARAM_NEW_KEY_BASE + 3)
46 
47 typedef struct {
48     CRYPT_EAL_ProvMgrCtx *mgrCtxHandle;
49 } TestProvCtx;
50 
51 typedef struct {
52     uint8_t prvkey[72];      // Private key
53     uint32_t prvkeyLen;      // Private key length
54     uint8_t pubkey[256];     // Public key
55     uint32_t pubkeyLen;      // Public key length
56     int32_t paraId;          // Parameter ID
57 } TestNewKeyCtx;
58 typedef struct {
59     CRYPT_EAL_ProvMgrCtx *provMgrCtx;
60     int32_t keyAlgId;
61     const char *outFormat;
62     const char *outType;
63 } TestNewAlgDer2KeyCtx;
64 
RandFunc(uint8_t * randNum,uint32_t randLen)65 static void RandFunc(uint8_t *randNum, uint32_t randLen)
66 {
67     for (uint32_t i = 0; i < randLen; i++) {
68         randNum[i] = (uint8_t)(rand() % UINT8_MAX_NUM);
69     }
70 }
71 
TestNewKeyMgmtNewCtx(void * provCtx,int32_t algId)72 void *TestNewKeyMgmtNewCtx(void *provCtx, int32_t algId)
73 {
74     (void)provCtx;
75     (void)algId;
76     TestNewKeyCtx *pkeyCtx = malloc(sizeof(TestNewKeyCtx));
77     if (pkeyCtx == NULL) {
78         return NULL;
79     }
80     return (void *)pkeyCtx;
81 }
82 
TestNewKeySetPara(TestNewKeyCtx * ctx,const BSL_Param * param)83 static int32_t TestNewKeySetPara(TestNewKeyCtx *ctx, const BSL_Param *param)
84 {
85     if (ctx == NULL || param == NULL) {
86         return CRYPT_NULL_INPUT;
87     }
88     const BSL_Param *para = TestFindConstParam(param, CRYPT_PARAM_NEW_KEY_GROUP);
89     if (para != NULL) {
90         if (para->value == NULL || para->valueType != BSL_PARAM_TYPE_INT32 ||
91             para->valueLen != sizeof(int32_t)) {
92             return CRYPT_INVALID_ARG;
93         }
94         ctx->paraId = *((int32_t *)para->value);
95     }
96     return CRYPT_SUCCESS;
97 }
98 
TestNewKeyGenKey(TestNewKeyCtx * ctx)99 static int32_t TestNewKeyGenKey(TestNewKeyCtx *ctx)
100 {
101     if (ctx == NULL) {
102         return CRYPT_NULL_INPUT;
103     }
104     if (ctx->paraId != NEW_PARA_ALGID) {
105         return CRYPT_INVALID_ARG;
106     }
107     ctx->prvkeyLen = 66;
108     ctx->pubkeyLen = 143;
109     RandFunc(ctx->prvkey, ctx->prvkeyLen);
110     RandFunc(ctx->pubkey, ctx->pubkeyLen);
111     return CRYPT_SUCCESS;
112 }
113 
TestNewKeySetPrvKey(TestNewKeyCtx * ctx,const BSL_Param * para)114 static int32_t TestNewKeySetPrvKey(TestNewKeyCtx *ctx, const BSL_Param *para)
115 {
116     if (ctx == NULL || para == NULL) {
117         return CRYPT_NULL_INPUT;
118     }
119     const BSL_Param *prv = TestFindConstParam(para, CRYPT_PARAM_NEW_KEY_PRVKEY);
120     if (prv == NULL || prv->value == NULL || prv->valueLen == 0) {
121         return CRYPT_NULL_INPUT;
122     }
123     (void)memcpy(ctx->prvkey, prv->value, prv->valueLen);
124     ctx->prvkeyLen = prv->valueLen;
125     return CRYPT_SUCCESS;
126 }
127 
TestNewKeySetPubKey(TestNewKeyCtx * ctx,const BSL_Param * para)128 static int32_t TestNewKeySetPubKey(TestNewKeyCtx *ctx, const BSL_Param *para)
129 {
130     if (ctx == NULL || para == NULL) {
131         return CRYPT_NULL_INPUT;
132     }
133     const BSL_Param *pub = TestFindConstParam(para, CRYPT_PARAM_NEW_KEY_PUBKEY);
134     if (pub == NULL) {
135         pub = TestFindConstParam(para, CRYPT_PARAM_PKEY_ENCODE_PUBKEY);
136     }
137     if (pub == NULL || pub->value == NULL || pub->valueLen == 0) {
138         return CRYPT_NULL_INPUT;
139     }
140     (void)memcpy(ctx->pubkey, pub->value, pub->valueLen);
141     ctx->pubkeyLen = pub->valueLen;
142     return CRYPT_SUCCESS;
143 }
144 
TestNewKeyGetPrvKey(TestNewKeyCtx * ctx,BSL_Param * para)145 static int32_t TestNewKeyGetPrvKey(TestNewKeyCtx *ctx, BSL_Param *para)
146 {
147     if (ctx == NULL || para == NULL) {
148         return CRYPT_NULL_INPUT;
149     }
150     BSL_Param *prv = TestFindParam(para, CRYPT_PARAM_NEW_KEY_PRVKEY);
151     if (prv == NULL) {
152         return CRYPT_NULL_INPUT;
153     }
154     if (prv->valueLen < ctx->prvkeyLen) {
155         return CRYPT_INVALID_ARG;
156     }
157     (void)memcpy(prv->value, ctx->prvkey, ctx->prvkeyLen);
158     prv->useLen = ctx->prvkeyLen;
159     return CRYPT_SUCCESS;
160 }
161 
TestNewKeyGetPubKey(TestNewKeyCtx * ctx,BSL_Param * para)162 static int32_t TestNewKeyGetPubKey(TestNewKeyCtx *ctx, BSL_Param *para)
163 {
164     if (ctx == NULL || para == NULL) {
165         return CRYPT_NULL_INPUT;
166     }
167     BSL_Param *pub = TestFindParam(para, CRYPT_PARAM_NEW_KEY_PUBKEY);
168     if (pub == NULL) {
169         pub = TestFindParam(para, CRYPT_PARAM_PKEY_ENCODE_PUBKEY);
170     }
171     if (pub == NULL || pub->value == NULL || pub->valueLen == 0) {
172         return CRYPT_NULL_INPUT;
173     }
174     if (ctx->pubkey == NULL) {
175         return CRYPT_ECC_PKEY_ERR_EMPTY_KEY;
176     }
177     (void)memcpy(pub->value, ctx->pubkey, ctx->pubkeyLen);
178     pub->useLen = ctx->pubkeyLen;
179     return CRYPT_SUCCESS;
180 }
181 
TestNewKeySign(const TestNewKeyCtx * ctx,int32_t algId,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t * signLen)182 static int32_t TestNewKeySign(const TestNewKeyCtx *ctx, int32_t algId,
183                             const uint8_t *data, uint32_t dataLen,
184                             uint8_t *sign, uint32_t *signLen)
185 {
186     if (ctx == NULL || data == NULL || sign == NULL || signLen == NULL) {
187         return CRYPT_NULL_INPUT;
188     }
189 
190     if (*signLen < TEST_CRYPT_DEFAULT_SIGNLEN) {
191         return CRYPT_INVALID_ARG;
192     }
193     sign[0] = 0x30;
194     sign[1] = 0x42;
195     sign[2] = 0x02;
196     sign[3] = 0x40;
197     for (uint32_t i = 4; i < TEST_CRYPT_DEFAULT_SIGNLEN; i++) {
198         sign[i] = ctx->pubkey[(i - 4) % ctx->pubkeyLen];
199     }
200     *signLen = TEST_CRYPT_DEFAULT_SIGNLEN;
201 
202     return CRYPT_SUCCESS;
203 }
204 
TestNewKeyVerify(const TestNewKeyCtx * ctx,int32_t algId,const uint8_t * data,uint32_t dataLen,const uint8_t * sign,uint32_t signLen)205 static int32_t TestNewKeyVerify(const TestNewKeyCtx *ctx, int32_t algId,
206                               const uint8_t *data, uint32_t dataLen,
207                               const uint8_t *sign, uint32_t signLen)
208 {
209     if (ctx == NULL || data == NULL || sign == NULL) {
210         return CRYPT_NULL_INPUT;
211     }
212 
213     if (signLen != TEST_CRYPT_DEFAULT_SIGNLEN) {
214         return CRYPT_INVALID_ARG;
215     }
216     if (sign[0] != 0x30 || sign[1] != 0x42) {
217         return CRYPT_ECDSA_VERIFY_FAIL;
218     }
219     if (sign[2] != 0x02 || sign[3] != 0x40) {
220         return CRYPT_ECDSA_VERIFY_FAIL;
221     }
222     for (uint32_t i = 4; i < TEST_CRYPT_DEFAULT_SIGNLEN; i++) {
223         if (sign[i] != ctx->pubkey[(i - 4) % ctx->pubkeyLen]) {
224             return CRYPT_ECDSA_VERIFY_FAIL;
225         }
226     }
227     return CRYPT_SUCCESS;
228 }
229 
TestNewKeyFreeCtx(TestNewKeyCtx * ctx)230 static void TestNewKeyFreeCtx(TestNewKeyCtx *ctx)
231 {
232     if (ctx != NULL) {
233         free(ctx);
234     }
235 }
236 
TestNewKeyCtrl(TestNewKeyCtx * ctx,int32_t cmd,void * val,uint32_t valLen)237 static int32_t TestNewKeyCtrl(TestNewKeyCtx *ctx, int32_t cmd, void *val, uint32_t valLen)
238 {
239     if (ctx == NULL || val == NULL) {
240         return CRYPT_NULL_INPUT;
241     }
242     if (valLen != sizeof(uint32_t)) {
243         return CRYPT_INVALID_ARG;
244     }
245     switch (cmd) {
246         case CRYPT_CTRL_GET_SECBITS:
247             if (valLen != sizeof(uint32_t)) {
248                 return CRYPT_INVALID_ARG;
249             }
250             *((uint32_t *)val) = 2048;
251             return CRYPT_SUCCESS;
252         case CRYPT_CTRL_GET_PARAID:
253             if (valLen != sizeof(uint32_t)) {
254                 return CRYPT_INVALID_ARG;
255             }
256             *((uint32_t *)val) = NEW_PARA_ALGID;
257             return CRYPT_SUCCESS;
258         case CRYPT_CTRL_SET_PARA_BY_ID:
259             ctx->paraId = *((uint32_t *)val);
260             return CRYPT_SUCCESS;
261         case CRYPT_CTRL_GET_SIGNLEN:
262             *((uint32_t *)val) = TEST_CRYPT_DEFAULT_SIGNLEN;
263             return CRYPT_SUCCESS;
264         default:
265             return CRYPT_NOT_SUPPORT;
266     }
267 }
268 
TestNewKeyImport(void * ctx,const BSL_Param * params)269 static int32_t TestNewKeyImport(void *ctx, const BSL_Param *params)
270 {
271     TestNewKeyCtx *keyCtx = (TestNewKeyCtx *)ctx;
272     if (keyCtx == NULL || params == NULL) {
273         return CRYPT_NULL_INPUT;
274     }
275     int32_t ret = CRYPT_SUCCESS;
276     const BSL_Param *para = TestFindConstParam(params, CRYPT_PARAM_NEW_KEY_GROUP);
277     const BSL_Param *prv = TestFindConstParam(params, CRYPT_PARAM_NEW_KEY_PRVKEY);
278     const BSL_Param *pub = TestFindConstParam(params, CRYPT_PARAM_NEW_KEY_PUBKEY);
279     if (para != NULL) {
280         ret = TestNewKeySetPara(keyCtx, para);
281         if (ret != CRYPT_SUCCESS) {
282             return ret;
283         }
284     }
285     if (prv != NULL) {
286         ret = TestNewKeySetPrvKey(keyCtx, prv);
287         if (ret != CRYPT_SUCCESS) {
288             return ret;
289         }
290     }
291     if (pub != NULL) {
292         ret = TestNewKeySetPubKey(keyCtx, pub);
293         if (ret != CRYPT_SUCCESS) {
294             return ret;
295         }
296     }
297 
298     return CRYPT_SUCCESS;
299 }
300 
TestNewKeyDupCtx(const void * ctx)301 static void *TestNewKeyDupCtx(const void *ctx)
302 {
303     void *dest = malloc(sizeof(TestNewKeyCtx));
304     if (dest == NULL) {
305         return NULL;
306     }
307     (void)memcpy(dest, ctx, sizeof(TestNewKeyCtx));
308     return dest;
309 }
310 
TestNewKeyExport(void * ctx,BSL_Param * params)311 static int32_t TestNewKeyExport(void *ctx, BSL_Param *params)
312 {
313     (void)ctx;
314     (void)params;
315     return CRYPT_SUCCESS;
316 }
317 
TestNewKeyExch(const void * ctx,const void * pubCtx,uint8_t * out,uint32_t * outLen)318 static int32_t TestNewKeyExch(const void *ctx, const void *pubCtx, uint8_t *out, uint32_t *outLen)
319 {
320     if (ctx == NULL || pubCtx == NULL || out == NULL || outLen == NULL) {
321         return CRYPT_NULL_INPUT;
322     }
323     const TestNewKeyCtx *prvKeyCtx = ctx;
324     const TestNewKeyCtx *pubKeyCtx = pubCtx;
325     int32_t len = pubKeyCtx->pubkeyLen < prvKeyCtx->pubkeyLen ? pubKeyCtx->pubkeyLen : prvKeyCtx->pubkeyLen;
326     for (uint32_t i = 0; i < len; i++) {
327         out[i] = (prvKeyCtx->pubkey[i] + pubKeyCtx->pubkey[i]) % 256;
328     }
329     *outLen = len;
330     return CRYPT_SUCCESS;
331 }
332 
333 const CRYPT_EAL_Func g_testKeyMgmtNewKey[] = {
334     {CRYPT_EAL_IMPLPKEYMGMT_NEWCTX, (CRYPT_EAL_ImplPkeyMgmtNewCtx)TestNewKeyMgmtNewCtx},
335     {CRYPT_EAL_IMPLPKEYMGMT_SETPARAM, (CRYPT_EAL_ImplPkeyMgmtSetParam)TestNewKeySetPara},
336     {CRYPT_EAL_IMPLPKEYMGMT_GENKEY, (CRYPT_EAL_ImplPkeyMgmtGenKey)TestNewKeyGenKey},
337     {CRYPT_EAL_IMPLPKEYMGMT_SETPRV, (CRYPT_EAL_ImplPkeyMgmtSetPrv)TestNewKeySetPrvKey},
338     {CRYPT_EAL_IMPLPKEYMGMT_SETPUB, (CRYPT_EAL_ImplPkeyMgmtSetPub)TestNewKeySetPubKey},
339     {CRYPT_EAL_IMPLPKEYMGMT_GETPRV, (CRYPT_EAL_ImplPkeyMgmtGetPrv)TestNewKeyGetPrvKey},
340     {CRYPT_EAL_IMPLPKEYMGMT_GETPUB, (CRYPT_EAL_ImplPkeyMgmtGetPub)TestNewKeyGetPubKey},
341     {CRYPT_EAL_IMPLPKEYMGMT_DUPCTX, (CRYPT_EAL_ImplPkeyMgmtDupCtx)TestNewKeyDupCtx},
342     {CRYPT_EAL_IMPLPKEYMGMT_CTRL, (CRYPT_EAL_ImplPkeyMgmtCtrl)TestNewKeyCtrl},
343     {CRYPT_EAL_IMPLPKEYMGMT_IMPORT, (CRYPT_EAL_ImplPkeyMgmtImport)TestNewKeyImport},
344     {CRYPT_EAL_IMPLPKEYMGMT_EXPORT, (CRYPT_EAL_ImplPkeyMgmtExport)TestNewKeyExport},
345     {CRYPT_EAL_IMPLPKEYMGMT_FREECTX, (CRYPT_EAL_ImplPkeyMgmtFreeCtx)TestNewKeyFreeCtx},
346     CRYPT_EAL_FUNC_END
347 };
348 
349 const CRYPT_EAL_Func g_testSignNew[] = {
350     {CRYPT_EAL_IMPLPKEYSIGN_SIGN, (void *)TestNewKeySign},
351     {CRYPT_EAL_IMPLPKEYSIGN_VERIFY, (void *)TestNewKeyVerify},
352     CRYPT_EAL_FUNC_END
353 };
354 
355 const CRYPT_EAL_Func g_testExchDh[] = {
356     {CRYPT_EAL_IMPLPKEYEXCH_EXCH, (CRYPT_EAL_ImplPkeyExch)TestNewKeyExch},
357     CRYPT_EAL_FUNC_END
358 };
359 
360 static CRYPT_EAL_AlgInfo g_testKeyMgmt[] = {
361     {NEW_PKEY_ALGID, g_testKeyMgmtNewKey, "provider=provider_new_alg_test"},
362     CRYPT_EAL_ALGINFO_END
363 };
364 
365 static CRYPT_EAL_AlgInfo g_testSign[] = {
366     {NEW_PKEY_ALGID, g_testSignNew, "provider=provider_new_alg_test"},
367     CRYPT_EAL_ALGINFO_END
368 };
369 
370 static CRYPT_EAL_AlgInfo g_testKeyExch[] = {
371     {NEW_PKEY_ALGID, g_testExchDh, "provider=provider_new_alg_test"}, // For computing the shared key
372     CRYPT_EAL_ALGINFO_END
373 };
374 
DECODER_NewAlgDer2Key_NewCtx(void * provCtx)375 static void *DECODER_NewAlgDer2Key_NewCtx(void *provCtx)
376 {
377     (void)provCtx;
378     TestNewAlgDer2KeyCtx *ctx = calloc(1, sizeof(TestNewAlgDer2KeyCtx));
379     if (ctx == NULL) {
380         return NULL;
381     }
382     ctx->outFormat = "OBJECT";
383     ctx->outType = "LOW_KEY";
384     ctx->keyAlgId = NEW_PKEY_ALGID;
385     return ctx;
386 }
387 
DECODER_NewAlgDer2Key_GetParam(void * ctx,void * param)388 static int32_t DECODER_NewAlgDer2Key_GetParam(void *ctx, void *param)
389 {
390     if (ctx == NULL || param == NULL) {
391         return CRYPT_NULL_INPUT;
392     }
393     TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
394     BSL_Param *param1 = TestFindParam(param, CRYPT_PARAM_DECODE_OUTPUT_TYPE);
395     if (param1 != NULL) {
396         if (param1->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
397             return CRYPT_INVALID_ARG;
398         }
399         param1->value = (void *)(uintptr_t)decoderCtx->outType;
400     }
401     BSL_Param *param2 = TestFindParam(param, CRYPT_PARAM_DECODE_OUTPUT_FORMAT);
402     if (param2 != NULL) {
403         if (param2->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
404             return CRYPT_INVALID_ARG;
405         }
406         param2->value = (void *)(uintptr_t)decoderCtx->outFormat;
407     }
408     return CRYPT_SUCCESS;
409 }
410 
DECODER_NewAlgDer2Key_SetParam(void * ctx,const void * param)411 static int32_t DECODER_NewAlgDer2Key_SetParam(void *ctx, const void *param)
412 {
413     TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
414     if (decoderCtx == NULL || param == NULL) {
415         return CRYPT_NULL_INPUT;
416     }
417 
418     const BSL_Param *input = TestFindConstParam(param, CRYPT_PARAM_DECODE_PROVIDER_CTX);
419     if (input != NULL) {
420         if (input->valueType != BSL_PARAM_TYPE_CTX_PTR || input->value == NULL) {
421             return CRYPT_INVALID_ARG;
422         }
423         decoderCtx->provMgrCtx = (CRYPT_EAL_ProvMgrCtx *)(uintptr_t)input->value;
424     }
425 
426     return CRYPT_SUCCESS;
427 }
428 
429 #define BSL_ASN1_TAG_NEW_ALG_PRIKEY_PARAM 0
430 
431 static BSL_ASN1_TemplateItem g_newAlgPrvTempl[] = {
432     {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0},  // ignore seq header
433         {BSL_ASN1_TAG_INTEGER, 0, 1}, /* version */
434         {BSL_ASN1_TAG_OCTETSTRING, 0, 1}, /* private key */
435         {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_NEW_ALG_PRIKEY_PARAM,
436             BSL_ASN1_FLAG_OPTIONAL, 1},
437             {BSL_ASN1_TAG_OBJECT_ID, 0, 2},
438         {BSL_ASN1_TAG_OCTETSTRING, 0, 1}, /* private key */
439 };
440 
441 typedef enum {
442     CRYPT_NEW_ALG_PRV_VERSION_IDX = 0,
443     CRYPT_NEW_ALG_PRV_PRVKEY_IDX = 1,
444     CRYPT_NEW_ALG_PRV_PRIKEY_PARAM_IDX = 2,
445     CRYPT_NEW_ALG_PRV_PUBKEY_IDX = 3,
446 } CRYPT_NEW_ALG_PRV_TEMPL_IDX;
447 
GetParaId(uint8_t * octs,uint32_t octsLen)448 static int32_t GetParaId(uint8_t *octs, uint32_t octsLen)
449 {
450     BslOidString oidStr = {octsLen, (char *)octs, 0};
451     BslCid cid = BSL_OBJ_GetCID(&oidStr);
452     if (cid == BSL_CID_UNKNOWN) {
453         return CRYPT_PKEY_PARAID_MAX;
454     }
455     return (int32_t)cid;
456 }
457 
ProcNewAlgKeyPair(uint8_t * buff,uint32_t buffLen,TestNewKeyCtx * newAlgKey)458 static int32_t ProcNewAlgKeyPair(uint8_t *buff, uint32_t buffLen, TestNewKeyCtx *newAlgKey)
459 {
460     // decode n and e
461     BSL_ASN1_Buffer asn1[CRYPT_NEW_ALG_PRV_PUBKEY_IDX + 1] = {0};
462     uint8_t *tmpBuff = buff;
463     uint32_t tmpBuffLen = buffLen;
464     BSL_ASN1_Template templ = {g_newAlgPrvTempl, sizeof(g_newAlgPrvTempl) / sizeof(g_newAlgPrvTempl[0])};
465     int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &tmpBuff, &tmpBuffLen, asn1,
466         CRYPT_NEW_ALG_PRV_PUBKEY_IDX + 1);
467     if (ret != CRYPT_SUCCESS) {
468         return ret;
469     }
470 
471     const BSL_Param param1[2] = {
472         {CRYPT_PARAM_NEW_KEY_PRVKEY, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_NEW_ALG_PRV_PRVKEY_IDX].buff,
473             asn1[CRYPT_NEW_ALG_PRV_PRVKEY_IDX].len, 0},
474         BSL_PARAM_END
475     };
476     ret = TestNewKeySetPrvKey(newAlgKey, param1);
477     if (ret != CRYPT_SUCCESS) {
478         return ret;
479     }
480     const BSL_Param param2[2] = {
481         {CRYPT_PARAM_NEW_KEY_PUBKEY, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_NEW_ALG_PRV_PUBKEY_IDX].buff,
482             asn1[CRYPT_NEW_ALG_PRV_PUBKEY_IDX].len, 0},
483         BSL_PARAM_END
484     };
485     ret = TestNewKeySetPubKey(newAlgKey, param2);
486     if (ret != CRYPT_SUCCESS) {
487         return ret;
488     }
489     int32_t cid = GetParaId(asn1[CRYPT_NEW_ALG_PRV_PRIKEY_PARAM_IDX].buff, asn1[CRYPT_NEW_ALG_PRV_PRIKEY_PARAM_IDX].len);
490     if (cid != NEW_PARA_ALGID) {
491         return CRYPT_INVALID_ARG;
492     }
493 
494     BSL_Param param[2] = {
495         {CRYPT_PARAM_NEW_KEY_GROUP, BSL_PARAM_TYPE_INT32, &cid, sizeof(cid), 0},
496         BSL_PARAM_END
497     };
498     return TestNewKeySetPara(newAlgKey, param);
499 }
500 
CRYPT_NewAlg_ParsePrikeyAsn1Buff(uint8_t * buffer,uint32_t bufferLen,void ** newAlgPriKey)501 static int32_t CRYPT_NewAlg_ParsePrikeyAsn1Buff(uint8_t *buffer, uint32_t bufferLen, void **newAlgPriKey)
502 {
503     if (buffer == NULL || bufferLen == 0 || newAlgPriKey == NULL) {
504         return CRYPT_NULL_INPUT;
505     }
506     TestNewKeyCtx *key = TestNewKeyMgmtNewCtx(NULL, NEW_PKEY_ALGID);
507     if (key == NULL) {
508         return CRYPT_MEM_ALLOC_FAIL;
509     }
510     int32_t ret = ProcNewAlgKeyPair(buffer, bufferLen, key);
511     if (ret != CRYPT_SUCCESS) {
512         TestNewKeyFreeCtx(key);
513         return ret;
514     }
515     *newAlgPriKey = key;
516     return CRYPT_SUCCESS;
517 }
518 
ConstructOutputParams(TestNewAlgDer2KeyCtx * decoderCtx,void * key,BSL_Param ** outParam)519 static int32_t ConstructOutputParams(TestNewAlgDer2KeyCtx *decoderCtx, void *key, BSL_Param **outParam)
520 {
521     BSL_Param *result = calloc(7, sizeof(BSL_Param));
522     if (result == NULL) {
523         return CRYPT_MEM_ALLOC_FAIL;
524     }
525     int32_t ret = TestParamInitValue(&result[0], CRYPT_PARAM_DECODE_OBJECT_DATA, BSL_PARAM_TYPE_CTX_PTR, key, 0);
526     if (ret != CRYPT_SUCCESS) {
527         goto EXIT;
528     }
529     ret = TestParamInitValue(&result[1], CRYPT_PARAM_DECODE_OBJECT_TYPE, BSL_PARAM_TYPE_INT32, &decoderCtx->keyAlgId,
530         sizeof(decoderCtx->outType));
531     if (ret != CRYPT_SUCCESS) {
532         goto EXIT;
533     }
534     ret = TestParamInitValue(&result[2], CRYPT_PARAM_DECODE_PKEY_EXPORT_METHOD_FUNC, BSL_PARAM_TYPE_FUNC_PTR,
535         TestNewKeyExport, 0);
536     if (ret != CRYPT_SUCCESS) {
537         goto EXIT;
538     }
539     ret = TestParamInitValue(&result[3], CRYPT_PARAM_DECODE_PKEY_FREE_METHOD_FUNC, BSL_PARAM_TYPE_FUNC_PTR,
540         TestNewKeyFreeCtx, 0);
541     if (ret != CRYPT_SUCCESS) {
542         goto EXIT;
543     }
544     ret = TestParamInitValue(&result[4], CRYPT_PARAM_DECODE_PKEY_DUP_METHOD_FUNC, BSL_PARAM_TYPE_FUNC_PTR,
545         TestNewKeyDupCtx, 0);
546     if (ret != CRYPT_SUCCESS) {
547         goto EXIT;
548     }
549     ret = TestParamInitValue(&result[5], CRYPT_PARAM_DECODE_PROVIDER_CTX, BSL_PARAM_TYPE_CTX_PTR,
550         decoderCtx->provMgrCtx, 0);
551     if (ret != CRYPT_SUCCESS) {
552         goto EXIT;
553     }
554     *outParam = result;
555     return CRYPT_SUCCESS;
556 EXIT:
557     TestNewKeyFreeCtx(key);
558     free(result);
559     return ret;
560 }
561 
DECODER_NewAlgDer2Key_Decode(void * ctx,const BSL_Param * inParam,BSL_Param ** outParam)562 static int32_t DECODER_NewAlgDer2Key_Decode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam)
563 {
564     if (ctx == NULL || inParam == NULL || outParam == NULL) {
565         return CRYPT_NULL_INPUT;
566     }
567     void *key = NULL;
568     TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
569     const BSL_Param *input = TestFindConstParam(inParam, CRYPT_PARAM_DECODE_BUFFER_DATA);
570     if (input == NULL) {
571         return CRYPT_NULL_INPUT;
572     }
573     if (input->value == NULL || input->valueLen == 0 || input->valueType != BSL_PARAM_TYPE_OCTETS) {
574         return CRYPT_INVALID_ARG;
575     }
576 
577     int32_t ret = CRYPT_NewAlg_ParsePrikeyAsn1Buff(input->value, input->valueLen, &key);
578     if (ret != CRYPT_SUCCESS) {
579         return ret;
580     }
581     return ConstructOutputParams(decoderCtx, key, outParam);
582 }
583 
NewAlgKeySubKeyInfoCb(int32_t type,uint32_t idx,void * data,void * expVal)584 static int32_t NewAlgKeySubKeyInfoCb(int32_t type, uint32_t idx, void *data, void *expVal)
585 {
586     (void)idx;
587     BSL_ASN1_Buffer *param = (BSL_ASN1_Buffer *)data;
588 
589     switch (type) {
590         case BSL_ASN1_TYPE_GET_ANY_TAG: {
591             BslOidString oidStr = {param->len, (char *)param->buff, 0};
592             BslCid cid = BSL_OBJ_GetCID(&oidStr);
593             if (cid == NEW_PKEY_ALGID) {
594                 // note: any It can be encoded empty or it can be null
595                 *(uint8_t *)expVal = BSL_ASN1_TAG_OBJECT_ID;
596             } else {
597                 *(uint8_t *)expVal = BSL_ASN1_TAG_NULL; // is null
598             }
599             return CRYPT_SUCCESS;
600         }
601         default:
602             break;
603     }
604     return CRYPT_DECODE_ASN1_BUFF_FAILED;
605 }
606 
DECODER_NewAlgSubPubKeyDer2Key_Decode(void * ctx,const BSL_Param * inParam,BSL_Param ** outParam)607 static int32_t DECODER_NewAlgSubPubKeyDer2Key_Decode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam)
608 {
609     if (ctx == NULL || inParam == NULL || outParam == NULL) {
610         return CRYPT_NULL_INPUT;
611     }
612     TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
613     CRYPT_DECODE_SubPubkeyInfo subKeyInfo = {0};
614     const BSL_Param *input = TestFindConstParam(inParam, CRYPT_PARAM_DECODE_BUFFER_DATA);
615     if (input == NULL) {
616         return CRYPT_NULL_INPUT;
617     }
618     if (input->value == NULL || input->valueLen == 0 || input->valueType != BSL_PARAM_TYPE_OCTETS) {
619         return CRYPT_INVALID_ARG;
620     }
621     int32_t ret = CRYPT_DECODE_SubPubkey((uint8_t *)input->value, input->valueLen, NewAlgKeySubKeyInfoCb, &subKeyInfo, false);
622     if (ret != CRYPT_SUCCESS) {
623         return ret;
624     }
625     if (subKeyInfo.keyType != NEW_PKEY_ALGID) {
626         return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
627     }
628 
629     TestNewKeyCtx *newAlgKey = TestNewKeyMgmtNewCtx(NULL, NEW_PKEY_ALGID);
630     if (newAlgKey == NULL) {
631         ret = CRYPT_MEM_ALLOC_FAIL;
632         goto EXIT;
633     }
634     int32_t cid = GetParaId(subKeyInfo.keyParam.buff, subKeyInfo.keyParam.len);
635     if (cid != NEW_PARA_ALGID) {
636         ret = CRYPT_INVALID_ARG;
637         goto EXIT;
638     }
639     const BSL_Param param2[2] = {
640         {CRYPT_PARAM_NEW_KEY_PUBKEY, BSL_PARAM_TYPE_OCTETS, subKeyInfo.pubKey.buff,
641             subKeyInfo.pubKey.len, 0},
642         BSL_PARAM_END
643     };
644     ret = TestNewKeySetPubKey(newAlgKey, param2);
645     if (ret != CRYPT_SUCCESS) {
646         goto EXIT;
647     }
648     ret = ConstructOutputParams(decoderCtx, newAlgKey, outParam);
649     if (ret != CRYPT_SUCCESS) {
650         goto EXIT;
651     }
652     return CRYPT_SUCCESS;
653 EXIT:
654     TestNewKeyFreeCtx(newAlgKey);
655     return ret;
656 }
657 
DECODER_NewAlgDer2Key_FreeOutData(void * ctx,BSL_Param * outData)658 static void DECODER_NewAlgDer2Key_FreeOutData(void *ctx, BSL_Param *outData)
659 {
660     TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
661     if (decoderCtx == NULL || outData == NULL) {
662         return;
663     }
664     BSL_Param *outKey = TestFindParam(outData, CRYPT_PARAM_DECODE_OBJECT_DATA);
665     if (outKey == NULL) {
666         return;
667     }
668     TestNewKeyFreeCtx(outKey->value);
669     BSL_SAL_Free(outData);
670 }
671 
DECODER_NewAlgDer2Key_FreeCtx(void * ctx)672 static void DECODER_NewAlgDer2Key_FreeCtx(void *ctx)
673 {
674     if (ctx == NULL) {
675         return;
676     }
677     TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
678     free(decoderCtx);
679 }
680 
681 static const CRYPT_EAL_Func g_testDer2NewAlgKey[] = {
682     {CRYPT_DECODER_IMPL_NEWCTX, (CRYPT_DECODER_IMPL_NewCtx)DECODER_NewAlgDer2Key_NewCtx},
683     {CRYPT_DECODER_IMPL_GETPARAM, (CRYPT_DECODER_IMPL_GetParam)DECODER_NewAlgDer2Key_GetParam},
684     {CRYPT_DECODER_IMPL_SETPARAM, (CRYPT_DECODER_IMPL_SetParam)DECODER_NewAlgDer2Key_SetParam},
685     {CRYPT_DECODER_IMPL_DECODE, (CRYPT_DECODER_IMPL_Decode)DECODER_NewAlgDer2Key_Decode},
686     {CRYPT_DECODER_IMPL_FREEOUTDATA, (CRYPT_DECODER_IMPL_FreeOutData)DECODER_NewAlgDer2Key_FreeOutData},
687     {CRYPT_DECODER_IMPL_FREECTX, (CRYPT_DECODER_IMPL_FreeCtx)DECODER_NewAlgDer2Key_FreeCtx},
688     CRYPT_EAL_FUNC_END
689 };
690 
691 static const CRYPT_EAL_Func g_testSubPubKeyDer2NewAlgKey[] = {
692     {CRYPT_DECODER_IMPL_NEWCTX, (CRYPT_DECODER_IMPL_NewCtx)DECODER_NewAlgDer2Key_NewCtx},
693     {CRYPT_DECODER_IMPL_GETPARAM, (CRYPT_DECODER_IMPL_GetParam)DECODER_NewAlgDer2Key_GetParam},
694     {CRYPT_DECODER_IMPL_SETPARAM, (CRYPT_DECODER_IMPL_SetParam)DECODER_NewAlgDer2Key_SetParam},
695     {CRYPT_DECODER_IMPL_DECODE, (CRYPT_DECODER_IMPL_Decode)DECODER_NewAlgSubPubKeyDer2Key_Decode},
696     {CRYPT_DECODER_IMPL_FREEOUTDATA, (CRYPT_DECODER_IMPL_FreeOutData)DECODER_NewAlgDer2Key_FreeOutData},
697     {CRYPT_DECODER_IMPL_FREECTX, (CRYPT_DECODER_IMPL_FreeCtx)DECODER_NewAlgDer2Key_FreeCtx},
698     CRYPT_EAL_FUNC_END
699 };
700 
701 static CRYPT_EAL_AlgInfo g_testDecoder[] = {
702     {NEW_PKEY_ALGID, g_testDer2NewAlgKey, "provider=provider_new_alg_test, inFormat=ASN1, inType=CRYPT_PKEY_NEW_ALG, outFormat=OBJECT, outType=LOW_KEY"},
703     {NEW_PKEY_ALGID, g_testSubPubKeyDer2NewAlgKey, "provider=provider_new_alg_test, inFormat=ASN1, inType=PUBKEY_SUBKEY_WITHOUT_SEQ, outFormat=OBJECT, outType=LOW_KEY"},
704     CRYPT_EAL_ALGINFO_END
705 };
706 
TestProvQuery(void * provCtx,int32_t operaId,CRYPT_EAL_AlgInfo ** algInfos)707 static int32_t TestProvQuery(void *provCtx, int32_t operaId, CRYPT_EAL_AlgInfo **algInfos)
708 {
709     (void)provCtx;
710     int32_t ret = CRYPT_SUCCESS;
711     switch (operaId) {
712         case CRYPT_EAL_OPERAID_KEYMGMT:
713             *algInfos = g_testKeyMgmt;
714             break;
715         case CRYPT_EAL_OPERAID_SIGN:
716             *algInfos = g_testSign;
717             break;
718         case CRYPT_EAL_OPERAID_KEYEXCH:
719             *algInfos = g_testKeyExch;
720             break;
721         case CRYPT_EAL_OPERAID_DECODER:
722             *algInfos = g_testDecoder;
723             break;
724         default:
725             return CRYPT_NOT_SUPPORT;
726     }
727     return CRYPT_SUCCESS;
728 }
729 
TestProvFree(void * provCtx)730 static int32_t TestProvFree(void *provCtx)
731 {
732     if (provCtx != NULL) {
733         free(provCtx);
734     }
735     return CRYPT_SUCCESS;
736 }
737 
738 static const Provider_Group g_tlsGroupInfo[] = {
739     {
740         "test_new_group_with_new_key_type",
741         NEW_PARA_ALGID,      // paraId
742         NEW_PKEY_ALGID,      // algId
743         1024,                // secBits
744         479,                 // groupId
745         143,                 // pubkeyLen
746         143,                 // sharedkeyLen
747         0,                   // ciphertextLen
748         TLS12_VERSION_BIT | TLS13_VERSION_BIT,  // versionBits
749         false               // isKem
750     }
751 };
752 
TestCryptGetSigAlgCaps(CRYPT_EAL_ProcessFuncCb cb,void * args)753 static int32_t TestCryptGetSigAlgCaps(CRYPT_EAL_ProcessFuncCb cb, void *args)
754 {
755     if (cb == NULL) {
756         return CRYPT_NULL_INPUT;
757     }
758     uint16_t signatureScheme = 24444;
759     int32_t keyType = NEW_PKEY_ALGID;
760     int32_t paraId = NEW_PARA_ALGID;
761     int32_t signHashAlgId = NEW_SIGN_HASH_ALGID;
762     int32_t signAlgId = NEW_PKEY_ALGID;
763     int32_t hashAlgId = NEW_HASH_ALGID;
764     int32_t secBits = 1024;
765     uint32_t certVersionBits = TLS12_VERSION_BIT | TLS13_VERSION_BIT;
766     uint32_t chainVersionBits = TLS12_VERSION_BIT | TLS13_VERSION_BIT;
767     BSL_Param param[] = {
768         {
769             CRYPT_PARAM_CAP_TLS_SIGNALG_IANA_SIGN_NAME,
770             BSL_PARAM_TYPE_OCTETS_PTR,
771             (void *)(uintptr_t)"test_new_sign_alg_name_with_new_key_type",
772             (uint32_t)strlen("test_new_sign_alg_name_with_new_key_type")
773         },
774         {
775             CRYPT_PARAM_CAP_TLS_SIGNALG_IANA_SIGN_ID,
776             BSL_PARAM_TYPE_UINT16,
777             (void *)(uintptr_t)&(signatureScheme),
778             sizeof(uint16_t)
779         },
780         {
781             CRYPT_PARAM_CAP_TLS_SIGNALG_KEY_TYPE,
782             BSL_PARAM_TYPE_INT32,
783             (void *)(uintptr_t)&(keyType),
784             sizeof(keyType)
785         },
786         {
787             CRYPT_PARAM_CAP_TLS_SIGNALG_KEY_TYPE_OID,
788             BSL_PARAM_TYPE_OCTETS_PTR,
789             (void *)(uintptr_t)"\150\40\66\77\57", // 68 20 36 3F 2F
790             (uint32_t)strlen("\150\40\66\77\57")
791         },
792         {
793             CRYPT_PARAM_CAP_TLS_SIGNALG_KEY_TYPE_NAME,
794             BSL_PARAM_TYPE_OCTETS_PTR,
795             (void *)(uintptr_t)"test_new_key_type",
796             (uint32_t)strlen("test_new_key_type")
797         },
798         {
799             CRYPT_PARAM_CAP_TLS_SIGNALG_PARA_ID,
800             BSL_PARAM_TYPE_INT32,
801             (void *)(uintptr_t)&(paraId),
802             sizeof(paraId)
803         },
804         {
805             CRYPT_PARAM_CAP_TLS_SIGNALG_PARA_OID,
806             BSL_PARAM_TYPE_OCTETS_PTR,
807             (void *)(uintptr_t)"\150\40\66\77\56", // 68 20 36 3F 2E
808             (uint32_t)strlen("\150\40\66\77\56")
809         },
810         {
811             CRYPT_PARAM_CAP_TLS_SIGNALG_PARA_NAME,
812             BSL_PARAM_TYPE_OCTETS_PTR,
813             (void *)(uintptr_t)"test_new_para_name",
814             (uint32_t)strlen("test_new_para_name")
815         },
816         {
817             CRYPT_PARAM_CAP_TLS_SIGNALG_SIGNWITHMD_ID,
818             BSL_PARAM_TYPE_INT32,
819             (void *)(uintptr_t)&(signHashAlgId),
820             sizeof(signHashAlgId)
821         },
822         {
823             CRYPT_PARAM_CAP_TLS_SIGNALG_SIGNWITHMD_OID,
824             BSL_PARAM_TYPE_OCTETS_PTR,
825             (void *)(uintptr_t)"\150\40\66\77\55", // 68 20 36 3F 2D
826             (uint32_t)strlen("\150\40\66\77\55")
827         },
828         {
829             CRYPT_PARAM_CAP_TLS_SIGNALG_SIGNWITHMD_NAME,
830             BSL_PARAM_TYPE_OCTETS_PTR,
831             (void *)(uintptr_t)"test_new_sign_with_md_name",
832             (uint32_t)strlen("test_new_sign_with_md_name")
833         },
834         {
835             CRYPT_PARAM_CAP_TLS_SIGNALG_SIGN_ID,
836             BSL_PARAM_TYPE_INT32,
837             (void *)(uintptr_t)&(signAlgId),
838             sizeof(signAlgId)
839         },
840         {
841             CRYPT_PARAM_CAP_TLS_SIGNALG_MD_ID,
842             BSL_PARAM_TYPE_INT32,
843             (void *)(uintptr_t)&(hashAlgId),
844             sizeof(hashAlgId)
845         },
846         {
847             CRYPT_PARAM_CAP_TLS_SIGNALG_MD_OID,
848             BSL_PARAM_TYPE_OCTETS_PTR,
849             (void *)(uintptr_t)"\150\40\66\71\65",  // 68 20 36 3F 35
850             (uint32_t)strlen("\150\40\66\71\65")
851         },
852         {
853             CRYPT_PARAM_CAP_TLS_SIGNALG_MD_NAME,
854             BSL_PARAM_TYPE_OCTETS_PTR,
855             (void *)(uintptr_t)"test_new_md_name",
856             (uint32_t)strlen("test_new_md_name")
857         },
858         {
859             CRYPT_PARAM_CAP_TLS_SIGNALG_SEC_BITS,
860             BSL_PARAM_TYPE_INT32,
861             (void *)(uintptr_t)&(secBits),
862             sizeof(secBits)
863         },
864         {
865             CRYPT_PARAM_CAP_TLS_SIGNALG_CHAIN_VERSION_BITS,
866             BSL_PARAM_TYPE_UINT32,
867             (void *)(uintptr_t)&(chainVersionBits),
868             sizeof(chainVersionBits)
869         },
870         {
871             CRYPT_PARAM_CAP_TLS_SIGNALG_CERT_VERSION_BITS,
872             BSL_PARAM_TYPE_UINT32,
873             (void *)(uintptr_t)&(certVersionBits),
874             sizeof(certVersionBits)
875         }
876     };
877     return cb(param, args);
878 }
879 
TestProvGetCaps(void * provCtx,int32_t cmd,CRYPT_EAL_ProcessFuncCb cb,void * args)880 static int32_t TestProvGetCaps(void *provCtx, int32_t cmd, CRYPT_EAL_ProcessFuncCb cb, void *args)
881 {
882     switch (cmd) {
883         case CRYPT_EAL_GET_GROUP_CAP:
884             return TestCryptGetGroupCaps(g_tlsGroupInfo, sizeof(g_tlsGroupInfo) / sizeof(g_tlsGroupInfo[0]), cb, args);
885         case CRYPT_EAL_GET_SIGALG_CAP:
886             return TestCryptGetSigAlgCaps(cb, args);
887         default:
888             return CRYPT_NOT_SUPPORT;
889     }
890 }
891 
892 static CRYPT_EAL_Func g_testProvOutFuncs[] = {
893     {CRYPT_EAL_PROVCB_QUERY, TestProvQuery},
894     {CRYPT_EAL_PROVCB_FREE, TestProvFree},
895     {CRYPT_EAL_PROVCB_CTRL, NULL},
896     {CRYPT_EAL_PROVCB_GETCAPS, TestProvGetCaps},
897     CRYPT_EAL_FUNC_END
898 };
899 
CRYPT_EAL_ProviderInit(CRYPT_EAL_ProvMgrCtx * mgrCtx,BSL_Param * param,CRYPT_EAL_Func * capFuncs,CRYPT_EAL_Func ** outFuncs,void ** provCtx)900 int32_t CRYPT_EAL_ProviderInit(CRYPT_EAL_ProvMgrCtx *mgrCtx, BSL_Param *param,
901                               CRYPT_EAL_Func *capFuncs, CRYPT_EAL_Func **outFuncs,
902                               void **provCtx)
903 {
904     if (mgrCtx == NULL || capFuncs == NULL || outFuncs == NULL || provCtx == NULL) {
905         return CRYPT_NULL_INPUT;
906     }
907 
908     TestProvCtx *ctx = malloc(sizeof(TestProvCtx));
909     if (ctx == NULL) {
910         return CRYPT_MEM_ALLOC_FAIL;
911     }
912 
913     ctx->mgrCtxHandle = mgrCtx;
914     *provCtx = ctx;
915     *outFuncs = g_testProvOutFuncs;
916 
917     return CRYPT_SUCCESS;
918 }
919