LibWeb: Implement the deriveBits algorithm for X448
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
This commit is contained in:
parent
96ddccd961
commit
d625e12082
Notes:
github-actions[bot]
2024-11-25 16:17:43 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/d625e120828 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2573
4 changed files with 81 additions and 18 deletions
|
@ -3751,6 +3751,69 @@ WebIDL::ExceptionOr<GC::Ref<JS::Object>> X25519::export_key(Bindings::KeyFormat
|
|||
return GC::Ref { *result };
|
||||
}
|
||||
|
||||
// https://wicg.github.io/webcrypto-secure-curves/#x448-operations
|
||||
WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> X448::derive_bits(
|
||||
AlgorithmParams const& params,
|
||||
GC::Ref<CryptoKey> key,
|
||||
Optional<u32> length_optional)
|
||||
{
|
||||
// 1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.
|
||||
if (key->type() != Bindings::KeyType::Private)
|
||||
return WebIDL::InvalidAccessError::create(m_realm, "Key is not a private key"_string);
|
||||
|
||||
// 2. Let publicKey be the public member of normalizedAlgorithm.
|
||||
auto& public_key = static_cast<EcdhKeyDerivePrams const&>(params).public_key;
|
||||
|
||||
// 3. If the [[type]] internal slot of publicKey is not "public", then throw an InvalidAccessError.
|
||||
if (public_key->type() != Bindings::KeyType::Public)
|
||||
return WebIDL::InvalidAccessError::create(m_realm, "Public key is not a public key"_string);
|
||||
|
||||
// 4. If the name attribute of the [[algorithm]] internal slot of publicKey is not equal to
|
||||
// the name property of the [[algorithm]] internal slot of key, then throw an InvalidAccessError.
|
||||
auto& internal_algorithm = static_cast<KeyAlgorithm const&>(*key->algorithm());
|
||||
auto& public_internal_algorithm = static_cast<KeyAlgorithm const&>(*public_key->algorithm());
|
||||
if (internal_algorithm.name() != public_internal_algorithm.name())
|
||||
return WebIDL::InvalidAccessError::create(m_realm, "Algorithm mismatch"_string);
|
||||
|
||||
// 5. Let secret be the result of performing the X448 function specified in [RFC7748] Section 5
|
||||
// with key as the X448 private key k and the X448 public key represented by the [[handle]]
|
||||
// internal slot of publicKey as the X448 public key u.
|
||||
auto private_key = key->handle().get<ByteBuffer>();
|
||||
auto public_key_data = public_key->handle().get<ByteBuffer>();
|
||||
|
||||
::Crypto::Curves::X448 curve;
|
||||
auto maybe_secret = curve.compute_coordinate(private_key, public_key_data);
|
||||
if (maybe_secret.is_error())
|
||||
return WebIDL::OperationError::create(m_realm, "Failed to compute secret"_string);
|
||||
|
||||
auto secret = maybe_secret.release_value();
|
||||
|
||||
// 6. If secret is the all-zero value, then throw a OperationError. This check must be performed in constant-time, as per [RFC7748] Section 6.2.
|
||||
// NOTE: The check may be performed by ORing all the bytes together and checking whether the result is zero,
|
||||
// as this eliminates standard side-channels in software implementations.
|
||||
auto or_bytes = 0;
|
||||
for (auto byte : secret.bytes()) {
|
||||
or_bytes |= byte;
|
||||
}
|
||||
|
||||
if (or_bytes == 0)
|
||||
return WebIDL::OperationError::create(m_realm, "Secret is the all-zero value"_string);
|
||||
|
||||
// 7. If length is null: Return secret
|
||||
if (!length_optional.has_value()) {
|
||||
auto result = TRY_OR_THROW_OOM(m_realm->vm(), ByteBuffer::copy(secret));
|
||||
return JS::ArrayBuffer::create(m_realm, move(result));
|
||||
}
|
||||
|
||||
// Otherwise: Return an octet string containing the first length bits of secret.
|
||||
auto length = length_optional.value();
|
||||
if (secret.size() * 8 < length)
|
||||
return WebIDL::OperationError::create(m_realm, "Secret is too short"_string);
|
||||
|
||||
auto slice = TRY_OR_THROW_OOM(m_realm->vm(), secret.slice(0, length / 8));
|
||||
return JS::ArrayBuffer::create(m_realm, move(slice));
|
||||
}
|
||||
|
||||
// https://wicg.github.io/webcrypto-secure-curves/#x448-operations
|
||||
WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> X448::generate_key(
|
||||
AlgorithmParams const&,
|
||||
|
|
|
@ -545,7 +545,7 @@ private:
|
|||
|
||||
class X448 : public AlgorithmMethods {
|
||||
public:
|
||||
// FIXME: virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, GC::Ref<CryptoKey>, Optional<u32>) override;
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, GC::Ref<CryptoKey>, Optional<u32>) 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;
|
||||
|
|
|
@ -873,7 +873,7 @@ SupportedAlgorithmsMap const& supported_algorithms()
|
|||
define_an_algorithm<X25519>("exportKey"_string, "X25519"_string);
|
||||
|
||||
// https://wicg.github.io/webcrypto-secure-curves/#x448-registration
|
||||
// FIXME: define_an_algorithm<X448, EcdhKeyDerivePrams>("deriveBits"_string, "X448"_string);
|
||||
define_an_algorithm<X448, EcdhKeyDerivePrams>("deriveBits"_string, "X448"_string);
|
||||
define_an_algorithm<X448>("generateKey"_string, "X448"_string);
|
||||
define_an_algorithm<X448>("importKey"_string, "X448"_string);
|
||||
define_an_algorithm<X448>("exportKey"_string, "X448"_string);
|
||||
|
|
|
@ -6,24 +6,24 @@ Rerun
|
|||
|
||||
Found 18 tests
|
||||
|
||||
1 Pass
|
||||
17 Fail
|
||||
15 Pass
|
||||
3 Fail
|
||||
Details
|
||||
Result Test Name MessagePass setup - define tests
|
||||
Fail X448 key derivation checks for all-zero value result with a key of order 0
|
||||
Fail X448 key derivation checks for all-zero value result with a key of order 1
|
||||
Fail X448 key derivation checks for all-zero value result with a key of order p-1 (order 2)
|
||||
Fail X448 key derivation checks for all-zero value result with a key of order p (=0, order 4)
|
||||
Fail X448 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1)
|
||||
Fail X448 good parameters
|
||||
Pass X448 key derivation checks for all-zero value result with a key of order 0
|
||||
Pass X448 key derivation checks for all-zero value result with a key of order 1
|
||||
Pass X448 key derivation checks for all-zero value result with a key of order p-1 (order 2)
|
||||
Pass X448 key derivation checks for all-zero value result with a key of order p (=0, order 4)
|
||||
Pass X448 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1)
|
||||
Pass X448 good parameters
|
||||
Fail X448 mixed case parameters
|
||||
Fail X448 short result
|
||||
Pass X448 short result
|
||||
Fail X448 non-multiple of 8 bits
|
||||
Fail X448 missing public property
|
||||
Fail X448 public property of algorithm is not a CryptoKey
|
||||
Pass X448 missing public property
|
||||
Pass X448 public property of algorithm is not a CryptoKey
|
||||
Fail X448 mismatched algorithms
|
||||
Fail X448 no deriveBits usage for base key
|
||||
Fail X448 base key is not a private key
|
||||
Fail X448 public property value is a private key
|
||||
Fail X448 public property value is a secret key
|
||||
Fail X448 asking for too many bits
|
||||
Pass X448 no deriveBits usage for base key
|
||||
Pass X448 base key is not a private key
|
||||
Pass X448 public property value is a private key
|
||||
Pass X448 public property value is a secret key
|
||||
Pass X448 asking for too many bits
|
Loading…
Add table
Reference in a new issue