SECURITY UPDATE (Klima-Rosa attack)

patch from:
Florian Weimer <Florian.Weimer@RUS.UNI-STUTTGART.DE>
# http://cert.uni-stuttgart.de/files/fw/gnupg-klima-rosa.diff
# http://cert.uni-stuttgart.de/files/fw/gnupg-klima-rosa.diff.asc

It introduces additional consistency checks, as suggested by the
authors of the paper.  The checks are slightly different, but they
make the two additional attacks infeasible, I think.  In the future,
it might be a good idea to add a check the generated signature for
validity, this will detect bugs in the MPI implementation which could
result in a revealed secret key, too.


ok markus@
This commit is contained in:
reinhard 2001-03-23 13:10:20 +00:00
parent 9770352f01
commit 36bdf033ff
2 changed files with 101 additions and 4 deletions

View File

@ -1,9 +1,9 @@
# $OpenBSD: Makefile,v 1.25 2001/03/05 18:54:06 brad Exp $
# $OpenBSD: Makefile,v 1.26 2001/03/23 13:10:20 reinhard Exp $
DISTNAME= gnupg-1.0.4
PKGNAME= ${DISTNAME}p1
PKGNAME= ${DISTNAME}p2
CATEGORIES= security
NEED_VERSION= 1.358
NEED_VERSION= 1.363
MASTER_SITES= ftp://ftp.gnupg.org/pub/gcrypt/gnupg/ \
ftp://ftp.progsoc.uts.edu.au/pub/gnupg/gnupg/ \
ftp://openbsd.rug.ac.be/pub/gcrypt/gnupg/ \
@ -15,7 +15,7 @@ MASTER_SITES= ftp://ftp.gnupg.org/pub/gcrypt/gnupg/ \
ftp://ftp.stacken.kth.se/pub/crypto/gnupg/gnupg/ \
ftp://ftp.net.lut.ac.uk/gcrypt/gnupg/ \
ftp://gd.tuwien.ac.at/privacy/gnupg/gnupg/
MASTER_SITES0= ftp://ftp.gnupg.org/pub/gcrypt/contrib/
MASTER_SITES0= ftp://ftp.gnupg.org/pub/gcrypt/contrib/
DISTFILES= gnupg-1.0.4.tar.gz
EXTRACT_ONLY= gnupg-1.0.4.tar.gz

View File

@ -0,0 +1,97 @@
$OpenBSD: patch-cipher_rsa_c,v 1.1 2001/03/23 13:10:21 reinhard Exp $
# Florian Weimer <Florian.Weimer@RUS.UNI-STUTTGART.DE>
# http://cert.uni-stuttgart.de/files/fw/gnupg-klima-rosa.diff
# http://cert.uni-stuttgart.de/files/fw/gnupg-klima-rosa.diff.asc
It introduces additional consistency checks, as suggested by the
authors of the paper. The checks are slightly different, but they
make the two additional attacks infeasible, I think. In the future,
it might be a good idea to add a check the generated signature for
validity, this will detect bugs in the MPI implementation which could
result in a revealed secret key, too.
--- cipher/rsa.c.orig Wed Sep 13 15:49:23 2000
+++ cipher/rsa.c Fri Mar 23 13:16:46 2001
@@ -165,18 +165,53 @@ generate( RSA_secret_key *sk, unsigned n
/****************
* Test wether the secret key is valid.
- * Returns: true if this is a valid key.
+ * 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;
}
@@ -389,6 +424,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;
@@ -401,6 +438,13 @@ rsa_sign( int algo, MPI *resarr, MPI dat
sk.u = skey[5];
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;
}