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