- From: Jim Schaad <ietf@augustcellars.com>
- Date: Mon, 22 Jul 2013 16:16:55 -0700
- To: "'Ryan Sleevi'" <sleevi@google.com>
- Cc: "'Vijay Bharadwaj'" <Vijay.Bharadwaj@microsoft.com>, <public-webcrypto@w3.org>, "'Richard Barnes'" <rlb@ipv.sx>, "'Israel Hilerio'" <israelh@microsoft.com>
> -----Original Message----- > From: Ryan Sleevi [mailto:sleevi@google.com] > Sent: Monday, July 22, 2013 3:58 PM > To: Jim Schaad > Cc: Vijay Bharadwaj; public-webcrypto@w3.org; Richard Barnes; Israel Hilerio > Subject: Re: ACTION-84: Finishing support for key derivation/key agreement > (take 2) > > On Mon, Jul 22, 2013 at 3:41 PM, Jim Schaad <ietf@augustcellars.com> > wrote: > > > > > >> -----Original Message----- > >> From: Ryan Sleevi [mailto:sleevi@google.com] > >> Sent: Monday, July 22, 2013 11:57 AM > >> To: Vijay Bharadwaj > >> Cc: public-webcrypto@w3.org; Richard Barnes; Jim Schaad; Israel > >> Hilerio > >> Subject: Re: ACTION-84: Finishing support for key derivation/key > >> agreement (take 2) > >> > >> On Tue, Jun 4, 2013 at 12:03 AM, Vijay Bharadwaj > >> <Vijay.Bharadwaj@microsoft.com> wrote: > >> > Following up on the previous thread (see > >> http://lists.w3.org/Archives/Public/public-webcrypto/2013May/0106.htm > >> l), here is a more fully-fleshed-out proposal based on the latest > >> working > > draft. > >> Please let me know if I missed anything from the previous discussion, > >> or > > if you > >> have new comments. > >> > > >> > Notes: > >> > - I am leaving out MQV from the algorithm definitions for now. If > >> > there > > is > >> interest, this can be added. I'd like to point out that Windows and > > OpenSSL at > >> least do not implement it and adoption may be low due to IPR-related > >> concerns such as Ryan expressed on the earlier thread. > >> > - This is defined with reference to Futures. This is for > >> > consistency > > with the > >> current draft. To the extent that open issues remain with Futures in > >> the > > spec, > >> those issues apply here as well. > >> > - This is also subject to the existing open issues around > >> > separation of > >> operational and algorithm parameters. > >> > - Naming is hard. Existing methods are named <verb> or <verb><noun>. > >> However agreeSecret and computeSecretAgreement sound clunky to me. > If > >> you have a better idea please share. > >> > > >> > Section 11: > >> > Add a new value "secretAgreement" to enum KeyUsage. > >> > > >> > Section 14: > >> > > >> > Add to interface SubtleCrypto: > >> > > >> > Future<any> secretAgreement(Key localPrivateKey, Key peerPublicKey, > >> > AlgorithmIdentifier agreementAlgorithm, AlgorithmIdentifier > >> > derivationAlgorithm, bool extractable = false); > >> > > >> > Future<any> deriveBits(AlgorithmIdentifier kdfAlgorithm, Key > >> > baseKey, unsigned long bitLength); > >> > > >> > Section 14.2: > >> > > >> > Add new subsections describing the above methods: > >> > > >> > 14.2.x. The secretAgreement method > >> > > >> > When invoked, secretAgreement MUST perform the following steps: > >> > > >> > 1. Let normalizedAgreementAlgorithm be the result of processing > >> agreementAlgorithm according to the algorithm normalizing rules. > >> > > >> > 2. If normalizedAgreementAlgorithm does not describe a registered > >> algorithm that supports the secretAgreement operation, throw a > >> NotSupportedError and terminate the algorithm. > >> > > >> > 3. Let normalizedDerivationAlgorithm be the result of processing > >> derivationAlgorithm according to the algorithm normalizing rules. > >> > > >> > 4. If normalizedDerivationAlgorithm does not describe a registered > >> algorithm that supports the derive operation, throw a > >> NotSupportedError > > and > >> terminate the algorithm. > >> > > >> > 5. Let future be a new Future object and resolver its associated > > resolver. > >> > > >> > 6. Return future and continue executing the remaining steps > >> asynchronously. > >> > > >> > 7. If an error occurs, run these substeps and then terminate the > > algorithm: > >> > 1. Let result be null. > >> > 2. Execute resolver's reject(value) algorithm, with result > >> > as > > the value > >> argument. > >> > > >> > 8. If localPrivateKey, peerPublicKey, > > agreementAlgorithm.localPrivateKey2 > >> (if present), agreementAlgorithm.localPublicKey2 (if present), and > >> agreementAlgorithm.peerPublicKey2 (if present) are not all keys of > >> type normalizedAgreementAlgorithm, terminate this algorithm with an > error. > >> > > >> > 9. If localPrivateKey, peerPublicKey, > > agreementAlgorithm.localPrivateKey2 > >> (if present), agreementAlgorithm.localPublicKey2 (if present), and > >> agreementAlgorithm.peerPublicKey2 (if present) do not all contain the > >> "secretAgreement" KeyUsage in their keyUsage properties, terminate > >> this algorithm with an error. > >> > > >> > 10. Let secret be the result of executing the secret agreement > >> > algorithm > >> defined by the algorithm indicated in normalizedAgreementAlgorithm. > >> > > >> > 11. Let result be the result of executing the importKey algorithm, > >> > with > > "raw" > >> as format, with secret as keyData, with normalizedDerivationAlgorithm > >> as algorithm, with extractable as extractable, and "derive" as keyUsages. > >> > > >> > 12. If the key import algorithm failed, terminate this algorithm > >> > with an > > error. > >> > > >> > 13. Execute resolver's resolve(value) algorithm, with result as the > > value > >> argument. > >> > > >> > > >> > 14.2.y The deriveBits method > >> > > >> > When invoked, deriveBits MUST perform the following steps: > >> > > >> > 1. Let normalizedKdfAlgorithm be the result of processing > >> > kdfAlgorithm > >> according to the algorithm normalizing rules. > >> > > >> > 2. If normalizedKdfAlgorithm does not describe a registered > >> > algorithm > > that > >> supports the derive operation, throw a NotSupportedError and > >> terminate the algorithm. > >> > > >> > 3. Let future be a new Future object and resolver its associated > > resolver. > >> > > >> > 4. Return future and continue executing the remaining steps > >> asynchronously. > >> > > >> > 5. If an error occurs, run these substeps and then terminate the > > algorithm: > >> > 1. Let result be null. > >> > 2. Execute resolver's reject(value) algorithm, with result > >> > as > > the value > >> argument. > >> > > >> > 6. If baseKey.keyUsage does not contain the "derive" KeyUsage, > >> > terminate > >> this algorithm with an error. > >> > > >> > 7. Let result be an ArrayBuffer object containing the result of > > executing the > >> key derivation algorithm defined by the algorithm indicated in > >> normalizedKdfAlgorithm, with baseKey as the base key, to generate > > bitLength > >> bits of output. If bitLength is not a multiple of 8, set the unused > >> bits > > in the last > >> byte of result to zero. > >> > > >> > 8. Execute resolver's resolve(value) algorithm, with result as the > >> > value > >> argument. > >> > > >> > > >> > Section 18 > >> > > >> > 18.8. ECDH > >> > > >> > > >> > 18.8.1. Description > >> > > >> > This describes using Elliptic Curve Diffie-Hellman (ECDH) for key > > generation > >> and key agreement, as specified by X9.63. > >> > > >> > > >> > 18.8.2. Registration > >> > > >> > The recognized algorithm name for this algorithm is "ECDH". > >> > > >> > > >> > Operation Parameters Result > >> > generateKey EcKeyGenParams KeyPair? > >> > secretAgreement EcdhSecretAgreementParams Key? > >> > > >> > > >> > 18.8.3. EcdhSecretAgreementParams dictionary > >> > > >> > IDL > >> > > >> > dictionary EcdhSecretAgreementParams : Algorithm { > >> > // The caller's secondary (ephemeral) private key, if used > >> > Key? localPrivateKey2; > >> > // The peer's secondary (ephemeral) public key, if used > >> > Key? peerPublicKey2; > >> > }; > >> > > >> > 18.8.4. Operations > >> > *Generate Key > >> > *Secret Agreement > >> > Perform the appropriate ECDH secret agreement scheme from SP > >> > 800-56A > >> Section 6, depending on whether localPrivateKey2 and peerPublicKey2 > >> are specified. The result is a Key object created by importing the > >> shared > > secret Z. > >> > > >> > Note: X9.63 Section 5.4.2 and NIST SP 800-56A Section 5.7.1.2 > >> > specify a > >> modified ECDH primitive that multiplies the shared secret value by > >> the cofactor of the curve. The cofactor of the NIST recommended > >> curves P-256, P-384, and P-521 is 1, so the standard and modified > >> ECDH primitives are equivalent for those curves. > >> > > >> > > >> > 18.15. Diffie-Hellman > >> > > >> > 18.15.1. Description > >> > > >> > This describes using Diffie-Hellman for key generation and key > > agreement, > >> as specified by PKCS #3. > >> > > >> > 18.15.2. Registration > >> > > >> > The recognized algorithm name for this algorithm is "DH". > >> > > >> > Operation Parameters Result > >> > generateKey DhKeyGenParams KeyPair? > >> > secretArgeement DhSecretAgreementParams Key? > >> > > >> > 18.15.3. DhKeyGenParams dictionary > >> > > >> > IDL > >> > > >> > dictionary DhKeyGenParams : Algorithm { > >> > // The prime p. > >> > BigInteger prime; > >> > // The base g. > >> > BigInteger generator; > >> > }; > >> > > >> > 18.15.4. DhSecretAgreementParams dictionary > >> > > >> > IDL > >> > > >> > dictionary DhSecretAgreementParams : Algorithm { > >> > // The caller's secondary (ephemeral) private key, if used > >> > Key? localPrivateKey2; > >> > // The peer's secondary (ephemeral) public key, if used > >> > Key? peerPublicKey2; > >> > }; > >> > > >> > 18.15.5. Operations > >> > *Generate Key > >> > *Secret Agreement > >> > Perform the appropriate DH secret agreement scheme from SP 800-56A > >> Section 6, depending on whether localPrivateKey2 and peerPublicKey2 > >> are specified. The result is a Key object created by importing the > >> shared > > secret Z. > >> > >> Sorry for the delays in getting back on this - as I worked through > >> all the > > other > >> ongoing discussions. > >> > >> Let me make sure I understand all the appropriate synthesis. > >> 1) Concat, HDKF, and PBKDF2 are all updated to support 'deriveKey' > >> and 'deriveBits'. If you wish to derive a set of four keys (ex: > >> client write > > key, server > >> write key, client hmac key, server hmac key), the only acceptable > >> thing is > > to > >> use deriveBits. > >> 2) DH & ECDH are updated to only support secretAgreement (eg: no > >> deriveKey, no deriveBits) > >> > >> If that's a correct understanding, then I'm not sure if this will > >> work for supporting polyfills. > >> > >> For example, consider the ZRTP (RFC 6189) case. ZRTP describes its > >> own KDF > > - > >> one that is (arguably) compatible with SP800-56A 6.1.2.1 (DH > >> Ephemeral/Ephemeral agreement). If an application wished to polyfill > >> this, they would also have to implement the DH algorithm in JS, since > >> there is > > no > >> way for an application to obtain Z (what is currently returned by > > deriveKey). > >> That seems much less flexible. > > > > Just for my edification. Is the problem that the built in version of > > DH would be unable to make the call to the polyfill KDF function? > > Correct - but it was based on a misunderstanding of Vijay's proposal. > > I understood the original proposal was that Z would be fed directly into the > KDF, and the key returned was the derived key. However, after reading this > again, I see that the Key returned wraps Z as a 'raw' > key. > > So the only issue here is that the algorithm (derivationAlgorithm) may be > something being polyfilled - in which case, a native implementation cannot > execute the algorithm normalization parameters or handle it for a polyfilled > case. > > Normally, a JS application would use any of the ES5/ES6 methods available to > intercept and/or wrap window.crypto.subtle's prototype with its own > extensions. However, in this case, it can't intercept the derivedKey algorithm. > > However, this issue exists in the current ED as well - the derivedAlgorithm > parameter (which isn't even specified fully - oops!) has the same issues. > > Off the top of my head (eg: not having fully considered the implementation > complexities/realities), I can see a couple solutions, but they all feel a bit > gross: > - Expose a meta 'raw' algorithm to allow a Key object to be created that can > then be exported > - Expose a meta 'raw' KDF, for which deriveBits() just exposes the key bits > - Expose some 'secret agree bits' function > > Of this, I'm inclined to go for a 'raw' KDF, but if anyone else has better > suggestions, I'm all for it. Can't you just export the returned key object? > > > > > The value of Z appears to be to be passed to the importKey algorithm, > > but it is not clear what is returned in the resolve since that is > > saying value not result. > > > > I don't understand what you mean here. Vijay's text seemed clear on this > point: > > 11. Let result be the result of executing the importKey algorithm [...] 12. [...] > 13. Execute resolver's resolve(value) algorithm, with result as the value > argument. One of these day's I will get use to how these things are written - I kind of expected it to just say 'resolve(result)'
Received on Monday, 22 July 2013 23:18:22 UTC