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