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, loggger);
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 loggger.
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 loggger.
maybe_log_secret(
"CLIENT_TRAFFIC_SECRET_0", client_application_traffic_secret);
179 loggger.
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);
251 m_encrypt->set_key(m_write_key);
252 m_encrypt->set_associated_data(header);
253 m_encrypt->start(current_nonce(m_write_seq_no, m_write_iv));
254 m_encrypt->finish(fragment);
256 return m_write_seq_no++;
262 BOTAN_ARG_CHECK(encrypted_fragment.size() >= m_decrypt->minimum_final_size(),
"fragment too short to decrypt");
264 m_decrypt->set_key(m_read_key);
265 m_decrypt->set_associated_data(header);
266 m_decrypt->start(current_nonce(m_read_seq_no, m_read_iv));
268 m_decrypt->finish(encrypted_fragment);
270 return m_read_seq_no++;
275 return m_encrypt->output_length(input_length);
280 return m_decrypt->output_length(input_length);
285 return m_decrypt->minimum_final_size();
306 (m_state == State::HandshakeTraffic || m_state == State::ServerApplicationTraffic)) {
322 m_state != State::Completed) {
326 return !m_write_key.empty() && !m_write_iv.empty();
334 m_state != State::Completed) {
342 return !m_read_key.empty() && !m_read_iv.empty();
347 return m_hash->name();
364 if(m_encrypt && m_encrypt->name() != cipher.
cipher_algo() && m_encrypt->name() != cipher.
cipher_algo() +
"(16)") {
372 const Transcript_Hash& transcript_hash_with_truncated_client_hello)
const {
375 auto hmac =
HMAC(m_hash->new_object());
376 hmac.set_key(m_binder_key);
377 hmac.update(transcript_hash_with_truncated_client_hello);
378 return hmac.final_stdvec();
386 auto hmac =
HMAC(m_hash->new_object());
387 hmac.set_key(m_finished_key);
388 hmac.update(transcript_hash);
389 return hmac.final_stdvec();
393 const std::vector<uint8_t>& peer_mac)
const {
398 auto hmac =
HMAC(m_hash->new_object());
399 hmac.set_key(m_peer_finished_key);
400 hmac.update(transcript_hash);
401 return hmac.verify_mac(peer_mac);
407 return derive_secret(m_resumption_master_secret,
"resumption", nonce.
get());
412 if(m_ticket_nonce == std::numeric_limits<
decltype(m_ticket_nonce)>::max()) {
416 Ticket_Nonce retval(std::vector<uint8_t>(
sizeof(m_ticket_nonce)));
417 store_be(m_ticket_nonce++, retval.data());
425 m_hash->update(context);
426 const auto context_hash = m_hash->final_stdvec();
427 return hkdf_expand_label(
428 derive_secret(m_exporter_master_secret, label, empty_hash()),
"exporter", context_hash, length);
433std::unique_ptr<MessageAuthenticationCode> create_hmac(std::string_view hash) {
439Cipher_State::Cipher_State(
Connection_Side whoami, std::string_view hash_function) :
440 m_state(State::Uninitialized),
441 m_connection_side(whoami),
442 m_extract(std::make_unique<HKDF_Extract>(create_hmac(hash_function))),
443 m_expand(std::make_unique<HKDF_Expand>(create_hmac(hash_function))),
444 m_hash(HashFunction::create_or_throw(hash_function)),
445 m_salt(m_hash->output_length(), 0x00),
448 m_write_key_update_count(0),
449 m_read_key_update_count(0),
454void Cipher_State::advance_without_psk() {
460 m_salt = derive_secret(early_secret,
"derived", empty_hash());
463 m_state = State::EarlyTraffic;
469 m_early_secret = hkdf_extract(std::move(
psk));
479 const auto binder_key = derive_secret(m_early_secret, binder_label, empty_hash());
480 m_binder_key = hkdf_expand_label(binder_key,
"finished", {}, m_hash->output_length());
482 m_state = State::PskBinder;
497 const auto handshake_secret = hkdf_extract(std::move(shared_secret));
499 const auto client_handshake_traffic_secret = derive_secret(handshake_secret,
"c hs traffic", transcript_hash);
500 const auto server_handshake_traffic_secret = derive_secret(handshake_secret,
"s hs traffic", transcript_hash);
506 loggger.
maybe_log_secret(
"CLIENT_HANDSHAKE_TRAFFIC_SECRET", client_handshake_traffic_secret);
507 loggger.
maybe_log_secret(
"SERVER_HANDSHAKE_TRAFFIC_SECRET", server_handshake_traffic_secret);
510 derive_read_traffic_key(client_handshake_traffic_secret,
true);
511 derive_write_traffic_key(server_handshake_traffic_secret,
true);
513 derive_read_traffic_key(server_handshake_traffic_secret,
true);
514 derive_write_traffic_key(client_handshake_traffic_secret,
true);
517 m_salt = derive_secret(handshake_secret,
"derived", empty_hash());
519 m_state = State::HandshakeTraffic;
523 const bool handshake_traffic_secret) {
526 m_write_key = hkdf_expand_label(traffic_secret,
"key", {}, m_encrypt->minimum_keylength());
527 m_write_iv = hkdf_expand_label(traffic_secret,
"iv", {}, NONCE_LENGTH);
530 if(handshake_traffic_secret) {
533 m_finished_key = hkdf_expand_label(traffic_secret,
"finished", {}, m_hash->output_length());
538 const bool handshake_traffic_secret) {
541 m_read_key = hkdf_expand_label(traffic_secret,
"key", {}, m_encrypt->minimum_keylength());
542 m_read_iv = hkdf_expand_label(traffic_secret,
"iv", {}, NONCE_LENGTH);
545 if(handshake_traffic_secret) {
548 m_peer_finished_key = hkdf_expand_label(traffic_secret,
"finished", {}, m_hash->output_length());
553 return m_extract->derive_key(m_hash->output_length(), ikm, m_salt, std::vector<uint8_t>());
557 std::string_view label,
558 const std::vector<uint8_t>& context,
559 const size_t length)
const {
562 hkdf_label.reserve(2 + (label.size() + 6 + 1 ) +
563 (context.size() + 1 ));
566 BOTAN_ARG_CHECK(length <= std::numeric_limits<uint16_t>::max(),
"invalid length");
567 const auto len =
static_cast<uint16_t
>(length);
572 const std::string prefix =
"tls13 ";
573 BOTAN_ARG_CHECK(prefix.size() + label.size() <= 255,
"label too large");
574 hkdf_label.push_back(
static_cast<uint8_t
>(prefix.size() + label.size()));
575 hkdf_label.insert(hkdf_label.end(), prefix.cbegin(), prefix.cend());
576 hkdf_label.insert(hkdf_label.end(), label.cbegin(), label.cend());
580 hkdf_label.push_back(
static_cast<uint8_t
>(context.size()));
581 hkdf_label.insert(hkdf_label.end(), context.cbegin(), context.cend());
584 return m_expand->derive_key(
585 length, secret, hkdf_label, std::vector<uint8_t>() );
589 std::string_view label,
591 return hkdf_expand_label(secret, label, messages_hash, m_hash->output_length());
594std::vector<uint8_t> Cipher_State::empty_hash()
const {
596 return m_hash->final_stdvec();
600 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
602 m_read_application_traffic_secret =
603 hkdf_expand_label(m_read_application_traffic_secret,
"traffic upd", {}, m_hash->output_length());
605 const auto secret_label =
fmt(
"{}_TRAFFIC_SECRET_{}",
607 ++m_read_key_update_count);
610 derive_read_traffic_key(m_read_application_traffic_secret);
614 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
615 m_write_application_traffic_secret =
616 hkdf_expand_label(m_write_application_traffic_secret,
"traffic upd", {}, m_hash->output_length());
618 const auto secret_label =
fmt(
"{}_TRAFFIC_SECRET_{}",
620 ++m_write_key_update_count);
623 derive_write_traffic_key(m_write_application_traffic_secret);
629 zap(m_read_application_traffic_secret);
635 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)
static std::unique_ptr< AEAD_Mode > create_or_throw(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)
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
constexpr uint8_t get_byte(T input)
void zap(std::vector< T, Alloc > &vec)
std::string fmt(std::string_view format, const T &... args)
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)