2020 #include < botan/curve25519.h>
2121#endif
2222
23+ #if defined(BOTAN_HAS_TLS_13_PQC)
24+ #include < botan/internal/composite_public_key.h>
25+
26+ #if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
27+ #include < botan/kyber.h>
28+ #endif
29+ #endif
30+
2331#include < botan/dh.h>
2432#include < botan/ecdh.h>
2533
@@ -53,6 +61,57 @@ namespace {
5361 group == Group_Params::FFDHE_8192;
5462 }
5563
64+ #if defined(BOTAN_HAS_TLS_13_PQC)
65+ #if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
66+
67+ [[maybe_unused]] constexpr bool is_kyber (const Group_Params group)
68+ {
69+ return
70+ group == Group_Params::KYBER_R3_512 ||
71+ group == Group_Params::KYBER_R3_768 ||
72+ group == Group_Params::KYBER_R3_1024 ||
73+ group == Group_Params::KYBER_90s_R3_512 ||
74+ group == Group_Params::KYBER_90s_R3_768 ||
75+ group == Group_Params::KYBER_90s_R3_1024;
76+ }
77+
78+ [[maybe_unused]] constexpr KyberMode::Mode get_kyber_mode (const Group_Params group)
79+ {
80+ switch (group)
81+ {
82+ case Group_Params::KYBER_R3_512:
83+ return KyberMode::Kyber512;
84+ case Group_Params::KYBER_R3_768:
85+ return KyberMode::Kyber768;
86+ case Group_Params::KYBER_R3_1024:
87+ return KyberMode::Kyber1024;
88+ case Group_Params::KYBER_90s_R3_512:
89+ return KyberMode::Kyber512_90s;
90+ case Group_Params::KYBER_90s_R3_768:
91+ return KyberMode::Kyber768_90s;
92+ case Group_Params::KYBER_90s_R3_1024:
93+ return KyberMode::Kyber1024_90s;
94+ default :
95+ BOTAN_ASSERT (false , " cannot determine kyber mode from non-kyber group ID" );
96+ }
97+ }
98+
99+ #endif
100+
101+ [[maybe_unused]] constexpr bool is_composite (const Group_Params group)
102+ {
103+ return
104+ group == Group_Params::X25519_KYBER_R3_512 ||
105+ group == Group_Params::SECP256R1_KYBER_R3_512 ||
106+ group == Group_Params::SECP384R1_KYBER_R3_768 ||
107+ group == Group_Params::SECP521R1_KYBER_R3_1024 ||
108+ group == Group_Params::SECP256R1_KYBER_90s_R3_512 ||
109+ group == Group_Params::SECP384R1_KYBER_90s_R3_768 ||
110+ group == Group_Params::SECP521R1_KYBER_90s_R3_1024;
111+ }
112+
113+ #endif
114+
56115class Key_Share_Entry
57116 {
58117 public:
@@ -74,7 +133,7 @@ class Key_Share_Entry
74133 }
75134 }
76135
77- Key_Share_Entry (const TLS::Group_Params group, Callbacks& cb, RandomNumberGenerator& rng)
136+ Key_Share_Entry (const TLS::Group_Params group, const Policy& policy, Callbacks& cb, RandomNumberGenerator& rng)
78137 : m_group(group)
79138 {
80139 if (is_ecdh (group))
@@ -112,11 +171,30 @@ class Key_Share_Entry
112171 m_key_exchange = skey->public_value ();
113172 m_private_key = std::move (skey);
114173 }
174+ #endif
175+ #if defined(BOTAN_HAS_TLS_13_PQC)
176+ #if defined(BOTAN_HAS_KYBER)
177+ else if (is_kyber (group))
178+ {
179+ auto skey = std::make_unique<Kyber_PrivateKey>(rng, get_kyber_mode (group));
180+ skey->set_binary_encoding (KyberKeyEncoding::Raw);
181+ m_key_exchange = skey->public_key_bits ();
182+ m_private_key = std::move (skey);
183+ }
184+ #endif
185+ else if (is_composite (group))
186+ {
187+ auto skey = std::make_unique<Composite_PrivateKey>(rng, group, policy);
188+ m_key_exchange = skey->public_key_bits ();
189+ m_private_key = std::move (skey);
190+ }
115191#endif
116192 else
117193 {
118194 throw Decoding_Error (" cannot create a key offering without a group definition" );
119195 }
196+
197+ BOTAN_UNUSED (policy);
120198 }
121199
122200 bool empty () const { return (m_group == Group_Params::NONE) && m_key_exchange.empty (); }
@@ -148,6 +226,14 @@ class Key_Share_Entry
148226 BOTAN_ASSERT_NOMSG (m_private_key != nullptr );
149227 BOTAN_ASSERT_NOMSG (m_group == received.m_group );
150228
229+ #if defined(BOTAN_HAS_KYBER) && defined(BOTAN_HAS_TLS_13_PQC)
230+ if (is_kyber (m_group) || is_composite (m_group))
231+ {
232+ return PK_KEM_Decryptor (*m_private_key, rng, " Raw" )
233+ .decrypt (received.m_key_exchange , 0 , std::vector<uint8_t >());
234+ }
235+ #endif
236+
151237 PK_Key_Agreement ka (*m_private_key, rng, " Raw" );
152238
153239 if (is_ecdh (m_group))
@@ -302,7 +388,7 @@ class Key_Share_ClientHello
302388 {
303389 continue ;
304390 }
305- m_client_shares.emplace_back (group, cb, rng);
391+ m_client_shares.emplace_back (group, policy, cb, rng);
306392 }
307393 }
308394 ~Key_Share_ClientHello () = default ;
@@ -313,7 +399,7 @@ class Key_Share_ClientHello
313399 Key_Share_ClientHello (Key_Share_ClientHello&&) = default ;
314400 Key_Share_ClientHello& operator =(Key_Share_ClientHello&&) = default ;
315401
316- void retry_offer (const TLS::Group_Params to_offer, Callbacks& cb, RandomNumberGenerator& rng)
402+ void retry_offer (const TLS::Group_Params to_offer, const Policy& policy, Callbacks& cb, RandomNumberGenerator& rng)
317403 {
318404 // RFC 8446 4.2.8
319405 // The selected_group field [MUST] not correspond to a group which was provided
@@ -326,7 +412,7 @@ class Key_Share_ClientHello
326412 }
327413
328414 m_client_shares.clear ();
329- m_client_shares.emplace_back (to_offer, cb, rng);
415+ m_client_shares.emplace_back (to_offer, policy, cb, rng);
330416 }
331417
332418 std::vector<uint8_t > serialize () const
@@ -510,6 +596,7 @@ secure_vector<uint8_t> Key_Share::exchange(const Key_Share& peer_keyshare,
510596
511597void Key_Share::retry_offer (const Key_Share& retry_request_keyshare,
512598 const std::vector<Named_Group>& supported_groups,
599+ const Policy& policy,
513600 Callbacks& cb,
514601 RandomNumberGenerator& rng)
515602 {
@@ -524,7 +611,7 @@ void Key_Share::retry_offer(const Key_Share& retry_request_keyshare,
524611 if (!value_exists (supported_groups, selected))
525612 { throw TLS_Exception (Alert::ILLEGAL_PARAMETER, " group was not advertised as supported" ); }
526613
527- return ch.retry_offer (selected, cb, rng);
614+ return ch.retry_offer (selected, policy, cb, rng);
528615 },
529616 [](const auto &, const auto &)
530617 {
0 commit comments