1 /*
2 * Elliptic curves over GF(p): generic functions
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 */
7
8 /*
9 * References:
10 *
11 * SEC1 https://www.secg.org/sec1-v2.pdf
12 * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
13 * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
14 * RFC 4492 for the related TLS structures and constants
15 * - https://www.rfc-editor.org/rfc/rfc4492
16 * RFC 7748 for the Curve448 and Curve25519 curve definitions
17 * - https://www.rfc-editor.org/rfc/rfc7748
18 *
19 * [Curve25519] https://cr.yp.to/ecdh/curve25519-20060209.pdf
20 *
21 * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
22 * for elliptic curve cryptosystems. In : Cryptographic Hardware and
23 * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
24 * <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
25 *
26 * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
27 * render ECC resistant against Side Channel Attacks. IACR Cryptology
28 * ePrint Archive, 2004, vol. 2004, p. 342.
29 * <http://eprint.iacr.org/2004/342.pdf>
30 */
31
32 #include "common.h"
33
34 /**
35 * \brief Function level alternative implementation.
36 *
37 * The MBEDTLS_ECP_INTERNAL_ALT macro enables alternative implementations to
38 * replace certain functions in this module. The alternative implementations are
39 * typically hardware accelerators and need to activate the hardware before the
40 * computation starts and deactivate it after it finishes. The
41 * mbedtls_internal_ecp_init() and mbedtls_internal_ecp_free() functions serve
42 * this purpose.
43 *
44 * To preserve the correct functionality the following conditions must hold:
45 *
46 * - The alternative implementation must be activated by
47 * mbedtls_internal_ecp_init() before any of the replaceable functions is
48 * called.
49 * - mbedtls_internal_ecp_free() must \b only be called when the alternative
50 * implementation is activated.
51 * - mbedtls_internal_ecp_init() must \b not be called when the alternative
52 * implementation is activated.
53 * - Public functions must not return while the alternative implementation is
54 * activated.
55 * - Replaceable functions are guarded by \c MBEDTLS_ECP_XXX_ALT macros and
56 * before calling them an \code if( mbedtls_internal_ecp_grp_capable( grp ) )
57 * \endcode ensures that the alternative implementation supports the current
58 * group.
59 */
60 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
61 #endif
62
63 #if defined(MBEDTLS_ECP_LIGHT)
64
65 #include "mbedtls/ecp.h"
66 #include "mbedtls/threading.h"
67 #include "mbedtls/platform_util.h"
68 #include "mbedtls/error.h"
69
70 #include "bn_mul.h"
71 #include "bignum_internal.h"
72 #include "ecp_invasive.h"
73
74 #include <string.h>
75
76 #if !defined(MBEDTLS_ECP_ALT)
77
78 #include "mbedtls/platform.h"
79
80 #include "ecp_internal_alt.h"
81
82 #if defined(MBEDTLS_SELF_TEST)
83 /*
84 * Counts of point addition and doubling, and field multiplications.
85 * Used to test resistance of point multiplication to simple timing attacks.
86 */
87 #if defined(MBEDTLS_ECP_C)
88 static unsigned long add_count, dbl_count;
89 #endif /* MBEDTLS_ECP_C */
90 static unsigned long mul_count;
91 #endif
92
93 #if defined(MBEDTLS_ECP_RESTARTABLE)
94 /*
95 * Maximum number of "basic operations" to be done in a row.
96 *
97 * Default value 0 means that ECC operations will not yield.
98 * Note that regardless of the value of ecp_max_ops, always at
99 * least one step is performed before yielding.
100 *
101 * Setting ecp_max_ops=1 can be suitable for testing purposes
102 * as it will interrupt computation at all possible points.
103 */
104 static unsigned ecp_max_ops = 0;
105
106 /*
107 * Set ecp_max_ops
108 */
mbedtls_ecp_set_max_ops(unsigned max_ops)109 void mbedtls_ecp_set_max_ops(unsigned max_ops)
110 {
111 ecp_max_ops = max_ops;
112 }
113
114 /*
115 * Check if restart is enabled
116 */
mbedtls_ecp_restart_is_enabled(void)117 int mbedtls_ecp_restart_is_enabled(void)
118 {
119 return ecp_max_ops != 0;
120 }
121
122 /*
123 * Restart sub-context for ecp_mul_comb()
124 */
125 struct mbedtls_ecp_restart_mul {
126 mbedtls_ecp_point R; /* current intermediate result */
127 size_t i; /* current index in various loops, 0 outside */
128 mbedtls_ecp_point *T; /* table for precomputed points */
129 unsigned char T_size; /* number of points in table T */
130 enum { /* what were we doing last time we returned? */
131 ecp_rsm_init = 0, /* nothing so far, dummy initial state */
132 ecp_rsm_pre_dbl, /* precompute 2^n multiples */
133 ecp_rsm_pre_norm_dbl, /* normalize precomputed 2^n multiples */
134 ecp_rsm_pre_add, /* precompute remaining points by adding */
135 ecp_rsm_pre_norm_add, /* normalize all precomputed points */
136 ecp_rsm_comb_core, /* ecp_mul_comb_core() */
137 ecp_rsm_final_norm, /* do the final normalization */
138 } state;
139 };
140
141 /*
142 * Init restart_mul sub-context
143 */
ecp_restart_rsm_init(mbedtls_ecp_restart_mul_ctx * ctx)144 static void ecp_restart_rsm_init(mbedtls_ecp_restart_mul_ctx *ctx)
145 {
146 mbedtls_ecp_point_init(&ctx->R);
147 ctx->i = 0;
148 ctx->T = NULL;
149 ctx->T_size = 0;
150 ctx->state = ecp_rsm_init;
151 }
152
153 /*
154 * Free the components of a restart_mul sub-context
155 */
ecp_restart_rsm_free(mbedtls_ecp_restart_mul_ctx * ctx)156 static void ecp_restart_rsm_free(mbedtls_ecp_restart_mul_ctx *ctx)
157 {
158 unsigned char i;
159
160 if (ctx == NULL) {
161 return;
162 }
163
164 mbedtls_ecp_point_free(&ctx->R);
165
166 if (ctx->T != NULL) {
167 for (i = 0; i < ctx->T_size; i++) {
168 mbedtls_ecp_point_free(ctx->T + i);
169 }
170 mbedtls_free(ctx->T);
171 }
172
173 ecp_restart_rsm_init(ctx);
174 }
175
176 /*
177 * Restart context for ecp_muladd()
178 */
179 struct mbedtls_ecp_restart_muladd {
180 mbedtls_ecp_point mP; /* mP value */
181 mbedtls_ecp_point R; /* R intermediate result */
182 enum { /* what should we do next? */
183 ecp_rsma_mul1 = 0, /* first multiplication */
184 ecp_rsma_mul2, /* second multiplication */
185 ecp_rsma_add, /* addition */
186 ecp_rsma_norm, /* normalization */
187 } state;
188 };
189
190 /*
191 * Init restart_muladd sub-context
192 */
ecp_restart_ma_init(mbedtls_ecp_restart_muladd_ctx * ctx)193 static void ecp_restart_ma_init(mbedtls_ecp_restart_muladd_ctx *ctx)
194 {
195 mbedtls_ecp_point_init(&ctx->mP);
196 mbedtls_ecp_point_init(&ctx->R);
197 ctx->state = ecp_rsma_mul1;
198 }
199
200 /*
201 * Free the components of a restart_muladd sub-context
202 */
ecp_restart_ma_free(mbedtls_ecp_restart_muladd_ctx * ctx)203 static void ecp_restart_ma_free(mbedtls_ecp_restart_muladd_ctx *ctx)
204 {
205 if (ctx == NULL) {
206 return;
207 }
208
209 mbedtls_ecp_point_free(&ctx->mP);
210 mbedtls_ecp_point_free(&ctx->R);
211
212 ecp_restart_ma_init(ctx);
213 }
214
215 /*
216 * Initialize a restart context
217 */
mbedtls_ecp_restart_init(mbedtls_ecp_restart_ctx * ctx)218 void mbedtls_ecp_restart_init(mbedtls_ecp_restart_ctx *ctx)
219 {
220 ctx->ops_done = 0;
221 ctx->depth = 0;
222 ctx->rsm = NULL;
223 ctx->ma = NULL;
224 }
225
226 /*
227 * Free the components of a restart context
228 */
mbedtls_ecp_restart_free(mbedtls_ecp_restart_ctx * ctx)229 void mbedtls_ecp_restart_free(mbedtls_ecp_restart_ctx *ctx)
230 {
231 if (ctx == NULL) {
232 return;
233 }
234
235 ecp_restart_rsm_free(ctx->rsm);
236 mbedtls_free(ctx->rsm);
237
238 ecp_restart_ma_free(ctx->ma);
239 mbedtls_free(ctx->ma);
240
241 mbedtls_ecp_restart_init(ctx);
242 }
243
244 /*
245 * Check if we can do the next step
246 */
mbedtls_ecp_check_budget(const mbedtls_ecp_group * grp,mbedtls_ecp_restart_ctx * rs_ctx,unsigned ops)247 int mbedtls_ecp_check_budget(const mbedtls_ecp_group *grp,
248 mbedtls_ecp_restart_ctx *rs_ctx,
249 unsigned ops)
250 {
251 if (rs_ctx != NULL && ecp_max_ops != 0) {
252 /* scale depending on curve size: the chosen reference is 256-bit,
253 * and multiplication is quadratic. Round to the closest integer. */
254 if (grp->pbits >= 512) {
255 ops *= 4;
256 } else if (grp->pbits >= 384) {
257 ops *= 2;
258 }
259
260 /* Avoid infinite loops: always allow first step.
261 * Because of that, however, it's not generally true
262 * that ops_done <= ecp_max_ops, so the check
263 * ops_done > ecp_max_ops below is mandatory. */
264 if ((rs_ctx->ops_done != 0) &&
265 (rs_ctx->ops_done > ecp_max_ops ||
266 ops > ecp_max_ops - rs_ctx->ops_done)) {
267 return MBEDTLS_ERR_ECP_IN_PROGRESS;
268 }
269
270 /* update running count */
271 rs_ctx->ops_done += ops;
272 }
273
274 return 0;
275 }
276
277 /* Call this when entering a function that needs its own sub-context */
278 #define ECP_RS_ENTER(SUB) do { \
279 /* reset ops count for this call if top-level */ \
280 if (rs_ctx != NULL && rs_ctx->depth++ == 0) \
281 rs_ctx->ops_done = 0; \
282 \
283 /* set up our own sub-context if needed */ \
284 if (mbedtls_ecp_restart_is_enabled() && \
285 rs_ctx != NULL && rs_ctx->SUB == NULL) \
286 { \
287 rs_ctx->SUB = mbedtls_calloc(1, sizeof(*rs_ctx->SUB)); \
288 if (rs_ctx->SUB == NULL) \
289 return MBEDTLS_ERR_ECP_ALLOC_FAILED; \
290 \
291 ecp_restart_## SUB ##_init(rs_ctx->SUB); \
292 } \
293 } while (0)
294
295 /* Call this when leaving a function that needs its own sub-context */
296 #define ECP_RS_LEAVE(SUB) do { \
297 /* clear our sub-context when not in progress (done or error) */ \
298 if (rs_ctx != NULL && rs_ctx->SUB != NULL && \
299 ret != MBEDTLS_ERR_ECP_IN_PROGRESS) \
300 { \
301 ecp_restart_## SUB ##_free(rs_ctx->SUB); \
302 mbedtls_free(rs_ctx->SUB); \
303 rs_ctx->SUB = NULL; \
304 } \
305 \
306 if (rs_ctx != NULL) \
307 rs_ctx->depth--; \
308 } while (0)
309
310 #else /* MBEDTLS_ECP_RESTARTABLE */
311
312 #define ECP_RS_ENTER(sub) (void) rs_ctx;
313 #define ECP_RS_LEAVE(sub) (void) rs_ctx;
314
315 #endif /* MBEDTLS_ECP_RESTARTABLE */
316
317 #if defined(MBEDTLS_ECP_C)
mpi_init_many(mbedtls_mpi * arr,size_t size)318 static void mpi_init_many(mbedtls_mpi *arr, size_t size)
319 {
320 while (size--) {
321 mbedtls_mpi_init(arr++);
322 }
323 }
324
mpi_free_many(mbedtls_mpi * arr,size_t size)325 static void mpi_free_many(mbedtls_mpi *arr, size_t size)
326 {
327 while (size--) {
328 mbedtls_mpi_free(arr++);
329 }
330 }
331 #endif /* MBEDTLS_ECP_C */
332
333 /*
334 * List of supported curves:
335 * - internal ID
336 * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2, RFC 8446 sec. 4.2.7)
337 * - size in bits
338 * - readable name
339 *
340 * Curves are listed in order: largest curves first, and for a given size,
341 * fastest curves first.
342 *
343 * Reminder: update profiles in x509_crt.c and ssl_tls.c when adding a new curve!
344 */
345 static const mbedtls_ecp_curve_info ecp_supported_curves[] =
346 {
347 #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
348 { MBEDTLS_ECP_DP_SECP521R1, 25, 521, "secp521r1" },
349 #endif
350 #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
351 { MBEDTLS_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" },
352 #endif
353 #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
354 { MBEDTLS_ECP_DP_SECP384R1, 24, 384, "secp384r1" },
355 #endif
356 #if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
357 { MBEDTLS_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" },
358 #endif
359 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
360 { MBEDTLS_ECP_DP_SECP256R1, 23, 256, "secp256r1" },
361 #endif
362 #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
363 { MBEDTLS_ECP_DP_SECP256K1, 22, 256, "secp256k1" },
364 #endif
365 #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
366 { MBEDTLS_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" },
367 #endif
368 #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
369 { MBEDTLS_ECP_DP_SECP224R1, 21, 224, "secp224r1" },
370 #endif
371 #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
372 { MBEDTLS_ECP_DP_SECP224K1, 20, 224, "secp224k1" },
373 #endif
374 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
375 { MBEDTLS_ECP_DP_SECP192R1, 19, 192, "secp192r1" },
376 #endif
377 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
378 { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" },
379 #endif
380 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
381 { MBEDTLS_ECP_DP_CURVE25519, 29, 256, "x25519" },
382 #endif
383 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
384 { MBEDTLS_ECP_DP_CURVE448, 30, 448, "x448" },
385 #endif
386 #if defined(MBEDTLS_ECP_DP_SM2_ENABLED)
387 /* https://tools.ietf.org/id/draft-yang-tls-tls13-sm-suites-05.html */
388 { MBEDTLS_ECP_DP_SM2, 41, 256, "sm2" },
389 #endif
390 { MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
391 };
392
393 #define ECP_NB_CURVES sizeof(ecp_supported_curves) / \
394 sizeof(ecp_supported_curves[0])
395
396 static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES];
397
398 /*
399 * List of supported curves and associated info
400 */
mbedtls_ecp_curve_list(void)401 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list(void)
402 {
403 return ecp_supported_curves;
404 }
405
406 /*
407 * List of supported curves, group ID only
408 */
mbedtls_ecp_grp_id_list(void)409 const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list(void)
410 {
411 static int init_done = 0;
412
413 if (!init_done) {
414 size_t i = 0;
415 const mbedtls_ecp_curve_info *curve_info;
416
417 for (curve_info = mbedtls_ecp_curve_list();
418 curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
419 curve_info++) {
420 ecp_supported_grp_id[i++] = curve_info->grp_id;
421 }
422 ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE;
423
424 init_done = 1;
425 }
426
427 return ecp_supported_grp_id;
428 }
429
430 /*
431 * Get the curve info for the internal identifier
432 */
mbedtls_ecp_curve_info_from_grp_id(mbedtls_ecp_group_id grp_id)433 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id(mbedtls_ecp_group_id grp_id)
434 {
435 const mbedtls_ecp_curve_info *curve_info;
436
437 for (curve_info = mbedtls_ecp_curve_list();
438 curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
439 curve_info++) {
440 if (curve_info->grp_id == grp_id) {
441 return curve_info;
442 }
443 }
444
445 return NULL;
446 }
447
448 /*
449 * Get the curve info from the TLS identifier
450 */
mbedtls_ecp_curve_info_from_tls_id(uint16_t tls_id)451 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id(uint16_t tls_id)
452 {
453 const mbedtls_ecp_curve_info *curve_info;
454
455 for (curve_info = mbedtls_ecp_curve_list();
456 curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
457 curve_info++) {
458 if (curve_info->tls_id == tls_id) {
459 return curve_info;
460 }
461 }
462
463 return NULL;
464 }
465
466 /*
467 * Get the curve info from the name
468 */
mbedtls_ecp_curve_info_from_name(const char * name)469 const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name(const char *name)
470 {
471 const mbedtls_ecp_curve_info *curve_info;
472
473 if (name == NULL) {
474 return NULL;
475 }
476
477 for (curve_info = mbedtls_ecp_curve_list();
478 curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
479 curve_info++) {
480 if (strcmp(curve_info->name, name) == 0) {
481 return curve_info;
482 }
483 }
484
485 return NULL;
486 }
487
488 /*
489 * Get the type of a curve
490 */
mbedtls_ecp_get_type(const mbedtls_ecp_group * grp)491 mbedtls_ecp_curve_type mbedtls_ecp_get_type(const mbedtls_ecp_group *grp)
492 {
493 if (grp->G.X.p == NULL) {
494 return MBEDTLS_ECP_TYPE_NONE;
495 }
496
497 if (grp->G.Y.p == NULL) {
498 return MBEDTLS_ECP_TYPE_MONTGOMERY;
499 } else {
500 return MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS;
501 }
502 }
503
504 /*
505 * Initialize (the components of) a point
506 */
mbedtls_ecp_point_init(mbedtls_ecp_point * pt)507 void mbedtls_ecp_point_init(mbedtls_ecp_point *pt)
508 {
509 mbedtls_mpi_init(&pt->X);
510 mbedtls_mpi_init(&pt->Y);
511 mbedtls_mpi_init(&pt->Z);
512 }
513
514 /*
515 * Initialize (the components of) a group
516 */
mbedtls_ecp_group_init(mbedtls_ecp_group * grp)517 void mbedtls_ecp_group_init(mbedtls_ecp_group *grp)
518 {
519 grp->id = MBEDTLS_ECP_DP_NONE;
520 mbedtls_mpi_init(&grp->P);
521 mbedtls_mpi_init(&grp->A);
522 mbedtls_mpi_init(&grp->B);
523 mbedtls_ecp_point_init(&grp->G);
524 mbedtls_mpi_init(&grp->N);
525 grp->pbits = 0;
526 grp->nbits = 0;
527 grp->h = 0;
528 grp->modp = NULL;
529 grp->t_pre = NULL;
530 grp->t_post = NULL;
531 grp->t_data = NULL;
532 grp->T = NULL;
533 grp->T_size = 0;
534 }
535
536 /*
537 * Initialize (the components of) a key pair
538 */
mbedtls_ecp_keypair_init(mbedtls_ecp_keypair * key)539 void mbedtls_ecp_keypair_init(mbedtls_ecp_keypair *key)
540 {
541 mbedtls_ecp_group_init(&key->grp);
542 mbedtls_mpi_init(&key->d);
543 mbedtls_ecp_point_init(&key->Q);
544 }
545
546 /*
547 * Unallocate (the components of) a point
548 */
mbedtls_ecp_point_free(mbedtls_ecp_point * pt)549 void mbedtls_ecp_point_free(mbedtls_ecp_point *pt)
550 {
551 if (pt == NULL) {
552 return;
553 }
554
555 mbedtls_mpi_free(&(pt->X));
556 mbedtls_mpi_free(&(pt->Y));
557 mbedtls_mpi_free(&(pt->Z));
558 }
559
560 /*
561 * Check that the comb table (grp->T) is static initialized.
562 */
ecp_group_is_static_comb_table(const mbedtls_ecp_group * grp)563 static int ecp_group_is_static_comb_table(const mbedtls_ecp_group *grp)
564 {
565 #if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
566 return grp->T != NULL && grp->T_size == 0;
567 #else
568 (void) grp;
569 return 0;
570 #endif
571 }
572
573 /*
574 * Unallocate (the components of) a group
575 */
mbedtls_ecp_group_free(mbedtls_ecp_group * grp)576 void mbedtls_ecp_group_free(mbedtls_ecp_group *grp)
577 {
578 size_t i;
579
580 if (grp == NULL) {
581 return;
582 }
583
584 if (grp->h != 1) {
585 mbedtls_mpi_free(&grp->A);
586 mbedtls_mpi_free(&grp->B);
587 mbedtls_ecp_point_free(&grp->G);
588
589 #if !defined(MBEDTLS_ECP_WITH_MPI_UINT)
590 mbedtls_mpi_free(&grp->N);
591 mbedtls_mpi_free(&grp->P);
592 #endif
593 }
594
595 if (!ecp_group_is_static_comb_table(grp) && grp->T != NULL) {
596 for (i = 0; i < grp->T_size; i++) {
597 mbedtls_ecp_point_free(&grp->T[i]);
598 }
599 mbedtls_free(grp->T);
600 }
601
602 mbedtls_platform_zeroize(grp, sizeof(mbedtls_ecp_group));
603 }
604
605 /*
606 * Unallocate (the components of) a key pair
607 */
mbedtls_ecp_keypair_free(mbedtls_ecp_keypair * key)608 void mbedtls_ecp_keypair_free(mbedtls_ecp_keypair *key)
609 {
610 if (key == NULL) {
611 return;
612 }
613
614 mbedtls_ecp_group_free(&key->grp);
615 mbedtls_mpi_free(&key->d);
616 mbedtls_ecp_point_free(&key->Q);
617 }
618
619 /*
620 * Copy the contents of a point
621 */
mbedtls_ecp_copy(mbedtls_ecp_point * P,const mbedtls_ecp_point * Q)622 int mbedtls_ecp_copy(mbedtls_ecp_point *P, const mbedtls_ecp_point *Q)
623 {
624 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
625 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&P->X, &Q->X));
626 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&P->Y, &Q->Y));
627 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&P->Z, &Q->Z));
628
629 cleanup:
630 return ret;
631 }
632
633 /*
634 * Copy the contents of a group object
635 */
mbedtls_ecp_group_copy(mbedtls_ecp_group * dst,const mbedtls_ecp_group * src)636 int mbedtls_ecp_group_copy(mbedtls_ecp_group *dst, const mbedtls_ecp_group *src)
637 {
638 return mbedtls_ecp_group_load(dst, src->id);
639 }
640
641 /*
642 * Set point to zero
643 */
mbedtls_ecp_set_zero(mbedtls_ecp_point * pt)644 int mbedtls_ecp_set_zero(mbedtls_ecp_point *pt)
645 {
646 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
647 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->X, 1));
648 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Y, 1));
649 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Z, 0));
650
651 cleanup:
652 return ret;
653 }
654
655 /*
656 * Tell if a point is zero
657 */
mbedtls_ecp_is_zero(mbedtls_ecp_point * pt)658 int mbedtls_ecp_is_zero(mbedtls_ecp_point *pt)
659 {
660 return mbedtls_mpi_cmp_int(&pt->Z, 0) == 0;
661 }
662
663 /*
664 * Compare two points lazily
665 */
mbedtls_ecp_point_cmp(const mbedtls_ecp_point * P,const mbedtls_ecp_point * Q)666 int mbedtls_ecp_point_cmp(const mbedtls_ecp_point *P,
667 const mbedtls_ecp_point *Q)
668 {
669 if (mbedtls_mpi_cmp_mpi(&P->X, &Q->X) == 0 &&
670 mbedtls_mpi_cmp_mpi(&P->Y, &Q->Y) == 0 &&
671 mbedtls_mpi_cmp_mpi(&P->Z, &Q->Z) == 0) {
672 return 0;
673 }
674
675 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
676 }
677
678 /*
679 * Import a non-zero point from ASCII strings
680 */
mbedtls_ecp_point_read_string(mbedtls_ecp_point * P,int radix,const char * x,const char * y)681 int mbedtls_ecp_point_read_string(mbedtls_ecp_point *P, int radix,
682 const char *x, const char *y)
683 {
684 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
685 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&P->X, radix, x));
686 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&P->Y, radix, y));
687 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&P->Z, 1));
688
689 cleanup:
690 return ret;
691 }
692
693 /*
694 * Export a point into unsigned binary data (SEC1 2.3.3 and RFC7748)
695 */
mbedtls_ecp_point_write_binary(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * P,int format,size_t * olen,unsigned char * buf,size_t buflen)696 int mbedtls_ecp_point_write_binary(const mbedtls_ecp_group *grp,
697 const mbedtls_ecp_point *P,
698 int format, size_t *olen,
699 unsigned char *buf, size_t buflen)
700 {
701 int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
702 size_t plen;
703 if (format != MBEDTLS_ECP_PF_UNCOMPRESSED &&
704 format != MBEDTLS_ECP_PF_COMPRESSED) {
705 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
706 }
707
708 plen = mbedtls_mpi_size(&grp->P);
709
710 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
711 (void) format; /* Montgomery curves always use the same point format */
712 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
713 *olen = plen;
714 if (buflen < *olen) {
715 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
716 }
717
718 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary_le(&P->X, buf, plen));
719 }
720 #endif
721 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
722 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
723 /*
724 * Common case: P == 0
725 */
726 if (mbedtls_mpi_cmp_int(&P->Z, 0) == 0) {
727 if (buflen < 1) {
728 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
729 }
730
731 buf[0] = 0x00;
732 *olen = 1;
733
734 return 0;
735 }
736
737 if (format == MBEDTLS_ECP_PF_UNCOMPRESSED) {
738 *olen = 2 * plen + 1;
739
740 if (buflen < *olen) {
741 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
742 }
743
744 buf[0] = 0x04;
745 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&P->X, buf + 1, plen));
746 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&P->Y, buf + 1 + plen, plen));
747 } else if (format == MBEDTLS_ECP_PF_COMPRESSED) {
748 *olen = plen + 1;
749
750 if (buflen < *olen) {
751 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
752 }
753
754 buf[0] = 0x02 + mbedtls_mpi_get_bit(&P->Y, 0);
755 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&P->X, buf + 1, plen));
756 }
757 }
758 #endif
759
760 cleanup:
761 return ret;
762 }
763
764 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
765 static int mbedtls_ecp_sw_derive_y(const mbedtls_ecp_group *grp,
766 const mbedtls_mpi *X,
767 mbedtls_mpi *Y,
768 int parity_bit);
769 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
770
771 /*
772 * Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748)
773 */
mbedtls_ecp_point_read_binary(const mbedtls_ecp_group * grp,mbedtls_ecp_point * pt,const unsigned char * buf,size_t ilen)774 int mbedtls_ecp_point_read_binary(const mbedtls_ecp_group *grp,
775 mbedtls_ecp_point *pt,
776 const unsigned char *buf, size_t ilen)
777 {
778 int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
779 size_t plen;
780 if (ilen < 1) {
781 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
782 }
783
784 plen = mbedtls_mpi_size(&grp->P);
785
786 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
787 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
788 if (plen != ilen) {
789 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
790 }
791
792 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary_le(&pt->X, buf, plen));
793 mbedtls_mpi_free(&pt->Y);
794
795 if (grp->id == MBEDTLS_ECP_DP_CURVE25519) {
796 /* Set most significant bit to 0 as prescribed in RFC7748 §5 */
797 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&pt->X, plen * 8 - 1, 0));
798 }
799
800 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Z, 1));
801 }
802 #endif
803 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
804 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
805 if (buf[0] == 0x00) {
806 if (ilen == 1) {
807 return mbedtls_ecp_set_zero(pt);
808 } else {
809 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
810 }
811 }
812
813 if (ilen < 1 + plen) {
814 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
815 }
816
817 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->X, buf + 1, plen));
818 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Z, 1));
819
820 if (buf[0] == 0x04) {
821 /* format == MBEDTLS_ECP_PF_UNCOMPRESSED */
822 if (ilen != 1 + plen * 2) {
823 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
824 }
825 return mbedtls_mpi_read_binary(&pt->Y, buf + 1 + plen, plen);
826 } else if (buf[0] == 0x02 || buf[0] == 0x03) {
827 /* format == MBEDTLS_ECP_PF_COMPRESSED */
828 if (ilen != 1 + plen) {
829 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
830 }
831 return mbedtls_ecp_sw_derive_y(grp, &pt->X, &pt->Y,
832 (buf[0] & 1));
833 } else {
834 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
835 }
836 }
837 #endif
838
839 cleanup:
840 return ret;
841 }
842
843 /*
844 * Import a point from a TLS ECPoint record (RFC 4492)
845 * struct {
846 * opaque point <1..2^8-1>;
847 * } ECPoint;
848 */
mbedtls_ecp_tls_read_point(const mbedtls_ecp_group * grp,mbedtls_ecp_point * pt,const unsigned char ** buf,size_t buf_len)849 int mbedtls_ecp_tls_read_point(const mbedtls_ecp_group *grp,
850 mbedtls_ecp_point *pt,
851 const unsigned char **buf, size_t buf_len)
852 {
853 unsigned char data_len;
854 const unsigned char *buf_start;
855 /*
856 * We must have at least two bytes (1 for length, at least one for data)
857 */
858 if (buf_len < 2) {
859 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
860 }
861
862 data_len = *(*buf)++;
863 if (data_len < 1 || data_len > buf_len - 1) {
864 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
865 }
866
867 /*
868 * Save buffer start for read_binary and update buf
869 */
870 buf_start = *buf;
871 *buf += data_len;
872
873 return mbedtls_ecp_point_read_binary(grp, pt, buf_start, data_len);
874 }
875
876 /*
877 * Export a point as a TLS ECPoint record (RFC 4492)
878 * struct {
879 * opaque point <1..2^8-1>;
880 * } ECPoint;
881 */
mbedtls_ecp_tls_write_point(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * pt,int format,size_t * olen,unsigned char * buf,size_t blen)882 int mbedtls_ecp_tls_write_point(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt,
883 int format, size_t *olen,
884 unsigned char *buf, size_t blen)
885 {
886 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
887 if (format != MBEDTLS_ECP_PF_UNCOMPRESSED &&
888 format != MBEDTLS_ECP_PF_COMPRESSED) {
889 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
890 }
891
892 /*
893 * buffer length must be at least one, for our length byte
894 */
895 if (blen < 1) {
896 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
897 }
898
899 if ((ret = mbedtls_ecp_point_write_binary(grp, pt, format,
900 olen, buf + 1, blen - 1)) != 0) {
901 return ret;
902 }
903
904 /*
905 * write length to the first byte and update total length
906 */
907 buf[0] = (unsigned char) *olen;
908 ++*olen;
909
910 return 0;
911 }
912
913 /*
914 * Set a group from an ECParameters record (RFC 4492)
915 */
mbedtls_ecp_tls_read_group(mbedtls_ecp_group * grp,const unsigned char ** buf,size_t len)916 int mbedtls_ecp_tls_read_group(mbedtls_ecp_group *grp,
917 const unsigned char **buf, size_t len)
918 {
919 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
920 mbedtls_ecp_group_id grp_id;
921 if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, len)) != 0) {
922 return ret;
923 }
924
925 return mbedtls_ecp_group_load(grp, grp_id);
926 }
927
928 /*
929 * Read a group id from an ECParameters record (RFC 4492) and convert it to
930 * mbedtls_ecp_group_id.
931 */
mbedtls_ecp_tls_read_group_id(mbedtls_ecp_group_id * grp,const unsigned char ** buf,size_t len)932 int mbedtls_ecp_tls_read_group_id(mbedtls_ecp_group_id *grp,
933 const unsigned char **buf, size_t len)
934 {
935 uint16_t tls_id;
936 const mbedtls_ecp_curve_info *curve_info;
937 /*
938 * We expect at least three bytes (see below)
939 */
940 if (len < 3) {
941 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
942 }
943
944 /*
945 * First byte is curve_type; only named_curve is handled
946 */
947 if (*(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE) {
948 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
949 }
950
951 /*
952 * Next two bytes are the namedcurve value
953 */
954 tls_id = MBEDTLS_GET_UINT16_BE(*buf, 0);
955 *buf += 2;
956
957 if ((curve_info = mbedtls_ecp_curve_info_from_tls_id(tls_id)) == NULL) {
958 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
959 }
960
961 *grp = curve_info->grp_id;
962
963 return 0;
964 }
965
966 /*
967 * Write the ECParameters record corresponding to a group (RFC 4492)
968 */
mbedtls_ecp_tls_write_group(const mbedtls_ecp_group * grp,size_t * olen,unsigned char * buf,size_t blen)969 int mbedtls_ecp_tls_write_group(const mbedtls_ecp_group *grp, size_t *olen,
970 unsigned char *buf, size_t blen)
971 {
972 const mbedtls_ecp_curve_info *curve_info;
973 if ((curve_info = mbedtls_ecp_curve_info_from_grp_id(grp->id)) == NULL) {
974 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
975 }
976
977 /*
978 * We are going to write 3 bytes (see below)
979 */
980 *olen = 3;
981 if (blen < *olen) {
982 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
983 }
984
985 /*
986 * First byte is curve_type, always named_curve
987 */
988 *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
989
990 /*
991 * Next two bytes are the namedcurve value
992 */
993 MBEDTLS_PUT_UINT16_BE(curve_info->tls_id, buf, 0);
994
995 return 0;
996 }
997
998 /*
999 * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi.
1000 * See the documentation of struct mbedtls_ecp_group.
1001 *
1002 * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf.
1003 */
ecp_modp(mbedtls_mpi * N,const mbedtls_ecp_group * grp)1004 static int ecp_modp(mbedtls_mpi *N, const mbedtls_ecp_group *grp)
1005 {
1006 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1007
1008 if (grp->modp == NULL) {
1009 return mbedtls_mpi_mod_mpi(N, N, &grp->P);
1010 }
1011
1012 /* N->s < 0 is a much faster test, which fails only if N is 0 */
1013 if ((N->s < 0 && mbedtls_mpi_cmp_int(N, 0) != 0) ||
1014 mbedtls_mpi_bitlen(N) > 2 * grp->pbits) {
1015 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1016 }
1017
1018 MBEDTLS_MPI_CHK(grp->modp(N));
1019
1020 /* N->s < 0 is a much faster test, which fails only if N is 0 */
1021 while (N->s < 0 && mbedtls_mpi_cmp_int(N, 0) != 0) {
1022 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &grp->P));
1023 }
1024
1025 while (mbedtls_mpi_cmp_mpi(N, &grp->P) >= 0) {
1026 /* we known P, N and the result are positive */
1027 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(N, N, &grp->P));
1028 }
1029
1030 cleanup:
1031 return ret;
1032 }
1033
1034 /*
1035 * Fast mod-p functions expect their argument to be in the 0..p^2 range.
1036 *
1037 * In order to guarantee that, we need to ensure that operands of
1038 * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will
1039 * bring the result back to this range.
1040 *
1041 * The following macros are shortcuts for doing that.
1042 */
1043
1044 /*
1045 * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi
1046 */
1047 #if defined(MBEDTLS_SELF_TEST)
1048 #define INC_MUL_COUNT mul_count++;
1049 #else
1050 #define INC_MUL_COUNT
1051 #endif
1052
1053 #define MOD_MUL(N) \
1054 do \
1055 { \
1056 MBEDTLS_MPI_CHK(ecp_modp(&(N), grp)); \
1057 INC_MUL_COUNT \
1058 } while (0)
1059
mbedtls_mpi_mul_mod(const mbedtls_ecp_group * grp,mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1060 static inline int mbedtls_mpi_mul_mod(const mbedtls_ecp_group *grp,
1061 mbedtls_mpi *X,
1062 const mbedtls_mpi *A,
1063 const mbedtls_mpi *B)
1064 {
1065 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1066 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(X, A, B));
1067 MOD_MUL(*X);
1068 cleanup:
1069 return ret;
1070 }
1071
1072 /*
1073 * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi
1074 * N->s < 0 is a very fast test, which fails only if N is 0
1075 */
1076 #define MOD_SUB(N) \
1077 do { \
1078 while ((N)->s < 0 && mbedtls_mpi_cmp_int((N), 0) != 0) \
1079 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi((N), (N), &grp->P)); \
1080 } while (0)
1081
1082 MBEDTLS_MAYBE_UNUSED
mbedtls_mpi_sub_mod(const mbedtls_ecp_group * grp,mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1083 static inline int mbedtls_mpi_sub_mod(const mbedtls_ecp_group *grp,
1084 mbedtls_mpi *X,
1085 const mbedtls_mpi *A,
1086 const mbedtls_mpi *B)
1087 {
1088 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1089 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(X, A, B));
1090 MOD_SUB(X);
1091 cleanup:
1092 return ret;
1093 }
1094
1095 /*
1096 * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int.
1097 * We known P, N and the result are positive, so sub_abs is correct, and
1098 * a bit faster.
1099 */
1100 #define MOD_ADD(N) \
1101 while (mbedtls_mpi_cmp_mpi((N), &grp->P) >= 0) \
1102 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs((N), (N), &grp->P))
1103
mbedtls_mpi_add_mod(const mbedtls_ecp_group * grp,mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1104 static inline int mbedtls_mpi_add_mod(const mbedtls_ecp_group *grp,
1105 mbedtls_mpi *X,
1106 const mbedtls_mpi *A,
1107 const mbedtls_mpi *B)
1108 {
1109 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1110 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, A, B));
1111 MOD_ADD(X);
1112 cleanup:
1113 return ret;
1114 }
1115
1116 MBEDTLS_MAYBE_UNUSED
mbedtls_mpi_mul_int_mod(const mbedtls_ecp_group * grp,mbedtls_mpi * X,const mbedtls_mpi * A,mbedtls_mpi_uint c)1117 static inline int mbedtls_mpi_mul_int_mod(const mbedtls_ecp_group *grp,
1118 mbedtls_mpi *X,
1119 const mbedtls_mpi *A,
1120 mbedtls_mpi_uint c)
1121 {
1122 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1123
1124 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(X, A, c));
1125 MOD_ADD(X);
1126 cleanup:
1127 return ret;
1128 }
1129
1130 MBEDTLS_MAYBE_UNUSED
mbedtls_mpi_sub_int_mod(const mbedtls_ecp_group * grp,mbedtls_mpi * X,const mbedtls_mpi * A,mbedtls_mpi_uint c)1131 static inline int mbedtls_mpi_sub_int_mod(const mbedtls_ecp_group *grp,
1132 mbedtls_mpi *X,
1133 const mbedtls_mpi *A,
1134 mbedtls_mpi_uint c)
1135 {
1136 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1137
1138 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(X, A, c));
1139 MOD_SUB(X);
1140 cleanup:
1141 return ret;
1142 }
1143
1144 #define MPI_ECP_SUB_INT(X, A, c) \
1145 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int_mod(grp, X, A, c))
1146
1147 MBEDTLS_MAYBE_UNUSED
mbedtls_mpi_shift_l_mod(const mbedtls_ecp_group * grp,mbedtls_mpi * X,size_t count)1148 static inline int mbedtls_mpi_shift_l_mod(const mbedtls_ecp_group *grp,
1149 mbedtls_mpi *X,
1150 size_t count)
1151 {
1152 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1153 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(X, count));
1154 MOD_ADD(X);
1155 cleanup:
1156 return ret;
1157 }
1158
1159 /*
1160 * Macro wrappers around ECP modular arithmetic
1161 *
1162 * Currently, these wrappers are defined via the bignum module.
1163 */
1164
1165 #define MPI_ECP_ADD(X, A, B) \
1166 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mod(grp, X, A, B))
1167
1168 #define MPI_ECP_SUB(X, A, B) \
1169 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mod(grp, X, A, B))
1170
1171 #define MPI_ECP_MUL(X, A, B) \
1172 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mod(grp, X, A, B))
1173
1174 #define MPI_ECP_SQR(X, A) \
1175 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mod(grp, X, A, A))
1176
1177 #define MPI_ECP_MUL_INT(X, A, c) \
1178 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int_mod(grp, X, A, c))
1179
1180 #define MPI_ECP_INV(dst, src) \
1181 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, (dst), (src), &grp->P))
1182
1183 #define MPI_ECP_MOV(X, A) \
1184 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A))
1185
1186 #define MPI_ECP_SHIFT_L(X, count) \
1187 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l_mod(grp, X, count))
1188
1189 #define MPI_ECP_LSET(X, c) \
1190 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, c))
1191
1192 #define MPI_ECP_CMP_INT(X, c) \
1193 mbedtls_mpi_cmp_int(X, c)
1194
1195 #define MPI_ECP_CMP(X, Y) \
1196 mbedtls_mpi_cmp_mpi(X, Y)
1197
1198 /* Needs f_rng, p_rng to be defined. */
1199 #define MPI_ECP_RAND(X) \
1200 MBEDTLS_MPI_CHK(mbedtls_mpi_random((X), 2, &grp->P, f_rng, p_rng))
1201
1202 /* Conditional negation
1203 * Needs grp and a temporary MPI tmp to be defined. */
1204 #define MPI_ECP_COND_NEG(X, cond) \
1205 do \
1206 { \
1207 unsigned char nonzero = mbedtls_mpi_cmp_int((X), 0) != 0; \
1208 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&tmp, &grp->P, (X))); \
1209 MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign((X), &tmp, \
1210 nonzero & cond)); \
1211 } while (0)
1212
1213 #define MPI_ECP_NEG(X) MPI_ECP_COND_NEG((X), 1)
1214
1215 #define MPI_ECP_VALID(X) \
1216 ((X)->p != NULL)
1217
1218 #define MPI_ECP_COND_ASSIGN(X, Y, cond) \
1219 MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign((X), (Y), (cond)))
1220
1221 #define MPI_ECP_COND_SWAP(X, Y, cond) \
1222 MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_swap((X), (Y), (cond)))
1223
1224 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
1225
1226 /*
1227 * Computes the right-hand side of the Short Weierstrass equation
1228 * RHS = X^3 + A X + B
1229 */
ecp_sw_rhs(const mbedtls_ecp_group * grp,mbedtls_mpi * rhs,const mbedtls_mpi * X)1230 static int ecp_sw_rhs(const mbedtls_ecp_group *grp,
1231 mbedtls_mpi *rhs,
1232 const mbedtls_mpi *X)
1233 {
1234 int ret;
1235
1236 /* Compute X^3 + A X + B as X (X^2 + A) + B */
1237 MPI_ECP_SQR(rhs, X);
1238
1239 /* Special case for A = -3 */
1240 if (mbedtls_ecp_group_a_is_minus_3(grp)) {
1241 MPI_ECP_SUB_INT(rhs, rhs, 3);
1242 } else {
1243 MPI_ECP_ADD(rhs, rhs, &grp->A);
1244 }
1245
1246 MPI_ECP_MUL(rhs, rhs, X);
1247 MPI_ECP_ADD(rhs, rhs, &grp->B);
1248
1249 cleanup:
1250 return ret;
1251 }
1252
1253 /*
1254 * Derive Y from X and a parity bit
1255 */
mbedtls_ecp_sw_derive_y(const mbedtls_ecp_group * grp,const mbedtls_mpi * X,mbedtls_mpi * Y,int parity_bit)1256 static int mbedtls_ecp_sw_derive_y(const mbedtls_ecp_group *grp,
1257 const mbedtls_mpi *X,
1258 mbedtls_mpi *Y,
1259 int parity_bit)
1260 {
1261 /* w = y^2 = x^3 + ax + b
1262 * y = sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4)
1263 *
1264 * Note: this method for extracting square root does not validate that w
1265 * was indeed a square so this function will return garbage in Y if X
1266 * does not correspond to a point on the curve.
1267 */
1268
1269 /* Check prerequisite p = 3 mod 4 */
1270 if (mbedtls_mpi_get_bit(&grp->P, 0) != 1 ||
1271 mbedtls_mpi_get_bit(&grp->P, 1) != 1) {
1272 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
1273 }
1274
1275 int ret;
1276 mbedtls_mpi exp;
1277 mbedtls_mpi_init(&exp);
1278
1279 /* use Y to store intermediate result, actually w above */
1280 MBEDTLS_MPI_CHK(ecp_sw_rhs(grp, Y, X));
1281
1282 /* w = y^2 */ /* Y contains y^2 intermediate result */
1283 /* exp = ((p+1)/4) */
1284 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&exp, &grp->P, 1));
1285 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&exp, 2));
1286 /* sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */
1287 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(Y, Y /*y^2*/, &exp, &grp->P, NULL));
1288
1289 /* check parity bit match or else invert Y */
1290 /* This quick inversion implementation is valid because Y != 0 for all
1291 * Short Weierstrass curves supported by mbedtls, as each supported curve
1292 * has an order that is a large prime, so each supported curve does not
1293 * have any point of order 2, and a point with Y == 0 would be of order 2 */
1294 if (mbedtls_mpi_get_bit(Y, 0) != parity_bit) {
1295 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(Y, &grp->P, Y));
1296 }
1297
1298 cleanup:
1299
1300 mbedtls_mpi_free(&exp);
1301 return ret;
1302 }
1303 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
1304
1305 #if defined(MBEDTLS_ECP_C)
1306 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
1307 /*
1308 * For curves in short Weierstrass form, we do all the internal operations in
1309 * Jacobian coordinates.
1310 *
1311 * For multiplication, we'll use a comb method with countermeasures against
1312 * SPA, hence timing attacks.
1313 */
1314
1315 /*
1316 * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1)
1317 * Cost: 1N := 1I + 3M + 1S
1318 */
ecp_normalize_jac(const mbedtls_ecp_group * grp,mbedtls_ecp_point * pt)1319 static int ecp_normalize_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt)
1320 {
1321 if (MPI_ECP_CMP_INT(&pt->Z, 0) == 0) {
1322 return 0;
1323 }
1324
1325 #if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
1326 if (mbedtls_internal_ecp_grp_capable(grp)) {
1327 return mbedtls_internal_ecp_normalize_jac(grp, pt);
1328 }
1329 #endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */
1330
1331 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
1332 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
1333 #else
1334 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1335 mbedtls_mpi T;
1336 mbedtls_mpi_init(&T);
1337
1338 MPI_ECP_INV(&T, &pt->Z); /* T <- 1 / Z */
1339 MPI_ECP_MUL(&pt->Y, &pt->Y, &T); /* Y' <- Y*T = Y / Z */
1340 MPI_ECP_SQR(&T, &T); /* T <- T^2 = 1 / Z^2 */
1341 MPI_ECP_MUL(&pt->X, &pt->X, &T); /* X <- X * T = X / Z^2 */
1342 MPI_ECP_MUL(&pt->Y, &pt->Y, &T); /* Y'' <- Y' * T = Y / Z^3 */
1343
1344 MPI_ECP_LSET(&pt->Z, 1);
1345
1346 cleanup:
1347
1348 mbedtls_mpi_free(&T);
1349
1350 return ret;
1351 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) */
1352 }
1353
1354 /*
1355 * Normalize jacobian coordinates of an array of (pointers to) points,
1356 * using Montgomery's trick to perform only one inversion mod P.
1357 * (See for example Cohen's "A Course in Computational Algebraic Number
1358 * Theory", Algorithm 10.3.4.)
1359 *
1360 * Warning: fails (returning an error) if one of the points is zero!
1361 * This should never happen, see choice of w in ecp_mul_comb().
1362 *
1363 * Cost: 1N(t) := 1I + (6t - 3)M + 1S
1364 */
ecp_normalize_jac_many(const mbedtls_ecp_group * grp,mbedtls_ecp_point * T[],size_t T_size)1365 static int ecp_normalize_jac_many(const mbedtls_ecp_group *grp,
1366 mbedtls_ecp_point *T[], size_t T_size)
1367 {
1368 if (T_size < 2) {
1369 return ecp_normalize_jac(grp, *T);
1370 }
1371
1372 #if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
1373 if (mbedtls_internal_ecp_grp_capable(grp)) {
1374 return mbedtls_internal_ecp_normalize_jac_many(grp, T, T_size);
1375 }
1376 #endif
1377
1378 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
1379 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
1380 #else
1381 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1382 size_t i;
1383 mbedtls_mpi *c, t;
1384
1385 if ((c = mbedtls_calloc(T_size, sizeof(mbedtls_mpi))) == NULL) {
1386 return MBEDTLS_ERR_ECP_ALLOC_FAILED;
1387 }
1388
1389 mbedtls_mpi_init(&t);
1390
1391 mpi_init_many(c, T_size);
1392 /*
1393 * c[i] = Z_0 * ... * Z_i, i = 0,..,n := T_size-1
1394 */
1395 MPI_ECP_MOV(&c[0], &T[0]->Z);
1396 for (i = 1; i < T_size; i++) {
1397 MPI_ECP_MUL(&c[i], &c[i-1], &T[i]->Z);
1398 }
1399
1400 /*
1401 * c[n] = 1 / (Z_0 * ... * Z_n) mod P
1402 */
1403 MPI_ECP_INV(&c[T_size-1], &c[T_size-1]);
1404
1405 for (i = T_size - 1;; i--) {
1406 /* At the start of iteration i (note that i decrements), we have
1407 * - c[j] = Z_0 * .... * Z_j for j < i,
1408 * - c[j] = 1 / (Z_0 * .... * Z_j) for j == i,
1409 *
1410 * This is maintained via
1411 * - c[i-1] <- c[i] * Z_i
1412 *
1413 * We also derive 1/Z_i = c[i] * c[i-1] for i>0 and use that
1414 * to do the actual normalization. For i==0, we already have
1415 * c[0] = 1 / Z_0.
1416 */
1417
1418 if (i > 0) {
1419 /* Compute 1/Z_i and establish invariant for the next iteration. */
1420 MPI_ECP_MUL(&t, &c[i], &c[i-1]);
1421 MPI_ECP_MUL(&c[i-1], &c[i], &T[i]->Z);
1422 } else {
1423 MPI_ECP_MOV(&t, &c[0]);
1424 }
1425
1426 /* Now t holds 1 / Z_i; normalize as in ecp_normalize_jac() */
1427 MPI_ECP_MUL(&T[i]->Y, &T[i]->Y, &t);
1428 MPI_ECP_SQR(&t, &t);
1429 MPI_ECP_MUL(&T[i]->X, &T[i]->X, &t);
1430 MPI_ECP_MUL(&T[i]->Y, &T[i]->Y, &t);
1431
1432 /*
1433 * Post-precessing: reclaim some memory by shrinking coordinates
1434 * - not storing Z (always 1)
1435 * - shrinking other coordinates, but still keeping the same number of
1436 * limbs as P, as otherwise it will too likely be regrown too fast.
1437 */
1438 MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(&T[i]->X, grp->P.n));
1439 MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(&T[i]->Y, grp->P.n));
1440
1441 MPI_ECP_LSET(&T[i]->Z, 1);
1442
1443 if (i == 0) {
1444 break;
1445 }
1446 }
1447
1448 cleanup:
1449
1450 mbedtls_mpi_free(&t);
1451 mpi_free_many(c, T_size);
1452 mbedtls_free(c);
1453
1454 return ret;
1455 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) */
1456 }
1457
1458 /*
1459 * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak.
1460 * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid
1461 */
ecp_safe_invert_jac(const mbedtls_ecp_group * grp,mbedtls_ecp_point * Q,unsigned char inv)1462 static int ecp_safe_invert_jac(const mbedtls_ecp_group *grp,
1463 mbedtls_ecp_point *Q,
1464 unsigned char inv)
1465 {
1466 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1467 mbedtls_mpi tmp;
1468 mbedtls_mpi_init(&tmp);
1469
1470 MPI_ECP_COND_NEG(&Q->Y, inv);
1471
1472 cleanup:
1473 mbedtls_mpi_free(&tmp);
1474 return ret;
1475 }
1476
1477 /*
1478 * Point doubling R = 2 P, Jacobian coordinates
1479 *
1480 * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 .
1481 *
1482 * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR
1483 * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring.
1484 *
1485 * Standard optimizations are applied when curve parameter A is one of { 0, -3 }.
1486 *
1487 * Cost: 1D := 3M + 4S (A == 0)
1488 * 4M + 4S (A == -3)
1489 * 3M + 6S + 1a otherwise
1490 */
ecp_double_jac(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_ecp_point * P,mbedtls_mpi tmp[4])1491 static int ecp_double_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1492 const mbedtls_ecp_point *P,
1493 mbedtls_mpi tmp[4])
1494 {
1495 #if defined(MBEDTLS_SELF_TEST)
1496 dbl_count++;
1497 #endif
1498
1499 #if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
1500 if (mbedtls_internal_ecp_grp_capable(grp)) {
1501 return mbedtls_internal_ecp_double_jac(grp, R, P);
1502 }
1503 #endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */
1504
1505 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
1506 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
1507 #else
1508 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1509
1510 /* Special case for A = -3 */
1511 if (mbedtls_ecp_group_a_is_minus_3(grp)) {
1512 /* tmp[0] <- M = 3(X + Z^2)(X - Z^2) */
1513 MPI_ECP_SQR(&tmp[1], &P->Z);
1514 MPI_ECP_ADD(&tmp[2], &P->X, &tmp[1]);
1515 MPI_ECP_SUB(&tmp[3], &P->X, &tmp[1]);
1516 MPI_ECP_MUL(&tmp[1], &tmp[2], &tmp[3]);
1517 MPI_ECP_MUL_INT(&tmp[0], &tmp[1], 3);
1518 } else {
1519 /* tmp[0] <- M = 3.X^2 + A.Z^4 */
1520 MPI_ECP_SQR(&tmp[1], &P->X);
1521 MPI_ECP_MUL_INT(&tmp[0], &tmp[1], 3);
1522
1523 /* Optimize away for "koblitz" curves with A = 0 */
1524 if (MPI_ECP_CMP_INT(&grp->A, 0) != 0) {
1525 /* M += A.Z^4 */
1526 MPI_ECP_SQR(&tmp[1], &P->Z);
1527 MPI_ECP_SQR(&tmp[2], &tmp[1]);
1528 MPI_ECP_MUL(&tmp[1], &tmp[2], &grp->A);
1529 MPI_ECP_ADD(&tmp[0], &tmp[0], &tmp[1]);
1530 }
1531 }
1532
1533 /* tmp[1] <- S = 4.X.Y^2 */
1534 MPI_ECP_SQR(&tmp[2], &P->Y);
1535 MPI_ECP_SHIFT_L(&tmp[2], 1);
1536 MPI_ECP_MUL(&tmp[1], &P->X, &tmp[2]);
1537 MPI_ECP_SHIFT_L(&tmp[1], 1);
1538
1539 /* tmp[3] <- U = 8.Y^4 */
1540 MPI_ECP_SQR(&tmp[3], &tmp[2]);
1541 MPI_ECP_SHIFT_L(&tmp[3], 1);
1542
1543 /* tmp[2] <- T = M^2 - 2.S */
1544 MPI_ECP_SQR(&tmp[2], &tmp[0]);
1545 MPI_ECP_SUB(&tmp[2], &tmp[2], &tmp[1]);
1546 MPI_ECP_SUB(&tmp[2], &tmp[2], &tmp[1]);
1547
1548 /* tmp[1] <- S = M(S - T) - U */
1549 MPI_ECP_SUB(&tmp[1], &tmp[1], &tmp[2]);
1550 MPI_ECP_MUL(&tmp[1], &tmp[1], &tmp[0]);
1551 MPI_ECP_SUB(&tmp[1], &tmp[1], &tmp[3]);
1552
1553 /* tmp[3] <- U = 2.Y.Z */
1554 MPI_ECP_MUL(&tmp[3], &P->Y, &P->Z);
1555 MPI_ECP_SHIFT_L(&tmp[3], 1);
1556
1557 /* Store results */
1558 MPI_ECP_MOV(&R->X, &tmp[2]);
1559 MPI_ECP_MOV(&R->Y, &tmp[1]);
1560 MPI_ECP_MOV(&R->Z, &tmp[3]);
1561
1562 cleanup:
1563
1564 return ret;
1565 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) */
1566 }
1567
1568 /*
1569 * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22)
1570 *
1571 * The coordinates of Q must be normalized (= affine),
1572 * but those of P don't need to. R is not normalized.
1573 *
1574 * P,Q,R may alias, but only at the level of EC points: they must be either
1575 * equal as pointers, or disjoint (including the coordinate data buffers).
1576 * Fine-grained aliasing at the level of coordinates is not supported.
1577 *
1578 * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q.
1579 * None of these cases can happen as intermediate step in ecp_mul_comb():
1580 * - at each step, P, Q and R are multiples of the base point, the factor
1581 * being less than its order, so none of them is zero;
1582 * - Q is an odd multiple of the base point, P an even multiple,
1583 * due to the choice of precomputed points in the modified comb method.
1584 * So branches for these cases do not leak secret information.
1585 *
1586 * Cost: 1A := 8M + 3S
1587 */
ecp_add_mixed(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_ecp_point * P,const mbedtls_ecp_point * Q,mbedtls_mpi tmp[4])1588 static int ecp_add_mixed(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1589 const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
1590 mbedtls_mpi tmp[4])
1591 {
1592 #if defined(MBEDTLS_SELF_TEST)
1593 add_count++;
1594 #endif
1595
1596 #if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
1597 if (mbedtls_internal_ecp_grp_capable(grp)) {
1598 return mbedtls_internal_ecp_add_mixed(grp, R, P, Q);
1599 }
1600 #endif /* MBEDTLS_ECP_ADD_MIXED_ALT */
1601
1602 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_ADD_MIXED_ALT)
1603 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
1604 #else
1605 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1606
1607 /* NOTE: Aliasing between input and output is allowed, so one has to make
1608 * sure that at the point X,Y,Z are written, {P,Q}->{X,Y,Z} are no
1609 * longer read from. */
1610 mbedtls_mpi * const X = &R->X;
1611 mbedtls_mpi * const Y = &R->Y;
1612 mbedtls_mpi * const Z = &R->Z;
1613
1614 if (!MPI_ECP_VALID(&Q->Z)) {
1615 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1616 }
1617
1618 /*
1619 * Trivial cases: P == 0 or Q == 0 (case 1)
1620 */
1621 if (MPI_ECP_CMP_INT(&P->Z, 0) == 0) {
1622 return mbedtls_ecp_copy(R, Q);
1623 }
1624
1625 if (MPI_ECP_CMP_INT(&Q->Z, 0) == 0) {
1626 return mbedtls_ecp_copy(R, P);
1627 }
1628
1629 /*
1630 * Make sure Q coordinates are normalized
1631 */
1632 if (MPI_ECP_CMP_INT(&Q->Z, 1) != 0) {
1633 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1634 }
1635
1636 MPI_ECP_SQR(&tmp[0], &P->Z);
1637 MPI_ECP_MUL(&tmp[1], &tmp[0], &P->Z);
1638 MPI_ECP_MUL(&tmp[0], &tmp[0], &Q->X);
1639 MPI_ECP_MUL(&tmp[1], &tmp[1], &Q->Y);
1640 MPI_ECP_SUB(&tmp[0], &tmp[0], &P->X);
1641 MPI_ECP_SUB(&tmp[1], &tmp[1], &P->Y);
1642
1643 /* Special cases (2) and (3) */
1644 if (MPI_ECP_CMP_INT(&tmp[0], 0) == 0) {
1645 if (MPI_ECP_CMP_INT(&tmp[1], 0) == 0) {
1646 ret = ecp_double_jac(grp, R, P, tmp);
1647 goto cleanup;
1648 } else {
1649 ret = mbedtls_ecp_set_zero(R);
1650 goto cleanup;
1651 }
1652 }
1653
1654 /* {P,Q}->Z no longer used, so OK to write to Z even if there's aliasing. */
1655 MPI_ECP_MUL(Z, &P->Z, &tmp[0]);
1656 MPI_ECP_SQR(&tmp[2], &tmp[0]);
1657 MPI_ECP_MUL(&tmp[3], &tmp[2], &tmp[0]);
1658 MPI_ECP_MUL(&tmp[2], &tmp[2], &P->X);
1659
1660 MPI_ECP_MOV(&tmp[0], &tmp[2]);
1661 MPI_ECP_SHIFT_L(&tmp[0], 1);
1662
1663 /* {P,Q}->X no longer used, so OK to write to X even if there's aliasing. */
1664 MPI_ECP_SQR(X, &tmp[1]);
1665 MPI_ECP_SUB(X, X, &tmp[0]);
1666 MPI_ECP_SUB(X, X, &tmp[3]);
1667 MPI_ECP_SUB(&tmp[2], &tmp[2], X);
1668 MPI_ECP_MUL(&tmp[2], &tmp[2], &tmp[1]);
1669 MPI_ECP_MUL(&tmp[3], &tmp[3], &P->Y);
1670 /* {P,Q}->Y no longer used, so OK to write to Y even if there's aliasing. */
1671 MPI_ECP_SUB(Y, &tmp[2], &tmp[3]);
1672
1673 cleanup:
1674
1675 return ret;
1676 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_ADD_MIXED_ALT) */
1677 }
1678
1679 /*
1680 * Randomize jacobian coordinates:
1681 * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l
1682 * This is sort of the reverse operation of ecp_normalize_jac().
1683 *
1684 * This countermeasure was first suggested in [2].
1685 */
ecp_randomize_jac(const mbedtls_ecp_group * grp,mbedtls_ecp_point * pt,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1686 static int ecp_randomize_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
1687 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1688 {
1689 #if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
1690 if (mbedtls_internal_ecp_grp_capable(grp)) {
1691 return mbedtls_internal_ecp_randomize_jac(grp, pt, f_rng, p_rng);
1692 }
1693 #endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */
1694
1695 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
1696 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
1697 #else
1698 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1699 mbedtls_mpi l;
1700
1701 mbedtls_mpi_init(&l);
1702
1703 /* Generate l such that 1 < l < p */
1704 MPI_ECP_RAND(&l);
1705
1706 /* Z' = l * Z */
1707 MPI_ECP_MUL(&pt->Z, &pt->Z, &l);
1708
1709 /* Y' = l * Y */
1710 MPI_ECP_MUL(&pt->Y, &pt->Y, &l);
1711
1712 /* X' = l^2 * X */
1713 MPI_ECP_SQR(&l, &l);
1714 MPI_ECP_MUL(&pt->X, &pt->X, &l);
1715
1716 /* Y'' = l^2 * Y' = l^3 * Y */
1717 MPI_ECP_MUL(&pt->Y, &pt->Y, &l);
1718
1719 cleanup:
1720 mbedtls_mpi_free(&l);
1721
1722 if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
1723 ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
1724 }
1725 return ret;
1726 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) */
1727 }
1728
1729 /*
1730 * Check and define parameters used by the comb method (see below for details)
1731 */
1732 #if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7
1733 #error "MBEDTLS_ECP_WINDOW_SIZE out of bounds"
1734 #endif
1735
1736 /* d = ceil( n / w ) */
1737 #define COMB_MAX_D (MBEDTLS_ECP_MAX_BITS + 1) / 2
1738
1739 /* number of precomputed points */
1740 #define COMB_MAX_PRE (1 << (MBEDTLS_ECP_WINDOW_SIZE - 1))
1741
1742 /*
1743 * Compute the representation of m that will be used with our comb method.
1744 *
1745 * The basic comb method is described in GECC 3.44 for example. We use a
1746 * modified version that provides resistance to SPA by avoiding zero
1747 * digits in the representation as in [3]. We modify the method further by
1748 * requiring that all K_i be odd, which has the small cost that our
1749 * representation uses one more K_i, due to carries, but saves on the size of
1750 * the precomputed table.
1751 *
1752 * Summary of the comb method and its modifications:
1753 *
1754 * - The goal is to compute m*P for some w*d-bit integer m.
1755 *
1756 * - The basic comb method splits m into the w-bit integers
1757 * x[0] .. x[d-1] where x[i] consists of the bits in m whose
1758 * index has residue i modulo d, and computes m * P as
1759 * S[x[0]] + 2 * S[x[1]] + .. + 2^(d-1) S[x[d-1]], where
1760 * S[i_{w-1} .. i_0] := i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + i_0 P.
1761 *
1762 * - If it happens that, say, x[i+1]=0 (=> S[x[i+1]]=0), one can replace the sum by
1763 * .. + 2^{i-1} S[x[i-1]] - 2^i S[x[i]] + 2^{i+1} S[x[i]] + 2^{i+2} S[x[i+2]] ..,
1764 * thereby successively converting it into a form where all summands
1765 * are nonzero, at the cost of negative summands. This is the basic idea of [3].
1766 *
1767 * - More generally, even if x[i+1] != 0, we can first transform the sum as
1768 * .. - 2^i S[x[i]] + 2^{i+1} ( S[x[i]] + S[x[i+1]] ) + 2^{i+2} S[x[i+2]] ..,
1769 * and then replace S[x[i]] + S[x[i+1]] = S[x[i] ^ x[i+1]] + 2 S[x[i] & x[i+1]].
1770 * Performing and iterating this procedure for those x[i] that are even
1771 * (keeping track of carry), we can transform the original sum into one of the form
1772 * S[x'[0]] +- 2 S[x'[1]] +- .. +- 2^{d-1} S[x'[d-1]] + 2^d S[x'[d]]
1773 * with all x'[i] odd. It is therefore only necessary to know S at odd indices,
1774 * which is why we are only computing half of it in the first place in
1775 * ecp_precompute_comb and accessing it with index abs(i) / 2 in ecp_select_comb.
1776 *
1777 * - For the sake of compactness, only the seven low-order bits of x[i]
1778 * are used to represent its absolute value (K_i in the paper), and the msb
1779 * of x[i] encodes the sign (s_i in the paper): it is set if and only if
1780 * if s_i == -1;
1781 *
1782 * Calling conventions:
1783 * - x is an array of size d + 1
1784 * - w is the size, ie number of teeth, of the comb, and must be between
1785 * 2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE)
1786 * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d
1787 * (the result will be incorrect if these assumptions are not satisfied)
1788 */
ecp_comb_recode_core(unsigned char x[],size_t d,unsigned char w,const mbedtls_mpi * m)1789 static void ecp_comb_recode_core(unsigned char x[], size_t d,
1790 unsigned char w, const mbedtls_mpi *m)
1791 {
1792 size_t i, j;
1793 unsigned char c, cc, adjust;
1794
1795 memset(x, 0, d+1);
1796
1797 /* First get the classical comb values (except for x_d = 0) */
1798 for (i = 0; i < d; i++) {
1799 for (j = 0; j < w; j++) {
1800 x[i] |= mbedtls_mpi_get_bit(m, i + d * j) << j;
1801 }
1802 }
1803
1804 /* Now make sure x_1 .. x_d are odd */
1805 c = 0;
1806 for (i = 1; i <= d; i++) {
1807 /* Add carry and update it */
1808 cc = x[i] & c;
1809 x[i] = x[i] ^ c;
1810 c = cc;
1811
1812 /* Adjust if needed, avoiding branches */
1813 adjust = 1 - (x[i] & 0x01);
1814 c |= x[i] & (x[i-1] * adjust);
1815 x[i] = x[i] ^ (x[i-1] * adjust);
1816 x[i-1] |= adjust << 7;
1817 }
1818 }
1819
1820 /*
1821 * Precompute points for the adapted comb method
1822 *
1823 * Assumption: T must be able to hold 2^{w - 1} elements.
1824 *
1825 * Operation: If i = i_{w-1} ... i_1 is the binary representation of i,
1826 * sets T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P.
1827 *
1828 * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1)
1829 *
1830 * Note: Even comb values (those where P would be omitted from the
1831 * sum defining T[i] above) are not needed in our adaption
1832 * the comb method. See ecp_comb_recode_core().
1833 *
1834 * This function currently works in four steps:
1835 * (1) [dbl] Computation of intermediate T[i] for 2-power values of i
1836 * (2) [norm_dbl] Normalization of coordinates of these T[i]
1837 * (3) [add] Computation of all T[i]
1838 * (4) [norm_add] Normalization of all T[i]
1839 *
1840 * Step 1 can be interrupted but not the others; together with the final
1841 * coordinate normalization they are the largest steps done at once, depending
1842 * on the window size. Here are operation counts for P-256:
1843 *
1844 * step (2) (3) (4)
1845 * w = 5 142 165 208
1846 * w = 4 136 77 160
1847 * w = 3 130 33 136
1848 * w = 2 124 11 124
1849 *
1850 * So if ECC operations are blocking for too long even with a low max_ops
1851 * value, it's useful to set MBEDTLS_ECP_WINDOW_SIZE to a lower value in order
1852 * to minimize maximum blocking time.
1853 */
ecp_precompute_comb(const mbedtls_ecp_group * grp,mbedtls_ecp_point T[],const mbedtls_ecp_point * P,unsigned char w,size_t d,mbedtls_ecp_restart_ctx * rs_ctx)1854 static int ecp_precompute_comb(const mbedtls_ecp_group *grp,
1855 mbedtls_ecp_point T[], const mbedtls_ecp_point *P,
1856 unsigned char w, size_t d,
1857 mbedtls_ecp_restart_ctx *rs_ctx)
1858 {
1859 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1860 unsigned char i;
1861 size_t j = 0;
1862 const unsigned char T_size = 1U << (w - 1);
1863 mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1] = { NULL };
1864
1865 mbedtls_mpi tmp[4];
1866
1867 mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi));
1868
1869 #if defined(MBEDTLS_ECP_RESTARTABLE)
1870 if (rs_ctx != NULL && rs_ctx->rsm != NULL) {
1871 if (rs_ctx->rsm->state == ecp_rsm_pre_dbl) {
1872 goto dbl;
1873 }
1874 if (rs_ctx->rsm->state == ecp_rsm_pre_norm_dbl) {
1875 goto norm_dbl;
1876 }
1877 if (rs_ctx->rsm->state == ecp_rsm_pre_add) {
1878 goto add;
1879 }
1880 if (rs_ctx->rsm->state == ecp_rsm_pre_norm_add) {
1881 goto norm_add;
1882 }
1883 }
1884 #else
1885 (void) rs_ctx;
1886 #endif
1887
1888 #if defined(MBEDTLS_ECP_RESTARTABLE)
1889 if (rs_ctx != NULL && rs_ctx->rsm != NULL) {
1890 rs_ctx->rsm->state = ecp_rsm_pre_dbl;
1891
1892 /* initial state for the loop */
1893 rs_ctx->rsm->i = 0;
1894 }
1895
1896 dbl:
1897 #endif
1898 /*
1899 * Set T[0] = P and
1900 * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value)
1901 */
1902 MBEDTLS_MPI_CHK(mbedtls_ecp_copy(&T[0], P));
1903
1904 #if defined(MBEDTLS_ECP_RESTARTABLE)
1905 if (rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0) {
1906 j = rs_ctx->rsm->i;
1907 } else
1908 #endif
1909 j = 0;
1910
1911 for (; j < d * (w - 1); j++) {
1912 MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_DBL);
1913
1914 i = 1U << (j / d);
1915 cur = T + i;
1916
1917 if (j % d == 0) {
1918 MBEDTLS_MPI_CHK(mbedtls_ecp_copy(cur, T + (i >> 1)));
1919 }
1920
1921 MBEDTLS_MPI_CHK(ecp_double_jac(grp, cur, cur, tmp));
1922 }
1923
1924 #if defined(MBEDTLS_ECP_RESTARTABLE)
1925 if (rs_ctx != NULL && rs_ctx->rsm != NULL) {
1926 rs_ctx->rsm->state = ecp_rsm_pre_norm_dbl;
1927 }
1928
1929 norm_dbl:
1930 #endif
1931 /*
1932 * Normalize current elements in T to allow them to be used in
1933 * ecp_add_mixed() below, which requires one normalized input.
1934 *
1935 * As T has holes, use an auxiliary array of pointers to elements in T.
1936 *
1937 */
1938 j = 0;
1939 for (i = 1; i < T_size; i <<= 1) {
1940 TT[j++] = T + i;
1941 }
1942
1943 MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV + 6 * j - 2);
1944
1945 MBEDTLS_MPI_CHK(ecp_normalize_jac_many(grp, TT, j));
1946
1947 #if defined(MBEDTLS_ECP_RESTARTABLE)
1948 if (rs_ctx != NULL && rs_ctx->rsm != NULL) {
1949 rs_ctx->rsm->state = ecp_rsm_pre_add;
1950 }
1951
1952 add:
1953 #endif
1954 /*
1955 * Compute the remaining ones using the minimal number of additions
1956 * Be careful to update T[2^l] only after using it!
1957 */
1958 MBEDTLS_ECP_BUDGET((T_size - 1) * MBEDTLS_ECP_OPS_ADD);
1959
1960 for (i = 1; i < T_size; i <<= 1) {
1961 j = i;
1962 while (j--) {
1963 MBEDTLS_MPI_CHK(ecp_add_mixed(grp, &T[i + j], &T[j], &T[i], tmp));
1964 }
1965 }
1966
1967 #if defined(MBEDTLS_ECP_RESTARTABLE)
1968 if (rs_ctx != NULL && rs_ctx->rsm != NULL) {
1969 rs_ctx->rsm->state = ecp_rsm_pre_norm_add;
1970 }
1971
1972 norm_add:
1973 #endif
1974 /*
1975 * Normalize final elements in T. Even though there are no holes now, we
1976 * still need the auxiliary array for homogeneity with the previous
1977 * call. Also, skip T[0] which is already normalised, being a copy of P.
1978 */
1979 for (j = 0; j + 1 < T_size; j++) {
1980 TT[j] = T + j + 1;
1981 }
1982
1983 MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV + 6 * j - 2);
1984
1985 MBEDTLS_MPI_CHK(ecp_normalize_jac_many(grp, TT, j));
1986
1987 /* Free Z coordinate (=1 after normalization) to save RAM.
1988 * This makes T[i] invalid as mbedtls_ecp_points, but this is OK
1989 * since from this point onwards, they are only accessed indirectly
1990 * via the getter function ecp_select_comb() which does set the
1991 * target's Z coordinate to 1. */
1992 for (i = 0; i < T_size; i++) {
1993 mbedtls_mpi_free(&T[i].Z);
1994 }
1995
1996 cleanup:
1997
1998 mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi));
1999
2000 #if defined(MBEDTLS_ECP_RESTARTABLE)
2001 if (rs_ctx != NULL && rs_ctx->rsm != NULL &&
2002 ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2003 if (rs_ctx->rsm->state == ecp_rsm_pre_dbl) {
2004 rs_ctx->rsm->i = j;
2005 }
2006 }
2007 #endif
2008
2009 return ret;
2010 }
2011
2012 /*
2013 * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ]
2014 *
2015 * See ecp_comb_recode_core() for background
2016 */
ecp_select_comb(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_ecp_point T[],unsigned char T_size,unsigned char i)2017 static int ecp_select_comb(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2018 const mbedtls_ecp_point T[], unsigned char T_size,
2019 unsigned char i)
2020 {
2021 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2022 unsigned char ii, j;
2023
2024 /* Ignore the "sign" bit and scale down */
2025 ii = (i & 0x7Fu) >> 1;
2026
2027 /* Read the whole table to thwart cache-based timing attacks */
2028 for (j = 0; j < T_size; j++) {
2029 MPI_ECP_COND_ASSIGN(&R->X, &T[j].X, j == ii);
2030 MPI_ECP_COND_ASSIGN(&R->Y, &T[j].Y, j == ii);
2031 }
2032
2033 /* Safely invert result if i is "negative" */
2034 MBEDTLS_MPI_CHK(ecp_safe_invert_jac(grp, R, i >> 7));
2035
2036 MPI_ECP_LSET(&R->Z, 1);
2037
2038 cleanup:
2039 return ret;
2040 }
2041
2042 /*
2043 * Core multiplication algorithm for the (modified) comb method.
2044 * This part is actually common with the basic comb method (GECC 3.44)
2045 *
2046 * Cost: d A + d D + 1 R
2047 */
ecp_mul_comb_core(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_ecp_point T[],unsigned char T_size,const unsigned char x[],size_t d,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_ecp_restart_ctx * rs_ctx)2048 static int ecp_mul_comb_core(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2049 const mbedtls_ecp_point T[], unsigned char T_size,
2050 const unsigned char x[], size_t d,
2051 int (*f_rng)(void *, unsigned char *, size_t),
2052 void *p_rng,
2053 mbedtls_ecp_restart_ctx *rs_ctx)
2054 {
2055 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2056 mbedtls_ecp_point Txi;
2057 mbedtls_mpi tmp[4];
2058 size_t i;
2059
2060 mbedtls_ecp_point_init(&Txi);
2061 mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi));
2062
2063 #if !defined(MBEDTLS_ECP_RESTARTABLE)
2064 (void) rs_ctx;
2065 #endif
2066
2067 #if defined(MBEDTLS_ECP_RESTARTABLE)
2068 if (rs_ctx != NULL && rs_ctx->rsm != NULL &&
2069 rs_ctx->rsm->state != ecp_rsm_comb_core) {
2070 rs_ctx->rsm->i = 0;
2071 rs_ctx->rsm->state = ecp_rsm_comb_core;
2072 }
2073
2074 /* new 'if' instead of nested for the sake of the 'else' branch */
2075 if (rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0) {
2076 /* restore current index (R already pointing to rs_ctx->rsm->R) */
2077 i = rs_ctx->rsm->i;
2078 } else
2079 #endif
2080 {
2081 /* Start with a non-zero point and randomize its coordinates */
2082 i = d;
2083 MBEDTLS_MPI_CHK(ecp_select_comb(grp, R, T, T_size, x[i]));
2084 if (f_rng != 0) {
2085 MBEDTLS_MPI_CHK(ecp_randomize_jac(grp, R, f_rng, p_rng));
2086 }
2087 }
2088
2089 while (i != 0) {
2090 MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD);
2091 --i;
2092
2093 MBEDTLS_MPI_CHK(ecp_double_jac(grp, R, R, tmp));
2094 MBEDTLS_MPI_CHK(ecp_select_comb(grp, &Txi, T, T_size, x[i]));
2095 MBEDTLS_MPI_CHK(ecp_add_mixed(grp, R, R, &Txi, tmp));
2096 }
2097
2098 cleanup:
2099
2100 mbedtls_ecp_point_free(&Txi);
2101 mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi));
2102
2103 #if defined(MBEDTLS_ECP_RESTARTABLE)
2104 if (rs_ctx != NULL && rs_ctx->rsm != NULL &&
2105 ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2106 rs_ctx->rsm->i = i;
2107 /* no need to save R, already pointing to rs_ctx->rsm->R */
2108 }
2109 #endif
2110
2111 return ret;
2112 }
2113
2114 /*
2115 * Recode the scalar to get constant-time comb multiplication
2116 *
2117 * As the actual scalar recoding needs an odd scalar as a starting point,
2118 * this wrapper ensures that by replacing m by N - m if necessary, and
2119 * informs the caller that the result of multiplication will be negated.
2120 *
2121 * This works because we only support large prime order for Short Weierstrass
2122 * curves, so N is always odd hence either m or N - m is.
2123 *
2124 * See ecp_comb_recode_core() for background.
2125 */
ecp_comb_recode_scalar(const mbedtls_ecp_group * grp,const mbedtls_mpi * m,unsigned char k[COMB_MAX_D+1],size_t d,unsigned char w,unsigned char * parity_trick)2126 static int ecp_comb_recode_scalar(const mbedtls_ecp_group *grp,
2127 const mbedtls_mpi *m,
2128 unsigned char k[COMB_MAX_D + 1],
2129 size_t d,
2130 unsigned char w,
2131 unsigned char *parity_trick)
2132 {
2133 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2134 mbedtls_mpi M, mm;
2135
2136 mbedtls_mpi_init(&M);
2137 mbedtls_mpi_init(&mm);
2138
2139 /* N is always odd (see above), just make extra sure */
2140 if (mbedtls_mpi_get_bit(&grp->N, 0) != 1) {
2141 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
2142 }
2143
2144 /* do we need the parity trick? */
2145 *parity_trick = (mbedtls_mpi_get_bit(m, 0) == 0);
2146
2147 /* execute parity fix in constant time */
2148 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&M, m));
2149 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&mm, &grp->N, m));
2150 MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(&M, &mm, *parity_trick));
2151
2152 /* actual scalar recoding */
2153 ecp_comb_recode_core(k, d, w, &M);
2154
2155 cleanup:
2156 mbedtls_mpi_free(&mm);
2157 mbedtls_mpi_free(&M);
2158
2159 return ret;
2160 }
2161
2162 /*
2163 * Perform comb multiplication (for short Weierstrass curves)
2164 * once the auxiliary table has been pre-computed.
2165 *
2166 * Scalar recoding may use a parity trick that makes us compute -m * P,
2167 * if that is the case we'll need to recover m * P at the end.
2168 */
ecp_mul_comb_after_precomp(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * T,unsigned char T_size,unsigned char w,size_t d,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_ecp_restart_ctx * rs_ctx)2169 static int ecp_mul_comb_after_precomp(const mbedtls_ecp_group *grp,
2170 mbedtls_ecp_point *R,
2171 const mbedtls_mpi *m,
2172 const mbedtls_ecp_point *T,
2173 unsigned char T_size,
2174 unsigned char w,
2175 size_t d,
2176 int (*f_rng)(void *, unsigned char *, size_t),
2177 void *p_rng,
2178 mbedtls_ecp_restart_ctx *rs_ctx)
2179 {
2180 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2181 unsigned char parity_trick;
2182 unsigned char k[COMB_MAX_D + 1];
2183 mbedtls_ecp_point *RR = R;
2184
2185 #if defined(MBEDTLS_ECP_RESTARTABLE)
2186 if (rs_ctx != NULL && rs_ctx->rsm != NULL) {
2187 RR = &rs_ctx->rsm->R;
2188
2189 if (rs_ctx->rsm->state == ecp_rsm_final_norm) {
2190 goto final_norm;
2191 }
2192 }
2193 #endif
2194
2195 MBEDTLS_MPI_CHK(ecp_comb_recode_scalar(grp, m, k, d, w,
2196 &parity_trick));
2197 MBEDTLS_MPI_CHK(ecp_mul_comb_core(grp, RR, T, T_size, k, d,
2198 f_rng, p_rng, rs_ctx));
2199 MBEDTLS_MPI_CHK(ecp_safe_invert_jac(grp, RR, parity_trick));
2200
2201 #if defined(MBEDTLS_ECP_RESTARTABLE)
2202 if (rs_ctx != NULL && rs_ctx->rsm != NULL) {
2203 rs_ctx->rsm->state = ecp_rsm_final_norm;
2204 }
2205
2206 final_norm:
2207 MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV);
2208 #endif
2209 MBEDTLS_MPI_CHK(ecp_normalize_jac(grp, RR));
2210
2211 #if defined(MBEDTLS_ECP_RESTARTABLE)
2212 if (rs_ctx != NULL && rs_ctx->rsm != NULL) {
2213 MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, RR));
2214 }
2215 #endif
2216
2217 cleanup:
2218 return ret;
2219 }
2220
2221 /*
2222 * Pick window size based on curve size and whether we optimize for base point
2223 */
ecp_pick_window_size(const mbedtls_ecp_group * grp,unsigned char p_eq_g)2224 static unsigned char ecp_pick_window_size(const mbedtls_ecp_group *grp,
2225 unsigned char p_eq_g)
2226 {
2227 unsigned char w;
2228
2229 /*
2230 * Minimize the number of multiplications, that is minimize
2231 * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w )
2232 * (see costs of the various parts, with 1S = 1M)
2233 */
2234 w = grp->nbits >= 384 ? 5 : 4;
2235
2236 /*
2237 * If P == G, pre-compute a bit more, since this may be re-used later.
2238 * Just adding one avoids upping the cost of the first mul too much,
2239 * and the memory cost too.
2240 */
2241 if (p_eq_g) {
2242 w++;
2243 }
2244
2245 /*
2246 * If static comb table may not be used (!p_eq_g) or static comb table does
2247 * not exists, make sure w is within bounds.
2248 * (The last test is useful only for very small curves in the test suite.)
2249 *
2250 * The user reduces MBEDTLS_ECP_WINDOW_SIZE does not changes the size of
2251 * static comb table, because the size of static comb table is fixed when
2252 * it is generated.
2253 */
2254 #if (MBEDTLS_ECP_WINDOW_SIZE < 6)
2255 if ((!p_eq_g || !ecp_group_is_static_comb_table(grp)) && w > MBEDTLS_ECP_WINDOW_SIZE) {
2256 w = MBEDTLS_ECP_WINDOW_SIZE;
2257 }
2258 #endif
2259 if (w >= grp->nbits) {
2260 w = 2;
2261 }
2262
2263 return w;
2264 }
2265
2266 /*
2267 * Multiplication using the comb method - for curves in short Weierstrass form
2268 *
2269 * This function is mainly responsible for administrative work:
2270 * - managing the restart context if enabled
2271 * - managing the table of precomputed points (passed between the below two
2272 * functions): allocation, computation, ownership transfer, freeing.
2273 *
2274 * It delegates the actual arithmetic work to:
2275 * ecp_precompute_comb() and ecp_mul_comb_with_precomp()
2276 *
2277 * See comments on ecp_comb_recode_core() regarding the computation strategy.
2278 */
ecp_mul_comb(mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_ecp_restart_ctx * rs_ctx)2279 static int ecp_mul_comb(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2280 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2281 int (*f_rng)(void *, unsigned char *, size_t),
2282 void *p_rng,
2283 mbedtls_ecp_restart_ctx *rs_ctx)
2284 {
2285 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2286 unsigned char w, p_eq_g, i;
2287 size_t d;
2288 unsigned char T_size = 0, T_ok = 0;
2289 mbedtls_ecp_point *T = NULL;
2290
2291 ECP_RS_ENTER(rsm);
2292
2293 /* Is P the base point ? */
2294 #if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
2295 p_eq_g = (MPI_ECP_CMP(&P->Y, &grp->G.Y) == 0 &&
2296 MPI_ECP_CMP(&P->X, &grp->G.X) == 0);
2297 #else
2298 p_eq_g = 0;
2299 #endif
2300
2301 /* Pick window size and deduce related sizes */
2302 w = ecp_pick_window_size(grp, p_eq_g);
2303 T_size = 1U << (w - 1);
2304 d = (grp->nbits + w - 1) / w;
2305
2306 /* Pre-computed table: do we have it already for the base point? */
2307 if (p_eq_g && grp->T != NULL) {
2308 /* second pointer to the same table, will be deleted on exit */
2309 T = grp->T;
2310 T_ok = 1;
2311 } else
2312 #if defined(MBEDTLS_ECP_RESTARTABLE)
2313 /* Pre-computed table: do we have one in progress? complete? */
2314 if (rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->T != NULL) {
2315 /* transfer ownership of T from rsm to local function */
2316 T = rs_ctx->rsm->T;
2317 rs_ctx->rsm->T = NULL;
2318 rs_ctx->rsm->T_size = 0;
2319
2320 /* This effectively jumps to the call to mul_comb_after_precomp() */
2321 T_ok = rs_ctx->rsm->state >= ecp_rsm_comb_core;
2322 } else
2323 #endif
2324 /* Allocate table if we didn't have any */
2325 {
2326 T = mbedtls_calloc(T_size, sizeof(mbedtls_ecp_point));
2327 if (T == NULL) {
2328 ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
2329 goto cleanup;
2330 }
2331
2332 for (i = 0; i < T_size; i++) {
2333 mbedtls_ecp_point_init(&T[i]);
2334 }
2335
2336 T_ok = 0;
2337 }
2338
2339 /* Compute table (or finish computing it) if not done already */
2340 if (!T_ok) {
2341 MBEDTLS_MPI_CHK(ecp_precompute_comb(grp, T, P, w, d, rs_ctx));
2342
2343 if (p_eq_g) {
2344 /* almost transfer ownership of T to the group, but keep a copy of
2345 * the pointer to use for calling the next function more easily */
2346 grp->T = T;
2347 grp->T_size = T_size;
2348 }
2349 }
2350
2351 /* Actual comb multiplication using precomputed points */
2352 MBEDTLS_MPI_CHK(ecp_mul_comb_after_precomp(grp, R, m,
2353 T, T_size, w, d,
2354 f_rng, p_rng, rs_ctx));
2355
2356 cleanup:
2357
2358 /* does T belong to the group? */
2359 if (T == grp->T) {
2360 T = NULL;
2361 }
2362
2363 /* does T belong to the restart context? */
2364 #if defined(MBEDTLS_ECP_RESTARTABLE)
2365 if (rs_ctx != NULL && rs_ctx->rsm != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS && T != NULL) {
2366 /* transfer ownership of T from local function to rsm */
2367 rs_ctx->rsm->T_size = T_size;
2368 rs_ctx->rsm->T = T;
2369 T = NULL;
2370 }
2371 #endif
2372
2373 /* did T belong to us? then let's destroy it! */
2374 if (T != NULL) {
2375 for (i = 0; i < T_size; i++) {
2376 mbedtls_ecp_point_free(&T[i]);
2377 }
2378 mbedtls_free(T);
2379 }
2380
2381 /* prevent caller from using invalid value */
2382 int should_free_R = (ret != 0);
2383 #if defined(MBEDTLS_ECP_RESTARTABLE)
2384 /* don't free R while in progress in case R == P */
2385 if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2386 should_free_R = 0;
2387 }
2388 #endif
2389 if (should_free_R) {
2390 mbedtls_ecp_point_free(R);
2391 }
2392
2393 ECP_RS_LEAVE(rsm);
2394
2395 return ret;
2396 }
2397
2398 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
2399
2400 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
2401 /*
2402 * For Montgomery curves, we do all the internal arithmetic in projective
2403 * coordinates. Import/export of points uses only the x coordinates, which is
2404 * internally represented as X / Z.
2405 *
2406 * For scalar multiplication, we'll use a Montgomery ladder.
2407 */
2408
2409 /*
2410 * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1
2411 * Cost: 1M + 1I
2412 */
ecp_normalize_mxz(const mbedtls_ecp_group * grp,mbedtls_ecp_point * P)2413 static int ecp_normalize_mxz(const mbedtls_ecp_group *grp, mbedtls_ecp_point *P)
2414 {
2415 #if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
2416 if (mbedtls_internal_ecp_grp_capable(grp)) {
2417 return mbedtls_internal_ecp_normalize_mxz(grp, P);
2418 }
2419 #endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
2420
2421 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
2422 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
2423 #else
2424 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2425 MPI_ECP_INV(&P->Z, &P->Z);
2426 MPI_ECP_MUL(&P->X, &P->X, &P->Z);
2427 MPI_ECP_LSET(&P->Z, 1);
2428
2429 cleanup:
2430 return ret;
2431 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) */
2432 }
2433
2434 /*
2435 * Randomize projective x/z coordinates:
2436 * (X, Z) -> (l X, l Z) for random l
2437 * This is sort of the reverse operation of ecp_normalize_mxz().
2438 *
2439 * This countermeasure was first suggested in [2].
2440 * Cost: 2M
2441 */
ecp_randomize_mxz(const mbedtls_ecp_group * grp,mbedtls_ecp_point * P,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)2442 static int ecp_randomize_mxz(const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
2443 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
2444 {
2445 #if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
2446 if (mbedtls_internal_ecp_grp_capable(grp)) {
2447 return mbedtls_internal_ecp_randomize_mxz(grp, P, f_rng, p_rng);
2448 }
2449 #endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */
2450
2451 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
2452 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
2453 #else
2454 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2455 mbedtls_mpi l;
2456 mbedtls_mpi_init(&l);
2457
2458 /* Generate l such that 1 < l < p */
2459 MPI_ECP_RAND(&l);
2460
2461 MPI_ECP_MUL(&P->X, &P->X, &l);
2462 MPI_ECP_MUL(&P->Z, &P->Z, &l);
2463
2464 cleanup:
2465 mbedtls_mpi_free(&l);
2466
2467 if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
2468 ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
2469 }
2470 return ret;
2471 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) */
2472 }
2473
2474 /*
2475 * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q),
2476 * for Montgomery curves in x/z coordinates.
2477 *
2478 * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3
2479 * with
2480 * d = X1
2481 * P = (X2, Z2)
2482 * Q = (X3, Z3)
2483 * R = (X4, Z4)
2484 * S = (X5, Z5)
2485 * and eliminating temporary variables tO, ..., t4.
2486 *
2487 * Cost: 5M + 4S
2488 */
ecp_double_add_mxz(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,mbedtls_ecp_point * S,const mbedtls_ecp_point * P,const mbedtls_ecp_point * Q,const mbedtls_mpi * d,mbedtls_mpi T[4])2489 static int ecp_double_add_mxz(const mbedtls_ecp_group *grp,
2490 mbedtls_ecp_point *R, mbedtls_ecp_point *S,
2491 const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
2492 const mbedtls_mpi *d,
2493 mbedtls_mpi T[4])
2494 {
2495 #if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
2496 if (mbedtls_internal_ecp_grp_capable(grp)) {
2497 return mbedtls_internal_ecp_double_add_mxz(grp, R, S, P, Q, d);
2498 }
2499 #endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */
2500
2501 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
2502 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
2503 #else
2504 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2505
2506 MPI_ECP_ADD(&T[0], &P->X, &P->Z); /* Pp := PX + PZ */
2507 MPI_ECP_SUB(&T[1], &P->X, &P->Z); /* Pm := PX - PZ */
2508 MPI_ECP_ADD(&T[2], &Q->X, &Q->Z); /* Qp := QX + XZ */
2509 MPI_ECP_SUB(&T[3], &Q->X, &Q->Z); /* Qm := QX - QZ */
2510 MPI_ECP_MUL(&T[3], &T[3], &T[0]); /* Qm * Pp */
2511 MPI_ECP_MUL(&T[2], &T[2], &T[1]); /* Qp * Pm */
2512 MPI_ECP_SQR(&T[0], &T[0]); /* Pp^2 */
2513 MPI_ECP_SQR(&T[1], &T[1]); /* Pm^2 */
2514 MPI_ECP_MUL(&R->X, &T[0], &T[1]); /* Pp^2 * Pm^2 */
2515 MPI_ECP_SUB(&T[0], &T[0], &T[1]); /* Pp^2 - Pm^2 */
2516 MPI_ECP_MUL(&R->Z, &grp->A, &T[0]); /* A * (Pp^2 - Pm^2) */
2517 MPI_ECP_ADD(&R->Z, &T[1], &R->Z); /* [ A * (Pp^2-Pm^2) ] + Pm^2 */
2518 MPI_ECP_ADD(&S->X, &T[3], &T[2]); /* Qm*Pp + Qp*Pm */
2519 MPI_ECP_SQR(&S->X, &S->X); /* (Qm*Pp + Qp*Pm)^2 */
2520 MPI_ECP_SUB(&S->Z, &T[3], &T[2]); /* Qm*Pp - Qp*Pm */
2521 MPI_ECP_SQR(&S->Z, &S->Z); /* (Qm*Pp - Qp*Pm)^2 */
2522 MPI_ECP_MUL(&S->Z, d, &S->Z); /* d * ( Qm*Pp - Qp*Pm )^2 */
2523 MPI_ECP_MUL(&R->Z, &T[0], &R->Z); /* [A*(Pp^2-Pm^2)+Pm^2]*(Pp^2-Pm^2) */
2524
2525 cleanup:
2526
2527 return ret;
2528 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) */
2529 }
2530
2531 /*
2532 * Multiplication with Montgomery ladder in x/z coordinates,
2533 * for curves in Montgomery form
2534 */
ecp_mul_mxz(mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)2535 static int ecp_mul_mxz(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2536 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2537 int (*f_rng)(void *, unsigned char *, size_t),
2538 void *p_rng)
2539 {
2540 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2541 size_t i;
2542 unsigned char b;
2543 mbedtls_ecp_point RP;
2544 mbedtls_mpi PX;
2545 mbedtls_mpi tmp[4];
2546 mbedtls_ecp_point_init(&RP); mbedtls_mpi_init(&PX);
2547
2548 mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi));
2549
2550 if (f_rng == NULL) {
2551 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
2552 }
2553
2554 /* Save PX and read from P before writing to R, in case P == R */
2555 MPI_ECP_MOV(&PX, &P->X);
2556 MBEDTLS_MPI_CHK(mbedtls_ecp_copy(&RP, P));
2557
2558 /* Set R to zero in modified x/z coordinates */
2559 MPI_ECP_LSET(&R->X, 1);
2560 MPI_ECP_LSET(&R->Z, 0);
2561 mbedtls_mpi_free(&R->Y);
2562
2563 /* RP.X might be slightly larger than P, so reduce it */
2564 MOD_ADD(&RP.X);
2565
2566 /* Randomize coordinates of the starting point */
2567 MBEDTLS_MPI_CHK(ecp_randomize_mxz(grp, &RP, f_rng, p_rng));
2568
2569 /* Loop invariant: R = result so far, RP = R + P */
2570 i = grp->nbits + 1; /* one past the (zero-based) required msb for private keys */
2571 while (i-- > 0) {
2572 b = mbedtls_mpi_get_bit(m, i);
2573 /*
2574 * if (b) R = 2R + P else R = 2R,
2575 * which is:
2576 * if (b) double_add( RP, R, RP, R )
2577 * else double_add( R, RP, R, RP )
2578 * but using safe conditional swaps to avoid leaks
2579 */
2580 MPI_ECP_COND_SWAP(&R->X, &RP.X, b);
2581 MPI_ECP_COND_SWAP(&R->Z, &RP.Z, b);
2582 MBEDTLS_MPI_CHK(ecp_double_add_mxz(grp, R, &RP, R, &RP, &PX, tmp));
2583 MPI_ECP_COND_SWAP(&R->X, &RP.X, b);
2584 MPI_ECP_COND_SWAP(&R->Z, &RP.Z, b);
2585 }
2586
2587 MBEDTLS_MPI_CHK(ecp_normalize_mxz(grp, R));
2588
2589 cleanup:
2590 mbedtls_ecp_point_free(&RP); mbedtls_mpi_free(&PX);
2591
2592 mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi));
2593 return ret;
2594 }
2595
2596 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
2597
2598 /*
2599 * Restartable multiplication R = m * P
2600 *
2601 * This internal function can be called without an RNG in case where we know
2602 * the inputs are not sensitive.
2603 */
ecp_mul_restartable_internal(mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_ecp_restart_ctx * rs_ctx)2604 static int ecp_mul_restartable_internal(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2605 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2606 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
2607 mbedtls_ecp_restart_ctx *rs_ctx)
2608 {
2609 int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
2610 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2611 char is_grp_capable = 0;
2612 #endif
2613
2614 #if defined(MBEDTLS_ECP_RESTARTABLE)
2615 /* reset ops count for this call if top-level */
2616 if (rs_ctx != NULL && rs_ctx->depth++ == 0) {
2617 rs_ctx->ops_done = 0;
2618 }
2619 #else
2620 (void) rs_ctx;
2621 #endif
2622
2623 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2624 if ((is_grp_capable = mbedtls_internal_ecp_grp_capable(grp))) {
2625 MBEDTLS_MPI_CHK(mbedtls_internal_ecp_init(grp));
2626 }
2627 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
2628
2629 int restarting = 0;
2630 #if defined(MBEDTLS_ECP_RESTARTABLE)
2631 restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL);
2632 #endif
2633 /* skip argument check when restarting */
2634 if (!restarting) {
2635 /* check_privkey is free */
2636 MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_CHK);
2637
2638 /* Common sanity checks */
2639 MBEDTLS_MPI_CHK(mbedtls_ecp_check_privkey(grp, m));
2640 MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P));
2641 }
2642
2643 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
2644 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
2645 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
2646 MBEDTLS_MPI_CHK(ecp_mul_mxz(grp, R, m, P, f_rng, p_rng));
2647 }
2648 #endif
2649 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
2650 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
2651 MBEDTLS_MPI_CHK(ecp_mul_comb(grp, R, m, P, f_rng, p_rng, rs_ctx));
2652 }
2653 #endif
2654
2655 cleanup:
2656
2657 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2658 if (is_grp_capable) {
2659 mbedtls_internal_ecp_free(grp);
2660 }
2661 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
2662
2663 #if defined(MBEDTLS_ECP_RESTARTABLE)
2664 if (rs_ctx != NULL) {
2665 rs_ctx->depth--;
2666 }
2667 #endif
2668
2669 return ret;
2670 }
2671
2672 /*
2673 * Restartable multiplication R = m * P
2674 */
mbedtls_ecp_mul_restartable(mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_ecp_restart_ctx * rs_ctx)2675 int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2676 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2677 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
2678 mbedtls_ecp_restart_ctx *rs_ctx)
2679 {
2680 if (f_rng == NULL) {
2681 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
2682 }
2683
2684 return ecp_mul_restartable_internal(grp, R, m, P, f_rng, p_rng, rs_ctx);
2685 }
2686
2687 /*
2688 * Multiplication R = m * P
2689 */
mbedtls_ecp_mul(mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)2690 int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2691 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2692 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
2693 {
2694 return mbedtls_ecp_mul_restartable(grp, R, m, P, f_rng, p_rng, NULL);
2695 }
2696 #endif /* MBEDTLS_ECP_C */
2697
2698 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
2699 /*
2700 * Check that an affine point is valid as a public key,
2701 * short weierstrass curves (SEC1 3.2.3.1)
2702 */
ecp_check_pubkey_sw(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * pt)2703 static int ecp_check_pubkey_sw(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt)
2704 {
2705 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2706 mbedtls_mpi YY, RHS;
2707
2708 /* pt coordinates must be normalized for our checks */
2709 if (mbedtls_mpi_cmp_int(&pt->X, 0) < 0 ||
2710 mbedtls_mpi_cmp_int(&pt->Y, 0) < 0 ||
2711 mbedtls_mpi_cmp_mpi(&pt->X, &grp->P) >= 0 ||
2712 mbedtls_mpi_cmp_mpi(&pt->Y, &grp->P) >= 0) {
2713 return MBEDTLS_ERR_ECP_INVALID_KEY;
2714 }
2715
2716 mbedtls_mpi_init(&YY); mbedtls_mpi_init(&RHS);
2717
2718 /*
2719 * YY = Y^2
2720 * RHS = X^3 + A X + B
2721 */
2722 MPI_ECP_SQR(&YY, &pt->Y);
2723 MBEDTLS_MPI_CHK(ecp_sw_rhs(grp, &RHS, &pt->X));
2724
2725 if (MPI_ECP_CMP(&YY, &RHS) != 0) {
2726 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
2727 }
2728
2729 cleanup:
2730
2731 mbedtls_mpi_free(&YY); mbedtls_mpi_free(&RHS);
2732
2733 return ret;
2734 }
2735 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
2736
2737 #if defined(MBEDTLS_ECP_C)
2738 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
2739 /*
2740 * R = m * P with shortcuts for m == 0, m == 1 and m == -1
2741 * NOT constant-time - ONLY for short Weierstrass!
2742 */
mbedtls_ecp_mul_shortcuts(mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P,mbedtls_ecp_restart_ctx * rs_ctx)2743 static int mbedtls_ecp_mul_shortcuts(mbedtls_ecp_group *grp,
2744 mbedtls_ecp_point *R,
2745 const mbedtls_mpi *m,
2746 const mbedtls_ecp_point *P,
2747 mbedtls_ecp_restart_ctx *rs_ctx)
2748 {
2749 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2750 mbedtls_mpi tmp;
2751 mbedtls_mpi_init(&tmp);
2752
2753 if (mbedtls_mpi_cmp_int(m, 0) == 0) {
2754 MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P));
2755 MBEDTLS_MPI_CHK(mbedtls_ecp_set_zero(R));
2756 } else if (mbedtls_mpi_cmp_int(m, 1) == 0) {
2757 MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P));
2758 MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, P));
2759 } else if (mbedtls_mpi_cmp_int(m, -1) == 0) {
2760 MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P));
2761 MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, P));
2762 MPI_ECP_NEG(&R->Y);
2763 } else {
2764 MBEDTLS_MPI_CHK(ecp_mul_restartable_internal(grp, R, m, P,
2765 NULL, NULL, rs_ctx));
2766 }
2767
2768 cleanup:
2769 mbedtls_mpi_free(&tmp);
2770
2771 return ret;
2772 }
2773
2774 /*
2775 * Restartable linear combination
2776 * NOT constant-time
2777 */
mbedtls_ecp_muladd_restartable(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,mbedtls_ecp_restart_ctx * rs_ctx)2778 int mbedtls_ecp_muladd_restartable(
2779 mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2780 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2781 const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
2782 mbedtls_ecp_restart_ctx *rs_ctx)
2783 {
2784 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2785 mbedtls_ecp_point mP;
2786 mbedtls_ecp_point *pmP = &mP;
2787 mbedtls_ecp_point *pR = R;
2788 mbedtls_mpi tmp[4];
2789 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2790 char is_grp_capable = 0;
2791 #endif
2792 if (mbedtls_ecp_get_type(grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
2793 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
2794 }
2795
2796 mbedtls_ecp_point_init(&mP);
2797 mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi));
2798
2799 ECP_RS_ENTER(ma);
2800
2801 #if defined(MBEDTLS_ECP_RESTARTABLE)
2802 if (rs_ctx != NULL && rs_ctx->ma != NULL) {
2803 /* redirect intermediate results to restart context */
2804 pmP = &rs_ctx->ma->mP;
2805 pR = &rs_ctx->ma->R;
2806
2807 /* jump to next operation */
2808 if (rs_ctx->ma->state == ecp_rsma_mul2) {
2809 goto mul2;
2810 }
2811 if (rs_ctx->ma->state == ecp_rsma_add) {
2812 goto add;
2813 }
2814 if (rs_ctx->ma->state == ecp_rsma_norm) {
2815 goto norm;
2816 }
2817 }
2818 #endif /* MBEDTLS_ECP_RESTARTABLE */
2819
2820 MBEDTLS_MPI_CHK(mbedtls_ecp_mul_shortcuts(grp, pmP, m, P, rs_ctx));
2821 #if defined(MBEDTLS_ECP_RESTARTABLE)
2822 if (rs_ctx != NULL && rs_ctx->ma != NULL) {
2823 rs_ctx->ma->state = ecp_rsma_mul2;
2824 }
2825
2826 mul2:
2827 #endif
2828 MBEDTLS_MPI_CHK(mbedtls_ecp_mul_shortcuts(grp, pR, n, Q, rs_ctx));
2829
2830 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2831 if ((is_grp_capable = mbedtls_internal_ecp_grp_capable(grp))) {
2832 MBEDTLS_MPI_CHK(mbedtls_internal_ecp_init(grp));
2833 }
2834 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
2835
2836 #if defined(MBEDTLS_ECP_RESTARTABLE)
2837 if (rs_ctx != NULL && rs_ctx->ma != NULL) {
2838 rs_ctx->ma->state = ecp_rsma_add;
2839 }
2840
2841 add:
2842 #endif
2843 MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_ADD);
2844 MBEDTLS_MPI_CHK(ecp_add_mixed(grp, pR, pmP, pR, tmp));
2845 #if defined(MBEDTLS_ECP_RESTARTABLE)
2846 if (rs_ctx != NULL && rs_ctx->ma != NULL) {
2847 rs_ctx->ma->state = ecp_rsma_norm;
2848 }
2849
2850 norm:
2851 #endif
2852 MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV);
2853 MBEDTLS_MPI_CHK(ecp_normalize_jac(grp, pR));
2854
2855 #if defined(MBEDTLS_ECP_RESTARTABLE)
2856 if (rs_ctx != NULL && rs_ctx->ma != NULL) {
2857 MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, pR));
2858 }
2859 #endif
2860
2861 cleanup:
2862
2863 mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi));
2864
2865 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2866 if (is_grp_capable) {
2867 mbedtls_internal_ecp_free(grp);
2868 }
2869 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
2870
2871 mbedtls_ecp_point_free(&mP);
2872
2873 ECP_RS_LEAVE(ma);
2874
2875 return ret;
2876 }
2877
2878 /*
2879 * Linear combination
2880 * NOT constant-time
2881 */
mbedtls_ecp_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)2882 int mbedtls_ecp_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2883 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2884 const mbedtls_mpi *n, const mbedtls_ecp_point *Q)
2885 {
2886 return mbedtls_ecp_muladd_restartable(grp, R, m, P, n, Q, NULL);
2887 }
2888 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
2889 #endif /* MBEDTLS_ECP_C */
2890
2891 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
2892 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
2893 #define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n), .use_mempool = 0 }
2894 #define ECP_MPI_INIT_ARRAY(x) \
2895 ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint))
2896 /*
2897 * Constants for the two points other than 0, 1, -1 (mod p) in
2898 * https://cr.yp.to/ecdh.html#validate
2899 * See ecp_check_pubkey_x25519().
2900 */
2901 static const mbedtls_mpi_uint x25519_bad_point_1[] = {
2902 MBEDTLS_BYTES_TO_T_UINT_8(0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae),
2903 MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a),
2904 MBEDTLS_BYTES_TO_T_UINT_8(0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd),
2905 MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00),
2906 };
2907 static const mbedtls_mpi_uint x25519_bad_point_2[] = {
2908 MBEDTLS_BYTES_TO_T_UINT_8(0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24),
2909 MBEDTLS_BYTES_TO_T_UINT_8(0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b),
2910 MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86),
2911 MBEDTLS_BYTES_TO_T_UINT_8(0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57),
2912 };
2913 static const mbedtls_mpi ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY(
2914 x25519_bad_point_1);
2915 static const mbedtls_mpi ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY(
2916 x25519_bad_point_2);
2917 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
2918
2919 /*
2920 * Check that the input point is not one of the low-order points.
2921 * This is recommended by the "May the Fourth" paper:
2922 * https://eprint.iacr.org/2017/806.pdf
2923 * Those points are never sent by an honest peer.
2924 */
ecp_check_bad_points_mx(const mbedtls_mpi * X,const mbedtls_mpi * P,const mbedtls_ecp_group_id grp_id)2925 static int ecp_check_bad_points_mx(const mbedtls_mpi *X, const mbedtls_mpi *P,
2926 const mbedtls_ecp_group_id grp_id)
2927 {
2928 int ret;
2929 mbedtls_mpi XmP;
2930
2931 mbedtls_mpi_init(&XmP);
2932
2933 /* Reduce X mod P so that we only need to check values less than P.
2934 * We know X < 2^256 so we can proceed by subtraction. */
2935 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&XmP, X));
2936 while (mbedtls_mpi_cmp_mpi(&XmP, P) >= 0) {
2937 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&XmP, &XmP, P));
2938 }
2939
2940 /* Check against the known bad values that are less than P. For Curve448
2941 * these are 0, 1 and -1. For Curve25519 we check the values less than P
2942 * from the following list: https://cr.yp.to/ecdh.html#validate */
2943 if (mbedtls_mpi_cmp_int(&XmP, 1) <= 0) { /* takes care of 0 and 1 */
2944 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
2945 goto cleanup;
2946 }
2947
2948 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
2949 if (grp_id == MBEDTLS_ECP_DP_CURVE25519) {
2950 if (mbedtls_mpi_cmp_mpi(&XmP, &ecp_x25519_bad_point_1) == 0) {
2951 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
2952 goto cleanup;
2953 }
2954
2955 if (mbedtls_mpi_cmp_mpi(&XmP, &ecp_x25519_bad_point_2) == 0) {
2956 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
2957 goto cleanup;
2958 }
2959 }
2960 #else
2961 (void) grp_id;
2962 #endif
2963
2964 /* Final check: check if XmP + 1 is P (final because it changes XmP!) */
2965 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&XmP, &XmP, 1));
2966 if (mbedtls_mpi_cmp_mpi(&XmP, P) == 0) {
2967 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
2968 goto cleanup;
2969 }
2970
2971 ret = 0;
2972
2973 cleanup:
2974 mbedtls_mpi_free(&XmP);
2975
2976 return ret;
2977 }
2978
2979 /*
2980 * Check validity of a public key for Montgomery curves with x-only schemes
2981 */
ecp_check_pubkey_mx(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * pt)2982 static int ecp_check_pubkey_mx(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt)
2983 {
2984 /* [Curve25519 p. 5] Just check X is the correct number of bytes */
2985 /* Allow any public value, if it's too big then we'll just reduce it mod p
2986 * (RFC 7748 sec. 5 para. 3). */
2987 if (mbedtls_mpi_size(&pt->X) > (grp->nbits + 7) / 8) {
2988 return MBEDTLS_ERR_ECP_INVALID_KEY;
2989 }
2990
2991 /* Implicit in all standards (as they don't consider negative numbers):
2992 * X must be non-negative. This is normally ensured by the way it's
2993 * encoded for transmission, but let's be extra sure. */
2994 if (mbedtls_mpi_cmp_int(&pt->X, 0) < 0) {
2995 return MBEDTLS_ERR_ECP_INVALID_KEY;
2996 }
2997
2998 return ecp_check_bad_points_mx(&pt->X, &grp->P, grp->id);
2999 }
3000 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3001
3002 /*
3003 * Check that a point is valid as a public key
3004 */
mbedtls_ecp_check_pubkey(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * pt)3005 int mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp,
3006 const mbedtls_ecp_point *pt)
3007 {
3008 /* Must use affine coordinates */
3009 if (mbedtls_mpi_cmp_int(&pt->Z, 1) != 0) {
3010 return MBEDTLS_ERR_ECP_INVALID_KEY;
3011 }
3012
3013 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3014 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
3015 return ecp_check_pubkey_mx(grp, pt);
3016 }
3017 #endif
3018 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3019 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
3020 return ecp_check_pubkey_sw(grp, pt);
3021 }
3022 #endif
3023 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3024 }
3025
3026 /*
3027 * Check that an mbedtls_mpi is valid as a private key
3028 */
mbedtls_ecp_check_privkey(const mbedtls_ecp_group * grp,const mbedtls_mpi * d)3029 int mbedtls_ecp_check_privkey(const mbedtls_ecp_group *grp,
3030 const mbedtls_mpi *d)
3031 {
3032 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3033 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
3034 /* see RFC 7748 sec. 5 para. 5 */
3035 if (mbedtls_mpi_get_bit(d, 0) != 0 ||
3036 mbedtls_mpi_get_bit(d, 1) != 0 ||
3037 mbedtls_mpi_bitlen(d) != grp->nbits + 1) { /* mbedtls_mpi_bitlen is one-based! */
3038 return MBEDTLS_ERR_ECP_INVALID_KEY;
3039 }
3040
3041 /* see [Curve25519] page 5 */
3042 if (grp->nbits == 254 && mbedtls_mpi_get_bit(d, 2) != 0) {
3043 return MBEDTLS_ERR_ECP_INVALID_KEY;
3044 }
3045
3046 return 0;
3047 }
3048 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3049 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3050 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
3051 /* see SEC1 3.2 */
3052 if (mbedtls_mpi_cmp_int(d, 1) < 0 ||
3053 mbedtls_mpi_cmp_mpi(d, &grp->N) >= 0) {
3054 return MBEDTLS_ERR_ECP_INVALID_KEY;
3055 } else {
3056 return 0;
3057 }
3058 }
3059 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3060
3061 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3062 }
3063
3064 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3065 MBEDTLS_STATIC_TESTABLE
mbedtls_ecp_gen_privkey_mx(size_t high_bit,mbedtls_mpi * d,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)3066 int mbedtls_ecp_gen_privkey_mx(size_t high_bit,
3067 mbedtls_mpi *d,
3068 int (*f_rng)(void *, unsigned char *, size_t),
3069 void *p_rng)
3070 {
3071 int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3072 size_t n_random_bytes = high_bit / 8 + 1;
3073
3074 /* [Curve25519] page 5 */
3075 /* Generate a (high_bit+1)-bit random number by generating just enough
3076 * random bytes, then shifting out extra bits from the top (necessary
3077 * when (high_bit+1) is not a multiple of 8). */
3078 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(d, n_random_bytes,
3079 f_rng, p_rng));
3080 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(d, 8 * n_random_bytes - high_bit - 1));
3081
3082 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, high_bit, 1));
3083
3084 /* Make sure the last two bits are unset for Curve448, three bits for
3085 Curve25519 */
3086 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, 0, 0));
3087 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, 1, 0));
3088 if (high_bit == 254) {
3089 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, 2, 0));
3090 }
3091
3092 cleanup:
3093 return ret;
3094 }
3095 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3096
3097 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
mbedtls_ecp_gen_privkey_sw(const mbedtls_mpi * N,mbedtls_mpi * d,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)3098 static int mbedtls_ecp_gen_privkey_sw(
3099 const mbedtls_mpi *N, mbedtls_mpi *d,
3100 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
3101 {
3102 int ret = mbedtls_mpi_random(d, 1, N, f_rng, p_rng);
3103 switch (ret) {
3104 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
3105 return MBEDTLS_ERR_ECP_RANDOM_FAILED;
3106 default:
3107 return ret;
3108 }
3109 }
3110 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3111
3112 /*
3113 * Generate a private key
3114 */
mbedtls_ecp_gen_privkey(const mbedtls_ecp_group * grp,mbedtls_mpi * d,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)3115 int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp,
3116 mbedtls_mpi *d,
3117 int (*f_rng)(void *, unsigned char *, size_t),
3118 void *p_rng)
3119 {
3120 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3121 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
3122 return mbedtls_ecp_gen_privkey_mx(grp->nbits, d, f_rng, p_rng);
3123 }
3124 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3125
3126 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3127 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
3128 return mbedtls_ecp_gen_privkey_sw(&grp->N, d, f_rng, p_rng);
3129 }
3130 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3131
3132 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3133 }
3134
3135 #if defined(MBEDTLS_ECP_C)
3136 /*
3137 * Generate a keypair with configurable base point
3138 */
mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group * grp,const mbedtls_ecp_point * G,mbedtls_mpi * d,mbedtls_ecp_point * Q,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)3139 int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp,
3140 const mbedtls_ecp_point *G,
3141 mbedtls_mpi *d, mbedtls_ecp_point *Q,
3142 int (*f_rng)(void *, unsigned char *, size_t),
3143 void *p_rng)
3144 {
3145 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3146 MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng));
3147 MBEDTLS_MPI_CHK(mbedtls_ecp_mul(grp, Q, d, G, f_rng, p_rng));
3148
3149 cleanup:
3150 return ret;
3151 }
3152
3153 /*
3154 * Generate key pair, wrapper for conventional base point
3155 */
mbedtls_ecp_gen_keypair(mbedtls_ecp_group * grp,mbedtls_mpi * d,mbedtls_ecp_point * Q,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)3156 int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp,
3157 mbedtls_mpi *d, mbedtls_ecp_point *Q,
3158 int (*f_rng)(void *, unsigned char *, size_t),
3159 void *p_rng)
3160 {
3161 return mbedtls_ecp_gen_keypair_base(grp, &grp->G, d, Q, f_rng, p_rng);
3162 }
3163
3164 /*
3165 * Generate a keypair, prettier wrapper
3166 */
mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id,mbedtls_ecp_keypair * key,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)3167 int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
3168 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
3169 {
3170 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3171 if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) {
3172 return ret;
3173 }
3174
3175 return mbedtls_ecp_gen_keypair(&key->grp, &key->d, &key->Q, f_rng, p_rng);
3176 }
3177 #endif /* MBEDTLS_ECP_C */
3178
mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id,mbedtls_ecp_keypair * key,const mbedtls_ecp_point * Q)3179 int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id,
3180 mbedtls_ecp_keypair *key,
3181 const mbedtls_ecp_point *Q)
3182 {
3183 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3184
3185 if (key->grp.id == MBEDTLS_ECP_DP_NONE) {
3186 /* Group not set yet */
3187 if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) {
3188 return ret;
3189 }
3190 } else if (key->grp.id != grp_id) {
3191 /* Group mismatch */
3192 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3193 }
3194 return mbedtls_ecp_copy(&key->Q, Q);
3195 }
3196
3197
3198 #define ECP_CURVE25519_KEY_SIZE 32
3199 #define ECP_CURVE448_KEY_SIZE 56
3200 /*
3201 * Read a private key.
3202 */
mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id,mbedtls_ecp_keypair * key,const unsigned char * buf,size_t buflen)3203 int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
3204 const unsigned char *buf, size_t buflen)
3205 {
3206 int ret = 0;
3207
3208 if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) {
3209 return ret;
3210 }
3211
3212 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
3213
3214 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3215 if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
3216 /*
3217 * Mask the key as mandated by RFC7748 for Curve25519 and Curve448.
3218 */
3219 if (grp_id == MBEDTLS_ECP_DP_CURVE25519) {
3220 if (buflen != ECP_CURVE25519_KEY_SIZE) {
3221 return MBEDTLS_ERR_ECP_INVALID_KEY;
3222 }
3223
3224 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary_le(&key->d, buf, buflen));
3225
3226 /* Set the three least significant bits to 0 */
3227 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 0, 0));
3228 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 1, 0));
3229 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 2, 0));
3230
3231 /* Set the most significant bit to 0 */
3232 MBEDTLS_MPI_CHK(
3233 mbedtls_mpi_set_bit(&key->d,
3234 ECP_CURVE25519_KEY_SIZE * 8 - 1, 0)
3235 );
3236
3237 /* Set the second most significant bit to 1 */
3238 MBEDTLS_MPI_CHK(
3239 mbedtls_mpi_set_bit(&key->d,
3240 ECP_CURVE25519_KEY_SIZE * 8 - 2, 1)
3241 );
3242 } else if (grp_id == MBEDTLS_ECP_DP_CURVE448) {
3243 if (buflen != ECP_CURVE448_KEY_SIZE) {
3244 return MBEDTLS_ERR_ECP_INVALID_KEY;
3245 }
3246
3247 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary_le(&key->d, buf, buflen));
3248
3249 /* Set the two least significant bits to 0 */
3250 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 0, 0));
3251 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 1, 0));
3252
3253 /* Set the most significant bit to 1 */
3254 MBEDTLS_MPI_CHK(
3255 mbedtls_mpi_set_bit(&key->d,
3256 ECP_CURVE448_KEY_SIZE * 8 - 1, 1)
3257 );
3258 }
3259 }
3260 #endif
3261 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3262 if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
3263 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&key->d, buf, buflen));
3264 }
3265 #endif
3266
3267 if (ret == 0) {
3268 MBEDTLS_MPI_CHK(mbedtls_ecp_check_privkey(&key->grp, &key->d));
3269 }
3270
3271 cleanup:
3272
3273 if (ret != 0) {
3274 mbedtls_mpi_free(&key->d);
3275 }
3276
3277 return ret;
3278 }
3279
3280 /*
3281 * Write a private key.
3282 */
3283 #if !defined MBEDTLS_DEPRECATED_REMOVED
mbedtls_ecp_write_key(mbedtls_ecp_keypair * key,unsigned char * buf,size_t buflen)3284 int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
3285 unsigned char *buf, size_t buflen)
3286 {
3287 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3288
3289 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3290 if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
3291 if (key->grp.id == MBEDTLS_ECP_DP_CURVE25519) {
3292 if (buflen < ECP_CURVE25519_KEY_SIZE) {
3293 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
3294 }
3295
3296 } else if (key->grp.id == MBEDTLS_ECP_DP_CURVE448) {
3297 if (buflen < ECP_CURVE448_KEY_SIZE) {
3298 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
3299 }
3300 }
3301 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary_le(&key->d, buf, buflen));
3302 }
3303 #endif
3304 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3305 if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
3306 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&key->d, buf, buflen));
3307 }
3308
3309 #endif
3310 cleanup:
3311
3312 return ret;
3313 }
3314 #endif /* MBEDTLS_DEPRECATED_REMOVED */
3315
mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair * key,size_t * olen,unsigned char * buf,size_t buflen)3316 int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
3317 size_t *olen, unsigned char *buf, size_t buflen)
3318 {
3319 size_t len = (key->grp.nbits + 7) / 8;
3320 if (len > buflen) {
3321 /* For robustness, ensure *olen <= buflen even on error. */
3322 *olen = 0;
3323 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
3324 }
3325 *olen = len;
3326
3327 /* Private key not set */
3328 if (key->d.n == 0) {
3329 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3330 }
3331
3332 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3333 if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
3334 return mbedtls_mpi_write_binary_le(&key->d, buf, len);
3335 }
3336 #endif
3337
3338 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3339 if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
3340 return mbedtls_mpi_write_binary(&key->d, buf, len);
3341 }
3342 #endif
3343
3344 /* Private key set but no recognized curve type? This shouldn't happen. */
3345 return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3346 }
3347
3348 /*
3349 * Write a public key.
3350 */
mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair * key,int format,size_t * olen,unsigned char * buf,size_t buflen)3351 int mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair *key,
3352 int format, size_t *olen,
3353 unsigned char *buf, size_t buflen)
3354 {
3355 return mbedtls_ecp_point_write_binary(&key->grp, &key->Q,
3356 format, olen, buf, buflen);
3357 }
3358
3359
3360 #if defined(MBEDTLS_ECP_C)
3361 /*
3362 * Check a public-private key pair
3363 */
mbedtls_ecp_check_pub_priv(const mbedtls_ecp_keypair * pub,const mbedtls_ecp_keypair * prv,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)3364 int mbedtls_ecp_check_pub_priv(
3365 const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
3366 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
3367 {
3368 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3369 mbedtls_ecp_point Q;
3370 mbedtls_ecp_group grp;
3371 if (pub->grp.id == MBEDTLS_ECP_DP_NONE ||
3372 pub->grp.id != prv->grp.id ||
3373 mbedtls_mpi_cmp_mpi(&pub->Q.X, &prv->Q.X) ||
3374 mbedtls_mpi_cmp_mpi(&pub->Q.Y, &prv->Q.Y) ||
3375 mbedtls_mpi_cmp_mpi(&pub->Q.Z, &prv->Q.Z)) {
3376 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3377 }
3378
3379 mbedtls_ecp_point_init(&Q);
3380 mbedtls_ecp_group_init(&grp);
3381
3382 /* mbedtls_ecp_mul() needs a non-const group... */
3383 mbedtls_ecp_group_copy(&grp, &prv->grp);
3384
3385 /* Also checks d is valid */
3386 MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&grp, &Q, &prv->d, &prv->grp.G, f_rng, p_rng));
3387
3388 if (mbedtls_mpi_cmp_mpi(&Q.X, &prv->Q.X) ||
3389 mbedtls_mpi_cmp_mpi(&Q.Y, &prv->Q.Y) ||
3390 mbedtls_mpi_cmp_mpi(&Q.Z, &prv->Q.Z)) {
3391 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3392 goto cleanup;
3393 }
3394
3395 cleanup:
3396 mbedtls_ecp_point_free(&Q);
3397 mbedtls_ecp_group_free(&grp);
3398
3399 return ret;
3400 }
3401
mbedtls_ecp_keypair_calc_public(mbedtls_ecp_keypair * key,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)3402 int mbedtls_ecp_keypair_calc_public(mbedtls_ecp_keypair *key,
3403 int (*f_rng)(void *, unsigned char *, size_t),
3404 void *p_rng)
3405 {
3406 return mbedtls_ecp_mul(&key->grp, &key->Q, &key->d, &key->grp.G,
3407 f_rng, p_rng);
3408 }
3409 #endif /* MBEDTLS_ECP_C */
3410
mbedtls_ecp_keypair_get_group_id(const mbedtls_ecp_keypair * key)3411 mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id(
3412 const mbedtls_ecp_keypair *key)
3413 {
3414 return key->grp.id;
3415 }
3416
3417 /*
3418 * Export generic key-pair parameters.
3419 */
mbedtls_ecp_export(const mbedtls_ecp_keypair * key,mbedtls_ecp_group * grp,mbedtls_mpi * d,mbedtls_ecp_point * Q)3420 int mbedtls_ecp_export(const mbedtls_ecp_keypair *key, mbedtls_ecp_group *grp,
3421 mbedtls_mpi *d, mbedtls_ecp_point *Q)
3422 {
3423 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3424
3425 if (grp != NULL && (ret = mbedtls_ecp_group_copy(grp, &key->grp)) != 0) {
3426 return ret;
3427 }
3428
3429 if (d != NULL && (ret = mbedtls_mpi_copy(d, &key->d)) != 0) {
3430 return ret;
3431 }
3432
3433 if (Q != NULL && (ret = mbedtls_ecp_copy(Q, &key->Q)) != 0) {
3434 return ret;
3435 }
3436
3437 return 0;
3438 }
3439
3440 #if defined(MBEDTLS_SELF_TEST)
3441
3442 #if defined(MBEDTLS_ECP_C)
3443 /*
3444 * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
3445 *
3446 * This is the linear congruential generator from numerical recipes,
3447 * except we only use the low byte as the output. See
3448 * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
3449 */
self_test_rng(void * ctx,unsigned char * out,size_t len)3450 static int self_test_rng(void *ctx, unsigned char *out, size_t len)
3451 {
3452 static uint32_t state = 42;
3453
3454 (void) ctx;
3455
3456 for (size_t i = 0; i < len; i++) {
3457 state = state * 1664525u + 1013904223u;
3458 out[i] = (unsigned char) state;
3459 }
3460
3461 return 0;
3462 }
3463
3464 /* Adjust the exponent to be a valid private point for the specified curve.
3465 * This is sometimes necessary because we use a single set of exponents
3466 * for all curves but the validity of values depends on the curve. */
self_test_adjust_exponent(const mbedtls_ecp_group * grp,mbedtls_mpi * m)3467 static int self_test_adjust_exponent(const mbedtls_ecp_group *grp,
3468 mbedtls_mpi *m)
3469 {
3470 int ret = 0;
3471 switch (grp->id) {
3472 /* If Curve25519 is available, then that's what we use for the
3473 * Montgomery test, so we don't need the adjustment code. */
3474 #if !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
3475 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
3476 case MBEDTLS_ECP_DP_CURVE448:
3477 /* Move highest bit from 254 to N-1. Setting bit N-1 is
3478 * necessary to enforce the highest-bit-set constraint. */
3479 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(m, 254, 0));
3480 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(m, grp->nbits, 1));
3481 /* Copy second-highest bit from 253 to N-2. This is not
3482 * necessary but improves the test variety a bit. */
3483 MBEDTLS_MPI_CHK(
3484 mbedtls_mpi_set_bit(m, grp->nbits - 1,
3485 mbedtls_mpi_get_bit(m, 253)));
3486 break;
3487 #endif
3488 #endif /* ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) */
3489 default:
3490 /* Non-Montgomery curves and Curve25519 need no adjustment. */
3491 (void) grp;
3492 (void) m;
3493 goto cleanup;
3494 }
3495 cleanup:
3496 return ret;
3497 }
3498
3499 /* Calculate R = m.P for each m in exponents. Check that the number of
3500 * basic operations doesn't depend on the value of m. */
self_test_point(int verbose,mbedtls_ecp_group * grp,mbedtls_ecp_point * R,mbedtls_mpi * m,const mbedtls_ecp_point * P,const char * const * exponents,size_t n_exponents)3501 static int self_test_point(int verbose,
3502 mbedtls_ecp_group *grp,
3503 mbedtls_ecp_point *R,
3504 mbedtls_mpi *m,
3505 const mbedtls_ecp_point *P,
3506 const char *const *exponents,
3507 size_t n_exponents)
3508 {
3509 int ret = 0;
3510 size_t i = 0;
3511 unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
3512 add_count = 0;
3513 dbl_count = 0;
3514 mul_count = 0;
3515
3516 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(m, 16, exponents[0]));
3517 MBEDTLS_MPI_CHK(self_test_adjust_exponent(grp, m));
3518 MBEDTLS_MPI_CHK(mbedtls_ecp_mul(grp, R, m, P, self_test_rng, NULL));
3519
3520 for (i = 1; i < n_exponents; i++) {
3521 add_c_prev = add_count;
3522 dbl_c_prev = dbl_count;
3523 mul_c_prev = mul_count;
3524 add_count = 0;
3525 dbl_count = 0;
3526 mul_count = 0;
3527
3528 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(m, 16, exponents[i]));
3529 MBEDTLS_MPI_CHK(self_test_adjust_exponent(grp, m));
3530 MBEDTLS_MPI_CHK(mbedtls_ecp_mul(grp, R, m, P, self_test_rng, NULL));
3531
3532 if (add_count != add_c_prev ||
3533 dbl_count != dbl_c_prev ||
3534 mul_count != mul_c_prev) {
3535 ret = 1;
3536 break;
3537 }
3538 }
3539
3540 cleanup:
3541 if (verbose != 0) {
3542 if (ret != 0) {
3543 mbedtls_printf("failed (%u)\n", (unsigned int) i);
3544 } else {
3545 mbedtls_printf("passed\n");
3546 }
3547 }
3548 return ret;
3549 }
3550 #endif /* MBEDTLS_ECP_C */
3551
3552 /*
3553 * Checkup routine
3554 */
mbedtls_ecp_self_test(int verbose)3555 int mbedtls_ecp_self_test(int verbose)
3556 {
3557 #if defined(MBEDTLS_ECP_C)
3558 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3559 mbedtls_ecp_group grp;
3560 mbedtls_ecp_point R, P;
3561 mbedtls_mpi m;
3562
3563 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3564 /* Exponents especially adapted for secp192k1, which has the lowest
3565 * order n of all supported curves (secp192r1 is in a slightly larger
3566 * field but the order of its base point is slightly smaller). */
3567 const char *sw_exponents[] =
3568 {
3569 "000000000000000000000000000000000000000000000001", /* one */
3570 "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8C", /* n - 1 */
3571 "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
3572 "400000000000000000000000000000000000000000000000", /* one and zeros */
3573 "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */
3574 "555555555555555555555555555555555555555555555555", /* 101010... */
3575 };
3576 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3577 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3578 const char *m_exponents[] =
3579 {
3580 /* Valid private values for Curve25519. In a build with Curve448
3581 * but not Curve25519, they will be adjusted in
3582 * self_test_adjust_exponent(). */
3583 "4000000000000000000000000000000000000000000000000000000000000000",
3584 "5C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C30",
3585 "5715ECCE24583F7A7023C24164390586842E816D7280A49EF6DF4EAE6B280BF8",
3586 "41A2B017516F6D254E1F002BCCBADD54BE30F8CEC737A0E912B4963B6BA74460",
3587 "5555555555555555555555555555555555555555555555555555555555555550",
3588 "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8",
3589 };
3590 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3591
3592 mbedtls_ecp_group_init(&grp);
3593 mbedtls_ecp_point_init(&R);
3594 mbedtls_ecp_point_init(&P);
3595 mbedtls_mpi_init(&m);
3596
3597 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3598 /* Use secp192r1 if available, or any available curve */
3599 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
3600 MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP192R1));
3601 #else
3602 MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, mbedtls_ecp_curve_list()->grp_id));
3603 #endif
3604
3605 if (verbose != 0) {
3606 mbedtls_printf(" ECP SW test #1 (constant op_count, base point G): ");
3607 }
3608 /* Do a dummy multiplication first to trigger precomputation */
3609 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&m, 2));
3610 MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&grp, &P, &m, &grp.G, self_test_rng, NULL));
3611 ret = self_test_point(verbose,
3612 &grp, &R, &m, &grp.G,
3613 sw_exponents,
3614 sizeof(sw_exponents) / sizeof(sw_exponents[0]));
3615 if (ret != 0) {
3616 goto cleanup;
3617 }
3618
3619 if (verbose != 0) {
3620 mbedtls_printf(" ECP SW test #2 (constant op_count, other point): ");
3621 }
3622 /* We computed P = 2G last time, use it */
3623 ret = self_test_point(verbose,
3624 &grp, &R, &m, &P,
3625 sw_exponents,
3626 sizeof(sw_exponents) / sizeof(sw_exponents[0]));
3627 if (ret != 0) {
3628 goto cleanup;
3629 }
3630
3631 mbedtls_ecp_group_free(&grp);
3632 mbedtls_ecp_point_free(&R);
3633 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3634
3635 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3636 if (verbose != 0) {
3637 mbedtls_printf(" ECP Montgomery test (constant op_count): ");
3638 }
3639 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
3640 MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_CURVE25519));
3641 #elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
3642 MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_CURVE448));
3643 #else
3644 #error "MBEDTLS_ECP_MONTGOMERY_ENABLED is defined, but no curve is supported for self-test"
3645 #endif
3646 ret = self_test_point(verbose,
3647 &grp, &R, &m, &grp.G,
3648 m_exponents,
3649 sizeof(m_exponents) / sizeof(m_exponents[0]));
3650 if (ret != 0) {
3651 goto cleanup;
3652 }
3653 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3654
3655 cleanup:
3656
3657 if (ret < 0 && verbose != 0) {
3658 mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret);
3659 }
3660
3661 mbedtls_ecp_group_free(&grp);
3662 mbedtls_ecp_point_free(&R);
3663 mbedtls_ecp_point_free(&P);
3664 mbedtls_mpi_free(&m);
3665
3666 if (verbose != 0) {
3667 mbedtls_printf("\n");
3668 }
3669
3670 return ret;
3671 #else /* MBEDTLS_ECP_C */
3672 (void) verbose;
3673 return 0;
3674 #endif /* MBEDTLS_ECP_C */
3675 }
3676
3677 #endif /* MBEDTLS_SELF_TEST */
3678
3679 #endif /* !MBEDTLS_ECP_ALT */
3680
3681 #endif /* MBEDTLS_ECP_LIGHT */
3682