92#include <botan/internal/tls_cipher_state.h>
94#include <botan/aead.h>
95#include <botan/assert.h>
96#include <botan/hash.h>
97#include <botan/secmem.h>
98#include <botan/tls_ciphersuite.h>
99#include <botan/tls_magic.h>
101#include <botan/internal/fmt.h>
102#include <botan/internal/hkdf.h>
103#include <botan/internal/hmac.h>
104#include <botan/internal/loadstor.h>
105#include <botan/internal/tls_channel_impl_13.h>
118constexpr size_t NONCE_LENGTH = 12;
127 cs->advance_without_psk();
128 cs->advance_with_server_hello(cipher, std::move(shared_secret), transcript_hash, logger);
135 std::string_view prf_algo) {
136 auto cs = std::unique_ptr<Cipher_State>(
new Cipher_State(side, prf_algo));
137 cs->advance_with_psk(type, std::move(
psk));
152 m_exporter_master_secret = derive_secret(m_early_secret,
"e exp master", transcript_hash);
158 logger.
maybe_log_secret(
"EARLY_EXPORTER_MASTER_SECRET", m_exporter_master_secret);
160 m_salt = derive_secret(m_early_secret,
"derived", empty_hash());
163 m_state = State::EarlyTraffic;
171 auto client_application_traffic_secret = derive_secret(master_secret,
"c ap traffic", transcript_hash);
172 auto server_application_traffic_secret = derive_secret(master_secret,
"s ap traffic", transcript_hash);
178 logger.
maybe_log_secret(
"CLIENT_TRAFFIC_SECRET_0", client_application_traffic_secret);
179 logger.
maybe_log_secret(
"SERVER_TRAFFIC_SECRET_0", server_application_traffic_secret);
185 derive_write_traffic_key(server_application_traffic_secret);
186 m_read_application_traffic_secret = std::move(client_application_traffic_secret);
187 m_write_application_traffic_secret = std::move(server_application_traffic_secret);
189 derive_read_traffic_key(server_application_traffic_secret);
190 m_read_application_traffic_secret = std::move(server_application_traffic_secret);
191 m_write_application_traffic_secret = std::move(client_application_traffic_secret);
194 m_exporter_master_secret = derive_secret(master_secret,
"exp master", transcript_hash);
202 m_state = State::ServerApplicationTraffic;
209 zap(m_peer_finished_key);
214 derive_read_traffic_key(m_read_application_traffic_secret);
216 derive_write_traffic_key(m_write_application_traffic_secret);
221 m_resumption_master_secret = derive_secret(master_secret,
"res master", transcript_hash);
226 m_state = State::Completed;
231auto current_nonce(
const uint64_t seq_no, std::span<const uint8_t> iv) {
240 std::array<uint8_t, NONCE_LENGTH> nonce{};
241 store_be(std::span{nonce}.last<
sizeof(seq_no)>(), seq_no);
253 if(m_write_seq_no == std::numeric_limits<uint64_t>::max()) {
257 m_encrypt->set_associated_data(header);
258 m_encrypt->start(current_nonce(m_write_seq_no, m_write_iv));
259 m_encrypt->finish(fragment);
261 return m_write_seq_no++;
267 BOTAN_ARG_CHECK(encrypted_fragment.size() >= m_decrypt->minimum_final_size(),
"fragment too short to decrypt");
271 if(m_read_seq_no == std::numeric_limits<uint64_t>::max()) {
275 m_decrypt->set_associated_data(header);
276 m_decrypt->start(current_nonce(m_read_seq_no, m_read_iv));
278 m_decrypt->finish(encrypted_fragment);
280 return m_read_seq_no++;
285 return m_encrypt->output_length(input_length);
290 return m_decrypt->output_length(input_length);
295 return m_decrypt->minimum_final_size();
316 (m_state == State::HandshakeTraffic || m_state == State::ServerApplicationTraffic)) {
332 m_state != State::Completed) {
336 return !m_write_key.empty() && !m_write_iv.empty();
344 m_state != State::Completed) {
352 return !m_read_key.empty() && !m_read_iv.empty();
357 return m_hash->name();
378 if(!canonical || canonical->name() != m_encrypt->name()) {
387 const Transcript_Hash& transcript_hash_with_truncated_client_hello)
const {
390 auto hmac =
HMAC(m_hash->new_object());
391 hmac.set_key(m_binder_key);
392 hmac.update(transcript_hash_with_truncated_client_hello);
393 return hmac.final_stdvec();
401 auto hmac =
HMAC(m_hash->new_object());
402 hmac.set_key(m_finished_key);
403 hmac.update(transcript_hash);
404 return hmac.final_stdvec();
408 const std::vector<uint8_t>& peer_mac)
const {
413 auto hmac =
HMAC(m_hash->new_object());
414 hmac.set_key(m_peer_finished_key);
415 hmac.update(transcript_hash);
416 return hmac.verify_mac(peer_mac);
422 return derive_secret(m_resumption_master_secret,
"resumption", nonce.
get());
427 if(m_ticket_nonce_exhausted) {
433 if(m_ticket_nonce == std::numeric_limits<
decltype(m_ticket_nonce)>::max()) {
434 m_ticket_nonce_exhausted =
true;
445 m_hash->update(context);
446 const auto context_hash = m_hash->final_stdvec();
447 return hkdf_expand_label(
448 derive_secret(m_exporter_master_secret, label, empty_hash()),
"exporter", context_hash, length);
453std::unique_ptr<MessageAuthenticationCode> create_hmac(std::string_view hash) {
460 m_state(State::Uninitialized),
461 m_connection_side(whoami),
462 m_extract(std::make_unique<HKDF_Extract>(create_hmac(hash_function))),
463 m_expand(std::make_unique<HKDF_Expand>(create_hmac(hash_function))),
464 m_hash(HashFunction::create_or_throw(hash_function)),
465 m_salt(m_hash->output_length(), 0x00),
468 m_write_key_update_count(0),
469 m_read_key_update_count(0),
474void Cipher_State::advance_without_psk() {
480 m_salt = derive_secret(early_secret,
"derived", empty_hash());
483 m_state = State::EarlyTraffic;
489 m_early_secret = hkdf_extract(std::move(
psk));
492 const char* binder_label = [type]() ->
const char* {
510 const auto binder_key = derive_secret(m_early_secret, binder_label, empty_hash());
511 m_binder_key = hkdf_expand_label(binder_key,
"finished", {}, m_hash->output_length());
513 m_state = State::PskBinder;
528 const auto handshake_secret = hkdf_extract(std::move(shared_secret));
530 const auto client_handshake_traffic_secret = derive_secret(handshake_secret,
"c hs traffic", transcript_hash);
531 const auto server_handshake_traffic_secret = derive_secret(handshake_secret,
"s hs traffic", transcript_hash);
537 logger.
maybe_log_secret(
"CLIENT_HANDSHAKE_TRAFFIC_SECRET", client_handshake_traffic_secret);
538 logger.
maybe_log_secret(
"SERVER_HANDSHAKE_TRAFFIC_SECRET", server_handshake_traffic_secret);
541 derive_read_traffic_key(client_handshake_traffic_secret,
true);
542 derive_write_traffic_key(server_handshake_traffic_secret,
true);
544 derive_read_traffic_key(server_handshake_traffic_secret,
true);
545 derive_write_traffic_key(client_handshake_traffic_secret,
true);
548 m_salt = derive_secret(handshake_secret,
"derived", empty_hash());
550 m_state = State::HandshakeTraffic;
554 const bool handshake_traffic_secret) {
557 m_write_key =
hkdf_expand_label(traffic_secret,
"key", {}, m_encrypt->minimum_keylength());
561 m_encrypt->set_key(m_write_key);
563 if(handshake_traffic_secret) {
566 m_finished_key = hkdf_expand_label(traffic_secret,
"finished", {}, m_hash->output_length());
571 const bool handshake_traffic_secret) {
574 m_read_key = hkdf_expand_label(traffic_secret,
"key", {}, m_decrypt->minimum_keylength());
575 m_read_iv = hkdf_expand_label(traffic_secret,
"iv", {}, NONCE_LENGTH);
578 m_decrypt->set_key(m_read_key);
580 if(handshake_traffic_secret) {
583 m_peer_finished_key = hkdf_expand_label(traffic_secret,
"finished", {}, m_hash->output_length());
588 return m_extract->derive_key(m_hash->output_length(), ikm, m_salt, std::vector<uint8_t>());
592 std::string_view label,
593 const std::vector<uint8_t>& context,
594 const size_t length)
const {
597 hkdf_label.reserve(2 + (label.size() + 6 + 1 ) +
598 (context.size() + 1 ));
601 BOTAN_ARG_CHECK(length <= std::numeric_limits<uint16_t>::max(),
"invalid length");
602 const auto len =
static_cast<uint16_t
>(length);
607 const std::string prefix =
"tls13 ";
608 BOTAN_ARG_CHECK(prefix.size() + label.size() <= 255,
"label too large");
609 hkdf_label.push_back(
static_cast<uint8_t
>(prefix.size() + label.size()));
610 hkdf_label.insert(hkdf_label.end(), prefix.cbegin(), prefix.cend());
611 hkdf_label.insert(hkdf_label.end(), label.cbegin(), label.cend());
615 hkdf_label.push_back(
static_cast<uint8_t
>(context.size()));
616 hkdf_label.insert(hkdf_label.end(), context.cbegin(), context.cend());
619 return m_expand->derive_key(
620 length, secret, hkdf_label, std::vector<uint8_t>() );
624 std::string_view label,
626 return hkdf_expand_label(secret, label, messages_hash, m_hash->output_length());
629std::vector<uint8_t> Cipher_State::empty_hash()
const {
631 return m_hash->final_stdvec();
635 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
637 m_read_application_traffic_secret =
638 hkdf_expand_label(m_read_application_traffic_secret,
"traffic upd", {}, m_hash->output_length());
640 const auto secret_label =
fmt(
"{}_TRAFFIC_SECRET_{}",
642 ++m_read_key_update_count);
645 derive_read_traffic_key(m_read_application_traffic_secret);
649 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
650 m_write_application_traffic_secret =
651 hkdf_expand_label(m_write_application_traffic_secret,
"traffic upd", {}, m_hash->output_length());
653 const auto secret_label =
fmt(
"{}_TRAFFIC_SECRET_{}",
655 ++m_write_key_update_count);
658 derive_write_traffic_key(m_write_application_traffic_secret);
664 zap(m_read_application_traffic_secret);
670 zap(m_write_application_traffic_secret);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
#define BOTAN_ARG_CHECK(expr, msg)
#define BOTAN_ASSERT_UNREACHABLE()
static std::unique_ptr< AEAD_Mode > create_or_throw(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
static std::unique_ptr< AEAD_Mode > create(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
bool can_decrypt_application_traffic() const
static std::unique_ptr< Cipher_State > init_with_server_hello(Connection_Side side, secure_vector< uint8_t > &&shared_secret, const Ciphersuite &cipher, const Transcript_Hash &transcript_hash, const Secret_Logger &channel)
uint64_t decrypt_record_fragment(const std::vector< uint8_t > &header, secure_vector< uint8_t > &encrypted_fragment)
bool can_export_keys() const
size_t minimum_decryption_input_length() const
bool must_expect_unprotected_alert_traffic() const
void update_write_keys(const Secret_Logger &channel)
void advance_with_client_finished(const Transcript_Hash &transcript_hash)
bool verify_peer_finished_mac(const Transcript_Hash &transcript_hash, const std::vector< uint8_t > &peer_mac) const
std::string hash_algorithm() const
static std::unique_ptr< Cipher_State > init_with_psk(Connection_Side side, PSK_Type type, secure_vector< uint8_t > &&psk, std::string_view prf_algo)
uint64_t encrypt_record_fragment(const std::vector< uint8_t > &header, secure_vector< uint8_t > &fragment)
void advance_with_client_hello(const Transcript_Hash &transcript_hash, const Secret_Logger &channel)
void advance_with_server_finished(const Transcript_Hash &transcript_hash, const Secret_Logger &channel)
void update_read_keys(const Secret_Logger &channel)
Cipher_State(const Cipher_State &other)=delete
secure_vector< uint8_t > psk(const Ticket_Nonce &nonce) const
bool is_compatible_with(const Ciphersuite &cipher) const
void advance_with_server_hello(const Ciphersuite &cipher, secure_vector< uint8_t > &&shared_secret, const Transcript_Hash &transcript_hash, const Secret_Logger &channel)
secure_vector< uint8_t > export_key(std::string_view label, std::string_view context, size_t length) const
bool can_encrypt_application_traffic() const
size_t encrypt_output_length(size_t input_length) const
std::vector< uint8_t > psk_binder_mac(const Transcript_Hash &transcript_hash_with_truncated_client_hello) const
size_t decrypt_output_length(size_t input_length) const
Ticket_Nonce next_ticket_nonce()
std::vector< uint8_t > finished_mac(const Transcript_Hash &transcript_hash) const
bool usable_in_version(Protocol_Version version) const
std::string prf_algo() const
std::string cipher_algo() const
virtual void maybe_log_secret(std::string_view label, std::span< const uint8_t > secret) const =0
std::vector< uint8_t > Transcript_Hash
Strong< std::vector< uint8_t >, struct Ticket_Nonce_ > Ticket_Nonce
Used to derive the ticket's PSK from the resumption_master_secret.
constexpr uint8_t get_byte(T input)
void zap(std::vector< T, Alloc > &vec)
std::string fmt(std::string_view format, const T &... args)
secure_vector< uint8_t > hkdf_expand_label(std::string_view hash_fn, std::span< const uint8_t > secret, std::string_view label, std::span< const uint8_t > hash_val, size_t length)
constexpr void xor_buf(ranges::contiguous_output_range< uint8_t > auto &&out, ranges::contiguous_range< uint8_t > auto &&in)
std::vector< T, secure_allocator< T > > secure_vector
constexpr auto store_be(ParamTs &&... params)