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