LCOV - code coverage report
Current view: top level - externals/mbedtls/library - ecdsa.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 93 200 46.5 %
Date: 2024-09-16 20:15:30 Functions: 6 15 40.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 40 122 32.8 %

           Branch data     Line data    Source code
       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                 :            :  */
      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                 :            :  */
      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                 :            :  */
     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                 :            :  */
     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                 :            :  */
     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                 :            :  */
     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                 :            :  */
     227                 :         10 : static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
     228                 :            :                        const unsigned char *buf, size_t blen )
     229                 :            : {
     230                 :         10 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     231                 :         10 :     size_t n_size = ( grp->nbits + 7 ) / 8;
     232                 :         10 :     size_t use_size = blen > n_size ? n_size : blen;
     233                 :            : 
     234         [ -  + ]:         10 :     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) );
     235         [ -  + ]:         10 :     if( use_size * 8 > grp->nbits )
     236         [ #  # ]:          0 :         MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) );
     237                 :            : 
     238                 :            :     /* While at it, reduce modulo N */
     239         [ +  - ]:         10 :     if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 )
     240         [ #  # ]:          0 :         MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) );
     241                 :            : 
     242                 :         10 : cleanup:
     243                 :         10 :     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                 :            :  */
     252                 :          4 : 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                 :          4 :     int ret, key_tries, sign_tries;
     261                 :          4 :     int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
     262                 :          4 :     mbedtls_ecp_point R;
     263                 :          4 :     mbedtls_mpi k, e, t;
     264                 :          4 :     mbedtls_mpi *pk = &k, *pr = r;
     265                 :            : 
     266                 :            :     /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
     267   [ +  -  +  - ]:          4 :     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   [ +  -  -  + ]:          4 :     if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
     272                 :          0 :         return( MBEDTLS_ERR_ECP_INVALID_KEY );
     273                 :            : 
     274                 :          4 :     mbedtls_ecp_point_init( &R );
     275                 :          4 :     mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t );
     276                 :            : 
     277                 :          4 :     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                 :          4 :     *p_sign_tries = 0;
     297                 :          4 :     do
     298                 :            :     {
     299         [ -  + ]:          4 :         if( (*p_sign_tries)++ > 10 )
     300                 :            :         {
     301                 :          0 :             ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
     302                 :          0 :             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                 :          4 :         do
     311                 :            :         {
     312         [ -  + ]:          4 :             if( (*p_key_tries)++ > 10 )
     313                 :            :             {
     314                 :          0 :                 ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
     315                 :          0 :                 goto cleanup;
     316                 :            :             }
     317                 :            : 
     318         [ -  + ]:          4 :             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         [ -  + ]:          4 :             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         [ -  + ]:          4 :             MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) );
     331                 :            :         }
     332         [ -  + ]:          4 :         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                 :          4 :         ECDSA_BUDGET( MBEDTLS_ECP_OPS_INV + 4 );
     345                 :            : 
     346                 :            :         /*
     347                 :            :          * Step 5: derive MPI from hashed message
     348                 :            :          */
     349         [ -  + ]:          4 :         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         [ -  + ]:          4 :         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         [ -  + ]:          4 :         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, pr, d ) );
     362         [ -  + ]:          4 :         MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
     363         [ -  + ]:          4 :         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
     364         [ -  + ]:          4 :         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) );
     365         [ -  + ]:          4 :         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pk, pk, &grp->N ) );
     366         [ -  + ]:          4 :         MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) );
     367         [ -  + ]:          4 :         MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
     368         [ -  + ]:          4 :         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
     369                 :            :     }
     370         [ -  + ]:          4 :     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                 :          4 : cleanup:
     378                 :          4 :     mbedtls_ecp_point_free( &R );
     379                 :          4 :     mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t );
     380                 :            : 
     381                 :          4 :     ECDSA_RS_LEAVE( sig );
     382                 :            : 
     383                 :          4 :     return( ret );
     384                 :            : }
     385                 :            : 
     386                 :         10 : int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid )
     387                 :            : {
     388                 :         10 :     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                 :         10 :     default: return 1;
     397                 :            :     }
     398                 :            : }
     399                 :            : 
     400                 :            : /*
     401                 :            :  * Compute ECDSA signature of a hashed message
     402                 :            :  */
     403                 :          4 : 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                 :          4 :     ECDSA_VALIDATE_RET( grp   != NULL );
     408                 :          4 :     ECDSA_VALIDATE_RET( r     != NULL );
     409                 :          4 :     ECDSA_VALIDATE_RET( s     != NULL );
     410                 :          4 :     ECDSA_VALIDATE_RET( d     != NULL );
     411                 :          4 :     ECDSA_VALIDATE_RET( f_rng != NULL );
     412                 :          4 :     ECDSA_VALIDATE_RET( buf   != NULL || blen == 0 );
     413                 :            : 
     414                 :            :     /* Use the same RNG for both blinding and ephemeral key generation */
     415                 :          4 :     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                 :            :  *
     424                 :            :  * note:    The f_rng_blind parameter must not be NULL.
     425                 :            :  *
     426                 :            :  */
     427                 :            : static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
     428                 :            :                     mbedtls_mpi *r, mbedtls_mpi *s,
     429                 :            :                     const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
     430                 :            :                     mbedtls_md_type_t md_alg,
     431                 :            :                     int (*f_rng_blind)(void *, unsigned char *, size_t),
     432                 :            :                     void *p_rng_blind,
     433                 :            :                     mbedtls_ecdsa_restart_ctx *rs_ctx )
     434                 :            : {
     435                 :            :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     436                 :            :     mbedtls_hmac_drbg_context rng_ctx;
     437                 :            :     mbedtls_hmac_drbg_context *p_rng = &rng_ctx;
     438                 :            :     unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
     439                 :            :     size_t grp_len = ( grp->nbits + 7 ) / 8;
     440                 :            :     const mbedtls_md_info_t *md_info;
     441                 :            :     mbedtls_mpi h;
     442                 :            : 
     443                 :            :     if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
     444                 :            :         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
     445                 :            : 
     446                 :            :     mbedtls_mpi_init( &h );
     447                 :            :     mbedtls_hmac_drbg_init( &rng_ctx );
     448                 :            : 
     449                 :            :     ECDSA_RS_ENTER( det );
     450                 :            : 
     451                 :            : #if defined(MBEDTLS_ECP_RESTARTABLE)
     452                 :            :     if( rs_ctx != NULL && rs_ctx->det != NULL )
     453                 :            :     {
     454                 :            :         /* redirect to our context */
     455                 :            :         p_rng = &rs_ctx->det->rng_ctx;
     456                 :            : 
     457                 :            :         /* jump to current step */
     458                 :            :         if( rs_ctx->det->state == ecdsa_det_sign )
     459                 :            :             goto sign;
     460                 :            :     }
     461                 :            : #endif /* MBEDTLS_ECP_RESTARTABLE */
     462                 :            : 
     463                 :            :     /* Use private key and message hash (reduced) to initialize HMAC_DRBG */
     464                 :            :     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
     465                 :            :     MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
     466                 :            :     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) );
     467                 :            :     mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len );
     468                 :            : 
     469                 :            : #if defined(MBEDTLS_ECP_RESTARTABLE)
     470                 :            :     if( rs_ctx != NULL && rs_ctx->det != NULL )
     471                 :            :         rs_ctx->det->state = ecdsa_det_sign;
     472                 :            : 
     473                 :            : sign:
     474                 :            : #endif
     475                 :            : #if defined(MBEDTLS_ECDSA_SIGN_ALT)
     476                 :            :     (void) f_rng_blind;
     477                 :            :     (void) p_rng_blind;
     478                 :            :     ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
     479                 :            :                               mbedtls_hmac_drbg_random, p_rng );
     480                 :            : #else
     481                 :            :     ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
     482                 :            :                                   mbedtls_hmac_drbg_random, p_rng,
     483                 :            :                                   f_rng_blind, p_rng_blind, rs_ctx );
     484                 :            : #endif /* MBEDTLS_ECDSA_SIGN_ALT */
     485                 :            : 
     486                 :            : cleanup:
     487                 :            :     mbedtls_hmac_drbg_free( &rng_ctx );
     488                 :            :     mbedtls_mpi_free( &h );
     489                 :            : 
     490                 :            :     ECDSA_RS_LEAVE( det );
     491                 :            : 
     492                 :            :     return( ret );
     493                 :            : }
     494                 :            : 
     495                 :            : /*
     496                 :            :  * Deterministic signature wrapper
     497                 :            :  */
     498                 :            : int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
     499                 :            :                                 mbedtls_mpi *s, const mbedtls_mpi *d,
     500                 :            :                                 const unsigned char *buf, size_t blen,
     501                 :            :                                 mbedtls_md_type_t md_alg,
     502                 :            :                                 int (*f_rng_blind)(void *, unsigned char *,
     503                 :            :                                                    size_t),
     504                 :            :                                 void *p_rng_blind )
     505                 :            : {
     506                 :            :     ECDSA_VALIDATE_RET( grp   != NULL );
     507                 :            :     ECDSA_VALIDATE_RET( r     != NULL );
     508                 :            :     ECDSA_VALIDATE_RET( s     != NULL );
     509                 :            :     ECDSA_VALIDATE_RET( d     != NULL );
     510                 :            :     ECDSA_VALIDATE_RET( buf   != NULL || blen == 0 );
     511                 :            :     ECDSA_VALIDATE_RET( f_rng_blind != NULL );
     512                 :            : 
     513                 :            :     return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg,
     514                 :            :                                         f_rng_blind, p_rng_blind, NULL ) );
     515                 :            : }
     516                 :            : #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
     517                 :            : 
     518                 :            : #if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
     519                 :            : /*
     520                 :            :  * Verify ECDSA signature of hashed message (SEC1 4.1.4)
     521                 :            :  * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
     522                 :            :  */
     523                 :          6 : static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
     524                 :            :                                      const unsigned char *buf, size_t blen,
     525                 :            :                                      const mbedtls_ecp_point *Q,
     526                 :            :                                      const mbedtls_mpi *r, const mbedtls_mpi *s,
     527                 :            :                                      mbedtls_ecdsa_restart_ctx *rs_ctx )
     528                 :            : {
     529                 :          6 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     530                 :          6 :     mbedtls_mpi e, s_inv, u1, u2;
     531                 :          6 :     mbedtls_ecp_point R;
     532                 :          6 :     mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
     533                 :            : 
     534                 :          6 :     mbedtls_ecp_point_init( &R );
     535                 :          6 :     mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv );
     536                 :          6 :     mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
     537                 :            : 
     538                 :            :     /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
     539   [ +  -  +  - ]:          6 :     if( ! mbedtls_ecdsa_can_do( grp->id ) || grp->N.p == NULL )
     540                 :            :         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
     541                 :            : 
     542                 :          6 :     ECDSA_RS_ENTER( ver );
     543                 :            : 
     544                 :            : #if defined(MBEDTLS_ECP_RESTARTABLE)
     545                 :            :     if( rs_ctx != NULL && rs_ctx->ver != NULL )
     546                 :            :     {
     547                 :            :         /* redirect to our context */
     548                 :            :         pu1 = &rs_ctx->ver->u1;
     549                 :            :         pu2 = &rs_ctx->ver->u2;
     550                 :            : 
     551                 :            :         /* jump to current step */
     552                 :            :         if( rs_ctx->ver->state == ecdsa_ver_muladd )
     553                 :            :             goto muladd;
     554                 :            :     }
     555                 :            : #endif /* MBEDTLS_ECP_RESTARTABLE */
     556                 :            : 
     557                 :            :     /*
     558                 :            :      * Step 1: make sure r and s are in range 1..n-1
     559                 :            :      */
     560   [ +  -  +  -  :         12 :     if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 ||
                   +  - ]
     561         [ -  + ]:         12 :         mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 )
     562                 :            :     {
     563                 :          0 :         ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
     564                 :          0 :         goto cleanup;
     565                 :            :     }
     566                 :            : 
     567                 :            :     /*
     568                 :            :      * Step 3: derive MPI from hashed message
     569                 :            :      */
     570         [ -  + ]:          6 :     MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
     571                 :            : 
     572                 :            :     /*
     573                 :            :      * Step 4: u1 = e / s mod n, u2 = r / s mod n
     574                 :            :      */
     575                 :          6 :     ECDSA_BUDGET( MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2 );
     576                 :            : 
     577         [ -  + ]:          6 :     MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) );
     578                 :            : 
     579         [ -  + ]:          6 :     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu1, &e, &s_inv ) );
     580         [ -  + ]:          6 :     MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu1, pu1, &grp->N ) );
     581                 :            : 
     582         [ -  + ]:          6 :     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu2, r, &s_inv ) );
     583         [ -  + ]:          6 :     MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu2, pu2, &grp->N ) );
     584                 :            : 
     585                 :            : #if defined(MBEDTLS_ECP_RESTARTABLE)
     586                 :            :     if( rs_ctx != NULL && rs_ctx->ver != NULL )
     587                 :            :         rs_ctx->ver->state = ecdsa_ver_muladd;
     588                 :            : 
     589                 :            : muladd:
     590                 :            : #endif
     591                 :            :     /*
     592                 :            :      * Step 5: R = u1 G + u2 Q
     593                 :            :      */
     594         [ -  + ]:          6 :     MBEDTLS_MPI_CHK( mbedtls_ecp_muladd_restartable( grp,
     595                 :            :                      &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP ) );
     596                 :            : 
     597         [ -  + ]:          6 :     if( mbedtls_ecp_is_zero( &R ) )
     598                 :            :     {
     599                 :          0 :         ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
     600                 :          0 :         goto cleanup;
     601                 :            :     }
     602                 :            : 
     603                 :            :     /*
     604                 :            :      * Step 6: convert xR to an integer (no-op)
     605                 :            :      * Step 7: reduce xR mod n (gives v)
     606                 :            :      */
     607         [ -  + ]:          6 :     MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) );
     608                 :            : 
     609                 :            :     /*
     610                 :            :      * Step 8: check if v (that is, R.X) is equal to r
     611                 :            :      */
     612         [ +  - ]:          6 :     if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 )
     613                 :            :     {
     614                 :          0 :         ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
     615                 :          0 :         goto cleanup;
     616                 :            :     }
     617                 :            : 
     618                 :          6 : cleanup:
     619                 :          6 :     mbedtls_ecp_point_free( &R );
     620                 :          6 :     mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv );
     621                 :          6 :     mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 );
     622                 :            : 
     623                 :          6 :     ECDSA_RS_LEAVE( ver );
     624                 :            : 
     625                 :          6 :     return( ret );
     626                 :            : }
     627                 :            : 
     628                 :            : /*
     629                 :            :  * Verify ECDSA signature of hashed message
     630                 :            :  */
     631                 :          6 : int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
     632                 :            :                           const unsigned char *buf, size_t blen,
     633                 :            :                           const mbedtls_ecp_point *Q,
     634                 :            :                           const mbedtls_mpi *r,
     635                 :            :                           const mbedtls_mpi *s)
     636                 :            : {
     637                 :          6 :     ECDSA_VALIDATE_RET( grp != NULL );
     638                 :          6 :     ECDSA_VALIDATE_RET( Q   != NULL );
     639                 :          6 :     ECDSA_VALIDATE_RET( r   != NULL );
     640                 :          6 :     ECDSA_VALIDATE_RET( s   != NULL );
     641                 :          6 :     ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
     642                 :            : 
     643                 :          6 :     return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) );
     644                 :            : }
     645                 :            : #endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
     646                 :            : 
     647                 :            : /*
     648                 :            :  * Convert a signature (given by context) to ASN.1
     649                 :            :  */
     650                 :          0 : static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
     651                 :            :                                     unsigned char *sig, size_t sig_size,
     652                 :            :                                     size_t *slen )
     653                 :            : {
     654                 :          0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     655                 :          0 :     unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = {0};
     656                 :          0 :     unsigned char *p = buf + sizeof( buf );
     657                 :          0 :     size_t len = 0;
     658                 :            : 
     659         [ #  # ]:          0 :     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) );
     660         [ #  # ]:          0 :     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) );
     661                 :            : 
     662         [ #  # ]:          0 :     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) );
     663         [ #  # ]:          0 :     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
     664                 :            :                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
     665                 :            : 
     666         [ #  # ]:          0 :     if( len > sig_size )
     667                 :            :         return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
     668                 :            : 
     669                 :          0 :     memcpy( sig, p, len );
     670                 :          0 :     *slen = len;
     671                 :            : 
     672                 :          0 :     return( 0 );
     673                 :            : }
     674                 :            : 
     675                 :            : /*
     676                 :            :  * Compute and write signature
     677                 :            :  */
     678                 :          0 : int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
     679                 :            :                            mbedtls_md_type_t md_alg,
     680                 :            :                            const unsigned char *hash, size_t hlen,
     681                 :            :                            unsigned char *sig, size_t sig_size, size_t *slen,
     682                 :            :                            int (*f_rng)(void *, unsigned char *, size_t),
     683                 :            :                            void *p_rng,
     684                 :            :                            mbedtls_ecdsa_restart_ctx *rs_ctx )
     685                 :            : {
     686                 :          0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     687                 :          0 :     mbedtls_mpi r, s;
     688                 :          0 :     ECDSA_VALIDATE_RET( ctx   != NULL );
     689                 :          0 :     ECDSA_VALIDATE_RET( hash  != NULL );
     690                 :          0 :     ECDSA_VALIDATE_RET( sig   != NULL );
     691                 :          0 :     ECDSA_VALIDATE_RET( slen  != NULL );
     692                 :            : 
     693         [ #  # ]:          0 :     if( f_rng == NULL )
     694                 :            :         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
     695                 :            : 
     696                 :          0 :     mbedtls_mpi_init( &r );
     697                 :          0 :     mbedtls_mpi_init( &s );
     698                 :            : 
     699                 :            : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
     700                 :            :     MBEDTLS_MPI_CHK( ecdsa_sign_det_restartable( &ctx->grp, &r, &s, &ctx->d,
     701                 :            :                                                  hash, hlen, md_alg, f_rng,
     702                 :            :                                                  p_rng, rs_ctx ) );
     703                 :            : #else
     704                 :          0 :     (void) md_alg;
     705                 :            : 
     706                 :            : #if defined(MBEDTLS_ECDSA_SIGN_ALT)
     707                 :            :     (void) rs_ctx;
     708                 :            : 
     709                 :            :     MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
     710                 :            :                          hash, hlen, f_rng, p_rng ) );
     711                 :            : #else
     712                 :            :     /* Use the same RNG for both blinding and ephemeral key generation */
     713         [ #  # ]:          0 :     MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d,
     714                 :            :                                              hash, hlen, f_rng, p_rng, f_rng,
     715                 :            :                                              p_rng, rs_ctx ) );
     716                 :            : #endif /* MBEDTLS_ECDSA_SIGN_ALT */
     717                 :            : #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
     718                 :            : 
     719         [ #  # ]:          0 :     MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, sig_size, slen ) );
     720                 :            : 
     721                 :          0 : cleanup:
     722                 :          0 :     mbedtls_mpi_free( &r );
     723                 :          0 :     mbedtls_mpi_free( &s );
     724                 :            : 
     725                 :          0 :     return( ret );
     726                 :            : }
     727                 :            : 
     728                 :            : /*
     729                 :            :  * Compute and write signature
     730                 :            :  */
     731                 :          0 : int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
     732                 :            :                                  mbedtls_md_type_t md_alg,
     733                 :            :                                  const unsigned char *hash, size_t hlen,
     734                 :            :                                  unsigned char *sig, size_t sig_size, size_t *slen,
     735                 :            :                                  int (*f_rng)(void *, unsigned char *, size_t),
     736                 :            :                                  void *p_rng )
     737                 :            : {
     738                 :          0 :     ECDSA_VALIDATE_RET( ctx  != NULL );
     739                 :          0 :     ECDSA_VALIDATE_RET( hash != NULL );
     740                 :          0 :     ECDSA_VALIDATE_RET( sig  != NULL );
     741                 :          0 :     ECDSA_VALIDATE_RET( slen != NULL );
     742                 :          0 :     return( mbedtls_ecdsa_write_signature_restartable(
     743                 :            :                 ctx, md_alg, hash, hlen, sig, sig_size, slen,
     744                 :            :                 f_rng, p_rng, NULL ) );
     745                 :            : }
     746                 :            : 
     747                 :            : /*
     748                 :            :  * Read and check signature
     749                 :            :  */
     750                 :          0 : int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
     751                 :            :                           const unsigned char *hash, size_t hlen,
     752                 :            :                           const unsigned char *sig, size_t slen )
     753                 :            : {
     754                 :          0 :     ECDSA_VALIDATE_RET( ctx  != NULL );
     755                 :          0 :     ECDSA_VALIDATE_RET( hash != NULL );
     756                 :          0 :     ECDSA_VALIDATE_RET( sig  != NULL );
     757                 :          0 :     return( mbedtls_ecdsa_read_signature_restartable(
     758                 :            :                 ctx, hash, hlen, sig, slen, NULL ) );
     759                 :            : }
     760                 :            : 
     761                 :            : /*
     762                 :            :  * Restartable read and check signature
     763                 :            :  */
     764                 :          0 : int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
     765                 :            :                           const unsigned char *hash, size_t hlen,
     766                 :            :                           const unsigned char *sig, size_t slen,
     767                 :            :                           mbedtls_ecdsa_restart_ctx *rs_ctx )
     768                 :            : {
     769                 :          0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     770                 :          0 :     unsigned char *p = (unsigned char *) sig;
     771                 :          0 :     const unsigned char *end = sig + slen;
     772                 :          0 :     size_t len;
     773                 :          0 :     mbedtls_mpi r, s;
     774                 :          0 :     ECDSA_VALIDATE_RET( ctx  != NULL );
     775                 :          0 :     ECDSA_VALIDATE_RET( hash != NULL );
     776                 :          0 :     ECDSA_VALIDATE_RET( sig  != NULL );
     777                 :            : 
     778                 :          0 :     mbedtls_mpi_init( &r );
     779                 :          0 :     mbedtls_mpi_init( &s );
     780                 :            : 
     781         [ #  # ]:          0 :     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
     782                 :            :                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
     783                 :            :     {
     784                 :          0 :         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     785                 :          0 :         goto cleanup;
     786                 :            :     }
     787                 :            : 
     788         [ #  # ]:          0 :     if( p + len != end )
     789                 :            :     {
     790                 :          0 :         ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
     791                 :            :               MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
     792                 :          0 :         goto cleanup;
     793                 :            :     }
     794                 :            : 
     795         [ #  # ]:          0 :     if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 ||
     796         [ #  # ]:          0 :         ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 )
     797                 :            :     {
     798                 :          0 :         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     799                 :          0 :         goto cleanup;
     800                 :            :     }
     801                 :            : #if defined(MBEDTLS_ECDSA_VERIFY_ALT)
     802                 :            :     (void) rs_ctx;
     803                 :            : 
     804                 :            :     if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
     805                 :            :                                       &ctx->Q, &r, &s ) ) != 0 )
     806                 :            :         goto cleanup;
     807                 :            : #else
     808         [ #  # ]:          0 :     if( ( ret = ecdsa_verify_restartable( &ctx->grp, hash, hlen,
     809                 :          0 :                               &ctx->Q, &r, &s, rs_ctx ) ) != 0 )
     810                 :          0 :         goto cleanup;
     811                 :            : #endif /* MBEDTLS_ECDSA_VERIFY_ALT */
     812                 :            : 
     813                 :            :     /* At this point we know that the buffer starts with a valid signature.
     814                 :            :      * Return 0 if the buffer just contains the signature, and a specific
     815                 :            :      * error code if the valid signature is followed by more data. */
     816         [ #  # ]:          0 :     if( p != end )
     817                 :          0 :         ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
     818                 :            : 
     819                 :          0 : cleanup:
     820                 :          0 :     mbedtls_mpi_free( &r );
     821                 :          0 :     mbedtls_mpi_free( &s );
     822                 :            : 
     823                 :          0 :     return( ret );
     824                 :            : }
     825                 :            : 
     826                 :            : #if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
     827                 :            : /*
     828                 :            :  * Generate key pair
     829                 :            :  */
     830                 :          0 : int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
     831                 :            :                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
     832                 :            : {
     833                 :          0 :     int ret = 0;
     834                 :          0 :     ECDSA_VALIDATE_RET( ctx   != NULL );
     835                 :          0 :     ECDSA_VALIDATE_RET( f_rng != NULL );
     836                 :            : 
     837                 :          0 :     ret = mbedtls_ecp_group_load( &ctx->grp, gid );
     838         [ #  # ]:          0 :     if( ret != 0 )
     839                 :            :         return( ret );
     840                 :            : 
     841                 :          0 :    return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d,
     842                 :            :                                     &ctx->Q, f_rng, p_rng ) );
     843                 :            : }
     844                 :            : #endif /* !MBEDTLS_ECDSA_GENKEY_ALT */
     845                 :            : 
     846                 :            : /*
     847                 :            :  * Set context from an mbedtls_ecp_keypair
     848                 :            :  */
     849                 :          0 : int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
     850                 :            : {
     851                 :          0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     852                 :          0 :     ECDSA_VALIDATE_RET( ctx != NULL );
     853                 :          0 :     ECDSA_VALIDATE_RET( key != NULL );
     854                 :            : 
     855         [ #  # ]:          0 :     if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ||
     856         [ #  # ]:          0 :         ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ||
     857         [ #  # ]:          0 :         ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 )
     858                 :            :     {
     859                 :          0 :         mbedtls_ecdsa_free( ctx );
     860                 :            :     }
     861                 :            : 
     862                 :          0 :     return( ret );
     863                 :            : }
     864                 :            : 
     865                 :            : /*
     866                 :            :  * Initialize context
     867                 :            :  */
     868                 :          0 : void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx )
     869                 :            : {
     870                 :          0 :     ECDSA_VALIDATE( ctx != NULL );
     871                 :            : 
     872                 :          0 :     mbedtls_ecp_keypair_init( ctx );
     873                 :          0 : }
     874                 :            : 
     875                 :            : /*
     876                 :            :  * Free context
     877                 :            :  */
     878                 :          0 : void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
     879                 :            : {
     880         [ #  # ]:          0 :     if( ctx == NULL )
     881                 :            :         return;
     882                 :            : 
     883                 :          0 :     mbedtls_ecp_keypair_free( ctx );
     884                 :            : }
     885                 :            : 
     886                 :            : #if defined(MBEDTLS_ECP_RESTARTABLE)
     887                 :            : /*
     888                 :            :  * Initialize a restart context
     889                 :            :  */
     890                 :            : void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx )
     891                 :            : {
     892                 :            :     ECDSA_VALIDATE( ctx != NULL );
     893                 :            : 
     894                 :            :     mbedtls_ecp_restart_init( &ctx->ecp );
     895                 :            : 
     896                 :            :     ctx->ver = NULL;
     897                 :            :     ctx->sig = NULL;
     898                 :            : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
     899                 :            :     ctx->det = NULL;
     900                 :            : #endif
     901                 :            : }
     902                 :            : 
     903                 :            : /*
     904                 :            :  * Free the components of a restart context
     905                 :            :  */
     906                 :            : void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx )
     907                 :            : {
     908                 :            :     if( ctx == NULL )
     909                 :            :         return;
     910                 :            : 
     911                 :            :     mbedtls_ecp_restart_free( &ctx->ecp );
     912                 :            : 
     913                 :            :     ecdsa_restart_ver_free( ctx->ver );
     914                 :            :     mbedtls_free( ctx->ver );
     915                 :            :     ctx->ver = NULL;
     916                 :            : 
     917                 :            :     ecdsa_restart_sig_free( ctx->sig );
     918                 :            :     mbedtls_free( ctx->sig );
     919                 :            :     ctx->sig = NULL;
     920                 :            : 
     921                 :            : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
     922                 :            :     ecdsa_restart_det_free( ctx->det );
     923                 :            :     mbedtls_free( ctx->det );
     924                 :            :     ctx->det = NULL;
     925                 :            : #endif
     926                 :            : }
     927                 :            : #endif /* MBEDTLS_ECP_RESTARTABLE */
     928                 :            : 
     929                 :            : #endif /* MBEDTLS_ECDSA_C */

Generated by: LCOV version 1.14