Skip to content

Commit 17c2e54

Browse files
committed
Merge branch 'tls13/hybrid_key_exchange' into tls13/integration3
2 parents 4081b7b + 7b74a14 commit 17c2e54

11 files changed

Lines changed: 693 additions & 8 deletions

src/lib/tls/msg_client_hello.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ Client_Hello_13::Client_Hello_13(const Policy& policy,
583583

584584
void Client_Hello_13::retry(const Hello_Retry_Request& hrr,
585585
const Transcript_Hash_State& transcript_hash_state,
586+
const Policy& policy,
586587
Callbacks& cb,
587588
RandomNumberGenerator& rng)
588589
{
@@ -593,7 +594,7 @@ void Client_Hello_13::retry(const Hello_Retry_Request& hrr,
593594
const auto& supported_groups = m_extensions.get<Supported_Groups>()->groups();
594595

595596
if(hrr.extensions().has<Key_Share>())
596-
m_extensions.get<Key_Share>()->retry_offer(*hrr_ks, supported_groups, cb, rng);
597+
m_extensions.get<Key_Share>()->retry_offer(*hrr_ks, supported_groups, policy, cb, rng);
597598

598599
// RFC 8446 4.2.2
599600
// When sending the new ClientHello, the client MUST copy

src/lib/tls/tls13/tls_client_impl_13.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ void Client_Impl_13::handle(const Hello_Retry_Request& hrr)
363363
m_transcript_hash = Transcript_Hash_State::recreate_after_hello_retry_request(cipher.value().prf_algo(),
364364
m_transcript_hash);
365365

366-
ch.retry(hrr, m_transcript_hash, callbacks(), rng());
366+
ch.retry(hrr, m_transcript_hash, policy(), callbacks(), rng());
367367

368368
callbacks().tls_examine_extensions(hrr.extensions(), SERVER);
369369

src/lib/tls/tls13/tls_extensions_key_share.cpp

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
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+
56115
class 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

511597
void 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

Comments
 (0)