• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 #include <stdbool.h>
13 #include <openssl/ec.h>
14 #include <openssl/bn.h>
15 #include <openssl/x509.h>
16 #include <openssl/ecdsa.h>
17 #include <openssl/obj_mac.h>
18 #include <openssl/x509v3.h>
19 #include <openssl/sha.h>
20 #include <rsa/rsa_local.h>
21 #include <openssl/ossl_typ.h>
22 #include <openssl/crypto.h>
23 #include <securec.h>
24 #include <tee_log.h>
25 #include "ec_wrapper.h"
26 #include "crypto_inner_interface.h"
27 #include "soft_common_api.h"
28 
29 /* ECC domain id defined in tomcrypto */
30 #define EC_KEY_FIX_BUFFER_LEN 66
31 
32 #define OBJ_LEN_ONE 1
33 #define OBJ_LEN_TWO 2
34 
ec_nid_tom2boringssl(uint32_t domain)35 int32_t ec_nid_tom2boringssl(uint32_t domain)
36 {
37     switch (domain) {
38     case NIST_P192:
39         return NID_X9_62_prime192v1;
40     case NIST_P224:
41         return NID_secp224r1;
42     case NIST_P256:
43         return NID_X9_62_prime256v1;
44     case NIST_P384:
45         return NID_secp384r1;
46     case NIST_P521:
47         return NID_secp521r1;
48     default:
49         tloge("error domain %u", domain);
50         return -1;
51     }
52 }
new_boring_ec_key(const BIGNUM * ecc_priv_boring,const EC_POINT * ecc_pub_boring,int32_t ec_nid,EC_KEY ** eckey)53 static TEE_Result new_boring_ec_key(const BIGNUM *ecc_priv_boring, const EC_POINT *ecc_pub_boring,
54     int32_t ec_nid, EC_KEY **eckey)
55 {
56     EC_KEY *ecc_key = EC_KEY_new_by_curve_name(ec_nid);
57     if (ecc_key == NULL) {
58         tloge("soft_enine: %s\n", "new ecc key error");
59         return TEE_ERROR_GENERIC;
60     }
61     if (EC_KEY_set_private_key(ecc_key, ecc_priv_boring) != 1) {
62         tloge("set private key error");
63         EC_KEY_free(ecc_key);
64         return TEE_ERROR_GENERIC;
65     }
66     if (EC_KEY_set_public_key(ecc_key, ecc_pub_boring) != 1) {
67         tloge("set pub key error");
68         EC_KEY_free(ecc_key);
69         return TEE_ERROR_GENERIC;
70     }
71     *eckey = ecc_key;
72     return TEE_SUCCESS;
73 }
74 
ecc_privkey_tee_to_boring(void * priv,void ** eckey)75 TEE_Result ecc_privkey_tee_to_boring(void *priv, void **eckey)
76 {
77     BIGNUM *ecc_priv_boring  = NULL;
78     EC_GROUP *group          = NULL;
79     EC_POINT *ecc_pub_boring = NULL;
80     ecc_priv_key_t *ecc_priv = NULL;
81     int32_t boring_nid;
82     TEE_Result ret;
83     if (priv == NULL || eckey == NULL) {
84         tloge("soft_enine: %s\n", "priv is null");
85         return TEE_ERROR_BAD_PARAMETERS;
86     }
87     ecc_priv        = (ecc_priv_key_t *)priv;
88     boring_nid      = (int32_t)ecc_priv->domain;
89     ecc_priv_boring = BN_bin2bn(ecc_priv->r, ecc_priv->r_len, NULL);
90     if (ecc_priv_boring == NULL) {
91         tloge("soft_enine: %s\n", "bin2bn error in tee key to boring private key");
92         return TEE_ERROR_GENERIC;
93     }
94 
95     group = EC_GROUP_new_by_curve_name(boring_nid);
96     if (group == NULL) {
97         tloge("new ec group error");
98         ret = TEE_ERROR_GENERIC;
99         goto error;
100     }
101     ecc_pub_boring = EC_POINT_new(group);
102     if (ecc_pub_boring == NULL) {
103         tloge("new boring pub error");
104         ret = TEE_ERROR_GENERIC;
105         goto error;
106     }
107     int32_t res = EC_POINT_mul(group, ecc_pub_boring, ecc_priv_boring, NULL, NULL, NULL);
108     if (res != 1) {
109         tloge("POINT_mul error");
110         ret = TEE_ERROR_GENERIC;
111         goto error;
112     }
113     ret = new_boring_ec_key(ecc_priv_boring, ecc_pub_boring, boring_nid, (EC_KEY **)eckey);
114 error:
115     BN_free(ecc_priv_boring);
116     EC_POINT_free(ecc_pub_boring);
117     EC_GROUP_free(group);
118     return ret;
119 }
120 
ecc_pubkey_tee_to_boring(void * public_key,EC_KEY ** eckey)121 TEE_Result ecc_pubkey_tee_to_boring(void *public_key, EC_KEY **eckey)
122 {
123     ecc_pub_key_t *pub_key = (ecc_pub_key_t *)public_key;
124     if (pub_key == NULL || eckey == NULL) {
125         tloge("soft_enine: %s\n", "key is null");
126         return TEE_ERROR_BAD_PARAMETERS;
127     }
128     EC_KEY *ec_key = EC_KEY_new_by_curve_name(pub_key->domain);
129     BIGNUM *x      = BN_bin2bn(pub_key->x, pub_key->x_len, NULL);
130     BIGNUM *y      = BN_bin2bn(pub_key->y, pub_key->y_len, NULL);
131     bool check     = (ec_key == NULL || x == NULL || y == NULL);
132     if (check) {
133         BN_free(x);
134         BN_free(y);
135         EC_KEY_free(ec_key);
136         tloge("bn new or create ec key error");
137         return TEE_ERROR_OUT_OF_MEMORY;
138     }
139     int32_t res = EC_KEY_set_public_key_affine_coordinates(ec_key, x, y);
140     if (res == 0) {
141         tloge("set pub key error");
142         BN_free(x);
143         BN_free(y);
144         EC_KEY_free(ec_key);
145         return TEE_ERROR_BAD_PARAMETERS;
146     }
147     *eckey = ec_key;
148     BN_free(x);
149     BN_free(y);
150     return TEE_SUCCESS;
151 }
get_public_key(const ecc_priv_key_t * priv_info,struct ecc_derive_public_key_t * public_key)152 static int32_t get_public_key(const ecc_priv_key_t *priv_info, struct ecc_derive_public_key_t *public_key)
153 {
154     public_key->priv_bn = BN_bin2bn(priv_info->r, priv_info->r_len, NULL);
155     if (public_key->priv_bn == NULL) {
156         tloge("priv bin2bn failed");
157         return -1;
158     }
159 
160     public_key->pub_pt = EC_POINT_new(public_key->group);
161     if (public_key->pub_pt == NULL) {
162         tloge("pub new failed");
163         return -1;
164     }
165 
166     int32_t ret = EC_POINT_mul(public_key->group, public_key->pub_pt, public_key->priv_bn, NULL, NULL, public_key->ctx);
167     if (ret != 1) {
168         tloge("ec point mul failed");
169         return -1;
170     }
171 
172     ret = EC_POINT_get_affine_coordinates_GFp(public_key->group, public_key->pub_pt, public_key->x_bn, public_key->y_bn,
173                                               public_key->ctx);
174     if (ret != 1) {
175         tloge("get pub point failed");
176         return -1;
177     }
178     return ret;
179 }
180 
ecc_derive_public_key(ecc_priv_key_t * priv_info,ecc_pub_key_t * pub_info)181 int ecc_derive_public_key(ecc_priv_key_t *priv_info, ecc_pub_key_t *pub_info)
182 {
183     bool check_flag = (priv_info == NULL || pub_info == NULL);
184     if (check_flag) {
185         tloge("soft_enine: %s\n", "invalid ec info");
186         return -1;
187     }
188 
189     int nid = ec_nid_tom2boringssl(priv_info->domain);
190     if (nid < 0) {
191         tloge("soft_enine: %s\n", "domain is error, bad private key");
192         return -1;
193     }
194 
195     struct ecc_derive_public_key_t public_key = {0};
196     int ret = -1;
197     public_key.group = EC_GROUP_new_by_curve_name(nid);
198     if (public_key.group == NULL) {
199         tloge("soft_enine: %s\n", "alloc group failed");
200         return -1;
201     }
202 
203     public_key.x_bn       = BN_new();
204     public_key.y_bn       = BN_new();
205     public_key.ctx        = BN_CTX_new();
206     check_flag = (public_key.x_bn == NULL || public_key.y_bn == NULL || public_key.ctx == NULL);
207     if (check_flag) {
208         tloge("alloc points failed");
209         goto error;
210     }
211 
212     ret = get_public_key(priv_info, &public_key);
213     if (ret != 1)
214         goto error;
215 
216     pub_info->x_len  = (uint32_t)BN_bn2bin(public_key.x_bn, pub_info->x);
217     pub_info->y_len  = (uint32_t)BN_bn2bin(public_key.y_bn, pub_info->y);
218     pub_info->domain = priv_info->domain;
219     ret              = 0;
220 
221 error:
222     /* boringssl API will check if pointer is NULL */
223     BN_CTX_free(public_key.ctx);
224     EC_POINT_free(public_key.pub_pt);
225     BN_free(public_key.x_bn);
226     BN_free(public_key.y_bn);
227     BN_free(public_key.priv_bn);
228     EC_GROUP_free(public_key.group);
229     return ret;
230 }
231 
derive_ecc_private_key_from_huk(ecc_priv_key_t * priv,const uint8_t * secret,uint32_t sec_len)232 int derive_ecc_private_key_from_huk(ecc_priv_key_t *priv, const uint8_t *secret, uint32_t sec_len)
233 {
234     struct derive_ecc_private_key_from_huk_t priv_key = {0};
235     int32_t ret = -1;
236 
237     if ((priv == NULL) || (secret == NULL) || (sec_len > SECRET_KEY_MAX_LEN)) {
238         tloge("soft_enine: %s\n", "invalid params");
239         return ret;
240     }
241 
242     const uint8_t nist_p256_group_order[] = {
243         0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
244         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17,
245         0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
246     };
247 
248     priv_key.ord = BN_bin2bn(nist_p256_group_order, sizeof(nist_p256_group_order), NULL);
249     if (priv_key.ord == NULL) {
250         tloge("soft_enine: %s\n", "bin to bn error");
251         return ret;
252     }
253     priv_key.x = BN_bin2bn(secret, sec_len, NULL);
254     if (priv_key.x == NULL) {
255         tloge("secret to bn fail");
256         goto error;
257     }
258     if (BN_sub_word(priv_key.ord, 1) != 1) {
259         tloge("ord get fail");
260         goto error;
261     }
262     priv_key.ctx = BN_CTX_new();
263     if (priv_key.ctx == NULL) {
264         tloge("new ctx fail");
265         goto error;
266     }
267     /* Compute x (mod (ord -1)) + 1 */
268     ret = BN_mod(priv_key.x, priv_key.x, priv_key.ord, priv_key.ctx);
269     BN_CTX_free(priv_key.ctx);
270     priv_key.ctx = NULL;
271     if ((ret != 1) || (BN_add_word(priv_key.x, 1) == 0)) {
272         ret = -1;
273         goto error;
274     }
275     priv->domain = NIST_P256;
276     if (BN_num_bytes(priv_key.x) > ECC_PRIV_LEN) {
277         ret = -1;
278         goto error;
279     }
280     priv->r_len = (uint32_t)BN_bn2bin(priv_key.x, priv->r);
281     ret         = 0;
282 
283 error:
284     BN_free(priv_key.x);
285     BN_free(priv_key.ord);
286     return ret;
287 }
288 
289 /* file_name if rsa key, we can store offset by file_name */
derive_private_key_from_secret(void * priv,uint8_t * secret,uint32_t secret_len,uint32_t bits,uint32_t key_type,uint8_t * file_name)290 int derive_private_key_from_secret(void *priv, uint8_t *secret, uint32_t secret_len, uint32_t bits, uint32_t key_type,
291                                    uint8_t *file_name)
292 {
293     /* file_name maybe null here */
294     if (secret == NULL) {
295         tloge("soft_enine: %s\n", "invalid params");
296         return -1;
297     }
298     if (priv == NULL) {
299         tloge("soft_enine: %s\n", "invalid params");
300         return -1;
301     }
302     switch (key_type) {
303     case RSA_ALG:
304         return generate_rsa_from_secret(priv, bits, secret, secret_len, file_name);
305     case ECC_ALG: {
306         ecc_priv_key_t *priv_key = (ecc_priv_key_t *)priv;
307         int ret;
308 
309         ret = derive_ecc_private_key_from_huk(priv_key, secret, secret_len);
310         if (ret < 0) {
311             tloge("soft_enine: %s\n", "derive ecc private fail");
312             return -1;
313         }
314         return ret;
315     }
316     default:
317         return -1;
318     }
319 }
ecc_export_pub(uint8_t * out,uint32_t out_size,ecc_pub_key_t * pub)320 int32_t ecc_export_pub(uint8_t *out, uint32_t out_size, ecc_pub_key_t *pub)
321 {
322     uint32_t old_domain;
323     bool check = (out == NULL || pub == NULL);
324     if (check) {
325         tloge("soft_enine: %s\n", "ecc export pub input error");
326         return -1;
327     }
328     old_domain     = pub->domain;
329     int boring_cur = ec_nid_tom2boringssl(pub->domain);
330     if (boring_cur < 0) {
331         tloge("soft_enine: %s\n", "bad domain in ecc export pub");
332         return -1;
333     }
334     pub->domain    = (uint32_t)boring_cur;
335     EC_KEY *eckey  = NULL;
336     TEE_Result ret = ecc_pubkey_tee_to_boring(pub, &eckey);
337     pub->domain    = old_domain;
338     if (ret != TEE_SUCCESS) {
339         tloge("soft_enine: %s\n", "tee public key to boring key fail");
340         return -1;
341     }
342     /* i2d_EC_PUBKEY while change tmp_out; */
343     int32_t buffer_size = i2d_EC_PUBKEY(eckey, NULL);
344     if ((uint32_t)buffer_size > out_size) {
345         tloge("out buffer not enough");
346         EC_KEY_free(eckey);
347         return -1;
348     }
349     buffer_size = i2d_EC_PUBKEY(eckey, &out);
350     EC_KEY_free(eckey);
351     if (buffer_size == 0) {
352         tloge("soft_enine: %s\n", "boring key to asn1 fail");
353         return -1;
354     }
355     return buffer_size;
356 }
ecc_get_domain_by_ec_key(const EC_KEY * key,uint32_t * domain)357 static TEE_Result ecc_get_domain_by_ec_key(const EC_KEY *key, uint32_t *domain)
358 {
359     EC_GROUP *g = (EC_GROUP *)EC_KEY_get0_group(key);
360     if (g == NULL) {
361         tloge("soft_enine: %s\n", "EC KEY get group fail");
362         return TEE_ERROR_BAD_PARAMETERS;
363     }
364     int cur                        = EC_GROUP_get_curve_name(g);
365     uint32_t index                 = 0;
366     crypto_u2u domain_to_curve_name[] = {
367         { NID_X9_62_prime192v1, NIST_P192 }, { NID_secp224r1, NIST_P224 }, { NID_X9_62_prime256v1, NIST_P256 },
368         { NID_secp384r1, NIST_P384 },        { NID_secp521r1, NIST_P521 },
369     };
370     for (; index < sizeof(domain_to_curve_name) / sizeof(crypto_u2u); index++) {
371         if ((uint32_t)cur == domain_to_curve_name[index].src) {
372             *domain = domain_to_curve_name[index].dest;
373             return TEE_SUCCESS;
374         }
375     }
376     tloge("get domain fail, invalid cur 0x%x\n", cur);
377     return TEE_ERROR_BAD_PARAMETERS;
378 }
379 
ecc_ecpubkey_boring_to_tee(const EC_KEY * key,ecc_pub_key_t * pub)380 TEE_Result ecc_ecpubkey_boring_to_tee(const EC_KEY *key, ecc_pub_key_t *pub)
381 {
382     if (key == NULL || pub == NULL) {
383         tloge("soft_enine: %s\n", "input param is NULL");
384         return TEE_ERROR_BAD_PARAMETERS;
385     }
386     TEE_Result ret;
387     BIGNUM *x = BN_new();
388     BIGNUM *y = BN_new();
389     if (x == NULL || y == NULL) {
390         tloge("new bn error in boring pub to tee pub");
391         ret = TEE_ERROR_BAD_PARAMETERS;
392         goto error;
393     }
394     const EC_POINT *point = EC_KEY_get0_public_key(key);
395     if (point == NULL) {
396         tloge("boring ec key get public key error");
397         ret = TEE_ERROR_GENERIC;
398         goto error;
399     }
400     int32_t res = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key), point, x, y, NULL);
401     if (res == 0) {
402         tloge("boring ec key get public x y error");
403         ret = TEE_ERROR_GENERIC;
404         goto error;
405     }
406     uint32_t public_key_x_len = (uint32_t)BN_num_bytes(x);
407     uint32_t public_key_y_len = (uint32_t)BN_num_bytes(y);
408     if (public_key_x_len > EC_KEY_FIX_BUFFER_LEN || public_key_y_len > EC_KEY_FIX_BUFFER_LEN) {
409         tloge("buffer not enough");
410         ret = TEE_ERROR_BAD_PARAMETERS;
411         goto error;
412     }
413     pub->x_len = (uint32_t)BN_bn2bin(x, pub->x);
414     pub->y_len = (uint32_t)BN_bn2bin(y, pub->y);
415     ret        = ecc_get_domain_by_ec_key(key, &pub->domain);
416     if (ret != TEE_SUCCESS) {
417         tloge("get domain fail");
418         goto error;
419     }
420 error:
421     BN_free(x);
422     BN_free(y);
423     return ret;
424 }
ecc_import_pub(ecc_pub_key_t * pub,const uint8_t * in,uint32_t inlen)425 int32_t ecc_import_pub(ecc_pub_key_t *pub, const uint8_t *in, uint32_t inlen)
426 {
427     bool check = (pub == NULL || in == NULL);
428     if (check) {
429         tloge("soft_enine: %s\n", "ecc import pub in error");
430         return -1;
431     }
432     EC_KEY *keyp             = NULL;
433     const unsigned char *inp = (const unsigned char *)in;
434     keyp                     = d2i_EC_PUBKEY(&keyp, &inp, inlen);
435     if (keyp == NULL) {
436         tloge("soft_enine: %s\n", "asn1 to ec public key fail");
437         return -1;
438     }
439     TEE_Result ret = ecc_ecpubkey_boring_to_tee(keyp, pub);
440     EC_KEY_free(keyp);
441     keyp = NULL;
442     if (ret != TEE_SUCCESS) {
443         tloge("soft_enine: %s\n", "boring ec key to tee fail");
444         return -1;
445     }
446     return 1;
447 }
ecc_priv_key_boring_to_tee(ecc_priv_key_t * priv,const EC_KEY * key)448 static TEE_Result ecc_priv_key_boring_to_tee(ecc_priv_key_t *priv, const EC_KEY *key)
449 {
450     const BIGNUM *priv_bn = EC_KEY_get0_private_key(key);
451     if (priv_bn == NULL) {
452         tloge("soft_enine: %s\n", "ec key error, get private fail");
453         return TEE_ERROR_BAD_PARAMETERS;
454     }
455     uint32_t domain = 0;
456     TEE_Result ret  = ecc_get_domain_by_ec_key(key, &domain);
457     if (ret != TEE_SUCCESS) {
458         tloge("soft_enine: %s\n", "get domain by ec key fail");
459         return TEE_ERROR_BAD_PARAMETERS;
460     }
461     priv->domain             = domain;
462     uint32_t private_key_len = (uint32_t)BN_num_bytes(priv_bn);
463     if (private_key_len > EC_FIX_BUFFER_LEN) {
464         tloge("soft_enine: %s\n", "private key to buffer error");
465         return TEE_ERROR_GENERIC;
466     }
467     priv->r_len = (uint32_t)BN_bn2bin(priv_bn, priv->r);
468 
469     return TEE_SUCCESS;
470 }
ecc_import_priv(ecc_priv_key_t * priv,const uint8_t * in,uint32_t inlen)471 int32_t ecc_import_priv(ecc_priv_key_t *priv, const uint8_t *in, uint32_t inlen)
472 {
473     bool check = (priv == NULL || in == NULL);
474     if (check) {
475         tloge("soft_enine: %s\n", "ecc import priv in error");
476         return -1;
477     }
478     EC_KEY *key        = NULL;
479     const uint8_t *inp = in;
480     key                = d2i_ECPrivateKey(&key, &inp, inlen);
481     if (key == NULL) {
482         tloge("soft_enine: %s\n", "asn1 to ec public key fail");
483         return -1;
484     }
485     TEE_Result ret = ecc_priv_key_boring_to_tee(priv, key);
486     EC_KEY_free(key);
487     key = NULL;
488     if (ret != TEE_SUCCESS) {
489         tloge("soft_enine: %s\n", "boring ec private key to tee fail");
490         return -1;
491     }
492 
493     return priv->r_len;
494 }
495 
496 /* Read next TLV (Type-Length-Value) from ASN1 buffer buf
497   @param type         [out] type of TLV
498   @param header_len     [out] length of TLV
499   @param buf         [in]  input TLV
500   @param buf_len     [in]  Length of buf in bytes
501   @Return length if next tlv can be found and otherwice -1.
502  * */
get_next_tlv(uint32_t * type,uint32_t * header_len,const uint8_t * buf,uint32_t buf_len)503 int32_t get_next_tlv(uint32_t *type, uint32_t *header_len, const uint8_t *buf, uint32_t buf_len)
504 {
505     uint32_t length = 0;
506     if (type == NULL || header_len == NULL || buf == NULL) {
507         tloge("soft_enine: %s\n", "get next tlv in error");
508         return -1;
509     }
510     if (buf_len < CRYPTO_NUMBER_THREE) {
511         tloge("soft_enine: %s\n", "buf_len too short.\n");
512         return -1;
513     }
514     *type = buf[0];
515     buf++;
516     buf_len--;
517     if (buf[0] < 0x80) { /* Current byte tells the length */
518         length = (uint32_t)buf[0];
519         buf++;
520         buf_len--;
521         *header_len = CRYPTO_NUMBER_TWO;
522     } else {
523         /* bit 8 is set */
524         switch (buf[0] & 0x7F) {
525         case OBJ_LEN_ONE: /* object length is one */
526             buf++;
527             length = (uint32_t)buf[0];
528             buf++;
529             buf_len -= CRYPTO_NUMBER_TWO;
530             *header_len = CRYPTO_NUMBER_THREE;
531             break;
532         case OBJ_LEN_TWO: /* object length is two */
533             if (buf_len < CRYPTO_NUMBER_THREE) {
534                 tloge("soft_enine: %s\n", "buf len is error");
535                 return -1;
536             }
537             buf_len -= CRYPTO_NUMBER_THREE;
538             buf++;
539             length = (((uint32_t)buf[0]) << CRYPTO_NUMBER_EIGHT) + (uint32_t)buf[1];
540             *header_len = CRYPTO_NUMBER_FOUR;
541             break;
542         default: /* Object length does not make sense */
543             return -1;
544         }
545     }
546     /* Check that tag length can fit into buffer */
547     if (length > buf_len) {
548         tloge("soft_enine: %s\n", "get tlv buffer too short");
549         return -1;
550     }
551     return length;
552 }
553 
get_ecsda_signature(ECDSA_SIG * sig_data,uint8_t * signature,uint32_t sig_size)554 static int32_t get_ecsda_signature(ECDSA_SIG *sig_data, uint8_t *signature, uint32_t sig_size)
555 {
556     uint8_t *outp    = NULL;
557     int32_t sign_len = i2d_ECDSA_SIG(sig_data, &outp);
558     OPENSSL_free(outp);
559     if (sign_len < 0 || sign_len > (int32_t)sig_size) {
560         tloge("out buffer too small");
561         return -1;
562     }
563     outp = signature;
564     return i2d_ECDSA_SIG(sig_data, &outp);
565 }
566 
ecc_sign_digest(uint8_t * signature,uint32_t sig_size,uint8_t * in,uint32_t in_len,ecc_priv_key_t * priv)567 int32_t ecc_sign_digest(uint8_t *signature, uint32_t sig_size, uint8_t *in, uint32_t in_len, ecc_priv_key_t *priv)
568 {
569     bool check = (signature == NULL || sig_size == 0 || (in == NULL && in_len != 0) || priv == NULL);
570     if (check) {
571         tloge("soft_enine: %s\n", "input param is NULL");
572         return -1;
573     }
574 
575     EC_KEY *eckey = NULL;
576     int32_t cur = ec_nid_tom2boringssl(priv->domain);
577     if (cur == -1) {
578         tloge("soft_enine: %s\n", "cur get error");
579         return -1;
580     }
581     uint32_t tmp_cur = priv->domain;
582     priv->domain     = (uint32_t)cur;
583     TEE_Result ret   = ecc_privkey_tee_to_boring(priv, (void **)&eckey);
584     priv->domain     = tmp_cur;
585     if (ret != TEE_SUCCESS) {
586         tloge("soft_enine: %s\n", "Tee Private Key To Boring Key error");
587         return -1;
588     }
589     ECDSA_SIG *sig_data = ECDSA_do_sign(in, in_len, eckey);
590     EC_KEY_free(eckey);
591     eckey = NULL;
592     /* boring to asn */
593     if (sig_data == NULL) {
594         tloge("soft_enine: %s\n", "boring sign error");
595         return -1;
596     }
597     int32_t sign_len = get_ecsda_signature(sig_data, signature, sig_size);
598     ECDSA_SIG_free(sig_data);
599 #ifdef OPENSSL_ENABLE
600     free_openssl_drbg_mem();
601 #endif
602 
603     return sign_len;
604 }
ecc_verify_digest(const uint8_t * signature,uint32_t sig_len,uint8_t * in,uint32_t in_len,ecc_pub_key_t * pub)605 int32_t ecc_verify_digest(const uint8_t *signature, uint32_t sig_len, uint8_t *in, uint32_t in_len, ecc_pub_key_t *pub)
606 {
607     bool check = (signature == NULL || sig_len == 0 || (in == NULL && in_len != 0) || pub == NULL);
608     if (check) {
609         tloge("soft_enine: %s\n", "input param is NULL");
610         return -1;
611     }
612 
613     ECDSA_SIG *outp    = NULL;
614     const uint8_t *tmp = signature;
615     EC_KEY *eckey      = NULL;
616     int32_t ret;
617     int cur = ec_nid_tom2boringssl(pub->domain);
618     if (cur < 0) {
619         tloge("soft_enine: %s\n", "get cur error");
620         return -1;
621     }
622     outp = d2i_ECDSA_SIG(&outp, &tmp, sig_len);
623     if (outp == NULL) {
624         tloge("soft_enine: %s\n", "asn to boring fail, sign may be dx");
625         return -1;
626     }
627     uint32_t tmp_cur = pub->domain;
628     pub->domain      = (uint32_t)cur;
629     ret              = (int32_t)ecc_pubkey_tee_to_boring(pub, &eckey);
630     pub->domain      = tmp_cur;
631     if (ret != 0) {
632         ECDSA_SIG_free(outp);
633         tloge("PubKeyToBoringKey key error");
634         return -1;
635     }
636     ret = ECDSA_do_verify(in, in_len, outp, eckey);
637     ECDSA_SIG_free(outp);
638     outp = NULL;
639     EC_KEY_free(eckey);
640     eckey = NULL;
641 #ifdef OPENSSL_ENABLE
642     free_openssl_drbg_mem();
643 #endif
644     if (ret != 1) {
645         tloge("soft_enine: %s\n", "boring verify error");
646         return 0;
647     }
648     return 1;
649 }
650 
651