• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21 
22 #include "hks_client_service_adapter.h"
23 
24 #include <openssl/bn.h>
25 #include <openssl/core_names.h>
26 #include <openssl/dh.h>
27 #include <openssl/dsa.h>
28 #include <openssl/ec.h>
29 #include <openssl/err.h>
30 #include <openssl/evp.h>
31 #include <openssl/obj_mac.h>
32 #include <openssl/ossl_typ.h>
33 #include <openssl/param_build.h>
34 #include "openssl/params.h"
35 #include <openssl/rsa.h>
36 #include <openssl/x509.h>
37 #include <stddef.h>
38 #include <stdint.h>
39 
40 #include "hks_crypto_hal.h"
41 #include "hks_log.h"
42 #include "hks_mem.h"
43 #include "hks_openssl_engine.h"
44 #include "hks_template.h"
45 #include "hks_type.h"
46 #include "securec.h"
47 
48 #if defined(HKS_SUPPORT_DSA_C)
49 typedef const BIGNUM* (*GetDsaInfoFunc)(const DSA *d);
50 #endif
51 
52 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C) || defined(HKS_SUPPORT_DSA_C) || \
53     defined(HKS_SUPPORT_DH_C) || defined(HKS_SUPPORT_SM2_C)
EvpKeyToX509Format(EVP_PKEY * pkey,struct HksBlob * x509Key)54 static int32_t EvpKeyToX509Format(EVP_PKEY *pkey, struct HksBlob *x509Key)
55 {
56     int32_t length = i2d_PUBKEY(pkey, NULL);
57     if (length <= 0 || length > MAX_OUT_BLOB_SIZE) {
58         HKS_LOG_E("i2d_PUBKEY error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
59         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
60     }
61 
62     uint32_t keyLength = (uint32_t)length;
63     uint8_t *key = (uint8_t *)HksMalloc(keyLength);
64     HKS_IF_NULL_LOGE_RETURN(key, HKS_ERROR_MALLOC_FAIL, "malloc key fail")
65 
66     /* tmp will be modified in i2d_PUBKEY */
67     uint8_t *tmp = key;
68     if ((uint32_t)i2d_PUBKEY(pkey, &tmp) != keyLength) {
69         HKS_LOG_E("i2d_PUBKEY error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
70         HksFree(key)
71         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
72     }
73 
74     x509Key->size = keyLength;
75     x509Key->data = key;
76     return HKS_SUCCESS;
77 }
78 
79 #if defined(HKS_SUPPORT_RSA_C) && defined(HKS_SUPPORT_RSA_GET_PUBLIC_KEY)
RsaToX509PublicKey(const struct HksBlob * mod,const struct HksBlob * e,struct HksBlob * x509Key)80 static int32_t RsaToX509PublicKey(const struct HksBlob *mod, const struct HksBlob *e, struct HksBlob *x509Key)
81 {
82     RSA *rsa = NULL;
83     BIGNUM *rsaN = NULL;
84     BIGNUM *rsaE = NULL;
85     EVP_PKEY *pkey = NULL;
86     int32_t result;
87 
88     do {
89         result = HKS_ERROR_CRYPTO_ENGINE_ERROR;
90         rsa = RSA_new();
91         HKS_IF_NULL_LOGE_BREAK(rsa, "rsa is null")
92         rsaN = BN_bin2bn(mod->data, mod->size, NULL);
93         rsaE = BN_bin2bn(e->data, e->size, NULL);
94         if (rsaN == NULL || rsaE == NULL) {
95             HKS_LOG_E("BN_bin2bn error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
96             break;
97         }
98         if (RSA_set0_key(rsa, rsaN, rsaE, NULL) == 0) {
99             HKS_LOG_E("RSA_set0_key error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
100             break;
101         }
102         rsaN = NULL;
103         rsaE = NULL;
104         pkey = EVP_PKEY_new();
105         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
106         if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) {
107             HKS_LOG_E("EVP_PKEY_set1_RSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
108             break;
109         }
110         result = EvpKeyToX509Format(pkey, x509Key);
111     } while (0);
112 
113     SELF_FREE_PTR(rsa, RSA_free)
114     SELF_FREE_PTR(rsaN, BN_free)
115     SELF_FREE_PTR(rsaE, BN_free)
116     SELF_FREE_PTR(pkey, EVP_PKEY_free)
117     return result;
118 }
119 #endif
120 
121 #if defined(HKS_SUPPORT_ECC_C) && defined(HKS_SUPPORT_ECC_GET_PUBLIC_KEY)
GetEccNid(uint32_t keySize,int32_t * nid)122 static int32_t GetEccNid(uint32_t keySize, int32_t *nid)
123 {
124     int32_t nids[][2] = {
125         /* 2 is size */
126         { 224, NID_secp224r1 },
127         { 256, NID_X9_62_prime256v1 },
128         { 384, NID_secp384r1 },
129         { 521, NID_secp521r1 },
130     };
131 
132     uint32_t nidCount = sizeof(nids) / sizeof(nids[0]);
133 
134     for (uint32_t i = 0; i < nidCount; i++) {
135         if (keySize == (uint32_t)nids[i][0]) {
136             *nid = nids[i][1];
137             return HKS_SUCCESS;
138         }
139     }
140 
141     HKS_LOG_E("not found nid!");
142     return HKS_ERROR_INVALID_ARGUMENT;
143 }
144 
EccToX509PublicKey(const uint32_t alg,uint32_t keySize,const struct HksBlob * x,const struct HksBlob * y,struct HksBlob * x509Key)145 static int32_t EccToX509PublicKey(
146     const uint32_t alg, uint32_t keySize, const struct HksBlob *x, const struct HksBlob *y, struct HksBlob *x509Key)
147 {
148     int32_t nid;
149     if (alg == HKS_ALG_SM2) {
150         nid = NID_sm2;
151     } else {
152         HKS_IF_NOT_SUCC_LOGE_RETURN(GetEccNid(keySize, &nid), HKS_ERROR_INVALID_ARGUMENT, "GetNidFromKeySize fail")
153     }
154 
155     EC_KEY *ecKey = NULL;
156     BIGNUM *ecX = NULL;
157     BIGNUM *ecY = NULL;
158     EVP_PKEY *pkey = NULL;
159     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
160     do {
161         ecKey = EC_KEY_new_by_curve_name(nid);
162         HKS_IF_NULL_LOGE_BREAK(ecKey,
163             "EC_KEY_new_by_curve_name error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
164 
165         ecX = BN_bin2bn(x->data, x->size, NULL);
166         ecY = BN_bin2bn(y->data, y->size, NULL);
167         if (ecX == NULL || ecY == NULL) {
168             HKS_LOG_E("x y point is null");
169             break;
170         }
171 
172         if (EC_KEY_set_public_key_affine_coordinates(ecKey, ecX, ecY) == 0) {
173             HKS_LOG_E("EC_KEY_set_public_key_affine_coordinates error %" LOG_PUBLIC "s",
174                 ERR_reason_error_string(ERR_get_error()));
175             break;
176         }
177 
178         EC_KEY_set_conv_form(ecKey, POINT_CONVERSION_UNCOMPRESSED);
179         pkey = EVP_PKEY_new();
180         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
181 
182         if (EVP_PKEY_set1_EC_KEY(pkey, ecKey) == 0) {
183             HKS_LOG_E("EVP_PKEY_set1_EC_KEY error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
184             break;
185         }
186 
187         ret = EvpKeyToX509Format(pkey, x509Key);
188     } while (0);
189 
190     SELF_FREE_PTR(ecKey, EC_KEY_free)
191     SELF_FREE_PTR(ecX, BN_free)
192     SELF_FREE_PTR(ecY, BN_free)
193     SELF_FREE_PTR(pkey, EVP_PKEY_free)
194     return ret;
195 }
196 #endif
197 
198 #if defined(HKS_SUPPORT_SM2_C) && defined(HKS_SUPPORT_SM2_GET_PUBLIC_KEY)
ConstructSm2ParamsPushPubKey(OSSL_PARAM_BLD * paramBld,uint32_t keySize,const struct HksBlob * x,const struct HksBlob * y)199 static int32_t ConstructSm2ParamsPushPubKey(OSSL_PARAM_BLD *paramBld,
200     uint32_t keySize, const struct HksBlob *x, const struct HksBlob *y)
201 {
202     // sizes have been checked in ConstructSm2ParamsFromRawPubKey
203     uint32_t fullSize = 1 + HKS_KEY_BYTES(keySize) + HKS_KEY_BYTES(keySize);
204     uint8_t *uncompressedPublicKey = HksMalloc(fullSize);
205     if (uncompressedPublicKey == NULL) {
206         HKS_LOG_E("HksMalloc failed");
207         return HKS_ERROR_INSUFFICIENT_MEMORY;
208     }
209     int ret = HKS_ERROR_BAD_STATE;
210     do {
211         errno_t memRet = memset_s(uncompressedPublicKey, fullSize, 0, fullSize);
212         if (memRet != EOK) {
213             HKS_LOG_E("set zero fail");
214             break;
215         }
216 
217         // https://www.mail-archive.com/openssl-users@openssl.org/msg90185.html
218         // Unfortunately supplying x and y separately is not supported for import.
219         // You have to instead use OSSL_PKEY_PARAM_PUB_KEY.
220         // You can supply the key as an uncompressed public key simply be concatenating the byte "04",
221         // the x co-ord (padded to the appropriate size if necessary) and the y co-cord (also padded as appropriate).
222 
223         // NOTICE: x size is less than or equal to HKS_KEY_BYTES(keySize),
224         // and such cases means that x has leading zeros, so does y.
225         uncompressedPublicKey[0] = POINT_CONVERSION_UNCOMPRESSED;
226         memRet = memcpy_s(uncompressedPublicKey + 1 + HKS_KEY_BYTES(keySize) - x->size, x->size, x->data, x->size);
227         if (memRet != EOK) {
228             HKS_LOG_E("copy x fail");
229             break;
230         }
231         memRet = memcpy_s(uncompressedPublicKey + fullSize - y->size, y->size, y->data, y->size);
232         if (memRet != EOK) {
233             HKS_LOG_E("copy y fail");
234             break;
235         }
236         int osRet = OSSL_PARAM_BLD_push_octet_string(paramBld, OSSL_PKEY_PARAM_PUB_KEY,
237             uncompressedPublicKey, fullSize);
238         if (osRet != HKS_OPENSSL_SUCCESS) {
239             HKS_LOG_E("OSSL_PARAM_BLD_push_octet_string failed %" LOG_PUBLIC "d", osRet);
240             break;
241         }
242         ret = HKS_SUCCESS;
243     } while (false);
244     HksFree(uncompressedPublicKey)
245     return ret;
246 }
247 
248 // Notice: you must call OSSL_PARAM_free after using the return value.
ConstructSm2ParamsFromRawPubKey(uint32_t keySize,const struct HksBlob * x,const struct HksBlob * y)249 static OSSL_PARAM *ConstructSm2ParamsFromRawPubKey(uint32_t keySize, const struct HksBlob *x, const struct HksBlob *y)
250 {
251     if (keySize != HKS_SM2_KEY_SIZE_256 || x->size > HKS_KEY_BYTES(keySize) || y->size > HKS_KEY_BYTES(keySize)) {
252         HKS_LOG_E("invalid length");
253         return NULL;
254     }
255     OSSL_PARAM_BLD *paramBld = OSSL_PARAM_BLD_new();
256     if (paramBld == NULL) {
257         HKS_LOG_E("OSSL_PARAM_BLD_new failed");
258         HksLogOpensslError();
259         return NULL;
260     }
261     OSSL_PARAM *params = NULL;
262     do {
263         int ret = OSSL_PARAM_BLD_push_utf8_string(paramBld, OSSL_PKEY_PARAM_GROUP_NAME, SN_sm2, 0);
264         if (ret != HKS_OPENSSL_SUCCESS) {
265             HKS_LOG_E("OSSL_PARAM_BLD_push_utf8_string failed %" LOG_PUBLIC "d", ret);
266             HksLogOpensslError();
267             break;
268         }
269 
270         ret = ConstructSm2ParamsPushPubKey(paramBld, keySize, x, y);
271         if (ret != HKS_SUCCESS) {
272             HKS_LOG_E("ConstructSm2ParamsPushPubKey failed %" LOG_PUBLIC "d", ret);
273             break;
274         }
275 
276         params = OSSL_PARAM_BLD_to_param(paramBld);
277         if (params == NULL) {
278             HKS_LOG_E("OSSL_PARAM_BLD_to_param failed");
279             HksLogOpensslError();
280             break;
281         }
282     } while (0);
283     SELF_FREE_PTR(paramBld, OSSL_PARAM_BLD_free)
284     return params;
285 }
286 
Sm2ToX509PublicKey(const uint32_t alg,uint32_t keySize,const struct HksBlob * x,const struct HksBlob * y,struct HksBlob * x509Key)287 static int32_t Sm2ToX509PublicKey(
288     const uint32_t alg, uint32_t keySize, const struct HksBlob *x, const struct HksBlob *y, struct HksBlob *x509Key)
289 {
290     EVP_PKEY *sm2EvpPkey = NULL;
291     HKS_LOG_I("begin ConstructSm2ParamsFromRawPubKey");
292     OSSL_PARAM *params = ConstructSm2ParamsFromRawPubKey(keySize, x, y);
293     if (params == NULL) {
294         HKS_LOG_E("ConstructSm2ParamsFromRawPubKey failed");
295         return HKS_ERROR_INTERNAL_ERROR;
296     }
297     do {
298         EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(NID_sm2, NULL);
299         if (ctx == NULL) {
300             HKS_LOG_E("EVP_PKEY_CTX_new_id failed");
301             HksLogOpensslError();
302             break;
303         }
304         int ret = EVP_PKEY_fromdata_init(ctx);
305         if (ret != HKS_OPENSSL_SUCCESS) {
306             HKS_LOG_E("EVP_PKEY_fromdata_init failed %" LOG_PUBLIC "d", ret);
307             HksLogOpensslError();
308             SELF_FREE_PTR(ctx, EVP_PKEY_CTX_free)
309             break;
310         }
311         ret = EVP_PKEY_fromdata(ctx, &sm2EvpPkey, EVP_PKEY_PUBLIC_KEY, params);
312         SELF_FREE_PTR(ctx, EVP_PKEY_CTX_free)
313         if (ret != HKS_OPENSSL_SUCCESS) {
314             HKS_LOG_E("EVP_PKEY_fromdata failed %" LOG_PUBLIC "d", ret);
315             break;
316         }
317     } while (false);
318     SELF_FREE_PTR(params, OSSL_PARAM_free)
319     if (sm2EvpPkey == NULL) {
320         HKS_LOG_E("build sm2 EVP_PKEY failed");
321         return HKS_ERROR_INTERNAL_ERROR;
322     }
323     HKS_LOG_I("construct EVP_PKEY *sm2EvpPkey OK!");
324     int32_t ret = EvpKeyToX509Format(sm2EvpPkey, x509Key);
325     if (ret != HKS_SUCCESS) {
326         HKS_LOG_E("EvpKeyToX509Format failed %" LOG_PUBLIC "d", ret);
327     }
328     SELF_FREE_PTR(sm2EvpPkey, EVP_PKEY_free)
329     return ret;
330 }
331 #endif
332 
333 #if defined(HKS_SUPPORT_DSA_C) && defined(HKS_SUPPORT_DSA_GET_PUBLIC_KEY)
GetDsaPubKeyParam(const struct HksBlob * publicKey,struct HksBlob * y,struct HksBlob * p,struct HksBlob * q,struct HksBlob * g)334 static int32_t GetDsaPubKeyParam(
335     const struct HksBlob *publicKey, struct HksBlob *y, struct HksBlob *p, struct HksBlob *q, struct HksBlob *g)
336 {
337     if (publicKey->size < sizeof(struct KeyMaterialDsa)) {
338         HKS_LOG_E("Invaild dsa key material size!");
339         return HKS_ERROR_INVALID_ARGUMENT;
340     }
341 
342     struct KeyMaterialDsa *keyMaterial = (struct KeyMaterialDsa *)publicKey->data;
343     uint32_t keyMaterialSize = sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + keyMaterial->ySize +
344         keyMaterial->pSize + keyMaterial->qSize + keyMaterial->gSize;
345     if (publicKey->size < keyMaterialSize) {
346         HKS_LOG_E("translate to x509 public key invalid size");
347         return HKS_ERROR_INVALID_ARGUMENT;
348     }
349     uint32_t offset = sizeof(struct KeyMaterialDsa) + keyMaterial->xSize;
350     y->size = keyMaterial->ySize;
351     y->data = publicKey->data + offset;
352     offset += keyMaterial->ySize;
353     p->size = keyMaterial->pSize;
354     p->data = publicKey->data + offset;
355     offset += keyMaterial->pSize;
356     q->size = keyMaterial->qSize;
357     q->data = publicKey->data + offset;
358     offset += keyMaterial->qSize;
359     g->size = keyMaterial->gSize;
360     g->data = publicKey->data + offset;
361     return HKS_SUCCESS;
362 }
363 
DsaToX509PublicKey(const struct HksBlob * y,const struct HksBlob * p,const struct HksBlob * q,const struct HksBlob * g,struct HksBlob * x509Key)364 static int32_t DsaToX509PublicKey(const struct HksBlob *y, const struct HksBlob *p, const struct HksBlob *q,
365     const struct HksBlob *g, struct HksBlob *x509Key)
366 {
367     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
368     DSA *dsa = NULL;
369     BIGNUM *dsaY = BN_bin2bn(y->data, y->size, NULL);
370     BIGNUM *dsaP = BN_bin2bn(p->data, p->size, NULL);
371     BIGNUM *dsaQ = BN_bin2bn(q->data, q->size, NULL);
372     BIGNUM *dsaG = BN_bin2bn(g->data, g->size, NULL);
373     EVP_PKEY *pkey = NULL;
374     do {
375         dsa = DSA_new();
376         HKS_IF_NULL_LOGE_BREAK(dsa, "DSA_new error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
377 
378         if (dsaY == NULL || dsaP == NULL || dsaQ == NULL || dsaG == NULL) {
379             HKS_LOG_E("DSA parameter is null.");
380             break;
381         }
382 
383         if (DSA_set0_key(dsa, dsaY, NULL) != 1) {
384             HKS_LOG_E("DSA_set0_key error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
385             break;
386         }
387         dsaY = NULL;
388         if (DSA_set0_pqg(dsa, dsaP, dsaQ, dsaG) != 1) {
389             HKS_LOG_E("DSA_set0_pqg error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
390             break;
391         }
392         dsaP = NULL;
393         dsaQ = NULL;
394         dsaG = NULL;
395 
396         pkey = EVP_PKEY_new();
397         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
398 
399         if (EVP_PKEY_set1_DSA(pkey, dsa) == 0) {
400             HKS_LOG_E("EVP_PKEY_set1_DSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
401             break;
402         }
403 
404         ret = EvpKeyToX509Format(pkey, x509Key);
405     } while (0);
406 
407     SELF_FREE_PTR(dsa, DSA_free)
408     SELF_FREE_PTR(dsaY, BN_free)
409     SELF_FREE_PTR(dsaP, BN_free)
410     SELF_FREE_PTR(dsaQ, BN_free)
411     SELF_FREE_PTR(dsaG, BN_free)
412     SELF_FREE_PTR(pkey, EVP_PKEY_free)
413     return ret;
414 }
415 
DsaPublicKeyToX509(const struct HksBlob * publicKey,struct HksBlob * x509Key)416 static int32_t DsaPublicKeyToX509(const struct HksBlob *publicKey, struct HksBlob *x509Key)
417 {
418     struct HksBlob y = {0};
419     struct HksBlob p = {0};
420     struct HksBlob q = {0};
421     struct HksBlob g = {0};
422     int32_t ret = GetDsaPubKeyParam(publicKey, &y, &p, &q, &g);
423     HKS_IF_NOT_SUCC_RETURN(ret, ret)
424 
425     return DsaToX509PublicKey(&y, &p, &q, &g, x509Key);
426 }
427 
428 #endif
429 
430 #if defined(HKS_SUPPORT_DH_C) && defined(HKS_SUPPORT_DH_GET_PUBLIC_KEY)
GetDhNid(uint32_t keySize,int32_t * nid)431 static int32_t GetDhNid(uint32_t keySize, int32_t *nid)
432 {
433     switch (keySize) {
434         case HKS_DH_KEY_SIZE_2048:
435             *nid = NID_ffdhe2048;
436             return HKS_SUCCESS;
437         case HKS_DH_KEY_SIZE_3072:
438             *nid = NID_ffdhe3072;
439             return HKS_SUCCESS;
440         case HKS_DH_KEY_SIZE_4096:
441             *nid = NID_ffdhe4096;
442             return HKS_SUCCESS;
443         default:
444             return HKS_ERROR_INVALID_ARGUMENT;
445     }
446 }
447 
DhToX509PublicKey(uint32_t keySize,const struct HksBlob * pubKey,const struct HksBlob * privKey,struct HksBlob * x509Key)448 static int32_t DhToX509PublicKey(
449     uint32_t keySize, const struct HksBlob *pubKey, const struct HksBlob *privKey, struct HksBlob *x509Key)
450 {
451     int32_t nid;
452     int32_t ret = GetDhNid(keySize, &nid);
453     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetNidFromKeySize fail")
454 
455     BIGNUM *pub = NULL;
456     DH *dh = NULL;
457     EVP_PKEY *pkey = NULL;
458     do {
459         dh = DH_new_by_nid(nid);
460         HKS_IF_NULL_LOGE_BREAK(dh, "DH_new_by_nid error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
461 
462         pub = BN_bin2bn(pubKey->data, pubKey->size, NULL);
463         HKS_IF_NULL_LOGE_BREAK(pub, "BN_bin2bn error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
464 
465         if (DH_set0_key(dh, pub, NULL) != 1) {
466             HKS_LOG_E("DH_set0_key error:%" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
467             break;
468         }
469         pub = NULL;
470 
471         pkey = EVP_PKEY_new();
472         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
473 
474         if (EVP_PKEY_set1_DH(pkey, dh) == 0) {
475             HKS_LOG_E("EVP_PKEY_set1_DH error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
476             break;
477         }
478 
479         ret = EvpKeyToX509Format(pkey, x509Key);
480     } while (0);
481 
482     SELF_FREE_PTR(dh, DH_free)
483     SELF_FREE_PTR(pub, BN_free)
484     SELF_FREE_PTR(pkey, EVP_PKEY_free)
485     return ret;
486 }
487 #endif
488 #endif
489 
490 #if defined(HKS_SUPPORT_X25519_C) || defined(HKS_SUPPORT_ED25519_C)
Curve25519ToX509PublicKey(const struct HksBlob * publicKey,struct HksBlob * x509Key)491 static int32_t Curve25519ToX509PublicKey(const struct HksBlob *publicKey, struct HksBlob *x509Key)
492 {
493     if (publicKey->size != HKS_KEY_BYTES(HKS_CURVE25519_KEY_SIZE_256)) {
494         HKS_LOG_E("Invalid public key size! key size = 0x%" LOG_PUBLIC "X", publicKey->size);
495         return HKS_ERROR_INVALID_ARGUMENT;
496     }
497 
498     x509Key->data = (uint8_t *)HksMalloc(publicKey->size);
499     HKS_IF_NULL_LOGE_RETURN(x509Key->data, HKS_ERROR_MALLOC_FAIL,
500         "X25519/Ed25519 to x509 public key malloc x509 key data failed!")
501 
502     (void)memcpy_s(x509Key->data, publicKey->size, publicKey->data, publicKey->size);
503     x509Key->size = publicKey->size;
504 
505     return HKS_SUCCESS;
506 }
507 #endif
508 
TranslateToX509PublicKeySwitchAlg(const struct HksPubKeyInfo * publicKeyInfo,const struct HksBlob * material1,const struct HksBlob * material2,const struct HksBlob * publicKey,struct HksBlob * x509Key)509 static int32_t TranslateToX509PublicKeySwitchAlg(const struct HksPubKeyInfo *publicKeyInfo,
510     const struct HksBlob *material1, const struct HksBlob *material2, const struct HksBlob *publicKey,
511     struct HksBlob *x509Key)
512 {
513     switch (publicKeyInfo->keyAlg) {
514 #if defined(HKS_SUPPORT_RSA_C) && defined(HKS_SUPPORT_RSA_GET_PUBLIC_KEY)
515         case HKS_ALG_RSA:
516             return RsaToX509PublicKey(material1, material2, x509Key);
517 #endif
518 #if defined(HKS_SUPPORT_ECC_C) && defined(HKS_SUPPORT_ECC_GET_PUBLIC_KEY)
519         case HKS_ALG_ECC:
520             return EccToX509PublicKey(publicKeyInfo->keyAlg, publicKeyInfo->keySize, material1, material2, x509Key);
521 #endif
522 #if defined(HKS_SUPPORT_SM2_C) && defined(HKS_SUPPORT_SM2_GET_PUBLIC_KEY)
523         case HKS_ALG_SM2:
524             return Sm2ToX509PublicKey(publicKeyInfo->keyAlg, publicKeyInfo->keySize, material1, material2, x509Key);
525 #endif
526 #if defined(HKS_SUPPORT_DSA_C) && defined(HKS_SUPPORT_DSA_GET_PUBLIC_KEY)
527         case HKS_ALG_DSA:
528             return DsaPublicKeyToX509(publicKey, x509Key);
529 #endif
530 #if defined(HKS_SUPPORT_X25519_C) || defined(HKS_SUPPORT_ED25519_C)
531         case HKS_ALG_X25519:
532         case HKS_ALG_ED25519:
533             return Curve25519ToX509PublicKey(material1, x509Key);
534 #endif
535 #if defined(HKS_SUPPORT_DH_C) && defined(HKS_SUPPORT_DH_GET_PUBLIC_KEY)
536         case HKS_ALG_DH:
537             return DhToX509PublicKey(publicKeyInfo->keySize, material1, NULL, x509Key);
538 #endif
539         default:
540             HKS_LOG_E("Unsupport alg type! type = 0x%" LOG_PUBLIC "X", publicKeyInfo->keyAlg);
541             return HKS_ERROR_INVALID_ARGUMENT;
542     }
543 }
544 
TranslateToX509PublicKey(const struct HksBlob * publicKey,struct HksBlob * x509Key)545 int32_t TranslateToX509PublicKey(const struct HksBlob *publicKey, struct HksBlob *x509Key)
546 {
547     if ((publicKey == NULL) || (publicKey->data == NULL) || (publicKey->size == 0) || (x509Key == NULL)) {
548         HKS_LOG_E("translate to x509 public key invalid args");
549         return HKS_ERROR_INVALID_ARGUMENT;
550     }
551 
552     if (publicKey->size < sizeof(struct HksPubKeyInfo)) {
553         HKS_LOG_E("translate to x509 public key invalid publicKey size");
554         return HKS_ERROR_INVALID_ARGUMENT;
555     }
556 
557     struct HksPubKeyInfo *publicKeyInfo = (struct HksPubKeyInfo *)publicKey->data;
558     uint32_t offset = sizeof(struct HksPubKeyInfo);
559     if ((publicKey->size - offset) < publicKeyInfo->nOrXSize) {
560         HKS_LOG_E("translate to x509 public key invalid nOrXSize size");
561         return HKS_ERROR_INVALID_ARGUMENT;
562     }
563 
564     struct HksBlob material1 = { publicKeyInfo->nOrXSize, publicKey->data + offset };
565     offset += publicKeyInfo->nOrXSize;
566     if ((publicKey->size - offset) < publicKeyInfo->eOrYSize) {
567         HKS_LOG_E("translate to x509 public key invalid eOrYSize size");
568         return HKS_ERROR_INVALID_ARGUMENT;
569     }
570 
571     struct HksBlob material2 = { publicKeyInfo->eOrYSize, publicKey->data + offset };
572     return TranslateToX509PublicKeySwitchAlg(publicKeyInfo, &material1, &material2, publicKey, x509Key);
573 }
574 
575 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C) || defined(HKS_SUPPORT_DSA_C) || \
576     defined(HKS_SUPPORT_DH_C)
577 #ifdef HKS_SUPPORT_RSA_C
X509PublicKeyToRsa(EVP_PKEY * pkey,struct HksBlob * rsaPublicKey)578 static int32_t X509PublicKeyToRsa(EVP_PKEY *pkey, struct HksBlob *rsaPublicKey)
579 {
580     const RSA *rsa = EVP_PKEY_get0_RSA(pkey);
581     HKS_IF_NULL_LOGE_RETURN(rsa, HKS_ERROR_NULL_POINTER,
582         "EVP_PKEY_get1_RSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
583 
584     int nSize = BN_num_bytes(RSA_get0_n(rsa));
585     int eSize = BN_num_bytes(RSA_get0_e(rsa));
586     if (nSize <= 0 || eSize <= 0) {
587         HKS_LOG_E("X509PublicKeyToRsa BN_num_bytes failed");
588         return HKS_ERROR_INTERNAL_ERROR;
589     }
590 
591     /* n and e in RSA algorithm is small, will never overflow. */
592     uint32_t totalSize = (uint32_t)nSize + (uint32_t)eSize + sizeof(struct HksPubKeyInfo);
593     uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
594     HKS_IF_NULL_LOGE_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL, "X509PublicKeyToRsa keyBuffer failed")
595 
596     struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)keyBuffer;
597     pubKeyInfo->keyAlg = HKS_ALG_RSA;
598     pubKeyInfo->keySize = ((uint32_t)RSA_size(rsa)) * HKS_BITS_PER_BYTE;
599     pubKeyInfo->nOrXSize = (uint32_t)nSize;
600     pubKeyInfo->eOrYSize = (uint32_t)eSize;
601     pubKeyInfo->placeHolder = 0;
602     if (BN_bn2bin(RSA_get0_n(rsa), keyBuffer + sizeof(struct HksPubKeyInfo)) == 0 ||
603         BN_bn2bin(RSA_get0_e(rsa), keyBuffer + sizeof(struct HksPubKeyInfo) + (uint32_t)nSize) == 0) {
604         HKS_LOG_E("BN_bn2bin error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
605         HKS_FREE_PTR(keyBuffer);
606         return HKS_ERROR_INTERNAL_ERROR;
607     }
608 
609     rsaPublicKey->data = keyBuffer;
610     rsaPublicKey->size = totalSize;
611     return HKS_SUCCESS;
612 }
613 #endif
614 
615 #ifdef HKS_SUPPORT_ECC_C
EcKeyToPublicKey(const uint32_t alg,const EC_KEY * ecKey,struct HksBlob * eccPublicKey)616 static int32_t EcKeyToPublicKey(const uint32_t alg, const EC_KEY *ecKey, struct HksBlob *eccPublicKey)
617 {
618     BIGNUM *x = BN_new();
619     BIGNUM *y = BN_new();
620     int32_t ret;
621     do {
622         ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
623         if (x == NULL || y == NULL) {
624             HKS_LOG_E("X509PublicKeyToEcc BN_new failed");
625             break;
626         }
627 
628         if (EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ecKey), EC_KEY_get0_public_key(ecKey), x, y, NULL) ==
629             0) {
630             HKS_LOG_E("EC_POINT_get_affine_coordinates_GFp error %" LOG_PUBLIC "s",
631                 ERR_reason_error_string(ERR_get_error()));
632             break;
633         }
634 
635         uint32_t keyLen = (uint32_t)EC_GROUP_order_bits(EC_KEY_get0_group(ecKey));
636         uint32_t xSize = HKS_KEY_BYTES(keyLen);
637         uint32_t ySize = HKS_KEY_BYTES(keyLen);
638 
639         if ((keyLen == 0) || (keyLen > HKS_ECC_KEY_SIZE_521)) {
640             HKS_LOG_E("invalid ecc key length");
641             break;
642         }
643 
644         uint32_t totalSize = xSize + ySize + sizeof(struct HksPubKeyInfo);
645         uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
646         HKS_IF_NULL_LOGE_BREAK(keyBuffer, "X509PublicKeyToRsa keyBuffer failed")
647 
648         struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)keyBuffer;
649         pubKeyInfo->keyAlg = alg;
650         pubKeyInfo->keySize = keyLen;
651         pubKeyInfo->nOrXSize = xSize;
652         pubKeyInfo->eOrYSize = ySize;
653         pubKeyInfo->placeHolder = 0;
654         if (BN_bn2binpad(x, keyBuffer + sizeof(struct HksPubKeyInfo), xSize) == 0 ||
655             BN_bn2binpad(y, keyBuffer + sizeof(struct HksPubKeyInfo) + xSize, ySize) == 0) {
656             HKS_LOG_E("BN_bn2binpad error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
657             HKS_FREE_PTR(keyBuffer);
658             break;
659         }
660 
661         ret = HKS_SUCCESS;
662         eccPublicKey->data = keyBuffer;
663         eccPublicKey->size = totalSize;
664     } while (0);
665 
666     SELF_FREE_PTR(x, BN_free)
667     SELF_FREE_PTR(y, BN_free)
668     return ret;
669 }
670 
X509PublicKeyToEcc(const uint32_t alg,EVP_PKEY * pkey,struct HksBlob * eccPublicKey)671 static int32_t X509PublicKeyToEcc(const uint32_t alg, EVP_PKEY *pkey, struct HksBlob *eccPublicKey)
672 {
673     const EC_KEY *ecKey = EVP_PKEY_get0_EC_KEY(pkey);
674     HKS_IF_NULL_LOGE_RETURN(ecKey, HKS_ERROR_NULL_POINTER,
675         "EVP_PKEY_get1_EC_KEY error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
676 
677     return EcKeyToPublicKey(alg, ecKey, eccPublicKey);
678 }
679 #endif
680 
681 #ifdef HKS_SUPPORT_SM2_C
EvpPkeyToHksPubKeyInfo(const uint32_t alg,uint32_t keyLen,const EVP_PKEY * pkey,struct HksBlob * sm2PublicKey)682 static int32_t EvpPkeyToHksPubKeyInfo(
683     const uint32_t alg, uint32_t keyLen, const EVP_PKEY *pkey, struct HksBlob *sm2PublicKey)
684 {
685     struct HksBlob pubXBlob = { 0, NULL };
686     struct HksBlob pubYBlob = { 0, NULL };
687     int pubXRet = GetBnBinpadFromPkey(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &pubXBlob);
688     int pubYRet = GetBnBinpadFromPkey(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &pubYBlob);
689     int ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
690     do {
691         if (pubXRet != HKS_SUCCESS || pubYRet != HKS_SUCCESS) {
692             break;
693         }
694         // NOTICE! x size and y size are smaller than or equal to HKS_KEY_BYTES(keyLen)
695         // e.g. assuming that HKS_KEY_BYTES(keyLen) is 32, x size might be 32, 31, 30, etc.
696         uint32_t rawInfoLen = sizeof(struct HksPubKeyInfo) + pubXBlob.size + pubYBlob.size;
697         uint8_t *rawInfo = (uint8_t *)HksMalloc(rawInfoLen);
698         if (!rawInfo) {
699             HKS_LOG_E("HksMalloc rawInfo NULL");
700             ret = HKS_ERROR_INSUFFICIENT_MEMORY;
701             break;
702         }
703         struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)rawInfo;
704         pubKeyInfo->keyAlg = (enum HksKeyAlg)alg;
705         pubKeyInfo->keySize = keyLen;
706         pubKeyInfo->nOrXSize = pubXBlob.size;
707         pubKeyInfo->eOrYSize = pubYBlob.size;
708         pubKeyInfo->placeHolder = 0;
709         uint32_t offset = sizeof(struct HksPubKeyInfo);
710         pubXRet = memcpy_s(rawInfo + offset, pubXBlob.size, pubXBlob.data, pubXBlob.size);
711         offset += pubKeyInfo->nOrXSize;
712         pubYRet = memcpy_s(rawInfo + offset, pubYBlob.size, pubYBlob.data, pubYBlob.size);
713         if (pubXRet != EOK || pubYRet != EOK) {
714             HKS_LOG_E("memcpy_s failed");
715             HksFree(rawInfo)
716             ret = HKS_ERROR_BAD_STATE;
717             break;
718         }
719         sm2PublicKey->data = rawInfo;
720         sm2PublicKey->size = rawInfoLen;
721         ret = HKS_SUCCESS;
722     } while (false);
723     HksFree(pubXBlob.data)
724     HksFree(pubYBlob.data)
725     return ret;
726 }
727 
X509PublicKeyToSm2(const uint32_t alg,EVP_PKEY * pkey,struct HksBlob * sm2PublicKey)728 static int32_t X509PublicKeyToSm2(const uint32_t alg, EVP_PKEY *pkey, struct HksBlob *sm2PublicKey)
729 {
730     HKS_LOG_I("into X509PublicKeyToSm2");
731     int keyLen = EVP_PKEY_get_bits(pkey);
732     if (keyLen <= 0) {
733         HKS_LOG_E("EVP_PKEY_get_bits failed keyLen = %" LOG_PUBLIC "d", keyLen);
734         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
735     }
736     if (keyLen != HKS_SM2_KEY_SIZE_256) {
737         HKS_LOG_E("not supported sm2 keyLen %" LOG_PUBLIC "d", keyLen);
738         return HKS_ERROR_NOT_SUPPORTED;
739     }
740     int ret = EvpPkeyToHksPubKeyInfo(alg, (uint32_t)keyLen, pkey, sm2PublicKey);
741     if (ret != HKS_SUCCESS) {
742         HKS_LOG_E("EvpPkeyToHksPubKeyInfo failed ret = %" LOG_PUBLIC "d", ret);
743     }
744     return ret;
745 }
746 #endif
747 
748 #ifdef HKS_SUPPORT_DSA_C
749 
GetDsaKeyInfo(const DSA * dsa,const BIGNUM ** info,uint32_t * infoSize,GetDsaInfoFunc func)750 static int32_t GetDsaKeyInfo(const DSA *dsa, const BIGNUM **info, uint32_t *infoSize, GetDsaInfoFunc func)
751 {
752     *info = func(dsa);
753     HKS_IF_NULL_RETURN(*info, HKS_ERROR_NULL_POINTER)
754 
755     int size = BN_num_bytes(*info);
756     if (size <= 0) {
757         return HKS_ERROR_INVALID_ARGUMENT;
758     }
759 
760     *infoSize = (uint32_t)size;
761     return HKS_SUCCESS;
762 }
763 
X509PublicKeyToDsa(EVP_PKEY * pkey,struct HksBlob * dsaPublicKey)764 static int32_t X509PublicKeyToDsa(EVP_PKEY *pkey, struct HksBlob *dsaPublicKey)
765 {
766     const DSA *dsa = EVP_PKEY_get0_DSA(pkey);
767     HKS_IF_NULL_LOGE_RETURN(dsa, HKS_ERROR_NULL_POINTER,
768         "EVP_PKEY_get1_DSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
769 
770     const BIGNUM *y = NULL;
771     const BIGNUM *p = NULL;
772     const BIGNUM *q = NULL;
773     const BIGNUM *g = NULL;
774     uint32_t ySize = 0;
775     uint32_t pSize = 0;
776     uint32_t qSize = 0;
777     uint32_t gSize = 0;
778 
779     if (GetDsaKeyInfo(dsa, &y, &ySize, DSA_get0_pub_key) != HKS_SUCCESS ||
780         GetDsaKeyInfo(dsa, &p, &pSize, DSA_get0_p) != HKS_SUCCESS ||
781         GetDsaKeyInfo(dsa, &q, &qSize, DSA_get0_q) != HKS_SUCCESS ||
782         GetDsaKeyInfo(dsa, &g, &gSize, DSA_get0_g) != HKS_SUCCESS) {
783         return HKS_ERROR_INVALID_ARGUMENT;
784     }
785 
786     uint32_t totalSize = sizeof(struct KeyMaterialDsa) + ySize + pSize + qSize + gSize;
787     uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
788     HKS_IF_NULL_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL)
789 
790     if ((ySize > UINT32_MAX - HKS_BITS_PER_BYTE) ||
791         ((ySize + HKS_BITS_PER_BYTE - 1) / HKS_BITS_PER_BYTE > UINT32_MAX / (HKS_BITS_PER_BYTE * HKS_BITS_PER_BYTE))) {
792         HKS_FREE_PTR(keyBuffer);
793         return HKS_ERROR_BAD_STATE;
794     }
795 
796     struct KeyMaterialDsa *keyMaterial = (struct KeyMaterialDsa *)keyBuffer;
797     keyMaterial->keyAlg = HKS_ALG_DSA;
798     keyMaterial->keySize = (ySize + HKS_BITS_PER_BYTE - 1) / HKS_BITS_PER_BYTE * HKS_BITS_PER_BYTE * HKS_BITS_PER_BYTE;
799     keyMaterial->xSize = 0;
800     keyMaterial->ySize = ySize;
801     keyMaterial->pSize = pSize;
802     keyMaterial->qSize = qSize;
803     keyMaterial->gSize = gSize;
804 
805     if ((BN_bn2bin(y, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize) == 0) ||
806         (BN_bn2bin(p, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + ySize) == 0) ||
807         (BN_bn2bin(q, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + ySize + pSize) == 0) ||
808         (BN_bn2bin(g, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + ySize + pSize + qSize) == 0)) {
809         HKS_LOG_E("BN_bn2bin error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
810         HKS_FREE_PTR(keyBuffer);
811         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
812     }
813     dsaPublicKey->size = totalSize;
814     dsaPublicKey->data = keyBuffer;
815 
816     return HKS_SUCCESS;
817 }
818 #endif
819 
820 #ifdef HKS_SUPPORT_DH_C
X509PublicKeyToDh(EVP_PKEY * pkey,struct HksBlob * dhPublicKey)821 static int32_t X509PublicKeyToDh(EVP_PKEY *pkey, struct HksBlob *dhPublicKey)
822 {
823     const DH *dh = EVP_PKEY_get0_DH(pkey);
824     HKS_IF_NULL_LOGE_RETURN(dh, HKS_ERROR_NULL_POINTER,
825         "EVP_PKEY_get0_DH error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
826 
827     const BIGNUM *pubKey = DH_get0_pub_key(dh);
828     HKS_IF_NULL_LOGE_RETURN(pubKey, HKS_ERROR_NULL_POINTER,
829         "DH_get0_pub_key error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
830 
831     uint32_t pubKeySize = (uint32_t)BN_num_bytes(pubKey);
832     if (pubKeySize > UINT32_MAX - sizeof(struct KeyMaterialDh)) {
833         HKS_LOG_E("the size is too long, failed");
834         return HKS_ERROR_BAD_STATE;
835     }
836 
837     uint32_t totalSize = sizeof(struct KeyMaterialDh) + pubKeySize;
838     uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
839     HKS_IF_NULL_LOGE_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL, "alloc keyBuffer failed")
840     struct KeyMaterialDh *keyMaterial = (struct KeyMaterialDh *)keyBuffer;
841     keyMaterial->keyAlg = HKS_ALG_DH;
842     keyMaterial->keySize = (uint32_t)DH_bits(dh);
843     keyMaterial->pubKeySize = pubKeySize;
844     keyMaterial->priKeySize = 0;
845     keyMaterial->reserved = 0;
846 
847     BN_bn2bin(pubKey, keyBuffer + sizeof(struct KeyMaterialDh));
848 
849     dhPublicKey->size = totalSize;
850     dhPublicKey->data = keyBuffer;
851 
852     return HKS_SUCCESS;
853 }
854 #endif
855 
TranslateFromX509PublicKey(const uint32_t alg,const struct HksBlob * x509Key,struct HksBlob * publicKey)856 int32_t TranslateFromX509PublicKey(const uint32_t alg, const struct HksBlob *x509Key, struct HksBlob *publicKey)
857 {
858     if (x509Key == NULL || x509Key->data == NULL || x509Key->size == 0 || publicKey == NULL) {
859         HKS_LOG_E("TranslateFromX509PublicKey invalid args");
860         return HKS_ERROR_INVALID_ARGUMENT;
861     }
862 
863     uint8_t *data = x509Key->data;
864 
865     EVP_PKEY *pkey = d2i_PUBKEY(NULL, (const unsigned char **)&data, x509Key->size);
866     HKS_IF_NULL_RETURN(pkey, HKS_ERROR_INVALID_ARGUMENT)
867 
868     int32_t ret;
869     int32_t keyType = EVP_PKEY_base_id(pkey);
870     if (keyType == EVP_PKEY_RSA) {
871 #ifdef HKS_SUPPORT_RSA_C
872         ret = X509PublicKeyToRsa(pkey, publicKey);
873 #else
874         ret = HKS_ERROR_INVALID_ALGORITHM;
875 #endif
876     } else if (keyType == EVP_PKEY_EC) {
877 #ifdef HKS_SUPPORT_ECC_C
878         ret = X509PublicKeyToEcc(alg, pkey, publicKey);
879 #else
880         ret = HKS_ERROR_INVALID_ALGORITHM;
881 #endif
882     } else if (EVP_PKEY_is_a(pkey, SN_sm2)) {
883 #ifdef HKS_SUPPORT_SM2_C
884         ret = X509PublicKeyToSm2(alg, pkey, publicKey);
885 #else
886         ret = HKS_ERROR_INVALID_ALGORITHM;
887 #endif
888     } else if (keyType == EVP_PKEY_DSA) {
889 #ifdef HKS_SUPPORT_DSA_C
890         ret = X509PublicKeyToDsa(pkey, publicKey);
891 #else
892         ret = HKS_ERROR_INVALID_ALGORITHM;
893 #endif
894     } else if (keyType == EVP_PKEY_DH) {
895 #ifdef HKS_SUPPORT_DH_C
896         ret = X509PublicKeyToDh(pkey, publicKey);
897 #else
898         ret = HKS_ERROR_INVALID_ALGORITHM;
899 #endif
900     } else {
901         HKS_LOG_E("Unsupport alg type! %" LOG_PUBLIC "d", keyType);
902         ret = HKS_ERROR_INVALID_ARGUMENT;
903     }
904 
905     SELF_FREE_PTR(pkey, EVP_PKEY_free)
906     return ret;
907 }
908 #endif
909 
910