mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-03 20:22:59 -05:00 
			
		
		
		
	Fix non-constant-time comparison in mbedtls_mpi_random
Calling mbedtls_mpi_cmp_int reveals the number of leading zero limbs to an adversary who is capable of very fine-grained timing measurements. This is very little information, but could be practical with secp521r1 (1/512 chance of the leading limb being 0) if the adversary can measure the precise timing of a large number of signature operations. Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
		
							parent
							
								
									0c1a42a147
								
							
						
					
					
						commit
						5b0589e9ab
					
				
							
								
								
									
										7
									
								
								ChangeLog.d/ecdsa-random-leading-zeros.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								ChangeLog.d/ecdsa-random-leading-zeros.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
Security
 | 
			
		||||
* Fix a potential side channel vulnerability in ECDSA ephemeral key generation.
 | 
			
		||||
  An adversary who is capable of very precise timing measurements could
 | 
			
		||||
  learn partial information about the leading bits of the nonce used for the
 | 
			
		||||
  signature, allowing the recovery of the private key after observing a
 | 
			
		||||
  large number of signature operations. This completes a partial fix in
 | 
			
		||||
  Mbed TLS 2.20.0.
 | 
			
		||||
@ -2466,9 +2466,10 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
 | 
			
		||||
{
 | 
			
		||||
    int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
 | 
			
		||||
    int count;
 | 
			
		||||
    unsigned cmp = 0;
 | 
			
		||||
    unsigned lt_lower = 1, lt_upper = 0;
 | 
			
		||||
    size_t n_bits = mbedtls_mpi_bitlen( N );
 | 
			
		||||
    size_t n_bytes = ( n_bits + 7 ) / 8;
 | 
			
		||||
    mbedtls_mpi lower_bound;
 | 
			
		||||
 | 
			
		||||
    if( min < 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 | 
			
		||||
@ -2494,10 +2495,14 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
 | 
			
		||||
     */
 | 
			
		||||
    count = ( n_bytes > 4 ? 30 : 250 );
 | 
			
		||||
 | 
			
		||||
    mbedtls_mpi_init( &lower_bound );
 | 
			
		||||
 | 
			
		||||
    /* Ensure that target MPI has exactly the same number of limbs
 | 
			
		||||
     * as the upper bound, even if the upper bound has leading zeros.
 | 
			
		||||
     * This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
 | 
			
		||||
    MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
 | 
			
		||||
    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
 | 
			
		||||
    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
 | 
			
		||||
@ -2518,11 +2523,13 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
 | 
			
		||||
            goto cleanup;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &cmp ) );
 | 
			
		||||
        MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, <_lower ) );
 | 
			
		||||
        MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, <_upper ) );
 | 
			
		||||
    }
 | 
			
		||||
    while( mbedtls_mpi_cmp_int( X, min ) < 0 || cmp != 1 );
 | 
			
		||||
    while( lt_lower != 0 || lt_upper == 0 );
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
    mbedtls_mpi_free( &lower_bound );
 | 
			
		||||
    return( ret );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user