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) 49typedef 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) 54static 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) 80static 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) 122static 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 145static 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) 199static 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) 207static 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 237static 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 289static 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) 304static 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 321static 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) 364static 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 382static 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 418int32_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 451static 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 489static 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 544static 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 555static 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 601static 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 623static 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 637static 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 694static 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 729int32_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