@@ -254,6 +254,8 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
254254 mbedtls_mpi * r , mbedtls_mpi * s ,
255255 const mbedtls_mpi * d , const unsigned char * buf , size_t blen ,
256256 int (* f_rng )(void * , unsigned char * , size_t ), void * p_rng ,
257+ int (* f_rng_blind )(void * , unsigned char * , size_t ),
258+ void * p_rng_blind ,
257259 mbedtls_ecdsa_restart_ctx * rs_ctx )
258260{
259261 int ret , key_tries , sign_tries ;
@@ -323,7 +325,9 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
323325mul :
324326#endif
325327 MBEDTLS_MPI_CHK ( mbedtls_ecp_mul_restartable ( grp , & R , pk , & grp -> G ,
326- f_rng , p_rng , ECDSA_RS_ECP ) );
328+ f_rng_blind ,
329+ p_rng_blind ,
330+ ECDSA_RS_ECP ) );
327331 MBEDTLS_MPI_CHK ( mbedtls_mpi_mod_mpi ( pr , & R .X , & grp -> N ) );
328332 }
329333 while ( mbedtls_mpi_cmp_int ( pr , 0 ) == 0 );
@@ -349,7 +353,8 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
349353 * Generate a random value to blind inv_mod in next step,
350354 * avoiding a potential timing leak.
351355 */
352- MBEDTLS_MPI_CHK ( mbedtls_ecp_gen_privkey ( grp , & t , f_rng , p_rng ) );
356+ MBEDTLS_MPI_CHK ( mbedtls_ecp_gen_privkey ( grp , & t , f_rng_blind ,
357+ p_rng_blind ) );
353358
354359 /*
355360 * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
@@ -406,8 +411,9 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
406411 ECDSA_VALIDATE_RET ( f_rng != NULL );
407412 ECDSA_VALIDATE_RET ( buf != NULL || blen == 0 );
408413
414+ /* Use the same RNG for both blinding and ephemeral key generation */
409415 return ( ecdsa_sign_restartable ( grp , r , s , d , buf , blen ,
410- f_rng , p_rng , NULL ) );
416+ f_rng , p_rng , f_rng , p_rng , NULL ) );
411417}
412418#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
413419
@@ -419,6 +425,8 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
419425 mbedtls_mpi * r , mbedtls_mpi * s ,
420426 const mbedtls_mpi * d , const unsigned char * buf , size_t blen ,
421427 mbedtls_md_type_t md_alg ,
428+ int (* f_rng_blind )(void * , unsigned char * , size_t ),
429+ void * p_rng_blind ,
422430 mbedtls_ecdsa_restart_ctx * rs_ctx )
423431{
424432 int ret ;
@@ -465,8 +473,69 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
465473 ret = mbedtls_ecdsa_sign ( grp , r , s , d , buf , blen ,
466474 mbedtls_hmac_drbg_random , p_rng );
467475#else
468- ret = ecdsa_sign_restartable ( grp , r , s , d , buf , blen ,
469- mbedtls_hmac_drbg_random , p_rng , rs_ctx );
476+ if ( f_rng_blind != NULL )
477+ ret = ecdsa_sign_restartable ( grp , r , s , d , buf , blen ,
478+ mbedtls_hmac_drbg_random , p_rng ,
479+ f_rng_blind , p_rng_blind , rs_ctx );
480+ else
481+ {
482+ mbedtls_hmac_drbg_context * p_rng_blind_det ;
483+
484+ #if !defined(MBEDTLS_ECP_RESTARTABLE )
485+ /*
486+ * To avoid reusing rng_ctx and risking incorrect behavior we seed a
487+ * second HMAC-DRBG with the same seed. We also apply a label to avoid
488+ * reusing the bits of the ephemeral key for blinding and eliminate the
489+ * risk that they leak this way.
490+ */
491+ const char * blind_label = "BLINDING CONTEXT" ;
492+ mbedtls_hmac_drbg_context rng_ctx_blind ;
493+
494+ mbedtls_hmac_drbg_init ( & rng_ctx_blind );
495+ p_rng_blind_det = & rng_ctx_blind ;
496+ mbedtls_hmac_drbg_seed_buf ( p_rng_blind_det , md_info ,
497+ data , 2 * grp_len );
498+ ret = mbedtls_hmac_drbg_update_ret ( p_rng_blind_det ,
499+ (const unsigned char * ) blind_label ,
500+ strlen ( blind_label ) );
501+ if ( ret != 0 )
502+ {
503+ mbedtls_hmac_drbg_free ( & rng_ctx_blind );
504+ goto cleanup ;
505+ }
506+ #else
507+ /*
508+ * In the case of restartable computations we would either need to store
509+ * the second RNG in the restart context too or set it up at every
510+ * restart. The first option would penalize the correct application of
511+ * the function and the second would defeat the purpose of the
512+ * restartable feature.
513+ *
514+ * Therefore in this case we reuse the original RNG. This comes with the
515+ * price that the resulting signature might not be a valid deterministic
516+ * ECDSA signature with a very low probability (same magnitude as
517+ * successfully guessing the private key). However even then it is still
518+ * a valid ECDSA signature.
519+ */
520+ p_rng_blind_det = p_rng ;
521+ #endif /* MBEDTLS_ECP_RESTARTABLE */
522+
523+ /*
524+ * Since the output of the RNGs is always the same for the same key and
525+ * message, this limits the efficiency of blinding and leaks information
526+ * through side channels. After mbedtls_ecdsa_sign_det() is removed NULL
527+ * won't be a valid value for f_rng_blind anymore. Therefore it should
528+ * be checked by the caller and this branch and check can be removed.
529+ */
530+ ret = ecdsa_sign_restartable ( grp , r , s , d , buf , blen ,
531+ mbedtls_hmac_drbg_random , p_rng ,
532+ mbedtls_hmac_drbg_random , p_rng_blind_det ,
533+ rs_ctx );
534+
535+ #if !defined(MBEDTLS_ECP_RESTARTABLE )
536+ mbedtls_hmac_drbg_free ( & rng_ctx_blind );
537+ #endif
538+ }
470539#endif /* MBEDTLS_ECDSA_SIGN_ALT */
471540
472541cleanup :
@@ -479,19 +548,43 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
479548}
480549
481550/*
482- * Deterministic signature wrapper
551+ * Deterministic signature wrappers
483552 */
484- int mbedtls_ecdsa_sign_det ( mbedtls_ecp_group * grp , mbedtls_mpi * r , mbedtls_mpi * s ,
485- const mbedtls_mpi * d , const unsigned char * buf , size_t blen ,
486- mbedtls_md_type_t md_alg )
553+
554+ #if !defined(MBEDTLS_DEPRECATED_REMOVED )
555+ int mbedtls_ecdsa_sign_det ( mbedtls_ecp_group * grp , mbedtls_mpi * r ,
556+ mbedtls_mpi * s , const mbedtls_mpi * d ,
557+ const unsigned char * buf , size_t blen ,
558+ mbedtls_md_type_t md_alg )
559+ {
560+ ECDSA_VALIDATE_RET ( grp != NULL );
561+ ECDSA_VALIDATE_RET ( r != NULL );
562+ ECDSA_VALIDATE_RET ( s != NULL );
563+ ECDSA_VALIDATE_RET ( d != NULL );
564+ ECDSA_VALIDATE_RET ( buf != NULL || blen == 0 );
565+
566+ return ( ecdsa_sign_det_restartable ( grp , r , s , d , buf , blen , md_alg ,
567+ NULL , NULL , NULL ) );
568+ }
569+ #endif /* MBEDTLS_DEPRECATED_REMOVED */
570+
571+ int mbedtls_ecdsa_sign_det_ext ( mbedtls_ecp_group * grp , mbedtls_mpi * r ,
572+ mbedtls_mpi * s , const mbedtls_mpi * d ,
573+ const unsigned char * buf , size_t blen ,
574+ mbedtls_md_type_t md_alg ,
575+ int (* f_rng_blind )(void * , unsigned char * ,
576+ size_t ),
577+ void * p_rng_blind )
487578{
488579 ECDSA_VALIDATE_RET ( grp != NULL );
489580 ECDSA_VALIDATE_RET ( r != NULL );
490581 ECDSA_VALIDATE_RET ( s != NULL );
491582 ECDSA_VALIDATE_RET ( d != NULL );
492583 ECDSA_VALIDATE_RET ( buf != NULL || blen == 0 );
584+ ECDSA_VALIDATE_RET ( f_rng_blind != NULL );
493585
494- return ( ecdsa_sign_det_restartable ( grp , r , s , d , buf , blen , md_alg , NULL ) );
586+ return ( ecdsa_sign_det_restartable ( grp , r , s , d , buf , blen , md_alg ,
587+ f_rng_blind , p_rng_blind , NULL ) );
495588}
496589#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
497590
@@ -670,20 +763,20 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
670763 mbedtls_mpi_init ( & s );
671764
672765#if defined(MBEDTLS_ECDSA_DETERMINISTIC )
673- (void ) f_rng ;
674- (void ) p_rng ;
675-
676766 MBEDTLS_MPI_CHK ( ecdsa_sign_det_restartable ( & ctx -> grp , & r , & s , & ctx -> d ,
677- hash , hlen , md_alg , rs_ctx ) );
767+ hash , hlen , md_alg , f_rng ,
768+ p_rng , rs_ctx ) );
678769#else
679770 (void ) md_alg ;
680771
681772#if defined(MBEDTLS_ECDSA_SIGN_ALT )
682773 MBEDTLS_MPI_CHK ( mbedtls_ecdsa_sign ( & ctx -> grp , & r , & s , & ctx -> d ,
683774 hash , hlen , f_rng , p_rng ) );
684775#else
776+ /* Use the same RNG for both blinding and ephemeral key generation */
685777 MBEDTLS_MPI_CHK ( ecdsa_sign_restartable ( & ctx -> grp , & r , & s , & ctx -> d ,
686- hash , hlen , f_rng , p_rng , rs_ctx ) );
778+ hash , hlen , f_rng , p_rng , f_rng ,
779+ p_rng , rs_ctx ) );
687780#endif /* MBEDTLS_ECDSA_SIGN_ALT */
688781#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
689782
0 commit comments