<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 13, 2018 at 4:40 PM, Christopher Wood <span dir="ltr"><<a href="mailto:christopherwood07@gmail.com" target="_blank">christopherwood07@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail-HOEnZb"><div class="gmail-h5">On Tue, Jun 12, 2018 at 10:20 AM Trevor Perrin <<a href="mailto:trevp@trevp.net">trevp@trevp.net</a>> wrote:<span style="color:rgb(34,34,34)">> 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.</span><br></div></div><span class="gmail-">
><br>
> 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:<br>
><br>
> # During handshake<br>
> ck, k = HKDF(ck, ikm)<br>
> ask_master = HKDF(ck, ikm, info="ask")<br>
><br>
> # During split<br>
> transport1, transport2 = HKDF(ck, zerolen)<br>
> ask_master = HKDF(ck, zerolen, info="ask")<br>
><br>
> # Either case<br>
> create_chains(labels):<br>
>   ask_chain1 = HMAC(ask_master, h || label1)<br>
>   ask_chain2 = HMAC(ask_master, h || label2)<br>
>   ask_chain3 = HMAC(ask_master, h || label3)<br>
>   ...<br>
>   delete ask_master<br>
<br>
</span>This is quite nice. To be clear, create_chains is invoked after<br>
Split(), correct? If an application doesn't need transport keys, would<br>
it still invoke Split()? Based on what you wrote, I believe the answer<br>
is "no," as ask_master is updated during the handshake (and in<br>
Split()). If that's the case, what is this new API?<br></blockquote><div><br></div><div>The application wouldn't have to call the Split() HKDF for transport keys, but how we'd phrase this as API / pseudocode is up in the air.</div><div><br></div><div>Maybe an API vaguely like this?</div><div><br></div><div>EnableASK():</div><div>  - sets a boolean that causes ASK master keys to be derived, both during the handshake and at the end of it.</div><div><br></div><div>InitializeASK(labels):</div><div>  - Assuming ASK was enabled, and there is a non-empty ASK master key, derives a set of ASK chain keys from the ASK master key and the input labels, then deletes the ASK master key.  This could be called multiple times, including after the handshake and during it, and replaces any previous ASK chains when called.</div><div><br></div><div>GetASK(label)</div><div> - Assuming ASK is enabled and initialized, returns the next key from the appropriate chain, and advances the appropriate ASK chain key, deleting the previous chain key.</div><div><br></div><div>So if you don't EnableASK(), you don't pay any costs for deriving ASK master keys.  If you do enable it, they you can call InitializeASK/GetASK either during a handshake or after it, to get ASKs with the same level of security as the current encryption keys.</div><div> </div><div><br></div><div>Trevor</div><div><br></div></div></div></div>