| ... | 
... | 
@@ -152,12 +152,24 @@ TestArray.addTest( | 
| 
152
 | 
152
 | 
   }
  | 
| 
153
 | 
153
 | 
 );
  | 
| 
154
 | 
154
 | 
 
  | 
| 
 
 | 
155
 | 
+// -----------------------------------------------------------------------------
  | 
| 
 
 | 
156
 | 
+TestArray.addTest(
  | 
| 
 
 | 
157
 | 
+  "Verify that ECDH import fails with a key with a mismatched 'crv' field",
  | 
| 
 
 | 
158
 | 
+  function() {
 | 
| 
 
 | 
159
 | 
+    var that = this;
  | 
| 
 
 | 
160
 | 
+    var alg = { name: "ECDH", namedCurve: "P-521"};
 | 
| 
 
 | 
161
 | 
+
  | 
| 
 
 | 
162
 | 
+    crypto.subtle.importKey("jwk", tv.ecdsa_jwk_crv_mismatch.pub_jwk, alg, true, ["verify"])
 | 
| 
 
 | 
163
 | 
+      .then(error(that), complete(that));
  | 
| 
 
 | 
164
 | 
+  }
  | 
| 
 
 | 
165
 | 
+);
  | 
| 
 
 | 
166
 | 
+
  | 
| 
155
 | 
167
 | 
 // -----------------------------------------------------------------------------
  | 
| 
156
 | 
168
 | 
 TestArray.addTest(
  | 
| 
157
 | 
169
 | 
   "JWK import an ECDH public and private key and derive bits (P-256)",
  | 
| 
158
 | 
170
 | 
   function() {
 | 
| 
159
 | 
171
 | 
     var that = this;
  | 
| 
160
 | 
 
 | 
-    var alg = { name: "ECDH" };
 | 
| 
 
 | 
172
 | 
+    var alg = { name: "ECDH", namedCurve: "P-256" };
 | 
| 
161
 | 
173
 | 
 
  | 
| 
162
 | 
174
 | 
     var pubKey, privKey;
  | 
| 
163
 | 
175
 | 
     function setPub(x) { pubKey = x; }
 | 
| ... | 
... | 
@@ -182,7 +194,7 @@ TestArray.addTest( | 
| 
182
 | 
194
 | 
   "JWK import an ECDH public and private key and derive bits (P-384)",
  | 
| 
183
 | 
195
 | 
   function() {
 | 
| 
184
 | 
196
 | 
     var that = this;
  | 
| 
185
 | 
 
 | 
-    var alg = { name: "ECDH" };
 | 
| 
 
 | 
197
 | 
+    var alg = { name: "ECDH", namedCurve: "P-384"};
 | 
| 
186
 | 
198
 | 
 
  | 
| 
187
 | 
199
 | 
     var pubKey, privKey;
  | 
| 
188
 | 
200
 | 
     function setPub(x) { pubKey = x; }
 | 
| ... | 
... | 
@@ -207,7 +219,7 @@ TestArray.addTest( | 
| 
207
 | 
219
 | 
   "JWK import an ECDH public and private key and derive bits (P-521)",
  | 
| 
208
 | 
220
 | 
   function() {
 | 
| 
209
 | 
221
 | 
     var that = this;
  | 
| 
210
 | 
 
 | 
-    var alg = { name: "ECDH" };
 | 
| 
 
 | 
222
 | 
+    var alg = { name: "ECDH", namedCurve : "P-521" };
 | 
| 
211
 | 
223
 | 
 
  | 
| 
212
 | 
224
 | 
     var pubKey, privKey;
  | 
| 
213
 | 
225
 | 
     function setPub(x) { pubKey = x; }
 | 
| ... | 
... | 
@@ -232,7 +244,7 @@ TestArray.addTest( | 
| 
232
 | 
244
 | 
   "JWK import/export roundtrip with ECDH (P-256)",
  | 
| 
233
 | 
245
 | 
   function() {
 | 
| 
234
 | 
246
 | 
     var that = this;
  | 
| 
235
 | 
 
 | 
-    var alg = { name: "ECDH" };
 | 
| 
 
 | 
247
 | 
+    var alg = { name: "ECDH", namedCurve : "P-256" };
 | 
| 
236
 | 
248
 | 
 
  | 
| 
237
 | 
249
 | 
     var pubKey, privKey;
  | 
| 
238
 | 
250
 | 
     function setPub(x) { pubKey = x; }
 | 
| ... | 
... | 
@@ -277,7 +289,7 @@ TestArray.addTest( | 
| 
277
 | 
289
 | 
   "PKCS8 import/export roundtrip with ECDH (P-256)",
  | 
| 
278
 | 
290
 | 
   function() {
 | 
| 
279
 | 
291
 | 
     var that = this;
  | 
| 
280
 | 
 
 | 
-    var alg = { name: "ECDH",  namedCurve: "P-256" };
 | 
| 
 
 | 
292
 | 
+    var alg = { name: "ECDH", namedCurve: "P-256" };
 | 
| 
281
 | 
293
 | 
 
  | 
| 
282
 | 
294
 | 
     function doExportPriv(x) {
 | 
| 
283
 | 
295
 | 
       return crypto.subtle.exportKey("pkcs8", x);
 | 
| ... | 
... | 
@@ -296,7 +308,7 @@ TestArray.addTest( | 
| 
296
 | 
308
 | 
   "Test that importing bad JWKs fails",
  | 
| 
297
 | 
309
 | 
   function() {
 | 
| 
298
 | 
310
 | 
     var that = this;
  | 
| 
299
 | 
 
 | 
-    var alg = { name: "ECDH" };
 | 
| 
 
 | 
311
 | 
+    var alg = { name: "ECDH", namedCurve: "P-256" };
 | 
| 
300
 | 
312
 | 
     var tvs = tv.ecdh_p256_negative;
  | 
| 
301
 | 
313
 | 
 
  | 
| 
302
 | 
314
 | 
     function doTryImport(jwk) {
 | 
| ... | 
... | 
@@ -306,6 +318,7 @@ TestArray.addTest( | 
| 
306
 | 
318
 | 
     }
  | 
| 
307
 | 
319
 | 
 
  | 
| 
308
 | 
320
 | 
     doTryImport(tvs.jwk_bad_crv)()
  | 
| 
 
 | 
321
 | 
+      .then(error(that), doTryImport(tvs.jwk_different_crv))
  | 
| 
309
 | 
322
 | 
       .then(error(that), doTryImport(tvs.jwk_missing_crv))
  | 
| 
310
 | 
323
 | 
       .then(error(that), doTryImport(tvs.jwk_missing_x))
  | 
| 
311
 | 
324
 | 
       .then(error(that), doTryImport(tvs.jwk_missing_y))
  | 
| ... | 
... | 
@@ -349,7 +362,7 @@ TestArray.addTest( | 
| 
349
 | 
362
 | 
   "Derive an HMAC key from two ECDH keys and test sign/verify",
  | 
| 
350
 | 
363
 | 
   function() {
 | 
| 
351
 | 
364
 | 
     var that = this;
  | 
| 
352
 | 
 
 | 
-    var alg = { name: "ECDH" };
 | 
| 
 
 | 
365
 | 
+    var alg = { name: "ECDH", namedCurve: "P-521" };
 | 
| 
353
 | 
366
 | 
     var algDerived = { name: "HMAC", hash: {name: "SHA-1"} };
 | 
| 
354
 | 
367
 | 
 
  | 
| 
355
 | 
368
 | 
     var pubKey, privKey;
  | 
| ... | 
... | 
@@ -391,6 +404,28 @@ TestArray.addTest( | 
| 
391
 | 
404
 | 
   }
  | 
| 
392
 | 
405
 | 
 );
  | 
| 
393
 | 
406
 | 
 
  | 
| 
 
 | 
407
 | 
+// -----------------------------------------------------------------------------
  | 
| 
 
 | 
408
 | 
+TestArray.addTest(
  | 
| 
 
 | 
409
 | 
+  "Derive an HKDF key from two ECDH keys and derive an HMAC key from that",
  | 
| 
 
 | 
410
 | 
+  function() {
 | 
| 
 
 | 
411
 | 
+    var that = this;
  | 
| 
 
 | 
412
 | 
+    var alg = { name: "ECDH", namedCurve: "P-256" };
 | 
| 
 
 | 
413
 | 
+
  | 
| 
 
 | 
414
 | 
+    async function doTest() {
 | 
| 
 
 | 
415
 | 
+      let privKey = await crypto.subtle.importKey("jwk", tv.ecdh_p256.jwk_priv, alg, false, ["deriveKey"]);
 | 
| 
 
 | 
416
 | 
+      let pubKey = await crypto.subtle.importKey("jwk", tv.ecdh_p256.jwk_pub, alg, false, []);
 | 
| 
 
 | 
417
 | 
+      let ecdhAlg = { name: "ECDH", public: pubKey };
 | 
| 
 
 | 
418
 | 
+      let hkdfAlg = { name: "HKDF", hash: "SHA-256", salt: new Uint8Array(), info: new Uint8Array() };
 | 
| 
 
 | 
419
 | 
+      let hkdfKey = await crypto.subtle.deriveKey(ecdhAlg, privKey, hkdfAlg, false, ["deriveKey"]);
  | 
| 
 
 | 
420
 | 
+      let hmacAlg = { name: "HMAC", hash: "SHA-256" };
 | 
| 
 
 | 
421
 | 
+      let hmacKey = await crypto.subtle.deriveKey(hkdfAlg, hkdfKey, hmacAlg, false, ["sign"]);
  | 
| 
 
 | 
422
 | 
+      return crypto.subtle.sign("HMAC", hmacKey, new Uint8Array());
 | 
| 
 
 | 
423
 | 
+    }
  | 
| 
 
 | 
424
 | 
+    const expected = util.hex2abv("acf62832fa93469824cd997593bc963b28a68e6f73f4516bbe51b35942fe9811");
 | 
| 
 
 | 
425
 | 
+    doTest().then(memcmp_complete(that, expected), error(that));
  | 
| 
 
 | 
426
 | 
+  }
  | 
| 
 
 | 
427
 | 
+);
  | 
| 
 
 | 
428
 | 
+
  | 
| 
394
 | 
429
 | 
 // -----------------------------------------------------------------------------
  | 
| 
395
 | 
430
 | 
 TestArray.addTest(
  | 
| 
396
 | 
431
 | 
   "SPKI import/export of public ECDH keys (P-256)",
  | 
| ... | 
... | 
@@ -433,7 +468,7 @@ TestArray.addTest( | 
| 
433
 | 
468
 | 
   "SPKI/JWK import ECDH keys (P-256) and derive a known secret",
  | 
| 
434
 | 
469
 | 
   function() {
 | 
| 
435
 | 
470
 | 
     var that = this;
  | 
| 
436
 | 
 
 | 
-    var alg = { name: "ECDH" };
 | 
| 
 
 | 
471
 | 
+    var alg = { name: "ECDH", namedCurve: "P-256" };
 | 
| 
437
 | 
472
 | 
 
  | 
| 
438
 | 
473
 | 
     var pubKey, privKey;
  | 
| 
439
 | 
474
 | 
     function setPub(x) { pubKey = x; }
 |