• 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 "hitls_build.h"
17 #ifdef HITLS_CRYPTO_KEY_DECODE
18 
19 #include "crypt_ecc.h"
20 #ifdef HITLS_CRYPTO_ECDSA
21 #include "crypt_ecdsa.h"
22 #endif
23 #ifdef HITLS_CRYPTO_SM2
24 #include "crypt_sm2.h"
25 #endif
26 #ifdef HITLS_CRYPTO_ED25519
27 #include "crypt_curve25519.h"
28 #endif
29 #include "crypt_params_key.h"
30 #include "bsl_asn1.h"
31 #include "bsl_params.h"
32 #include "bsl_obj_internal.h"
33 #include "bsl_err_internal.h"
34 #include "crypt_errno.h"
35 #include "crypt_encode_decode_local.h"
36 #include "crypt_encode_decode_key.h"
37 
38 #if defined(HITLS_CRYPTO_ECDSA) || defined(HITLS_CRYPTO_SM2)
39 typedef struct {
40     int32_t version;
41     BSL_ASN1_Buffer param;
42     BSL_ASN1_Buffer prikey;
43     BSL_ASN1_Buffer pubkey;
44 } CRYPT_DECODE_EccPrikeyInfo;
45 
GetParaId(uint8_t * octs,uint32_t octsLen)46 static int32_t GetParaId(uint8_t *octs, uint32_t octsLen)
47 {
48     BslOidString oidStr = {octsLen, (char *)octs, 0};
49     BslCid cid = BSL_OBJ_GetCID(&oidStr);
50     if (cid == BSL_CID_UNKNOWN) {
51         BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID);
52         return CRYPT_PKEY_PARAID_MAX;
53     }
54     return (int32_t)cid;
55 }
56 
ParsePrikeyAsn1Info(uint8_t * buff,uint32_t buffLen,BSL_ASN1_Buffer * pk8AlgoParam,CRYPT_DECODE_EccPrikeyInfo * eccPrvInfo)57 static int32_t ParsePrikeyAsn1Info(uint8_t *buff, uint32_t buffLen, BSL_ASN1_Buffer *pk8AlgoParam,
58     CRYPT_DECODE_EccPrikeyInfo *eccPrvInfo)
59 {
60     BSL_ASN1_Buffer asn1[CRYPT_ECPRIKEY_PUBKEY_IDX + 1] = {0};
61     int32_t ret = CRYPT_DECODE_PrikeyAsn1Buff(buff, buffLen, asn1, CRYPT_ECPRIKEY_PUBKEY_IDX + 1);
62     if (ret != CRYPT_SUCCESS) {
63         BSL_ERR_PUSH_ERROR(ret);
64         return ret;
65     }
66     int32_t version;
67     BSL_ASN1_Buffer *prikey = &asn1[CRYPT_ECPRIKEY_PRIKEY_IDX]; // the ECC OID
68     BSL_ASN1_Buffer *ecParamOid = &asn1[CRYPT_ECPRIKEY_PARAM_IDX]; // the parameters OID
69     BSL_ASN1_Buffer *pubkey = &asn1[CRYPT_ECPRIKEY_PUBKEY_IDX]; // the ECC OID
70     BSL_ASN1_Buffer *param = pk8AlgoParam;
71     if (ecParamOid->len != 0) {
72         // has a valid Algorithm param
73         param = ecParamOid;
74     } else {
75         if (param == NULL) {
76             BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
77             return CRYPT_NULL_INPUT;
78         }
79         if (param->len == 0) {
80             BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PKCS8_INVALID_ALGO_PARAM);
81             return CRYPT_DECODE_PKCS8_INVALID_ALGO_PARAM;
82         }
83     }
84     if (pubkey->len == 0) {
85         BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ASN1_BUFF_FAILED);
86         return CRYPT_DECODE_ASN1_BUFF_FAILED;
87     }
88 
89     ret = BSL_ASN1_DecodePrimitiveItem(&asn1[CRYPT_ECPRIKEY_VERSION_IDX], &version);
90     if (ret != CRYPT_SUCCESS) {
91         BSL_ERR_PUSH_ERROR(ret);
92         return ret;
93     }
94     eccPrvInfo->version = version;
95     eccPrvInfo->param = *param;
96     eccPrvInfo->prikey = *prikey;
97     eccPrvInfo->pubkey = *pubkey;
98     return CRYPT_SUCCESS;
99 }
100 
101 #endif // HITLS_CRYPTO_ECDSA || HITLS_CRYPTO_SM2
102 
103 #ifdef HITLS_CRYPTO_ECDSA
104 // ecdh is not considered, and it will be improved in the future
EccKeyNew(BSL_ASN1_Buffer * ecParamOid,void ** ecKey)105 static int32_t EccKeyNew(BSL_ASN1_Buffer *ecParamOid, void **ecKey)
106 {
107     int32_t paraId = GetParaId(ecParamOid->buff, ecParamOid->len);
108     if (!IsEcdsaEcParaId(paraId)) {
109         return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
110     }
111     CRYPT_ECDSA_Ctx *key = CRYPT_ECDSA_NewCtx();
112     if (key == NULL) {
113         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
114         return CRYPT_MEM_ALLOC_FAIL;
115     }
116 
117     int32_t ret = ECC_SetPara(key, ECC_NewPara(paraId));
118     if (ret != CRYPT_SUCCESS) {
119         ECC_FreeCtx(key);
120         BSL_ERR_PUSH_ERROR(ret);
121         return ret;
122     }
123     *ecKey = (void *)key;
124     return CRYPT_SUCCESS;
125 }
126 
CRYPT_ECC_ParseSubPubkeyAsn1Buff(uint8_t * buff,uint32_t buffLen,void ** pubKey,bool isComplete)127 int32_t CRYPT_ECC_ParseSubPubkeyAsn1Buff(uint8_t *buff, uint32_t buffLen, void **pubKey, bool isComplete)
128 {
129     if (buff == NULL || buffLen == 0 || pubKey == NULL) {
130         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
131         return CRYPT_NULL_INPUT;
132     }
133     CRYPT_DECODE_SubPubkeyInfo subPubkeyInfo = {0};
134     void *pctx = NULL;
135     int32_t ret = CRYPT_DECODE_SubPubkey(buff, buffLen, NULL, &subPubkeyInfo, isComplete);
136     if (ret != CRYPT_SUCCESS) {
137         BSL_ERR_PUSH_ERROR(ret);
138         return ret;
139     }
140     if (subPubkeyInfo.keyType != BSL_CID_EC_PUBLICKEY) {
141         BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH);
142         return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
143     }
144     ret = EccKeyNew(&subPubkeyInfo.keyParam, &pctx);
145     if (ret != CRYPT_SUCCESS) {
146         BSL_ERR_PUSH_ERROR(ret);
147         return ret;
148     }
149     BSL_Param pubParam[2] = {
150         {CRYPT_PARAM_EC_PUBKEY, BSL_PARAM_TYPE_OCTETS, subPubkeyInfo.pubKey.buff,
151             subPubkeyInfo.pubKey.len, 0},
152         BSL_PARAM_END
153     };
154     ret = ECC_PkeySetPubKey(pctx, pubParam);
155     if (ret != CRYPT_SUCCESS) {
156         BSL_ERR_PUSH_ERROR(ret);
157         ECC_FreeCtx(pctx);
158         return ret;
159     }
160     *pubKey = (void *)pctx;
161     return ret;
162 }
163 
CRYPT_ECC_ParsePrikeyAsn1Buff(uint8_t * buffer,uint32_t bufferLen,BSL_ASN1_Buffer * pk8AlgoParam,void ** ecPriKey)164 int32_t CRYPT_ECC_ParsePrikeyAsn1Buff(uint8_t *buffer, uint32_t bufferLen, BSL_ASN1_Buffer *pk8AlgoParam,
165     void **ecPriKey)
166 {
167     if (buffer == NULL || bufferLen == 0 || ecPriKey == NULL) {
168         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
169         return CRYPT_NULL_INPUT;
170     }
171 
172     CRYPT_DECODE_EccPrikeyInfo eccPrvInfo = {0};
173     int32_t ret = ParsePrikeyAsn1Info(buffer, bufferLen, pk8AlgoParam, &eccPrvInfo);
174     if (ret != CRYPT_SUCCESS) {
175         BSL_ERR_PUSH_ERROR(ret);
176         return ret;
177     }
178     void *pctx = NULL;
179     ret = EccKeyNew(&eccPrvInfo.param, &pctx);
180     if (ret != CRYPT_SUCCESS) {
181         BSL_ERR_PUSH_ERROR(ret);
182         return ret;
183     }
184     BSL_Param pubParam[2] = {
185         {CRYPT_PARAM_EC_PUBKEY, BSL_PARAM_TYPE_OCTETS, (eccPrvInfo.pubkey.buff + 1),
186             eccPrvInfo.pubkey.len - 1, 0},
187         BSL_PARAM_END
188     };
189     ret = ECC_PkeySetPubKey(pctx, pubParam);
190     if (ret != CRYPT_SUCCESS) {
191         BSL_ERR_PUSH_ERROR(ret);
192         goto ERR;
193     }
194     BSL_Param prvParam[2] = {
195         {CRYPT_PARAM_EC_PRVKEY, BSL_PARAM_TYPE_OCTETS, eccPrvInfo.prikey.buff, eccPrvInfo.prikey.len, 0},
196         BSL_PARAM_END
197     };
198     ret = ECC_PkeySetPrvKey(pctx, prvParam);
199     if (ret != CRYPT_SUCCESS) {
200         BSL_ERR_PUSH_ERROR(ret);
201         goto ERR;
202     }
203     *ecPriKey = pctx;
204     return ret;
205 ERR:
206     ECC_FreeCtx(pctx);
207     return ret;
208 }
209 
CRYPT_ECC_ParsePkcs8Key(uint8_t * buff,uint32_t buffLen,void ** ecdsaPriKey)210 int32_t CRYPT_ECC_ParsePkcs8Key(uint8_t *buff, uint32_t buffLen, void **ecdsaPriKey)
211 {
212     CRYPT_ENCODE_DECODE_Pk8PrikeyInfo pk8PrikeyInfo = {0};
213     int32_t ret = CRYPT_DECODE_Pkcs8Info(buff, buffLen, NULL, &pk8PrikeyInfo);
214     if (ret != CRYPT_SUCCESS) {
215         BSL_ERR_PUSH_ERROR(ret);
216         return ret;
217     }
218     if (pk8PrikeyInfo.keyType != BSL_CID_EC_PUBLICKEY) {
219         BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH);
220         return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
221     }
222     ret = CRYPT_ECC_ParsePrikeyAsn1Buff(pk8PrikeyInfo.pkeyRawKey, pk8PrikeyInfo.pkeyRawKeyLen, &pk8PrikeyInfo.keyParam,
223         ecdsaPriKey);
224     if (ret != CRYPT_SUCCESS) {
225         BSL_ERR_PUSH_ERROR(ret);
226     }
227     return ret;
228 }
229 #endif // HITLS_CRYPTO_ECDSA
230 #ifdef HITLS_CRYPTO_SM2
Sm2KeyNew(BSL_ASN1_Buffer * ecParamOid,CRYPT_SM2_Ctx ** ecKey)231 static int32_t Sm2KeyNew(BSL_ASN1_Buffer *ecParamOid, CRYPT_SM2_Ctx **ecKey)
232 {
233     CRYPT_SM2_Ctx *key = NULL;
234     int32_t paraId = GetParaId(ecParamOid->buff, ecParamOid->len);
235     if (paraId != CRYPT_ECC_SM2) {
236         return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
237     }
238     key = CRYPT_SM2_NewCtx();
239     if (key == NULL) {
240         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
241         return CRYPT_MEM_ALLOC_FAIL;
242     }
243     *ecKey = key;
244     return CRYPT_SUCCESS;
245 }
246 
CRYPT_SM2_ParseSubPubkeyAsn1Buff(uint8_t * buff,uint32_t buffLen,CRYPT_SM2_Ctx ** pubKey,bool isComplete)247 int32_t CRYPT_SM2_ParseSubPubkeyAsn1Buff(uint8_t *buff, uint32_t buffLen, CRYPT_SM2_Ctx **pubKey, bool isComplete)
248 {
249     if (buff == NULL || buffLen == 0 || pubKey == NULL) {
250         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
251         return CRYPT_NULL_INPUT;
252     }
253     CRYPT_DECODE_SubPubkeyInfo subPubkeyInfo = {0};
254     CRYPT_SM2_Ctx *pctx = NULL;
255     int32_t ret = CRYPT_DECODE_SubPubkey(buff, buffLen, NULL, &subPubkeyInfo, isComplete);
256     if (ret != CRYPT_SUCCESS) {
257         BSL_ERR_PUSH_ERROR(ret);
258         return ret;
259     }
260     if (subPubkeyInfo.keyType != BSL_CID_EC_PUBLICKEY && subPubkeyInfo.keyType != BSL_CID_SM2PRIME256) {
261         BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH);
262         return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
263     }
264     ret = Sm2KeyNew(&subPubkeyInfo.keyParam, &pctx);
265     if (ret != CRYPT_SUCCESS) {
266         BSL_ERR_PUSH_ERROR(ret);
267         return ret;
268     }
269     BSL_Param pubParam[2] = {
270         {CRYPT_PARAM_EC_PUBKEY, BSL_PARAM_TYPE_OCTETS, subPubkeyInfo.pubKey.buff,
271             subPubkeyInfo.pubKey.len, 0},
272         BSL_PARAM_END
273     };
274     ret = CRYPT_SM2_SetPubKey(pctx, pubParam);
275     if (ret != CRYPT_SUCCESS) {
276         BSL_ERR_PUSH_ERROR(ret);
277         CRYPT_SM2_FreeCtx(pctx);
278         return ret;
279     }
280     *pubKey = pctx;
281     return ret;
282 }
283 
CRYPT_SM2_ParsePrikeyAsn1Buff(uint8_t * buffer,uint32_t bufferLen,BSL_ASN1_Buffer * pk8AlgoParam,CRYPT_SM2_Ctx ** sm2PriKey)284 int32_t CRYPT_SM2_ParsePrikeyAsn1Buff(uint8_t *buffer, uint32_t bufferLen, BSL_ASN1_Buffer *pk8AlgoParam,
285     CRYPT_SM2_Ctx **sm2PriKey)
286 {
287     CRYPT_DECODE_EccPrikeyInfo eccPrvInfo = {0};
288     int32_t ret = ParsePrikeyAsn1Info(buffer, bufferLen, pk8AlgoParam, &eccPrvInfo);
289     if (ret != CRYPT_SUCCESS) {
290         BSL_ERR_PUSH_ERROR(ret);
291         return ret;
292     }
293     CRYPT_SM2_Ctx *pctx = NULL;
294     ret = Sm2KeyNew(&eccPrvInfo.param, &pctx);
295     if (ret != CRYPT_SUCCESS) {
296         BSL_ERR_PUSH_ERROR(ret);
297         return ret;
298     }
299     BSL_Param pubParam[2] = {
300         {CRYPT_PARAM_EC_PUBKEY, BSL_PARAM_TYPE_OCTETS, eccPrvInfo.pubkey.buff + 1,
301             eccPrvInfo.pubkey.len - 1, 0},
302         BSL_PARAM_END
303     };
304     ret = CRYPT_SM2_SetPubKey(pctx, pubParam);
305     if (ret != CRYPT_SUCCESS) {
306         BSL_ERR_PUSH_ERROR(ret);
307         goto ERR;
308     }
309     BSL_Param prvParam[2] = {
310         {CRYPT_PARAM_EC_PRVKEY, BSL_PARAM_TYPE_OCTETS, eccPrvInfo.prikey.buff, eccPrvInfo.prikey.len, 0},
311         BSL_PARAM_END
312     };
313     ret = CRYPT_SM2_SetPrvKey(pctx, prvParam);
314     if (ret != CRYPT_SUCCESS) {
315         BSL_ERR_PUSH_ERROR(ret);
316         goto ERR;
317     }
318     *sm2PriKey = pctx;
319     return ret;
320 ERR:
321     CRYPT_SM2_FreeCtx(pctx);
322     return ret;
323 }
324 
CRYPT_SM2_ParsePkcs8Key(uint8_t * buff,uint32_t buffLen,CRYPT_SM2_Ctx ** sm2PriKey)325 int32_t CRYPT_SM2_ParsePkcs8Key(uint8_t *buff, uint32_t buffLen, CRYPT_SM2_Ctx **sm2PriKey)
326 {
327     CRYPT_ENCODE_DECODE_Pk8PrikeyInfo pk8PrikeyInfo = {0};
328     int32_t ret = CRYPT_DECODE_Pkcs8Info(buff, buffLen, NULL, &pk8PrikeyInfo);
329     if (ret != CRYPT_SUCCESS) {
330         BSL_ERR_PUSH_ERROR(ret);
331         return ret;
332     }
333     if (pk8PrikeyInfo.keyType != BSL_CID_EC_PUBLICKEY) {
334         BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH);
335         return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
336     }
337     ret = CRYPT_SM2_ParsePrikeyAsn1Buff(pk8PrikeyInfo.pkeyRawKey, pk8PrikeyInfo.pkeyRawKeyLen, &pk8PrikeyInfo.keyParam,
338         sm2PriKey);
339     if (ret != CRYPT_SUCCESS) {
340         BSL_ERR_PUSH_ERROR(ret);
341     }
342     return ret;
343 }
344 #endif // HITLS_CRYPTO_SM2
345 
346 #ifdef HITLS_CRYPTO_ED25519
ParseEd25519PrikeyAsn1Buff(uint8_t * buffer,uint32_t bufferLen,CRYPT_CURVE25519_Ctx ** ed25519PriKey)347 static int32_t ParseEd25519PrikeyAsn1Buff(uint8_t *buffer, uint32_t bufferLen, CRYPT_CURVE25519_Ctx **ed25519PriKey)
348 {
349     uint8_t *tmpBuff = buffer;
350     uint32_t tmpBuffLen = bufferLen;
351 
352     int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_OCTETSTRING, &tmpBuff, &tmpBuffLen, &tmpBuffLen);
353     if (ret != BSL_SUCCESS) {
354         BSL_ERR_PUSH_ERROR(ret);
355         return ret;
356     }
357 
358     CRYPT_CURVE25519_Ctx *pctx = CRYPT_ED25519_NewCtx();
359     if (pctx == NULL) {
360         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
361         return CRYPT_MEM_ALLOC_FAIL;
362     }
363     BSL_Param prvParam[2] = {
364         {CRYPT_PARAM_CURVE25519_PRVKEY, BSL_PARAM_TYPE_OCTETS, tmpBuff, tmpBuffLen, 0},
365         BSL_PARAM_END
366     };
367     ret = CRYPT_CURVE25519_SetPrvKey(pctx, prvParam);
368     if (ret != CRYPT_SUCCESS) {
369         CRYPT_CURVE25519_FreeCtx(pctx);
370         BSL_ERR_PUSH_ERROR(ret);
371         return ret;
372     }
373     *ed25519PriKey = pctx;
374     return CRYPT_SUCCESS;
375 }
376 
CRYPT_ED25519_ParsePkcs8Key(uint8_t * buffer,uint32_t bufferLen,CRYPT_CURVE25519_Ctx ** ed25519PriKey)377 int32_t CRYPT_ED25519_ParsePkcs8Key(uint8_t *buffer, uint32_t bufferLen, CRYPT_CURVE25519_Ctx **ed25519PriKey)
378 {
379     CRYPT_ENCODE_DECODE_Pk8PrikeyInfo pk8PrikeyInfo = {0};
380     int32_t ret = CRYPT_DECODE_Pkcs8Info(buffer, bufferLen, NULL, &pk8PrikeyInfo);
381     if (ret != CRYPT_SUCCESS) {
382         BSL_ERR_PUSH_ERROR(ret);
383         return ret;
384     }
385     if (pk8PrikeyInfo.keyType != BSL_CID_ED25519) {
386         BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH);
387         return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
388     }
389     return ParseEd25519PrikeyAsn1Buff(pk8PrikeyInfo.pkeyRawKey, pk8PrikeyInfo.pkeyRawKeyLen, ed25519PriKey);
390 }
391 
CRYPT_ED25519_ParseSubPubkeyAsn1Buff(uint8_t * buff,uint32_t buffLen,CRYPT_CURVE25519_Ctx ** pubKey,bool isComplete)392 int32_t CRYPT_ED25519_ParseSubPubkeyAsn1Buff(uint8_t *buff, uint32_t buffLen, CRYPT_CURVE25519_Ctx **pubKey,
393     bool isComplete)
394 {
395     if (buff == NULL || buffLen == 0 || pubKey == NULL) {
396         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
397         return CRYPT_NULL_INPUT;
398     }
399     CRYPT_DECODE_SubPubkeyInfo subPubkeyInfo = {0};
400     int32_t ret = CRYPT_DECODE_SubPubkey(buff, buffLen, NULL, &subPubkeyInfo, isComplete);
401     if (ret != CRYPT_SUCCESS) {
402         BSL_ERR_PUSH_ERROR(ret);
403         return ret;
404     }
405     if (subPubkeyInfo.keyType != BSL_CID_ED25519) {
406         BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH);
407         return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
408     }
409     CRYPT_CURVE25519_Ctx *pctx = CRYPT_ED25519_NewCtx();
410     if (pctx == NULL) {
411         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
412         return CRYPT_MEM_ALLOC_FAIL;
413     }
414     BSL_Param pubParam[2] = {
415         {CRYPT_PARAM_CURVE25519_PUBKEY, BSL_PARAM_TYPE_OCTETS, subPubkeyInfo.pubKey.buff, subPubkeyInfo.pubKey.len, 0},
416         BSL_PARAM_END
417     };
418     ret = CRYPT_CURVE25519_SetPubKey(pctx, pubParam);
419     if (ret != CRYPT_SUCCESS) {
420         BSL_ERR_PUSH_ERROR(ret);
421         CRYPT_CURVE25519_FreeCtx(pctx);
422         return ret;
423     }
424     *pubKey = pctx;
425     return ret;
426 
427 }
428 #endif // HITLS_CRYPTO_ED25519
429 #endif // HITLS_CRYPTO_KEY_DECODE
430