@@ -254,6 +254,8 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
254
254
mbedtls_mpi * r , mbedtls_mpi * s ,
255
255
const mbedtls_mpi * d , const unsigned char * buf , size_t blen ,
256
256
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 ,
257
259
mbedtls_ecdsa_restart_ctx * rs_ctx )
258
260
{
259
261
int ret , key_tries , sign_tries ;
@@ -323,7 +325,9 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
323
325
mul :
324
326
#endif
325
327
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 ) );
327
331
MBEDTLS_MPI_CHK ( mbedtls_mpi_mod_mpi ( pr , & R .X , & grp -> N ) );
328
332
}
329
333
while ( mbedtls_mpi_cmp_int ( pr , 0 ) == 0 );
@@ -349,7 +353,8 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
349
353
* Generate a random value to blind inv_mod in next step,
350
354
* avoiding a potential timing leak.
351
355
*/
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 ) );
353
358
354
359
/*
355
360
* 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,
406
411
ECDSA_VALIDATE_RET ( f_rng != NULL );
407
412
ECDSA_VALIDATE_RET ( buf != NULL || blen == 0 );
408
413
414
+ /* Use the same RNG for both blinding and ephemeral key generation */
409
415
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 ) );
411
417
}
412
418
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
413
419
@@ -419,6 +425,8 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
419
425
mbedtls_mpi * r , mbedtls_mpi * s ,
420
426
const mbedtls_mpi * d , const unsigned char * buf , size_t blen ,
421
427
mbedtls_md_type_t md_alg ,
428
+ int (* f_rng_blind )(void * , unsigned char * , size_t ),
429
+ void * p_rng_blind ,
422
430
mbedtls_ecdsa_restart_ctx * rs_ctx )
423
431
{
424
432
int ret ;
@@ -465,8 +473,69 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
465
473
ret = mbedtls_ecdsa_sign ( grp , r , s , d , buf , blen ,
466
474
mbedtls_hmac_drbg_random , p_rng );
467
475
#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
+ }
470
539
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
471
540
472
541
cleanup :
@@ -479,19 +548,43 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
479
548
}
480
549
481
550
/*
482
- * Deterministic signature wrapper
551
+ * Deterministic signature wrappers
483
552
*/
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 )
487
578
{
488
579
ECDSA_VALIDATE_RET ( grp != NULL );
489
580
ECDSA_VALIDATE_RET ( r != NULL );
490
581
ECDSA_VALIDATE_RET ( s != NULL );
491
582
ECDSA_VALIDATE_RET ( d != NULL );
492
583
ECDSA_VALIDATE_RET ( buf != NULL || blen == 0 );
584
+ ECDSA_VALIDATE_RET ( f_rng_blind != NULL );
493
585
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 ) );
495
588
}
496
589
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
497
590
@@ -670,20 +763,20 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
670
763
mbedtls_mpi_init ( & s );
671
764
672
765
#if defined(MBEDTLS_ECDSA_DETERMINISTIC )
673
- (void ) f_rng ;
674
- (void ) p_rng ;
675
-
676
766
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 ) );
678
769
#else
679
770
(void ) md_alg ;
680
771
681
772
#if defined(MBEDTLS_ECDSA_SIGN_ALT )
682
773
MBEDTLS_MPI_CHK ( mbedtls_ecdsa_sign ( & ctx -> grp , & r , & s , & ctx -> d ,
683
774
hash , hlen , f_rng , p_rng ) );
684
775
#else
776
+ /* Use the same RNG for both blinding and ephemeral key generation */
685
777
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 ) );
687
780
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
688
781
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
689
782
0 commit comments