webauthn: support evaluating PRFs during create()

The WebAuthn "prf" extension supports evaluating a credential's PRF
during its creation. However, the CTAP2-level "hmac-secret" extension
does not support this. Since there were no devices that could do it,
that WebAuthn feature wasn't wired up.

However, it's possible for hybrid devices to support this feature so
this change wires it up from the renderer to the device code.

Low-Coverage-Reason: n/a
Change-Id: I690bac2d26ad9d76fc64fc256252d0a3ee461643
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4918043
Commit-Queue: Adam Langley <agl@chromium.org>
Reviewed-by: Ken Buchanan <kenrb@chromium.org>
Reviewed-by: Martin Kreichgauer <martinkr@google.com>
Cr-Commit-Position: refs/heads/main@{#1207965}
diff --git a/webauthn/createcredential-prf.https.html b/webauthn/createcredential-prf.https.html
index 7243e08..ac2d5b5 100644
--- a/webauthn/createcredential-prf.https.html
+++ b/webauthn/createcredential-prf.https.html
@@ -37,6 +37,31 @@
     });
     return promise_rejects_dom(t, "NotSupportedError", promise);
   }, "navigator.credentials.create() with nonsensical evalByCredential");
+
+  promise_test(async t => {
+    // Evaluating the PRF at creation time is not supported by security keys
+    // because it cannot be expressed with the CTAP2 hmac-secret extension,
+    // but it is defined at the WebAuthn level.
+
+    const credential = await createCredential({
+      options: {
+        publicKey: {
+          extensions: {
+            prf: {eval: {first: new Uint8Array([1,2,3,4]).buffer}},
+          },
+        },
+      },
+    });
+    assert_true(credential.getClientExtensionResults().prf.enabled,
+                "prf.enabled");
+    assert_true('results' in credential.getClientExtensionResults().prf,
+                "has results");
+    assert_true('first' in credential.getClientExtensionResults().prf.results,
+                "has results.first");
+    assert_equals(
+        credential.getClientExtensionResults().prf.results.first.byteLength, 32,
+        "correct length output");
+  }, "navigator.credentials.create() with eval");
 }, {
   protocol: "ctap2_1",
   extensions: ["prf"],