Upstream-Status: Backport CVE: CVE-2013-4576 Index: gnupg-1.4.7/cipher/dsa.c =================================================================== --- gnupg-1.4.7.orig/cipher/dsa.c 2006-12-12 02:27:21.000000000 +0800 +++ gnupg-1.4.7/cipher/dsa.c 2014-01-23 11:30:17.300915919 +0800 @@ -287,6 +287,8 @@ MPI kinv; MPI tmp; + mpi_normalize (hash); + /* select a random k with 0 < k < q */ k = gen_k( skey->q ); Index: gnupg-1.4.7/cipher/elgamal.c =================================================================== --- gnupg-1.4.7.orig/cipher/elgamal.c 2006-12-12 03:08:05.000000000 +0800 +++ gnupg-1.4.7/cipher/elgamal.c 2014-01-23 11:30:17.300915919 +0800 @@ -376,6 +376,9 @@ { MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) ); + mpi_normalize (a); + mpi_normalize (b); + /* output = b/(a^x) mod p */ mpi_powm( t1, a, skey->x, skey->p ); mpi_invm( t1, t1, skey->p ); Index: gnupg-1.4.7/cipher/random.c =================================================================== --- gnupg-1.4.7.orig/cipher/random.c 2006-11-03 18:09:39.000000000 +0800 +++ gnupg-1.4.7/cipher/random.c 2014-01-23 11:31:53.993495462 +0800 @@ -273,6 +273,18 @@ } +/* Randomize the MPI */ +void +randomize_mpi (MPI mpi, size_t nbits, int level) +{ + unsigned char *buffer; + + buffer = get_random_bits (nbits, level, mpi_is_secure (mpi)); + mpi_set_buffer (mpi, buffer, (nbits+7)/8, 0); + xfree (buffer); +} + + int random_is_faked() { Index: gnupg-1.4.7/cipher/random.h =================================================================== --- gnupg-1.4.7.orig/cipher/random.h 2006-02-09 19:29:29.000000000 +0800 +++ gnupg-1.4.7/cipher/random.h 2014-01-23 11:30:17.300915919 +0800 @@ -32,6 +32,7 @@ int random_is_faked(void); void random_disable_locking (void); void randomize_buffer( byte *buffer, size_t length, int level ); +void randomize_mpi (MPI mpi, size_t nbits, int level); byte *get_random_bits( size_t nbits, int level, int secure ); void fast_random_poll( void ); Index: gnupg-1.4.7/cipher/rsa.c =================================================================== --- gnupg-1.4.7.orig/cipher/rsa.c 2006-12-12 03:09:00.000000000 +0800 +++ gnupg-1.4.7/cipher/rsa.c 2014-01-23 11:35:04.330639125 +0800 @@ -301,9 +301,26 @@ #if 0 mpi_powm( output, input, skey->d, skey->n ); #else - MPI m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 ); - MPI m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 ); - MPI h = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 ); + int nlimbs = mpi_get_nlimbs (skey->n)+1; + MPI m1 = mpi_alloc_secure (nlimbs); + MPI m2 = mpi_alloc_secure (nlimbs); + MPI h = mpi_alloc_secure (nlimbs); +# if 1 + MPI bdata= mpi_alloc_secure (nlimbs); + MPI r = mpi_alloc_secure (nlimbs); +# endif + + /* Remove superfluous leading zeroes from INPUT. */ + mpi_normalize (input); + +# if 1 + /* Blind: bdata = (data * r^e) mod n */ + randomize_mpi (r, mpi_get_nbits (skey->n), 0); + mpi_fdiv_r (r, r, skey->n); + mpi_powm (bdata, r, skey->e, skey->n); + mpi_mulm (bdata, bdata, input, skey->n); + input = bdata; +# endif /* m1 = c ^ (d mod (p-1)) mod p */ mpi_sub_ui( h, skey->p, 1 ); @@ -321,8 +338,15 @@ /* m = m2 + h * p */ mpi_mul ( h, h, skey->p ); mpi_add ( output, m1, h ); - /* ready */ - + +# if 1 + mpi_free (bdata); + /* Unblind: output = (output * r^(-1)) mod n */ + mpi_invm (r, r, skey->n); + mpi_mulm (output, output, r, skey->n); + mpi_free (r); +# endif + mpi_free ( h ); mpi_free ( m1 ); mpi_free ( m2 ); @@ -397,6 +421,7 @@ rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey ) { RSA_secret_key sk; + MPI input; if( algo != 1 && algo != 2 ) return G10ERR_PUBKEY_ALGO; @@ -407,8 +432,14 @@ sk.p = skey[3]; sk.q = skey[4]; sk.u = skey[5]; - *result = mpi_alloc_secure( mpi_get_nlimbs( sk.n ) ); - secret( *result, data[0], &sk ); + + /* Mitigates side-channel attacks (CVE-2013-4576). */ + input = mpi_alloc (0); + mpi_normalize (data[0]); + mpi_fdiv_r (input, data[0], sk.n); + *result = mpi_alloc_secure (mpi_get_nlimbs (sk.n)); + secret (*result, input, &sk); + mpi_free (input); return 0; } Index: gnupg-1.4.7/g10/gpgv.c =================================================================== --- gnupg-1.4.7.orig/g10/gpgv.c 2006-12-13 19:25:04.000000000 +0800 +++ gnupg-1.4.7/g10/gpgv.c 2014-01-23 11:30:17.300915919 +0800 @@ -390,6 +390,7 @@ void random_dump_stats(void) {} int quick_random_gen( int onoff ) { return -1;} void randomize_buffer( byte *buffer, size_t length, int level ) {} +void randomize_mpi (MPI mpi, size_t nbits, int level) {} int random_is_faked() { return -1;} byte *get_random_bits( size_t nbits, int level, int secure ) { return NULL;} void set_random_seed_file( const char *name ) {}