<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[213624] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/213624">213624</a></dd>
<dt>Author</dt> <dd>jiewen_tan@apple.com</dd>
<dt>Date</dt> <dd>2017-03-08 20:04:29 -0800 (Wed, 08 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WebCrypto] Implement ECDH DeriveBits operation
https://bugs.webkit.org/show_bug.cgi?id=169319
&lt;rdar://problem/23789585&gt;

Reviewed by Brent Fulgham.

Source/WebCore:

This patch implements DeriveBits operation of ECDH according to the spec:
https://www.w3.org/TR/WebCryptoAPI/#ecdh-operations.

Tests: crypto/subtle/derive-bits-malformed-parameters.html
       crypto/subtle/ecdh-derive-bits-malformed-parametrs.html
       crypto/subtle/ecdh-generate-key-derive-bits.html
       crypto/subtle/ecdh-import-key-derive-bits-custom-length.html
       crypto/subtle/ecdh-import-key-derive-bits-null-length.html
       crypto/workers/subtle/ecdh-import-key-derive-bits.html

* CMakeLists.txt:
* DerivedSources.make:
* PlatformGTK.cmake:
* PlatformMac.cmake:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSSubtleCryptoCustom.cpp:
(WebCore::normalizeCryptoAlgorithmParameters):
(WebCore::jsSubtleCryptoFunctionDeriveKeyPromise):
(WebCore::jsSubtleCryptoFunctionDeriveBitsPromise):
(WebCore::JSSubtleCrypto::generateKey):
Reorder a bit of the functions.
* crypto/CommonCryptoUtilities.h:
* crypto/CryptoAlgorithm.cpp:
(WebCore::CryptoAlgorithm::deriveBits):
* crypto/CryptoAlgorithm.h:
* crypto/CryptoAlgorithmParameters.h:
* crypto/algorithms/CryptoAlgorithmECDH.cpp:
(WebCore::CryptoAlgorithmECDH::deriveBits):
* crypto/algorithms/CryptoAlgorithmECDH.h:
* crypto/gnutls/CryptoAlgorithmECDHGnuTLS.cpp: Added.
(WebCore::CryptoAlgorithmECDH::platformDeriveBits):
* crypto/keys/CryptoKeyEC.h:
* crypto/mac/CryptoAlgorithmECDHMac.cpp: Added.
(WebCore::CryptoAlgorithmECDH::platformDeriveBits):
* crypto/parameters/CryptoAlgorithmEcdhKeyDeriveParams.h: Added.
* crypto/parameters/EcdhKeyDeriveParams.idl: Added.

LayoutTests:

* TestExpectations:
Refine some comments.
* crypto/subtle/derive-bits-malformed-parameters-expected.txt: Renamed from LayoutTests/crypto/subtle/deriveBits-malformed-parameters-expected.txt.
* crypto/subtle/derive-bits-malformed-parameters.html: Added.
* crypto/subtle/deriveBits-malformed-parameters.html: Removed.
* crypto/subtle/ecdh-derive-bits-malformed-parametrs-expected.txt: Added.
* crypto/subtle/ecdh-derive-bits-malformed-parametrs.html: Added.
* crypto/subtle/ecdh-generate-key-derive-bits-expected.txt: Added.
* crypto/subtle/ecdh-generate-key-derive-bits.html: Added.
* crypto/subtle/ecdh-import-key-derive-bits-custom-length-expected.txt: Added.
* crypto/subtle/ecdh-import-key-derive-bits-custom-length.html: Added.
* crypto/subtle/ecdh-import-key-derive-bits-null-length-expected.txt: Added.
* crypto/subtle/ecdh-import-key-derive-bits-null-length.html: Added.
* crypto/workers/subtle/ecdh-import-key-derive-bits-expected.txt: Added.
* crypto/workers/subtle/ecdh-import-key-derive-bits.html: Added.
* crypto/workers/subtle/resources/ecdh-import-key-derive-bits.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsTestExpectations">trunk/LayoutTests/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesmake">trunk/Source/WebCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceWebCorePlatformGTKcmake">trunk/Source/WebCore/PlatformGTK.cmake</a></li>
<li><a href="#trunkSourceWebCorePlatformMaccmake">trunk/Source/WebCore/PlatformMac.cmake</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSSubtleCryptoCustomcpp">trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptoCommonCryptoUtilitiesh">trunk/Source/WebCore/crypto/CommonCryptoUtilities.h</a></li>
<li><a href="#trunkSourceWebCorecryptoCryptoAlgorithmcpp">trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptoCryptoAlgorithmh">trunk/Source/WebCore/crypto/CryptoAlgorithm.h</a></li>
<li><a href="#trunkSourceWebCorecryptoCryptoAlgorithmParametersh">trunk/Source/WebCore/crypto/CryptoAlgorithmParameters.h</a></li>
<li><a href="#trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHcpp">trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHh">trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h</a></li>
<li><a href="#trunkSourceWebCorecryptokeysCryptoKeyECh">trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscryptosubtlederivebitsmalformedparametersexpectedtxt">trunk/LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtlederivebitsmalformedparametershtml">trunk/LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhderivebitsmalformedparametrsexpectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-derive-bits-malformed-parametrs-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhderivebitsmalformedparametrshtml">trunk/LayoutTests/crypto/subtle/ecdh-derive-bits-malformed-parametrs.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgeneratekeyderivebitsexpectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-generate-key-derive-bits-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhgeneratekeyderivebitshtml">trunk/LayoutTests/crypto/subtle/ecdh-generate-key-derive-bits.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportkeyderivebitscustomlengthexpectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-custom-length-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportkeyderivebitscustomlengthhtml">trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-custom-length.html</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportkeyderivebitsnulllengthexpectedtxt">trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-null-length-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtleecdhimportkeyderivebitsnulllengthhtml">trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-null-length.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecdhimportkeyderivebitsexpectedtxt">trunk/LayoutTests/crypto/workers/subtle/ecdh-import-key-derive-bits-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleecdhimportkeyderivebitshtml">trunk/LayoutTests/crypto/workers/subtle/ecdh-import-key-derive-bits.html</a></li>
<li><a href="#trunkLayoutTestscryptoworkerssubtleresourcesecdhimportkeyderivebitsjs">trunk/LayoutTests/crypto/workers/subtle/resources/ecdh-import-key-derive-bits.js</a></li>
<li><a href="#trunkSourceWebCorecryptognutlsCryptoAlgorithmECDHGnuTLScpp">trunk/Source/WebCore/crypto/gnutls/CryptoAlgorithmECDHGnuTLS.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptomacCryptoAlgorithmECDHMaccpp">trunk/Source/WebCore/crypto/mac/CryptoAlgorithmECDHMac.cpp</a></li>
<li><a href="#trunkSourceWebCorecryptoparametersCryptoAlgorithmEcdhKeyDeriveParamsh">trunk/Source/WebCore/crypto/parameters/CryptoAlgorithmEcdhKeyDeriveParams.h</a></li>
<li><a href="#trunkSourceWebCorecryptoparametersEcdhKeyDeriveParamsidl">trunk/Source/WebCore/crypto/parameters/EcdhKeyDeriveParams.idl</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscryptosubtlederiveBitsmalformedparametersexpectedtxt">trunk/LayoutTests/crypto/subtle/deriveBits-malformed-parameters-expected.txt</a></li>
<li><a href="#trunkLayoutTestscryptosubtlederiveBitsmalformedparametershtml">trunk/LayoutTests/crypto/subtle/deriveBits-malformed-parameters.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/LayoutTests/ChangeLog        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2017-03-08  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
+        [WebCrypto] Implement ECDH DeriveBits operation
+        https://bugs.webkit.org/show_bug.cgi?id=169319
+        &lt;rdar://problem/23789585&gt;
+
+        Reviewed by Brent Fulgham.
+
+        * TestExpectations:
+        Refine some comments.
+        * crypto/subtle/derive-bits-malformed-parameters-expected.txt: Renamed from LayoutTests/crypto/subtle/deriveBits-malformed-parameters-expected.txt.
+        * crypto/subtle/derive-bits-malformed-parameters.html: Added.
+        * crypto/subtle/deriveBits-malformed-parameters.html: Removed.
+        * crypto/subtle/ecdh-derive-bits-malformed-parametrs-expected.txt: Added.
+        * crypto/subtle/ecdh-derive-bits-malformed-parametrs.html: Added.
+        * crypto/subtle/ecdh-generate-key-derive-bits-expected.txt: Added.
+        * crypto/subtle/ecdh-generate-key-derive-bits.html: Added.
+        * crypto/subtle/ecdh-import-key-derive-bits-custom-length-expected.txt: Added.
+        * crypto/subtle/ecdh-import-key-derive-bits-custom-length.html: Added.
+        * crypto/subtle/ecdh-import-key-derive-bits-null-length-expected.txt: Added.
+        * crypto/subtle/ecdh-import-key-derive-bits-null-length.html: Added.
+        * crypto/workers/subtle/ecdh-import-key-derive-bits-expected.txt: Added.
+        * crypto/workers/subtle/ecdh-import-key-derive-bits.html: Added.
+        * crypto/workers/subtle/resources/ecdh-import-key-derive-bits.js: Added.
+
</ins><span class="cx"> 2017-03-08  John Wilander  &lt;wilander@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Resource Load Statistics: Communicate to the network process which domains to partition
</span></span></pre></div>
<a id="trunkLayoutTestsTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/TestExpectations (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/TestExpectations        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/LayoutTests/TestExpectations        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -959,7 +959,7 @@
</span><span class="cx"> # This test is just way too slow.
</span><span class="cx"> workers/bomb-with-v8.html [ Skip ]
</span><span class="cx"> 
</span><del>-# WebCryptoAPI tests that take too long to complete, need to scale down. webkit.org/b/159638
</del><ins>+# WebCryptoAPI tests that take too long to complete
</ins><span class="cx"> imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/hkdf.worker.html [ Skip ]
</span><span class="cx"> imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/pbkdf2.worker.html [ Skip ]
</span><span class="cx"> imported/w3c/web-platform-tests/WebCryptoAPI/generateKey/successes_RSA-OAEP.worker.html [ Skip ]
</span></span></pre></div>
<a id="trunkLayoutTestscryptosubtlederivebitsmalformedparametersexpectedtxtfromrev213623trunkLayoutTestscryptosubtlederiveBitsmalformedparametersexpectedtxt"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt (from rev 213623, trunk/LayoutTests/crypto/subtle/deriveBits-malformed-parameters-expected.txt) (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+Test deriveBits operation with malformed parameters
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS crypto.subtle.deriveBits() rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.deriveBits(1) rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.deriveBits(1, 2) rejected promise  with TypeError: Not enough arguments.
+PASS crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:wrongKey }, wrongKey, 128) rejected promise  with InvalidAccessError (DOM Exception 15): CryptoKey doesn't match AlgorithmIdentifier.
+PASS crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:wrongKey }, wrongKey, 128) rejected promise  with InvalidAccessError (DOM Exception 15): CryptoKey doesn't support bits derivation.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtlederivebitsmalformedparametershtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test deriveBits operation with malformed parameters&quot;);
+
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var hmacImportParams = {
+    name: &quot;hmac&quot;,
+    hash: &quot;sha-1&quot;,
+}
+var rawKey = asciiToUint8Array(&quot;jnOw99oOZFLIEPMr&quot;);
+var jwkKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+    d: &quot;ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg&quot;,
+};
+
+
+// Not enough arguments.
+shouldReject('crypto.subtle.deriveBits()');
+shouldReject('crypto.subtle.deriveBits(1)');
+shouldReject('crypto.subtle.deriveBits(1, 2)');
+
+crypto.subtle.importKey(&quot;raw&quot;, rawKey, hmacImportParams, extractable, [&quot;sign&quot;, &quot;verify&quot;]).then(function(result) {
+    wrongKey = result;
+    // Wrong algorithm identifier.
+    shouldReject('crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:wrongKey }, wrongKey, 128)');
+
+    return crypto.subtle.importKey(&quot;jwk&quot;, jwkKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveKey&quot;]);
+}).then(function(result) {
+    wrongKey = result;
+    // Wrong usage.
+    shouldReject('crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:wrongKey }, wrongKey, 128)');
+
+    finishJSTest();
+});
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtlederiveBitsmalformedparametersexpectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/crypto/subtle/deriveBits-malformed-parameters-expected.txt (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/deriveBits-malformed-parameters-expected.txt        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/LayoutTests/crypto/subtle/deriveBits-malformed-parameters-expected.txt        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -1,13 +0,0 @@
</span><del>-Test deriveBits operation with malformed parameters
-
-On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
-
-
-PASS crypto.subtle.deriveBits() rejected promise  with TypeError: Not enough arguments.
-PASS crypto.subtle.deriveBits(1) rejected promise  with TypeError: Not enough arguments.
-PASS crypto.subtle.deriveBits(1, 2) rejected promise  with TypeError: Not enough arguments.
-PASS crypto.subtle.deriveBits(&quot;ECDH&quot;, 2, 3) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
</del></span></pre></div>
<a id="trunkLayoutTestscryptosubtlederiveBitsmalformedparametershtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/crypto/subtle/deriveBits-malformed-parameters.html (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/deriveBits-malformed-parameters.html        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/LayoutTests/crypto/subtle/deriveBits-malformed-parameters.html        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -1,24 +0,0 @@
</span><del>-&lt;!DOCTYPE html&gt;
-&lt;html&gt;
-&lt;head&gt;
-&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
-&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
-&lt;/head&gt;
-&lt;body&gt;
-&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
-&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
-
-&lt;script&gt;
-description(&quot;Test deriveBits operation with malformed parameters&quot;);
-
-// Not enough arguments.
-shouldReject('crypto.subtle.deriveBits()');
-shouldReject('crypto.subtle.deriveBits(1)');
-shouldReject('crypto.subtle.deriveBits(1, 2)');
-// Not support.
-shouldReject('crypto.subtle.deriveBits(&quot;ECDH&quot;, 2, 3)');
-&lt;/script&gt;
-
-&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
-&lt;/body&gt;
-&lt;/html&gt;
</del></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhderivebitsmalformedparametrsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-derive-bits-malformed-parametrs-expected.txt (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-derive-bits-malformed-parametrs-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-derive-bits-malformed-parametrs-expected.txt        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+Test ECDH deriveBits operation with malformed parameters
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS crypto.subtle.deriveBits(&quot;ecdh&quot;, privateKey, null) rejected promise  with TypeError: Member EcdhKeyDeriveParams.publicKey is required and must be an instance of CryptoKey.
+PASS crypto.subtle.deriveBits({name: &quot;ecdh&quot;}, privateKey, null) rejected promise  with TypeError: Member EcdhKeyDeriveParams.publicKey is required and must be an instance of CryptoKey.
+PASS crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: true}, privateKey, null) rejected promise  with TypeError: Type error.
+PASS crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: null}, privateKey, null) rejected promise  with TypeError: Type error.
+PASS crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: undefined}, privateKey, null) rejected promise  with TypeError: Member EcdhKeyDeriveParams.publicKey is required and must be an instance of CryptoKey.
+PASS crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: Symbol()}, privateKey, null) rejected promise  with TypeError: Type error.
+PASS crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: { }}, privateKey, null) rejected promise  with TypeError: Type error.
+PASS crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: 1}, privateKey, null) rejected promise  with TypeError: Type error.
+PASS crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, privateKey, 1) rejected promise  with OperationError (DOM Exception 34): The operation failed for an operation-specific reason.
+PASS crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, publicKey, null) rejected promise  with InvalidAccessError (DOM Exception 15): CryptoKey doesn't support bits derivation.
+PASS crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:privateKey }, privateKey, null) rejected promise  with InvalidAccessError (DOM Exception 15): The requested operation is not valid for the provided key.
+PASS crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:fakeKey }, privateKey, null) rejected promise  with InvalidAccessError (DOM Exception 15): The requested operation is not valid for the provided key.
+PASS crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKeyP384 }, privateKey, null) rejected promise  with InvalidAccessError (DOM Exception 15): The requested operation is not valid for the provided key.
+PASS crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, privateKey, 384) rejected promise  with OperationError (DOM Exception 34): The operation failed for an operation-specific reason.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhderivebitsmalformedparametrshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-derive-bits-malformed-parametrs.html (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-derive-bits-malformed-parametrs.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-derive-bits-malformed-parametrs.html        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test ECDH deriveBits operation with malformed parameters&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var jwkPrivateKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+    d: &quot;ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg&quot;,
+};
+var jwkPublicKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+};
+var jwkPublicKeyP384 = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-384&quot;,
+    x: &quot;TEsQRAL-nau4K75XNynuR6fdoTGGm5X1XgOrR5iSziBVqhRYOAteuF8-U0wxN89s&quot;,
+    y: &quot;r-Wn9YIXJ_r7uNN5s9eVeXElm6ZcTGvYKg6GtKJXUXuJUZRMF7EIB_H6xpOmthV6&quot;,
+};
+var rsaSpkiKey = Base64URL.parse(&quot;MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCjRCtFwvSNYMZ07u5SxARxglJl75T7bUZXFsDVxHkMhpNC2RaN4jWE5bwYUDMeD2fVmxhpaUQn/6AbFLh6gHxtwrCfc7rIo/SfDdGd3GkRlXK5xXwGuM6MvP9nuZHaarIyArRFh2U2UZxFlVsKI0pSHo6n58W1fPZ1syOoVEZ/WYE6gLhMMwfpeAm97mro7mekRdMULOV/mR5Ul3CHm9Zt93Dc8GpnPA8bhLiB0VNyGTEMa06nJul4gj1sjxLDoUvZY2EWq7oUUnfLBUYMfiqK0kQcW94wvBrIq2DQUApLyTTbaAOY46TLwX6c8LtubJriYKTC5a9Bb0/7ovTWB0wIDAQAB&quot;);
+
+crypto.subtle.importKey(&quot;jwk&quot;, jwkPrivateKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveBits&quot;]).then(function(result) {
+    privateKey = result;
+    return crypto.subtle.importKey(&quot;jwk&quot;, jwkPublicKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]);
+}).then(function(result) {
+    publicKey = result;
+    return crypto.subtle.importKey(&quot;spki&quot;, rsaSpkiKey, {name: &quot;RSA-OAEP&quot;, hash: &quot;sha-1&quot;}, extractable, [&quot;encrypt&quot;, &quot;wrapKey&quot;]);
+}).then(function(result) {
+    fakeKey = result;
+    return crypto.subtle.importKey(&quot;jwk&quot;, jwkPublicKeyP384, { name: &quot;ECDH&quot;, namedCurve: &quot;P-384&quot; }, extractable, [ ]);
+}).then(function(result) {
+    publicKeyP384 = result;
+    // Malformed AlgorithmIdentifiers
+    shouldReject('crypto.subtle.deriveBits(&quot;ecdh&quot;, privateKey, null)');
+    shouldReject('crypto.subtle.deriveBits({name: &quot;ecdh&quot;}, privateKey, null)');
+    shouldReject('crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: true}, privateKey, null)');
+    shouldReject('crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: null}, privateKey, null)');
+    shouldReject('crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: undefined}, privateKey, null)');
+    shouldReject('crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: Symbol()}, privateKey, null)');
+    shouldReject('crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: { }}, privateKey, null)');
+    shouldReject('crypto.subtle.deriveBits({name: &quot;ecdh&quot;, public: 1}, privateKey, null)');
+    // Wrong length
+    shouldReject('crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, privateKey, 1)');
+    // base key is public
+    shouldReject('crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, publicKey, null)');
+    // public key is private
+    shouldReject('crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:privateKey }, privateKey, null)');
+    // faked public key
+    shouldReject('crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:fakeKey }, privateKey, null)');
+    // mismatched named curve
+    shouldReject('crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKeyP384 }, privateKey, null)');
+    // Wrong length
+    return shouldReject('crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, privateKey, 384)');
+}).then(finishJSTest, finishJSTest);
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhgeneratekeyderivebitsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-generate-key-derive-bits-expected.txt (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-key-derive-bits-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-key-derive-bits-expected.txt        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+Test ECDH deriveBits operation with generated base key and null length
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS derivedKey.byteLength is 32
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhgeneratekeyderivebitshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-generate-key-derive-bits.html (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-generate-key-derive-bits.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-generate-key-derive-bits.html        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test ECDH deriveBits operation with generated base key and null length&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var jwkPublicKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+};
+
+crypto.subtle.generateKey({ name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveBits&quot;]).then(function(result) {
+    privateKey = result.privateKey;
+    return crypto.subtle.importKey(&quot;jwk&quot;, jwkPublicKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]);
+}).then(function(result) {
+    publicKey = result;
+    return crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, privateKey, null);
+}).then(function(result) {
+    derivedKey = result;
+
+    shouldBe(&quot;derivedKey.byteLength&quot;, &quot;32&quot;);
+
+    finishJSTest();
+}, failAndFinishJSTest);
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhimportkeyderivebitscustomlengthexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-custom-length-expected.txt (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-custom-length-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-custom-length-expected.txt        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+Test ECDH deriveBits operation with imported base key and custom length
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS bytesToHexString(derivedKey) is expectedDerivedKey
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhimportkeyderivebitscustomlengthhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-custom-length.html (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-custom-length.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-custom-length.html        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test ECDH deriveBits operation with imported base key and custom length&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var jwkPrivateKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+    d: &quot;ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg&quot;,
+};
+var jwkPublicKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+};
+var expectedDerivedKey = &quot;40bf0c0a56f75ca587ea4f6729d7bf9a&quot;;
+
+crypto.subtle.importKey(&quot;jwk&quot;, jwkPrivateKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveBits&quot;]).then(function(result) {
+    privateKey = result;
+    return crypto.subtle.importKey(&quot;jwk&quot;, jwkPublicKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]);
+}).then(function(result) {
+    publicKey = result;
+    return crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, privateKey, 128);
+}).then(function(result) {
+    derivedKey = result;
+
+    shouldBe(&quot;bytesToHexString(derivedKey)&quot;, &quot;expectedDerivedKey&quot;);
+
+    finishJSTest();
+}, failAndFinishJSTest);
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhimportkeyderivebitsnulllengthexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-null-length-expected.txt (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-null-length-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-null-length-expected.txt        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+Test ECDH deriveBits operation with imported base key and null length
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS bytesToHexString(derivedKey) is expectedDerivedKey
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptosubtleecdhimportkeyderivebitsnulllengthhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-null-length.html (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-null-length.html                                (rev 0)
+++ trunk/LayoutTests/crypto/subtle/ecdh-import-key-derive-bits-null-length.html        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/common.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+description(&quot;Test ECDH deriveBits operation with imported base key and null length&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var jwkPrivateKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+    d: &quot;ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg&quot;,
+};
+var jwkPublicKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+};
+var expectedDerivedKey = &quot;40bf0c0a56f75ca587ea4f6729d7bf9a30c5f4a0d47eea13fdf9da8f0b53b85e&quot;;
+
+crypto.subtle.importKey(&quot;jwk&quot;, jwkPrivateKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveBits&quot;]).then(function(result) {
+    privateKey = result;
+    return crypto.subtle.importKey(&quot;jwk&quot;, jwkPublicKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]);
+}).then(function(result) {
+    publicKey = result;
+    return crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, privateKey, null);
+}).then(function(result) {
+    derivedKey = result;
+
+    shouldBe(&quot;bytesToHexString(derivedKey)&quot;, &quot;expectedDerivedKey&quot;);
+
+    finishJSTest();
+}, failAndFinishJSTest);
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleecdhimportkeyderivebitsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ecdh-import-key-derive-bits-expected.txt (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ecdh-import-key-derive-bits-expected.txt                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ecdh-import-key-derive-bits-expected.txt        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+[Worker] Test ECDH deriveBits operation with imported base key in workers
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+Starting worker: resources/ecdh-import-key-derive-bits.js
+PASS [Worker] bytesToHexString(derivedKey) is expectedDerivedKey
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleecdhimportkeyderivebitshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/ecdh-import-key-derive-bits.html (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/ecdh-import-key-derive-bits.html                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/ecdh-import-key-derive-bits.html        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;script src=&quot;../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;script&gt;
+        worker = startWorker('resources/ecdh-import-key-derive-bits.js');
+    &lt;/script&gt;
+    &lt;script src=&quot;../../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscryptoworkerssubtleresourcesecdhimportkeyderivebitsjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/crypto/workers/subtle/resources/ecdh-import-key-derive-bits.js (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/crypto/workers/subtle/resources/ecdh-import-key-derive-bits.js                                (rev 0)
+++ trunk/LayoutTests/crypto/workers/subtle/resources/ecdh-import-key-derive-bits.js        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+importScripts('../../../../resources/js-test-pre.js');
+importScripts(&quot;../../../resources/common.js&quot;);
+
+description(&quot;Test ECDH deriveBits operation with imported base key in workers&quot;);
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var jwkPrivateKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+    d: &quot;ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg&quot;,
+};
+var jwkPublicKey = {
+    kty: &quot;EC&quot;,
+    crv: &quot;P-256&quot;,
+    x: &quot;1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA&quot;,
+    y: &quot;9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI&quot;,
+};
+var expectedDerivedKey = &quot;40bf0c0a56f75ca587ea4f6729d7bf9a30c5f4a0d47eea13fdf9da8f0b53b85e&quot;;
+
+crypto.subtle.importKey(&quot;jwk&quot;, jwkPrivateKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [&quot;deriveBits&quot;]).then(function(result) {
+    privateKey = result;
+    return crypto.subtle.importKey(&quot;jwk&quot;, jwkPublicKey, { name: &quot;ECDH&quot;, namedCurve: &quot;P-256&quot; }, extractable, [ ]);
+}).then(function(result) {
+    publicKey = result;
+    return crypto.subtle.deriveBits({ name:&quot;ECDH&quot;, public:publicKey }, privateKey, null);
+}).then(function(result) {
+    derivedKey = result;
+
+    shouldBe(&quot;bytesToHexString(derivedKey)&quot;, &quot;expectedDerivedKey&quot;);
+
+    finishJSTest();
+}, failAndFinishJSTest);
</ins></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/CMakeLists.txt        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -344,6 +344,7 @@
</span><span class="cx">     crypto/parameters/AesGcmParams.idl
</span><span class="cx">     crypto/parameters/AesKeyGenParams.idl
</span><span class="cx">     crypto/parameters/EcKeyParams.idl
</span><ins>+    crypto/parameters/EcdhKeyDeriveParams.idl
</ins><span class="cx">     crypto/parameters/HmacKeyParams.idl
</span><span class="cx">     crypto/parameters/RsaHashedImportParams.idl
</span><span class="cx">     crypto/parameters/RsaHashedKeyGenParams.idl
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/ChangeLog        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2017-03-08  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
+
+        [WebCrypto] Implement ECDH DeriveBits operation
+        https://bugs.webkit.org/show_bug.cgi?id=169319
+        &lt;rdar://problem/23789585&gt;
+
+        Reviewed by Brent Fulgham.
+
+        This patch implements DeriveBits operation of ECDH according to the spec:
+        https://www.w3.org/TR/WebCryptoAPI/#ecdh-operations.
+
+        Tests: crypto/subtle/derive-bits-malformed-parameters.html
+               crypto/subtle/ecdh-derive-bits-malformed-parametrs.html
+               crypto/subtle/ecdh-generate-key-derive-bits.html
+               crypto/subtle/ecdh-import-key-derive-bits-custom-length.html
+               crypto/subtle/ecdh-import-key-derive-bits-null-length.html
+               crypto/workers/subtle/ecdh-import-key-derive-bits.html
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * PlatformGTK.cmake:
+        * PlatformMac.cmake:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSSubtleCryptoCustom.cpp:
+        (WebCore::normalizeCryptoAlgorithmParameters):
+        (WebCore::jsSubtleCryptoFunctionDeriveKeyPromise):
+        (WebCore::jsSubtleCryptoFunctionDeriveBitsPromise):
+        (WebCore::JSSubtleCrypto::generateKey):
+        Reorder a bit of the functions.
+        * crypto/CommonCryptoUtilities.h:
+        * crypto/CryptoAlgorithm.cpp:
+        (WebCore::CryptoAlgorithm::deriveBits):
+        * crypto/CryptoAlgorithm.h:
+        * crypto/CryptoAlgorithmParameters.h:
+        * crypto/algorithms/CryptoAlgorithmECDH.cpp:
+        (WebCore::CryptoAlgorithmECDH::deriveBits):
+        * crypto/algorithms/CryptoAlgorithmECDH.h:
+        * crypto/gnutls/CryptoAlgorithmECDHGnuTLS.cpp: Added.
+        (WebCore::CryptoAlgorithmECDH::platformDeriveBits):
+        * crypto/keys/CryptoKeyEC.h:
+        * crypto/mac/CryptoAlgorithmECDHMac.cpp: Added.
+        (WebCore::CryptoAlgorithmECDH::platformDeriveBits):
+        * crypto/parameters/CryptoAlgorithmEcdhKeyDeriveParams.h: Added.
+        * crypto/parameters/EcdhKeyDeriveParams.idl: Added.
+
</ins><span class="cx"> 2017-03-08  John Wilander  &lt;wilander@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Resource Load Statistics: Communicate to the network process which domains to partition
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources.make (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources.make        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/DerivedSources.make        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -276,6 +276,7 @@
</span><span class="cx">     $(WebCore)/crypto/parameters/AesGcmParams.idl \
</span><span class="cx">     $(WebCore)/crypto/parameters/AesKeyGenParams.idl \
</span><span class="cx">     $(WebCore)/crypto/parameters/EcKeyParams.idl \
</span><ins>+    $(WebCore)/crypto/parameters/EcdhKeyDeriveParams.idl \
</ins><span class="cx">     $(WebCore)/crypto/parameters/HmacKeyParams.idl \
</span><span class="cx">     $(WebCore)/crypto/parameters/RsaHashedImportParams.idl \
</span><span class="cx">     $(WebCore)/crypto/parameters/RsaHashedKeyGenParams.idl \
</span></span></pre></div>
<a id="trunkSourceWebCorePlatformGTKcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/PlatformGTK.cmake (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/PlatformGTK.cmake        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/PlatformGTK.cmake        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -403,6 +403,7 @@
</span><span class="cx">         crypto/gnutls/CryptoAlgorithmAES_CFBGnuTLS.cpp
</span><span class="cx">         crypto/gnutls/CryptoAlgorithmAES_GCMGnuTLS.cpp
</span><span class="cx">         crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp
</span><ins>+        crypto/gnutls/CryptoAlgorithmECDHGnuTLS.cpp
</ins><span class="cx">         crypto/gnutls/CryptoAlgorithmRSAES_PKCS1_v1_5GnuTLS.cpp
</span><span class="cx">         crypto/gnutls/CryptoAlgorithmRSASSA_PKCS1_v1_5GnuTLS.cpp
</span><span class="cx">         crypto/gnutls/CryptoAlgorithmRSA_OAEPGnuTLS.cpp
</span></span></pre></div>
<a id="trunkSourceWebCorePlatformMaccmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/PlatformMac.cmake (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/PlatformMac.cmake        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/PlatformMac.cmake        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -206,6 +206,7 @@
</span><span class="cx">     crypto/mac/CryptoAlgorithmAES_CFBMac.cpp
</span><span class="cx">     crypto/mac/CryptoAlgorithmAES_GCMMac.cpp
</span><span class="cx">     crypto/mac/CryptoAlgorithmAES_KWMac.cpp
</span><ins>+    crypto/mac/CryptoAlgorithmECDHMac.cpp
</ins><span class="cx">     crypto/mac/CryptoAlgorithmHMACMac.cpp
</span><span class="cx">     crypto/mac/CryptoAlgorithmRSAES_PKCS1_v1_5Mac.cpp
</span><span class="cx">     crypto/mac/CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -2378,6 +2378,10 @@
</span><span class="cx">                 5750A9821E6A150800705C4A /* JSEcKeyParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5750A9801E6A150800705C4A /* JSEcKeyParams.h */; };
</span><span class="cx">                 5750A9861E6A216800705C4A /* CryptoAlgorithmECDH.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5750A9841E6A216800705C4A /* CryptoAlgorithmECDH.cpp */; };
</span><span class="cx">                 5750A9871E6A216800705C4A /* CryptoAlgorithmECDH.h in Headers */ = {isa = PBXBuildFile; fileRef = 5750A9851E6A216800705C4A /* CryptoAlgorithmECDH.h */; };
</span><ins>+                5768142A1E6F99C100E77754 /* CryptoAlgorithmEcdhKeyDeriveParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 576814291E6F99C100E77754 /* CryptoAlgorithmEcdhKeyDeriveParams.h */; };
+                576814351E6FE3E800E77754 /* CryptoAlgorithmECDHMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 576814341E6FE3E800E77754 /* CryptoAlgorithmECDHMac.cpp */; };
+                576814401E709FA100E77754 /* JSEcdhKeyDeriveParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5768143D1E709C3600E77754 /* JSEcdhKeyDeriveParams.cpp */; };
+                576814411E709FA400E77754 /* JSEcdhKeyDeriveParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5768143E1E709C3600E77754 /* JSEcdhKeyDeriveParams.h */; };
</ins><span class="cx">                 5768E4341DB7524500D0A4F7 /* JSRsaHashedKeyGenParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5768E4331DB7524500D0A4F7 /* JSRsaHashedKeyGenParams.h */; };
</span><span class="cx">                 5768E4361DB7527400D0A4F7 /* JSRsaHashedKeyGenParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5768E4351DB7527300D0A4F7 /* JSRsaHashedKeyGenParams.cpp */; };
</span><span class="cx">                 577483121DADC55D00716EF9 /* CryptoAlgorithmAesKeyGenParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 577483111DADC55D00716EF9 /* CryptoAlgorithmAesKeyGenParams.h */; };
</span><span class="lines">@@ -9807,6 +9811,11 @@
</span><span class="cx">                 5750A9801E6A150800705C4A /* JSEcKeyParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEcKeyParams.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5750A9841E6A216800705C4A /* CryptoAlgorithmECDH.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmECDH.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5750A9851E6A216800705C4A /* CryptoAlgorithmECDH.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmECDH.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                576814281E6F98AD00E77754 /* EcdhKeyDeriveParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = EcdhKeyDeriveParams.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
+                576814291E6F99C100E77754 /* CryptoAlgorithmEcdhKeyDeriveParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmEcdhKeyDeriveParams.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                576814341E6FE3E800E77754 /* CryptoAlgorithmECDHMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmECDHMac.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                5768143D1E709C3600E77754 /* JSEcdhKeyDeriveParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEcdhKeyDeriveParams.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                5768143E1E709C3600E77754 /* JSEcdhKeyDeriveParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEcdhKeyDeriveParams.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 5768E4331DB7524500D0A4F7 /* JSRsaHashedKeyGenParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRsaHashedKeyGenParams.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5768E4351DB7527300D0A4F7 /* JSRsaHashedKeyGenParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRsaHashedKeyGenParams.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 577483101DADC49900716EF9 /* AesKeyGenParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = AesKeyGenParams.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -23598,6 +23607,7 @@
</span><span class="cx">                                 570440571E53851600356601 /* CryptoAlgorithmAES_CFBMac.cpp */,
</span><span class="cx">                                 57B5F80D1E5D2F2D00F34F90 /* CryptoAlgorithmAES_GCMMac.cpp */,
</span><span class="cx">                                 E1FE137C184D270200892F13 /* CryptoAlgorithmAES_KWMac.cpp */,
</span><ins>+                                576814341E6FE3E800E77754 /* CryptoAlgorithmECDHMac.cpp */,
</ins><span class="cx">                                 E125F8371822F1EB00D84CD9 /* CryptoAlgorithmHMACMac.cpp */,
</span><span class="cx">                                 E1BB84AC1822CA7400525043 /* CryptoAlgorithmRegistryMac.cpp */,
</span><span class="cx">                                 E1FE136E183FECF000892F13 /* CryptoAlgorithmRSA_OAEPMac.cpp */,
</span><span class="lines">@@ -23679,6 +23689,7 @@
</span><span class="cx">                                 577483111DADC55D00716EF9 /* CryptoAlgorithmAesKeyGenParams.h */,
</span><span class="cx">                                 E19AC3F61824E5D100349426 /* CryptoAlgorithmAesKeyGenParamsDeprecated.h */,
</span><span class="cx">                                 5750A97D1E6A13EF00705C4A /* CryptoAlgorithmEcKeyParams.h */,
</span><ins>+                                576814291E6F99C100E77754 /* CryptoAlgorithmEcdhKeyDeriveParams.h */,
</ins><span class="cx">                                 577483181DB4491F00716EF9 /* CryptoAlgorithmHmacKeyParams.h */,
</span><span class="cx">                                 E19DA29B18189ADD00088BC8 /* CryptoAlgorithmHmacKeyParamsDeprecated.h */,
</span><span class="cx">                                 E1C6571E1816E50300256CDD /* CryptoAlgorithmHmacParamsDeprecated.h */,
</span><span class="lines">@@ -23691,6 +23702,7 @@
</span><span class="cx">                                 E1FE1376184D1E3300892F13 /* CryptoAlgorithmRsaOaepParamsDeprecated.h */,
</span><span class="cx">                                 E1BD331B182D8EE900C05D9F /* CryptoAlgorithmRsaSsaParamsDeprecated.h */,
</span><span class="cx">                                 5750A97C1E6A12B400705C4A /* EcKeyParams.idl */,
</span><ins>+                                576814281E6F98AD00E77754 /* EcdhKeyDeriveParams.idl */,
</ins><span class="cx">                                 577483171DB1FE8900716EF9 /* HmacKeyParams.idl */,
</span><span class="cx">                                 57E2336C1DCD437000F28D01 /* RsaHashedImportParams.idl */,
</span><span class="cx">                                 57F827391DB72C22009D2BF4 /* RsaHashedKeyGenParams.idl */,
</span><span class="lines">@@ -23867,6 +23879,8 @@
</span><span class="cx">                                 57D0018C1DD5413200ED19D9 /* JSCryptoKeyUsage.h */,
</span><span class="cx">                                 5750A97F1E6A150800705C4A /* JSEcKeyParams.cpp */,
</span><span class="cx">                                 5750A9801E6A150800705C4A /* JSEcKeyParams.h */,
</span><ins>+                                5768143D1E709C3600E77754 /* JSEcdhKeyDeriveParams.cpp */,
+                                5768143E1E709C3600E77754 /* JSEcdhKeyDeriveParams.h */,
</ins><span class="cx">                                 57E233681DCAB24300F28D01 /* JSHmacKeyParams.cpp */,
</span><span class="cx">                                 57E233661DCAB21C00F28D01 /* JSHmacKeyParams.h */,
</span><span class="cx">                                 57E2335E1DC7D67B00F28D01 /* JSJsonWebKey.cpp */,
</span><span class="lines">@@ -26741,6 +26755,7 @@
</span><span class="cx">                                 1AE96A911D1A0DDD00B86768 /* JSApplePayShippingContactSelectedEvent.h in Headers */,
</span><span class="cx">                                 7C6579F41E00856600E3A27A /* JSApplePayShippingMethod.h in Headers */,
</span><span class="cx">                                 1AE96A931D1A0DDD00B86768 /* JSApplePayShippingMethodSelectedEvent.h in Headers */,
</span><ins>+                                576814411E709FA400E77754 /* JSEcdhKeyDeriveParams.h in Headers */,
</ins><span class="cx">                                 65DF31DB09D1C123000BE325 /* JSAttr.h in Headers */,
</span><span class="cx">                                 FDA15E9E12B03EE1003A583A /* JSAudioBuffer.h in Headers */,
</span><span class="cx">                                 FDF7E9C413AC21DB00A51EAC /* JSAudioBufferCallback.h in Headers */,
</span><span class="lines">@@ -28469,6 +28484,7 @@
</span><span class="cx">                                 A8EA800A0A19516E00A8EF5F /* StyleSheetList.h in Headers */,
</span><span class="cx">                                 BC5EB5E50E81BF6D00B25965 /* StyleSurroundData.h in Headers */,
</span><span class="cx">                                 BC5EB8100E81F2CE00B25965 /* StyleTransformData.h in Headers */,
</span><ins>+                                5768142A1E6F99C100E77754 /* CryptoAlgorithmEcdhKeyDeriveParams.h in Headers */,
</ins><span class="cx">                                 E4DEAA1817A93DC3000E0430 /* StyleTreeResolver.h in Headers */,
</span><span class="cx">                                 E42E76DC1C7AF77600E3614D /* StyleUpdate.h in Headers */,
</span><span class="cx">                                 E48137B91DB3B526005C59BF /* StyleValidity.h in Headers */,
</span><span class="lines">@@ -30406,6 +30422,7 @@
</span><span class="cx">                                 A871DB260A150BD600B12A68 /* HTMLTableSectionElement.cpp in Sources */,
</span><span class="cx">                                 D66817FA166FE6D700FA07B4 /* HTMLTemplateElement.cpp in Sources */,
</span><span class="cx">                                 A81369D7097374F600D74463 /* HTMLTextAreaElement.cpp in Sources */,
</span><ins>+                                576814401E709FA100E77754 /* JSEcdhKeyDeriveParams.cpp in Sources */,
</ins><span class="cx">                                 9BC6C21C13CCC97B008E0337 /* HTMLTextFormControlElement.cpp in Sources */,
</span><span class="cx">                                 830519951BB0F11000F3772E /* HTMLTimeElement.cpp in Sources */,
</span><span class="cx">                                 A871DC290A15205700B12A68 /* HTMLTitleElement.cpp in Sources */,
</span><span class="lines">@@ -30607,6 +30624,7 @@
</span><span class="cx">                                 76FB9FF819A73E3A00420562 /* JSAutocompleteErrorEvent.cpp in Sources */,
</span><span class="cx">                                 BC124EFF0C26447A009E2349 /* JSBarProp.cpp in Sources */,
</span><span class="cx">                                 BC946346107A934B00857193 /* JSBeforeLoadEvent.cpp in Sources */,
</span><ins>+                                576814351E6FE3E800E77754 /* CryptoAlgorithmECDHMac.cpp in Sources */,
</ins><span class="cx">                                 70F546E8B8B5D7DC54EE144E /* JSBeforeUnloadEvent.cpp in Sources */,
</span><span class="cx">                                 FDF09DC81399B62200688E5B /* JSBiquadFilterNode.cpp in Sources */,
</span><span class="cx">                                 2E2D99CD10E2BBDA00496337 /* JSBlob.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSSubtleCryptoCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include &quot;JSDOMPromise.h&quot;
</span><span class="cx"> #include &quot;JSDOMWrapper.h&quot;
</span><span class="cx"> #include &quot;JSEcKeyParams.h&quot;
</span><ins>+#include &quot;JSEcdhKeyDeriveParams.h&quot;
</ins><span class="cx"> #include &quot;JSHmacKeyParams.h&quot;
</span><span class="cx"> #include &quot;JSJsonWebKey.h&quot;
</span><span class="cx"> #include &quot;JSRsaHashedImportParams.h&quot;
</span><span class="lines">@@ -160,9 +161,28 @@
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">         case Operations::DeriveKey:
</span><del>-        case Operations::DeriveBits:
</del><span class="cx">             throwNotSupportedError(state, scope);
</span><span class="cx">             return nullptr;
</span><ins>+        case Operations::DeriveBits:
+            switch (*identifier) {
+            case CryptoAlgorithmIdentifier::ECDH: {
+                // Remove this hack once https://bugs.webkit.org/show_bug.cgi?id=169333 is fixed.
+                JSValue nameValue = value.getObject()-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;name&quot;));
+                JSValue publicValue = value.getObject()-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;public&quot;));
+                JSObject* newValue = constructEmptyObject(&amp;state);
+                newValue-&gt;putDirect(vm, Identifier::fromString(&amp;vm, &quot;name&quot;), nameValue);
+                newValue-&gt;putDirect(vm, Identifier::fromString(&amp;vm, &quot;publicKey&quot;), publicValue);
+
+                auto params = convertDictionary&lt;CryptoAlgorithmEcdhKeyDeriveParams&gt;(state, newValue);
+                RETURN_IF_EXCEPTION(scope, nullptr);
+                result = std::make_unique&lt;CryptoAlgorithmEcdhKeyDeriveParams&gt;(params);
+                break;
+            }
+            default:
+                throwNotSupportedError(state, scope);
+                return nullptr;
+            }
+            break;
</ins><span class="cx">         case Operations::GenerateKey:
</span><span class="cx">             switch (*identifier) {
</span><span class="cx">             case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5: {
</span><span class="lines">@@ -660,40 +680,6 @@
</span><span class="cx">     algorithm-&gt;digest(WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContextFromExecState(&amp;state), subtle-&gt;wrapped().workQueue());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void jsSubtleCryptoFunctionDeriveKeyPromise(ExecState&amp; state, Ref&lt;DeferredPromise&gt;&amp;&amp; promise)
-{
-    VM&amp; vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(state.argumentCount() &lt; 5)) {
-        promise-&gt;reject&lt;IDLAny&gt;(createNotEnoughArgumentsError(&amp;state));
-        return;
-    }
-
-    auto params = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(0), Operations::DeriveKey);
-    RETURN_IF_EXCEPTION(scope, void());
-
-    // We should always return a NOT_SUPPORTED_ERR since we currently don't support any algorithms that has deriveKey operation.
-    ASSERT_NOT_REACHED();
-}
-
-static void jsSubtleCryptoFunctionDeriveBitsPromise(ExecState&amp; state, Ref&lt;DeferredPromise&gt;&amp;&amp; promise)
-{
-    VM&amp; vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(state.argumentCount() &lt; 3)) {
-        promise-&gt;reject&lt;IDLAny&gt;(createNotEnoughArgumentsError(&amp;state));
-        return;
-    }
-
-    auto params = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(0), Operations::DeriveBits);
-    RETURN_IF_EXCEPTION(scope, void());
-
-    // We should always return a NOT_SUPPORTED_ERR since we currently don't support any algorithms that has deriveBits operation.
-    ASSERT_NOT_REACHED();
-}
-
</del><span class="cx"> static void jsSubtleCryptoFunctionGenerateKeyPromise(ExecState&amp; state, Ref&lt;DeferredPromise&gt;&amp;&amp; promise)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = state.vm();
</span><span class="lines">@@ -747,6 +733,71 @@
</span><span class="cx">     algorithm-&gt;generateKey(*params, extractable, keyUsages, WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContextFromExecState(&amp;state));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void jsSubtleCryptoFunctionDeriveKeyPromise(ExecState&amp; state, Ref&lt;DeferredPromise&gt;&amp;&amp; promise)
+{
+    VM&amp; vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (UNLIKELY(state.argumentCount() &lt; 5)) {
+        promise-&gt;reject&lt;IDLAny&gt;(createNotEnoughArgumentsError(&amp;state));
+        return;
+    }
+
+    auto params = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(0), Operations::DeriveKey);
+    RETURN_IF_EXCEPTION(scope, void());
+
+    // We should always return a NOT_SUPPORTED_ERR since we currently don't support any algorithms that has deriveKey operation.
+    ASSERT_NOT_REACHED();
+}
+
+static void jsSubtleCryptoFunctionDeriveBitsPromise(ExecState&amp; state, Ref&lt;DeferredPromise&gt;&amp;&amp; promise)
+{
+    VM&amp; vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (UNLIKELY(state.argumentCount() &lt; 3)) {
+        promise-&gt;reject&lt;IDLAny&gt;(createNotEnoughArgumentsError(&amp;state));
+        return;
+    }
+
+    auto params = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(0), Operations::DeriveBits);
+    RETURN_IF_EXCEPTION(scope, void());
+
+    auto baseKey = toCryptoKey(state, state.uncheckedArgument(1));
+    RETURN_IF_EXCEPTION(scope, void());
+
+    auto length = convert&lt;IDLUnsignedLong&gt;(state, state.uncheckedArgument(2), IntegerConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(scope, void());
+
+    if (params-&gt;identifier != baseKey-&gt;algorithmIdentifier()) {
+        promise-&gt;reject(INVALID_ACCESS_ERR, ASCIILiteral(&quot;CryptoKey doesn't match AlgorithmIdentifier&quot;));
+        return;
+    }
+
+    if (!baseKey-&gt;allows(CryptoKeyUsageDeriveBits)) {
+        promise-&gt;reject(INVALID_ACCESS_ERR, ASCIILiteral(&quot;CryptoKey doesn't support bits derivation&quot;));
+        return;
+    }
+
+    auto algorithm = CryptoAlgorithmRegistry::singleton().create(params-&gt;identifier);
+    if (UNLIKELY(!algorithm)) {
+        throwNotSupportedError(state, scope);
+        return;
+    }
+
+    auto callback = [capturedPromise = promise.copyRef()](const Vector&lt;uint8_t&gt;&amp; derivedKey) mutable {
+        fulfillPromiseWithArrayBuffer(WTFMove(capturedPromise), derivedKey.data(), derivedKey.size());
+        return;
+    };
+    auto exceptionCallback = [capturedPromise = WTFMove(promise)](ExceptionCode ec) mutable {
+        rejectWithException(WTFMove(capturedPromise), ec);
+    };
+
+    auto subtle = jsDynamicDowncast&lt;JSSubtleCrypto*&gt;(vm, state.thisValue());
+    ASSERT(subtle);
+    algorithm-&gt;deriveBits(WTFMove(params), baseKey.releaseNonNull(), length, WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContextFromExecState(&amp;state), subtle-&gt;wrapped().workQueue());
+}
+
</ins><span class="cx"> static void jsSubtleCryptoFunctionImportKeyPromise(ExecState&amp; state, Ref&lt;DeferredPromise&gt;&amp;&amp; promise)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = state.vm();
</span><span class="lines">@@ -1098,6 +1149,12 @@
</span><span class="cx">     return callPromiseFunction&lt;jsSubtleCryptoFunctionDigestPromise, PromiseExecutionScope::WindowOrWorker&gt;(state);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
+JSValue JSSubtleCrypto::generateKey(ExecState&amp; state)
+{
+    return callPromiseFunction&lt;jsSubtleCryptoFunctionGenerateKeyPromise, PromiseExecutionScope::WindowOrWorker&gt;(state);
+}
+
</ins><span class="cx"> JSValue JSSubtleCrypto::deriveKey(ExecState&amp; state)
</span><span class="cx"> {
</span><span class="cx">     return callPromiseFunction&lt;jsSubtleCryptoFunctionDeriveKeyPromise, PromiseExecutionScope::WindowOrWorker&gt;(state);
</span><span class="lines">@@ -1108,11 +1165,6 @@
</span><span class="cx">     return callPromiseFunction&lt;jsSubtleCryptoFunctionDeriveBitsPromise, PromiseExecutionScope::WindowOrWorker&gt;(state);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSValue JSSubtleCrypto::generateKey(ExecState&amp; state)
-{
-    return callPromiseFunction&lt;jsSubtleCryptoFunctionGenerateKeyPromise, PromiseExecutionScope::WindowOrWorker&gt;(state);
-}
-
</del><span class="cx"> JSValue JSSubtleCrypto::importKey(ExecState&amp; state)
</span><span class="cx"> {
</span><span class="cx">     return callPromiseFunction&lt;jsSubtleCryptoFunctionImportKeyPromise, PromiseExecutionScope::WindowOrWorker&gt;(state);
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoCommonCryptoUtilitiesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/CommonCryptoUtilities.h (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/CommonCryptoUtilities.h        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/crypto/CommonCryptoUtilities.h        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -107,8 +107,8 @@
</span><span class="cx"> extern &quot;C&quot; int CCECGetKeySize(CCECCryptorRef key);
</span><span class="cx"> extern &quot;C&quot; CCCryptorStatus CCECCryptorCreateFromData(size_t keySize, uint8_t *qX, size_t qXLength, uint8_t *qY, size_t qYLength, CCECCryptorRef *ref);
</span><span class="cx"> extern &quot;C&quot; CCCryptorStatus CCECCryptorGetKeyComponents(CCECCryptorRef ecKey, size_t *keySize, uint8_t *qX, size_t *qXLength, uint8_t *qY, size_t *qYLength, uint8_t *d, size_t *dLength);
</span><ins>+extern &quot;C&quot; CCCryptorStatus CCECCryptorComputeSharedSecret(CCECCryptorRef privateKey, CCECCryptorRef publicKey, void *out, size_t *outLen);
</ins><span class="cx"> 
</span><del>-
</del><span class="cx"> #if !USE(APPLE_INTERNAL_SDK)
</span><span class="cx"> extern &quot;C&quot; CCCryptorStatus CCCryptorGCM(CCOperation op, CCAlgorithm alg, const void* key, size_t keyLength, const void* iv, size_t ivLen, const void* aData, size_t aDataLen, const void* dataIn, size_t dataInLength, void* dataOut, void* tag, size_t* tagLength);
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoCryptoAlgorithmcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -62,6 +62,11 @@
</span><span class="cx">     exceptionCallback(NOT_SUPPORTED_ERR);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CryptoAlgorithm::deriveBits(std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp;, Ref&lt;CryptoKey&gt;&amp;&amp;, unsigned long, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp; exceptionCallback, ScriptExecutionContext&amp;, WorkQueue&amp;)
+{
+    exceptionCallback(NOT_SUPPORTED_ERR);
+}
+
</ins><span class="cx"> void CryptoAlgorithm::importKey(SubtleCrypto::KeyFormat, KeyData&amp;&amp;, const std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp;, bool, CryptoKeyUsageBitmap, KeyCallback&amp;&amp;, ExceptionCallback&amp;&amp; exceptionCallback)
</span><span class="cx"> {
</span><span class="cx">     exceptionCallback(NOT_SUPPORTED_ERR);
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoCryptoAlgorithmh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/CryptoAlgorithm.h (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/CryptoAlgorithm.h        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/crypto/CryptoAlgorithm.h        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -72,6 +72,7 @@
</span><span class="cx">     virtual void verify(Ref&lt;CryptoKey&gt;&amp;&amp;, Vector&lt;uint8_t&gt;&amp;&amp; signature, Vector&lt;uint8_t&gt;&amp;&amp;, BoolCallback&amp;&amp;, ExceptionCallback&amp;&amp;, ScriptExecutionContext&amp;, WorkQueue&amp;);
</span><span class="cx">     virtual void digest(Vector&lt;uint8_t&gt;&amp;&amp;, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;, ScriptExecutionContext&amp;, WorkQueue&amp;);
</span><span class="cx">     virtual void generateKey(const CryptoAlgorithmParameters&amp;, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&amp;&amp;, ExceptionCallback&amp;&amp;, ScriptExecutionContext&amp;);
</span><ins>+    virtual void deriveBits(std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp;, Ref&lt;CryptoKey&gt;&amp;&amp;, unsigned long length, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;, ScriptExecutionContext&amp;, WorkQueue&amp;);
</ins><span class="cx">     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=169262
</span><span class="cx">     virtual void importKey(SubtleCrypto::KeyFormat, KeyData&amp;&amp;, const std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp;, bool extractable, CryptoKeyUsageBitmap, KeyCallback&amp;&amp;, ExceptionCallback&amp;&amp;);
</span><span class="cx">     virtual void exportKey(SubtleCrypto::KeyFormat, Ref&lt;CryptoKey&gt;&amp;&amp;, KeyDataCallback&amp;&amp;, ExceptionCallback&amp;&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoCryptoAlgorithmParametersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/CryptoAlgorithmParameters.h (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/CryptoAlgorithmParameters.h        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/crypto/CryptoAlgorithmParameters.h        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx">         AesGcmParams,
</span><span class="cx">         AesKeyGenParams,
</span><span class="cx">         EcKeyParams,
</span><ins>+        EcdhKeyDeriveParams,
</ins><span class="cx">         HmacKeyParams,
</span><span class="cx">         RsaHashedKeyGenParams,
</span><span class="cx">         RsaHashedImportParams,
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(SUBTLE_CRYPTO)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CryptoAlgorithmEcKeyParams.h&quot;
</span><ins>+#include &quot;CryptoAlgorithmEcdhKeyDeriveParams.h&quot;
</ins><span class="cx"> #include &quot;CryptoKeyEC.h&quot;
</span><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -65,6 +66,56 @@
</span><span class="cx">     callback(WTFMove(pair));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CryptoAlgorithmECDH::deriveBits(std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp; parameters, Ref&lt;CryptoKey&gt;&amp;&amp; baseKey, unsigned long length, VectorCallback&amp;&amp; callback, ExceptionCallback&amp;&amp; exceptionCallback, ScriptExecutionContext&amp; context, WorkQueue&amp; workQueue)
+{
+    // We only accept length that is a multiple of 8.
+    if (length % 8) {
+        exceptionCallback(OperationError);
+        return;
+    }
+
+    ASSERT(parameters);
+    auto&amp; ecParameters = downcast&lt;CryptoAlgorithmEcdhKeyDeriveParams&gt;(*parameters);
+
+    if (baseKey-&gt;type() != CryptoKey::Type::Private) {
+        exceptionCallback(INVALID_ACCESS_ERR);
+        return;
+    }
+    ASSERT(ecParameters.publicKey);
+    if (ecParameters.publicKey-&gt;type() != CryptoKey::Type::Public) {
+        exceptionCallback(INVALID_ACCESS_ERR);
+        return;
+    }
+    if (baseKey-&gt;algorithmIdentifier() != ecParameters.publicKey-&gt;algorithmIdentifier()) {
+        exceptionCallback(INVALID_ACCESS_ERR);
+        return;
+    }
+    auto&amp; ecBaseKey = downcast&lt;CryptoKeyEC&gt;(baseKey.get());
+    auto&amp; ecPublicKey = downcast&lt;CryptoKeyEC&gt;(*(ecParameters.publicKey.get()));
+    if (ecBaseKey.namedCurve() != ecPublicKey.namedCurve()) {
+        exceptionCallback(INVALID_ACCESS_ERR);
+        return;
+    }
+
+    auto unifiedCallback = [callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback)](std::optional&lt;Vector&lt;uint8_t&gt;&gt;&amp;&amp; derivedKey, unsigned long length) mutable {
+        if (!derivedKey) {
+            exceptionCallback(OperationError);
+            return;
+        }
+        if (!length) {
+            callback(WTFMove(*derivedKey));
+            return;
+        }
+        if (length / 8 &gt; (*derivedKey).size()) {
+            exceptionCallback(OperationError);
+            return;
+        }
+        (*derivedKey).shrink(length / 8);
+        callback(WTFMove(*derivedKey));
+    };
+    platformDeriveBits(WTFMove(baseKey), ecParameters.publicKey.releaseNonNull(), length, WTFMove(unifiedCallback), context, workQueue);
+}
+
</ins><span class="cx"> void CryptoAlgorithmECDH::importKey(SubtleCrypto::KeyFormat format, KeyData&amp;&amp; data, const std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp; parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&amp;&amp; callback, ExceptionCallback&amp;&amp; exceptionCallback)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(parameters);
</span></span></pre></div>
<a id="trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -42,8 +42,12 @@
</span><span class="cx">     CryptoAlgorithmIdentifier identifier() const final;
</span><span class="cx"> 
</span><span class="cx">     void generateKey(const CryptoAlgorithmParameters&amp;, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&amp;&amp;, ExceptionCallback&amp;&amp;, ScriptExecutionContext&amp;) final;
</span><ins>+    void deriveBits(std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp;, Ref&lt;CryptoKey&gt;&amp;&amp;, unsigned long length, VectorCallback&amp;&amp;, ExceptionCallback&amp;&amp;, ScriptExecutionContext&amp;, WorkQueue&amp;) final;
</ins><span class="cx">     void importKey(SubtleCrypto::KeyFormat, KeyData&amp;&amp;, const std::unique_ptr&lt;CryptoAlgorithmParameters&gt;&amp;&amp;, bool extractable, CryptoKeyUsageBitmap, KeyCallback&amp;&amp;, ExceptionCallback&amp;&amp;) final;
</span><span class="cx">     void exportKey(SubtleCrypto::KeyFormat, Ref&lt;CryptoKey&gt;&amp;&amp;, KeyDataCallback&amp;&amp;, ExceptionCallback&amp;&amp;) final;
</span><ins>+
+    using Callback = Function&lt;void(std::optional&lt;Vector&lt;uint8_t&gt;&gt;&amp;&amp;, unsigned long)&gt;;
+    void platformDeriveBits(Ref&lt;CryptoKey&gt;&amp;&amp; baseKey, Ref&lt;CryptoKey&gt;&amp;&amp; publicKey, unsigned long length, Callback&amp;&amp;, ScriptExecutionContext&amp;, WorkQueue&amp;);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorecryptognutlsCryptoAlgorithmECDHGnuTLScppfromrev213623trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/crypto/gnutls/CryptoAlgorithmECDHGnuTLS.cpp (from rev 213623, trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h) (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/gnutls/CryptoAlgorithmECDHGnuTLS.cpp                                (rev 0)
+++ trunk/Source/WebCore/crypto/gnutls/CryptoAlgorithmECDHGnuTLS.cpp        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;CryptoAlgorithmECDH.h&quot;
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+#include &quot;NotImplemented.h&quot;
+
+namespace WebCore {
+
+void CryptoAlgorithmECDH::platformDeriveBits(Ref&lt;CryptoKey&gt;&amp;&amp;, Ref&lt;CryptoKey&gt;&amp;&amp;, unsigned long, Callback&amp;&amp;, ScriptExecutionContext&amp;, WorkQueue&amp;)
+{
+    notImplemented();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO)
</ins></span></pre></div>
<a id="trunkSourceWebCorecryptokeysCryptoKeyECh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h (213623 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h        2017-03-09 04:02:14 UTC (rev 213623)
+++ trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -84,6 +84,8 @@
</span><span class="cx">     JsonWebKey exportJwk() const;
</span><span class="cx"> 
</span><span class="cx">     size_t keySizeInBits() const;
</span><ins>+    NamedCurve namedCurve() const { return m_curve; }
+    PlatformECKey platformKey() { return m_platformKey; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     CryptoKeyEC(CryptoAlgorithmIdentifier, NamedCurve, CryptoKeyType, PlatformECKey, bool extractable, CryptoKeyUsageBitmap);
</span></span></pre></div>
<a id="trunkSourceWebCorecryptomacCryptoAlgorithmECDHMaccppfromrev213623trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/crypto/mac/CryptoAlgorithmECDHMac.cpp (from rev 213623, trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h) (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/mac/CryptoAlgorithmECDHMac.cpp                                (rev 0)
+++ trunk/Source/WebCore/crypto/mac/CryptoAlgorithmECDHMac.cpp        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;CryptoAlgorithmECDH.h&quot;
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+#include &quot;CommonCryptoUtilities.h&quot;
+#include &quot;CryptoKeyEC.h&quot;
+#include &quot;ScriptExecutionContext.h&quot;
+
+namespace WebCore {
+
+void CryptoAlgorithmECDH::platformDeriveBits(Ref&lt;CryptoKey&gt;&amp;&amp; baseKey, Ref&lt;CryptoKey&gt;&amp;&amp; publicKey, unsigned long length, Callback&amp;&amp; callback, ScriptExecutionContext&amp; context, WorkQueue&amp; workQueue)
+{
+    context.ref();
+    workQueue.dispatch([baseKey = WTFMove(baseKey), publicKey = WTFMove(publicKey), length, callback = WTFMove(callback), &amp;context]() mutable {
+        auto&amp; ecBaseKey = downcast&lt;CryptoKeyEC&gt;(baseKey.get());
+        auto&amp; ecPublicKey = downcast&lt;CryptoKeyEC&gt;(publicKey.get());
+
+        std::optional&lt;Vector&lt;uint8_t&gt;&gt; result = std::nullopt;
+        Vector&lt;uint8_t&gt; derivedKey(ecBaseKey.keySizeInBits() / 8); // Per https://tools.ietf.org/html/rfc6090#section-4.
+        size_t size = derivedKey.size();
+        if (!CCECCryptorComputeSharedSecret(ecBaseKey.platformKey(), ecPublicKey.platformKey(), derivedKey.data(), &amp;size))
+            result = WTFMove(derivedKey);
+
+        context.postTask([result = WTFMove(result), length, callback = WTFMove(callback)](ScriptExecutionContext&amp; context) mutable {
+            callback(WTFMove(result), length);
+            context.deref();
+        });
+    });
+}
+
+}
+
+#endif // ENABLE(SUBTLE_CRYPTO)
</ins></span></pre></div>
<a id="trunkSourceWebCorecryptoparametersCryptoAlgorithmEcdhKeyDeriveParamshfromrev213623trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/crypto/parameters/CryptoAlgorithmEcdhKeyDeriveParams.h (from rev 213623, trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h) (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/parameters/CryptoAlgorithmEcdhKeyDeriveParams.h                                (rev 0)
+++ trunk/Source/WebCore/crypto/parameters/CryptoAlgorithmEcdhKeyDeriveParams.h        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include &quot;CryptoAlgorithmParameters.h&quot;
+#include &lt;wtf/RefCounted.h&gt;
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKey;
+
+class CryptoAlgorithmEcdhKeyDeriveParams final : public CryptoAlgorithmParameters {
+public:
+    RefPtr&lt;CryptoKey&gt; publicKey;
+
+    Class parametersClass() const final { return Class::EcdhKeyDeriveParams; }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(EcdhKeyDeriveParams)
+
+#endif // ENABLE(SUBTLE_CRYPTO)
</ins></span></pre></div>
<a id="trunkSourceWebCorecryptoparametersEcdhKeyDeriveParamsidlfromrev213623trunkSourceWebCorecryptoalgorithmsCryptoAlgorithmECDHh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/crypto/parameters/EcdhKeyDeriveParams.idl (from rev 213623, trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h) (0 => 213624)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/crypto/parameters/EcdhKeyDeriveParams.idl                                (rev 0)
+++ trunk/Source/WebCore/crypto/parameters/EcdhKeyDeriveParams.idl        2017-03-09 04:04:29 UTC (rev 213624)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    Conditional=SUBTLE_CRYPTO,
+    ImplementedAs=CryptoAlgorithmEcdhKeyDeriveParams,
+] dictionary EcdhKeyDeriveParams : CryptoAlgorithmParameters {
+    // We should rename this to public once https://bugs.webkit.org/show_bug.cgi?id=169333 is fixed.
+    // The peer's EC public key.
+    required CryptoKey publicKey;
+};
</ins></span></pre>
</div>
</div>

</body>
</html>