Page MenuHome GnuPG

Failure to decrypt AEAD-encrypted files in some rare cases
Closed, ResolvedPublic

Description

When size of encrypted data (i.e. total number of bytes in underlying literal/compressed packet) is multiple of chunk length then decryption fails 'Premature EOF' error (decrypt-data.c:586 of 26c900a)
This was reproduced at least for small inputs (~5k) and small chunk sizes (64-256 bytes).
I will attach encrypted file, which exposes the error, and cleartext file. Decryption password is 'password'.

Details

Version
26c900a

Event Timeline

Can you help me and tell me the AD for the last and the final chunk?
My current values are:

gpg: DBG: nonce: 19c04f0a089368d13a754442f7841ccf
gpg: DBG: authdata: d4010c01000000000000000009
gpg: DBG: tag: 5a15c6f5bf899436399c3ee6be047493
gpg: DBG: tag is valid

gpg: DBG: nonce: 19c04f0a089368d13a754442f7841ccc
gpg: DBG: authdata: d4010c0100000000000000000a0000000000000280
gpg: DBG: tag: a9a8b8756566aa47d374ccf06711ad1f
gpg: DBG: gcry_cipher_checktag failed (final): Checksum error

Hi Werner,
Looks like there is a problem on my side, I miscalculated data length (0x240 while it should be 0x280).
Other then this values are the same:

authenticated data:  (13 bytess):
00000 | d4 01 0c 01 00 00 00 00 00 00 00 00 09
nonce:  (16 bytess):
00000 | 19 c0 4f 0a 08 93 68 d1 3a 75 44 42 f7 84 1c cf 

authenticated data:  (21 bytess):
00000 | d4 01 0c 01 00 00 00 00 00 00 00 00 0a 00 00 00
00016 | 00 00 00 02 40
nonce:  (16 bytess):
00000 | 19 c0 4f 0a 08 93 68 d1 3a 75 44 42 f7 84 1c cc

I found another issue in current master of GnuPG. Probably you already noticed it - when GnuPG AEAD-encrypts input which is a multiple of chunk size, then incorrect chunk number is used in the last block (+1)
The same happens for decryption.
Here is debug output of 128-byte input decryption with 64-byte chunk len:

gpg: DBG: nonce: D0 33 CD AC B5 54 07 66 2C 5C 55 7F A9 F2 EF
gpg: DBG: authdata: D4 01 07 02 00 00 00 00 00 00 00 00 00
gpg: DBG: nonce: D0 33 CD AC B5 54 07 66 2C 5C 55 7F A9 F2 EE
gpg: DBG: authdata: D4 01 07 02 00 00 00 00 00 00 00 00 01
gpg: DBG: nonce: D0 33 CD AC B5 54 07 66 2C 5C 55 7F A9 F2 ED
gpg: DBG: authdata: D4 01 07 02 00 00 00 00 00 00 00 00 02
gpg: DBG: eof seen: holdback buffer has the tags.
gpg: DBG: nonce: D0 33 CD AC B5 54 07 66 2C 5C 55 7F A9 F2 EC
gpg: DBG: authdata: D4 01 07 02 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 80

Looks like GnuPG starts the third chunk and then also increments chunk number for final auth data, while not checking that last chunk didn't process any data.

Here is a file

created using the fixed gpg version. I have a lot more of these test files; I can tar them up and provide them here. They are too lareg to go into the repo or the tarball. The files are all uncompressed and consists of ~ characters.

Hi Werner, thanks.
Looks like our tests against GnuPG are passing now.
Can you please provide the password for this file as well? 'password' doesn't seem to fit.

password is "abc". I have some comments in the commit logs.

(Some files are incorrect)


is a simple script to check that the encrypted files in the above tarball. How to use:

cd gnupg
mkdir test-aead
cd test-aead
tar xzf gnupg-aead-enc-files-20180227.tar.gz
sh checktestdata.sh gnupg-aead-enc-files-20180227/*

I found another encoding error which renders the test data uploaded yesterday useless: Here is a bogus AEAD packet:

00000040  d4 84 01 07 01 00 6c 34  7c 37 83 24 2a 11 bc 1c  
00000050  bd 1a 76 da 93 8a
              [start chunk] 32 cd  80 a5 8e db 3a 7d 4a 40  
00000060  c5 0d 82 01 8d 64 7f 65  cd ca 58 d0 e7 db 3b 5e  
00000070  89 d9 1b c8 d9 93 1a 37  3c 0e a5 8f 4b 0d 9f db  
00000080  34 56 c8 f1 e9 b7 f5 0b  d2 53 4f 6c fd f8 e9 16  
00000090  cd a4 ae f6 7f 65
                      [tag] ef 5f  96 af 62 70 f4 30 27 37  
000000a0  68 61 95 0a fb 23
                [extra tag] a6 66  75 7a 47 bb 57 d3 da 5a  
000000b0  4d d1 c2 2f 43 39
                [final tag] cd 22  91 16 1d 92 17 1f f2 cf  
000000c0  0f c9 11 56 d0 a9

The [extra tag] is done on a zero length chunk which we should not emit. A sample of the correct output is this:

00000040  d4 74 01 07 01 00 26 60  d4 c6 4c 8c a1 ad 31 84  
00000050  8a 68 ff 70 c4 5e
              [start chunk] 75 52  d6 77 96 ea 25 4d 26 dc  
00000060  9c 6d 6c b0 40 3a 53 e2  45 0e bf de 6d 46 ad fa  
00000070  de 87 a8 83 54 76 f1 25  7c d5 1c 39 b5 23 01 c8  
00000080  40 80 40 cf 8f cd d4 95  41 16 d5 3f 49 fd e2 b7  
00000090  b6 58 8d bc 32 2b
                      [tag] 12 cb  4e 41 33 ce ea ac 82 02  
000000a0  80 81 10 90 ed b2
                [final tag] e6 ee  4f 16 34 b1 dc 58 19 a7  
000000b0  c9 57 5b 81 c7 5e

Here is fixed set of encrypted files for use with the checkdata.sh script.

Thanks, Werner.
With the latest data everything works fine.
I also a problem with incorrect cipher state resetting if last chunk is 0-size.