1 /*
2  *  Elliptic curve DSA
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  */
25 
26 #include "common.h"
27 
28 #if defined(MBEDTLS_ECDSA_C)
29 
30 #include "mbedtls/ecdsa.h"
31 #include "mbedtls/asn1write.h"
32 
33 #include <string.h>
34 
35 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
36 #include "mbedtls/hmac_drbg.h"
37 #endif
38 
39 #if defined(MBEDTLS_PLATFORM_C)
40 #include "mbedtls/platform.h"
41 #else
42 #include <stdlib.h>
43 #define mbedtls_calloc    calloc
44 #define mbedtls_free       free
45 #endif
46 
47 #include "mbedtls/platform_util.h"
48 #include "mbedtls/error.h"
49 
50 /* Parameter validation macros based on platform_util.h */
51 #define ECDSA_VALIDATE_RET( cond )    \
52     MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
53 #define ECDSA_VALIDATE( cond )        \
54     MBEDTLS_INTERNAL_VALIDATE( cond )
55 
56 #if defined(MBEDTLS_ECP_RESTARTABLE)
57 
58 /*
59  * Sub-context for ecdsa_verify()
60  */
61 struct mbedtls_ecdsa_restart_ver
62 {
63     mbedtls_mpi u1, u2;     /* intermediate values  */
64     enum {                  /* what to do next?     */
65         ecdsa_ver_init = 0, /* getting started      */
66         ecdsa_ver_muladd,   /* muladd step          */
67     } state;
68 };
69 
70 /*
71  * Init verify restart sub-context
72  */
ecdsa_restart_ver_init(mbedtls_ecdsa_restart_ver_ctx * ctx)73 static void ecdsa_restart_ver_init( mbedtls_ecdsa_restart_ver_ctx *ctx )
74 {
75     mbedtls_mpi_init( &ctx->u1 );
76     mbedtls_mpi_init( &ctx->u2 );
77     ctx->state = ecdsa_ver_init;
78 }
79 
80 /*
81  * Free the components of a verify restart sub-context
82  */
ecdsa_restart_ver_free(mbedtls_ecdsa_restart_ver_ctx * ctx)83 static void ecdsa_restart_ver_free( mbedtls_ecdsa_restart_ver_ctx *ctx )
84 {
85     if( ctx == NULL )
86         return;
87 
88     mbedtls_mpi_free( &ctx->u1 );
89     mbedtls_mpi_free( &ctx->u2 );
90 
91     ecdsa_restart_ver_init( ctx );
92 }
93 
94 /*
95  * Sub-context for ecdsa_sign()
96  */
97 struct mbedtls_ecdsa_restart_sig
98 {
99     int sign_tries;
100     int key_tries;
101     mbedtls_mpi k;          /* per-signature random */
102     mbedtls_mpi r;          /* r value              */
103     enum {                  /* what to do next?     */
104         ecdsa_sig_init = 0, /* getting started      */
105         ecdsa_sig_mul,      /* doing ecp_mul()      */
106         ecdsa_sig_modn,     /* mod N computations   */
107     } state;
108 };
109 
110 /*
111  * Init verify sign sub-context
112  */
ecdsa_restart_sig_init(mbedtls_ecdsa_restart_sig_ctx * ctx)113 static void ecdsa_restart_sig_init( mbedtls_ecdsa_restart_sig_ctx *ctx )
114 {
115     ctx->sign_tries = 0;
116     ctx->key_tries = 0;
117     mbedtls_mpi_init( &ctx->k );
118     mbedtls_mpi_init( &ctx->r );
119     ctx->state = ecdsa_sig_init;
120 }
121 
122 /*
123  * Free the components of a sign restart sub-context
124  */
ecdsa_restart_sig_free(mbedtls_ecdsa_restart_sig_ctx * ctx)125 static void ecdsa_restart_sig_free( mbedtls_ecdsa_restart_sig_ctx *ctx )
126 {
127     if( ctx == NULL )
128         return;
129 
130     mbedtls_mpi_free( &ctx->k );
131     mbedtls_mpi_free( &ctx->r );
132 }
133 
134 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
135 /*
136  * Sub-context for ecdsa_sign_det()
137  */
138 struct mbedtls_ecdsa_restart_det
139 {
140     mbedtls_hmac_drbg_context rng_ctx;  /* DRBG state   */
141     enum {                      /* what to do next?     */
142         ecdsa_det_init = 0,     /* getting started      */
143         ecdsa_det_sign,         /* make signature       */
144     } state;
145 };
146 
147 /*
148  * Init verify sign_det sub-context
149  */
ecdsa_restart_det_init(mbedtls_ecdsa_restart_det_ctx * ctx)150 static void ecdsa_restart_det_init( mbedtls_ecdsa_restart_det_ctx *ctx )
151 {
152     mbedtls_hmac_drbg_init( &ctx->rng_ctx );
153     ctx->state = ecdsa_det_init;
154 }
155 
156 /*
157  * Free the components of a sign_det restart sub-context
158  */
ecdsa_restart_det_free(mbedtls_ecdsa_restart_det_ctx * ctx)159 static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx )
160 {
161     if( ctx == NULL )
162         return;
163 
164     mbedtls_hmac_drbg_free( &ctx->rng_ctx );
165 
166     ecdsa_restart_det_init( ctx );
167 }
168 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
169 
170 #define ECDSA_RS_ECP    ( rs_ctx == NULL ? NULL : &rs_ctx->ecp )
171 
172 /* Utility macro for checking and updating ops budget */
173 #define ECDSA_BUDGET( ops )   \
174     MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, ECDSA_RS_ECP, ops ) );
175 
176 /* Call this when entering a function that needs its own sub-context */
177 #define ECDSA_RS_ENTER( SUB )   do {                                 \
178     /* reset ops count for this call if top-level */                 \
179     if( rs_ctx != NULL && rs_ctx->ecp.depth++ == 0 )                 \
180         rs_ctx->ecp.ops_done = 0;                                    \
181                                                                      \
182     /* set up our own sub-context if needed */                       \
183     if( mbedtls_ecp_restart_is_enabled() &&                          \
184         rs_ctx != NULL && rs_ctx->SUB == NULL )                      \
185     {                                                                \
186         rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) );   \
187         if( rs_ctx->SUB == NULL )                                    \
188             return( MBEDTLS_ERR_ECP_ALLOC_FAILED );                  \
189                                                                      \
190         ecdsa_restart_## SUB ##_init( rs_ctx->SUB );                 \
191     }                                                                \
192 } while( 0 )
193 
194 /* Call this when leaving a function that needs its own sub-context */
195 #define ECDSA_RS_LEAVE( SUB )   do {                                 \
196     /* clear our sub-context when not in progress (done or error) */ \
197     if( rs_ctx != NULL && rs_ctx->SUB != NULL &&                     \
198         ret != MBEDTLS_ERR_ECP_IN_PROGRESS )                         \
199     {                                                                \
200         ecdsa_restart_## SUB ##_free( rs_ctx->SUB );                 \
201         mbedtls_free( rs_ctx->SUB );                                 \
202         rs_ctx->SUB = NULL;                                          \
203     }                                                                \
204                                                                      \
205     if( rs_ctx != NULL )                                             \
206         rs_ctx->ecp.depth--;                                         \
207 } while( 0 )
208 
209 #else /* MBEDTLS_ECP_RESTARTABLE */
210 
211 #define ECDSA_RS_ECP    NULL
212 
213 #define ECDSA_BUDGET( ops )   /* no-op; for compatibility */
214 
215 #define ECDSA_RS_ENTER( SUB )   (void) rs_ctx
216 #define ECDSA_RS_LEAVE( SUB )   (void) rs_ctx
217 
218 #endif /* MBEDTLS_ECP_RESTARTABLE */
219 
220 #if defined(MBEDTLS_ECDSA_DETERMINISTIC) || \
221     !defined(MBEDTLS_ECDSA_SIGN_ALT)     || \
222     !defined(MBEDTLS_ECDSA_VERIFY_ALT)
223 /*
224  * Derive a suitable integer for group grp from a buffer of length len
225  * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
226  */
derive_mpi(const mbedtls_ecp_group * grp,mbedtls_mpi * x,const unsigned char * buf,size_t blen)227 static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
228                        const unsigned char *buf, size_t blen )
229 {
230     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
231     size_t n_size = ( grp->nbits + 7 ) / 8;
232     size_t use_size = blen > n_size ? n_size : blen;
233 
234     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) );
235     if( use_size * 8 > grp->nbits )
236         MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) );
237 
238     /* While at it, reduce modulo N */
239     if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 )
240         MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) );
241 
242 cleanup:
243     return( ret );
244 }
245 #endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */
246 
247 #if !defined(MBEDTLS_ECDSA_SIGN_ALT)
248 /*
249  * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
250  * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
251  */
ecdsa_sign_restartable(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int (* f_rng_blind)(void *,unsigned char *,size_t),void * p_rng_blind,mbedtls_ecdsa_restart_ctx * rs_ctx)252 static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
253                 mbedtls_mpi *r, mbedtls_mpi *s,
254                 const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
255                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
256                 int (*f_rng_blind)(void *, unsigned char *, size_t),
257                 void *p_rng_blind,
258                 mbedtls_ecdsa_restart_ctx *rs_ctx )
259 {
260     int ret, key_tries, sign_tries;
261     int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
262     mbedtls_ecp_point R;
263     mbedtls_mpi k, e, t;
264     mbedtls_mpi *pk = &k, *pr = r;
265 
266     /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
267     if( ! mbedtls_ecdsa_can_do( grp->id ) || grp->N.p == NULL )
268         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
269 
270     /* Make sure d is in range 1..n-1 */
271     if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
272         return( MBEDTLS_ERR_ECP_INVALID_KEY );
273 
274     mbedtls_ecp_point_init( &R );
275     mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t );
276 
277     ECDSA_RS_ENTER( sig );
278 
279 #if defined(MBEDTLS_ECP_RESTARTABLE)
280     if( rs_ctx != NULL && rs_ctx->sig != NULL )
281     {
282         /* redirect to our context */
283         p_sign_tries = &rs_ctx->sig->sign_tries;
284         p_key_tries = &rs_ctx->sig->key_tries;
285         pk = &rs_ctx->sig->k;
286         pr = &rs_ctx->sig->r;
287 
288         /* jump to current step */
289         if( rs_ctx->sig->state == ecdsa_sig_mul )
290             goto mul;
291         if( rs_ctx->sig->state == ecdsa_sig_modn )
292             goto modn;
293     }
294 #endif /* MBEDTLS_ECP_RESTARTABLE */
295 
296     *p_sign_tries = 0;
297     do
298     {
299         if( (*p_sign_tries)++ > 10 )
300         {
301             ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
302             goto cleanup;
303         }
304 
305         /*
306          * Steps 1-3: generate a suitable ephemeral keypair
307          * and set r = xR mod n
308          */
309         *p_key_tries = 0;
310         do
311         {
312             if( (*p_key_tries)++ > 10 )
313             {
314                 ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
315                 goto cleanup;
316             }
317 
318             MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, pk, f_rng, p_rng ) );
319 
320 #if defined(MBEDTLS_ECP_RESTARTABLE)
321             if( rs_ctx != NULL && rs_ctx->sig != NULL )
322                 rs_ctx->sig->state = ecdsa_sig_mul;
323 
324 mul:
325 #endif
326             MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &R, pk, &grp->G,
327                                                           f_rng_blind,
328                                                           p_rng_blind,
329                                                           ECDSA_RS_ECP ) );
330             MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) );
331         }
332         while( mbedtls_mpi_cmp_int( pr, 0 ) == 0 );
333 
334 #if defined(MBEDTLS_ECP_RESTARTABLE)
335         if( rs_ctx != NULL && rs_ctx->sig != NULL )
336             rs_ctx->sig->state = ecdsa_sig_modn;
337 
338 modn:
339 #endif
340         /*
341          * Accounting for everything up to the end of the loop
342          * (step 6, but checking now avoids saving e and t)
343          */
344         ECDSA_BUDGET( MBEDTLS_ECP_OPS_INV + 4 );
345 
346         /*
347          * Step 5: derive MPI from hashed message
348          */
349         MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
350 
351         /*
352          * Generate a random value to blind inv_mod in next step,
353          * avoiding a potential timing leak.
354          */
355         MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng_blind,
356                                                   p_rng_blind ) );
357 
358         /*
359          * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
360          */
361         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, pr, d ) );
362         MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
363         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
364         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) );
365         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pk, pk, &grp->N ) );
366         MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) );
367         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
368         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
369     }
370     while( mbedtls_mpi_cmp_int( s, 0 ) == 0 );
371 
372 #if defined(MBEDTLS_ECP_RESTARTABLE)
373     if( rs_ctx != NULL && rs_ctx->sig != NULL )
374         mbedtls_mpi_copy( r, pr );
375 #endif
376 
377 cleanup:
378     mbedtls_ecp_point_free( &R );
379     mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t );
380 
381     ECDSA_RS_LEAVE( sig );
382 
383     return( ret );
384 }
385 
mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid)386 int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid )
387 {
388     switch( gid )
389     {
390 #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
391         case MBEDTLS_ECP_DP_CURVE25519: return 0;
392 #endif
393 #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
394         case MBEDTLS_ECP_DP_CURVE448: return 0;
395 #endif
396     default: return 1;
397     }
398 }
399 
400 /*
401  * Compute ECDSA signature of a hashed message
402  */
mbedtls_ecdsa_sign(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)403 int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
404                 const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
405                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
406 {
407     ECDSA_VALIDATE_RET( grp   != NULL );
408     ECDSA_VALIDATE_RET( r     != NULL );
409     ECDSA_VALIDATE_RET( s     != NULL );
410     ECDSA_VALIDATE_RET( d     != NULL );
411     ECDSA_VALIDATE_RET( f_rng != NULL );
412     ECDSA_VALIDATE_RET( buf   != NULL || blen == 0 );
413 
414     /* Use the same RNG for both blinding and ephemeral key generation */
415     return( ecdsa_sign_restartable( grp, r, s, d, buf, blen,
416                                     f_rng, p_rng, f_rng, p_rng, NULL ) );
417 }
418 #endif /* !MBEDTLS_ECDSA_SIGN_ALT */
419 
420 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
421 /*
422  * Deterministic signature wrapper
423  */
ecdsa_sign_det_restartable(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen,mbedtls_md_type_t md_alg,int (* f_rng_blind)(void *,unsigned char *,size_t),void * p_rng_blind,mbedtls_ecdsa_restart_ctx * rs_ctx)424 static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
425                     mbedtls_mpi *r, mbedtls_mpi *s,
426                     const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
427                     mbedtls_md_type_t md_alg,
428                     int (*f_rng_blind)(void *, unsigned char *, size_t),
429                     void *p_rng_blind,
430                     mbedtls_ecdsa_restart_ctx *rs_ctx )
431 {
432     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
433     mbedtls_hmac_drbg_context rng_ctx;
434     mbedtls_hmac_drbg_context *p_rng = &rng_ctx;
435     unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
436     size_t grp_len = ( grp->nbits + 7 ) / 8;
437     const mbedtls_md_info_t *md_info;
438     mbedtls_mpi h;
439 
440     if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
441         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
442 
443     mbedtls_mpi_init( &h );
444     mbedtls_hmac_drbg_init( &rng_ctx );
445 
446     ECDSA_RS_ENTER( det );
447 
448 #if defined(MBEDTLS_ECP_RESTARTABLE)
449     if( rs_ctx != NULL && rs_ctx->det != NULL )
450     {
451         /* redirect to our context */
452         p_rng = &rs_ctx->det->rng_ctx;
453 
454         /* jump to current step */
455         if( rs_ctx->det->state == ecdsa_det_sign )
456             goto sign;
457     }
458 #endif /* MBEDTLS_ECP_RESTARTABLE */
459 
460     /* Use private key and message hash (reduced) to initialize HMAC_DRBG */
461     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
462     MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
463     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) );
464     mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len );
465 
466 #if defined(MBEDTLS_ECP_RESTARTABLE)
467     if( rs_ctx != NULL && rs_ctx->det != NULL )
468         rs_ctx->det->state = ecdsa_det_sign;
469 
470 sign:
471 #endif
472 #if defined(MBEDTLS_ECDSA_SIGN_ALT)
473     (void) f_rng_blind;
474     (void) p_rng_blind;
475     ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
476                               mbedtls_hmac_drbg_random, p_rng );
477 #else
478     if( f_rng_blind != NULL )
479         ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
480                                       mbedtls_hmac_drbg_random, p_rng,
481                                       f_rng_blind, p_rng_blind, rs_ctx );
482     else
483     {
484         mbedtls_hmac_drbg_context *p_rng_blind_det;
485 
486 #if !defined(MBEDTLS_ECP_RESTARTABLE)
487         /*
488          * To avoid reusing rng_ctx and risking incorrect behavior we seed a
489          * second HMAC-DRBG with the same seed. We also apply a label to avoid
490          * reusing the bits of the ephemeral key for blinding and eliminate the
491          * risk that they leak this way.
492          */
493         const char* blind_label = "BLINDING CONTEXT";
494         mbedtls_hmac_drbg_context rng_ctx_blind;
495 
496         mbedtls_hmac_drbg_init( &rng_ctx_blind );
497         p_rng_blind_det = &rng_ctx_blind;
498         mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info,
499                                     data, 2 * grp_len );
500         ret = mbedtls_hmac_drbg_update_ret( p_rng_blind_det,
501                                             (const unsigned char*) blind_label,
502                                             strlen( blind_label ) );
503         if( ret != 0 )
504         {
505             mbedtls_hmac_drbg_free( &rng_ctx_blind );
506             goto cleanup;
507         }
508 #else
509         /*
510          * In the case of restartable computations we would either need to store
511          * the second RNG in the restart context too or set it up at every
512          * restart. The first option would penalize the correct application of
513          * the function and the second would defeat the purpose of the
514          * restartable feature.
515          *
516          * Therefore in this case we reuse the original RNG. This comes with the
517          * price that the resulting signature might not be a valid deterministic
518          * ECDSA signature with a very low probability (same magnitude as
519          * successfully guessing the private key). However even then it is still
520          * a valid ECDSA signature.
521          */
522         p_rng_blind_det = p_rng;
523 #endif /* MBEDTLS_ECP_RESTARTABLE */
524 
525         /*
526          * Since the output of the RNGs is always the same for the same key and
527          * message, this limits the efficiency of blinding and leaks information
528          * through side channels. After mbedtls_ecdsa_sign_det() is removed NULL
529          * won't be a valid value for f_rng_blind anymore. Therefore it should
530          * be checked by the caller and this branch and check can be removed.
531          */
532         ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
533                                       mbedtls_hmac_drbg_random, p_rng,
534                                       mbedtls_hmac_drbg_random, p_rng_blind_det,
535                                       rs_ctx );
536 
537 #if !defined(MBEDTLS_ECP_RESTARTABLE)
538         mbedtls_hmac_drbg_free( &rng_ctx_blind );
539 #endif
540     }
541 #endif /* MBEDTLS_ECDSA_SIGN_ALT */
542 
543 cleanup:
544     mbedtls_hmac_drbg_free( &rng_ctx );
545     mbedtls_mpi_free( &h );
546 
547     ECDSA_RS_LEAVE( det );
548 
549     return( ret );
550 }
551 
552 /*
553  * Deterministic signature wrappers
554  */
555 
556 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_ecdsa_sign_det(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen,mbedtls_md_type_t md_alg)557 int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
558                             mbedtls_mpi *s, const mbedtls_mpi *d,
559                             const unsigned char *buf, size_t blen,
560                             mbedtls_md_type_t md_alg )
561 {
562     ECDSA_VALIDATE_RET( grp   != NULL );
563     ECDSA_VALIDATE_RET( r     != NULL );
564     ECDSA_VALIDATE_RET( s     != NULL );
565     ECDSA_VALIDATE_RET( d     != NULL );
566     ECDSA_VALIDATE_RET( buf   != NULL || blen == 0 );
567 
568     return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg,
569                                         NULL, NULL, NULL ) );
570 }
571 #endif /* MBEDTLS_DEPRECATED_REMOVED */
572 
mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen,mbedtls_md_type_t md_alg,int (* f_rng_blind)(void *,unsigned char *,size_t),void * p_rng_blind)573 int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
574                                 mbedtls_mpi *s, const mbedtls_mpi *d,
575                                 const unsigned char *buf, size_t blen,
576                                 mbedtls_md_type_t md_alg,
577                                 int (*f_rng_blind)(void *, unsigned char *,
578                                                    size_t),
579                                 void *p_rng_blind )
580 {
581     ECDSA_VALIDATE_RET( grp   != NULL );
582     ECDSA_VALIDATE_RET( r     != NULL );
583     ECDSA_VALIDATE_RET( s     != NULL );
584     ECDSA_VALIDATE_RET( d     != NULL );
585     ECDSA_VALIDATE_RET( buf   != NULL || blen == 0 );
586     ECDSA_VALIDATE_RET( f_rng_blind != NULL );
587 
588     return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg,
589                                         f_rng_blind, p_rng_blind, NULL ) );
590 }
591 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
592 
593 #if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
594 /*
595  * Verify ECDSA signature of hashed message (SEC1 4.1.4)
596  * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
597  */
ecdsa_verify_restartable(mbedtls_ecp_group * grp,const unsigned char * buf,size_t blen,const mbedtls_ecp_point * Q,const mbedtls_mpi * r,const mbedtls_mpi * s,mbedtls_ecdsa_restart_ctx * rs_ctx)598 static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
599                                      const unsigned char *buf, size_t blen,
600                                      const mbedtls_ecp_point *Q,
601                                      const mbedtls_mpi *r, const mbedtls_mpi *s,
602                                      mbedtls_ecdsa_restart_ctx *rs_ctx )
603 {
604     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
605     mbedtls_mpi e, s_inv, u1, u2;
606     mbedtls_ecp_point R;
607     mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
608 
609     mbedtls_ecp_point_init( &R );
610     mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv );
611     mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
612 
613     /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
614     if( ! mbedtls_ecdsa_can_do( grp->id ) || grp->N.p == NULL )
615         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
616 
617     ECDSA_RS_ENTER( ver );
618 
619 #if defined(MBEDTLS_ECP_RESTARTABLE)
620     if( rs_ctx != NULL && rs_ctx->ver != NULL )
621     {
622         /* redirect to our context */
623         pu1 = &rs_ctx->ver->u1;
624         pu2 = &rs_ctx->ver->u2;
625 
626         /* jump to current step */
627         if( rs_ctx->ver->state == ecdsa_ver_muladd )
628             goto muladd;
629     }
630 #endif /* MBEDTLS_ECP_RESTARTABLE */
631 
632     /*
633      * Step 1: make sure r and s are in range 1..n-1
634      */
635     if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 ||
636         mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 )
637     {
638         ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
639         goto cleanup;
640     }
641 
642     /*
643      * Step 3: derive MPI from hashed message
644      */
645     MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
646 
647     /*
648      * Step 4: u1 = e / s mod n, u2 = r / s mod n
649      */
650     ECDSA_BUDGET( MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2 );
651 
652     MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) );
653 
654     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu1, &e, &s_inv ) );
655     MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu1, pu1, &grp->N ) );
656 
657     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu2, r, &s_inv ) );
658     MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu2, pu2, &grp->N ) );
659 
660 #if defined(MBEDTLS_ECP_RESTARTABLE)
661     if( rs_ctx != NULL && rs_ctx->ver != NULL )
662         rs_ctx->ver->state = ecdsa_ver_muladd;
663 
664 muladd:
665 #endif
666     /*
667      * Step 5: R = u1 G + u2 Q
668      */
669     MBEDTLS_MPI_CHK( mbedtls_ecp_muladd_restartable( grp,
670                      &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP ) );
671 
672     if( mbedtls_ecp_is_zero( &R ) )
673     {
674         ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
675         goto cleanup;
676     }
677 
678     /*
679      * Step 6: convert xR to an integer (no-op)
680      * Step 7: reduce xR mod n (gives v)
681      */
682     MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) );
683 
684     /*
685      * Step 8: check if v (that is, R.X) is equal to r
686      */
687     if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 )
688     {
689         ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
690         goto cleanup;
691     }
692 
693 cleanup:
694     mbedtls_ecp_point_free( &R );
695     mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv );
696     mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 );
697 
698     ECDSA_RS_LEAVE( ver );
699 
700     return( ret );
701 }
702 
703 /*
704  * Verify ECDSA signature of hashed message
705  */
mbedtls_ecdsa_verify(mbedtls_ecp_group * grp,const unsigned char * buf,size_t blen,const mbedtls_ecp_point * Q,const mbedtls_mpi * r,const mbedtls_mpi * s)706 int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
707                           const unsigned char *buf, size_t blen,
708                           const mbedtls_ecp_point *Q,
709                           const mbedtls_mpi *r,
710                           const mbedtls_mpi *s)
711 {
712     ECDSA_VALIDATE_RET( grp != NULL );
713     ECDSA_VALIDATE_RET( Q   != NULL );
714     ECDSA_VALIDATE_RET( r   != NULL );
715     ECDSA_VALIDATE_RET( s   != NULL );
716     ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
717 
718     return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) );
719 }
720 #endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
721 
722 /*
723  * Convert a signature (given by context) to ASN.1
724  */
ecdsa_signature_to_asn1(const mbedtls_mpi * r,const mbedtls_mpi * s,unsigned char * sig,size_t * slen)725 static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
726                                     unsigned char *sig, size_t *slen )
727 {
728     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
729     unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = {0};
730     unsigned char *p = buf + sizeof( buf );
731     size_t len = 0;
732 
733     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) );
734     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) );
735 
736     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) );
737     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
738                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
739 
740     memcpy( sig, p, len );
741     *slen = len;
742 
743     return( 0 );
744 }
745 
746 /*
747  * Compute and write signature
748  */
mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hlen,unsigned char * sig,size_t * slen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_ecdsa_restart_ctx * rs_ctx)749 int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
750                            mbedtls_md_type_t md_alg,
751                            const unsigned char *hash, size_t hlen,
752                            unsigned char *sig, size_t *slen,
753                            int (*f_rng)(void *, unsigned char *, size_t),
754                            void *p_rng,
755                            mbedtls_ecdsa_restart_ctx *rs_ctx )
756 {
757     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
758     mbedtls_mpi r, s;
759     ECDSA_VALIDATE_RET( ctx  != NULL );
760     ECDSA_VALIDATE_RET( hash != NULL );
761     ECDSA_VALIDATE_RET( sig  != NULL );
762     ECDSA_VALIDATE_RET( slen != NULL );
763 
764     mbedtls_mpi_init( &r );
765     mbedtls_mpi_init( &s );
766 
767 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
768     MBEDTLS_MPI_CHK( ecdsa_sign_det_restartable( &ctx->grp, &r, &s, &ctx->d,
769                                                  hash, hlen, md_alg, f_rng,
770                                                  p_rng, rs_ctx ) );
771 #else
772     (void) md_alg;
773 
774 #if defined(MBEDTLS_ECDSA_SIGN_ALT)
775     (void) rs_ctx;
776 
777     MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
778                          hash, hlen, f_rng, p_rng ) );
779 #else
780     /* Use the same RNG for both blinding and ephemeral key generation */
781     MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d,
782                                              hash, hlen, f_rng, p_rng, f_rng,
783                                              p_rng, rs_ctx ) );
784 #endif /* MBEDTLS_ECDSA_SIGN_ALT */
785 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
786 
787     MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) );
788 
789 cleanup:
790     mbedtls_mpi_free( &r );
791     mbedtls_mpi_free( &s );
792 
793     return( ret );
794 }
795 
796 /*
797  * Compute and write signature
798  */
mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hlen,unsigned char * sig,size_t * slen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)799 int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
800                                  mbedtls_md_type_t md_alg,
801                                  const unsigned char *hash, size_t hlen,
802                                  unsigned char *sig, size_t *slen,
803                                  int (*f_rng)(void *, unsigned char *, size_t),
804                                  void *p_rng )
805 {
806     ECDSA_VALIDATE_RET( ctx  != NULL );
807     ECDSA_VALIDATE_RET( hash != NULL );
808     ECDSA_VALIDATE_RET( sig  != NULL );
809     ECDSA_VALIDATE_RET( slen != NULL );
810     return( mbedtls_ecdsa_write_signature_restartable(
811                 ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) );
812 }
813 
814 #if !defined(MBEDTLS_DEPRECATED_REMOVED) && \
815     defined(MBEDTLS_ECDSA_DETERMINISTIC)
mbedtls_ecdsa_write_signature_det(mbedtls_ecdsa_context * ctx,const unsigned char * hash,size_t hlen,unsigned char * sig,size_t * slen,mbedtls_md_type_t md_alg)816 int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
817                                const unsigned char *hash, size_t hlen,
818                                unsigned char *sig, size_t *slen,
819                                mbedtls_md_type_t md_alg )
820 {
821     ECDSA_VALIDATE_RET( ctx  != NULL );
822     ECDSA_VALIDATE_RET( hash != NULL );
823     ECDSA_VALIDATE_RET( sig  != NULL );
824     ECDSA_VALIDATE_RET( slen != NULL );
825     return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen,
826                                    NULL, NULL ) );
827 }
828 #endif
829 
830 /*
831  * Read and check signature
832  */
mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context * ctx,const unsigned char * hash,size_t hlen,const unsigned char * sig,size_t slen)833 int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
834                           const unsigned char *hash, size_t hlen,
835                           const unsigned char *sig, size_t slen )
836 {
837     ECDSA_VALIDATE_RET( ctx  != NULL );
838     ECDSA_VALIDATE_RET( hash != NULL );
839     ECDSA_VALIDATE_RET( sig  != NULL );
840     return( mbedtls_ecdsa_read_signature_restartable(
841                 ctx, hash, hlen, sig, slen, NULL ) );
842 }
843 
844 /*
845  * Restartable read and check signature
846  */
mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context * ctx,const unsigned char * hash,size_t hlen,const unsigned char * sig,size_t slen,mbedtls_ecdsa_restart_ctx * rs_ctx)847 int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
848                           const unsigned char *hash, size_t hlen,
849                           const unsigned char *sig, size_t slen,
850                           mbedtls_ecdsa_restart_ctx *rs_ctx )
851 {
852     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
853     unsigned char *p = (unsigned char *) sig;
854     const unsigned char *end = sig + slen;
855     size_t len;
856     mbedtls_mpi r, s;
857     ECDSA_VALIDATE_RET( ctx  != NULL );
858     ECDSA_VALIDATE_RET( hash != NULL );
859     ECDSA_VALIDATE_RET( sig  != NULL );
860 
861     mbedtls_mpi_init( &r );
862     mbedtls_mpi_init( &s );
863 
864     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
865                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
866     {
867         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
868         goto cleanup;
869     }
870 
871     if( p + len != end )
872     {
873         ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
874               MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
875         goto cleanup;
876     }
877 
878     if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 ||
879         ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 )
880     {
881         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
882         goto cleanup;
883     }
884 #if defined(MBEDTLS_ECDSA_VERIFY_ALT)
885     (void) rs_ctx;
886 
887     if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
888                                       &ctx->Q, &r, &s ) ) != 0 )
889         goto cleanup;
890 #else
891     if( ( ret = ecdsa_verify_restartable( &ctx->grp, hash, hlen,
892                               &ctx->Q, &r, &s, rs_ctx ) ) != 0 )
893         goto cleanup;
894 #endif /* MBEDTLS_ECDSA_VERIFY_ALT */
895 
896     /* At this point we know that the buffer starts with a valid signature.
897      * Return 0 if the buffer just contains the signature, and a specific
898      * error code if the valid signature is followed by more data. */
899     if( p != end )
900         ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
901 
902 cleanup:
903     mbedtls_mpi_free( &r );
904     mbedtls_mpi_free( &s );
905 
906     return( ret );
907 }
908 
909 #if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
910 /*
911  * Generate key pair
912  */
mbedtls_ecdsa_genkey(mbedtls_ecdsa_context * ctx,mbedtls_ecp_group_id gid,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)913 int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
914                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
915 {
916     int ret = 0;
917     ECDSA_VALIDATE_RET( ctx   != NULL );
918     ECDSA_VALIDATE_RET( f_rng != NULL );
919 
920     ret = mbedtls_ecp_group_load( &ctx->grp, gid );
921     if( ret != 0 )
922         return( ret );
923 
924    return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d,
925                                     &ctx->Q, f_rng, p_rng ) );
926 }
927 #endif /* !MBEDTLS_ECDSA_GENKEY_ALT */
928 
929 /*
930  * Set context from an mbedtls_ecp_keypair
931  */
mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context * ctx,const mbedtls_ecp_keypair * key)932 int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
933 {
934     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
935     ECDSA_VALIDATE_RET( ctx != NULL );
936     ECDSA_VALIDATE_RET( key != NULL );
937 
938     if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ||
939         ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ||
940         ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 )
941     {
942         mbedtls_ecdsa_free( ctx );
943     }
944 
945     return( ret );
946 }
947 
948 /*
949  * Initialize context
950  */
mbedtls_ecdsa_init(mbedtls_ecdsa_context * ctx)951 void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx )
952 {
953     ECDSA_VALIDATE( ctx != NULL );
954 
955     mbedtls_ecp_keypair_init( ctx );
956 }
957 
958 /*
959  * Free context
960  */
mbedtls_ecdsa_free(mbedtls_ecdsa_context * ctx)961 void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
962 {
963     if( ctx == NULL )
964         return;
965 
966     mbedtls_ecp_keypair_free( ctx );
967 }
968 
969 #if defined(MBEDTLS_ECP_RESTARTABLE)
970 /*
971  * Initialize a restart context
972  */
mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx * ctx)973 void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx )
974 {
975     ECDSA_VALIDATE( ctx != NULL );
976 
977     mbedtls_ecp_restart_init( &ctx->ecp );
978 
979     ctx->ver = NULL;
980     ctx->sig = NULL;
981 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
982     ctx->det = NULL;
983 #endif
984 }
985 
986 /*
987  * Free the components of a restart context
988  */
mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx * ctx)989 void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx )
990 {
991     if( ctx == NULL )
992         return;
993 
994     mbedtls_ecp_restart_free( &ctx->ecp );
995 
996     ecdsa_restart_ver_free( ctx->ver );
997     mbedtls_free( ctx->ver );
998     ctx->ver = NULL;
999 
1000     ecdsa_restart_sig_free( ctx->sig );
1001     mbedtls_free( ctx->sig );
1002     ctx->sig = NULL;
1003 
1004 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
1005     ecdsa_restart_det_free( ctx->det );
1006     mbedtls_free( ctx->det );
1007     ctx->det = NULL;
1008 #endif
1009 }
1010 #endif /* MBEDTLS_ECP_RESTARTABLE */
1011 
1012 #endif /* MBEDTLS_ECDSA_C */
1013