--- gnupg-1.4.1/cipher/rsa.c.orig 2004-09-23 23:34:45 +0400 +++ gnupg-1.4.1/cipher/rsa.c 2005-03-17 16:47:44 +0300 @@ -193,19 +193,54 @@ generate( RSA_secret_key *sk, unsigned n /**************** - * Test wether the secret key is valid. - * Returns: true if this is a valid key. + * Test whether the secret key is valid. + * Returns: nonzero if this is a valid key. */ static int check_secret_key( RSA_secret_key *sk ) { - int rc; - MPI temp = mpi_alloc( mpi_get_nlimbs(sk->p)*2 ); + int rc = 0; + MPI temp = mpi_alloc_secure ( mpi_get_nlimbs(sk->p) + mpi_get_nlimbs(sk->q) ); + MPI p_1 = mpi_copy (sk->p); /* (p-1) */ + MPI q_1 = mpi_copy (sk->p); /* (q-1) */ + MPI p_1_q_1 = mpi_alloc_secure ( mpi_get_nlimbs(sk->p) + mpi_get_nlimbs(sk->q) ); /* (p-1)(q-1) */ + + /* Calculate (p-1)(q-1). */ + mpi_sub_ui(p_1, p_1, 1); + mpi_sub_ui(q_1, q_1, 1); + mpi_mul(p_1_q_1, p_1, q_1); + /* Check pq = n. */ mpi_mul(temp, sk->p, sk->q ); - rc = mpi_cmp( temp, sk->n ); + if( 0 != mpi_cmp(temp, sk->n ) ) + goto end; + + /* Check gcd(e, (p-1)(q-1)) = 1. */ + if( ! mpi_gcd(temp, sk->e, p_1_q_1) ) + goto end; + + /* Check de == 1 (mod (p-1)) and (mod (q-1)), i.e. d = e^-1. */ + mpi_mulm(temp, sk->d, sk->e, p_1); + if( 0 != mpi_cmp_ui(temp, 1)) + goto end; + mpi_mulm(temp, sk->d, sk->e, q_1); + if( 0 != mpi_cmp_ui(temp, 1)) + goto end; + + /* Check up == 1 (mod q). */ + mpi_mulm(temp, sk->u, sk->p, sk->q); + if( 0 != mpi_cmp_ui(temp, 1)) + goto end; + + /* Success. Fall through to deallocation code. */ + rc = 1; + + end: mpi_free(temp); - return !rc; + mpi_free(p_1); + mpi_free(q_1); + mpi_free(p_1_q_1); + return rc; } @@ -419,6 +454,8 @@ int rsa_sign( int algo, MPI *resarr, MPI data, MPI *skey ) { RSA_secret_key sk; + RSA_public_key pk; + MPI orig = mpi_alloc( mpi_get_nlimbs( data ) ); if( algo != 1 && algo != 3 ) return G10ERR_PUBKEY_ALGO; @@ -432,6 +469,13 @@ rsa_sign( int algo, MPI *resarr, MPI dat resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.n ) ); secret( resarr[0], data, &sk ); + /* Check against wrong computation. */ + pk.n = sk.n; + pk.e = sk.e; + public( orig, resarr[0], &pk); + if ( 0 != mpi_cmp( orig, data ) ) + return G10ERR_BAD_SECKEY; + return 0; }