• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright The Mbed TLS Contributors
3  *  SPDX-License-Identifier: Apache-2.0
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
6  *  not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *  Copyright (c) 2023 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
17  */
18 
19 /*
20  * References:
21  *
22  * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
23  * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
24  * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
25  * RFC 4492 for the related TLS structures and constants
26  * RFC 7748 for the Curve448 and Curve25519 curve definitions
27  *
28  * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
29  *
30  * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
31  *     for elliptic curve cryptosystems. In : Cryptographic Hardware and
32  *     Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
33  *     <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
34  *
35  * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
36  *     render ECC resistant against Side Channel Attacks. IACR Cryptology
37  *     ePrint Archive, 2004, vol. 2004, p. 342.
38  *     <http://eprint.iacr.org/2004/342.pdf>
39  */
40 
41 #include "common.h"
42 
43 #if defined(MBEDTLS_ECP_C)
44 
45 #include "mbedtls/ecp.h"
46 #include "mbedtls/error.h"
47 #include "multithread.h"
48 #include "pke.h"
49 #include <string.h>
50 
51 #if defined(MBEDTLS_ECP_ALT)
52 
53 /****************************************************************
54  * HW unit curve data constants definition
55  ****************************************************************/
56 
57 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
58 static eccp_curve_t secp256r1 = {.eccp_p_bitLen = 256,
59     .eccp_p = (unsigned int[8]) {0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
60         0xffffffff},
61     .eccp_p_h = (unsigned int[8]) {0x00000003, 0x00000000, 0xffffffff, 0xfffffffb, 0xfffffffe, 0xffffffff, 0xfffffffd,
62         0x00000004},
63     .eccp_p_h = (unsigned int[1]) {0x00000001},
64     .eccp_a = (unsigned int[8]) {0xfffffffc, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
65         0xffffffff},
66     .eccp_b = (unsigned int[8]) {
67         0x27d2604b, 0x3bce3c3e, 0xcc53b0f6, 0x651d06b0, 0x769886bc, 0xb3ebbd55, 0xaa3a93e7, 0x5ac635d8}};
68 #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
69 
70 #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
71 static eccp_curve_t secp256k1 = {.eccp_p_bitLen = 256,
72     .eccp_p = (unsigned int[8]) {0xfffffc2f, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
73         0xffffffff},
74     .eccp_p_h = (unsigned int[8]) {0x000e90a1, 0x000007a2, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
75         0x00000000},
76     .eccp_p_h = (unsigned int[1]) {0xd2253531},
77     .eccp_a = (unsigned int[8]) {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
78         0x00000000},
79     .eccp_b = (unsigned int[8]) {
80         0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}};
81 #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
82 
83 #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
84 static eccp_curve_t BP256r1 = {.eccp_p_bitLen = 256,
85     .eccp_p = (unsigned int[8]) {0x1f6e5377, 0x2013481d, 0xd5262028, 0x6e3bf623, 0x9d838d72, 0x3e660a90, 0xa1eea9bc,
86         0xa9fb57db},
87     .eccp_p_h = (unsigned int[8]) {0xa6465b6c, 0x8cfedf7b, 0x614d4f4d, 0x5cce4c26, 0x6b1ac807, 0xa1ecdacd, 0xe5957fa8,
88         0x4717aa21},
89     .eccp_p_h = (unsigned int[1]) {0xcefd89b9},
90     .eccp_a = (unsigned int[8]) {0xf330b5d9, 0xe94a4b44, 0x26dc5c6c, 0xfb8055c1, 0x417affe7, 0xeef67530, 0xfc2c3057,
91         0x7d5a0975},
92     .eccp_b = (unsigned int[8]){
93         0xff8c07b6, 0x6bccdc18, 0x5cf7e1ce, 0x95841629, 0xbbd77cbf, 0xf330b5d9, 0xe94a4b44, 0x26dc5c6c}};
94 #endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
95 
96 #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
97 static eccp_curve_t secp224r1 = {.eccp_p_bitLen = 224,
98     .eccp_p = (unsigned int[7]) {0x00000001, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
99     .eccp_p_h = (unsigned int[7]) {0x00000001, 0x00000000, 0x00000000, 0xfffffffe, 0xffffffff, 0xffffffff, 0x00000000},
100     .eccp_p_h = (unsigned int[1]) {0xffffffff},
101     .eccp_a = (unsigned int[7]) {0xfffffffe, 0xffffffff, 0xffffffff, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff},
102     .eccp_b = (unsigned int[7]) {0x2355ffb4, 0x270b3943, 0xd7bfd8ba, 0x5044b0b7, 0xf5413256, 0x0c04b3ab, 0xb4050a85}};
103 #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
104 
105 #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
106 static eccp_curve_t secp224k1 = {.eccp_p_bitLen = 224,
107     .eccp_p = (unsigned int[7]) {0xffffe56d, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
108     .eccp_p_h = (unsigned int[7]) {0x02c23069, 0x00003526, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
109     .eccp_p_h = (unsigned int[1]) {0x198d139b},
110     .eccp_a = (unsigned int[7]) {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
111     .eccp_b = (unsigned int[7]) {0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}};
112 #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
113 
114 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
115 static eccp_curve_t secp192r1 = {.eccp_p_bitLen = 192,
116     .eccp_p = (unsigned int[6]) {0xffffffff, 0xffffffff, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff},
117     .eccp_p_h = (unsigned int[6]) {0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000},
118     .eccp_p_h = (unsigned int[1]) {0x00000001},
119     .eccp_a = (unsigned int[6]) {0xfffffffc, 0xffffffff, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff},
120     .eccp_b = (unsigned int[6]) {0xc146b9b1, 0xfeb8deec, 0x72243049, 0x0fa7e9ab, 0xe59c80e7, 0x64210519}};
121 #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
122 
123 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
124 static eccp_curve_t secp192k1 = {.eccp_p_bitLen = 192,
125     .eccp_p = (unsigned int[6]) {0xffffee37, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
126     .eccp_p_h = (unsigned int[6]) {0x013c4fd1, 0x00002392, 0x00000001, 0x00000000, 0x00000000, 0x00000000},
127     .eccp_p_h = (unsigned int[1]) {0x7446d879},
128     .eccp_a = (unsigned int[6]) {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
129     .eccp_b = (unsigned int[6]) {0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}};
130 #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
131 
132 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
133 static mont_curve_t x25519 = {.mont_p_bitLen = 255,
134     .mont_p = (unsigned int[8]) {0xffffffed, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
135         0x7fffffff},
136     .mont_p_h = (unsigned int[8]) {0x000005a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
137         0x00000000},
138     .mont_p_n1 = (unsigned int[1]) {0x286bca1b},
139     .mont_a24 = (unsigned int[8]) {
140         0x0001db41, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}};
141 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
142 
143 /****************************************************************
144  * Linking mbedtls to HW unit curve data
145  ****************************************************************/
146 
147 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
148 static const struct {
149     mbedtls_ecp_group_id group;
150     eccp_curve_t *curve_dat;
151 } eccp_curve_linking[] = {
152 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
153     {.group = MBEDTLS_ECP_DP_SECP256R1, .curve_dat = &secp256r1},
154 #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
155 #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
156     {.group = MBEDTLS_ECP_DP_SECP256K1, .curve_dat = &secp256k1},
157 #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
158 #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
159     {.group = MBEDTLS_ECP_DP_BP256R1, .curve_dat = &BP256r1},
160 #endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
161 #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
162     {.group = MBEDTLS_ECP_DP_SECP224R1, .curve_dat = &secp224r1},
163 #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
164 #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
165     {.group = MBEDTLS_ECP_DP_SECP224K1, .curve_dat = &secp224k1},
166 #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
167 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
168     {.group = MBEDTLS_ECP_DP_SECP192R1, .curve_dat = &secp192r1},
169 #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
170 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
171     {.group = MBEDTLS_ECP_DP_SECP192K1, .curve_dat = &secp192k1}
172 #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
173 };
174 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
175 
176 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
177 static const struct {
178     mbedtls_ecp_group_id group;
179     mont_curve_t *curve_dat;
180 } mont_curve_linking[] = {
181 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
182     {.group = MBEDTLS_ECP_DP_CURVE25519, .curve_dat = &x25519}
183 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
184 };
185 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
186 
187 /****************************************************************
188  * Private functions declaration
189  ****************************************************************/
190 
191 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
eccp_curve_get(const mbedtls_ecp_group * grp)192 static eccp_curve_t *eccp_curve_get(const mbedtls_ecp_group *grp)
193 {
194     eccp_curve_t *eccp_curve = NULL;
195 
196     for (size_t i = 0; i < sizeof(eccp_curve_linking) / sizeof(eccp_curve_linking[0]); i++) {
197         if (eccp_curve_linking[i].group == grp->id) {
198             eccp_curve = eccp_curve_linking[i].curve_dat;
199             break;
200         }
201     }
202 
203     return eccp_curve;
204 }
205 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
206 
207 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
mont_curve_get(const mbedtls_ecp_group * grp)208 static mont_curve_t *mont_curve_get(const mbedtls_ecp_group *grp)
209 {
210     mont_curve_t *mont_curve = NULL;
211 
212     for (size_t i = 0; i < sizeof(mont_curve_linking) / sizeof(mont_curve_linking[0]); i++) {
213         if (mont_curve_linking[i].group == grp->id) {
214             mont_curve = mont_curve_linking[i].curve_dat;
215             break;
216         }
217     }
218 
219     return mont_curve;
220 }
221 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
222 
223 /****************************************************************
224  * Public functions declaration
225  ****************************************************************/
226 
ecp_alt_b91_backend_check_pubkey(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * pt)227 int ecp_alt_b91_backend_check_pubkey(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt)
228 {
229     int result = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
230 
231     if (grp != NULL && pt != NULL) {
232         result = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
233         const unsigned int word_len = GET_WORD_LEN(grp->pbits);
234 
235         if (word_len <= PKE_OPERAND_MAX_WORD_LEN) {
236             unsigned int Qx[word_len], Qy[word_len];
237 
238 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
239             if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
240                 eccp_curve_t *eccp_curve = eccp_curve_get(grp);
241                 if (eccp_curve != NULL) {
242                     (void)mbedtls_mpi_write_binary_le(&pt->X, (unsigned char *)Qx, sizeof(Qx));
243                     (void)mbedtls_mpi_write_binary_le(&pt->Y, (unsigned char *)Qy, sizeof(Qy));
244 
245                     mbedtls_ecp_lock();
246                     if (pke_eccp_point_verify(eccp_curve, Qx, Qy) == PKE_SUCCESS)
247                         result = 0;
248                     else
249                         result = MBEDTLS_ERR_ECP_INVALID_KEY;
250                     mbedtls_ecp_unlock();
251                 }
252             }
253 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
254 
255             memset(Qx, 0, sizeof(Qx));
256             memset(Qy, 0, sizeof(Qy));
257         }
258     }
259     return result;
260 }
261 
ecp_alt_b91_backend_mul(mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P)262 int ecp_alt_b91_backend_mul(
263     mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P)
264 {
265     int result = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
266 
267     if (grp != NULL && R != NULL && m != NULL && P != NULL) {
268         result = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
269         const unsigned int word_len = GET_WORD_LEN(grp->pbits);
270 
271         if (word_len <= PKE_OPERAND_MAX_WORD_LEN) {
272             unsigned int ms[word_len], Qx[word_len], Qy[word_len];
273 
274 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
275             if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
276                 eccp_curve_t *eccp_curve = eccp_curve_get(grp);
277                 if (eccp_curve != NULL) {
278                     (void)mbedtls_mpi_write_binary_le(m, (unsigned char *)ms, sizeof(ms));
279                     (void)mbedtls_mpi_write_binary_le(&P->X, (unsigned char *)Qx, sizeof(Qx));
280                     (void)mbedtls_mpi_write_binary_le(&P->Y, (unsigned char *)Qy, sizeof(Qy));
281 
282                     mbedtls_ecp_lock();
283                     if (pke_eccp_point_mul(eccp_curve, ms, Qx, Qy, Qx, Qy) == PKE_SUCCESS) {
284                         (void)mbedtls_mpi_read_binary_le(&R->X, (const unsigned char *)Qx, sizeof(Qx));
285                         (void)mbedtls_mpi_read_binary_le(&R->Y, (const unsigned char *)Qy, sizeof(Qy));
286                         (void)mbedtls_mpi_lset(&R->Z, 1);
287                         result = 0;
288                     } else
289                         result = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
290                     mbedtls_ecp_unlock();
291                 }
292             }
293 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
294 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
295             if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
296                 mont_curve_t *mont_curve = mont_curve_get(grp);
297                 if (mont_curve != NULL) {
298                     (void)mbedtls_mpi_write_binary_le(m, (unsigned char *)ms, sizeof(ms));
299                     (void)mbedtls_mpi_write_binary_le(&P->X, (unsigned char *)Qx, sizeof(Qx));
300 
301                     mbedtls_ecp_lock();
302                     if (pke_x25519_point_mul(mont_curve, ms, Qx, Qx) == PKE_SUCCESS) {
303                         (void)mbedtls_mpi_read_binary_le(&R->X, (const unsigned char *)Qx, sizeof(Qx));
304                         (void)mbedtls_mpi_lset(&R->Y, 0);
305                         (void)mbedtls_mpi_lset(&R->Z, 1);
306                         result = 0;
307                     } else
308                         result = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
309                     mbedtls_ecp_unlock();
310                 }
311             }
312 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
313 
314             memset(ms, 0, sizeof(ms));
315             memset(Qx, 0, sizeof(Qx));
316             memset(Qy, 0, sizeof(Qy));
317         }
318     }
319     return result;
320 }
321 
ecp_alt_b91_backend_muladd(mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P,const mbedtls_mpi * n,const mbedtls_ecp_point * Q)322 int ecp_alt_b91_backend_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m,
323     const mbedtls_ecp_point *P, const mbedtls_mpi *n, const mbedtls_ecp_point *Q)
324 {
325     int result = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
326 
327     if (grp != NULL && R != NULL && m != NULL && P != NULL && n != NULL && Q != NULL) {
328         result = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
329         const unsigned int word_len = GET_WORD_LEN(grp->pbits);
330 
331         if (word_len <= PKE_OPERAND_MAX_WORD_LEN) {
332             unsigned int ms[word_len], Q1x[word_len], Q1y[word_len], Q2x[word_len], Q2y[word_len];
333 
334 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
335             if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
336                 eccp_curve_t *eccp_curve = eccp_curve_get(grp);
337                 if (eccp_curve != NULL) {
338                     (void)mbedtls_mpi_write_binary_le(&P->X, (unsigned char *)Q1x, sizeof(Q1x));
339                     (void)mbedtls_mpi_write_binary_le(&P->Y, (unsigned char *)Q1y, sizeof(Q1y));
340                     (void)mbedtls_mpi_write_binary_le(&Q->X, (unsigned char *)Q2x, sizeof(Q2x));
341                     (void)mbedtls_mpi_write_binary_le(&Q->Y, (unsigned char *)Q2y, sizeof(Q2y));
342 
343                     result = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
344 
345                     mbedtls_ecp_lock();
346 
347                     do {
348                         (void)mbedtls_mpi_write_binary_le(m, (unsigned char *)ms, sizeof(ms));
349                         if (pke_eccp_point_mul(eccp_curve, ms, Q1x, Q1y, Q1x, Q1y) != PKE_SUCCESS)
350                             break;
351 
352                         (void)mbedtls_mpi_write_binary_le(n, (unsigned char *)ms, sizeof(ms));
353                         if (pke_eccp_point_mul(eccp_curve, ms, Q2x, Q2y, Q2x, Q2y) != PKE_SUCCESS)
354                             break;
355 
356                         if (pke_eccp_point_add(eccp_curve, Q1x, Q1y, Q2x, Q2y, Q1x, Q1y) != PKE_SUCCESS)
357                             break;
358 
359                         (void)mbedtls_mpi_read_binary_le(&R->X, (const unsigned char *)Q1x, sizeof(Q1x));
360                         (void)mbedtls_mpi_read_binary_le(&R->Y, (const unsigned char *)Q1y, sizeof(Q1y));
361                         (void)mbedtls_mpi_lset(&R->Z, 1);
362                         result = 0;
363                     } while (0);
364 
365                     mbedtls_ecp_unlock();
366                 }
367             }
368 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
369 
370             memset(ms, 0, sizeof(ms));
371             memset(Q1x, 0, sizeof(Q1x));
372             memset(Q1y, 0, sizeof(Q1y));
373             memset(Q2x, 0, sizeof(Q2x));
374             memset(Q2y, 0, sizeof(Q2y));
375         }
376     }
377     return result;
378 }
379 
380 #endif /* MBEDTLS_ECP_ALT */
381 
382 #endif /* MBEDTLS_ECP_C */
383