[noise] Re-keying CipherState's

Trevor Perrin trevp at trevp.net
Thu Dec 29 15:54:08 PST 2016


On Thu, Dec 29, 2016 at 2:39 PM, Rhys Weatherley
<rhys.weatherley at gmail.com> wrote:
> After posting my previous message, I thought a bit more about re-negotiation
> of keys during a session.
>
> Using resumption keys and a completely new NoisePSK_NN handshake may be a
> bit heavy.  And it is difficult to co-ordinate between the two directions
> when they should stop using the previous keys and re-negotiate.
>
> CipherState.Rekey():
>   - If k is empty or n is 2^64-1, then signal and error and fail.
>   - Set temp to the first 32 bytes of ENCRYPT(k, n, [], zeroes) where zeroes
> is a sequence of 32 zero bytes.
>   - InitializeKey(temp)


We experimented with something like that:

At one point every call to cipher encryption/decryption would rekey,
but we removed it because frequent rekeying is slow with some ciphers
(eg AES-GCM), and some implementations.  But that's something you
could do with minimal protocol impact by redefining
CipherState.EncryptWithAd / DecryptWithAd.

I think the goal here is forward secrecy for long-lived connections.
Could applications achieve this with existing mechanisms, just by
re-handshaking periodically?

Re-handshaking has a little better security properties, because it
re-authenticates the long-term keys, and even if the attacker steals
those keys, re-handshaking forces the attacker to become an active
MITM (instead of a passive decrypter).

More importantly it might avoid new mechanisms and complexity:
 - new state variables and state machines
 - new packet types in clear, leaking information (we currently don't
need a "type" byte for transport messages)
 - new checks that parties might or might not apply, thus one more
thing to debug and complicate interop

So I guess I'd like to understand the use cases / requirements for
something like this better, and why they can't be met with existing
features.

Trevor


More information about the Noise mailing list