[noise] Extra key derivation - use cases, mechanisms
trevp at trevp.net
Thu Jan 19 01:49:53 PST 2017
We've had a few discussions about deriving extra keys for various
uses. I'll try to collect the use cases and some options:
Use cases for extra keys
(1) REKEY: During the transport phase, the application might want to
replace an old k with new k such that compromise of new k doesn't
compromise old k.
We would probably define the rekey operation in the Noise spec, but
leave it to the application if/when to trigger rekeys. For example:
* After every 1000 messages (Lightning)
* After every message (old versions of Noise)
* After a certain volume of data is transmitted (TLS 1.3)
* After requested by peer (TLS 1.3)
Note that rekey might be frequent (every message), so it should be fast.
(2) PSK for renegotiation/resumption: A key derived from an old
session could be used as PSK in a new handshake either contained
within the original session (renegotiation) or some time later
(3) MISC: TLS introduced the idea of "exporters" or "extractors" for
letting the application request extra keys based on labels . I
think it's mainly (entirely?) used in two cases:
* The TLS handshake is performed, but instead of the TLS record layer
something different is done (e.g. EAP). However in these cases the
TLS traffic keys aren't used, so it's not clear why TLS encourages
exporting different keys instead of just using the traffic keys.
* TLS uses an exported value for channel binding. However Noise uses
the handshake hash for this, which is simpler and allows binding at
any stage of the handshake.
So I'm not sure there's much value to arbitrary exporters/extractors.
But we'll consider how to provide this anyways.
Mechanisms for extra keys
As an example, TLS 1.3 currently specifies HMAC to derive some extra
keys in the handshake:
- client and server traffic secrets (for HMAC-based REKEY)
- resumption secret (for PSK)
- exporter secret (for MISC)
It's a little inelegant to derive and store 4 extra keys you might not
need. Also, the HMAC-based rekey requires 3 HMACs, which is
inefficient if we imagine rekeying on every message.
Lightning uses HKDF to derive the equivalent of traffic secrets for
HKDF-based REKEY, which also turns into 3 HMACS per rekey.
If we don't want to store extra secrets for extra key derivation, and
we want fast rekey, we could do extra key derivation from the traffic
keys (k) themselves. For example, use k to encrypt 96 bytes of zeros
with nonce=2^64-1, and use:
- first 32 bytes of ciphertext for rekey
- next 32 bytes for a renegotiation/resumption key
- next 32 bytes for an exporter-like key to derive more keys from an
application-chosen label, as HMAC(key, label)
This is very fast for ChaChaPoly and AESGCM, since the authenticator
can be skipped so this is just a few ChaCha20 or AES operations. It's
less efficient for AESGCMSIV, because SIV modes calculate the
authenticator first, then use it as the IV (so it can't be skipped).
Also, AESGVMSIV performs some key-derivation internally.
We could define a special key derivation for AESGCMSIV and similar
modes that uses the "key-genererating key" directly. That's a bit
ugly, but anyone with access to an AES-GCM-SIV function probably also
has access to a raw AES, so maybe this is OK?
More information about the Noise