• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifdef HKS_SUPPORT_ECC_C
23 #include "hks_openssl_ecc.h"
24 
25 #include <openssl/bn.h>
26 #include <openssl/ec.h>
27 #include <openssl/evp.h>
28 #include <openssl/obj_mac.h>
29 #include <openssl/ossl_typ.h>
30 #include <stdbool.h>
31 #include <stddef.h>
32 
33 #include "hks_log.h"
34 #include "hks_mem.h"
35 #include "hks_openssl_engine.h"
36 #include "hks_template.h"
37 #include "securec.h"
38 
HksOpensslEccCheckKeyLen(uint32_t keyLen)39 static int32_t HksOpensslEccCheckKeyLen(uint32_t keyLen)
40 {
41     if ((keyLen != HKS_ECC_KEY_SIZE_224) && (keyLen != HKS_ECC_KEY_SIZE_256) && (keyLen != HKS_ECC_KEY_SIZE_384) &&
42         (keyLen != HKS_ECC_KEY_SIZE_521)) {
43         HKS_LOG_E("invalid param keyLen(0x%" LOG_PUBLIC "x)!", keyLen);
44         return HKS_ERROR_INVALID_ARGUMENT;
45     }
46     return HKS_SUCCESS;
47 }
48 
HksOpensslGetCurveId(uint32_t keyLen,int * nid)49 static int32_t HksOpensslGetCurveId(uint32_t keyLen, int *nid)
50 {
51     switch (keyLen) {
52         case HKS_ECC_KEY_SIZE_224:
53             *nid = NID_secp224r1;
54             break;
55         case HKS_ECC_KEY_SIZE_256:
56             *nid = NID_X9_62_prime256v1;
57             break;
58         case HKS_ECC_KEY_SIZE_384:
59             *nid = NID_secp384r1;
60             break;
61         case HKS_ECC_KEY_SIZE_521:
62             *nid = NID_secp521r1;
63             break;
64         default:
65             HKS_LOG_E("invalid key size.");
66             return HKS_ERROR_INVALID_AE_TAG;
67     }
68 
69     return HKS_SUCCESS;
70 }
71 
72 #ifdef HKS_SUPPORT_ECC_GENERATE_KEY
TransEccKeyToKeyBlob(const EC_KEY * eccKey,const struct KeyMaterialEcc * keyMaterial,BIGNUM * pubX,BIGNUM * pubY,uint8_t * rawMaterial)73 static int32_t TransEccKeyToKeyBlob(
74     const EC_KEY *eccKey, const struct KeyMaterialEcc *keyMaterial, BIGNUM *pubX, BIGNUM *pubY, uint8_t *rawMaterial)
75 {
76     const EC_GROUP *ecGroup = EC_KEY_get0_group(eccKey);
77     int retCode = EC_POINT_get_affine_coordinates_GFp(ecGroup, EC_KEY_get0_public_key(eccKey), pubX, pubY, NULL);
78     if (retCode <= 0) {
79         HksLogOpensslError();
80         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
81     }
82 
83     const BIGNUM *priv = EC_KEY_get0_private_key(eccKey);
84     uint32_t offset = sizeof(struct KeyMaterialEcc);
85 
86     retCode = BN_bn2binpad(pubX, rawMaterial + offset, keyMaterial->xSize);
87     if (retCode <= 0) {
88         HksLogOpensslError();
89         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
90     }
91     offset += keyMaterial->xSize;
92 
93     retCode = BN_bn2binpad(pubY, rawMaterial + offset, keyMaterial->ySize);
94     if (retCode <= 0) {
95         HksLogOpensslError();
96         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
97     }
98     offset += keyMaterial->ySize;
99 
100     retCode = BN_bn2binpad(priv, rawMaterial + offset, keyMaterial->zSize);
101     if (retCode <= 0) {
102         HksLogOpensslError();
103         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
104     }
105 
106     return HKS_SUCCESS;
107 }
108 
EccSaveKeyMaterial(const EC_KEY * eccKey,const struct HksKeySpec * spec,uint8_t ** output,uint32_t * outputSize)109 static int32_t EccSaveKeyMaterial(const EC_KEY *eccKey, const struct HksKeySpec *spec,
110     uint8_t **output, uint32_t *outputSize)
111 {
112     uint32_t keySize = spec->keyLen;
113     /* public exponent x and y, and private exponent, so need size is: keySize / 8 * 3 */
114     uint32_t rawMaterialLen = sizeof(struct KeyMaterialEcc) + HKS_KEY_BYTES(keySize) * ECC_KEYPAIR_CNT;
115     uint8_t *rawMaterial = (uint8_t *)HksMalloc(rawMaterialLen);
116     HKS_IF_NULL_LOGE_RETURN(rawMaterial, HKS_ERROR_MALLOC_FAIL, "malloc buffer failed!")
117 
118     (void)memset_s(rawMaterial, rawMaterialLen, 0, rawMaterialLen);
119 
120     /*
121      * ECC key data internal struct:
122      * struct KeyMaterialEcc + pubX_data + pubY_data + pri_data
123      */
124     struct KeyMaterialEcc *keyMaterial = (struct KeyMaterialEcc *)rawMaterial;
125     keyMaterial->keyAlg = (enum HksKeyAlg)spec->algType;
126     keyMaterial->keySize = keySize;
127     keyMaterial->xSize = HKS_KEY_BYTES(keySize);
128     keyMaterial->ySize = HKS_KEY_BYTES(keySize);
129     keyMaterial->zSize = HKS_KEY_BYTES(keySize);
130 
131     BIGNUM *pubX = BN_new();
132     BIGNUM *pubY = BN_new();
133 
134     int32_t ret;
135     do {
136         if ((pubX == NULL) || (pubY == NULL)) {
137             HKS_LOG_E("BN_new x or y failed");
138             ret = HKS_ERROR_NULL_POINTER;
139             HksFree(rawMaterial);
140             break;
141         }
142         ret = TransEccKeyToKeyBlob(eccKey, keyMaterial, pubX, pubY, rawMaterial);
143         if (ret != HKS_SUCCESS) {
144             HKS_LOG_E("transfer ecc key to key blob failed");
145             HksFree(rawMaterial);
146             break;
147         }
148         *output = rawMaterial;
149         *outputSize = rawMaterialLen;
150     } while (0);
151 
152     if (pubX != NULL) {
153         BN_free(pubX);
154         pubX = NULL;
155     }
156     if (pubY != NULL) {
157         BN_free(pubY);
158         pubY = NULL;
159     }
160     return ret;
161 }
162 
HksOpensslEccGenerateKey(const struct HksKeySpec * spec,struct HksBlob * key)163 int32_t HksOpensslEccGenerateKey(const struct HksKeySpec *spec, struct HksBlob *key)
164 {
165     int curveId;
166     switch (spec->algType) {
167 #if defined(HKS_SUPPORT_SM2_C) && defined(HKS_SUPPORT_SM2_GENERATE_KEY)
168         case HKS_ALG_SM2:
169             if (spec->keyLen != HKS_SM2_KEY_SIZE_256) {
170                 HKS_LOG_E("Sm2 Invalid Param!");
171                 return HKS_ERROR_INVALID_ARGUMENT;
172             }
173             curveId = NID_sm2;
174             break;
175 #endif
176         default:
177             HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslEccCheckKeyLen(spec->keyLen),
178                 HKS_ERROR_INVALID_ARGUMENT, "Ecc Invalid Param!")
179 
180             HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslGetCurveId(spec->keyLen, &curveId),
181                 HKS_ERROR_INVALID_ARGUMENT, "Ecc get curveId failed!")
182             break;
183     }
184 
185     EC_KEY *eccKey = NULL;
186     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
187     do {
188         eccKey = EC_KEY_new_by_curve_name(curveId);
189         if (eccKey == NULL) {
190             HKS_LOG_E("new ec key failed");
191             HksLogOpensslError();
192             break;
193         }
194 
195         if (EC_KEY_generate_key(eccKey) <= 0) {
196             HKS_LOG_E("generate ec key failed");
197             HksLogOpensslError();
198             break;
199         }
200 
201         ret = EccSaveKeyMaterial(eccKey, spec, &key->data, &key->size);
202         HKS_IF_NOT_SUCC_LOGE(ret, "save ec key material failed! ret=0x%" LOG_PUBLIC "x", ret)
203     } while (0);
204 
205     if (eccKey != NULL) {
206         EC_KEY_free(eccKey);
207         eccKey = NULL;
208     }
209 
210     return ret;
211 }
212 #endif
213 
214 #ifdef HKS_SUPPORT_ECC_GET_PUBLIC_KEY
HksOpensslGetEccPubKey(const struct HksBlob * input,struct HksBlob * output)215 int32_t HksOpensslGetEccPubKey(const struct HksBlob *input, struct HksBlob *output)
216 {
217     struct KeyMaterialEcc *keyMaterial = (struct KeyMaterialEcc *)input->data;
218 
219     if ((keyMaterial->xSize == 0) || (keyMaterial->ySize == 0)) {
220         HKS_LOG_E("not support get pubkey");
221         return HKS_ERROR_NOT_SUPPORTED;
222     }
223 
224     output->size = sizeof(struct KeyMaterialEcc) + keyMaterial->xSize + keyMaterial->ySize;
225 
226     struct KeyMaterialEcc *publickeyMaterial = (struct KeyMaterialEcc *)output->data;
227     publickeyMaterial->keyAlg = keyMaterial->keyAlg;
228     publickeyMaterial->keySize = keyMaterial->keySize;
229     publickeyMaterial->xSize = keyMaterial->xSize;
230     publickeyMaterial->ySize = keyMaterial->ySize;
231     publickeyMaterial->zSize = 0;
232 
233     (void)memcpy_s(output->data + sizeof(struct KeyMaterialEcc), output->size - sizeof(struct KeyMaterialEcc),
234         input->data + sizeof(struct KeyMaterialEcc), keyMaterial->xSize + keyMaterial->ySize);
235 
236     return HKS_SUCCESS;
237 }
238 #endif
239 
GetEccModules(const uint8_t * key,uint32_t * keySize,uint32_t * publicXSize,uint32_t * publicYSize,uint32_t * privateXSize)240 static int GetEccModules(
241     const uint8_t *key, uint32_t *keySize, uint32_t *publicXSize, uint32_t *publicYSize, uint32_t *privateXSize)
242 {
243     struct KeyMaterialEcc *keyMaterial = (struct KeyMaterialEcc *)key;
244     *keySize = keyMaterial->keySize;
245     *publicXSize = keyMaterial->xSize;
246     *publicYSize = keyMaterial->ySize;
247     *privateXSize = keyMaterial->zSize;
248 
249     return 0;
250 }
251 
EccInitPublicKey(EC_KEY * eccKey,const uint8_t * keyPair,uint32_t xSize,uint32_t ySize)252 static int32_t EccInitPublicKey(EC_KEY *eccKey, const uint8_t *keyPair, uint32_t xSize, uint32_t ySize)
253 {
254     const EC_GROUP *ecGroup = EC_KEY_get0_group(eccKey);
255     if (ecGroup == NULL) {
256         HksLogOpensslError();
257         return HKS_ERROR_INVALID_ARGUMENT;
258     }
259 
260     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
261     uint32_t offset = sizeof(struct KeyMaterialEcc);
262     EC_POINT *pub = EC_POINT_new(ecGroup);
263     BIGNUM *pubX = BN_bin2bn(keyPair + offset, xSize, NULL);
264     offset += xSize;
265     BIGNUM *pubY = BN_bin2bn(keyPair + offset, ySize, NULL);
266     do {
267         if ((pubX == NULL) || (pubY == NULL) || (pub == NULL)) {
268             HKS_LOG_E("new big num x or y or pub failed");
269             break;
270         }
271 
272         if (EC_POINT_set_affine_coordinates_GFp(ecGroup, pub, pubX, pubY, NULL) <= 0) {
273             HksLogOpensslError();
274             break;
275         }
276 
277         if (EC_KEY_set_public_key(eccKey, pub) <= 0) {
278             HksLogOpensslError();
279             break;
280         }
281         ret = HKS_SUCCESS;
282     } while (0);
283 
284     if (pubX != NULL) {
285         BN_free(pubX);
286         pubX = NULL;
287     }
288 
289     if (pubY != NULL) {
290         BN_free(pubY);
291         pubY = NULL;
292     }
293 
294     if (pub != NULL) {
295         EC_POINT_free(pub);
296         pub = NULL;
297     }
298     return ret;
299 }
300 
EccInitKey(const struct HksBlob * keyBlob,bool private)301 static EC_KEY *EccInitKey(const struct HksBlob *keyBlob, bool private)
302 {
303     /* get ecc pubX,pubY,pri */
304     uint8_t *keyPair = keyBlob->data;
305     uint32_t publicXSize;
306     uint32_t publicYSize;
307     uint32_t privateSize;
308     uint32_t keySize;
309 
310     if (GetEccModules(keyPair, &keySize, &publicXSize, &publicYSize, &privateSize) != 0) {
311         HKS_LOG_E("get ecc key modules is failed");
312         return NULL;
313     }
314 
315     int nid;
316     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslGetCurveId(keySize, &nid), NULL, "get curve id failed")
317 
318     EC_KEY *eccKey = EC_KEY_new_by_curve_name(nid);
319     if (eccKey == NULL) {
320         HksLogOpensslError();
321         return NULL;
322     }
323 
324     if (!private) {
325         if (EccInitPublicKey(eccKey, keyPair, publicXSize, publicYSize) != HKS_SUCCESS) {
326             HKS_LOG_E("initialize ecc public key failed");
327             EC_KEY_free(eccKey);
328             return NULL;
329         }
330     }
331 
332     if (private) {
333         BIGNUM *pri = BN_bin2bn(keyPair + sizeof(struct KeyMaterialEcc) + publicXSize + publicYSize, privateSize, NULL);
334         if (pri == NULL || EC_KEY_set_private_key(eccKey, pri) <= 0) {
335             HKS_LOG_E("build ecc key failed");
336             BN_free(pri);
337             EC_KEY_free(eccKey);
338             return NULL;
339         }
340         BN_clear_free(pri);
341     }
342 
343     return eccKey;
344 }
345 
GetEvpKey(const struct HksBlob * keyBlob,EVP_PKEY * key,bool private)346 static int32_t GetEvpKey(const struct HksBlob *keyBlob, EVP_PKEY *key, bool private)
347 {
348     EC_KEY *eccKey = EccInitKey(keyBlob, private);
349     HKS_IF_NULL_LOGE_RETURN(eccKey, HKS_ERROR_CRYPTO_ENGINE_ERROR, "initialize ecc key failed\n")
350 
351     if (EVP_PKEY_assign_EC_KEY(key, eccKey) <= 0) {
352         HksLogOpensslError();
353         EC_KEY_free(eccKey);
354         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
355     }
356     return HKS_SUCCESS;
357 }
358 
GetNativePKey(const struct HksBlob * nativeKey,EVP_PKEY * key)359 static int32_t GetNativePKey(const struct HksBlob *nativeKey, EVP_PKEY *key)
360 {
361     int32_t ret = GetEvpKey(nativeKey, key, true);
362     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get native evp key failed")
363     return ret;
364 }
365 
GetPeerKey(const struct HksBlob * pubKey,EVP_PKEY * key)366 static int32_t GetPeerKey(const struct HksBlob *pubKey, EVP_PKEY *key)
367 {
368     int32_t ret = GetEvpKey(pubKey, key, false);
369     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CRYPTO_ENGINE_ERROR, "get peer evp key failed")
370     return ret;
371 }
372 
EcdhDerive(EVP_PKEY_CTX * ctx,EVP_PKEY * peerKey,struct HksBlob * sharedKey)373 static int32_t EcdhDerive(EVP_PKEY_CTX *ctx, EVP_PKEY *peerKey, struct HksBlob *sharedKey)
374 {
375     size_t tmpSharedKeySize = (size_t)sharedKey->size;
376     if (EVP_PKEY_derive_init(ctx) != 1) {
377         HksLogOpensslError();
378         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
379     }
380     if (EVP_PKEY_derive_set_peer(ctx, peerKey) != 1) {
381         HksLogOpensslError();
382         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
383     }
384     if (EVP_PKEY_derive(ctx, NULL, &tmpSharedKeySize) != 1) {
385         HksLogOpensslError();
386         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
387     }
388 
389     if (tmpSharedKeySize > sharedKey->size) {
390         return HKS_ERROR_BUFFER_TOO_SMALL;
391     }
392 
393     if (EVP_PKEY_derive(ctx, sharedKey->data, &tmpSharedKeySize) != 1) {
394         HksLogOpensslError();
395         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
396     }
397     sharedKey->size = tmpSharedKeySize;
398 
399     return HKS_SUCCESS;
400 }
401 
AgreeKeyEcdh(const struct HksBlob * nativeKey,const struct HksBlob * pubKey,struct HksBlob * sharedKey)402 static int32_t AgreeKeyEcdh(const struct HksBlob *nativeKey, const struct HksBlob *pubKey, struct HksBlob *sharedKey)
403 {
404     int32_t res = HKS_ERROR_CRYPTO_ENGINE_ERROR;
405     EVP_PKEY *pKey = EVP_PKEY_new();
406     EVP_PKEY *peerKey = EVP_PKEY_new();
407     EVP_PKEY_CTX *ctx = NULL;
408 
409     do {
410         if ((peerKey == NULL) || (pKey == NULL)) {
411             HKS_LOG_E("new pkey failed\n");
412             break;
413         }
414         int32_t ret = GetNativePKey(nativeKey, pKey);
415         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get native pkey failed\n")
416 
417         ret = GetPeerKey(pubKey, peerKey);
418         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get peer pkey failed\n")
419 
420         ctx = EVP_PKEY_CTX_new(pKey, NULL);
421         if (ctx == NULL) {
422             HksLogOpensslError();
423             break;
424         }
425 
426         ret = EcdhDerive(ctx, peerKey, sharedKey);
427         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "derive ecdh key failed\n")
428 
429         res = HKS_SUCCESS;
430     } while (0);
431 
432     EVP_PKEY_CTX_free(ctx);
433     if (peerKey != NULL) {
434         EVP_PKEY_free(peerKey);
435     }
436     if (pKey != NULL) {
437         EVP_PKEY_free(pKey);
438     }
439 
440     return res;
441 }
442 
443 #ifdef HKS_SUPPORT_ECDH_AGREE_KEY
HksOpensslEcdhAgreeKey(const struct HksBlob * nativeKey,const struct HksBlob * pubKey,const struct HksKeySpec * spec,struct HksBlob * sharedKey)444 int32_t HksOpensslEcdhAgreeKey(const struct HksBlob *nativeKey, const struct HksBlob *pubKey,
445     const struct HksKeySpec *spec, struct HksBlob *sharedKey)
446 {
447     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslEccCheckKeyLen(spec->keyLen),
448         HKS_ERROR_INVALID_ARGUMENT, "invalid param!")
449     int32_t ret = AgreeKeyEcdh(nativeKey, pubKey, sharedKey);
450     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "ecdh key agreement failed!")
451 
452     return ret;
453 }
454 #endif
455 
456 #ifdef HKS_SUPPORT_ECDSA_SIGN_VERIFY
InitEcdsaCtx(const struct HksBlob * mainKey,uint32_t digest,bool sign,uint32_t len)457 static EVP_PKEY_CTX *InitEcdsaCtx(const struct HksBlob *mainKey, uint32_t digest, bool sign, uint32_t len)
458 {
459     const EVP_MD *opensslAlg = GetOpensslAlg(digest);
460     if (digest == HKS_DIGEST_NONE) {
461         opensslAlg = GetOpensslAlgFromLen(len);
462     }
463     if (opensslAlg == NULL) {
464         HKS_LOG_E("get openssl algorithm fail");
465         return NULL;
466     }
467 
468     EC_KEY *eccKey = EccInitKey(mainKey, sign);
469     HKS_IF_NULL_LOGE_RETURN(eccKey, NULL, "initialize ecc key failed")
470 
471     EVP_PKEY *key = EVP_PKEY_new();
472     if (key == NULL) {
473         HksLogOpensslError();
474         EC_KEY_free(eccKey);
475         return NULL;
476     }
477 
478     if (EVP_PKEY_assign_EC_KEY(key, eccKey) <= 0) {
479         EC_KEY_free(eccKey);
480         EVP_PKEY_free(key);
481         return NULL;
482     }
483 
484     EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(key, NULL);
485     if (ctx == NULL) {
486         HksLogOpensslError();
487         EVP_PKEY_free(key);
488         return NULL;
489     }
490     int32_t ret;
491     if (sign) {
492         ret = EVP_PKEY_sign_init(ctx);
493     } else {
494         ret = EVP_PKEY_verify_init(ctx);
495     }
496     EVP_PKEY_free(key);
497     if (ret != HKS_OPENSSL_SUCCESS) {
498         HksLogOpensslError();
499         EVP_PKEY_CTX_free(ctx);
500         return NULL;
501     }
502     if (EVP_PKEY_CTX_set_signature_md(ctx, opensslAlg) != HKS_OPENSSL_SUCCESS) {
503         HksLogOpensslError();
504         EVP_PKEY_CTX_free(ctx);
505         return NULL;
506     }
507     return ctx;
508 }
509 
HksOpensslEcdsaVerify(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const struct HksBlob * signature)510 int32_t HksOpensslEcdsaVerify(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
511     const struct HksBlob *message, const struct HksBlob *signature)
512 {
513     EVP_PKEY_CTX *ctx = InitEcdsaCtx(key, usageSpec->digest, false, message->size);
514     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_INVALID_KEY_INFO, "initialize ecc context failed")
515 
516     if (EVP_PKEY_verify(ctx, signature->data, signature->size, message->data, message->size) != HKS_OPENSSL_SUCCESS) {
517         HksLogOpensslError();
518         EVP_PKEY_CTX_free(ctx);
519         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
520     }
521 
522     EVP_PKEY_CTX_free(ctx);
523     return HKS_SUCCESS;
524 }
525 
HksOpensslEcdsaSign(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * signature)526 int32_t HksOpensslEcdsaSign(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
527     const struct HksBlob *message, struct HksBlob *signature)
528 {
529     EVP_PKEY_CTX *ctx = InitEcdsaCtx(key, usageSpec->digest, true, message->size);
530     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_INVALID_KEY_INFO, "initialize ecc context failed")
531 
532     size_t sigSize = (size_t)signature->size;
533     if (EVP_PKEY_sign(ctx, signature->data, &sigSize, message->data, message->size) != HKS_OPENSSL_SUCCESS) {
534         HksLogOpensslError();
535         EVP_PKEY_CTX_free(ctx);
536         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
537     }
538     signature->size = (uint32_t)sigSize;
539     EVP_PKEY_CTX_free(ctx);
540     return HKS_SUCCESS;
541 }
542 #endif
543 #endif