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