diff --git a/Tests/LibCrypto/TestCurves.cpp b/Tests/LibCrypto/TestCurves.cpp index c7a40c351c9..8aa007aa71c 100644 --- a/Tests/LibCrypto/TestCurves.cpp +++ b/Tests/LibCrypto/TestCurves.cpp @@ -195,13 +195,15 @@ TEST_CASE(test_secp256r1) ReadonlyBytes bob_private_key { bob_private_key_data, 32 }; ReadonlyBytes bob_public_key { bob_public_key_data, 65 }; - auto generated_alice_public = MUST(Crypto::Curves::SECP256r1::generate_public_key(alice_private_key)); + Crypto::Curves::SECP256r1 curve; + + auto generated_alice_public = MUST(curve.generate_public_key(alice_private_key)); EXPECT_EQ(alice_public_key, generated_alice_public); - auto generated_bob_public = MUST(Crypto::Curves::SECP256r1::generate_public_key(bob_private_key)); + auto generated_bob_public = MUST(curve.generate_public_key(bob_private_key)); EXPECT_EQ(bob_public_key, generated_bob_public); - auto generated_public = MUST(Crypto::Curves::SECP256r1::generate_public_key({ private_key_data, 32 })); + auto generated_public = MUST(curve.generate_public_key({ private_key_data, 32 })); ReadonlyBytes expected_public_key { expected_public_key_data, 65 }; EXPECT_EQ(expected_public_key, generated_public); } diff --git a/Userland/Libraries/LibCrypto/Curves/SECP256r1.cpp b/Userland/Libraries/LibCrypto/Curves/SECP256r1.cpp index d5164c9823b..6a77dfb3647 100644 --- a/Userland/Libraries/LibCrypto/Curves/SECP256r1.cpp +++ b/Userland/Libraries/LibCrypto/Curves/SECP256r1.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -346,6 +347,13 @@ bool SECP256r1::is_point_on_curve(JacobianPoint const& point) return temp.is_zero_constant_time(); } +ErrorOr SECP256r1::generate_private_key() +{ + auto buffer = TRY(ByteBuffer::create_uninitialized(32)); + fill_with_random(buffer.data(), buffer.size()); + return buffer; +} + ErrorOr SECP256r1::generate_public_key(ReadonlyBytes a) { // clang-format off @@ -426,4 +434,14 @@ ErrorOr SECP256r1::compute_coordinate(ReadonlyBytes scalar_bytes, Re return buf; } +ErrorOr SECP256r1::derive_premaster_key(ReadonlyBytes shared_point) +{ + VERIFY(shared_point.size() == 65); + VERIFY(shared_point[0] == 0x04); + + ByteBuffer premaster_key = TRY(ByteBuffer::create_uninitialized(32)); + premaster_key.overwrite(0, shared_point.data() + 1, 32); + return premaster_key; +} + } diff --git a/Userland/Libraries/LibCrypto/Curves/SECP256r1.h b/Userland/Libraries/LibCrypto/Curves/SECP256r1.h index 1972cf9c10c..aaaf722d57f 100644 --- a/Userland/Libraries/LibCrypto/Curves/SECP256r1.h +++ b/Userland/Libraries/LibCrypto/Curves/SECP256r1.h @@ -8,6 +8,7 @@ #include #include +#include namespace Crypto::Curves { @@ -17,10 +18,13 @@ struct JacobianPoint { u256 z { 0u }; }; -class SECP256r1 { +class SECP256r1 : public EllipticCurve { public: - static ErrorOr generate_public_key(ReadonlyBytes a); - static ErrorOr compute_coordinate(ReadonlyBytes scalar_bytes, ReadonlyBytes point_bytes); + size_t key_size() override { return 1 + 2 * 32; } + ErrorOr generate_private_key() override; + ErrorOr generate_public_key(ReadonlyBytes a) override; + ErrorOr compute_coordinate(ReadonlyBytes scalar_bytes, ReadonlyBytes point_bytes) override; + ErrorOr derive_premaster_key(ReadonlyBytes shared_point) override; private: static u256 modular_reduce(u256 const& value); diff --git a/Userland/Libraries/LibTLS/HandshakeServer.cpp b/Userland/Libraries/LibTLS/HandshakeServer.cpp index 1e0866bcecc..e263d82d4d1 100644 --- a/Userland/Libraries/LibTLS/HandshakeServer.cpp +++ b/Userland/Libraries/LibTLS/HandshakeServer.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -311,6 +312,9 @@ ssize_t TLSv12::handle_ecdhe_rsa_server_key_exchange(ReadonlyBytes buffer) case NamedCurve::x448: m_context.server_key_exchange_curve = make(); break; + case NamedCurve::secp256r1: + m_context.server_key_exchange_curve = make(); + break; default: return (i8)Error::NotUnderstood; } diff --git a/Userland/Libraries/LibTLS/TLSv12.h b/Userland/Libraries/LibTLS/TLSv12.h index 6440fd52905..a503c2e4a47 100644 --- a/Userland/Libraries/LibTLS/TLSv12.h +++ b/Userland/Libraries/LibTLS/TLSv12.h @@ -245,6 +245,7 @@ struct Options { { HashAlgorithm::SHA1, SignatureAlgorithm::RSA }); OPTION_WITH_DEFAULTS(Vector, elliptic_curves, NamedCurve::x25519, + NamedCurve::secp256r1, NamedCurve::x448) OPTION_WITH_DEFAULTS(Vector, supported_ec_point_formats, ECPointFormat::Uncompressed)