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     buf[0] = curve_info->tls_id >> 8;
1164     buf[1] = curve_info->tls_id & 0xFF;
1165 
1166     return( 0 );
1167 }
1168 
1169 /*
1170  * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi.
1171  * See the documentation of struct mbedtls_ecp_group.
1172  *
1173  * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf.
1174  */
ecp_modp(mbedtls_mpi * N,const mbedtls_ecp_group * grp)1175 static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp )
1176 {
1177     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1178 
1179     if( grp->modp == NULL )
1180         return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) );
1181 
1182     /* N->s < 0 is a much faster test, which fails only if N is 0 */
1183     if( ( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) ||
1184         mbedtls_mpi_bitlen( N ) > 2 * grp->pbits )
1185     {
1186         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1187     }
1188 
1189     MBEDTLS_MPI_CHK( grp->modp( N ) );
1190 
1191     /* N->s < 0 is a much faster test, which fails only if N is 0 */
1192     while( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 )
1193         MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &grp->P ) );
1194 
1195     while( mbedtls_mpi_cmp_mpi( N, &grp->P ) >= 0 )
1196         /* we known P, N and the result are positive */
1197         MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, N, &grp->P ) );
1198 
1199 cleanup:
1200     return( ret );
1201 }
1202 
1203 /*
1204  * Fast mod-p functions expect their argument to be in the 0..p^2 range.
1205  *
1206  * In order to guarantee that, we need to ensure that operands of
1207  * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will
1208  * bring the result back to this range.
1209  *
1210  * The following macros are shortcuts for doing that.
1211  */
1212 
1213 /*
1214  * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi
1215  */
1216 #if defined(MBEDTLS_SELF_TEST)
1217 #define INC_MUL_COUNT   mul_count++;
1218 #else
1219 #define INC_MUL_COUNT
1220 #endif
1221 
1222 #define MOD_MUL( N )                                                    \
1223     do                                                                  \
1224     {                                                                   \
1225         MBEDTLS_MPI_CHK( ecp_modp( &(N), grp ) );                       \
1226         INC_MUL_COUNT                                                   \
1227     } while( 0 )
1228 
mbedtls_mpi_mul_mod(const mbedtls_ecp_group * grp,mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1229 static inline int mbedtls_mpi_mul_mod( const mbedtls_ecp_group *grp,
1230                                        mbedtls_mpi *X,
1231                                        const mbedtls_mpi *A,
1232                                        const mbedtls_mpi *B )
1233 {
1234     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1235     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( X, A, B ) );
1236     MOD_MUL( *X );
1237 cleanup:
1238     return( ret );
1239 }
1240 
1241 /*
1242  * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi
1243  * N->s < 0 is a very fast test, which fails only if N is 0
1244  */
1245 #define MOD_SUB( N )                                                    \
1246     while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 )           \
1247         MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) )
1248 
1249 #if ( defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \
1250       !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
1251          defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && \
1252          defined(MBEDTLS_ECP_ADD_MIXED_ALT) ) ) || \
1253     ( defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) && \
1254       !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
1255          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)1256 static inline int mbedtls_mpi_sub_mod( const mbedtls_ecp_group *grp,
1257                                        mbedtls_mpi *X,
1258                                        const mbedtls_mpi *A,
1259                                        const mbedtls_mpi *B )
1260 {
1261     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1262     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( X, A, B ) );
1263     MOD_SUB( *X );
1264 cleanup:
1265     return( ret );
1266 }
1267 #endif /* All functions referencing mbedtls_mpi_sub_mod() are alt-implemented without fallback */
1268 
1269 /*
1270  * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int.
1271  * We known P, N and the result are positive, so sub_abs is correct, and
1272  * a bit faster.
1273  */
1274 #define MOD_ADD( N )                                                    \
1275     while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 )                  \
1276         MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) )
1277 
mbedtls_mpi_add_mod(const mbedtls_ecp_group * grp,mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1278 static inline int mbedtls_mpi_add_mod( const mbedtls_ecp_group *grp,
1279                                        mbedtls_mpi *X,
1280                                        const mbedtls_mpi *A,
1281                                        const mbedtls_mpi *B )
1282 {
1283     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1284     MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, A, B ) );
1285     MOD_ADD( *X );
1286 cleanup:
1287     return( ret );
1288 }
1289 
1290 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \
1291     !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
1292        defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && \
1293        defined(MBEDTLS_ECP_ADD_MIXED_ALT) )
mbedtls_mpi_shift_l_mod(const mbedtls_ecp_group * grp,mbedtls_mpi * X,size_t count)1294 static inline int mbedtls_mpi_shift_l_mod( const mbedtls_ecp_group *grp,
1295                                            mbedtls_mpi *X,
1296                                            size_t count )
1297 {
1298     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1299     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( X, count ) );
1300     MOD_ADD( *X );
1301 cleanup:
1302     return( ret );
1303 }
1304 #endif /* All functions referencing mbedtls_mpi_shift_l_mod() are alt-implemented without fallback */
1305 
1306 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
1307 /*
1308  * For curves in short Weierstrass form, we do all the internal operations in
1309  * Jacobian coordinates.
1310  *
1311  * For multiplication, we'll use a comb method with coutermeasueres against
1312  * SPA, hence timing attacks.
1313  */
1314 
1315 /*
1316  * Normalize jacobian coordinates so that Z == 0 || Z == 1  (GECC 3.2.1)
1317  * Cost: 1N := 1I + 3M + 1S
1318  */
ecp_normalize_jac(const mbedtls_ecp_group * grp,mbedtls_ecp_point * pt)1319 static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt )
1320 {
1321     if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 )
1322         return( 0 );
1323 
1324 #if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
1325     if( mbedtls_internal_ecp_grp_capable( grp ) )
1326         return( mbedtls_internal_ecp_normalize_jac( grp, pt ) );
1327 #endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */
1328 
1329 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
1330     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
1331 #else
1332     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1333     mbedtls_mpi Zi, ZZi;
1334     mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
1335 
1336     /*
1337      * X = X / Z^2  mod p
1338      */
1339     MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi,      &pt->Z,     &grp->P ) );
1340     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi,     &Zi,        &Zi     ) );
1341     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X,   &pt->X,     &ZZi    ) );
1342 
1343     /*
1344      * Y = Y / Z^3  mod p
1345      */
1346     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y,   &pt->Y,     &ZZi    ) );
1347     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y,   &pt->Y,     &Zi     ) );
1348 
1349     /*
1350      * Z = 1
1351      */
1352     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
1353 
1354 cleanup:
1355 
1356     mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
1357 
1358     return( ret );
1359 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) */
1360 }
1361 
1362 /*
1363  * Normalize jacobian coordinates of an array of (pointers to) points,
1364  * using Montgomery's trick to perform only one inversion mod P.
1365  * (See for example Cohen's "A Course in Computational Algebraic Number
1366  * Theory", Algorithm 10.3.4.)
1367  *
1368  * Warning: fails (returning an error) if one of the points is zero!
1369  * This should never happen, see choice of w in ecp_mul_comb().
1370  *
1371  * Cost: 1N(t) := 1I + (6t - 3)M + 1S
1372  */
ecp_normalize_jac_many(const mbedtls_ecp_group * grp,mbedtls_ecp_point * T[],size_t T_size)1373 static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
1374                                    mbedtls_ecp_point *T[], size_t T_size )
1375 {
1376     if( T_size < 2 )
1377         return( ecp_normalize_jac( grp, *T ) );
1378 
1379 #if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
1380     if( mbedtls_internal_ecp_grp_capable( grp ) )
1381         return( mbedtls_internal_ecp_normalize_jac_many( grp, T, T_size ) );
1382 #endif
1383 
1384 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
1385     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
1386 #else
1387     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1388     size_t i;
1389     mbedtls_mpi *c, u, Zi, ZZi;
1390 
1391     if( ( c = mbedtls_calloc( T_size, sizeof( mbedtls_mpi ) ) ) == NULL )
1392         return( MBEDTLS_ERR_ECP_ALLOC_FAILED );
1393 
1394     for( i = 0; i < T_size; i++ )
1395         mbedtls_mpi_init( &c[i] );
1396 
1397     mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
1398 
1399     /*
1400      * c[i] = Z_0 * ... * Z_i
1401      */
1402     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) );
1403     for( i = 1; i < T_size; i++ )
1404     {
1405         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &c[i], &c[i-1], &T[i]->Z ) );
1406     }
1407 
1408     /*
1409      * u = 1 / (Z_0 * ... * Z_n) mod P
1410      */
1411     MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[T_size-1], &grp->P ) );
1412 
1413     for( i = T_size - 1; ; i-- )
1414     {
1415         /*
1416          * Zi = 1 / Z_i mod p
1417          * u = 1 / (Z_0 * ... * Z_i) mod P
1418          */
1419         if( i == 0 ) {
1420             MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Zi, &u ) );
1421         }
1422         else
1423         {
1424             MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Zi, &u, &c[i-1]  ) );
1425             MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &u,  &u, &T[i]->Z ) );
1426         }
1427 
1428         /*
1429          * proceed as in normalize()
1430          */
1431         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi,     &Zi,      &Zi  ) );
1432         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->X, &T[i]->X, &ZZi ) );
1433         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &ZZi ) );
1434         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &Zi  ) );
1435 
1436         /*
1437          * Post-precessing: reclaim some memory by shrinking coordinates
1438          * - not storing Z (always 1)
1439          * - shrinking other coordinates, but still keeping the same number of
1440          *   limbs as P, as otherwise it will too likely be regrown too fast.
1441          */
1442         MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->X, grp->P.n ) );
1443         MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->Y, grp->P.n ) );
1444         mbedtls_mpi_free( &T[i]->Z );
1445 
1446         if( i == 0 )
1447             break;
1448     }
1449 
1450 cleanup:
1451 
1452     mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
1453     for( i = 0; i < T_size; i++ )
1454         mbedtls_mpi_free( &c[i] );
1455     mbedtls_free( c );
1456 
1457     return( ret );
1458 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) */
1459 }
1460 
1461 /*
1462  * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak.
1463  * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid
1464  */
ecp_safe_invert_jac(const mbedtls_ecp_group * grp,mbedtls_ecp_point * Q,unsigned char inv)1465 static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp,
1466                             mbedtls_ecp_point *Q,
1467                             unsigned char inv )
1468 {
1469     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1470     unsigned char nonzero;
1471     mbedtls_mpi mQY;
1472 
1473     mbedtls_mpi_init( &mQY );
1474 
1475     /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */
1476     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) );
1477     nonzero = mbedtls_mpi_cmp_int( &Q->Y, 0 ) != 0;
1478     MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) );
1479 
1480 cleanup:
1481     mbedtls_mpi_free( &mQY );
1482 
1483     return( ret );
1484 }
1485 
1486 /*
1487  * Point doubling R = 2 P, Jacobian coordinates
1488  *
1489  * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 .
1490  *
1491  * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR
1492  * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring.
1493  *
1494  * Standard optimizations are applied when curve parameter A is one of { 0, -3 }.
1495  *
1496  * Cost: 1D := 3M + 4S          (A ==  0)
1497  *             4M + 4S          (A == -3)
1498  *             3M + 6S + 1a     otherwise
1499  */
ecp_double_jac(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_ecp_point * P)1500 static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1501                            const mbedtls_ecp_point *P )
1502 {
1503 #if defined(MBEDTLS_SELF_TEST)
1504     dbl_count++;
1505 #endif
1506 
1507 #if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
1508     if( mbedtls_internal_ecp_grp_capable( grp ) )
1509         return( mbedtls_internal_ecp_double_jac( grp, R, P ) );
1510 #endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */
1511 
1512 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
1513     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
1514 #else
1515     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1516     mbedtls_mpi M, S, T, U;
1517 
1518     mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U );
1519 
1520     /* Special case for A = -3 */
1521     if( grp->A.p == NULL )
1522     {
1523         /* M = 3(X + Z^2)(X - Z^2) */
1524         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &P->Z,  &P->Z   ) );
1525         MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &T,  &P->X,  &S      ) );
1526         MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &U,  &P->X,  &S      ) );
1527         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &T,     &U      ) );
1528         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M,  &S,     3       ) ); MOD_ADD( M );
1529     }
1530     else
1531     {
1532         /* M = 3.X^2 */
1533         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &P->X,  &P->X   ) );
1534         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M,  &S,     3       ) ); MOD_ADD( M );
1535 
1536         /* Optimize away for "koblitz" curves with A = 0 */
1537         if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 )
1538         {
1539             /* M += A.Z^4 */
1540             MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &P->Z,  &P->Z   ) );
1541             MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T,  &S,     &S      ) );
1542             MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &T,     &grp->A ) );
1543             MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &M,  &M,     &S      ) );
1544         }
1545     }
1546 
1547     /* S = 4.X.Y^2 */
1548     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T,  &P->Y,  &P->Y   ) );
1549     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T,  1               ) );
1550     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &P->X,  &T      ) );
1551     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &S,  1               ) );
1552 
1553     /* U = 8.Y^4 */
1554     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U,  &T,     &T      ) );
1555     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U,  1               ) );
1556 
1557     /* T = M^2 - 2.S */
1558     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T,  &M,     &M      ) );
1559     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T,  &T,     &S      ) );
1560     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T,  &T,     &S      ) );
1561 
1562     /* S = M(S - T) - U */
1563     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S,  &S,     &T      ) );
1564     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S,  &S,     &M      ) );
1565     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S,  &S,     &U      ) );
1566 
1567     /* U = 2.Y.Z */
1568     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U,  &P->Y,  &P->Z   ) );
1569     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U,  1               ) );
1570 
1571     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) );
1572     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) );
1573     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &U ) );
1574 
1575 cleanup:
1576     mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U );
1577 
1578     return( ret );
1579 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) */
1580 }
1581 
1582 /*
1583  * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22)
1584  *
1585  * The coordinates of Q must be normalized (= affine),
1586  * but those of P don't need to. R is not normalized.
1587  *
1588  * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q.
1589  * None of these cases can happen as intermediate step in ecp_mul_comb():
1590  * - at each step, P, Q and R are multiples of the base point, the factor
1591  *   being less than its order, so none of them is zero;
1592  * - Q is an odd multiple of the base point, P an even multiple,
1593  *   due to the choice of precomputed points in the modified comb method.
1594  * So branches for these cases do not leak secret information.
1595  *
1596  * We accept Q->Z being unset (saving memory in tables) as meaning 1.
1597  *
1598  * Cost: 1A := 8M + 3S
1599  */
ecp_add_mixed(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_ecp_point * P,const mbedtls_ecp_point * Q)1600 static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1601                           const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
1602 {
1603 #if defined(MBEDTLS_SELF_TEST)
1604     add_count++;
1605 #endif
1606 
1607 #if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
1608     if( mbedtls_internal_ecp_grp_capable( grp ) )
1609         return( mbedtls_internal_ecp_add_mixed( grp, R, P, Q ) );
1610 #endif /* MBEDTLS_ECP_ADD_MIXED_ALT */
1611 
1612 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_ADD_MIXED_ALT)
1613     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
1614 #else
1615     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1616     mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
1617 
1618     /*
1619      * Trivial cases: P == 0 or Q == 0 (case 1)
1620      */
1621     if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
1622         return( mbedtls_ecp_copy( R, Q ) );
1623 
1624     if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 0 ) == 0 )
1625         return( mbedtls_ecp_copy( R, P ) );
1626 
1627     /*
1628      * Make sure Q coordinates are normalized
1629      */
1630     if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 1 ) != 0 )
1631         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1632 
1633     mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 );
1634     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
1635 
1636     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1,  &P->Z,  &P->Z ) );
1637     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2,  &T1,    &P->Z ) );
1638     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1,  &T1,    &Q->X ) );
1639     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2,  &T2,    &Q->Y ) );
1640     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T1,  &T1,    &P->X ) );
1641     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T2,  &T2,    &P->Y ) );
1642 
1643     /* Special cases (2) and (3) */
1644     if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 )
1645     {
1646         if( mbedtls_mpi_cmp_int( &T2, 0 ) == 0 )
1647         {
1648             ret = ecp_double_jac( grp, R, P );
1649             goto cleanup;
1650         }
1651         else
1652         {
1653             ret = mbedtls_ecp_set_zero( R );
1654             goto cleanup;
1655         }
1656     }
1657 
1658     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Z,   &P->Z,  &T1   ) );
1659     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3,  &T1,    &T1   ) );
1660     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4,  &T3,    &T1   ) );
1661     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3,  &T3,    &P->X ) );
1662     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &T3 ) );
1663     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T1,  1     ) );
1664     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &X,   &T2,    &T2   ) );
1665     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X,   &X,     &T1   ) );
1666     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X,   &X,     &T4   ) );
1667     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T3,  &T3,    &X    ) );
1668     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3,  &T3,    &T2   ) );
1669     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4,  &T4,    &P->Y ) );
1670     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &Y,   &T3,    &T4   ) );
1671 
1672     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) );
1673     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) );
1674     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) );
1675 
1676 cleanup:
1677 
1678     mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 );
1679     mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
1680 
1681     return( ret );
1682 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_ADD_MIXED_ALT) */
1683 }
1684 
1685 /*
1686  * Randomize jacobian coordinates:
1687  * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l
1688  * This is sort of the reverse operation of ecp_normalize_jac().
1689  *
1690  * This countermeasure was first suggested in [2].
1691  */
ecp_randomize_jac(const mbedtls_ecp_group * grp,mbedtls_ecp_point * pt,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1692 static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
1693                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1694 {
1695 #if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
1696     if( mbedtls_internal_ecp_grp_capable( grp ) )
1697         return( mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ) );
1698 #endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */
1699 
1700 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
1701     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
1702 #else
1703     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1704     mbedtls_mpi l, ll;
1705 
1706     mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll );
1707 
1708     /* Generate l such that 1 < l < p */
1709     MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
1710 
1711     /* Z = l * Z */
1712     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Z,   &pt->Z,     &l  ) );
1713 
1714     /* X = l^2 * X */
1715     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll,      &l,         &l  ) );
1716     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X,   &pt->X,     &ll ) );
1717 
1718     /* Y = l^3 * Y */
1719     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll,      &ll,        &l  ) );
1720     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y,   &pt->Y,     &ll ) );
1721 
1722 cleanup:
1723     mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll );
1724 
1725     if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
1726         ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
1727     return( ret );
1728 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) */
1729 }
1730 
1731 /*
1732  * Check and define parameters used by the comb method (see below for details)
1733  */
1734 #if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7
1735 #error "MBEDTLS_ECP_WINDOW_SIZE out of bounds"
1736 #endif
1737 
1738 /* d = ceil( n / w ) */
1739 #define COMB_MAX_D      ( MBEDTLS_ECP_MAX_BITS + 1 ) / 2
1740 
1741 /* number of precomputed points */
1742 #define COMB_MAX_PRE    ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
1743 
1744 /*
1745  * Compute the representation of m that will be used with our comb method.
1746  *
1747  * The basic comb method is described in GECC 3.44 for example. We use a
1748  * modified version that provides resistance to SPA by avoiding zero
1749  * digits in the representation as in [3]. We modify the method further by
1750  * requiring that all K_i be odd, which has the small cost that our
1751  * representation uses one more K_i, due to carries, but saves on the size of
1752  * the precomputed table.
1753  *
1754  * Summary of the comb method and its modifications:
1755  *
1756  * - The goal is to compute m*P for some w*d-bit integer m.
1757  *
1758  * - The basic comb method splits m into the w-bit integers
1759  *   x[0] .. x[d-1] where x[i] consists of the bits in m whose
1760  *   index has residue i modulo d, and computes m * P as
1761  *   S[x[0]] + 2 * S[x[1]] + .. + 2^(d-1) S[x[d-1]], where
1762  *   S[i_{w-1} .. i_0] := i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + i_0 P.
1763  *
1764  * - If it happens that, say, x[i+1]=0 (=> S[x[i+1]]=0), one can replace the sum by
1765  *    .. + 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]] ..,
1766  *   thereby successively converting it into a form where all summands
1767  *   are nonzero, at the cost of negative summands. This is the basic idea of [3].
1768  *
1769  * - More generally, even if x[i+1] != 0, we can first transform the sum as
1770  *   .. - 2^i S[x[i]] + 2^{i+1} ( S[x[i]] + S[x[i+1]] ) + 2^{i+2} S[x[i+2]] ..,
1771  *   and then replace S[x[i]] + S[x[i+1]] = S[x[i] ^ x[i+1]] + 2 S[x[i] & x[i+1]].
1772  *   Performing and iterating this procedure for those x[i] that are even
1773  *   (keeping track of carry), we can transform the original sum into one of the form
1774  *   S[x'[0]] +- 2 S[x'[1]] +- .. +- 2^{d-1} S[x'[d-1]] + 2^d S[x'[d]]
1775  *   with all x'[i] odd. It is therefore only necessary to know S at odd indices,
1776  *   which is why we are only computing half of it in the first place in
1777  *   ecp_precompute_comb and accessing it with index abs(i) / 2 in ecp_select_comb.
1778  *
1779  * - For the sake of compactness, only the seven low-order bits of x[i]
1780  *   are used to represent its absolute value (K_i in the paper), and the msb
1781  *   of x[i] encodes the sign (s_i in the paper): it is set if and only if
1782  *   if s_i == -1;
1783  *
1784  * Calling conventions:
1785  * - x is an array of size d + 1
1786  * - w is the size, ie number of teeth, of the comb, and must be between
1787  *   2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE)
1788  * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d
1789  *   (the result will be incorrect if these assumptions are not satisfied)
1790  */
ecp_comb_recode_core(unsigned char x[],size_t d,unsigned char w,const mbedtls_mpi * m)1791 static void ecp_comb_recode_core( unsigned char x[], size_t d,
1792                                   unsigned char w, const mbedtls_mpi *m )
1793 {
1794     size_t i, j;
1795     unsigned char c, cc, adjust;
1796 
1797     memset( x, 0, d+1 );
1798 
1799     /* First get the classical comb values (except for x_d = 0) */
1800     for( i = 0; i < d; i++ )
1801         for( j = 0; j < w; j++ )
1802             x[i] |= mbedtls_mpi_get_bit( m, i + d * j ) << j;
1803 
1804     /* Now make sure x_1 .. x_d are odd */
1805     c = 0;
1806     for( i = 1; i <= d; i++ )
1807     {
1808         /* Add carry and update it */
1809         cc   = x[i] & c;
1810         x[i] = x[i] ^ c;
1811         c = cc;
1812 
1813         /* Adjust if needed, avoiding branches */
1814         adjust = 1 - ( x[i] & 0x01 );
1815         c   |= x[i] & ( x[i-1] * adjust );
1816         x[i] = x[i] ^ ( x[i-1] * adjust );
1817         x[i-1] |= adjust << 7;
1818     }
1819 }
1820 
1821 /*
1822  * Precompute points for the adapted comb method
1823  *
1824  * Assumption: T must be able to hold 2^{w - 1} elements.
1825  *
1826  * Operation: If i = i_{w-1} ... i_1 is the binary representation of i,
1827  *            sets T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P.
1828  *
1829  * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1)
1830  *
1831  * Note: Even comb values (those where P would be omitted from the
1832  *       sum defining T[i] above) are not needed in our adaption
1833  *       the comb method. See ecp_comb_recode_core().
1834  *
1835  * This function currently works in four steps:
1836  * (1) [dbl]      Computation of intermediate T[i] for 2-power values of i
1837  * (2) [norm_dbl] Normalization of coordinates of these T[i]
1838  * (3) [add]      Computation of all T[i]
1839  * (4) [norm_add] Normalization of all T[i]
1840  *
1841  * Step 1 can be interrupted but not the others; together with the final
1842  * coordinate normalization they are the largest steps done at once, depending
1843  * on the window size. Here are operation counts for P-256:
1844  *
1845  * step     (2)     (3)     (4)
1846  * w = 5    142     165     208
1847  * w = 4    136      77     160
1848  * w = 3    130      33     136
1849  * w = 2    124      11     124
1850  *
1851  * So if ECC operations are blocking for too long even with a low max_ops
1852  * value, it's useful to set MBEDTLS_ECP_WINDOW_SIZE to a lower value in order
1853  * to minimize maximum blocking time.
1854  */
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)1855 static int ecp_precompute_comb( const mbedtls_ecp_group *grp,
1856                                 mbedtls_ecp_point T[], const mbedtls_ecp_point *P,
1857                                 unsigned char w, size_t d,
1858                                 mbedtls_ecp_restart_ctx *rs_ctx )
1859 {
1860     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1861     unsigned char i;
1862     size_t j = 0;
1863     const unsigned char T_size = 1U << ( w - 1 );
1864     mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1];
1865 
1866 #if defined(MBEDTLS_ECP_RESTARTABLE)
1867     if( rs_ctx != NULL && rs_ctx->rsm != NULL )
1868     {
1869         if( rs_ctx->rsm->state == ecp_rsm_pre_dbl )
1870             goto dbl;
1871         if( rs_ctx->rsm->state == ecp_rsm_pre_norm_dbl )
1872             goto norm_dbl;
1873         if( rs_ctx->rsm->state == ecp_rsm_pre_add )
1874             goto add;
1875         if( rs_ctx->rsm->state == ecp_rsm_pre_norm_add )
1876             goto norm_add;
1877     }
1878 #else
1879     (void) rs_ctx;
1880 #endif
1881 
1882 #if defined(MBEDTLS_ECP_RESTARTABLE)
1883     if( rs_ctx != NULL && rs_ctx->rsm != NULL )
1884     {
1885         rs_ctx->rsm->state = ecp_rsm_pre_dbl;
1886 
1887         /* initial state for the loop */
1888         rs_ctx->rsm->i = 0;
1889     }
1890 
1891 dbl:
1892 #endif
1893     /*
1894      * Set T[0] = P and
1895      * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value)
1896      */
1897     MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &T[0], P ) );
1898 
1899 #if defined(MBEDTLS_ECP_RESTARTABLE)
1900     if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 )
1901         j = rs_ctx->rsm->i;
1902     else
1903 #endif
1904         j = 0;
1905 
1906     for( ; j < d * ( w - 1 ); j++ )
1907     {
1908         MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL );
1909 
1910         i = 1U << ( j / d );
1911         cur = T + i;
1912 
1913         if( j % d == 0 )
1914             MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) );
1915 
1916         MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) );
1917     }
1918 
1919 #if defined(MBEDTLS_ECP_RESTARTABLE)
1920     if( rs_ctx != NULL && rs_ctx->rsm != NULL )
1921         rs_ctx->rsm->state = ecp_rsm_pre_norm_dbl;
1922 
1923 norm_dbl:
1924 #endif
1925     /*
1926      * Normalize current elements in T. As T has holes,
1927      * use an auxiliary array of pointers to elements in T.
1928      */
1929     j = 0;
1930     for( i = 1; i < T_size; i <<= 1 )
1931         TT[j++] = T + i;
1932 
1933     MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 );
1934 
1935     MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) );
1936 
1937 #if defined(MBEDTLS_ECP_RESTARTABLE)
1938     if( rs_ctx != NULL && rs_ctx->rsm != NULL )
1939         rs_ctx->rsm->state = ecp_rsm_pre_add;
1940 
1941 add:
1942 #endif
1943     /*
1944      * Compute the remaining ones using the minimal number of additions
1945      * Be careful to update T[2^l] only after using it!
1946      */
1947     MBEDTLS_ECP_BUDGET( ( T_size - 1 ) * MBEDTLS_ECP_OPS_ADD );
1948 
1949     for( i = 1; i < T_size; i <<= 1 )
1950     {
1951         j = i;
1952         while( j-- )
1953             MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) );
1954     }
1955 
1956 #if defined(MBEDTLS_ECP_RESTARTABLE)
1957     if( rs_ctx != NULL && rs_ctx->rsm != NULL )
1958         rs_ctx->rsm->state = ecp_rsm_pre_norm_add;
1959 
1960 norm_add:
1961 #endif
1962     /*
1963      * Normalize final elements in T. Even though there are no holes now, we
1964      * still need the auxiliary array for homogeneity with the previous
1965      * call. Also, skip T[0] which is already normalised, being a copy of P.
1966      */
1967     for( j = 0; j + 1 < T_size; j++ )
1968         TT[j] = T + j + 1;
1969 
1970     MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 );
1971 
1972     MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) );
1973 
1974 cleanup:
1975 #if defined(MBEDTLS_ECP_RESTARTABLE)
1976     if( rs_ctx != NULL && rs_ctx->rsm != NULL &&
1977         ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
1978     {
1979         if( rs_ctx->rsm->state == ecp_rsm_pre_dbl )
1980             rs_ctx->rsm->i = j;
1981     }
1982 #endif
1983 
1984     return( ret );
1985 }
1986 
1987 /*
1988  * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ]
1989  *
1990  * See ecp_comb_recode_core() for background
1991  */
ecp_select_comb(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_ecp_point T[],unsigned char T_size,unsigned char i)1992 static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1993                             const mbedtls_ecp_point T[], unsigned char T_size,
1994                             unsigned char i )
1995 {
1996     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1997     unsigned char ii, j;
1998 
1999     /* Ignore the "sign" bit and scale down */
2000     ii =  ( i & 0x7Fu ) >> 1;
2001 
2002     /* Read the whole table to thwart cache-based timing attacks */
2003     for( j = 0; j < T_size; j++ )
2004     {
2005         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) );
2006         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) );
2007     }
2008 
2009     /* Safely invert result if i is "negative" */
2010     MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) );
2011 
2012 cleanup:
2013     return( ret );
2014 }
2015 
2016 /*
2017  * Core multiplication algorithm for the (modified) comb method.
2018  * This part is actually common with the basic comb method (GECC 3.44)
2019  *
2020  * Cost: d A + d D + 1 R
2021  */
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)2022 static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2023                               const mbedtls_ecp_point T[], unsigned char T_size,
2024                               const unsigned char x[], size_t d,
2025                               int (*f_rng)(void *, unsigned char *, size_t),
2026                               void *p_rng,
2027                               mbedtls_ecp_restart_ctx *rs_ctx )
2028 {
2029     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2030     mbedtls_ecp_point Txi;
2031     size_t i;
2032 
2033     mbedtls_ecp_point_init( &Txi );
2034 
2035 #if !defined(MBEDTLS_ECP_RESTARTABLE)
2036     (void) rs_ctx;
2037 #endif
2038 
2039 #if defined(MBEDTLS_ECP_RESTARTABLE)
2040     if( rs_ctx != NULL && rs_ctx->rsm != NULL &&
2041         rs_ctx->rsm->state != ecp_rsm_comb_core )
2042     {
2043         rs_ctx->rsm->i = 0;
2044         rs_ctx->rsm->state = ecp_rsm_comb_core;
2045     }
2046 
2047     /* new 'if' instead of nested for the sake of the 'else' branch */
2048     if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 )
2049     {
2050         /* restore current index (R already pointing to rs_ctx->rsm->R) */
2051         i = rs_ctx->rsm->i;
2052     }
2053     else
2054 #endif
2055     {
2056         /* Start with a non-zero point and randomize its coordinates */
2057         i = d;
2058         MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) );
2059         MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) );
2060 #if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2061         if( f_rng != 0 )
2062 #endif
2063             MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) );
2064     }
2065 
2066     while( i != 0 )
2067     {
2068         MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD );
2069         --i;
2070 
2071         MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) );
2072         MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, T_size, x[i] ) );
2073         MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) );
2074     }
2075 
2076 cleanup:
2077 
2078     mbedtls_ecp_point_free( &Txi );
2079 
2080 #if defined(MBEDTLS_ECP_RESTARTABLE)
2081     if( rs_ctx != NULL && rs_ctx->rsm != NULL &&
2082         ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
2083     {
2084         rs_ctx->rsm->i = i;
2085         /* no need to save R, already pointing to rs_ctx->rsm->R */
2086     }
2087 #endif
2088 
2089     return( ret );
2090 }
2091 
2092 /*
2093  * Recode the scalar to get constant-time comb multiplication
2094  *
2095  * As the actual scalar recoding needs an odd scalar as a starting point,
2096  * this wrapper ensures that by replacing m by N - m if necessary, and
2097  * informs the caller that the result of multiplication will be negated.
2098  *
2099  * This works because we only support large prime order for Short Weierstrass
2100  * curves, so N is always odd hence either m or N - m is.
2101  *
2102  * See ecp_comb_recode_core() for background.
2103  */
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)2104 static int ecp_comb_recode_scalar( const mbedtls_ecp_group *grp,
2105                                    const mbedtls_mpi *m,
2106                                    unsigned char k[COMB_MAX_D + 1],
2107                                    size_t d,
2108                                    unsigned char w,
2109                                    unsigned char *parity_trick )
2110 {
2111     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2112     mbedtls_mpi M, mm;
2113 
2114     mbedtls_mpi_init( &M );
2115     mbedtls_mpi_init( &mm );
2116 
2117     /* N is always odd (see above), just make extra sure */
2118     if( mbedtls_mpi_get_bit( &grp->N, 0 ) != 1 )
2119         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
2120 
2121     /* do we need the parity trick? */
2122     *parity_trick = ( mbedtls_mpi_get_bit( m, 0 ) == 0 );
2123 
2124     /* execute parity fix in constant time */
2125     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) );
2126     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) );
2127     MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, *parity_trick ) );
2128 
2129     /* actual scalar recoding */
2130     ecp_comb_recode_core( k, d, w, &M );
2131 
2132 cleanup:
2133     mbedtls_mpi_free( &mm );
2134     mbedtls_mpi_free( &M );
2135 
2136     return( ret );
2137 }
2138 
2139 /*
2140  * Perform comb multiplication (for short Weierstrass curves)
2141  * once the auxiliary table has been pre-computed.
2142  *
2143  * Scalar recoding may use a parity trick that makes us compute -m * P,
2144  * if that is the case we'll need to recover m * P at the end.
2145  */
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)2146 static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp,
2147                                 mbedtls_ecp_point *R,
2148                                 const mbedtls_mpi *m,
2149                                 const mbedtls_ecp_point *T,
2150                                 unsigned char T_size,
2151                                 unsigned char w,
2152                                 size_t d,
2153                                 int (*f_rng)(void *, unsigned char *, size_t),
2154                                 void *p_rng,
2155                                 mbedtls_ecp_restart_ctx *rs_ctx )
2156 {
2157     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2158     unsigned char parity_trick;
2159     unsigned char k[COMB_MAX_D + 1];
2160     mbedtls_ecp_point *RR = R;
2161 
2162 #if defined(MBEDTLS_ECP_RESTARTABLE)
2163     if( rs_ctx != NULL && rs_ctx->rsm != NULL )
2164     {
2165         RR = &rs_ctx->rsm->R;
2166 
2167         if( rs_ctx->rsm->state == ecp_rsm_final_norm )
2168             goto final_norm;
2169     }
2170 #endif
2171 
2172     MBEDTLS_MPI_CHK( ecp_comb_recode_scalar( grp, m, k, d, w,
2173                                             &parity_trick ) );
2174     MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, RR, T, T_size, k, d,
2175                                         f_rng, p_rng, rs_ctx ) );
2176     MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, RR, parity_trick ) );
2177 
2178 #if defined(MBEDTLS_ECP_RESTARTABLE)
2179     if( rs_ctx != NULL && rs_ctx->rsm != NULL )
2180         rs_ctx->rsm->state = ecp_rsm_final_norm;
2181 
2182 final_norm:
2183     MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV );
2184 #endif
2185     /*
2186      * Knowledge of the jacobian coordinates may leak the last few bits of the
2187      * scalar [1], and since our MPI implementation isn't constant-flow,
2188      * inversion (used for coordinate normalization) may leak the full value
2189      * of its input via side-channels [2].
2190      *
2191      * [1] https://eprint.iacr.org/2003/191
2192      * [2] https://eprint.iacr.org/2020/055
2193      *
2194      * Avoid the leak by randomizing coordinates before we normalize them.
2195      */
2196 #if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2197     if( f_rng != 0 )
2198 #endif
2199         MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) );
2200 
2201     MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) );
2202 
2203 #if defined(MBEDTLS_ECP_RESTARTABLE)
2204     if( rs_ctx != NULL && rs_ctx->rsm != NULL )
2205         MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, RR ) );
2206 #endif
2207 
2208 cleanup:
2209     return( ret );
2210 }
2211 
2212 /*
2213  * Pick window size based on curve size and whether we optimize for base point
2214  */
ecp_pick_window_size(const mbedtls_ecp_group * grp,unsigned char p_eq_g)2215 static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp,
2216                                            unsigned char p_eq_g )
2217 {
2218     unsigned char w;
2219 
2220     /*
2221      * Minimize the number of multiplications, that is minimize
2222      * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w )
2223      * (see costs of the various parts, with 1S = 1M)
2224      */
2225     w = grp->nbits >= 384 ? 5 : 4;
2226 
2227     /*
2228      * If P == G, pre-compute a bit more, since this may be re-used later.
2229      * Just adding one avoids upping the cost of the first mul too much,
2230      * and the memory cost too.
2231      */
2232     if( p_eq_g )
2233         w++;
2234 
2235     /*
2236      * Make sure w is within bounds.
2237      * (The last test is useful only for very small curves in the test suite.)
2238      */
2239 #if( MBEDTLS_ECP_WINDOW_SIZE < 6 )
2240     if( w > MBEDTLS_ECP_WINDOW_SIZE )
2241         w = MBEDTLS_ECP_WINDOW_SIZE;
2242 #endif
2243     if( w >= grp->nbits )
2244         w = 2;
2245 
2246     return( w );
2247 }
2248 
2249 /*
2250  * Multiplication using the comb method - for curves in short Weierstrass form
2251  *
2252  * This function is mainly responsible for administrative work:
2253  * - managing the restart context if enabled
2254  * - managing the table of precomputed points (passed between the below two
2255  *   functions): allocation, computation, ownership tranfer, freeing.
2256  *
2257  * It delegates the actual arithmetic work to:
2258  *      ecp_precompute_comb() and ecp_mul_comb_with_precomp()
2259  *
2260  * See comments on ecp_comb_recode_core() regarding the computation strategy.
2261  */
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)2262 static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2263                          const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2264                          int (*f_rng)(void *, unsigned char *, size_t),
2265                          void *p_rng,
2266                          mbedtls_ecp_restart_ctx *rs_ctx )
2267 {
2268     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2269     unsigned char w, p_eq_g, i;
2270     size_t d;
2271     unsigned char T_size = 0, T_ok = 0;
2272     mbedtls_ecp_point *T = NULL;
2273 #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2274     ecp_drbg_context drbg_ctx;
2275 
2276     ecp_drbg_init( &drbg_ctx );
2277 #endif
2278 
2279     ECP_RS_ENTER( rsm );
2280 
2281 #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2282     if( f_rng == NULL )
2283     {
2284         /* Adjust pointers */
2285         f_rng = &ecp_drbg_random;
2286 #if defined(MBEDTLS_ECP_RESTARTABLE)
2287         if( rs_ctx != NULL && rs_ctx->rsm != NULL )
2288             p_rng = &rs_ctx->rsm->drbg_ctx;
2289         else
2290 #endif
2291             p_rng = &drbg_ctx;
2292 
2293         /* Initialize internal DRBG if necessary */
2294 #if defined(MBEDTLS_ECP_RESTARTABLE)
2295         if( rs_ctx == NULL || rs_ctx->rsm == NULL ||
2296             rs_ctx->rsm->drbg_seeded == 0 )
2297 #endif
2298         {
2299             const size_t m_len = ( grp->nbits + 7 ) / 8;
2300             MBEDTLS_MPI_CHK( ecp_drbg_seed( p_rng, m, m_len ) );
2301         }
2302 #if defined(MBEDTLS_ECP_RESTARTABLE)
2303         if( rs_ctx != NULL && rs_ctx->rsm != NULL )
2304             rs_ctx->rsm->drbg_seeded = 1;
2305 #endif
2306     }
2307 #endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
2308 
2309     /* Is P the base point ? */
2310 #if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
2311     p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
2312                mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 );
2313 #else
2314     p_eq_g = 0;
2315 #endif
2316 
2317     /* Pick window size and deduce related sizes */
2318     w = ecp_pick_window_size( grp, p_eq_g );
2319     T_size = 1U << ( w - 1 );
2320     d = ( grp->nbits + w - 1 ) / w;
2321 
2322     /* Pre-computed table: do we have it already for the base point? */
2323     if( p_eq_g && grp->T != NULL )
2324     {
2325         /* second pointer to the same table, will be deleted on exit */
2326         T = grp->T;
2327         T_ok = 1;
2328     }
2329     else
2330 #if defined(MBEDTLS_ECP_RESTARTABLE)
2331     /* Pre-computed table: do we have one in progress? complete? */
2332     if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->T != NULL )
2333     {
2334         /* transfer ownership of T from rsm to local function */
2335         T = rs_ctx->rsm->T;
2336         rs_ctx->rsm->T = NULL;
2337         rs_ctx->rsm->T_size = 0;
2338 
2339         /* This effectively jumps to the call to mul_comb_after_precomp() */
2340         T_ok = rs_ctx->rsm->state >= ecp_rsm_comb_core;
2341     }
2342     else
2343 #endif
2344     /* Allocate table if we didn't have any */
2345     {
2346         T = mbedtls_calloc( T_size, sizeof( mbedtls_ecp_point ) );
2347         if( T == NULL )
2348         {
2349             ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
2350             goto cleanup;
2351         }
2352 
2353         for( i = 0; i < T_size; i++ )
2354             mbedtls_ecp_point_init( &T[i] );
2355 
2356         T_ok = 0;
2357     }
2358 
2359     /* Compute table (or finish computing it) if not done already */
2360     if( !T_ok )
2361     {
2362         MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d, rs_ctx ) );
2363 
2364         if( p_eq_g )
2365         {
2366             /* almost transfer ownership of T to the group, but keep a copy of
2367              * the pointer to use for calling the next function more easily */
2368             grp->T = T;
2369             grp->T_size = T_size;
2370         }
2371     }
2372 
2373     /* Actual comb multiplication using precomputed points */
2374     MBEDTLS_MPI_CHK( ecp_mul_comb_after_precomp( grp, R, m,
2375                                                  T, T_size, w, d,
2376                                                  f_rng, p_rng, rs_ctx ) );
2377 
2378 cleanup:
2379 
2380 #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2381     ecp_drbg_free( &drbg_ctx );
2382 #endif
2383 
2384     /* does T belong to the group? */
2385     if( T == grp->T )
2386         T = NULL;
2387 
2388     /* does T belong to the restart context? */
2389 #if defined(MBEDTLS_ECP_RESTARTABLE)
2390     if( rs_ctx != NULL && rs_ctx->rsm != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS && T != NULL )
2391     {
2392         /* transfer ownership of T from local function to rsm */
2393         rs_ctx->rsm->T_size = T_size;
2394         rs_ctx->rsm->T = T;
2395         T = NULL;
2396     }
2397 #endif
2398 
2399     /* did T belong to us? then let's destroy it! */
2400     if( T != NULL )
2401     {
2402         for( i = 0; i < T_size; i++ )
2403             mbedtls_ecp_point_free( &T[i] );
2404         mbedtls_free( T );
2405     }
2406 
2407     /* don't free R while in progress in case R == P */
2408 #if defined(MBEDTLS_ECP_RESTARTABLE)
2409     if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
2410 #endif
2411     /* prevent caller from using invalid value */
2412     if( ret != 0 )
2413         mbedtls_ecp_point_free( R );
2414 
2415     ECP_RS_LEAVE( rsm );
2416 
2417     return( ret );
2418 }
2419 
2420 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
2421 
2422 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
2423 /*
2424  * For Montgomery curves, we do all the internal arithmetic in projective
2425  * coordinates. Import/export of points uses only the x coordinates, which is
2426  * internaly represented as X / Z.
2427  *
2428  * For scalar multiplication, we'll use a Montgomery ladder.
2429  */
2430 
2431 /*
2432  * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1
2433  * Cost: 1M + 1I
2434  */
ecp_normalize_mxz(const mbedtls_ecp_group * grp,mbedtls_ecp_point * P)2435 static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P )
2436 {
2437 #if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
2438     if( mbedtls_internal_ecp_grp_capable( grp ) )
2439         return( mbedtls_internal_ecp_normalize_mxz( grp, P ) );
2440 #endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
2441 
2442 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
2443     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
2444 #else
2445     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2446     MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) );
2447     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &P->Z ) );
2448     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
2449 
2450 cleanup:
2451     return( ret );
2452 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) */
2453 }
2454 
2455 /*
2456  * Randomize projective x/z coordinates:
2457  * (X, Z) -> (l X, l Z) for random l
2458  * This is sort of the reverse operation of ecp_normalize_mxz().
2459  *
2460  * This countermeasure was first suggested in [2].
2461  * Cost: 2M
2462  */
ecp_randomize_mxz(const mbedtls_ecp_group * grp,mbedtls_ecp_point * P,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)2463 static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
2464                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
2465 {
2466 #if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
2467     if( mbedtls_internal_ecp_grp_capable( grp ) )
2468         return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ) );
2469 #endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */
2470 
2471 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
2472     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
2473 #else
2474     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2475     mbedtls_mpi l;
2476     mbedtls_mpi_init( &l );
2477 
2478     /* Generate l such that 1 < l < p */
2479     MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
2480 
2481     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &l ) );
2482     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->Z, &P->Z, &l ) );
2483 
2484 cleanup:
2485     mbedtls_mpi_free( &l );
2486 
2487     if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
2488         ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
2489     return( ret );
2490 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) */
2491 }
2492 
2493 /*
2494  * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q),
2495  * for Montgomery curves in x/z coordinates.
2496  *
2497  * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3
2498  * with
2499  * d =  X1
2500  * P = (X2, Z2)
2501  * Q = (X3, Z3)
2502  * R = (X4, Z4)
2503  * S = (X5, Z5)
2504  * and eliminating temporary variables tO, ..., t4.
2505  *
2506  * Cost: 5M + 4S
2507  */
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)2508 static int ecp_double_add_mxz( const mbedtls_ecp_group *grp,
2509                                mbedtls_ecp_point *R, mbedtls_ecp_point *S,
2510                                const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
2511                                const mbedtls_mpi *d )
2512 {
2513 #if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
2514     if( mbedtls_internal_ecp_grp_capable( grp ) )
2515         return( mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ) );
2516 #endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */
2517 
2518 #if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
2519     return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
2520 #else
2521     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2522     mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB;
2523 
2524     mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B );
2525     mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C );
2526     mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB );
2527 
2528     MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &A,    &P->X,   &P->Z ) );
2529     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &AA,   &A,      &A    ) );
2530     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &B,    &P->X,   &P->Z ) );
2531     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &BB,   &B,      &B    ) );
2532     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &E,    &AA,     &BB   ) );
2533     MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &C,    &Q->X,   &Q->Z ) );
2534     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &D,    &Q->X,   &Q->Z ) );
2535     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &DA,   &D,      &A    ) );
2536     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &CB,   &C,      &B    ) );
2537     MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &S->X, &DA,     &CB   ) );
2538     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->X, &S->X,   &S->X ) );
2539     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S->Z, &DA,     &CB   ) );
2540     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, &S->Z,   &S->Z ) );
2541     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, d,       &S->Z ) );
2542     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->X, &AA,     &BB   ) );
2543     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &grp->A, &E    ) );
2544     MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &R->Z, &BB,     &R->Z ) );
2545     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &E,      &R->Z ) );
2546 
2547 cleanup:
2548     mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B );
2549     mbedtls_mpi_free( &BB ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &C );
2550     mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB );
2551 
2552     return( ret );
2553 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) */
2554 }
2555 
2556 /*
2557  * Multiplication with Montgomery ladder in x/z coordinates,
2558  * for curves in Montgomery form
2559  */
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)2560 static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2561                         const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2562                         int (*f_rng)(void *, unsigned char *, size_t),
2563                         void *p_rng )
2564 {
2565     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2566     size_t i;
2567     unsigned char b;
2568     mbedtls_ecp_point RP;
2569     mbedtls_mpi PX;
2570 #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2571     ecp_drbg_context drbg_ctx;
2572 
2573     ecp_drbg_init( &drbg_ctx );
2574 #endif
2575     mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX );
2576 
2577 #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2578     if( f_rng == NULL )
2579     {
2580         const size_t m_len = ( grp->nbits + 7 ) / 8;
2581         MBEDTLS_MPI_CHK( ecp_drbg_seed( &drbg_ctx, m, m_len ) );
2582         f_rng = &ecp_drbg_random;
2583         p_rng = &drbg_ctx;
2584     }
2585 #endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
2586 
2587     /* Save PX and read from P before writing to R, in case P == R */
2588     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) );
2589     MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &RP, P ) );
2590 
2591     /* Set R to zero in modified x/z coordinates */
2592     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->X, 1 ) );
2593     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) );
2594     mbedtls_mpi_free( &R->Y );
2595 
2596     /* RP.X might be sligtly larger than P, so reduce it */
2597     MOD_ADD( RP.X );
2598 
2599     /* Randomize coordinates of the starting point */
2600 #if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2601     if( f_rng != NULL )
2602 #endif
2603         MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
2604 
2605     /* Loop invariant: R = result so far, RP = R + P */
2606     i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */
2607     while( i-- > 0 )
2608     {
2609         b = mbedtls_mpi_get_bit( m, i );
2610         /*
2611          *  if (b) R = 2R + P else R = 2R,
2612          * which is:
2613          *  if (b) double_add( RP, R, RP, R )
2614          *  else   double_add( R, RP, R, RP )
2615          * but using safe conditional swaps to avoid leaks
2616          */
2617         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
2618         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
2619         MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) );
2620         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
2621         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
2622     }
2623 
2624     /*
2625      * Knowledge of the projective coordinates may leak the last few bits of the
2626      * scalar [1], and since our MPI implementation isn't constant-flow,
2627      * inversion (used for coordinate normalization) may leak the full value
2628      * of its input via side-channels [2].
2629      *
2630      * [1] https://eprint.iacr.org/2003/191
2631      * [2] https://eprint.iacr.org/2020/055
2632      *
2633      * Avoid the leak by randomizing coordinates before we normalize them.
2634      */
2635 #if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2636     if( f_rng != NULL )
2637 #endif
2638         MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
2639 
2640     MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
2641 
2642 cleanup:
2643 #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
2644     ecp_drbg_free( &drbg_ctx );
2645 #endif
2646 
2647     mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX );
2648 
2649     return( ret );
2650 }
2651 
2652 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
2653 
2654 /*
2655  * Restartable multiplication R = m * P
2656  */
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)2657 int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2658              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2659              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
2660              mbedtls_ecp_restart_ctx *rs_ctx )
2661 {
2662     int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
2663 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2664     char is_grp_capable = 0;
2665 #endif
2666     ECP_VALIDATE_RET( grp != NULL );
2667     ECP_VALIDATE_RET( R   != NULL );
2668     ECP_VALIDATE_RET( m   != NULL );
2669     ECP_VALIDATE_RET( P   != NULL );
2670 
2671 #if defined(MBEDTLS_ECP_RESTARTABLE)
2672     /* reset ops count for this call if top-level */
2673     if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
2674         rs_ctx->ops_done = 0;
2675 #else
2676     (void) rs_ctx;
2677 #endif
2678 
2679 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2680     if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) )
2681         MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
2682 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
2683 
2684 #if defined(MBEDTLS_ECP_RESTARTABLE)
2685     /* skip argument check when restarting */
2686     if( rs_ctx == NULL || rs_ctx->rsm == NULL )
2687 #endif
2688     {
2689         /* check_privkey is free */
2690         MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK );
2691 
2692         /* Common sanity checks */
2693         MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( grp, m ) );
2694         MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) );
2695     }
2696 
2697     ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
2698 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
2699     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
2700         MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) );
2701 #endif
2702 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
2703     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
2704         MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) );
2705 #endif
2706 
2707 cleanup:
2708 
2709 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2710     if( is_grp_capable )
2711         mbedtls_internal_ecp_free( grp );
2712 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
2713 
2714 #if defined(MBEDTLS_ECP_RESTARTABLE)
2715     if( rs_ctx != NULL )
2716         rs_ctx->depth--;
2717 #endif
2718 
2719     return( ret );
2720 }
2721 
2722 /*
2723  * Multiplication R = m * P
2724  */
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)2725 int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2726              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2727              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
2728 {
2729     ECP_VALIDATE_RET( grp != NULL );
2730     ECP_VALIDATE_RET( R   != NULL );
2731     ECP_VALIDATE_RET( m   != NULL );
2732     ECP_VALIDATE_RET( P   != NULL );
2733     return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) );
2734 }
2735 
2736 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
2737 /*
2738  * Check that an affine point is valid as a public key,
2739  * short weierstrass curves (SEC1 3.2.3.1)
2740  */
ecp_check_pubkey_sw(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * pt)2741 static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
2742 {
2743     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2744     mbedtls_mpi YY, RHS;
2745 
2746     /* pt coordinates must be normalized for our checks */
2747     if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 ||
2748         mbedtls_mpi_cmp_int( &pt->Y, 0 ) < 0 ||
2749         mbedtls_mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 ||
2750         mbedtls_mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 )
2751         return( MBEDTLS_ERR_ECP_INVALID_KEY );
2752 
2753     mbedtls_mpi_init( &YY ); mbedtls_mpi_init( &RHS );
2754 
2755     /*
2756      * YY = Y^2
2757      * RHS = X (X^2 + A) + B = X^3 + A X + B
2758      */
2759     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &YY,  &pt->Y,   &pt->Y  ) );
2760     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &pt->X,   &pt->X  ) );
2761 
2762     /* Special case for A = -3 */
2763     if( grp->A.p == NULL )
2764     {
2765         MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &RHS, &RHS, 3       ) );  MOD_SUB( RHS );
2766     }
2767     else
2768     {
2769         MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS, &grp->A ) );
2770     }
2771 
2772     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &RHS,     &pt->X  ) );
2773     MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS,     &grp->B ) );
2774 
2775     if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 )
2776         ret = MBEDTLS_ERR_ECP_INVALID_KEY;
2777 
2778 cleanup:
2779 
2780     mbedtls_mpi_free( &YY ); mbedtls_mpi_free( &RHS );
2781 
2782     return( ret );
2783 }
2784 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
2785 
2786 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
2787 /*
2788  * R = m * P with shortcuts for m == 0, m == 1 and m == -1
2789  * NOT constant-time - ONLY for short Weierstrass!
2790  */
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)2791 static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
2792                                       mbedtls_ecp_point *R,
2793                                       const mbedtls_mpi *m,
2794                                       const mbedtls_ecp_point *P,
2795                                       mbedtls_ecp_restart_ctx *rs_ctx )
2796 {
2797     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2798 
2799     if( mbedtls_mpi_cmp_int( m, 0 ) == 0 )
2800     {
2801         MBEDTLS_MPI_CHK( mbedtls_ecp_set_zero( R ) );
2802     }
2803     else if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
2804     {
2805         MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
2806     }
2807     else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 )
2808     {
2809         MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
2810         if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 )
2811             MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) );
2812     }
2813     else
2814     {
2815         MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P,
2816                                                       NULL, NULL, rs_ctx ) );
2817     }
2818 
2819 cleanup:
2820     return( ret );
2821 }
2822 
2823 /*
2824  * Restartable linear combination
2825  * NOT constant-time
2826  */
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)2827 int mbedtls_ecp_muladd_restartable(
2828              mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2829              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2830              const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
2831              mbedtls_ecp_restart_ctx *rs_ctx )
2832 {
2833     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2834     mbedtls_ecp_point mP;
2835     mbedtls_ecp_point *pmP = &mP;
2836     mbedtls_ecp_point *pR = R;
2837 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2838     char is_grp_capable = 0;
2839 #endif
2840     ECP_VALIDATE_RET( grp != NULL );
2841     ECP_VALIDATE_RET( R   != NULL );
2842     ECP_VALIDATE_RET( m   != NULL );
2843     ECP_VALIDATE_RET( P   != NULL );
2844     ECP_VALIDATE_RET( n   != NULL );
2845     ECP_VALIDATE_RET( Q   != NULL );
2846 
2847     if( mbedtls_ecp_get_type( grp ) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
2848         return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
2849 
2850     mbedtls_ecp_point_init( &mP );
2851 
2852     ECP_RS_ENTER( ma );
2853 
2854 #if defined(MBEDTLS_ECP_RESTARTABLE)
2855     if( rs_ctx != NULL && rs_ctx->ma != NULL )
2856     {
2857         /* redirect intermediate results to restart context */
2858         pmP = &rs_ctx->ma->mP;
2859         pR  = &rs_ctx->ma->R;
2860 
2861         /* jump to next operation */
2862         if( rs_ctx->ma->state == ecp_rsma_mul2 )
2863             goto mul2;
2864         if( rs_ctx->ma->state == ecp_rsma_add )
2865             goto add;
2866         if( rs_ctx->ma->state == ecp_rsma_norm )
2867             goto norm;
2868     }
2869 #endif /* MBEDTLS_ECP_RESTARTABLE */
2870 
2871     MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pmP, m, P, rs_ctx ) );
2872 #if defined(MBEDTLS_ECP_RESTARTABLE)
2873     if( rs_ctx != NULL && rs_ctx->ma != NULL )
2874         rs_ctx->ma->state = ecp_rsma_mul2;
2875 
2876 mul2:
2877 #endif
2878     MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pR,  n, Q, rs_ctx ) );
2879 
2880 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2881     if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) )
2882         MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
2883 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
2884 
2885 #if defined(MBEDTLS_ECP_RESTARTABLE)
2886     if( rs_ctx != NULL && rs_ctx->ma != NULL )
2887         rs_ctx->ma->state = ecp_rsma_add;
2888 
2889 add:
2890 #endif
2891     MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_ADD );
2892     MBEDTLS_MPI_CHK( ecp_add_mixed( grp, pR, pmP, pR ) );
2893 #if defined(MBEDTLS_ECP_RESTARTABLE)
2894     if( rs_ctx != NULL && rs_ctx->ma != NULL )
2895         rs_ctx->ma->state = ecp_rsma_norm;
2896 
2897 norm:
2898 #endif
2899     MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV );
2900     MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, pR ) );
2901 
2902 #if defined(MBEDTLS_ECP_RESTARTABLE)
2903     if( rs_ctx != NULL && rs_ctx->ma != NULL )
2904         MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, pR ) );
2905 #endif
2906 
2907 cleanup:
2908 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
2909     if( is_grp_capable )
2910         mbedtls_internal_ecp_free( grp );
2911 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
2912 
2913     mbedtls_ecp_point_free( &mP );
2914 
2915     ECP_RS_LEAVE( ma );
2916 
2917     return( ret );
2918 }
2919 
2920 /*
2921  * Linear combination
2922  * NOT constant-time
2923  */
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)2924 int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
2925              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
2926              const mbedtls_mpi *n, const mbedtls_ecp_point *Q )
2927 {
2928     ECP_VALIDATE_RET( grp != NULL );
2929     ECP_VALIDATE_RET( R   != NULL );
2930     ECP_VALIDATE_RET( m   != NULL );
2931     ECP_VALIDATE_RET( P   != NULL );
2932     ECP_VALIDATE_RET( n   != NULL );
2933     ECP_VALIDATE_RET( Q   != NULL );
2934     return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) );
2935 }
2936 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
2937 
2938 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
2939 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
2940 #define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
2941 #define ECP_MPI_INIT_ARRAY(x)   \
2942     ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
2943 /*
2944  * Constants for the two points other than 0, 1, -1 (mod p) in
2945  * https://cr.yp.to/ecdh.html#validate
2946  * See ecp_check_pubkey_x25519().
2947  */
2948 static const mbedtls_mpi_uint x25519_bad_point_1[] = {
2949     MBEDTLS_BYTES_TO_T_UINT_8( 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae ),
2950     MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a ),
2951     MBEDTLS_BYTES_TO_T_UINT_8( 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd ),
2952     MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 ),
2953 };
2954 static const mbedtls_mpi_uint x25519_bad_point_2[] = {
2955     MBEDTLS_BYTES_TO_T_UINT_8( 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24 ),
2956     MBEDTLS_BYTES_TO_T_UINT_8( 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b ),
2957     MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86 ),
2958     MBEDTLS_BYTES_TO_T_UINT_8( 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 ),
2959 };
2960 static const mbedtls_mpi ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY(
2961         x25519_bad_point_1 );
2962 static const mbedtls_mpi ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY(
2963         x25519_bad_point_2 );
2964 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
2965 
2966 /*
2967  * Check that the input point is not one of the low-order points.
2968  * This is recommended by the "May the Fourth" paper:
2969  * https://eprint.iacr.org/2017/806.pdf
2970  * Those points are never sent by an honest peer.
2971  */
ecp_check_bad_points_mx(const mbedtls_mpi * X,const mbedtls_mpi * P,const mbedtls_ecp_group_id grp_id)2972 static int ecp_check_bad_points_mx( const mbedtls_mpi *X, const mbedtls_mpi *P,
2973                                     const mbedtls_ecp_group_id grp_id )
2974 {
2975     int ret;
2976     mbedtls_mpi XmP;
2977 
2978     mbedtls_mpi_init( &XmP );
2979 
2980     /* Reduce X mod P so that we only need to check values less than P.
2981      * We know X < 2^256 so we can proceed by subtraction. */
2982     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &XmP, X ) );
2983     while( mbedtls_mpi_cmp_mpi( &XmP, P ) >= 0 )
2984         MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &XmP, &XmP, P ) );
2985 
2986     /* Check against the known bad values that are less than P. For Curve448
2987      * these are 0, 1 and -1. For Curve25519 we check the values less than P
2988      * from the following list: https://cr.yp.to/ecdh.html#validate */
2989     if( mbedtls_mpi_cmp_int( &XmP, 1 ) <= 0 ) /* takes care of 0 and 1 */
2990     {
2991         ret = MBEDTLS_ERR_ECP_INVALID_KEY;
2992         goto cleanup;
2993     }
2994 
2995 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
2996     if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
2997     {
2998         if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_1 ) == 0 )
2999         {
3000             ret = MBEDTLS_ERR_ECP_INVALID_KEY;
3001             goto cleanup;
3002         }
3003 
3004         if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_2 ) == 0 )
3005         {
3006             ret = MBEDTLS_ERR_ECP_INVALID_KEY;
3007             goto cleanup;
3008         }
3009     }
3010 #else
3011     (void) grp_id;
3012 #endif
3013 
3014     /* Final check: check if XmP + 1 is P (final because it changes XmP!) */
3015     MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &XmP, &XmP, 1 ) );
3016     if( mbedtls_mpi_cmp_mpi( &XmP, P ) == 0 )
3017     {
3018         ret = MBEDTLS_ERR_ECP_INVALID_KEY;
3019         goto cleanup;
3020     }
3021 
3022     ret = 0;
3023 
3024 cleanup:
3025     mbedtls_mpi_free( &XmP );
3026 
3027     return( ret );
3028 }
3029 
3030 /*
3031  * Check validity of a public key for Montgomery curves with x-only schemes
3032  */
ecp_check_pubkey_mx(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * pt)3033 static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
3034 {
3035     /* [Curve25519 p. 5] Just check X is the correct number of bytes */
3036     /* Allow any public value, if it's too big then we'll just reduce it mod p
3037      * (RFC 7748 sec. 5 para. 3). */
3038     if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 )
3039         return( MBEDTLS_ERR_ECP_INVALID_KEY );
3040 
3041     /* Implicit in all standards (as they don't consider negative numbers):
3042      * X must be non-negative. This is normally ensured by the way it's
3043      * encoded for transmission, but let's be extra sure. */
3044     if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 )
3045         return( MBEDTLS_ERR_ECP_INVALID_KEY );
3046 
3047     return( ecp_check_bad_points_mx( &pt->X, &grp->P, grp->id ) );
3048 }
3049 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3050 
3051 /*
3052  * Check that a point is valid as a public key
3053  */
mbedtls_ecp_check_pubkey(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * pt)3054 int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
3055                               const mbedtls_ecp_point *pt )
3056 {
3057     ECP_VALIDATE_RET( grp != NULL );
3058     ECP_VALIDATE_RET( pt  != NULL );
3059 
3060     /* Must use affine coordinates */
3061     if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
3062         return( MBEDTLS_ERR_ECP_INVALID_KEY );
3063 
3064 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3065     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
3066         return( ecp_check_pubkey_mx( grp, pt ) );
3067 #endif
3068 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3069     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
3070         return( ecp_check_pubkey_sw( grp, pt ) );
3071 #endif
3072     return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
3073 }
3074 
3075 /*
3076  * Check that an mbedtls_mpi is valid as a private key
3077  */
mbedtls_ecp_check_privkey(const mbedtls_ecp_group * grp,const mbedtls_mpi * d)3078 int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
3079                                const mbedtls_mpi *d )
3080 {
3081     ECP_VALIDATE_RET( grp != NULL );
3082     ECP_VALIDATE_RET( d   != NULL );
3083 
3084 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3085     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
3086     {
3087         /* see RFC 7748 sec. 5 para. 5 */
3088         if( mbedtls_mpi_get_bit( d, 0 ) != 0 ||
3089             mbedtls_mpi_get_bit( d, 1 ) != 0 ||
3090             mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */
3091             return( MBEDTLS_ERR_ECP_INVALID_KEY );
3092 
3093         /* see [Curve25519] page 5 */
3094         if( grp->nbits == 254 && mbedtls_mpi_get_bit( d, 2 ) != 0 )
3095             return( MBEDTLS_ERR_ECP_INVALID_KEY );
3096 
3097         return( 0 );
3098     }
3099 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3100 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3101     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
3102     {
3103         /* see SEC1 3.2 */
3104         if( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
3105             mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
3106             return( MBEDTLS_ERR_ECP_INVALID_KEY );
3107         else
3108             return( 0 );
3109     }
3110 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3111 
3112     return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
3113 }
3114 
3115 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3116 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)3117 int mbedtls_ecp_gen_privkey_mx( size_t high_bit,
3118                                 mbedtls_mpi *d,
3119                                 int (*f_rng)(void *, unsigned char *, size_t),
3120                                 void *p_rng )
3121 {
3122     int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3123     size_t n_random_bytes = high_bit / 8 + 1;
3124 
3125     /* [Curve25519] page 5 */
3126     /* Generate a (high_bit+1)-bit random number by generating just enough
3127      * random bytes, then shifting out extra bits from the top (necessary
3128      * when (high_bit+1) is not a multiple of 8). */
3129     MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_random_bytes,
3130                                               f_rng, p_rng ) );
3131     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_random_bytes - high_bit - 1 ) );
3132 
3133     MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, high_bit, 1 ) );
3134 
3135     /* Make sure the last two bits are unset for Curve448, three bits for
3136        Curve25519 */
3137     MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
3138     MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
3139     if( high_bit == 254 )
3140     {
3141         MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
3142     }
3143 
3144 cleanup:
3145     return( ret );
3146 }
3147 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3148 
3149 #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)3150 static int mbedtls_ecp_gen_privkey_sw(
3151     const mbedtls_mpi *N, mbedtls_mpi *d,
3152     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
3153 {
3154     int ret = mbedtls_mpi_random( d, 1, N, f_rng, p_rng );
3155     switch( ret )
3156     {
3157         case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
3158             return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
3159         default:
3160             return( ret );
3161     }
3162 }
3163 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3164 
3165 /*
3166  * Generate a private key
3167  */
mbedtls_ecp_gen_privkey(const mbedtls_ecp_group * grp,mbedtls_mpi * d,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)3168 int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
3169                      mbedtls_mpi *d,
3170                      int (*f_rng)(void *, unsigned char *, size_t),
3171                      void *p_rng )
3172 {
3173     ECP_VALIDATE_RET( grp   != NULL );
3174     ECP_VALIDATE_RET( d     != NULL );
3175     ECP_VALIDATE_RET( f_rng != NULL );
3176 
3177 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3178     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
3179         return( mbedtls_ecp_gen_privkey_mx( grp->nbits, d, f_rng, p_rng ) );
3180 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3181 
3182 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3183     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
3184         return( mbedtls_ecp_gen_privkey_sw( &grp->N, d, f_rng, p_rng ) );
3185 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3186 
3187     return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
3188 }
3189 
3190 /*
3191  * Generate a keypair with configurable base point
3192  */
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)3193 int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
3194                      const mbedtls_ecp_point *G,
3195                      mbedtls_mpi *d, mbedtls_ecp_point *Q,
3196                      int (*f_rng)(void *, unsigned char *, size_t),
3197                      void *p_rng )
3198 {
3199     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3200     ECP_VALIDATE_RET( grp   != NULL );
3201     ECP_VALIDATE_RET( d     != NULL );
3202     ECP_VALIDATE_RET( G     != NULL );
3203     ECP_VALIDATE_RET( Q     != NULL );
3204     ECP_VALIDATE_RET( f_rng != NULL );
3205 
3206     MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
3207     MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
3208 
3209 cleanup:
3210     return( ret );
3211 }
3212 
3213 /*
3214  * Generate key pair, wrapper for conventional base point
3215  */
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)3216 int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp,
3217                              mbedtls_mpi *d, mbedtls_ecp_point *Q,
3218                              int (*f_rng)(void *, unsigned char *, size_t),
3219                              void *p_rng )
3220 {
3221     ECP_VALIDATE_RET( grp   != NULL );
3222     ECP_VALIDATE_RET( d     != NULL );
3223     ECP_VALIDATE_RET( Q     != NULL );
3224     ECP_VALIDATE_RET( f_rng != NULL );
3225 
3226     return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
3227 }
3228 
3229 /*
3230  * Generate a keypair, prettier wrapper
3231  */
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)3232 int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
3233                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
3234 {
3235     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3236     ECP_VALIDATE_RET( key   != NULL );
3237     ECP_VALIDATE_RET( f_rng != NULL );
3238 
3239     if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
3240         return( ret );
3241 
3242     return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) );
3243 }
3244 
3245 #define ECP_CURVE25519_KEY_SIZE 32
3246 /*
3247  * Read a private key.
3248  */
mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id,mbedtls_ecp_keypair * key,const unsigned char * buf,size_t buflen)3249 int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
3250                           const unsigned char *buf, size_t buflen )
3251 {
3252     int ret = 0;
3253 
3254     ECP_VALIDATE_RET( key  != NULL );
3255     ECP_VALIDATE_RET( buf  != NULL );
3256 
3257     if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
3258         return( ret );
3259 
3260     ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
3261 
3262 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3263     if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
3264     {
3265         /*
3266          * If it is Curve25519 curve then mask the key as mandated by RFC7748
3267          */
3268         if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
3269         {
3270             if( buflen != ECP_CURVE25519_KEY_SIZE )
3271                 return MBEDTLS_ERR_ECP_INVALID_KEY;
3272 
3273             MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) );
3274 
3275             /* Set the three least significant bits to 0 */
3276             MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) );
3277             MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) );
3278             MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 2, 0 ) );
3279 
3280             /* Set the most significant bit to 0 */
3281             MBEDTLS_MPI_CHK(
3282                     mbedtls_mpi_set_bit( &key->d,
3283                                          ECP_CURVE25519_KEY_SIZE * 8 - 1, 0 )
3284                     );
3285 
3286             /* Set the second most significant bit to 1 */
3287             MBEDTLS_MPI_CHK(
3288                     mbedtls_mpi_set_bit( &key->d,
3289                                          ECP_CURVE25519_KEY_SIZE * 8 - 2, 1 )
3290                     );
3291         }
3292         else
3293             ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
3294     }
3295 
3296 #endif
3297 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3298     if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
3299     {
3300         MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) );
3301 
3302         MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( &key->grp, &key->d ) );
3303     }
3304 
3305 #endif
3306 cleanup:
3307 
3308     if( ret != 0 )
3309         mbedtls_mpi_free( &key->d );
3310 
3311     return( ret );
3312 }
3313 
3314 /*
3315  * Write a private key.
3316  */
mbedtls_ecp_write_key(mbedtls_ecp_keypair * key,unsigned char * buf,size_t buflen)3317 int mbedtls_ecp_write_key( mbedtls_ecp_keypair *key,
3318                            unsigned char *buf, size_t buflen )
3319 {
3320     int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
3321 
3322     ECP_VALIDATE_RET( key != NULL );
3323     ECP_VALIDATE_RET( buf != NULL );
3324 
3325 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3326     if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
3327     {
3328         if( key->grp.id == MBEDTLS_ECP_DP_CURVE25519 )
3329         {
3330             if( buflen < ECP_CURVE25519_KEY_SIZE )
3331                 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
3332 
3333             MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &key->d, buf, buflen ) );
3334         }
3335         else
3336             ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
3337     }
3338 
3339 #endif
3340 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3341     if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
3342     {
3343         MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &key->d, buf, buflen ) );
3344     }
3345 
3346 #endif
3347 cleanup:
3348 
3349     return( ret );
3350 }
3351 
3352 
3353 /*
3354  * Check a public-private key pair
3355  */
mbedtls_ecp_check_pub_priv(const mbedtls_ecp_keypair * pub,const mbedtls_ecp_keypair * prv)3356 int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv )
3357 {
3358     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3359     mbedtls_ecp_point Q;
3360     mbedtls_ecp_group grp;
3361     ECP_VALIDATE_RET( pub != NULL );
3362     ECP_VALIDATE_RET( prv != NULL );
3363 
3364     if( pub->grp.id == MBEDTLS_ECP_DP_NONE ||
3365         pub->grp.id != prv->grp.id ||
3366         mbedtls_mpi_cmp_mpi( &pub->Q.X, &prv->Q.X ) ||
3367         mbedtls_mpi_cmp_mpi( &pub->Q.Y, &prv->Q.Y ) ||
3368         mbedtls_mpi_cmp_mpi( &pub->Q.Z, &prv->Q.Z ) )
3369     {
3370         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
3371     }
3372 
3373     mbedtls_ecp_point_init( &Q );
3374     mbedtls_ecp_group_init( &grp );
3375 
3376     /* mbedtls_ecp_mul() needs a non-const group... */
3377     mbedtls_ecp_group_copy( &grp, &prv->grp );
3378 
3379     /* Also checks d is valid */
3380     MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) );
3381 
3382     if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) ||
3383         mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) ||
3384         mbedtls_mpi_cmp_mpi( &Q.Z, &prv->Q.Z ) )
3385     {
3386         ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3387         goto cleanup;
3388     }
3389 
3390 cleanup:
3391     mbedtls_ecp_point_free( &Q );
3392     mbedtls_ecp_group_free( &grp );
3393 
3394     return( ret );
3395 }
3396 
3397 #if defined(MBEDTLS_SELF_TEST)
3398 
3399 /* Adjust the exponent to be a valid private point for the specified curve.
3400  * This is sometimes necessary because we use a single set of exponents
3401  * for all curves but the validity of values depends on the curve. */
self_test_adjust_exponent(const mbedtls_ecp_group * grp,mbedtls_mpi * m)3402 static int self_test_adjust_exponent( const mbedtls_ecp_group *grp,
3403                                       mbedtls_mpi *m )
3404 {
3405     int ret = 0;
3406     switch( grp->id )
3407     {
3408         /* If Curve25519 is available, then that's what we use for the
3409          * Montgomery test, so we don't need the adjustment code. */
3410 #if ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
3411 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
3412         case MBEDTLS_ECP_DP_CURVE448:
3413             /* Move highest bit from 254 to N-1. Setting bit N-1 is
3414              * necessary to enforce the highest-bit-set constraint. */
3415             MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( m, 254, 0 ) );
3416             MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( m, grp->nbits, 1 ) );
3417             /* Copy second-highest bit from 253 to N-2. This is not
3418              * necessary but improves the test variety a bit. */
3419             MBEDTLS_MPI_CHK(
3420                 mbedtls_mpi_set_bit( m, grp->nbits - 1,
3421                                      mbedtls_mpi_get_bit( m, 253 ) ) );
3422             break;
3423 #endif
3424 #endif /* ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) */
3425         default:
3426             /* Non-Montgomery curves and Curve25519 need no adjustment. */
3427             (void) grp;
3428             (void) m;
3429             goto cleanup;
3430     }
3431 cleanup:
3432     return( ret );
3433 }
3434 
3435 /* Calculate R = m.P for each m in exponents. Check that the number of
3436  * 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)3437 static int self_test_point( int verbose,
3438                             mbedtls_ecp_group *grp,
3439                             mbedtls_ecp_point *R,
3440                             mbedtls_mpi *m,
3441                             const mbedtls_ecp_point *P,
3442                             const char *const *exponents,
3443                             size_t n_exponents )
3444 {
3445     int ret = 0;
3446     size_t i = 0;
3447     unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
3448     add_count = 0;
3449     dbl_count = 0;
3450     mul_count = 0;
3451 
3452     MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[0] ) );
3453     MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
3454     MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
3455 
3456     for( i = 1; i < n_exponents; i++ )
3457     {
3458         add_c_prev = add_count;
3459         dbl_c_prev = dbl_count;
3460         mul_c_prev = mul_count;
3461         add_count = 0;
3462         dbl_count = 0;
3463         mul_count = 0;
3464 
3465         MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[i] ) );
3466         MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
3467         MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
3468 
3469         if( add_count != add_c_prev ||
3470             dbl_count != dbl_c_prev ||
3471             mul_count != mul_c_prev )
3472         {
3473             ret = 1;
3474             break;
3475         }
3476     }
3477 
3478 cleanup:
3479     if( verbose != 0 )
3480     {
3481         if( ret != 0 )
3482             mbedtls_printf( "failed (%u)\n", (unsigned int) i );
3483         else
3484             mbedtls_printf( "passed\n" );
3485     }
3486     return( ret );
3487 }
3488 
3489 /*
3490  * Checkup routine
3491  */
mbedtls_ecp_self_test(int verbose)3492 int mbedtls_ecp_self_test( int verbose )
3493 {
3494     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3495     mbedtls_ecp_group grp;
3496     mbedtls_ecp_point R, P;
3497     mbedtls_mpi m;
3498 
3499 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3500     /* Exponents especially adapted for secp192k1, which has the lowest
3501      * order n of all supported curves (secp192r1 is in a slightly larger
3502      * field but the order of its base point is slightly smaller). */
3503     const char *sw_exponents[] =
3504     {
3505         "000000000000000000000000000000000000000000000001", /* one */
3506         "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8C", /* n - 1 */
3507         "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
3508         "400000000000000000000000000000000000000000000000", /* one and zeros */
3509         "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */
3510         "555555555555555555555555555555555555555555555555", /* 101010... */
3511     };
3512 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3513 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3514     const char *m_exponents[] =
3515     {
3516         /* Valid private values for Curve25519. In a build with Curve448
3517          * but not Curve25519, they will be adjusted in
3518          * self_test_adjust_exponent(). */
3519         "4000000000000000000000000000000000000000000000000000000000000000",
3520         "5C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C30",
3521         "5715ECCE24583F7A7023C24164390586842E816D7280A49EF6DF4EAE6B280BF8",
3522         "41A2B017516F6D254E1F002BCCBADD54BE30F8CEC737A0E912B4963B6BA74460",
3523         "5555555555555555555555555555555555555555555555555555555555555550",
3524         "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8",
3525     };
3526 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3527 
3528     mbedtls_ecp_group_init( &grp );
3529     mbedtls_ecp_point_init( &R );
3530     mbedtls_ecp_point_init( &P );
3531     mbedtls_mpi_init( &m );
3532 
3533 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
3534     /* Use secp192r1 if available, or any available curve */
3535 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
3536     MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) );
3537 #else
3538     MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, mbedtls_ecp_curve_list()->grp_id ) );
3539 #endif
3540 
3541     if( verbose != 0 )
3542         mbedtls_printf( "  ECP SW test #1 (constant op_count, base point G): " );
3543     /* Do a dummy multiplication first to trigger precomputation */
3544     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
3545     MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
3546     ret = self_test_point( verbose,
3547                            &grp, &R, &m, &grp.G,
3548                            sw_exponents,
3549                            sizeof( sw_exponents ) / sizeof( sw_exponents[0] ));
3550     if( ret != 0 )
3551         goto cleanup;
3552 
3553     if( verbose != 0 )
3554         mbedtls_printf( "  ECP SW test #2 (constant op_count, other point): " );
3555     /* We computed P = 2G last time, use it */
3556     ret = self_test_point( verbose,
3557                            &grp, &R, &m, &P,
3558                            sw_exponents,
3559                            sizeof( sw_exponents ) / sizeof( sw_exponents[0] ));
3560     if( ret != 0 )
3561         goto cleanup;
3562 
3563     mbedtls_ecp_group_free( &grp );
3564     mbedtls_ecp_point_free( &R );
3565 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
3566 
3567 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
3568     if( verbose != 0 )
3569         mbedtls_printf( "  ECP Montgomery test (constant op_count): " );
3570 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
3571     MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_CURVE25519 ) );
3572 #elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
3573     MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_CURVE448 ) );
3574 #else
3575 #error "MBEDTLS_ECP_MONTGOMERY_ENABLED is defined, but no curve is supported for self-test"
3576 #endif
3577     ret = self_test_point( verbose,
3578                            &grp, &R, &m, &grp.G,
3579                            m_exponents,
3580                            sizeof( m_exponents ) / sizeof( m_exponents[0] ));
3581     if( ret != 0 )
3582         goto cleanup;
3583 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3584 
3585 cleanup:
3586 
3587     if( ret < 0 && verbose != 0 )
3588         mbedtls_printf( "Unexpected error, return code = %08X\n", (unsigned int) ret );
3589 
3590     mbedtls_ecp_group_free( &grp );
3591     mbedtls_ecp_point_free( &R );
3592     mbedtls_ecp_point_free( &P );
3593     mbedtls_mpi_free( &m );
3594 
3595     if( verbose != 0 )
3596         mbedtls_printf( "\n" );
3597 
3598     return( ret );
3599 }
3600 
3601 #endif /* MBEDTLS_SELF_TEST */
3602 
3603 #endif /* !MBEDTLS_ECP_ALT */
3604 
3605 #endif /* MBEDTLS_ECP_C */
3606