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.simp...@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

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

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.


The cryptography mailing list

Reply via email to