Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cd583eb
Tests: Re-import WebCryptoAPI tests
tete17 Nov 25, 2025
56c2a7b
LibWeb: Fix typo in spec url
tete17 Nov 22, 2025
f0bba37
LibCrypto: Remove no longer needed output_size in Public Key class
tete17 Nov 22, 2025
aa74581
LibCrypto: Implement key pair generation for ML-DSA algorithm
tete17 Nov 22, 2025
32f0fbf
LibCrypto: Implement message signing for ML-DSA algorithm
tete17 Nov 22, 2025
0a19a4b
LibCrypto: Implement verify for ML-DSA algorithm
tete17 Nov 22, 2025
f341439
LibCrypto: Support the parsing of certs and keys for ml-dsa keys
tete17 Nov 23, 2025
27db01c
LibWeb: Implement key generation for ML-DSA algorithms
tete17 Nov 22, 2025
d5c3628
LibWeb: Implement message signing for ML-DSA algorithm
tete17 Nov 22, 2025
834e5c6
LibWeb: Implement verify for ML-DSA algorithm
tete17 Nov 22, 2025
682c1d5
LibWeb: Expand JsonWebKey to accommodate post quantum algorithms
tete17 Nov 23, 2025
313cc6a
LibWeb: Support the importing of ml-dsa keys in spki format
tete17 Nov 23, 2025
656ff9b
LibWeb: Support the exporting of ml-dsa keys in spki format
tete17 Nov 23, 2025
8971810
LibWeb: Support the importing of ml-dsa keys in raw-public format
tete17 Nov 23, 2025
37bcc56
LibWeb: Support the exporting of ml-dsa keys in raw-public format
tete17 Nov 23, 2025
d894ae6
LibWeb: Support the importing of ml-dsa keys in raw-seed format
tete17 Nov 24, 2025
3cd2d82
LibWeb: Support the exporting of ml-dsa keys in raw-seed format
tete17 Nov 23, 2025
5f0bf68
LibWeb: Support the importing of ml-dsa keys in jwk format
tete17 Nov 24, 2025
70815f0
LibWeb: Support the exporting of ml-dsa keys in jwk format
tete17 Nov 24, 2025
8453688
LibWeb: Support the importing of ml-dsa keys in pkcs8 format
tete17 Nov 25, 2025
18e1197
LibWeb: Support the exporting of ml-dsa keys in pkcs8 format
tete17 Nov 24, 2025
78b5ffb
LibWeb: Add ML-DSA test
tete17 Nov 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Libraries/LibCrypto/ASN1/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ constexpr static Array<int, 4>
issuer_alternative_name_oid { 2, 5, 29, 18 },
basic_constraints_oid { 2, 5, 29, 19 };

constexpr static Array<int, 9>
ml_dsa_44_oid { 2, 16, 840, 1, 101, 3, 4, 3, 17 },
ml_dsa_65_oid { 2, 16, 840, 1, 101, 3, 4, 3, 18 },
ml_dsa_87_oid { 2, 16, 840, 1, 101, 3, 4, 3, 19 };

#define _ENUM(key, value) key,

#define __ENUM_OBJECT_CLASS \
Expand Down
3 changes: 2 additions & 1 deletion Libraries/LibCrypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ set(SOURCES
Hash/SHA1.cpp
Hash/SHA2.cpp
Hash/SHA3.cpp
PK/RSA.cpp
PK/EC.cpp
PK/MLDSA.cpp
PK/RSA.cpp
SecureRandom.cpp
)

Expand Down
65 changes: 58 additions & 7 deletions Libraries/LibCrypto/Certificate/Certificate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(ASN1::Decoder& de
READ_OBJECT(ObjectIdentifier, Vector<int>, algorithm);
POP_SCOPE();

constexpr static Array<Span<int const>, 13> known_algorithm_identifiers {
constexpr static Array<Span<int const>, 16> known_algorithm_identifiers {
ASN1::rsa_encryption_oid,
ASN1::rsa_md5_encryption_oid,
ASN1::rsa_sha1_encryption_oid,
Expand All @@ -69,6 +69,9 @@ static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(ASN1::Decoder& de
ASN1::ed25519_oid,
ASN1::x448_oid,
ASN1::ed448_oid,
ASN1::ml_dsa_44_oid,
ASN1::ml_dsa_65_oid,
ASN1::ml_dsa_87_oid
};

bool is_known_algorithm = false;
Expand Down Expand Up @@ -128,15 +131,21 @@ static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(ASN1::Decoder& de

// https://datatracker.ietf.org/doc/html/rfc8410#section-9
// For all of the OIDs, the parameters MUST be absent.
constexpr static Array<Span<int const>, 8> no_parameter_algorithms = {

// https://datatracker.ietf.org/doc/html/rfc9881/#section-2
// The contents of the parameters component for each algorithm MUST be absent.
constexpr static Array<Span<int const>, 12> no_parameter_algorithms = {
ASN1::ecdsa_with_sha224_encryption_oid,
ASN1::ecdsa_with_sha256_encryption_oid,
ASN1::ecdsa_with_sha384_encryption_oid,
ASN1::ecdsa_with_sha512_encryption_oid,
ASN1::x25519_oid,
ASN1::x448_oid,
ASN1::ed25519_oid,
ASN1::ed448_oid
ASN1::ed448_oid,
ASN1::ml_dsa_44_oid,
ASN1::ml_dsa_65_oid,
ASN1::ml_dsa_87_oid,
};

bool is_no_parameter_algorithm = false;
Expand Down Expand Up @@ -226,12 +235,18 @@ ErrorOr<SubjectPublicKey> parse_subject_public_key_info(ASN1::Decoder& decoder,

// https://datatracker.ietf.org/doc/html/rfc8410#section-9
// For all of the OIDs, the parameters MUST be absent.
constexpr static Array<Span<int const>, 5> no_parameter_algorithms = {

// https://datatracker.ietf.org/doc/html/rfc9881/#section-2
// The contents of the parameters component for each algorithm MUST be absent.
constexpr static Array<Span<int const>, 8> no_parameter_algorithms = {
ASN1::ec_public_key_encryption_oid,
ASN1::x25519_oid,
ASN1::x448_oid,
ASN1::ed25519_oid,
ASN1::ed448_oid
ASN1::ed448_oid,
ASN1::ml_dsa_44_oid,
ASN1::ml_dsa_65_oid,
ASN1::ml_dsa_87_oid,
};

for (auto const& inner : no_parameter_algorithms) {
Expand Down Expand Up @@ -293,15 +308,51 @@ ErrorOr<PrivateKey> parse_private_key_info(ASN1::Decoder& decoder, Vector<String
EXIT_SCOPE();
return private_key;
}
if (private_key.algorithm.identifier.span() == ASN1::ml_dsa_44_oid.span()) {
auto maybe_key = Crypto::PK::MLDSA::parse_mldsa_key(PK::MLDSA44, value.bytes(), current_scope);
if (maybe_key.is_error()) {
ERROR_WITH_SCOPE(maybe_key.release_error());
}

private_key.mldsa = move(maybe_key.release_value().private_key);
EXIT_SCOPE();
return private_key;
}
if (private_key.algorithm.identifier.span() == ASN1::ml_dsa_65_oid.span()) {
auto maybe_key = Crypto::PK::MLDSA::parse_mldsa_key(PK::MLDSA65, value.bytes(), current_scope);
if (maybe_key.is_error()) {
ERROR_WITH_SCOPE(maybe_key.release_error());
}

private_key.mldsa = move(maybe_key.release_value().private_key);
EXIT_SCOPE();
return private_key;
}
if (private_key.algorithm.identifier.span() == ASN1::ml_dsa_87_oid.span()) {
auto maybe_key = Crypto::PK::MLDSA::parse_mldsa_key(PK::MLDSA87, value.bytes(), current_scope);
if (maybe_key.is_error()) {
ERROR_WITH_SCOPE(maybe_key.release_error());
}

private_key.mldsa = move(maybe_key.release_value().private_key);
EXIT_SCOPE();
return private_key;
}

// https://datatracker.ietf.org/doc/html/rfc8410#section-9
// For all of the OIDs, the parameters MUST be absent.
constexpr static Array<Span<int const>, 5> no_parameter_algorithms = {

// https://datatracker.ietf.org/doc/html/rfc9881/#section-2
// The contents of the parameters component for each algorithm MUST be absent.
constexpr static Array<Span<int const>, 8> no_parameter_algorithms = {
ASN1::ec_public_key_encryption_oid,
ASN1::x25519_oid,
ASN1::x448_oid,
ASN1::ed25519_oid,
ASN1::ed448_oid
ASN1::ed448_oid,
ASN1::ml_dsa_44_oid,
ASN1::ml_dsa_65_oid,
ASN1::ml_dsa_87_oid
};

for (auto const& inner : no_parameter_algorithms) {
Expand Down
2 changes: 2 additions & 0 deletions Libraries/LibCrypto/Certificate/Certificate.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <LibCrypto/ASN1/DER.h>
#include <LibCrypto/PK/EC.h>
#include <LibCrypto/PK/MLDSA.h>
#include <LibCrypto/PK/RSA.h>

namespace Crypto::Certificate {
Expand Down Expand Up @@ -44,6 +45,7 @@ class PrivateKey {
public:
PK::RSAPrivateKey rsa;
PK::ECPrivateKey ec;
PK::MLDSAPrivateKey mldsa;

AlgorithmIdentifier algorithm;
ByteBuffer raw_key;
Expand Down
Loading
Loading