• 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/dh.h>
26 #include <openssl/dsa.h>
27 #include <openssl/ec.h>
28 #include <openssl/err.h>
29 #include <openssl/evp.h>
30 #include <openssl/obj_mac.h>
31 #include <openssl/ossl_typ.h>
32 #include <openssl/rsa.h>
33 #include <openssl/x509.h>
34 #include <stddef.h>
35 #include <stdint.h>
36 
37 #include "hks_crypto_hal.h"
38 #include "hks_log.h"
39 #include "hks_mem.h"
40 #include "hks_template.h"
41 #include "securec.h"
42 
43 #if defined(HKS_SUPPORT_DSA_C)
44 typedef const BIGNUM* (*GetDsaInfoFunc)(const DSA *d);
45 #endif
46 
47 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C) || defined(HKS_SUPPORT_DSA_C) || \
48     defined(HKS_SUPPORT_DH_C) || defined(HKS_SUPPORT_SM2_C)
EvpKeyToX509Format(EVP_PKEY * pkey,struct HksBlob * x509Key)49 static int32_t EvpKeyToX509Format(EVP_PKEY *pkey, struct HksBlob *x509Key)
50 {
51     int32_t length = i2d_PUBKEY(pkey, NULL);
52     if (length <= 0 || length > MAX_OUT_BLOB_SIZE) {
53         HKS_LOG_E("i2d_PUBKEY error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
54         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
55     }
56 
57     uint32_t keyLength = (uint32_t)length;
58     uint8_t *key = (uint8_t *)HksMalloc(keyLength);
59     HKS_IF_NULL_LOGE_RETURN(key, HKS_ERROR_MALLOC_FAIL, "malloc key fail")
60 
61     /* tmp will be modified in i2d_PUBKEY */
62     uint8_t *tmp = key;
63     if ((uint32_t)i2d_PUBKEY(pkey, &tmp) != keyLength) {
64         HKS_LOG_E("i2d_PUBKEY error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
65         HksFree(key);
66         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
67     }
68 
69     x509Key->size = keyLength;
70     x509Key->data = key;
71     return HKS_SUCCESS;
72 }
73 
74 #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)75 static int32_t RsaToX509PublicKey(const struct HksBlob *mod, const struct HksBlob *e, struct HksBlob *x509Key)
76 {
77     RSA *rsa = NULL;
78     BIGNUM *rsaN = NULL;
79     BIGNUM *rsaE = NULL;
80     EVP_PKEY *pkey = NULL;
81     int32_t result;
82 
83     do {
84         result = HKS_ERROR_CRYPTO_ENGINE_ERROR;
85         rsa = RSA_new();
86         HKS_IF_NULL_LOGE_BREAK(rsa, "rsa is null")
87         rsaN = BN_bin2bn(mod->data, mod->size, NULL);
88         rsaE = BN_bin2bn(e->data, e->size, NULL);
89         if (rsaN == NULL || rsaE == NULL) {
90             HKS_LOG_E("BN_bin2bn error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
91             break;
92         }
93         if (RSA_set0_key(rsa, rsaN, rsaE, NULL) == 0) {
94             HKS_LOG_E("RSA_set0_key error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
95             break;
96         }
97         rsaN = NULL;
98         rsaE = NULL;
99         pkey = EVP_PKEY_new();
100         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
101         if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) {
102             HKS_LOG_E("EVP_PKEY_set1_RSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
103             break;
104         }
105         result = EvpKeyToX509Format(pkey, x509Key);
106     } while (0);
107 
108     SELF_FREE_PTR(rsa, RSA_free);
109     SELF_FREE_PTR(rsaN, BN_free);
110     SELF_FREE_PTR(rsaE, BN_free);
111     SELF_FREE_PTR(pkey, EVP_PKEY_free);
112     return result;
113 }
114 #endif
115 
116 #if defined(HKS_SUPPORT_ECC_C) && defined(HKS_SUPPORT_ECC_GET_PUBLIC_KEY)
GetEccNid(uint32_t keySize,int32_t * nid)117 static int32_t GetEccNid(uint32_t keySize, int32_t *nid)
118 {
119     int32_t nids[][2] = {
120         /* 2 is size */
121         { 224, NID_secp224r1 },
122         { 256, NID_X9_62_prime256v1 },
123         { 384, NID_secp384r1 },
124         { 521, NID_secp521r1 },
125     };
126 
127     uint32_t nidCount = sizeof(nids) / sizeof(nids[0]);
128 
129     for (uint32_t i = 0; i < nidCount; i++) {
130         if (keySize == (uint32_t)nids[i][0]) {
131             *nid = nids[i][1];
132             return HKS_SUCCESS;
133         }
134     }
135 
136     HKS_LOG_E("not found nid!");
137     return HKS_ERROR_INVALID_ARGUMENT;
138 }
139 
EccToX509PublicKey(const uint32_t alg,uint32_t keySize,const struct HksBlob * x,const struct HksBlob * y,struct HksBlob * x509Key)140 static int32_t EccToX509PublicKey(
141     const uint32_t alg, uint32_t keySize, const struct HksBlob *x, const struct HksBlob *y, struct HksBlob *x509Key)
142 {
143     int32_t nid;
144     if (alg == HKS_ALG_SM2) {
145         nid = NID_sm2;
146     } else {
147         HKS_IF_NOT_SUCC_LOGE_RETURN(GetEccNid(keySize, &nid), HKS_ERROR_INVALID_ARGUMENT, "GetNidFromKeySize fail")
148     }
149 
150     EC_KEY *ecKey = NULL;
151     BIGNUM *ecX = NULL;
152     BIGNUM *ecY = NULL;
153     EVP_PKEY *pkey = NULL;
154     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
155     do {
156         ecKey = EC_KEY_new_by_curve_name(nid);
157         HKS_IF_NULL_LOGE_BREAK(ecKey,
158             "EC_KEY_new_by_curve_name error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
159 
160         ecX = BN_bin2bn(x->data, x->size, NULL);
161         ecY = BN_bin2bn(y->data, y->size, NULL);
162         if (ecX == NULL || ecY == NULL) {
163             HKS_LOG_E("x y point is null");
164             break;
165         }
166 
167         if (EC_KEY_set_public_key_affine_coordinates(ecKey, ecX, ecY) == 0) {
168             HKS_LOG_E("EC_KEY_set_public_key_affine_coordinates error %" LOG_PUBLIC "s",
169                 ERR_reason_error_string(ERR_get_error()));
170             break;
171         }
172 
173         EC_KEY_set_conv_form(ecKey, POINT_CONVERSION_UNCOMPRESSED);
174         pkey = EVP_PKEY_new();
175         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
176 
177         if (EVP_PKEY_set1_EC_KEY(pkey, ecKey) == 0) {
178             HKS_LOG_E("EVP_PKEY_set1_EC_KEY error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
179             break;
180         }
181 
182         ret = EvpKeyToX509Format(pkey, x509Key);
183     } while (0);
184 
185     SELF_FREE_PTR(ecKey, EC_KEY_free);
186     SELF_FREE_PTR(ecX, BN_free);
187     SELF_FREE_PTR(ecY, BN_free);
188     SELF_FREE_PTR(pkey, EVP_PKEY_free);
189     return ret;
190 }
191 #endif
192 
193 #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)194 static int32_t GetDsaPubKeyParam(
195     const struct HksBlob *publicKey, struct HksBlob *y, struct HksBlob *p, struct HksBlob *q, struct HksBlob *g)
196 {
197     if (publicKey->size < sizeof(struct KeyMaterialDsa)) {
198         HKS_LOG_E("Invaild dsa key material size!");
199         return HKS_ERROR_INVALID_ARGUMENT;
200     }
201 
202     struct KeyMaterialDsa *keyMaterial = (struct KeyMaterialDsa *)publicKey->data;
203     uint32_t keyMaterialSize = sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + keyMaterial->ySize +
204         keyMaterial->pSize + keyMaterial->qSize + keyMaterial->gSize;
205     if (publicKey->size < keyMaterialSize) {
206         HKS_LOG_E("translate to x509 public key invalid size");
207         return HKS_ERROR_INVALID_ARGUMENT;
208     }
209     uint32_t offset = sizeof(struct KeyMaterialDsa) + keyMaterial->xSize;
210     y->size = keyMaterial->ySize;
211     y->data = publicKey->data + offset;
212     offset += keyMaterial->ySize;
213     p->size = keyMaterial->pSize;
214     p->data = publicKey->data + offset;
215     offset += keyMaterial->pSize;
216     q->size = keyMaterial->qSize;
217     q->data = publicKey->data + offset;
218     offset += keyMaterial->qSize;
219     g->size = keyMaterial->gSize;
220     g->data = publicKey->data + offset;
221     return HKS_SUCCESS;
222 }
223 
DsaToX509PublicKey(const struct HksBlob * y,const struct HksBlob * p,const struct HksBlob * q,const struct HksBlob * g,struct HksBlob * x509Key)224 static int32_t DsaToX509PublicKey(const struct HksBlob *y, const struct HksBlob *p, const struct HksBlob *q,
225     const struct HksBlob *g, struct HksBlob *x509Key)
226 {
227     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
228     DSA *dsa = NULL;
229     BIGNUM *dsaY = BN_bin2bn(y->data, y->size, NULL);
230     BIGNUM *dsaP = BN_bin2bn(p->data, p->size, NULL);
231     BIGNUM *dsaQ = BN_bin2bn(q->data, q->size, NULL);
232     BIGNUM *dsaG = BN_bin2bn(g->data, g->size, NULL);
233     EVP_PKEY *pkey = NULL;
234     do {
235         dsa = DSA_new();
236         HKS_IF_NULL_LOGE_BREAK(dsa, "DSA_new error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
237 
238         if (dsaY == NULL || dsaP == NULL || dsaQ == NULL || dsaG == NULL) {
239             HKS_LOG_E("DSA parameter is null.");
240             break;
241         }
242 
243         if (DSA_set0_key(dsa, dsaY, NULL) != 1) {
244             HKS_LOG_E("DSA_set0_key error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
245             break;
246         }
247         dsaY = NULL;
248         if (DSA_set0_pqg(dsa, dsaP, dsaQ, dsaG) != 1) {
249             HKS_LOG_E("DSA_set0_pqg error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
250             break;
251         }
252         dsaP = NULL;
253         dsaQ = NULL;
254         dsaG = NULL;
255 
256         pkey = EVP_PKEY_new();
257         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
258 
259         if (EVP_PKEY_set1_DSA(pkey, dsa) == 0) {
260             HKS_LOG_E("EVP_PKEY_set1_DSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
261             break;
262         }
263 
264         ret = EvpKeyToX509Format(pkey, x509Key);
265     } while (0);
266 
267     SELF_FREE_PTR(dsa, DSA_free);
268     SELF_FREE_PTR(dsaY, BN_free);
269     SELF_FREE_PTR(dsaP, BN_free);
270     SELF_FREE_PTR(dsaQ, BN_free);
271     SELF_FREE_PTR(dsaG, BN_free);
272     SELF_FREE_PTR(pkey, EVP_PKEY_free);
273     return ret;
274 }
275 
DsaPublicKeyToX509(const struct HksBlob * publicKey,struct HksBlob * x509Key)276 static int32_t DsaPublicKeyToX509(const struct HksBlob *publicKey, struct HksBlob *x509Key)
277 {
278     struct HksBlob y = {0};
279     struct HksBlob p = {0};
280     struct HksBlob q = {0};
281     struct HksBlob g = {0};
282     int32_t ret = GetDsaPubKeyParam(publicKey, &y, &p, &q, &g);
283     HKS_IF_NOT_SUCC_RETURN(ret, ret)
284 
285     return DsaToX509PublicKey(&y, &p, &q, &g, x509Key);
286 }
287 
288 #endif
289 
290 #if defined(HKS_SUPPORT_DH_C) && defined(HKS_SUPPORT_DH_GET_PUBLIC_KEY)
GetDhNid(uint32_t keySize,int32_t * nid)291 static int32_t GetDhNid(uint32_t keySize, int32_t *nid)
292 {
293     switch (keySize) {
294         case HKS_DH_KEY_SIZE_2048:
295             *nid = NID_ffdhe2048;
296             return HKS_SUCCESS;
297         case HKS_DH_KEY_SIZE_3072:
298             *nid = NID_ffdhe3072;
299             return HKS_SUCCESS;
300         case HKS_DH_KEY_SIZE_4096:
301             *nid = NID_ffdhe4096;
302             return HKS_SUCCESS;
303         default:
304             return HKS_ERROR_INVALID_ARGUMENT;
305     }
306 }
307 
DhToX509PublicKey(uint32_t keySize,const struct HksBlob * pubKey,const struct HksBlob * privKey,struct HksBlob * x509Key)308 static int32_t DhToX509PublicKey(
309     uint32_t keySize, const struct HksBlob *pubKey, const struct HksBlob *privKey, struct HksBlob *x509Key)
310 {
311     int32_t nid;
312     int32_t ret = GetDhNid(keySize, &nid);
313     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetNidFromKeySize fail")
314 
315     BIGNUM *pub = NULL;
316     DH *dh = NULL;
317     EVP_PKEY *pkey = NULL;
318     do {
319         dh = DH_new_by_nid(nid);
320         HKS_IF_NULL_LOGE_BREAK(dh, "DH_new_by_nid error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
321 
322         pub = BN_bin2bn(pubKey->data, pubKey->size, NULL);
323         HKS_IF_NULL_LOGE_BREAK(pub, "BN_bin2bn error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
324 
325         if (DH_set0_key(dh, pub, NULL) != 1) {
326             HKS_LOG_E("DH_set0_key error:%" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
327             break;
328         }
329         pub = NULL;
330 
331         pkey = EVP_PKEY_new();
332         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
333 
334         if (EVP_PKEY_set1_DH(pkey, dh) == 0) {
335             HKS_LOG_E("EVP_PKEY_set1_DH error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
336             break;
337         }
338 
339         ret = EvpKeyToX509Format(pkey, x509Key);
340     } while (0);
341 
342     SELF_FREE_PTR(dh, DH_free);
343     SELF_FREE_PTR(pub, BN_free);
344     SELF_FREE_PTR(pkey, EVP_PKEY_free);
345     return ret;
346 }
347 #endif
348 #endif
349 
350 #if defined(HKS_SUPPORT_X25519_C) || defined(HKS_SUPPORT_ED25519_C)
Curve25519ToX509PublicKey(const struct HksBlob * publicKey,struct HksBlob * x509Key)351 static int32_t Curve25519ToX509PublicKey(const struct HksBlob *publicKey, struct HksBlob *x509Key)
352 {
353     if (publicKey->size != HKS_KEY_BYTES(HKS_CURVE25519_KEY_SIZE_256)) {
354         HKS_LOG_E("Invalid public key size! key size = 0x%" LOG_PUBLIC "X", publicKey->size);
355         return HKS_ERROR_INVALID_ARGUMENT;
356     }
357 
358     x509Key->data = (uint8_t *)HksMalloc(publicKey->size);
359     HKS_IF_NULL_LOGE_RETURN(x509Key->data, HKS_ERROR_MALLOC_FAIL,
360         "X25519/Ed25519 to x509 public key malloc x509 key data failed!")
361 
362     (void)memcpy_s(x509Key->data, publicKey->size, publicKey->data, publicKey->size);
363     x509Key->size = publicKey->size;
364 
365     return HKS_SUCCESS;
366 }
367 #endif
368 
TranslateToX509PublicKey(const struct HksBlob * publicKey,struct HksBlob * x509Key)369 int32_t TranslateToX509PublicKey(const struct HksBlob *publicKey, struct HksBlob *x509Key)
370 {
371     if ((publicKey == NULL) || (publicKey->data == NULL) || (publicKey->size == 0) || (x509Key == NULL)) {
372         HKS_LOG_E("translate to x509 public key invalid args");
373         return HKS_ERROR_INVALID_ARGUMENT;
374     }
375 
376     if (publicKey->size < sizeof(struct HksPubKeyInfo)) {
377         HKS_LOG_E("translate to x509 public key invalid publicKey size");
378         return HKS_ERROR_INVALID_ARGUMENT;
379     }
380 
381     struct HksPubKeyInfo *publicKeyInfo = (struct HksPubKeyInfo *)publicKey->data;
382     uint32_t offset = sizeof(struct HksPubKeyInfo);
383     if ((publicKey->size - offset) < publicKeyInfo->nOrXSize) {
384         HKS_LOG_E("translate to x509 public key invalid nOrXSize size");
385         return HKS_ERROR_INVALID_ARGUMENT;
386     }
387 
388     struct HksBlob material1 = { publicKeyInfo->nOrXSize, publicKey->data + offset };
389     offset += publicKeyInfo->nOrXSize;
390     if ((publicKey->size - offset) < publicKeyInfo->eOrYSize) {
391         HKS_LOG_E("translate to x509 public key invalid eOrYSize size");
392         return HKS_ERROR_INVALID_ARGUMENT;
393     }
394 
395     struct HksBlob material2 = { publicKeyInfo->eOrYSize, publicKey->data + offset };
396     switch (publicKeyInfo->keyAlg) {
397 #if defined(HKS_SUPPORT_RSA_C) && defined(HKS_SUPPORT_RSA_GET_PUBLIC_KEY)
398         case HKS_ALG_RSA:
399             return RsaToX509PublicKey(&material1, &material2, x509Key);
400 #endif
401 #if (defined(HKS_SUPPORT_ECC_C) && defined(HKS_SUPPORT_ECC_GET_PUBLIC_KEY)) || \
402         (defined(HKS_SUPPORT_SM2_C) && defined(HKS_SUPPORT_SM2_GET_PUBLIC_KEY))
403         case HKS_ALG_ECC:
404         case HKS_ALG_SM2:
405             return EccToX509PublicKey(publicKeyInfo->keyAlg, publicKeyInfo->keySize, &material1, &material2, x509Key);
406 #endif
407 #if defined(HKS_SUPPORT_DSA_C) && defined(HKS_SUPPORT_DSA_GET_PUBLIC_KEY)
408         case HKS_ALG_DSA:
409             return DsaPublicKeyToX509(publicKey, x509Key);
410 #endif
411 #if defined(HKS_SUPPORT_X25519_C) || defined(HKS_SUPPORT_ED25519_C)
412         case HKS_ALG_X25519:
413         case HKS_ALG_ED25519:
414             return Curve25519ToX509PublicKey(&material1, x509Key);
415 #endif
416 #if defined(HKS_SUPPORT_DH_C) && defined(HKS_SUPPORT_DH_GET_PUBLIC_KEY)
417         case HKS_ALG_DH:
418             return DhToX509PublicKey(publicKeyInfo->keySize, &material1, NULL, x509Key);
419 #endif
420         default:
421             HKS_LOG_E("Unsupport alg type! type = 0x%" LOG_PUBLIC "X", publicKeyInfo->keyAlg);
422             return HKS_ERROR_INVALID_ARGUMENT;
423     }
424 }
425 
426 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C) || defined(HKS_SUPPORT_DSA_C) || \
427     defined(HKS_SUPPORT_DH_C)
428 #ifdef HKS_SUPPORT_RSA_C
X509PublicKeyToRsa(EVP_PKEY * pkey,struct HksBlob * rsaPublicKey)429 static int32_t X509PublicKeyToRsa(EVP_PKEY *pkey, struct HksBlob *rsaPublicKey)
430 {
431     RSA *rsa = EVP_PKEY_get0_RSA(pkey);
432     HKS_IF_NULL_LOGE_RETURN(rsa, HKS_ERROR_NULL_POINTER,
433         "EVP_PKEY_get1_RSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
434 
435     int nSize = BN_num_bytes(RSA_get0_n(rsa));
436     int eSize = BN_num_bytes(RSA_get0_e(rsa));
437     if (nSize <= 0 || eSize <= 0) {
438         HKS_LOG_E("X509PublicKeyToRsa BN_num_bytes failed");
439         return HKS_ERROR_INTERNAL_ERROR;
440     }
441 
442     /* n and e in RSA algorithm is small, will never overflow. */
443     uint32_t totalSize = (uint32_t)nSize + (uint32_t)eSize + sizeof(struct HksPubKeyInfo);
444     uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
445     HKS_IF_NULL_LOGE_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL, "X509PublicKeyToRsa keyBuffer failed")
446 
447     struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)keyBuffer;
448     pubKeyInfo->keyAlg = HKS_ALG_RSA;
449     pubKeyInfo->keySize = ((uint32_t)RSA_size(rsa)) * HKS_BITS_PER_BYTE;
450     pubKeyInfo->nOrXSize = (uint32_t)nSize;
451     pubKeyInfo->eOrYSize = (uint32_t)eSize;
452     pubKeyInfo->placeHolder = 0;
453     if (BN_bn2bin(RSA_get0_n(rsa), keyBuffer + sizeof(struct HksPubKeyInfo)) == 0 ||
454         BN_bn2bin(RSA_get0_e(rsa), keyBuffer + sizeof(struct HksPubKeyInfo) + (uint32_t)nSize) == 0) {
455         HKS_LOG_E("BN_bn2bin error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
456         HKS_FREE_PTR(keyBuffer);
457         return HKS_ERROR_INTERNAL_ERROR;
458     }
459 
460     rsaPublicKey->data = keyBuffer;
461     rsaPublicKey->size = totalSize;
462     return HKS_SUCCESS;
463 }
464 #endif
465 
466 #ifdef HKS_SUPPORT_ECC_C
EcKeyToPublicKey(const uint32_t alg,EC_KEY * ecKey,struct HksBlob * eccPublicKey)467 static int32_t EcKeyToPublicKey(const uint32_t alg, EC_KEY *ecKey, struct HksBlob *eccPublicKey)
468 {
469     BIGNUM *x = BN_new();
470     BIGNUM *y = BN_new();
471     int32_t ret;
472     do {
473         ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
474         if (x == NULL || y == NULL) {
475             HKS_LOG_E("X509PublicKeyToEcc BN_new failed");
476             break;
477         }
478 
479         if (EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ecKey), EC_KEY_get0_public_key(ecKey), x, y, NULL) ==
480             0) {
481             HKS_LOG_E("EC_POINT_get_affine_coordinates_GFp error %" LOG_PUBLIC "s",
482                 ERR_reason_error_string(ERR_get_error()));
483             break;
484         }
485 
486         uint32_t keyLen = (uint32_t)EC_GROUP_order_bits(EC_KEY_get0_group(ecKey));
487         uint32_t xSize = HKS_KEY_BYTES(keyLen);
488         uint32_t ySize = HKS_KEY_BYTES(keyLen);
489 
490         if ((keyLen == 0) || (keyLen > HKS_ECC_KEY_SIZE_521)) {
491             HKS_LOG_E("invalid ecc key length");
492             break;
493         }
494 
495         uint32_t totalSize = xSize + ySize + sizeof(struct HksPubKeyInfo);
496         uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
497         HKS_IF_NULL_LOGE_BREAK(keyBuffer, "X509PublicKeyToRsa keyBuffer failed")
498 
499         struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)keyBuffer;
500         pubKeyInfo->keyAlg = alg;
501         pubKeyInfo->keySize = keyLen;
502         pubKeyInfo->nOrXSize = xSize;
503         pubKeyInfo->eOrYSize = ySize;
504         pubKeyInfo->placeHolder = 0;
505         if (BN_bn2binpad(x, keyBuffer + sizeof(struct HksPubKeyInfo), xSize) == 0 ||
506             BN_bn2binpad(y, keyBuffer + sizeof(struct HksPubKeyInfo) + xSize, ySize) == 0) {
507             HKS_LOG_E("BN_bn2binpad error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
508             HKS_FREE_PTR(keyBuffer);
509             break;
510         }
511 
512         ret = HKS_SUCCESS;
513         eccPublicKey->data = keyBuffer;
514         eccPublicKey->size = totalSize;
515     } while (0);
516 
517     SELF_FREE_PTR(x, BN_free);
518     SELF_FREE_PTR(y, BN_free);
519     return ret;
520 }
521 
X509PublicKeyToEcc(const uint32_t alg,EVP_PKEY * pkey,struct HksBlob * eccPublicKey)522 static int32_t X509PublicKeyToEcc(const uint32_t alg, EVP_PKEY *pkey, struct HksBlob *eccPublicKey)
523 {
524     EC_KEY *ecKey = EVP_PKEY_get0_EC_KEY(pkey);
525     HKS_IF_NULL_LOGE_RETURN(ecKey, HKS_ERROR_NULL_POINTER,
526         "EVP_PKEY_get1_EC_KEY error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
527 
528     return EcKeyToPublicKey(alg, ecKey, eccPublicKey);
529 }
530 #endif
531 
532 #ifdef HKS_SUPPORT_DSA_C
533 
GetDsaKeyInfo(const DSA * dsa,const BIGNUM ** info,uint32_t * infoSize,GetDsaInfoFunc func)534 static int32_t GetDsaKeyInfo(const DSA *dsa, const BIGNUM **info, uint32_t *infoSize, GetDsaInfoFunc func)
535 {
536     *info = func(dsa);
537     HKS_IF_NULL_RETURN(*info, HKS_ERROR_NULL_POINTER)
538 
539     int size = BN_num_bytes(*info);
540     if (size <= 0) {
541         return HKS_ERROR_INVALID_ARGUMENT;
542     }
543 
544     *infoSize = (uint32_t)size;
545     return HKS_SUCCESS;
546 }
547 
X509PublicKeyToDsa(EVP_PKEY * pkey,struct HksBlob * dsaPublicKey)548 static int32_t X509PublicKeyToDsa(EVP_PKEY *pkey, struct HksBlob *dsaPublicKey)
549 {
550     DSA *dsa = EVP_PKEY_get0_DSA(pkey);
551     HKS_IF_NULL_LOGE_RETURN(dsa, HKS_ERROR_NULL_POINTER,
552         "EVP_PKEY_get1_DSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
553 
554     const BIGNUM *y = NULL;
555     const BIGNUM *p = NULL;
556     const BIGNUM *q = NULL;
557     const BIGNUM *g = NULL;
558     uint32_t ySize = 0;
559     uint32_t pSize = 0;
560     uint32_t qSize = 0;
561     uint32_t gSize = 0;
562 
563     if (GetDsaKeyInfo(dsa, &y, &ySize, DSA_get0_pub_key) != HKS_SUCCESS ||
564         GetDsaKeyInfo(dsa, &p, &pSize, DSA_get0_p) != HKS_SUCCESS ||
565         GetDsaKeyInfo(dsa, &q, &qSize, DSA_get0_q) != HKS_SUCCESS ||
566         GetDsaKeyInfo(dsa, &g, &gSize, DSA_get0_g) != HKS_SUCCESS) {
567         return HKS_ERROR_INVALID_ARGUMENT;
568     }
569 
570     uint32_t totalSize = sizeof(struct KeyMaterialDsa) + ySize + pSize + qSize + gSize;
571     uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
572     HKS_IF_NULL_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL)
573 
574     if ((ySize > UINT32_MAX - HKS_BITS_PER_BYTE) ||
575         ((ySize + HKS_BITS_PER_BYTE - 1) / HKS_BITS_PER_BYTE > UINT32_MAX / (HKS_BITS_PER_BYTE * HKS_BITS_PER_BYTE))) {
576         HKS_FREE_PTR(keyBuffer);
577         return HKS_ERROR_BAD_STATE;
578     }
579 
580     struct KeyMaterialDsa *keyMaterial = (struct KeyMaterialDsa *)keyBuffer;
581     keyMaterial->keyAlg = HKS_ALG_DSA;
582     keyMaterial->keySize = (ySize + HKS_BITS_PER_BYTE - 1) / HKS_BITS_PER_BYTE * HKS_BITS_PER_BYTE * HKS_BITS_PER_BYTE;
583     keyMaterial->xSize = 0;
584     keyMaterial->ySize = ySize;
585     keyMaterial->pSize = pSize;
586     keyMaterial->qSize = qSize;
587     keyMaterial->gSize = gSize;
588 
589     if ((BN_bn2bin(y, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize) == 0) ||
590         (BN_bn2bin(p, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + ySize) == 0) ||
591         (BN_bn2bin(q, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + ySize + pSize) == 0) ||
592         (BN_bn2bin(g, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + ySize + pSize + qSize) == 0)) {
593         HKS_LOG_E("BN_bn2bin error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
594         HKS_FREE_PTR(keyBuffer);
595         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
596     }
597     dsaPublicKey->size = totalSize;
598     dsaPublicKey->data = keyBuffer;
599 
600     return HKS_SUCCESS;
601 }
602 #endif
603 
604 #ifdef HKS_SUPPORT_DH_C
X509PublicKeyToDh(EVP_PKEY * pkey,struct HksBlob * dhPublicKey)605 static int32_t X509PublicKeyToDh(EVP_PKEY *pkey, struct HksBlob *dhPublicKey)
606 {
607     DH *dh = EVP_PKEY_get0_DH(pkey);
608     HKS_IF_NULL_LOGE_RETURN(dh, HKS_ERROR_NULL_POINTER,
609         "EVP_PKEY_get0_DH error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
610 
611     const BIGNUM *pubKey = DH_get0_pub_key(dh);
612     HKS_IF_NULL_LOGE_RETURN(pubKey, HKS_ERROR_NULL_POINTER,
613         "DH_get0_pub_key error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
614 
615     uint32_t pubKeySize = (uint32_t)BN_num_bytes(pubKey);
616     if (pubKeySize > UINT32_MAX - sizeof(struct KeyMaterialDh)) {
617         HKS_LOG_E("the size is too long, failed");
618         return HKS_ERROR_BAD_STATE;
619     }
620 
621     uint32_t totalSize = sizeof(struct KeyMaterialDh) + pubKeySize;
622     uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
623     HKS_IF_NULL_LOGE_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL, "alloc keyBuffer failed")
624     struct KeyMaterialDh *keyMaterial = (struct KeyMaterialDh *)keyBuffer;
625     keyMaterial->keyAlg = HKS_ALG_DH;
626     keyMaterial->keySize = (uint32_t)DH_bits(dh);
627     keyMaterial->pubKeySize = pubKeySize;
628     keyMaterial->priKeySize = 0;
629     keyMaterial->reserved = 0;
630 
631     BN_bn2bin(pubKey, keyBuffer + sizeof(struct KeyMaterialDh));
632 
633     dhPublicKey->size = totalSize;
634     dhPublicKey->data = keyBuffer;
635 
636     return HKS_SUCCESS;
637 }
638 #endif
639 
TranslateFromX509PublicKey(const uint32_t alg,const struct HksBlob * x509Key,struct HksBlob * publicKey)640 int32_t TranslateFromX509PublicKey(const uint32_t alg, const struct HksBlob *x509Key, struct HksBlob *publicKey)
641 {
642     if (x509Key == NULL || x509Key->data == NULL || x509Key->size == 0 || publicKey == NULL) {
643         HKS_LOG_E("TranslateFromX509PublicKey invalid args");
644         return HKS_ERROR_INVALID_ARGUMENT;
645     }
646 
647     uint8_t *data = x509Key->data;
648 
649     EVP_PKEY *pkey = d2i_PUBKEY(NULL, (const unsigned char **)&data, x509Key->size);
650     HKS_IF_NULL_RETURN(pkey, HKS_ERROR_INVALID_ARGUMENT)
651 
652     int32_t ret;
653     int32_t keyType = EVP_PKEY_base_id(pkey);
654     if (keyType == EVP_PKEY_RSA) {
655 #ifdef HKS_SUPPORT_RSA_C
656         ret = X509PublicKeyToRsa(pkey, publicKey);
657 #else
658         ret = HKS_ERROR_INVALID_ALGORITHM;
659 #endif
660     } else if (keyType == EVP_PKEY_EC) {
661 #if defined(HKS_SUPPORT_ECC_C) || defined(HKS_SUPPORT_SM2_C)
662         ret = X509PublicKeyToEcc(alg, pkey, publicKey);
663 #else
664         ret = HKS_ERROR_INVALID_ALGORITHM;
665 #endif
666     } else if (keyType == EVP_PKEY_DSA) {
667 #ifdef HKS_SUPPORT_DSA_C
668         ret = X509PublicKeyToDsa(pkey, publicKey);
669 #else
670         ret = HKS_ERROR_INVALID_ALGORITHM;
671 #endif
672     } else if (keyType == EVP_PKEY_DH) {
673 #ifdef HKS_SUPPORT_DH_C
674         ret = X509PublicKeyToDh(pkey, publicKey);
675 #else
676         ret = HKS_ERROR_INVALID_ALGORITHM;
677 #endif
678     } else {
679         HKS_LOG_E("Unsupport alg type!");
680         ret = HKS_ERROR_INVALID_ARGUMENT;
681     }
682 
683     SELF_FREE_PTR(pkey, EVP_PKEY_free);
684     return ret;
685 }
686 #endif
687 
688