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