Attack against OpenPGP encryption

David Shaw <[email protected]> Thu, 10 Feb 2005 20:11:15 -0500
Newsgroups gmane.comp.encryption.gpg.announce
Message-ID <20050211011115.GD1476__2045.43068907714$1108086732$gmane$org@jabberwocky.com>
Last night, Serge Mister and Robert Zuccherato published a paper
reporting on an attack against OpenPGP symmetric encryption.

This attack, while very significant from a cryptographic point of
view, is not generally effective in the real world.  To be specific,
unless you have your OpenPGP program set up as part of an automated
system to accept encrypted messages, decrypt them, and then provide a
response to the submitter, then this does not affect you at all.

There is a very good writeup on the attack that goes into more depth
at http://www.pgp.com/library/ctocorner/openpgp.html

There will undoubtedly be further discussion of this over the next
several days, but I wanted to provide a few comments now, to try and
answer some questions that may arise:

1) This is not a bug in any particular OpenPGP implementation (GnuPG,
   PGP, Hushmail, etc).  Rather, this is an attack against the OpenPGP
   protocol itself.

2) The attack requires an average of 32,768 probes to get two bytes of
   plaintext.  This is why it is completely ineffective against
   human beings, who will presumably wonder why a stranger wants them
   to decrypt thousands and thousands of messages that won't decrypt,
   and then tell them what errors were seen.

3) It might be effective against an automated process that
   incorporates OpenPGP decryption, if that process returns errors
   back to the sender.

4) The OpenPGP Working Group will be discussing this issue and coming
   up with an effective and permanent fix.  In the meantime, I have
   attached two patches to this mail.  These patches disable a
   portion of the OpenPGP protocol that the attack is exploiting.
   This change should not be user visible.  With the patch in place,
   this attack will not work using a public-key encrypted message.  It
   will still work using a passphrase-encrypted message.  These
   patches will be part of the 1.2.8 and 1.4.1 releases of GnuPG.

5) The full paper is available at http://eprint.iacr.org/2005/033
   It's a great piece of work.

David

_______________________________________________
Gnupg-announce mailing list
[email protected]
http://lists.gnupg.org/mailman/listinfo/gnupg-announce
gnupg-1.2.7.cfb.patch (text/plain, 1.7 KB)
Index: include/cipher.h
===================================================================
RCS file: /cvs/gnupg/gnupg/include/cipher.h,v
retrieving revision 1.53.2.6
diff -u -r1.53.2.6 cipher.h
--- include/cipher.h	29 Nov 2004 21:07:43 -0000	1.53.2.6
+++ include/cipher.h	8 Feb 2005 04:12:12 -0000
@@ -76,6 +76,7 @@
     int keylen;
     int algo_info_printed;
     int use_mdc;
+    int symmetric;
     byte key[32]; /* this is the largest used keylen (256 bit) */
 } DEK;
 
Index: g10/mainproc.c
===================================================================
RCS file: /cvs/gnupg/gnupg/g10/mainproc.c,v
retrieving revision 1.112.2.27
diff -u -r1.112.2.27 mainproc.c
--- g10/mainproc.c	27 Jun 2004 18:26:49 -0000	1.112.2.27
+++ g10/mainproc.c	8 Feb 2005 04:12:13 -0000
@@ -317,6 +317,8 @@
 	c->dek = passphrase_to_dek( NULL, 0, algo, &enc->s2k, 0, NULL, NULL );
 	if(c->dek)
 	  {
+	    c->dek->symmetric=1;
+
 	    /* FIXME: This doesn't work perfectly if a symmetric key
 	       comes before a public key in the message - if the user
 	       doesn't know the passphrase, then there is a chance
Index: g10/encr-data.c
===================================================================
RCS file: /cvs/gnupg/gnupg/g10/encr-data.c,v
retrieving revision 1.29
diff -u -r1.29 encr-data.c
--- g10/encr-data.c	29 Jun 2002 13:46:33 -0000	1.29
+++ g10/encr-data.c	8 Feb 2005 04:12:14 -0000
@@ -120,7 +120,7 @@
     cipher_sync( dfx.cipher_hd );
     p = temp;
 /* log_hexdump( "prefix", temp, nprefix+2 ); */
-    if( p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1] ) {
+    if( dek->symmetric && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) ) {
 	rc = G10ERR_BAD_KEY;
 	goto leave;
     }
gnupg-1.4.0.cfb.patch (text/plain, 1.6 KB)
Index: include/cipher.h
===================================================================
RCS file: /cvs/gnupg/gnupg/include/cipher.h,v
retrieving revision 1.63
diff -u -r1.63 cipher.h
--- include/cipher.h	29 Nov 2004 21:14:18 -0000	1.63
+++ include/cipher.h	8 Feb 2005 04:10:29 -0000
@@ -75,6 +75,7 @@
     int keylen;
     int algo_info_printed;
     int use_mdc;
+    int symmetric;
     byte key[32]; /* this is the largest used keylen (256 bit) */
 } DEK;
 
Index: g10/mainproc.c
===================================================================
RCS file: /cvs/gnupg/gnupg/g10/mainproc.c,v
retrieving revision 1.161
diff -u -r1.161 mainproc.c
--- g10/mainproc.c	21 Oct 2004 19:18:47 -0000	1.161
+++ g10/mainproc.c	8 Feb 2005 04:10:30 -0000
@@ -330,6 +330,8 @@
 
 	    if(c->dek)
 	      {
+		c->dek->symmetric=1;
+
 		/* FIXME: This doesn't work perfectly if a symmetric
 		   key comes before a public key in the message - if
 		   the user doesn't know the passphrase, then there is
Index: g10/encr-data.c
===================================================================
RCS file: /cvs/gnupg/gnupg/g10/encr-data.c,v
retrieving revision 1.30
diff -u -r1.30 encr-data.c
--- g10/encr-data.c	8 Oct 2004 21:54:26 -0000	1.30
+++ g10/encr-data.c	8 Feb 2005 04:10:30 -0000
@@ -125,7 +125,7 @@
     cipher_sync( dfx.cipher_hd );
     p = temp;
 /* log_hexdump( "prefix", temp, nprefix+2 ); */
-    if( p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1] ) {
+    if( dek->symmetric && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) ) {
 	rc = G10ERR_BAD_KEY;
 	goto leave;
     }
signature.asc (application/pgp-signature, 249 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1rc1 (GNU/Linux)

iGoEARECACoFAkIMBjMjGGh0dHA6Ly93d3cuamFiYmVyd29ja3kuY29tL2tleS5h
c2MACgkQ4mZch0nhy8lkVQCg5CVUq4iPCnVgUIjEAbIiU5ekEtcAnilv3XOCmuXU
6oYmTKH6T/1A8WjB
=B2MX
-----END PGP SIGNATURE-----