[noise] Resumption PSKs
Christopher Wood
christopherwood07 at gmail.com
Wed Jun 13 09:40:23 PDT 2018
On Tue, Jun 12, 2018 at 10:20 AM Trevor Perrin <trevp at trevp.net> wrote:
>
>
> On Tue, Jun 12, 2018 at 4:13 PM, Christopher Wood <christopherwood07 at gmail.com> wrote:
>>
>>
>> This optimization is nice. However, I still think there's room to
>> improve from an API perspective. Assuming
>> implementations discard the handshake state after calling Split and
>> also have access to a PRF, what if we did this:
>>
>> ~~~
>> transport1, transport2, K = HKDF(ck, zerolen, 3)
>> c1, c2 = CipherState(transport1), CipherState(transport2)
>> tk = HMAC(K, h)
>> delete ck
>> return c1, c2, tk
>> ~~~
>>
>> Applications could then derive whatever keying material they wanted
>> from the third output -- tk -- independently
>> from c1 and c2. Applications which don't want this can simply toss it,
>> much like apps that don't need both CipherState
>> objects will do. Of course, punts additional key derivation
>> responsibility to the application. Provided we describe how
>> additional keys are derived, e.g., HMAC(tk, label), this seems fine.
>
>
>
> OK, I see some value to separating the derivation of additional keys from the HKDF(ck, ...).
>
> For example, I'm wondering if we should adapt this mechanism to also handle derivation of additional keys *during* the handshake:
>
> https://moderncrypto.org/mail-archive/noise/2018/001675.html
>
> In that case, we could perhaps modify MixKey() so that it produced some additional "master" key material independent from ck and k, and then the application could access this to derive additional keys. So it would make sense to separate derivation of the master key material from the later point where the application requests additional keys.
>
> What I don't like as much about that sketch is:
>
> * Just giving the application a single key. I think we should have a defined way to derive multiple keys for multiple purposes from the same master material, so that mechanisms for resumption PSKs, and extra indistinguishability padding, and etc, can easily coexist, and so people don't have to roll-their-own key derivation on top of their Noise library.
Indeed -- punting this to the application seems to be an easy way for
it to go wrong.
>
> * I also think it would be nice to derive the additional key material without deriving the transport keys, in case some applications don't need transport keys.
Agreed. The API should support both use cases easily.
>
> So the following sketch derives an Additional Symmetric Key (ASK) "master key" from HKDF, which can then be used to create chains at a later point.
>
> The idea is that we can use this during the handshake as well as during Split(). We haven't used HKDF info before, but using it now means that ask_master derivation just requires a single extra HMAC, since it can share the HKDF-Extract step with the existing HKDF:
>
> # During handshake
> ck, k = HKDF(ck, ikm)
> ask_master = HKDF(ck, ikm, info="ask")
>
> # During split
> transport1, transport2 = HKDF(ck, zerolen)
> ask_master = HKDF(ck, zerolen, info="ask")
>
> # Either case
> create_chains(labels):
> ask_chain1 = HMAC(ask_master, h || label1)
> ask_chain2 = HMAC(ask_master, h || label2)
> ask_chain3 = HMAC(ask_master, h || label3)
> ...
> delete ask_master
This is quite nice. To be clear, create_chains is invoked after
Split(), correct? If an application doesn't need transport keys, would
it still invoke Split()? Based on what you wrote, I believe the answer
is "no," as ask_master is updated during the handshake (and in
Split()). If that's the case, what is this new API?
Best,
Chris
More information about the Noise
mailing list