• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2023 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 #include "mbedtls_ec_adapter.h"
17 
18 #include <mbedtls/base64.h>
19 #include <mbedtls/bignum.h>
20 #include <mbedtls/ctr_drbg.h>
21 #include <mbedtls/entropy.h>
22 #include <mbedtls/error.h>
23 #include <mbedtls/pk.h>
24 #include <mbedtls/x509.h>
25 
26 #include "hal_error.h"
27 #include "hc_log.h"
28 #include "huks_adapter.h"
29 #include "huks_adapter_utils.h"
30 
31 #define LOG_AND_RETURN_IF_MBED_FAIL(ret, fmt, ...) \
32 do { \
33     if ((ret) != 0) { \
34         LOGE(fmt, ##__VA_ARGS__); \
35         return HAL_ERR_MBEDTLS; \
36     } \
37 } while (0)
38 
39 #define LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, fmt, ...) \
40 do { \
41     if ((ret) != 0) { \
42         LOGE(fmt, ##__VA_ARGS__); \
43         goto CLEAN_UP; \
44     } \
45 } while (0)
46 
47 #define LEN_HALF_DIVISOR 2
48 #define BITS_PER_BYTE 8
49 #define EC_LEN 64
50 #define SHA256_HASH_LEN 32
51 #define P256_KEY_SIZE 32
52 #define P256_PUBLIC_SIZE 64 // P256_KEY_SIZE * 2
53 #define X25519_PUBLIC_SIZE 32
54 #define PARAM_A_INDEX 2
55 #define PARAM_U_INDEX 4
56 #define PARAM_MINUS_A_INDEX 3
57 #define PARAM_ONE_INDEX 5
58 #define HASH_TO_POINT_PARA_NUMS 6
59 
60 typedef struct Blob {
61     uint32_t dataSize;
62     uint8_t *data;
63 } Blob;
64 
65 static const uint8_t POINT_A[] = {
66     0x04, 0x53, 0xf9, 0xe4, 0xf4, 0xbc, 0x3a, 0xb5, 0x9d, 0x44, 0x78, 0x45, 0x21, 0x13, 0x8b, 0x49,
67     0xba, 0xa3, 0x1c, 0xe2, 0xa8, 0xdb, 0xbd, 0xb8, 0xd6, 0x73, 0x31, 0x46, 0x3a, 0x69, 0x53, 0xf1,
68     0xed, 0xef, 0x96, 0x1e, 0xdb, 0x42, 0xbe, 0x3a, 0x24, 0x43, 0xc4, 0x08, 0x23, 0xfb, 0x58, 0xee,
69     0x61, 0x24, 0x8b, 0x59, 0x64, 0x65, 0x2d, 0xbc, 0x6b, 0xa5, 0x1d, 0x6e, 0x04, 0x22, 0x53, 0xae,
70     0x27
71 };
72 static const uint8_t POINT_B[] = {
73     0x04, 0x03, 0x4d, 0x11, 0x11, 0xa6, 0x3f, 0x5f, 0x72, 0x43, 0x59, 0x73, 0x8b, 0x46, 0xc3, 0xfd,
74     0x70, 0x58, 0xb0, 0xb6, 0x11, 0xd3, 0x4f, 0xf3, 0x49, 0xa0, 0xd2, 0x86, 0xd7, 0x35, 0x33, 0xc5,
75     0x36, 0xe4, 0x99, 0xcc, 0x13, 0x47, 0xe4, 0xab, 0xde, 0x8f, 0x3a, 0xd6, 0x65, 0x1a, 0x77, 0x0b,
76     0xc4, 0x82, 0xd5, 0xac, 0x4b, 0x5d, 0xe4, 0xcc, 0x48, 0xb0, 0x54, 0x6c, 0x9b, 0x76, 0x76, 0x1a,
77     0xba
78 };
79 
80 static uint8_t g_hash2pointParas[HASH_TO_POINT_PARA_NUMS][BYTE_LENGTH_CURVE_25519] = {
81     { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    /* 0:p */
82       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
83       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
84       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed },
85     { 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    /* 1:divide_minus_p_1_2 */
86       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
87       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
88       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6 },
89     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    /* 2:A */
90       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92       0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6d, 0x06 },
93     { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    /* 3:-A */
94       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
95       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
96       0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x92, 0xe7 },
97     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    /* 4:u = 2 */
98       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
101     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    /* 5:1 */
102       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
105 };
106 
107 static const uint8_t RANDOM_SEED_CUSTOM[] = { 0x4C, 0x54, 0x4B, 0x53 }; // LTKS means LiteKeystore
108 
IsValidBlob(const Blob * blob)109 static bool IsValidBlob(const Blob *blob)
110 {
111     return (blob != NULL) && (blob->data != NULL) && (blob->dataSize != 0);
112 }
113 
IsValidUint8Buff(const Uint8Buff * buff)114 static bool IsValidUint8Buff(const Uint8Buff *buff)
115 {
116     return (buff != NULL) && (buff->val != NULL) && (buff->length != 0);
117 }
118 
InitPointParams(mbedtls_mpi * scalarA,mbedtls_mpi * scalarB,mbedtls_ecp_point * pointA,mbedtls_ecp_point * pointB,mbedtls_ecp_point * result)119 static void InitPointParams(mbedtls_mpi *scalarA, mbedtls_mpi *scalarB, mbedtls_ecp_point *pointA,
120     mbedtls_ecp_point *pointB, mbedtls_ecp_point *result)
121 {
122     mbedtls_mpi_init(scalarA);
123     mbedtls_mpi_init(scalarB);
124     mbedtls_ecp_point_init(pointA);
125     mbedtls_ecp_point_init(pointB);
126     mbedtls_ecp_point_init(result);
127 }
128 
FreePointParams(mbedtls_mpi * scalarA,mbedtls_mpi * scalarB,mbedtls_ecp_point * pointA,mbedtls_ecp_point * pointB,mbedtls_ecp_point * result)129 static void FreePointParams(mbedtls_mpi *scalarA, mbedtls_mpi *scalarB, mbedtls_ecp_point *pointA,
130     mbedtls_ecp_point *pointB, mbedtls_ecp_point *result)
131 {
132     mbedtls_mpi_free(scalarA);
133     mbedtls_mpi_free(scalarB);
134     mbedtls_ecp_point_free(pointA);
135     mbedtls_ecp_point_free(pointB);
136     mbedtls_ecp_point_free(result);
137 }
138 
SwapEndian(uint8_t * pubKey,int len)139 static void SwapEndian(uint8_t *pubKey, int len)
140 {
141     if ((pubKey == NULL) || (len <= 0)) {
142         return;
143     }
144     for (int i = 0; i < len / LEN_HALF_DIVISOR; ++i) {
145         uint8_t tmp = pubKey[i];
146         pubKey[i] = pubKey[len - i - 1];
147         pubKey[len - i - 1] = tmp;
148     }
149 }
150 
FreeCleanFiveBns(mbedtls_mpi * bn1,mbedtls_mpi * bn2,mbedtls_mpi * bn3,mbedtls_mpi * bn4,mbedtls_mpi * bn5)151 static void FreeCleanFiveBns(mbedtls_mpi *bn1, mbedtls_mpi *bn2, mbedtls_mpi *bn3,
152                              mbedtls_mpi *bn4, mbedtls_mpi *bn5)
153 {
154     mbedtls_mpi_free(bn1);
155     mbedtls_mpi_free(bn2);
156     mbedtls_mpi_free(bn3);
157     mbedtls_mpi_free(bn4);
158     mbedtls_mpi_free(bn5);
159 }
160 
CalTmpParaX(mbedtls_mpi * tmpY,const mbedtls_mpi * tmpX,const mbedtls_mpi * modP)161 static int32_t CalTmpParaX(mbedtls_mpi *tmpY, const mbedtls_mpi *tmpX, const mbedtls_mpi *modP)
162 {
163     int32_t status;
164     mbedtls_mpi tmpBnA;
165     mbedtls_mpi tmpBnB;
166     mbedtls_mpi tmpBnC;
167     mbedtls_mpi tmpBnE;
168     mbedtls_mpi paraBnA;
169     mbedtls_mpi paraBnU;
170 
171     mbedtls_mpi_init(&tmpBnA);
172     mbedtls_mpi_init(&tmpBnB);
173     mbedtls_mpi_init(&tmpBnC);
174     mbedtls_mpi_init(&tmpBnE);
175     mbedtls_mpi_init(&paraBnA);
176     mbedtls_mpi_init(&paraBnU);
177 
178     status = mbedtls_mpi_read_binary(&paraBnA, g_hash2pointParas[PARAM_A_INDEX], BYTE_LENGTH_CURVE_25519);
179     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error1");
180 
181     status = mbedtls_mpi_read_binary(&paraBnU, g_hash2pointParas[PARAM_U_INDEX], BYTE_LENGTH_CURVE_25519);
182     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error2");
183 
184     status = mbedtls_mpi_copy(&tmpBnB, tmpX);
185     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error3");
186     /* a := b ^ 3 + A * b ^ 2 + b */
187 
188     status = mbedtls_mpi_exp_mod(&tmpBnE, &tmpBnB, &paraBnU, modP, NULL);
189     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error4"); // b^2
190 
191     status = mbedtls_mpi_mul_mpi(&tmpBnC, &tmpBnE, &tmpBnB);
192     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error5");
193     status = mbedtls_mpi_mod_mpi(&tmpBnC, &tmpBnC, modP);
194     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error6"); // b^3
195 
196     status = mbedtls_mpi_mul_mpi(&tmpBnA, &tmpBnE, &paraBnA); // A*b^2
197     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error7");
198     status = mbedtls_mpi_mod_mpi(&tmpBnA, &tmpBnA, modP);
199     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error8");
200 
201     status = mbedtls_mpi_add_mpi(&tmpBnE, &tmpBnC, &tmpBnA); // b^3 + A*b^2
202     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error9");
203     status = mbedtls_mpi_mod_mpi(&tmpBnE, &tmpBnE, modP);
204     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error10");
205 
206     status = mbedtls_mpi_add_mpi(tmpY, &tmpBnE, &tmpBnB); // b^3 + A*b^2 + b
207     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error11");
208     status = mbedtls_mpi_mod_mpi(tmpY, tmpY, modP);
209     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error12");
210 
211 CLEAN_UP:
212     FreeCleanFiveBns(&paraBnA, &tmpBnA, &tmpBnB, &tmpBnC, &tmpBnE);
213     mbedtls_mpi_free(&paraBnU);
214     return status;
215 }
216 
CalTmpParab(mbedtls_mpi * tmpX,const mbedtls_mpi * modP,const uint8_t * hash,uint32_t hashLen)217 static int32_t CalTmpParab(mbedtls_mpi *tmpX, const mbedtls_mpi *modP, const uint8_t *hash, uint32_t hashLen)
218 {
219     int32_t status;
220     mbedtls_mpi paraBnNegA;
221     mbedtls_mpi paraBNOne;
222     mbedtls_mpi paraBnU;
223     mbedtls_mpi tmpBnA;
224     mbedtls_mpi tmpBnB;
225 
226     mbedtls_mpi_init(&paraBnNegA);
227     mbedtls_mpi_init(&paraBNOne);
228     mbedtls_mpi_init(&paraBnU);
229     mbedtls_mpi_init(&tmpBnA);
230     mbedtls_mpi_init(&tmpBnB);
231 
232     status = mbedtls_mpi_read_binary(&paraBnNegA, g_hash2pointParas[PARAM_MINUS_A_INDEX], BYTE_LENGTH_CURVE_25519);
233     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error1");
234     status = mbedtls_mpi_read_binary(&paraBNOne, g_hash2pointParas[PARAM_ONE_INDEX], BYTE_LENGTH_CURVE_25519);
235     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error2");
236     status = mbedtls_mpi_read_binary(&paraBnU, g_hash2pointParas[PARAM_U_INDEX], BYTE_LENGTH_CURVE_25519);
237     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error3");
238     status = mbedtls_mpi_read_binary(&tmpBnA, hash, hashLen);
239     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error4");
240 
241     /* b := -A / (1 + u * a ^ 2) */
242     status = mbedtls_mpi_exp_mod(&tmpBnB, &tmpBnA, &paraBnU, modP, NULL);
243     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error5");
244 
245     status = mbedtls_mpi_mul_mpi(&tmpBnA, &tmpBnB, &paraBnU);
246     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error6");
247     status = mbedtls_mpi_mod_mpi(&tmpBnA, &tmpBnA, modP);
248     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error7");
249 
250     status = mbedtls_mpi_add_mpi(&tmpBnB, &tmpBnA, &paraBNOne);
251     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error8");
252     status = mbedtls_mpi_mod_mpi(&tmpBnB, &tmpBnB, modP);
253     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error9");
254 
255     status = mbedtls_mpi_inv_mod(&tmpBnA, &tmpBnB, modP);
256     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error10");
257 
258     status = mbedtls_mpi_mul_mpi(tmpX, &tmpBnA, &paraBnNegA);
259     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error11");
260     status = mbedtls_mpi_mod_mpi(tmpX, tmpX, modP);
261     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error12");
262 CLEAN_UP:
263     FreeCleanFiveBns(&paraBnNegA, &paraBNOne, &paraBnU, &tmpBnA, &tmpBnB);
264     return status;
265 }
266 
267 /*
268  * hash2point function, use BoringSSL big number algorithm library;
269  * p_point(little endian): the output pointer of Curve25519 point;
270  * p_hash (little endian): the input pointer of string;
271  */
Elligator(unsigned char * point,int pointLength,const unsigned char * hash,int hashLength)272 static int32_t Elligator(unsigned char *point, int pointLength, const unsigned char *hash, int hashLength)
273 {
274     mbedtls_mpi paraBnP;
275     mbedtls_mpi paraBnSquare;
276     mbedtls_mpi paraBnNegA;
277     mbedtls_mpi tmpBnA;
278     mbedtls_mpi tmpBnB;
279     mbedtls_mpi tmpBnC;
280     mbedtls_mpi tmpBnE;
281 
282     mbedtls_mpi_init(&paraBnP);
283     mbedtls_mpi_init(&paraBnSquare);
284     mbedtls_mpi_init(&paraBnNegA);
285     mbedtls_mpi_init(&tmpBnA);
286     mbedtls_mpi_init(&tmpBnB);
287     mbedtls_mpi_init(&tmpBnC);
288     mbedtls_mpi_init(&tmpBnE);
289 
290     int32_t status = mbedtls_mpi_read_binary(&paraBnP, g_hash2pointParas[0], BYTE_LENGTH_CURVE_25519);
291     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error1");
292     status = mbedtls_mpi_read_binary(&paraBnSquare, g_hash2pointParas[1], BYTE_LENGTH_CURVE_25519);
293     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error2");
294     status = mbedtls_mpi_read_binary(&paraBnNegA, g_hash2pointParas[PARAM_MINUS_A_INDEX], BYTE_LENGTH_CURVE_25519);
295     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error3");
296 
297     status = CalTmpParab(&tmpBnB, &paraBnP, hash, hashLength);
298     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error4");
299     status = CalTmpParaX(&tmpBnA, &tmpBnB, &paraBnP);
300     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error5");
301 
302     status = mbedtls_mpi_sub_mpi(&tmpBnC, &paraBnP, &tmpBnB);
303     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error6");
304     status = mbedtls_mpi_mod_mpi(&tmpBnC, &tmpBnC, &paraBnP);
305     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error7");
306 
307     status = mbedtls_mpi_add_mpi(&tmpBnC, &tmpBnC, &paraBnNegA);
308     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error8");
309     status = mbedtls_mpi_mod_mpi(&tmpBnC, &tmpBnC, &paraBnP);
310     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error9");
311 
312     status = mbedtls_mpi_exp_mod(&tmpBnE, &tmpBnA, &paraBnSquare, &paraBnP, NULL);
313     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error10");
314 
315     status = mbedtls_mpi_safe_cond_swap(&tmpBnB, &tmpBnC, (mbedtls_mpi_cmp_mpi(&paraBnSquare, &tmpBnE) == 1));
316     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error11");
317 
318     status = mbedtls_mpi_write_binary(&tmpBnC, point, pointLength);
319     LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error12");
320 
321     SwapEndian(point, pointLength);
322 CLEAN_UP:
323     mbedtls_mpi_free(&paraBnP);
324     mbedtls_mpi_free(&paraBnSquare);
325     FreeCleanFiveBns(&paraBnNegA, &tmpBnA, &tmpBnB, &tmpBnC, &tmpBnE);
326     return status;
327 }
328 
CalculateMessageDigest(mbedtls_md_type_t type,const Blob * input,Blob * output)329 static int32_t CalculateMessageDigest(mbedtls_md_type_t type, const Blob *input, Blob *output)
330 {
331     const mbedtls_md_info_t *info = mbedtls_md_info_from_type(type);
332     if (info == NULL) {
333         return HAL_ERR_NOT_SUPPORTED;
334     }
335 
336     uint32_t outSize = mbedtls_md_get_size(info);
337     if (output->dataSize < outSize) {
338         return HAL_ERR_SHORT_BUFFER;
339     }
340 
341     int32_t ret = mbedtls_md(info, input->data, input->dataSize, output->data);
342     LOG_AND_RETURN_IF_MBED_FAIL(ret, "Calculate message digest failed.");
343 
344     output->dataSize = outSize;
345     return HAL_SUCCESS;
346 }
347 
Sha256(const Blob * input,Blob * output)348 static int32_t Sha256(const Blob *input, Blob *output)
349 {
350     if (!IsValidBlob(input) || !IsValidBlob(output)) {
351         LOGE("Input params for sha256 is invalid.");
352         return HAL_ERR_INVALID_PARAM;
353     }
354     return CalculateMessageDigest(MBEDTLS_MD_SHA256, input, output);
355 }
356 
ReadBigNums(mbedtls_mpi * x,mbedtls_mpi * y,const Blob * blob)357 static int32_t ReadBigNums(mbedtls_mpi *x, mbedtls_mpi *y, const Blob *blob)
358 {
359     int32_t ret = mbedtls_mpi_read_binary(x, blob->data, P256_KEY_SIZE);
360     LOG_AND_RETURN_IF_MBED_FAIL(ret, "Read x coordinate of public key failed.");
361     ret = mbedtls_mpi_read_binary(y, blob->data + P256_KEY_SIZE, P256_KEY_SIZE);
362     LOG_AND_RETURN_IF_MBED_FAIL(ret, "Read y coordinate of public key failed.");
363     return HAL_SUCCESS;
364 }
365 
ReadEcPublicKey(mbedtls_ecp_point * point,const Blob * publicKey)366 static int32_t ReadEcPublicKey(mbedtls_ecp_point *point, const Blob *publicKey)
367 {
368     int32_t ret = ReadBigNums(&point->MBEDTLS_PRIVATE(X), &point->MBEDTLS_PRIVATE(Y), publicKey);
369     LOG_AND_RETURN_IF_MBED_FAIL(ret, "Read coordinate of public key failed.");
370     ret = mbedtls_mpi_lset(&point->MBEDTLS_PRIVATE(Z), 1);
371     LOG_AND_RETURN_IF_MBED_FAIL(ret, "Lset point z failed.");
372     return HAL_SUCCESS;
373 }
374 
WriteOutBigNums(const mbedtls_mpi * x,const mbedtls_mpi * y,Blob * out)375 static int32_t WriteOutBigNums(const mbedtls_mpi *x, const mbedtls_mpi *y, Blob *out)
376 {
377     int32_t ret = mbedtls_mpi_write_binary(x, out->data, P256_KEY_SIZE);
378     LOG_AND_RETURN_IF_MBED_FAIL(ret, "Write x coordinate of public key failed.");
379 
380     ret = mbedtls_mpi_write_binary(y, out->data + P256_KEY_SIZE, P256_KEY_SIZE);
381     LOG_AND_RETURN_IF_MBED_FAIL(ret, "Write y coordinate of public key failed.");
382 
383     out->dataSize = P256_PUBLIC_SIZE;
384     return HAL_SUCCESS;
385 }
386 
WriteOutEcPublicKey(const mbedtls_ecp_point * point,Blob * publicKey)387 static int32_t WriteOutEcPublicKey(const mbedtls_ecp_point *point, Blob *publicKey)
388 {
389     return WriteOutBigNums(&point->MBEDTLS_PRIVATE(X), &point->MBEDTLS_PRIVATE(Y), publicKey);
390 }
391 
EcKeyAgreementLog(mbedtls_ecp_keypair * keyPair,mbedtls_ecp_point * p,mbedtls_ctr_drbg_context * ctrDrbg)392 static int EcKeyAgreementLog(mbedtls_ecp_keypair *keyPair, mbedtls_ecp_point *p, mbedtls_ctr_drbg_context *ctrDrbg)
393 {
394     return mbedtls_ecp_mul_restartable(&keyPair->MBEDTLS_PRIVATE(grp), p, &keyPair->MBEDTLS_PRIVATE(d),
395         &keyPair->MBEDTLS_PRIVATE(Q), mbedtls_ctr_drbg_random, ctrDrbg, NULL);
396 }
397 
EcKeyAgreement(const Blob * privateKey,const Blob * publicKey,Blob * secretKey)398 static int32_t EcKeyAgreement(const Blob *privateKey, const Blob *publicKey, Blob *secretKey)
399 {
400     if (!IsValidBlob(publicKey) || publicKey->dataSize != P256_PUBLIC_SIZE || !IsValidBlob(secretKey) ||
401         secretKey->dataSize != P256_PUBLIC_SIZE || !IsValidBlob(privateKey)) {
402         LOGE("Input params for ec key agree is invalid.");
403         return HAL_ERR_INVALID_PARAM;
404     }
405     mbedtls_mpi *secret = HcMalloc(sizeof(mbedtls_mpi), 0);
406     mbedtls_ecp_keypair *keyPair = HcMalloc(sizeof(mbedtls_ecp_keypair), 0);
407     mbedtls_entropy_context *entropy = HcMalloc(sizeof(mbedtls_entropy_context), 0);
408     mbedtls_ctr_drbg_context *ctrDrbg = HcMalloc(sizeof(mbedtls_ctr_drbg_context), 0);
409     if ((secret == NULL) || (keyPair == NULL) || (entropy == NULL) || (ctrDrbg == NULL)) {
410         LOGE("Malloc for mbedtls ec key param failed.");
411         HcFree(secret);
412         HcFree(keyPair);
413         HcFree(entropy);
414         HcFree(ctrDrbg);
415         return HAL_ERR_BAD_ALLOC;
416     }
417     mbedtls_mpi_init(secret);
418     mbedtls_ecp_keypair_init(keyPair);
419     mbedtls_entropy_init(entropy);
420     mbedtls_ctr_drbg_init(ctrDrbg);
421     mbedtls_ecp_point p;
422     mbedtls_ecp_point_init(&p);
423     int32_t ret = ReadEcPublicKey(&keyPair->MBEDTLS_PRIVATE(Q), publicKey);
424     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read the public key failed.");
425     ret = mbedtls_ecp_group_load(&keyPair->MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
426     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Load the ecp group failed.");
427     ret = mbedtls_mpi_read_binary(&keyPair->MBEDTLS_PRIVATE(d), privateKey->data, privateKey->dataSize);
428     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read the private key failed.");
429     ret = mbedtls_ctr_drbg_seed(ctrDrbg, mbedtls_entropy_func, entropy,
430         RANDOM_SEED_CUSTOM, sizeof(RANDOM_SEED_CUSTOM));
431     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set custom string failed.");
432     LOG_AND_GOTO_CLEANUP_IF_FAIL(EcKeyAgreementLog(keyPair, &p, ctrDrbg), "Compute secret key failed.");
433     LOG_AND_GOTO_CLEANUP_IF_FAIL(mbedtls_mpi_copy(secret, &p.MBEDTLS_PRIVATE(X)), "Copy secret failed.");
434     LOG_AND_GOTO_CLEANUP_IF_FAIL(WriteOutEcPublicKey(&p, secretKey), "Write out ec public key failed.");
435 CLEAN_UP:
436     mbedtls_mpi_free(secret);
437     mbedtls_ecp_keypair_free(keyPair);
438     mbedtls_entropy_free(entropy);
439     mbedtls_ctr_drbg_free(ctrDrbg);
440     mbedtls_ecp_point_free(&p);
441     HcFree(secret);
442     HcFree(keyPair);
443     HcFree(entropy);
444     HcFree(ctrDrbg);
445     LOG_AND_RETURN_IF_MBED_FAIL(ret, "Ec key agree failed.");
446     return HAL_SUCCESS;
447 }
448 
EcHashToPoint(const Blob * hash,Blob * point)449 static int32_t EcHashToPoint(const Blob *hash, Blob *point)
450 {
451     mbedtls_mpi scalarA;
452     mbedtls_mpi scalarB;
453     mbedtls_ecp_point pointA;
454     mbedtls_ecp_point pointB;
455     mbedtls_ecp_point result;
456     InitPointParams(&scalarA, &scalarB, &pointA, &pointB, &result);
457 
458     mbedtls_ecp_group grp;
459     mbedtls_ecp_group_init(&grp);
460     uint8_t digest[SHA256_HASH_LEN] = { 0 };
461     Blob digestBlob = { sizeof(digest), digest };
462 
463     int32_t ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
464     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Load ecp group failed.");
465     ret = mbedtls_ecp_point_read_binary(&grp, &pointA, POINT_A, sizeof(POINT_A));
466     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read point A failed.");
467     ret = mbedtls_ecp_point_read_binary(&grp, &pointB, POINT_B, sizeof(POINT_B));
468     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read point B failed.");
469     ret = Sha256(hash, &digestBlob);
470     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Compute message digest failed.");
471     ret = mbedtls_mpi_lset(&scalarA, 1);
472     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set number one failed.");
473     ret = mbedtls_mpi_read_binary(&scalarB, digest, SHA256_HASH_LEN);
474     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read digest failed.");
475     ret = mbedtls_ecp_muladd(&grp, &result, &scalarA, &pointA, &scalarB, &pointB);
476     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Double-scalar multiplication failed.");
477     ret = mbedtls_ecp_check_pubkey(&grp, &result);
478     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Invalid point on P256 is returned.");
479     ret = WriteOutEcPublicKey(&result, point);
480     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Write out public key failed.");
481 CLEAN_UP:
482     FreePointParams(&scalarA, &scalarB, &pointA, &pointB, &result);
483     mbedtls_ecp_group_free(&grp);
484     LOG_AND_RETURN_IF_MBED_FAIL(ret, "Ec hash to point failed.");
485     return HAL_SUCCESS;
486 }
487 
488 // only support P256 HashToPoint for standard system
MbedtlsHashToPoint(const Uint8Buff * hash,Uint8Buff * outEcPoint)489 int32_t MbedtlsHashToPoint(const Uint8Buff *hash, Uint8Buff *outEcPoint)
490 {
491     CHECK_PTR_RETURN_HAL_ERROR_CODE(hash, "hash");
492     CHECK_PTR_RETURN_HAL_ERROR_CODE(hash->val, "hash->val");
493     CHECK_LEN_EQUAL_RETURN(hash->length, SHA256_LEN, "hash->length");
494     CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint, "outEcPoint");
495     CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint->val, "outEcPoint->val");
496     CHECK_LEN_EQUAL_RETURN(outEcPoint->length, EC_LEN, "outEcPoint->length");
497 
498     struct Blob hashBlob = {
499         .dataSize = hash->length,
500         .data = hash->val
501     };
502     struct Blob pointBlob = {
503         .dataSize = outEcPoint->length,
504         .data = outEcPoint->val
505     };
506 
507     int32_t ret = EcHashToPoint(&hashBlob, &pointBlob);
508     if (ret != 0 || pointBlob.dataSize != EC_LEN) {
509         LOGE("HashToPoint with mbedtls for P256 failed, ret: %" LOG_PUB "d", ret);
510         return HAL_FAILED;
511     }
512 
513     return HAL_SUCCESS;
514 }
515 
MbedtlsHashToPoint25519(const Uint8Buff * hash,Uint8Buff * outEcPoint)516 int32_t MbedtlsHashToPoint25519(const Uint8Buff *hash, Uint8Buff *outEcPoint)
517 {
518     if (!IsValidUint8Buff(hash) || !IsValidUint8Buff(outEcPoint)) {
519         return HAL_ERR_INVALID_PARAM;
520     }
521     if (hash->length != BYTE_LENGTH_CURVE_25519 || outEcPoint->length != BYTE_LENGTH_CURVE_25519) {
522         LOGE("MbedtlsHashToPoint invalid length.");
523         return HAL_ERR_INVALID_PARAM;
524     }
525     uint8_t hashTmp[BYTE_LENGTH_CURVE_25519] = { 0 };
526     (void)memcpy_s(hashTmp, BYTE_LENGTH_CURVE_25519, hash->val, BYTE_LENGTH_CURVE_25519);
527 
528     hashTmp[BYTE_LENGTH_CURVE_25519 - 1] &= ~HASH2POINT_PARA_PREPRO;
529     SwapEndian(hashTmp, BYTE_LENGTH_CURVE_25519);
530     int status = Elligator(outEcPoint->val, BYTE_LENGTH_CURVE_25519, hashTmp, BYTE_LENGTH_CURVE_25519);
531     if (status != 0) {
532         LOGE("Elligator failed, status:%" LOG_PUB "d", status);
533     }
534     return status;
535 }
536 
537 // only support P256 AgreeSharedSecret for standard system
MbedtlsAgreeSharedSecret(const KeyBuff * priKey,const KeyBuff * pubKey,Uint8Buff * sharedKey)538 int32_t MbedtlsAgreeSharedSecret(const KeyBuff *priKey, const KeyBuff *pubKey, Uint8Buff *sharedKey)
539 {
540     CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey, "priKey");
541     CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey->key, "priKey->key");
542     CHECK_LEN_ZERO_RETURN_ERROR_CODE(priKey->keyLen, "priKey->keyLen");
543     CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey, "devicePk");
544     CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey->key, "devicePk->key");
545     CHECK_LEN_ZERO_RETURN_ERROR_CODE(pubKey->keyLen, "devicePk->keyLen");
546     CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKey, "sharedKey");
547     CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKey->val, "sharedKey->val");
548     CHECK_LEN_ZERO_RETURN_ERROR_CODE(sharedKey->length, "sharedKey->length");
549 
550     struct Blob priKeyBlob = {
551         .dataSize = priKey->keyLen,
552         .data = priKey->key
553     };
554     struct Blob pubKeyBlob = {
555         .dataSize = pubKey->keyLen,
556         .data = pubKey->key
557     };
558     struct Blob sharedKeyBlob = {
559         .dataSize = sharedKey->length,
560         .data = sharedKey->val
561     };
562     int32_t ret = EcKeyAgreement(&priKeyBlob, &pubKeyBlob, &sharedKeyBlob);
563     if (ret != 0) {
564         LOGE("Agree key failed, ret = %" LOG_PUB "d", ret);
565         return HAL_FAILED;
566     }
567     return HAL_SUCCESS;
568 }
569 
MbedtlsBase64Encode(const uint8_t * byte,uint32_t byteLen,char * base64Str,uint32_t strLen,uint32_t * outLen)570 int32_t MbedtlsBase64Encode(const uint8_t *byte, uint32_t byteLen, char *base64Str, uint32_t strLen, uint32_t *outLen)
571 {
572     CHECK_PTR_RETURN_HAL_ERROR_CODE(byte, "byte");
573     CHECK_LEN_ZERO_RETURN_ERROR_CODE(byteLen, "byteLen");
574     CHECK_PTR_RETURN_HAL_ERROR_CODE(base64Str, "base64Str");
575     CHECK_LEN_ZERO_RETURN_ERROR_CODE(strLen, "strLen");
576     CHECK_PTR_RETURN_HAL_ERROR_CODE(outLen, "outLen");
577 
578     size_t needBuffLen = 0;
579     (void)mbedtls_base64_encode(NULL, 0, &needBuffLen, byte, byteLen);
580     if (needBuffLen > strLen) {
581         LOGE("The content to be written is larger than the input buffer size. Need: %" LOG_PUB "zd, Buffer: %"
582             LOG_PUB "u", needBuffLen, strLen);
583         return HAL_ERR_SHORT_BUFFER;
584     }
585 
586     int res = mbedtls_base64_encode((unsigned char *)base64Str, strLen, &needBuffLen, byte, byteLen);
587     if (res != 0) {
588         LOGE("call mbedtls's mbedtls_base64_encode fail. res: %" LOG_PUB "d", res);
589         return HAL_ERR_MBEDTLS;
590     }
591 
592     *outLen = needBuffLen;
593     return HAL_SUCCESS;
594 }
595 
MbedtlsBase64Decode(const char * base64Str,uint32_t strLen,uint8_t * byte,uint32_t byteLen,uint32_t * outLen)596 int32_t MbedtlsBase64Decode(const char *base64Str, uint32_t strLen, uint8_t *byte, uint32_t byteLen, uint32_t *outLen)
597 {
598     CHECK_PTR_RETURN_HAL_ERROR_CODE(base64Str, "base64Str");
599     CHECK_LEN_ZERO_RETURN_ERROR_CODE(strLen, "strLen");
600     CHECK_PTR_RETURN_HAL_ERROR_CODE(byte, "byte");
601     CHECK_LEN_ZERO_RETURN_ERROR_CODE(byteLen, "byteLen");
602     CHECK_PTR_RETURN_HAL_ERROR_CODE(outLen, "outLen");
603 
604     size_t needBuffLen = 0;
605     int res = mbedtls_base64_decode(NULL, 0, &needBuffLen, (const unsigned char *)base64Str, strLen);
606     if (res == MBEDTLS_ERR_BASE64_INVALID_CHARACTER) {
607         LOGE("The input string is not in base64 encoding format.");
608         return HAL_ERR_BASE64_FORMAT;
609     }
610 
611     if (needBuffLen > byteLen) {
612         LOGE("The content to be written is larger than the input buffer size. Need: %" LOG_PUB "zd, Buffer: %"
613             LOG_PUB "u", needBuffLen, byteLen);
614         return HAL_ERR_SHORT_BUFFER;
615     }
616 
617     res = mbedtls_base64_decode(byte, byteLen, &needBuffLen, (const unsigned char *)base64Str, strLen);
618     if (res != 0) {
619         LOGE("call mbedtls's mbedtls_base64_decode fail. res: %" LOG_PUB "d", res);
620         return HAL_ERR_MBEDTLS;
621     }
622 
623     *outLen = (uint32_t)needBuffLen;
624     return HAL_SUCCESS;
625 }
626 
MbedtlsIsP256PublicKeyValid(const Uint8Buff * pubKey)627 bool MbedtlsIsP256PublicKeyValid(const Uint8Buff *pubKey)
628 {
629     if ((pubKey == NULL) || (pubKey->val == NULL) || (pubKey->length != P256_PUBLIC_SIZE)) {
630         LOGE("Invaild P256 pubKey input.");
631         return false;
632     }
633     mbedtls_ctr_drbg_context *ctrDrbg = HcMalloc(sizeof(mbedtls_ctr_drbg_context), 0);
634     if (ctrDrbg == NULL) {
635         LOGE("Malloc for mbedtls_ctr_drbg_context failed.");
636         return false;
637     }
638     mbedtls_ecp_group grp;
639     mbedtls_ecp_point publicKeyPoint;
640     mbedtls_ecp_point returnPoint;
641     mbedtls_ecp_group_init(&grp);
642     mbedtls_ctr_drbg_init(ctrDrbg);
643     mbedtls_ecp_point_init(&publicKeyPoint);
644     mbedtls_ecp_point_init(&returnPoint);
645     mbedtls_mpi scalar;
646     mbedtls_mpi_init(&scalar);
647     const int32_t P256_CHECK_SCALAR_VALUE = 8;
648     Blob publicKey = {
649         .data = pubKey->val,
650         .dataSize = pubKey->length
651     };
652     int32_t ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
653     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Load P256 group failed.");
654     ret = ReadEcPublicKey(&publicKeyPoint, &publicKey);
655     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read P256 public key failed.");
656     ret = mbedtls_ecp_check_pubkey(&grp, &publicKeyPoint);
657     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Invaild point on P256.");
658     ret = mbedtls_mpi_lset(&scalar, P256_CHECK_SCALAR_VALUE);
659     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set number eight failed.");
660     ret = mbedtls_ecp_mul(&grp, &returnPoint, &scalar, &publicKeyPoint, mbedtls_ctr_drbg_random, ctrDrbg);
661     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Compute 8PK failed.");
662     ret = mbedtls_ecp_is_zero(&returnPoint);
663     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "8PK is the point at infinity.");
664 CLEAN_UP:
665     mbedtls_ecp_group_free(&grp);
666     mbedtls_ctr_drbg_free(ctrDrbg);
667     mbedtls_ecp_point_free(&publicKeyPoint);
668     mbedtls_ecp_point_free(&returnPoint);
669     mbedtls_mpi_free(&scalar);
670     HcFree(ctrDrbg);
671     if (ret != HAL_SUCCESS) {
672         LOGE("P256 pubKey is invaild!");
673         return false;
674     }
675     LOGI("Check P256 pubKey success.");
676     return true;
677 }
678 
SetX25519CheckScalar(mbedtls_mpi * scalar)679 static int32_t SetX25519CheckScalar(mbedtls_mpi *scalar)
680 {
681     const int32_t VAILD_SCALAR_VALUE_ZERO_POS0 = 0;
682     const int32_t VAILD_SCALAR_VALUE_ZERO_POS1 = 1;
683     const int32_t VAILD_SCALAR_VALUE_ZERO_POS2 = 2;
684     const int32_t VAILD_SCALAR_VALUE_ONE_POS254 = 254;
685     const int32_t CHECK_SCALAR_VALUE_ONE_POS3 = 3;
686 #if defined(MBEDTLS_HAVE_INT64)
687     const int32_t SCALAR_LENGTH = 4;
688 #elif defined(MBEDTLS_HAVE_INT32)
689     const int32_t SCALAR_LENGTH = 8;
690 #else
691     LOG_AND_GOTO_CLEANUP_IF_FAIL(HAL_ERR_NOT_SUPPORTED, "Scalar limb size unknown.");
692 #endif
693     //2^254 + 8 * 1
694     int32_t ret = mbedtls_mpi_grow(scalar, SCALAR_LENGTH);
695     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set scalar length failed.");
696     ret = mbedtls_mpi_set_bit(scalar, VAILD_SCALAR_VALUE_ZERO_POS0, 0);
697     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set scalar pos 0 failed.");
698     ret = mbedtls_mpi_set_bit(scalar, VAILD_SCALAR_VALUE_ZERO_POS1, 0);
699     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set scalar pos 1 failed.");
700     ret = mbedtls_mpi_set_bit(scalar, VAILD_SCALAR_VALUE_ZERO_POS2, 0);
701     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set scalar pos 2 failed.");
702     ret = mbedtls_mpi_set_bit(scalar, VAILD_SCALAR_VALUE_ONE_POS254, 1);
703     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set scalar pos 254 failed.");
704     ret = mbedtls_mpi_set_bit(scalar, CHECK_SCALAR_VALUE_ONE_POS3, 1);
705     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set scalar pos 3 failed.");
706 CLEAN_UP:
707     return ret;
708 }
709 
MbedtlsIsX25519PublicKeyValid(const Uint8Buff * pubKey)710 bool MbedtlsIsX25519PublicKeyValid(const Uint8Buff *pubKey)
711 {
712     if ((pubKey == NULL) || (pubKey->val == NULL) || (pubKey->length != X25519_PUBLIC_SIZE)) {
713         LOGE("Invaild X25519 pubKey input.");
714         return false;
715     }
716     mbedtls_ctr_drbg_context *ctrDrbg = HcMalloc(sizeof(mbedtls_ctr_drbg_context), 0);
717     if (ctrDrbg == NULL) {
718         LOGE("Malloc for ctrDrbg failed.");
719         return false;
720     }
721     mbedtls_ecp_group grp;
722     mbedtls_ecp_point publicKeyPoint;
723     mbedtls_ecp_point returnPoint;
724     mbedtls_mpi scalar;
725     mbedtls_ecp_group_init(&grp);
726     mbedtls_ctr_drbg_init(ctrDrbg);
727     mbedtls_ecp_point_init(&publicKeyPoint);
728     mbedtls_ecp_point_init(&returnPoint);
729     mbedtls_mpi_init(&scalar);
730     int32_t ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_CURVE25519);
731     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Load X25519 group failed.");
732     ret = mbedtls_ecp_point_read_binary(&grp, &publicKeyPoint, pubKey->val, pubKey->length);
733     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read X25519 public key failed.");
734     ret = mbedtls_ecp_check_pubkey(&grp, &publicKeyPoint);
735     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Invaild point on X25519.");
736     ret = SetX25519CheckScalar(&scalar);
737     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set scalar (2^254 + 8 * 1) failed.");
738     ret = mbedtls_ecp_mul(&grp, &returnPoint, &scalar, &publicKeyPoint, mbedtls_ctr_drbg_random, ctrDrbg);
739     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Compute (2^254 + 8 * 1)PK failed.");
740     ret = mbedtls_ecp_is_zero(&returnPoint);
741     LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "(2^254 + 8 * 1)PK is the point at infinity.");
742 CLEAN_UP:
743     mbedtls_ecp_group_free(&grp);
744     mbedtls_ctr_drbg_free(ctrDrbg);
745     mbedtls_ecp_point_free(&publicKeyPoint);
746     mbedtls_ecp_point_free(&returnPoint);
747     mbedtls_mpi_free(&scalar);
748     HcFree(ctrDrbg);
749     if (ret != HAL_SUCCESS) {
750         LOGE("X25519 pubKey is invaild!");
751         return false;
752     }
753     LOGI("Check X25519 pubKey success.");
754     return true;
755 }