Skip to content

Commit

Permalink
Add TLS 1.3 groups ML-KEM-512, -768 and -1024
Browse files Browse the repository at this point in the history
Those groups are described in draft-connolly-tls-mlkem-key-agreement and
request registration of code points 0x0512, 0x0768 and 0x1024 from IANA.
  • Loading branch information
reneme committed Oct 18, 2024
1 parent e24dd8a commit c98372a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
17 changes: 17 additions & 0 deletions src/lib/tls/tls_algos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ std::optional<Group_Params> Group_Params::from_string(std::string_view group_nam
return Group_Params::KYBER_1024_R3_OQS;
}

if(group_name == "ML-KEM-512") {
return Group_Params::ML_KEM_512;
}
if(group_name == "ML-KEM-768") {
return Group_Params::ML_KEM_768;
}
if(group_name == "ML-KEM-1024") {
return Group_Params::ML_KEM_1024;
}

if(group_name == "eFrodoKEM-640-SHAKE") {
return Group_Params::eFRODOKEM_640_SHAKE_OQS;
}
Expand Down Expand Up @@ -303,6 +313,13 @@ std::optional<std::string> Group_Params::to_string() const {
case Group_Params::KYBER_1024_R3_OQS:
return "Kyber-1024-r3";

case Group_Params::ML_KEM_512:
return "ML-KEM-512";
case Group_Params::ML_KEM_768:
return "ML-KEM-768";
case Group_Params::ML_KEM_1024:
return "ML-KEM-1024";

case Group_Params::eFRODOKEM_640_SHAKE_OQS:
return "eFrodoKEM-640-SHAKE";
case Group_Params::eFRODOKEM_976_SHAKE_OQS:
Expand Down
18 changes: 16 additions & 2 deletions src/lib/tls/tls_algos.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ enum class Group_Params_Code : uint16_t {
KYBER_768_R3_OQS = 0x023C,
KYBER_1024_R3_OQS = 0x023D,

// https://datatracker.ietf.org/doc/draft-connolly-tls-mlkem-key-agreement/02/
ML_KEM_512 = 0x0512,
ML_KEM_768 = 0x0768,
ML_KEM_1024 = 0x1024,

eFRODOKEM_640_SHAKE_OQS = 0x0201,
eFRODOKEM_976_SHAKE_OQS = 0x0203,
eFRODOKEM_1344_SHAKE_OQS = 0x0205,
Expand Down Expand Up @@ -194,6 +199,11 @@ class BOTAN_PUBLIC_API(3, 2) Group_Params final {
m_code == Group_Params_Code::FFDHE_8192;
}

constexpr bool is_pure_ml_kem() const {
return m_code == Group_Params_Code::ML_KEM_512 || m_code == Group_Params_Code::ML_KEM_768 ||
m_code == Group_Params_Code::ML_KEM_1024;
}

constexpr bool is_pure_kyber() const {
return m_code == Group_Params_Code::KYBER_512_R3_OQS || m_code == Group_Params_Code::KYBER_768_R3_OQS ||
m_code == Group_Params_Code::KYBER_1024_R3_OQS;
Expand All @@ -210,7 +220,9 @@ class BOTAN_PUBLIC_API(3, 2) Group_Params final {

constexpr bool is_pure_ecc_group() const { return is_x25519() || is_x448() || is_ecdh_named_curve(); }

constexpr bool is_post_quantum() const { return is_pure_kyber() || is_pure_frodokem() || is_pqc_hybrid(); }
constexpr bool is_post_quantum() const {
return is_pure_kyber() || is_pure_ml_kem() || is_pure_frodokem() || is_pqc_hybrid();
}

constexpr bool is_pqc_hybrid() const {
BOTAN_DIAGNOSTIC_PUSH
Expand Down Expand Up @@ -238,7 +250,9 @@ class BOTAN_PUBLIC_API(3, 2) Group_Params final {
BOTAN_DIAGNOSTIC_POP
}

constexpr bool is_kem() const { return is_pure_kyber() || is_pure_frodokem() || is_pqc_hybrid(); }
constexpr bool is_kem() const {
return is_pure_kyber() || is_pure_ml_kem() || is_pure_frodokem() || is_pqc_hybrid();
}

// Returns std::nullopt if the param has no known name
std::optional<std::string> to_string() const;
Expand Down
16 changes: 16 additions & 0 deletions src/lib/tls/tls_callbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
#include <botan/kyber.h>
#endif

#if defined(BOTAN_HAS_ML_KEM)
#include <botan/ml_kem.h>
#endif

#if defined(BOTAN_HAS_FRODOKEM)
#include <botan/frodokem.h>
#endif
Expand Down Expand Up @@ -228,6 +232,12 @@ std::unique_ptr<Public_Key> TLS::Callbacks::tls_deserialize_peer_public_key(
}
#endif

#if defined(BOTAN_HAS_ML_KEM)
if(group_params.is_pure_ml_kem()) {
return std::make_unique<ML_KEM_PublicKey>(key_bits, ML_KEM_Mode(group_params.to_string().value()));
}
#endif

#if defined(BOTAN_HAS_KYBER)
if(group_params.is_pure_kyber()) {
return std::make_unique<Kyber_PublicKey>(key_bits, KyberMode(group_params.to_string().value()));
Expand All @@ -244,6 +254,12 @@ std::unique_ptr<Public_Key> TLS::Callbacks::tls_deserialize_peer_public_key(
}

std::unique_ptr<Private_Key> TLS::Callbacks::tls_kem_generate_key(TLS::Group_Params group, RandomNumberGenerator& rng) {
#if defined(BOTAN_HAS_ML_KEM)
if(group.is_pure_ml_kem()) {
return std::make_unique<Kyber_PrivateKey>(rng, KyberMode(group.to_string().value()));
}
#endif

#if defined(BOTAN_HAS_KYBER)
if(group.is_pure_kyber()) {
return std::make_unique<Kyber_PrivateKey>(rng, KyberMode(group.to_string().value()));
Expand Down
6 changes: 6 additions & 0 deletions src/scripts/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,12 @@ def get_oqs_rootca():
TestConfig("test.openquantumsafe.org", "secp256r1/Kyber-768-r3", port=oqsp['p256_kyber768'], ca=oqs_test_ca),
TestConfig("test.openquantumsafe.org", "secp384r1/Kyber-768-r3", port=oqsp['p384_kyber768'], ca=oqs_test_ca),
TestConfig("test.openquantumsafe.org", "secp521r1/Kyber-1024-r3", port=oqsp['p521_kyber1024'], ca=oqs_test_ca),
# Currently oqs did not adopt the 0x0512 code point defined in draft-connolly-tls-mlkem-key-agreement-02.
# To be fair: this code point was proposed only in the latest revision of the draft (published 8 days ago).
# TODO: enable this test once the code point is adopted by oqs
# TestConfig("test.openquantumsafe.org", "ML-KEM-512", port=oqsp['mlkem512'], ca=oqs_test_ca),
TestConfig("test.openquantumsafe.org", "ML-KEM-768", port=oqsp['mlkem768'], ca=oqs_test_ca),
TestConfig("test.openquantumsafe.org", "ML-KEM-1024", port=oqsp['mlkem1024'], ca=oqs_test_ca),
TestConfig("test.openquantumsafe.org", "Kyber-512-r3", port=oqsp['kyber512'], ca=oqs_test_ca),
TestConfig("test.openquantumsafe.org", "Kyber-768-r3", port=oqsp['kyber768'], ca=oqs_test_ca),
TestConfig("test.openquantumsafe.org", "Kyber-1024-r3", port=oqsp['kyber1024'], ca=oqs_test_ca),
Expand Down

0 comments on commit c98372a

Please sign in to comment.