• 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         HKS_FREE(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)
Sm2ToX509PublicKey(const uint32_t alg,uint32_t keySize,const struct HksBlob * x,const struct HksBlob * y,struct HksBlob * x509Key)199 static int32_t Sm2ToX509PublicKey(
200     const uint32_t alg, uint32_t keySize, const struct HksBlob *x, const struct HksBlob *y, struct HksBlob *x509Key)
201 {
202     return EccToX509PublicKey(alg, keySize, x, y, x509Key);
203 }
204 #endif
205 
206 #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)207 static int32_t GetDsaPubKeyParam(
208     const struct HksBlob *publicKey, struct HksBlob *y, struct HksBlob *p, struct HksBlob *q, struct HksBlob *g)
209 {
210     HKS_IF_TRUE_LOGE_RETURN(publicKey->size < sizeof(struct KeyMaterialDsa), HKS_ERROR_INVALID_ARGUMENT,
211         "Invaild dsa key material size!")
212 
213     struct KeyMaterialDsa *keyMaterial = (struct KeyMaterialDsa *)publicKey->data;
214     uint32_t keyMaterialSize = sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + keyMaterial->ySize +
215         keyMaterial->pSize + keyMaterial->qSize + keyMaterial->gSize;
216     HKS_IF_TRUE_LOGE_RETURN(publicKey->size < keyMaterialSize, HKS_ERROR_INVALID_ARGUMENT,
217         "translate to x509 public key invalid size")
218     uint32_t offset = sizeof(struct KeyMaterialDsa) + keyMaterial->xSize;
219     y->size = keyMaterial->ySize;
220     y->data = publicKey->data + offset;
221     offset += keyMaterial->ySize;
222     p->size = keyMaterial->pSize;
223     p->data = publicKey->data + offset;
224     offset += keyMaterial->pSize;
225     q->size = keyMaterial->qSize;
226     q->data = publicKey->data + offset;
227     offset += keyMaterial->qSize;
228     g->size = keyMaterial->gSize;
229     g->data = publicKey->data + offset;
230     return HKS_SUCCESS;
231 }
232 
DsaToX509PublicKey(const struct HksBlob * y,const struct HksBlob * p,const struct HksBlob * q,const struct HksBlob * g,struct HksBlob * x509Key)233 static int32_t DsaToX509PublicKey(const struct HksBlob *y, const struct HksBlob *p, const struct HksBlob *q,
234     const struct HksBlob *g, struct HksBlob *x509Key)
235 {
236     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
237     DSA *dsa = NULL;
238     BIGNUM *dsaY = BN_bin2bn(y->data, y->size, NULL);
239     BIGNUM *dsaP = BN_bin2bn(p->data, p->size, NULL);
240     BIGNUM *dsaQ = BN_bin2bn(q->data, q->size, NULL);
241     BIGNUM *dsaG = BN_bin2bn(g->data, g->size, NULL);
242     EVP_PKEY *pkey = NULL;
243     do {
244         dsa = DSA_new();
245         HKS_IF_NULL_LOGE_BREAK(dsa, "DSA_new error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
246 
247         if (dsaY == NULL || dsaP == NULL || dsaQ == NULL || dsaG == NULL) {
248             HKS_LOG_E("DSA parameter is null.");
249             break;
250         }
251 
252         if (DSA_set0_key(dsa, dsaY, NULL) != 1) {
253             HKS_LOG_E("DSA_set0_key error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
254             break;
255         }
256         dsaY = NULL;
257         if (DSA_set0_pqg(dsa, dsaP, dsaQ, dsaG) != 1) {
258             HKS_LOG_E("DSA_set0_pqg error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
259             break;
260         }
261         dsaP = NULL;
262         dsaQ = NULL;
263         dsaG = NULL;
264 
265         pkey = EVP_PKEY_new();
266         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
267 
268         if (EVP_PKEY_set1_DSA(pkey, dsa) == 0) {
269             HKS_LOG_E("EVP_PKEY_set1_DSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
270             break;
271         }
272 
273         ret = EvpKeyToX509Format(pkey, x509Key);
274     } while (0);
275 
276     SELF_FREE_PTR(dsa, DSA_free)
277     SELF_FREE_PTR(dsaY, BN_free)
278     SELF_FREE_PTR(dsaP, BN_free)
279     SELF_FREE_PTR(dsaQ, BN_free)
280     SELF_FREE_PTR(dsaG, BN_free)
281     SELF_FREE_PTR(pkey, EVP_PKEY_free)
282     return ret;
283 }
284 
DsaPublicKeyToX509(const struct HksBlob * publicKey,struct HksBlob * x509Key)285 static int32_t DsaPublicKeyToX509(const struct HksBlob *publicKey, struct HksBlob *x509Key)
286 {
287     struct HksBlob y = {0};
288     struct HksBlob p = {0};
289     struct HksBlob q = {0};
290     struct HksBlob g = {0};
291     int32_t ret = GetDsaPubKeyParam(publicKey, &y, &p, &q, &g);
292     HKS_IF_NOT_SUCC_RETURN(ret, ret)
293 
294     return DsaToX509PublicKey(&y, &p, &q, &g, x509Key);
295 }
296 
297 #endif
298 
299 #if defined(HKS_SUPPORT_DH_C) && defined(HKS_SUPPORT_DH_GET_PUBLIC_KEY)
GetDhNid(uint32_t keySize,int32_t * nid)300 static int32_t GetDhNid(uint32_t keySize, int32_t *nid)
301 {
302     switch (keySize) {
303         case HKS_DH_KEY_SIZE_2048:
304             *nid = NID_ffdhe2048;
305             return HKS_SUCCESS;
306         case HKS_DH_KEY_SIZE_3072:
307             *nid = NID_ffdhe3072;
308             return HKS_SUCCESS;
309         case HKS_DH_KEY_SIZE_4096:
310             *nid = NID_ffdhe4096;
311             return HKS_SUCCESS;
312         default:
313             return HKS_ERROR_INVALID_ARGUMENT;
314     }
315 }
316 
DhToX509PublicKey(uint32_t keySize,const struct HksBlob * pubKey,const struct HksBlob * privKey,struct HksBlob * x509Key)317 static int32_t DhToX509PublicKey(
318     uint32_t keySize, const struct HksBlob *pubKey, const struct HksBlob *privKey, struct HksBlob *x509Key)
319 {
320     int32_t nid;
321     int32_t ret = GetDhNid(keySize, &nid);
322     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetNidFromKeySize fail")
323 
324     BIGNUM *pub = NULL;
325     DH *dh = NULL;
326     EVP_PKEY *pkey = NULL;
327     do {
328         dh = DH_new_by_nid(nid);
329         HKS_IF_NULL_LOGE_BREAK(dh, "DH_new_by_nid error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
330 
331         pub = BN_bin2bn(pubKey->data, pubKey->size, NULL);
332         HKS_IF_NULL_LOGE_BREAK(pub, "BN_bin2bn error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
333 
334         if (DH_set0_key(dh, pub, NULL) != 1) {
335             HKS_LOG_E("DH_set0_key error:%" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
336             break;
337         }
338         pub = NULL;
339 
340         pkey = EVP_PKEY_new();
341         HKS_IF_NULL_LOGE_BREAK(pkey, "pkey is null")
342 
343         if (EVP_PKEY_set1_DH(pkey, dh) == 0) {
344             HKS_LOG_E("EVP_PKEY_set1_DH error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
345             break;
346         }
347 
348         ret = EvpKeyToX509Format(pkey, x509Key);
349     } while (0);
350 
351     SELF_FREE_PTR(dh, DH_free)
352     SELF_FREE_PTR(pub, BN_free)
353     SELF_FREE_PTR(pkey, EVP_PKEY_free)
354     return ret;
355 }
356 #endif
357 #endif
358 
359 #if defined(HKS_SUPPORT_X25519_C) || defined(HKS_SUPPORT_ED25519_C)
Curve25519ToX509PublicKey(const struct HksBlob * publicKey,struct HksBlob * x509Key)360 static int32_t Curve25519ToX509PublicKey(const struct HksBlob *publicKey, struct HksBlob *x509Key)
361 {
362     HKS_IF_TRUE_LOGE_RETURN(publicKey->size != HKS_KEY_BYTES(HKS_CURVE25519_KEY_SIZE_256), HKS_ERROR_INVALID_ARGUMENT,
363         "Invalid public key size! key size = 0x%" LOG_PUBLIC "X", publicKey->size)
364 
365     x509Key->data = (uint8_t *)HksMalloc(publicKey->size);
366     HKS_IF_NULL_LOGE_RETURN(x509Key->data, HKS_ERROR_MALLOC_FAIL,
367         "X25519/Ed25519 to x509 public key malloc x509 key data failed!")
368 
369     (void)memcpy_s(x509Key->data, publicKey->size, publicKey->data, publicKey->size);
370     x509Key->size = publicKey->size;
371 
372     return HKS_SUCCESS;
373 }
374 #endif
375 
TranslateToX509PublicKeySwitchAlg(const struct HksPubKeyInfo * publicKeyInfo,const struct HksBlob * material1,const struct HksBlob * material2,const struct HksBlob * publicKey,struct HksBlob * x509Key)376 static int32_t TranslateToX509PublicKeySwitchAlg(const struct HksPubKeyInfo *publicKeyInfo,
377     const struct HksBlob *material1, const struct HksBlob *material2, const struct HksBlob *publicKey,
378     struct HksBlob *x509Key)
379 {
380     switch (publicKeyInfo->keyAlg) {
381 #if defined(HKS_SUPPORT_RSA_C) && defined(HKS_SUPPORT_RSA_GET_PUBLIC_KEY)
382         case HKS_ALG_RSA:
383             return RsaToX509PublicKey(material1, material2, x509Key);
384 #endif
385 #if defined(HKS_SUPPORT_ECC_C) && defined(HKS_SUPPORT_ECC_GET_PUBLIC_KEY)
386         case HKS_ALG_ECC:
387             return EccToX509PublicKey(publicKeyInfo->keyAlg, publicKeyInfo->keySize, material1, material2, x509Key);
388 #endif
389 #if defined(HKS_SUPPORT_SM2_C) && defined(HKS_SUPPORT_SM2_GET_PUBLIC_KEY)
390         case HKS_ALG_SM2:
391             return Sm2ToX509PublicKey(publicKeyInfo->keyAlg, publicKeyInfo->keySize, material1, material2, x509Key);
392 #endif
393 #if defined(HKS_SUPPORT_DSA_C) && defined(HKS_SUPPORT_DSA_GET_PUBLIC_KEY)
394         case HKS_ALG_DSA:
395             return DsaPublicKeyToX509(publicKey, x509Key);
396 #endif
397 #if defined(HKS_SUPPORT_X25519_C) || defined(HKS_SUPPORT_ED25519_C)
398         case HKS_ALG_X25519:
399         case HKS_ALG_ED25519:
400             return Curve25519ToX509PublicKey(material1, x509Key);
401 #endif
402 #if defined(HKS_SUPPORT_DH_C) && defined(HKS_SUPPORT_DH_GET_PUBLIC_KEY)
403         case HKS_ALG_DH:
404             return DhToX509PublicKey(publicKeyInfo->keySize, material1, NULL, x509Key);
405 #endif
406         default:
407             HKS_LOG_E("Unsupport alg type! type = 0x%" LOG_PUBLIC "X", publicKeyInfo->keyAlg);
408             return HKS_ERROR_INVALID_ARGUMENT;
409     }
410 }
411 
TranslateToX509PublicKey(const struct HksBlob * publicKey,struct HksBlob * x509Key)412 int32_t TranslateToX509PublicKey(const struct HksBlob *publicKey, struct HksBlob *x509Key)
413 {
414     if ((publicKey == NULL) || (publicKey->data == NULL) || (publicKey->size == 0) || (x509Key == NULL)) {
415         HKS_LOG_E("translate to x509 public key invalid args");
416         return HKS_ERROR_INVALID_ARGUMENT;
417     }
418 
419     if (publicKey->size < sizeof(struct HksPubKeyInfo)) {
420         HKS_LOG_E("translate to x509 public key invalid publicKey size");
421         return HKS_ERROR_INVALID_ARGUMENT;
422     }
423 
424     struct HksPubKeyInfo *publicKeyInfo = (struct HksPubKeyInfo *)publicKey->data;
425     uint32_t offset = sizeof(struct HksPubKeyInfo);
426     HKS_IF_TRUE_LOGE_RETURN(publicKey->size - offset < publicKeyInfo->nOrXSize, HKS_ERROR_INVALID_ARGUMENT,
427         "translate to x509 public key invalid nOrXSize size")
428 
429     struct HksBlob material1 = { publicKeyInfo->nOrXSize, publicKey->data + offset };
430     offset += publicKeyInfo->nOrXSize;
431     HKS_IF_TRUE_LOGE_RETURN(publicKey->size - offset < publicKeyInfo->eOrYSize, HKS_ERROR_INVALID_ARGUMENT,
432         "translate to x509 public key invalid eOrYSize size")
433 
434     struct HksBlob material2 = { publicKeyInfo->eOrYSize, publicKey->data + offset };
435     return TranslateToX509PublicKeySwitchAlg(publicKeyInfo, &material1, &material2, publicKey, x509Key);
436 }
437 
438 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C) || defined(HKS_SUPPORT_DSA_C) || \
439     defined(HKS_SUPPORT_DH_C)
440 #ifdef HKS_SUPPORT_RSA_C
X509PublicKeyToRsa(EVP_PKEY * pkey,struct HksBlob * rsaPublicKey)441 static int32_t X509PublicKeyToRsa(EVP_PKEY *pkey, struct HksBlob *rsaPublicKey)
442 {
443     const RSA *rsa = EVP_PKEY_get0_RSA(pkey);
444     HKS_IF_NULL_LOGE_RETURN(rsa, HKS_ERROR_NULL_POINTER,
445         "EVP_PKEY_get1_RSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
446 
447     int nSize = BN_num_bytes(RSA_get0_n(rsa));
448     int eSize = BN_num_bytes(RSA_get0_e(rsa));
449     if (nSize <= 0 || eSize <= 0) {
450         HKS_LOG_E("X509PublicKeyToRsa BN_num_bytes failed");
451         return HKS_ERROR_INTERNAL_ERROR;
452     }
453 
454     /* n and e in RSA algorithm is small, will never overflow. */
455     uint32_t totalSize = (uint32_t)nSize + (uint32_t)eSize + sizeof(struct HksPubKeyInfo);
456     uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
457     HKS_IF_NULL_LOGE_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL, "X509PublicKeyToRsa keyBuffer failed")
458 
459     struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)keyBuffer;
460     pubKeyInfo->keyAlg = HKS_ALG_RSA;
461     pubKeyInfo->keySize = ((uint32_t)RSA_size(rsa)) * HKS_BITS_PER_BYTE;
462     pubKeyInfo->nOrXSize = (uint32_t)nSize;
463     pubKeyInfo->eOrYSize = (uint32_t)eSize;
464     pubKeyInfo->placeHolder = 0;
465     if (BN_bn2bin(RSA_get0_n(rsa), keyBuffer + sizeof(struct HksPubKeyInfo)) == 0 ||
466         BN_bn2bin(RSA_get0_e(rsa), keyBuffer + sizeof(struct HksPubKeyInfo) + (uint32_t)nSize) == 0) {
467         HKS_LOG_E("BN_bn2bin error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
468         HKS_FREE(keyBuffer);
469         return HKS_ERROR_INTERNAL_ERROR;
470     }
471 
472     rsaPublicKey->data = keyBuffer;
473     rsaPublicKey->size = totalSize;
474     return HKS_SUCCESS;
475 }
476 #endif
477 
478 #ifdef HKS_SUPPORT_ECC_C
EcKeyToPublicKey(const uint32_t alg,const EC_KEY * ecKey,struct HksBlob * eccPublicKey)479 static int32_t EcKeyToPublicKey(const uint32_t alg, const EC_KEY *ecKey, struct HksBlob *eccPublicKey)
480 {
481     BIGNUM *x = BN_new();
482     BIGNUM *y = BN_new();
483     int32_t ret;
484     do {
485         ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
486         if (x == NULL || y == NULL) {
487             HKS_LOG_E("X509PublicKeyToEcc BN_new failed");
488             break;
489         }
490 
491         if (EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ecKey), EC_KEY_get0_public_key(ecKey), x, y, NULL) ==
492             0) {
493             HKS_LOG_E("EC_POINT_get_affine_coordinates_GFp error %" LOG_PUBLIC "s",
494                 ERR_reason_error_string(ERR_get_error()));
495             break;
496         }
497 
498         uint32_t keyLen = (uint32_t)EC_GROUP_order_bits(EC_KEY_get0_group(ecKey));
499         uint32_t xSize = HKS_KEY_BYTES(keyLen);
500         uint32_t ySize = HKS_KEY_BYTES(keyLen);
501 
502         if ((keyLen == 0) || (keyLen > HKS_ECC_KEY_SIZE_521)) {
503             HKS_LOG_E("invalid ecc key length");
504             break;
505         }
506 
507         uint32_t totalSize = xSize + ySize + sizeof(struct HksPubKeyInfo);
508         uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
509         HKS_IF_NULL_LOGE_BREAK(keyBuffer, "X509PublicKeyToRsa keyBuffer failed")
510 
511         struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)keyBuffer;
512         pubKeyInfo->keyAlg = alg;
513         pubKeyInfo->keySize = keyLen;
514         pubKeyInfo->nOrXSize = xSize;
515         pubKeyInfo->eOrYSize = ySize;
516         pubKeyInfo->placeHolder = 0;
517         if (BN_bn2binpad(x, keyBuffer + sizeof(struct HksPubKeyInfo), xSize) == 0 ||
518             BN_bn2binpad(y, keyBuffer + sizeof(struct HksPubKeyInfo) + xSize, ySize) == 0) {
519             HKS_LOG_E("BN_bn2binpad error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
520             HKS_FREE(keyBuffer);
521             break;
522         }
523 
524         ret = HKS_SUCCESS;
525         eccPublicKey->data = keyBuffer;
526         eccPublicKey->size = totalSize;
527     } while (0);
528 
529     SELF_FREE_PTR(x, BN_free)
530     SELF_FREE_PTR(y, BN_free)
531     return ret;
532 }
533 
X509PublicKeyToEcc(const uint32_t alg,EVP_PKEY * pkey,struct HksBlob * eccPublicKey)534 static int32_t X509PublicKeyToEcc(const uint32_t alg, EVP_PKEY *pkey, struct HksBlob *eccPublicKey)
535 {
536     const EC_KEY *ecKey = EVP_PKEY_get0_EC_KEY(pkey);
537     HKS_IF_NULL_LOGE_RETURN(ecKey, HKS_ERROR_NULL_POINTER,
538         "EVP_PKEY_get1_EC_KEY error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
539 
540     return EcKeyToPublicKey(alg, ecKey, eccPublicKey);
541 }
542 #endif
543 
544 #ifdef HKS_SUPPORT_SM2_C
EvpPkeyToHksPubKeyInfo(const uint32_t alg,uint32_t keyLen,const EVP_PKEY * pkey,struct HksBlob * sm2PublicKey)545 static int32_t EvpPkeyToHksPubKeyInfo(
546     const uint32_t alg, uint32_t keyLen, const EVP_PKEY *pkey, struct HksBlob *sm2PublicKey)
547 {
548     struct HksBlob pubXBlob = { 0, NULL };
549     struct HksBlob pubYBlob = { 0, NULL };
550     int pubXRet = GetBnBinpadFromPkey(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &pubXBlob);
551     int pubYRet = GetBnBinpadFromPkey(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &pubYBlob);
552     int ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
553     do {
554         HKS_IF_TRUE_BREAK(pubXRet != HKS_SUCCESS || pubYRet != HKS_SUCCESS)
555         // NOTICE! x size and y size are smaller than or equal to HKS_KEY_BYTES(keyLen)
556         // e.g. assuming that HKS_KEY_BYTES(keyLen) is 32, x size might be 32, 31, 30, etc.
557         uint32_t rawInfoLen = sizeof(struct HksPubKeyInfo) + pubXBlob.size + pubYBlob.size;
558         uint8_t *rawInfo = (uint8_t *)HksMalloc(rawInfoLen);
559         if (!rawInfo) {
560             HKS_LOG_E("HksMalloc rawInfo NULL");
561             ret = HKS_ERROR_INSUFFICIENT_MEMORY;
562             break;
563         }
564         struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)rawInfo;
565         pubKeyInfo->keyAlg = (enum HksKeyAlg)alg;
566         pubKeyInfo->keySize = keyLen;
567         pubKeyInfo->nOrXSize = pubXBlob.size;
568         pubKeyInfo->eOrYSize = pubYBlob.size;
569         pubKeyInfo->placeHolder = 0;
570         uint32_t offset = sizeof(struct HksPubKeyInfo);
571         pubXRet = memcpy_s(rawInfo + offset, pubXBlob.size, pubXBlob.data, pubXBlob.size);
572         offset += pubKeyInfo->nOrXSize;
573         pubYRet = memcpy_s(rawInfo + offset, pubYBlob.size, pubYBlob.data, pubYBlob.size);
574         if (pubXRet != EOK || pubYRet != EOK) {
575             HKS_LOG_E("memcpy_s failed");
576             HKS_FREE(rawInfo);
577             ret = HKS_ERROR_BAD_STATE;
578             break;
579         }
580         sm2PublicKey->data = rawInfo;
581         sm2PublicKey->size = rawInfoLen;
582         ret = HKS_SUCCESS;
583     } while (false);
584     HKS_FREE(pubXBlob.data);
585     HKS_FREE(pubYBlob.data);
586     return ret;
587 }
588 
X509PublicKeyToSm2(const uint32_t alg,EVP_PKEY * pkey,struct HksBlob * sm2PublicKey)589 static int32_t X509PublicKeyToSm2(const uint32_t alg, EVP_PKEY *pkey, struct HksBlob *sm2PublicKey)
590 {
591     HKS_LOG_I("into X509PublicKeyToSm2");
592     int keyLen = EVP_PKEY_get_bits(pkey);
593     if (keyLen <= 0) {
594         HKS_LOG_E("EVP_PKEY_get_bits failed keyLen = %" LOG_PUBLIC "d", keyLen);
595         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
596     }
597     HKS_IF_TRUE_LOGE_RETURN(keyLen != HKS_SM2_KEY_SIZE_256, HKS_ERROR_NOT_SUPPORTED,
598         "not supported sm2 keyLen %" LOG_PUBLIC "d", keyLen)
599     int ret = EvpPkeyToHksPubKeyInfo(alg, (uint32_t)keyLen, pkey, sm2PublicKey);
600     HKS_IF_NOT_SUCC_LOGE(ret, "EvpPkeyToHksPubKeyInfo failed ret = %" LOG_PUBLIC "d", ret)
601     return ret;
602 }
603 #endif
604 
605 #ifdef HKS_SUPPORT_DSA_C
606 
GetDsaKeyInfo(const DSA * dsa,const BIGNUM ** info,uint32_t * infoSize,GetDsaInfoFunc func)607 static int32_t GetDsaKeyInfo(const DSA *dsa, const BIGNUM **info, uint32_t *infoSize, GetDsaInfoFunc func)
608 {
609     *info = func(dsa);
610     HKS_IF_NULL_RETURN(*info, HKS_ERROR_NULL_POINTER)
611 
612     int size = BN_num_bytes(*info);
613     if (size <= 0) {
614         return HKS_ERROR_INVALID_ARGUMENT;
615     }
616 
617     *infoSize = (uint32_t)size;
618     return HKS_SUCCESS;
619 }
620 
X509PublicKeyToDsa(EVP_PKEY * pkey,struct HksBlob * dsaPublicKey)621 static int32_t X509PublicKeyToDsa(EVP_PKEY *pkey, struct HksBlob *dsaPublicKey)
622 {
623     const DSA *dsa = EVP_PKEY_get0_DSA(pkey);
624     HKS_IF_NULL_LOGE_RETURN(dsa, HKS_ERROR_NULL_POINTER,
625         "EVP_PKEY_get1_DSA error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
626 
627     const BIGNUM *y = NULL;
628     const BIGNUM *p = NULL;
629     const BIGNUM *q = NULL;
630     const BIGNUM *g = NULL;
631     uint32_t ySize = 0;
632     uint32_t pSize = 0;
633     uint32_t qSize = 0;
634     uint32_t gSize = 0;
635 
636     if (GetDsaKeyInfo(dsa, &y, &ySize, DSA_get0_pub_key) != HKS_SUCCESS ||
637         GetDsaKeyInfo(dsa, &p, &pSize, DSA_get0_p) != HKS_SUCCESS ||
638         GetDsaKeyInfo(dsa, &q, &qSize, DSA_get0_q) != HKS_SUCCESS ||
639         GetDsaKeyInfo(dsa, &g, &gSize, DSA_get0_g) != HKS_SUCCESS) {
640         return HKS_ERROR_INVALID_ARGUMENT;
641     }
642 
643     uint32_t totalSize = sizeof(struct KeyMaterialDsa) + ySize + pSize + qSize + gSize;
644     uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
645     HKS_IF_NULL_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL)
646 
647     if ((ySize > UINT32_MAX - HKS_BITS_PER_BYTE) ||
648         ((ySize + HKS_BITS_PER_BYTE - 1) / HKS_BITS_PER_BYTE > UINT32_MAX / (HKS_BITS_PER_BYTE * HKS_BITS_PER_BYTE))) {
649         HKS_FREE(keyBuffer);
650         return HKS_ERROR_BAD_STATE;
651     }
652 
653     struct KeyMaterialDsa *keyMaterial = (struct KeyMaterialDsa *)keyBuffer;
654     keyMaterial->keyAlg = HKS_ALG_DSA;
655     keyMaterial->keySize = (ySize + HKS_BITS_PER_BYTE - 1) / HKS_BITS_PER_BYTE * HKS_BITS_PER_BYTE * HKS_BITS_PER_BYTE;
656     keyMaterial->xSize = 0;
657     keyMaterial->ySize = ySize;
658     keyMaterial->pSize = pSize;
659     keyMaterial->qSize = qSize;
660     keyMaterial->gSize = gSize;
661 
662     if ((BN_bn2bin(y, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize) == 0) ||
663         (BN_bn2bin(p, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + ySize) == 0) ||
664         (BN_bn2bin(q, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + ySize + pSize) == 0) ||
665         (BN_bn2bin(g, keyBuffer + sizeof(struct KeyMaterialDsa) + keyMaterial->xSize + ySize + pSize + qSize) == 0)) {
666         HKS_LOG_E("BN_bn2bin error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()));
667         HKS_FREE(keyBuffer);
668         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
669     }
670     dsaPublicKey->size = totalSize;
671     dsaPublicKey->data = keyBuffer;
672 
673     return HKS_SUCCESS;
674 }
675 #endif
676 
677 #ifdef HKS_SUPPORT_DH_C
X509PublicKeyToDh(EVP_PKEY * pkey,struct HksBlob * dhPublicKey)678 static int32_t X509PublicKeyToDh(EVP_PKEY *pkey, struct HksBlob *dhPublicKey)
679 {
680     const DH *dh = EVP_PKEY_get0_DH(pkey);
681     HKS_IF_NULL_LOGE_RETURN(dh, HKS_ERROR_NULL_POINTER,
682         "EVP_PKEY_get0_DH error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
683 
684     const BIGNUM *pubKey = DH_get0_pub_key(dh);
685     HKS_IF_NULL_LOGE_RETURN(pubKey, HKS_ERROR_NULL_POINTER,
686         "DH_get0_pub_key error %" LOG_PUBLIC "s", ERR_reason_error_string(ERR_get_error()))
687 
688     uint32_t pubKeySize = (uint32_t)BN_num_bytes(pubKey);
689     HKS_IF_TRUE_LOGE_RETURN(pubKeySize > UINT32_MAX - sizeof(struct KeyMaterialDh), HKS_ERROR_BAD_STATE,
690         "the size is too long, failed")
691 
692     uint32_t totalSize = sizeof(struct KeyMaterialDh) + pubKeySize;
693     uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
694     HKS_IF_NULL_LOGE_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL, "alloc keyBuffer failed")
695     struct KeyMaterialDh *keyMaterial = (struct KeyMaterialDh *)keyBuffer;
696     keyMaterial->keyAlg = HKS_ALG_DH;
697     keyMaterial->keySize = (uint32_t)DH_bits(dh);
698     keyMaterial->pubKeySize = pubKeySize;
699     keyMaterial->priKeySize = 0;
700     keyMaterial->reserved = 0;
701 
702     BN_bn2bin(pubKey, keyBuffer + sizeof(struct KeyMaterialDh));
703 
704     dhPublicKey->size = totalSize;
705     dhPublicKey->data = keyBuffer;
706 
707     return HKS_SUCCESS;
708 }
709 #endif
710 
TranslateFromX509PublicKey(const uint32_t alg,const struct HksBlob * x509Key,struct HksBlob * publicKey)711 int32_t TranslateFromX509PublicKey(const uint32_t alg, const struct HksBlob *x509Key, struct HksBlob *publicKey)
712 {
713     if (x509Key == NULL || x509Key->data == NULL || x509Key->size == 0 || publicKey == NULL) {
714         HKS_LOG_E("TranslateFromX509PublicKey invalid args");
715         return HKS_ERROR_INVALID_ARGUMENT;
716     }
717 
718     uint8_t *data = x509Key->data;
719 
720     EVP_PKEY *pkey = d2i_PUBKEY(NULL, (const unsigned char **)&data, x509Key->size);
721     HKS_IF_NULL_RETURN(pkey, HKS_ERROR_INVALID_ARGUMENT)
722 
723     int32_t ret;
724     int32_t keyType = EVP_PKEY_base_id(pkey);
725     if (keyType == EVP_PKEY_RSA) {
726 #ifdef HKS_SUPPORT_RSA_C
727         ret = X509PublicKeyToRsa(pkey, publicKey);
728 #else
729         ret = HKS_ERROR_INVALID_ALGORITHM;
730 #endif
731     } else if (keyType == EVP_PKEY_EC) {
732 #ifdef HKS_SUPPORT_ECC_C
733         ret = X509PublicKeyToEcc(alg, pkey, publicKey);
734 #else
735         ret = HKS_ERROR_INVALID_ALGORITHM;
736 #endif
737     } else if (EVP_PKEY_is_a(pkey, SN_sm2)) {
738 #ifdef HKS_SUPPORT_SM2_C
739         ret = X509PublicKeyToSm2(alg, pkey, publicKey);
740 #else
741         ret = HKS_ERROR_INVALID_ALGORITHM;
742 #endif
743     } else if (keyType == EVP_PKEY_DSA) {
744 #ifdef HKS_SUPPORT_DSA_C
745         ret = X509PublicKeyToDsa(pkey, publicKey);
746 #else
747         ret = HKS_ERROR_INVALID_ALGORITHM;
748 #endif
749     } else if (keyType == EVP_PKEY_DH) {
750 #ifdef HKS_SUPPORT_DH_C
751         ret = X509PublicKeyToDh(pkey, publicKey);
752 #else
753         ret = HKS_ERROR_INVALID_ALGORITHM;
754 #endif
755     } else {
756         HKS_LOG_E("Unsupport alg type! %" LOG_PUBLIC "d", keyType);
757         ret = HKS_ERROR_INVALID_ARGUMENT;
758     }
759 
760     SELF_FREE_PTR(pkey, EVP_PKEY_free)
761     return ret;
762 }
763 #endif
764 
765