aes128gcm: vulnerable to truncation attacks

There is a serious flaw in aes128gcm that allows a message to be truncated while authenticated decryption still succeeds.

aes128gcm produces 1 or more AEAD records, where all but the last match the given record size. This allows you to authenticate the end of the stream when you receive at least 2 records. But if you only receive 1 record you cannot tell if you have a complete message or a truncated message with a tampered record size.

The problem is that the record size in the header is not authenticated.

For example, the "Encryption with Multiple Records" example in the spec consists of the following ciphertext (in base64url), which decrypted to "I am the walrus":

uNCkWiNYzKTnBN9ji3-qWAAAABoCYTGHOqYFz-0in3dpb-VE2GfBngkaPy6bZus_
qLF79s6zQyTSsA0iLOKyd3JqVIwprNzVatRCWZGUx_qsFbJBCQu62RqQuR2d

Truncating this ciphertext after the 1st record, and increasing the record size field in the header from 26 to 27 gives:

uNCkWiNYzKTnBN9ji3-qWAAAABsCYTGHOqYFz-0in3dpb-VE2GfBngkaPy6bZus_qA

This successfully decrypts to "I am th". It needs to fail, either with an authentication failure or a premature end failure.


Suggestion: include the record size in the derivation of the key and nonces.
Passing the 20 bytes <16-byte salt><4-byte records size> as the 'salt' parameter of the HKDF Extract call might work. Though putting including the record size in the cek_info and nonce_info values that are fed to HKDF Expand calls might be even better.

--
James Manger

Received on Monday, 23 January 2017 02:48:45 UTC