[Announce] Attack against OpenPGP encryption

David Shaw dshaw at jabberwocky.com
Fri Feb 11 02:11:15 CET 2005


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
-------------- next part --------------
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;
     }
-------------- next part --------------
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;
     }


More information about the Gnupg-announce mailing list