Possible bug in gpg?

David Shaw dshaw at jabberwocky.com
Sun Jul 29 06:48:25 CEST 2012


On Jul 28, 2012, at 2:18 PM, Brad Tilley wrote:

> Hi,
> 
> I have a symmetrically encrypted pgp file here:
> 
> http://16s.us/word_machine/downloads/pgp-easy.tgz.pgp
> 
> gpg will accept the three characters !=X as the password and exit with a
> return status of 0 (although it does not actually decrypt the file):
> 
> $ gpg -d pgp-easy.tgz.pgp
> gpg: CAST5 encrypted data
> gpg: encrypted with 1 passphrase
> gpg: WARNING: message was not integrity protected
> 
> $ echo $?
> 0
> 
> !=X is not the plaintext password that was used to encrypt the file. I was
> hoping someone on the list might be able to help me understand why this
> might happen. Could it be a bug in gpg, or OpenPGP itself? Here is my gpg
> version:

I haven't examined this file extensively, but assuming it isn't corrupt, or specifically engineered to be not decryptable in some way, I'm suspecting this is an example of a quick check failure.  In OpenPGP, a message is made up of different packets.  In your case you have a symmetric key encrypted session key packet (essentially instructions on how to mangle the passphrase into a session key), followed by an encrypted data packet, which is encrypted to the session key that results from the first packet.  Normally, when decrypting, the client will read the first packet, prompt the user for a passphrase, and mangle the passphrase into a session key.  Then it reads the second packet, and uses the session key to decrypt the data.

However, people being people, they can easily typo the passphrase, and given the method above, if the passphrase is wrong, the session key will be wrong, and the data decrypted will be gibberish.  To combat this, OpenPGP has two "quick check" bytes in the encrypted data packet.  Basically, they're a repetition of two random bytes from earlier in the message.  The idea is that if the session key is wrong (i.e. the passphrase is wrong), the original random bytes won't match their repetition, and the client can immediately say "Wrong passphrase!" rather than blithely continue and potentially decrypt lots of data that won't turn out to be valid.

The practical upshot of this design is that while it works most of the time (in that virtually all incorrect passwords will be immediately flagged as such), each symmetrically encrypted message has the chance for other, incorrect, passphrases that nevertheless will pass the quick check.  Obviously, these cannot decrypt the message, but they mangle into (invalid) session keys that just so happen to decrypt the data so that the 16-bit quick check matches, allowing the client to proceed, and decrypt (incorrectly) the rest of the data.  Usually this fails fairly quickly afterwards as the data decrypted is not valid OpenPGP structures, so the client will stop with an error message about being unable to read the file.

In this particular case, the !=X passphrase passes the quick check, and the incorrectly decrypted data happens to look like a packet of packet type 0, of length 942141745.  GPG ignores the invalid packet (there is no packet type 0), and so no output is generated.

So, assuming my guess is right, it's not a bug in OpenPGP or GnuPG (though perhaps giving an error when it saw the packet type of 0 would have been better), but a pretty unlikely confluence of events.  How did you come up with the !=X passphrase?  Exhaustive search?  I'd be curious to find out what the real password is, once it is revealed.

Incidentally, these quick check bytes were used as the basis for an ingenious attack against OpenPGP a few years ago.  See http://eprint.iacr.org/2005/033.pdf

David




More information about the Gnupg-users mailing list