[Cryptography] Evaluating draft-agl-tls-chacha20poly1305

William Allen Simpson william.allen.simpson at gmail.com
Wed Sep 11 12:43:04 EDT 2013

On 9/11/13 10:27 AM, Adam Langley wrote:
> [attempt two, because I bounced off the mailing list the first time.]
> On Tue, Sep 10, 2013 at 9:35 PM, William Allen Simpson
> <william.allen.simpson at gmail.com> wrote:
>> Why generate the ICV key this way, instead of using a longer key blob
>> from TLS and dividing it?  Is there a related-key attack?
> The keying material from the TLS handshake is per-session information.
> However, for a polynomial MAC, a unique key is needed per-record and
> must be secret.

Thanks, this part I knew, although it would be good explanatory text to
add to the draft.

I meant a related-key attack against the MAC-key generated by TLS?

Thereby causing you to discard it and not key the ICV with it?

> Using stream cipher output as MAC key material is a
> trick taken from [1], although it is likely to have more history than
> that. (As another example, UMAC/VMAC runs AES-CTR with a separate key
> to generate the per-record keys, as did Poly1305 in its original
> paper.)
Oh sure.  We used hashes long ago.  Using AES is insane, but then
UMAC is -- to be kind -- not very efficient.

My old formulation from CBCS was developed during the old IPsec
discussions.  It's just simpler and faster to xor the per-packet counter
with the MAC-key than using the ChaCha cipher itself to generate
per-packet key expansion.

I was simply wondering about the rationale for doing it yourself.  And
worrying a little about the extra overhead on back-to-back packets.

>> If AEAD, aren't the ICV and cipher text generated in parallel?  So how do
>> you check the ICV first, then decipher?
> The Poly1305 key (ICV in your terms?) is taken from a prefix of the
> ChaCha20 stream output. Thus the decryption proceeds as:
> 1) Generate one block of ChaCha20 keystream and use the first 32 bytes
> as a Poly1305 key.
> 2) Feed Poly1305 the additional data and ciphertext, with the length
> prefixing as described in the draft.
> 3) Verify that the Poly1305 authenticator matches the value in the
> received record. If not, the record can be rejected immediately.
> 4) Run ChaCha20, starting with a counter value of one, to decrypt the
> ciphertext.
ICV = Integrity Check Value at the end of the packet.  So ICV-key.
Sometimes MAC-key.

Anyway, good explanation!  Please add it to the draft.

> An alternative implementation is possible where ChaCha20 is run in one
> go on a buffer that consists of 64 zeros followed by the ciphertext.
> The advantage of this is that it may be faster because the ChaCha20
> blocks can be pipelined. The disadvantage is that it may need memory
> copies to setup the input buffer correctly. A moot advantage, in the
> case of TLS, of the steps that I outlined is that forgeries are
> rejected faster.
Depends on how swamped the processor.  I'm a big fan of rejecting
forgeries (and replay attacks) before decrypting.  Not everybody is
Google with unlimited processing power. ;)

>> Needs a bit more implementation details.  I assume there's an
>> implementation in the works.  (Always helps define things with
>> something concrete.)
> I currently have Chrome talking to OpenSSL, although the code needs
> cleanup of course.

More information about the cryptography mailing list