Skip to content

Commit

Permalink
LibWeb: Add Ed448 support in WebCryptoAPI
Browse files Browse the repository at this point in the history
Add full support for Ed448 and import relevant tests.
  • Loading branch information
devgianlu committed Dec 24, 2024
1 parent b73323f commit 86ea7f8
Show file tree
Hide file tree
Showing 15 changed files with 1,521 additions and 7 deletions.
523 changes: 523 additions & 0 deletions Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions Libraries/LibWeb/Crypto/CryptoAlgorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,24 @@ class ED25519 : public AlgorithmMethods {
}
};

class ED448 : public AlgorithmMethods {
public:
virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> sign(AlgorithmParams const&, GC::Ref<CryptoKey>, ByteBuffer const&) override;
virtual WebIDL::ExceptionOr<JS::Value> verify(AlgorithmParams const&, GC::Ref<CryptoKey>, ByteBuffer const&, ByteBuffer const&) override;

virtual WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
virtual WebIDL::ExceptionOr<GC::Ref<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
virtual WebIDL::ExceptionOr<GC::Ref<JS::Object>> export_key(Bindings::KeyFormat, GC::Ref<CryptoKey>) override;

static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ED448(realm)); }

private:
explicit ED448(JS::Realm& realm)
: AlgorithmMethods(realm)
{
}
};

class X25519 : public AlgorithmMethods {
public:
virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, GC::Ref<CryptoKey>, Optional<u32>) override;
Expand Down Expand Up @@ -620,6 +638,20 @@ struct EcKeyImportParams : public AlgorithmParams {
static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
};

// https://wicg.github.io/webcrypto-secure-curves/#dfn-Ed448Params
struct Ed448Params : public AlgorithmParams {
virtual ~Ed448Params() override;

Ed448Params(Optional<ByteBuffer>& context)
: context(context)
{
}

Optional<ByteBuffer> context;

static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
};

ErrorOr<String> base64_url_uint_encode(::Crypto::UnsignedBigInteger);
WebIDL::ExceptionOr<ByteBuffer> base64_url_bytes_decode(JS::Realm&, String const& base64_url_string);
WebIDL::ExceptionOr<::Crypto::UnsignedBigInteger> base64_url_uint_decode(JS::Realm&, String const& base64_url_string);
Expand Down
10 changes: 5 additions & 5 deletions Libraries/LibWeb/Crypto/SubtleCrypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1181,11 +1181,11 @@ SupportedAlgorithmsMap const& supported_algorithms()
define_an_algorithm<ED25519>("exportKey"_string, "Ed25519"_string);

// https://wicg.github.io/webcrypto-secure-curves/#ed448-registration
// FIXME: define_an_algorithm<ED448, Ed448Params>("sign"_string, "Ed448"_string);
// FIXME: define_an_algorithm<ED448, Ed448Params>("verify"_string, "Ed448"_string);
// FIXME: define_an_algorithm<ED448>("generateKey"_string, "Ed448"_string);
// FIXME: define_an_algorithm<ED448>("importKey"_string, "Ed448"_string);
// FIXME: define_an_algorithm<ED448>("exportKey"_string, "Ed448"_string);
define_an_algorithm<ED448, Ed448Params>("sign"_string, "Ed448"_string);
define_an_algorithm<ED448, Ed448Params>("verify"_string, "Ed448"_string);
define_an_algorithm<ED448>("generateKey"_string, "Ed448"_string);
define_an_algorithm<ED448>("importKey"_string, "Ed448"_string);
define_an_algorithm<ED448>("exportKey"_string, "Ed448"_string);

return internal_object;
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Harness status: OK

Found 18 tests

18 Pass
Pass Success: generateKey({name: ED448}, false, [sign])
Pass Success: generateKey({name: ED448}, true, [sign])
Pass Success: generateKey({name: ED448}, false, [verify, sign])
Pass Success: generateKey({name: ED448}, true, [verify, sign])
Pass Success: generateKey({name: ED448}, false, [sign, verify, sign, sign, verify])
Pass Success: generateKey({name: ED448}, true, [sign, verify, sign, sign, verify])
Pass Success: generateKey({name: ed448}, false, [sign])
Pass Success: generateKey({name: ed448}, true, [sign])
Pass Success: generateKey({name: ed448}, false, [verify, sign])
Pass Success: generateKey({name: ed448}, true, [verify, sign])
Pass Success: generateKey({name: ed448}, false, [sign, verify, sign, sign, verify])
Pass Success: generateKey({name: ed448}, true, [sign, verify, sign, sign, verify])
Pass Success: generateKey({name: Ed448}, false, [sign])
Pass Success: generateKey({name: Ed448}, true, [sign])
Pass Success: generateKey({name: Ed448}, false, [verify, sign])
Pass Success: generateKey({name: Ed448}, true, [verify, sign])
Pass Success: generateKey({name: Ed448}, false, [sign, verify, sign, sign, verify])
Pass Success: generateKey({name: Ed448}, true, [sign, verify, sign, sign, verify])
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Harness status: OK

Found 13 tests

13 Pass
Pass EdDSA Ed448 verification
Pass EdDSA Ed448 verification with altered signature after call
Pass EdDSA Ed448 with altered data after call
Pass EdDSA Ed448 using privateKey to verify
Pass EdDSA Ed448 using publicKey to sign
Pass EdDSA Ed448 no verify usage
Pass EdDSA Ed448 round trip
Pass EdDSA Ed448 signing with wrong algorithm name
Pass EdDSA Ed448 verifying with wrong algorithm name
Pass EdDSA Ed448 verification failure due to altered signature
Pass EdDSA Ed448 verification failure due to shortened signature
Pass EdDSA Ed448 verification failure due to altered data
Pass Sign and verify using generated Ed448 keys.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Harness status: OK

Found 281 tests
Found 309 tests

281 Pass
309 Pass
Pass setup
Pass Can wrap and unwrap RSA-OAEP public key keys using spki and RSA-OAEP
Pass Can wrap and unwrap RSA-OAEP public key keys using jwk and RSA-OAEP
Expand All @@ -27,6 +27,13 @@ Pass Can wrap and unwrap Ed25519 private key keys as non-extractable using pkcs8
Pass Can wrap and unwrap Ed25519 private key keys using jwk and RSA-OAEP
Pass Can wrap and unwrap Ed25519 private key keys as non-extractable using jwk and RSA-OAEP
Pass Can unwrap Ed25519 private key non-extractable keys using jwk and RSA-OAEP
Pass Can wrap and unwrap Ed448 public key keys using spki and RSA-OAEP
Pass Can wrap and unwrap Ed448 public key keys using jwk and RSA-OAEP
Pass Can wrap and unwrap Ed448 private key keys using pkcs8 and RSA-OAEP
Pass Can wrap and unwrap Ed448 private key keys as non-extractable using pkcs8 and RSA-OAEP
Pass Can wrap and unwrap Ed448 private key keys using jwk and RSA-OAEP
Pass Can wrap and unwrap Ed448 private key keys as non-extractable using jwk and RSA-OAEP
Pass Can unwrap Ed448 private key non-extractable keys using jwk and RSA-OAEP
Pass Can wrap and unwrap X25519 public key keys using spki and RSA-OAEP
Pass Can wrap and unwrap X25519 public key keys using jwk and RSA-OAEP
Pass Can wrap and unwrap X25519 private key keys using pkcs8 and RSA-OAEP
Expand Down Expand Up @@ -94,6 +101,13 @@ Pass Can wrap and unwrap Ed25519 private key keys as non-extractable using pkcs8
Pass Can wrap and unwrap Ed25519 private key keys using jwk and AES-CTR
Pass Can wrap and unwrap Ed25519 private key keys as non-extractable using jwk and AES-CTR
Pass Can unwrap Ed25519 private key non-extractable keys using jwk and AES-CTR
Pass Can wrap and unwrap Ed448 public key keys using spki and AES-CTR
Pass Can wrap and unwrap Ed448 public key keys using jwk and AES-CTR
Pass Can wrap and unwrap Ed448 private key keys using pkcs8 and AES-CTR
Pass Can wrap and unwrap Ed448 private key keys as non-extractable using pkcs8 and AES-CTR
Pass Can wrap and unwrap Ed448 private key keys using jwk and AES-CTR
Pass Can wrap and unwrap Ed448 private key keys as non-extractable using jwk and AES-CTR
Pass Can unwrap Ed448 private key non-extractable keys using jwk and AES-CTR
Pass Can wrap and unwrap X25519 public key keys using spki and AES-CTR
Pass Can wrap and unwrap X25519 public key keys using jwk and AES-CTR
Pass Can wrap and unwrap X25519 private key keys using pkcs8 and AES-CTR
Expand Down Expand Up @@ -161,6 +175,13 @@ Pass Can wrap and unwrap Ed25519 private key keys as non-extractable using pkcs8
Pass Can wrap and unwrap Ed25519 private key keys using jwk and AES-CBC
Pass Can wrap and unwrap Ed25519 private key keys as non-extractable using jwk and AES-CBC
Pass Can unwrap Ed25519 private key non-extractable keys using jwk and AES-CBC
Pass Can wrap and unwrap Ed448 public key keys using spki and AES-CBC
Pass Can wrap and unwrap Ed448 public key keys using jwk and AES-CBC
Pass Can wrap and unwrap Ed448 private key keys using pkcs8 and AES-CBC
Pass Can wrap and unwrap Ed448 private key keys as non-extractable using pkcs8 and AES-CBC
Pass Can wrap and unwrap Ed448 private key keys using jwk and AES-CBC
Pass Can wrap and unwrap Ed448 private key keys as non-extractable using jwk and AES-CBC
Pass Can unwrap Ed448 private key non-extractable keys using jwk and AES-CBC
Pass Can wrap and unwrap X25519 public key keys using spki and AES-CBC
Pass Can wrap and unwrap X25519 public key keys using jwk and AES-CBC
Pass Can wrap and unwrap X25519 private key keys using pkcs8 and AES-CBC
Expand Down Expand Up @@ -228,6 +249,13 @@ Pass Can wrap and unwrap Ed25519 private key keys as non-extractable using pkcs8
Pass Can wrap and unwrap Ed25519 private key keys using jwk and AES-GCM
Pass Can wrap and unwrap Ed25519 private key keys as non-extractable using jwk and AES-GCM
Pass Can unwrap Ed25519 private key non-extractable keys using jwk and AES-GCM
Pass Can wrap and unwrap Ed448 public key keys using spki and AES-GCM
Pass Can wrap and unwrap Ed448 public key keys using jwk and AES-GCM
Pass Can wrap and unwrap Ed448 private key keys using pkcs8 and AES-GCM
Pass Can wrap and unwrap Ed448 private key keys as non-extractable using pkcs8 and AES-GCM
Pass Can wrap and unwrap Ed448 private key keys using jwk and AES-GCM
Pass Can wrap and unwrap Ed448 private key keys as non-extractable using jwk and AES-GCM
Pass Can unwrap Ed448 private key non-extractable keys using jwk and AES-GCM
Pass Can wrap and unwrap X25519 public key keys using spki and AES-GCM
Pass Can wrap and unwrap X25519 public key keys using jwk and AES-GCM
Pass Can wrap and unwrap X25519 private key keys using pkcs8 and AES-GCM
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<meta charset=utf-8>
<title>WebCryptoAPI: generateKey() for Failures</title>
<meta name="timeout" content="long">
<script>
self.GLOBAL = {
isWindow: function() { return true; },
isWorker: function() { return false; },
isShadowRealm: function() { return false; },
};
</script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../util/helpers.js"></script>
<script src="failures.js"></script>
<div id=log></div>
<script src="../../WebCryptoAPI/generateKey/failures_Ed448.https.any.js"></script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// META: title=WebCryptoAPI: generateKey() for Failures
// META: timeout=long
// META: script=../util/helpers.js
// META: script=failures.js
run_test(["Ed448"]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<meta charset=utf-8>
<title>WebCryptoAPI: generateKey() Successful Calls</title>
<meta name="timeout" content="long">
<script>
self.GLOBAL = {
isWindow: function() { return true; },
isWorker: function() { return false; },
isShadowRealm: function() { return false; },
};
</script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../util/helpers.js"></script>
<script src="../../common/subset-tests.js"></script>
<script src="successes.js"></script>
<div id=log></div>
<script src="../../WebCryptoAPI/generateKey/successes_Ed448.https.any.js"></script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// META: title=WebCryptoAPI: generateKey() Successful Calls
// META: timeout=long
// META: script=../util/helpers.js
// META: script=/common/subset-tests.js
// META: script=successes.js
run_test(["Ed448"]);
Loading

0 comments on commit 86ea7f8

Please sign in to comment.