Re: aes128gcm: why verify padding?

I don't think that this warrants a change at this stage.

The reason for enforcing the checking was so that we could ensure that
when people sent padding there was only one way to send it.  You are
asking to allow variation, which I think needs stronger justification
than you've provided.

A secondary, though weak, reason for validating is to squash
heartbleed-like uninitialized memory reads.

Regarding AEAD APIs, yes, I'm aware that some libraries have bad APIs
for AEADs (thanks openssl).  I don't think that's justification for a
change, at least not in the format.  The API, certainly.


On 16 January 2017 at 12:51, Manger, James
<James.H.Manger@team.telstra.com> wrote:
> draft-ietf-httpbis-encryption-encoding allows any amount of padding to be
> added alongside the content being encrypted. The spec says the receiver
> (decryptor) MUST confirm that every padding byte is 0x00. Why?
>
>
>
> I’m not sure how it helps to check the padding. It doesn’t make the
> encryption deterministic as there is a salt involved, and the length of
> padding can also vary. It isn’t useful for integrity as that is provided by
> the GCM tag.
>
>
>
> Checking the padding could be harmful. Padding (to a block size) has caused
> lots of security vulnerabilities when the padding is checked before doing a
> proper integrity check. AEAD algorithms (such as GCM) theoretically solve
> this, but only when receivers process a whole AEAD decryption in one go, not
> via a (very common) streaming API.
>
>
>
> The aes128gcm Content-Encoding adds “app-layer” padding, but by putting it
> first with a fixed format it is almost tempting receivers to check it before
> processing the rest of the ciphertext, and hence introduce vulnerabilities.
>
>
>
> 3 possible improvements:
>
>
>
> 1.       Allow padding bytes to have any value. The receiver just skips
> them.
>
>
>
> 2.       Calculate the padding length by reducing a 2-byte unsigned integer
> modulo the maximum possible padding length (plaintext length – 2). That
> means every 2-byte value will give a valid padding length.
>
>
>
> 3.       Put the 2-byte padding length field at the end. So the receiver has
> to have a whole AEAD plaintext block before knowing where the content
> starts.
>
>
>
> A plaintext block would be: plaintext = padding || content || padlen
>
> Len(plaintext) is the record size - 16.
>
> Len(padlen) is 2 bytes.
>
> Len(padding) = padlen % (Len(plaintext) - 2)
>
> Padding bytes have any value.
>
> Content is the remainder of the plaintext block.
>
>
>
> The nice feature of this is that every plaintext block is valid. The last 2
> bytes can be anything; mod (Len(plaintext) - 2) always gives a valid padding
> length; padding can be anything; and all that is left is the content to pass
> to the next layer. With this arrangement there is very little risk that
> plaintext structure is dangerously checked before performing the AEAD
> integrity check.
>
>
>
> This form is no harder that the current structure to process, but it does
> encourage proper use of AEAD APIs.
>
>
>
> --
>
> James Manger
>
>

Received on Monday, 16 January 2017 00:33:17 UTC