# RE: Explanation of deriveKey (was Re: ACTION-22: Key export)

Date: Tue, 28 Aug 2012 15:18:39 +0000
To: Mark Watson <watsonm@netflix.com>
CC: Ryan Sleevi <sleevi@google.com>, Mitch Zollinger <mzollinger@netflix.com>, "<public-webcrypto@w3.org>" <public-webcrypto@w3.org>
```I think the difference is in whether one defines generation vs. derivation as a characteristic of the inputs or the outputs.

My proposal (and my understanding of Ryan's proposal):

- Generation = defined as an operation whose output has a specific structure and is useful for a specific algorithm (i.e. a key)
- Derivation = an operation whose output is opaque "random-looking" bytes

- Generation = an operation which generates something (a key or random-looking bytes) using entropy not supplied by the caller
- Derivation = an operation which generates something (a key or random-looking bytes) purely as a function of inputs supplied by the caller

Did I understand your proposal correctly?

-----Original Message-----
From: Mark Watson [mailto:watsonm@netflix.com]
Sent: Tuesday, August 28, 2012 8:12 AM
Cc: Ryan Sleevi; Mitch Zollinger; <public-webcrypto@w3.org>
Subject: Re: Explanation of deriveKey (was Re: ACTION-22: Key export)

Sent from my iPhone

>> To me it would make sense that "generation" is an operation that creates secret information "out of nowhere" (or rather, out of something that is invisible to this API), and "derivation" is an operation that creates secret information based on some other secret information already present and visible through the API (i.e. another Key).
>
> This is appealing, but has the problem that "generation" also requires the result to have algorithm-specific structure (e.g. product of two large primes) that "derivation" algorithms typically don't guarantee.
>
> Stated differently, this proposal seems to require "derivation" to also supply a target algorithm, which isn't always needed (e.g. when generating nonces through a KDF).
>
> My mental model is more in line with what Ryan proposed.

I was trying to capture what Ryan was proposing. What difference do you see ?

...Mark

>
> -----Original Message-----
> From: Mark Watson [mailto:watsonm@netflix.com]
> Sent: Monday, August 27, 2012 1:22 PM
> To: Ryan Sleevi
> Cc: Mitch Zollinger; <public-webcrypto@w3.org>
> Subject: Re: Explanation of deriveKey (was Re: ACTION-22: Key export)
>
> Ryan,
>
> Makes sense. Could you add some text clarifying this to the specification ?
>
> One comment below...
>
> On Aug 27, 2012, at 11:48 AM, Ryan Sleevi wrote:
>
>> On Mon, Aug 27, 2012 at 11:10 AM, Mark Watson <watsonm@netflix.com> wrote:
>>> Ryan, all,
>>>
>>> I think the specification could do with some better explanation of the scope of the deriveKey operation.
>>>
>>> There are a few things which I believe I understand now (based on the discussion below), but which are not at all clear in the specification as it stands. I think this could be a cause of confusion if not addressed for FPWD.
>>>
>>> First, the Key object can represent any kind of secrets, not just
>>> keys that are suitable for the encrypt/decrypt/sign/verify
>>> operations. Specifically, a Key object may represent
>>> - the public/private values generated in the first phase of a DH
>>> exchange (these are not "keys" in the usual sense)
>>
>> The public/private values here are typically referred to as "DH
>> private keys" and "DH public keys". Even RFC 2631 refers to them as
>> such.
>>
>>> - the shared secret generated as the output of the second phase of a
>>> DH exchange (this is not a "key" yet either)
>>
>> In PKCS#11 terms, a "shared secret" is known as a "secret key". In
>> CNG terms, the result of key agreement is called a SECRET_HANDLE,
>> although the SECRET_HANDLE is admittedly a distinct type than the
>> KEY_HANDLE type.
>>
>> I think I take the view that the API data-type hierarchy should be
>> similar to the PKCS#11 data-type hierarchy documented in Section 6.4
>> of PKCS#11 2.20 -
>> http://www.cryptsoft.com/pkcs11doc/STANDARD/pkcs-11v2-20.pdf
>>
>> Within the "Key" type, there are three types of keys that may
>> represented - a public key, a private key, and a secret key. For
>> secret keys, there may be a specific algorithm (ie: symmetric keys),
>> or it may be defined as a "generic" key (ie: a opaque blob-o-bytes)
>>
>>>
>>> Second, the deriveKey method can be used for any operation which takes one Key object and creates a new one by combining somehow with some other input information. This could be key derivation in the usual sense of extracting an appropriate amount of keying material from a secret and designating it as suitable for specific operation types. Or it could be Phase 2 of a DH key exchange, where the client private value is combined with the server public value.
>>
>> Yes.
>>
>> In CNG terms, this is the combination of the functionality provided
>> by the NCryptKeyDerivation and NCryptSecretAgreement functions.
>>
>> In PKCS#11 terms, this maps to C_DeriveKey.
>>
>> Admittedly, it's a problematic distinction to separate our
>> "generation" and "derivation". In PKCS#11 terms, for example, PBKDF#2
>> is a key generation mechanism, while for CNG & CDSA, it's listed
>> under key derivation. For DH, in PKCS#11 & CDSA, it's derivation,
>> while for CNG, it's secret agreement (AFAICT).
>>
>> I'm not sure what the good criteria should be for why an algorithm
>> should be one rather than the other. Perhaps derivation should be any
>> operation that yields an opaque series of bytes, while generation
>> should be any operation that yields a key? I'm not entirely sure here
>> either, which is admittedly, problematic :)
>
> To me it would make sense that "generation" is an operation that creates secret information "out of nowhere" (or rather, out of something that is invisible to this API), and "derivation" is an operation that creates secret information based on some other secret information already present and visible through the API (i.e. another Key).
>
> If the operations are defined in those broad terms, then the DH and other usages all make sense.
>
> ...Mark
>
>>
>>>
>>> Of course, if I got either of the two things above wrong, there's
>>> even more need for explanation ;-)
>>>
>>> ...Mark
>>>
>>>
>>> On Aug 27, 2012, at 10:43 AM, Ryan Sleevi wrote:
>>>
>>>> On Sun, Aug 26, 2012 at 1:06 AM, Mitch Zollinger <mzollinger@netflix.com> wrote:
>>>>> Ryan,
>>>>>
>>>>> First off, thank you. Things are beginning to make more sense
>>>>> because of your detailed response. More inline below...
>>>>>
>>>>>
>>>>> On 8/25/12 1:10 PM, Ryan Sleevi wrote:
>>>>>>
>>>> <snip>
>>>>>> // Handles completion of Phase 2 of DH agreement function
>>>>>> onDHDeriveKeyComplete(keyDeriver) {  // zz is the result of the
>>>>>> Phase 2 of PKCS #3 and is equivalent to ZZ  // as documented in
>>>>>> X9.42 - aka the shared secret  // ZZ = g ^ (xb * xa) mod p  var
>>>>>> zz = keyDeriver.result;
>>>>>
>>>>>
>>>>> Is zz the actual shared secret, or is it an opaque handle at this point?
>>>>
>>>> For sake of discussion, let's say an opaque Key handle. That is, I
>>>> imagine where there are cases where it might be more useful to be
>>>> able to combine the (derive+export as opaque bytes) into a single
>>>> step, at which point you'd want zz to be an ArrayBuffer, but for
>>>> the sake of the example & discussion, I think using a Key object here is fine.
>>>>
>>>> <snip>
>>>>>> Am I also understanding that
>>>>>> this is being proposed as an OPTIONAL / MAY (not even a normative
>>>>>> RFC
>>>>>> SHOULD) - eg: not all user agents need to support
>>>>>> ProtectedKeyExchange?
>>>>>
>>>>>
>>>>> I don't want to add the ProtectedKeyExchange if we can meet the
>>>>> intended goals of a multi-step key exchange / derivation where no
>>>>> keying material created during the different phases is visible to
>>>>> the script code at any time.
>>>>
>>>> To make sure I'm on the same page - we're talking about ensuring
>>>> that the "Core API" (eg: excluding specific algorithm definitions)
>>>> makes no normative requirements on what the output of operations
>>>> MUST be, right? That is, to ensure the spec DOES NOT say that every
>>>> output MUST be an ArrayBuffer for this type of operation (for
>>>> example)
>>>>
>>>> If so, I'd agree, that's a reasonable concern, and I would want to
>>>> ensure that whatever is normatively specified is the bare minimum
>>>> of algorithm-independent functionality, and to leave the majority
>>>> of normative behaviours to individual algorithms. The "Core API"'s
>>>> normative behaviours should focus on state machines and error
>>>> handling, while the algorithms themselves should define inputs &
>>>> outputs.
>>>>
>>>> Is that a reasonable understanding of the concerns?
>>>>
>>>> <snip>
>>>>>>
>>>>>> So, there's two meanings of protected key exchange here
>>>>>> - Protected from content script, but the content script is
>>>>>> allowed to 'drive' the operation. I think this need is already
>>>>>> met (as demonstrated by the pseudo-code)
>>>>>
>>>>>
>>>>> This is what we're aiming for.
>>>>>
>>>>>
>>>>>> - Protected from the user agent (as in, secure element
>>>>>> provisioning), which I think is, at best, secondary features, but
>>>>>> more likely out of scope in general.
>>>>>
>>>>>
>>>>> I get this point. It's still somewhat unclear where this goal is
>>>>> incompatible with the "protected from content script" goal given
>>>>> that the underlying implementation could call out to a HW element.
>>>>> But that's more of a curiosity question.
>>>>
>>>> What I mean is whether the spec should normatively mandate or claim
>>>> any protection from user agents.
>>>>
>>>> I want to ensure that the spec doesn't *mandate* a secure element
>>>> in order to implement the normative criteria. If the definition of
>>>> 'protected' means you distrust the user agent, then no user agent
>>>> that trusts or protects users can ever actually implement this,
>>>> short of outsourcing the crypto.
>>>>
>>>> My view is that a conforming user agent should be able to implement
>>>> this in terms of storing the secrets in plain text in stable
>>>> storage, even when a key has been flagged 'protected' (meaning:
>>>> protected from /future/ content script). That you /can/ implement
>>>> more protection -
>>>> eg: by using a secure element - is great, but by no means is it
>>>> mandated in the API that you MUST do so.
>>>>
>>>> Make sense?
>>>>
>>>> <snip>
>>>>
>>>>>> In which case, your application would/should never request the
>>>>>> 'exportable' flag, and your problem should be solved.
>>>>>
>>>>>
>>>>> I believe this is one of the key points that I would like to make
>>>>> certain we agree on. Would I be correct in taking the above
>>>>> comment and expanding it in more detail:
>>>>> * Our application would never request "exportable = true".
>>>>> * If our application ever did request "exportable = true" the
>>>>> underlying implementation would throw an error.
>>>>> * Every phase in our key exchange + session key derivation,
>>>>> including the final stage, would have a result which was an opaque
>>>>> handle to the underlying key data, inaccessible to the script code.
>>>>>
>>>>> ?
>>>>
>>>> re: throwing an error: Yes, I think that's the intent, but that
>>>> means normative text should be added to the appropriate places to
>>>> clarify the handling of unsupported parameters/algorithms/modes and
>>>> raising the right exceptions. But yes, I think that's correct.
>>>>
>>>> re: every phase: I think that behaviour is going to be dictated by
>>>> how the algorithms are defined (what their inputs are, what their
>>>> outputs are). I think for the algorithms documented by this
>>>> WG/endorsed by the W3C, we'll want to reach consensus on what the
>>>> right form of each output should be. Should it be data, a single Key, multiple Keys, etc.
>>>> If an implementation does do something vendor-specific, then it's
>>>> up to that implementation to describe the outputs and their behaviour.
>>>>
>>>>
>>>
>>
>
>
>
>
```
Received on Tuesday, 28 August 2012 15:19:52 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 19:01:26 UTC