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/hkdf.h>
102#include <botan/internal/hmac.h>
103#include <botan/internal/loadstor.h>
116constexpr size_t NONCE_LENGTH = 12;
124 cs->advance_without_psk();
125 cs->advance_with_server_hello(cipher, std::move(shared_secret), transcript_hash);
132 std::string_view prf_algo) {
133 auto cs = std::unique_ptr<Cipher_State>(
new Cipher_State(side, prf_algo));
134 cs->advance_with_psk(type, std::move(
psk));
149 m_exporter_master_secret = derive_secret(m_early_secret,
"e exp master", transcript_hash);
151 m_salt = derive_secret(m_early_secret,
"derived", empty_hash());
154 m_state = State::EarlyTraffic;
162 auto client_application_traffic_secret = derive_secret(master_secret,
"c ap traffic", transcript_hash);
163 auto server_application_traffic_secret = derive_secret(master_secret,
"s ap traffic", transcript_hash);
169 derive_write_traffic_key(server_application_traffic_secret);
170 m_read_application_traffic_secret = std::move(client_application_traffic_secret);
171 m_write_application_traffic_secret = std::move(server_application_traffic_secret);
173 derive_read_traffic_key(server_application_traffic_secret);
174 m_read_application_traffic_secret = std::move(server_application_traffic_secret);
175 m_write_application_traffic_secret = std::move(client_application_traffic_secret);
178 m_exporter_master_secret = derive_secret(master_secret,
"exp master", transcript_hash);
180 m_state = State::ServerApplicationTraffic;
187 zap(m_peer_finished_key);
192 derive_read_traffic_key(m_read_application_traffic_secret);
194 derive_write_traffic_key(m_write_application_traffic_secret);
199 m_resumption_master_secret = derive_secret(master_secret,
"res master", transcript_hash);
204 m_state = State::Completed;
218 std::vector<uint8_t> nonce(NONCE_LENGTH);
219 store_be(seq_no, nonce.data() + (NONCE_LENGTH -
sizeof(seq_no)));
220 xor_buf(nonce, iv.data(), iv.size());
229 m_encrypt->set_key(m_write_key);
230 m_encrypt->set_associated_data(header);
231 m_encrypt->start(current_nonce(m_write_seq_no, m_write_iv));
232 m_encrypt->finish(fragment);
234 return m_write_seq_no++;
240 BOTAN_ARG_CHECK(encrypted_fragment.size() >= m_decrypt->minimum_final_size(),
"fragment too short to decrypt");
242 m_decrypt->set_key(m_read_key);
243 m_decrypt->set_associated_data(header);
244 m_decrypt->start(current_nonce(m_read_seq_no, m_read_iv));
246 m_decrypt->finish(encrypted_fragment);
248 return m_read_seq_no++;
253 return m_encrypt->output_length(input_length);
258 return m_decrypt->output_length(input_length);
263 return m_decrypt->minimum_final_size();
284 (m_state == State::HandshakeTraffic || m_state == State::ServerApplicationTraffic)) {
300 m_state != State::Completed) {
304 return !m_write_key.empty() && !m_write_iv.empty();
312 m_state != State::Completed) {
320 return !m_read_key.empty() && !m_read_iv.empty();
325 return m_hash->name();
342 if(m_encrypt && m_encrypt->name() != cipher.
cipher_algo() && m_encrypt->name() != cipher.
cipher_algo() +
"(16)") {
350 const Transcript_Hash& transcript_hash_with_truncated_client_hello)
const {
353 auto hmac =
HMAC(m_hash->new_object());
354 hmac.set_key(m_binder_key);
355 hmac.update(transcript_hash_with_truncated_client_hello);
356 return hmac.final_stdvec();
364 auto hmac =
HMAC(m_hash->new_object());
365 hmac.set_key(m_finished_key);
366 hmac.update(transcript_hash);
367 return hmac.final_stdvec();
371 const std::vector<uint8_t>& peer_mac)
const {
376 auto hmac =
HMAC(m_hash->new_object());
377 hmac.set_key(m_peer_finished_key);
378 hmac.update(transcript_hash);
379 return hmac.verify_mac(peer_mac);
385 return derive_secret(m_resumption_master_secret,
"resumption", nonce.
get());
390 if(m_ticket_nonce == std::numeric_limits<
decltype(m_ticket_nonce)>::max()) {
394 Ticket_Nonce retval(std::vector<uint8_t>(
sizeof(m_ticket_nonce)));
395 store_be(m_ticket_nonce++, retval.data());
403 m_hash->update(context);
404 const auto context_hash = m_hash->final_stdvec();
405 return hkdf_expand_label(
406 derive_secret(m_exporter_master_secret, label, empty_hash()),
"exporter", context_hash, length);
411std::unique_ptr<MessageAuthenticationCode> create_hmac(std::string_view hash) {
417Cipher_State::Cipher_State(
Connection_Side whoami, std::string_view hash_function) :
418 m_state(State::Uninitialized),
419 m_connection_side(whoami),
420 m_extract(std::make_unique<HKDF_Extract>(create_hmac(hash_function))),
421 m_expand(std::make_unique<HKDF_Expand>(create_hmac(hash_function))),
422 m_hash(HashFunction::create_or_throw(hash_function)),
423 m_salt(m_hash->output_length(), 0x00),
430void Cipher_State::advance_without_psk() {
435 const auto early_secret = hkdf_extract(secure_vector<uint8_t>(m_hash->output_length(), 0x00));
436 m_salt = derive_secret(early_secret,
"derived", empty_hash());
439 m_state = State::EarlyTraffic;
442void Cipher_State::advance_with_psk(PSK_Type type, secure_vector<uint8_t>&& psk) {
445 m_early_secret = hkdf_extract(std::move(
psk));
455 const auto binder_key = derive_secret(m_early_secret, binder_label, empty_hash());
456 m_binder_key = hkdf_expand_label(binder_key,
"finished", {}, m_hash->output_length());
458 m_state = State::PskBinder;
472 const auto handshake_secret = hkdf_extract(std::move(shared_secret));
474 const auto client_handshake_traffic_secret = derive_secret(handshake_secret,
"c hs traffic", transcript_hash);
475 const auto server_handshake_traffic_secret = derive_secret(handshake_secret,
"s hs traffic", transcript_hash);
478 derive_read_traffic_key(client_handshake_traffic_secret,
true);
479 derive_write_traffic_key(server_handshake_traffic_secret,
true);
481 derive_read_traffic_key(server_handshake_traffic_secret,
true);
482 derive_write_traffic_key(client_handshake_traffic_secret,
true);
485 m_salt = derive_secret(handshake_secret,
"derived", empty_hash());
487 m_state = State::HandshakeTraffic;
491 const bool handshake_traffic_secret) {
494 m_write_key = hkdf_expand_label(traffic_secret,
"key", {}, m_encrypt->minimum_keylength());
495 m_write_iv = hkdf_expand_label(traffic_secret,
"iv", {}, NONCE_LENGTH);
498 if(handshake_traffic_secret) {
501 m_finished_key = hkdf_expand_label(traffic_secret,
"finished", {}, m_hash->output_length());
505void Cipher_State::derive_read_traffic_key(
const secure_vector<uint8_t>& traffic_secret,
506 const bool handshake_traffic_secret) {
509 m_read_key = hkdf_expand_label(traffic_secret,
"key", {}, m_encrypt->minimum_keylength());
510 m_read_iv = hkdf_expand_label(traffic_secret,
"iv", {}, NONCE_LENGTH);
513 if(handshake_traffic_secret) {
516 m_peer_finished_key = hkdf_expand_label(traffic_secret,
"finished", {}, m_hash->output_length());
520secure_vector<uint8_t> Cipher_State::hkdf_extract(secure_vector<uint8_t>&& ikm)
const {
521 return m_extract->derive_key(m_hash->output_length(), ikm, m_salt, std::vector<uint8_t>());
524secure_vector<uint8_t> Cipher_State::hkdf_expand_label(
const secure_vector<uint8_t>& secret,
525 std::string_view label,
526 const std::vector<uint8_t>& context,
527 const size_t length)
const {
529 secure_vector<uint8_t> hkdf_label;
530 hkdf_label.reserve(2 + (label.size() + 6 + 1 ) +
531 (context.size() + 1 ));
534 BOTAN_ARG_CHECK(length <= std::numeric_limits<uint16_t>::max(),
"invalid length");
535 const auto len =
static_cast<uint16_t
>(length);
536 hkdf_label.push_back(get_byte<0>(len));
537 hkdf_label.push_back(get_byte<1>(len));
540 const std::string prefix =
"tls13 ";
541 BOTAN_ARG_CHECK(prefix.size() + label.size() <= 255,
"label too large");
542 hkdf_label.push_back(
static_cast<uint8_t
>(prefix.size() + label.size()));
543 hkdf_label.insert(hkdf_label.end(), prefix.cbegin(), prefix.cend());
544 hkdf_label.insert(hkdf_label.end(), label.cbegin(), label.cend());
548 hkdf_label.push_back(
static_cast<uint8_t
>(context.size()));
549 hkdf_label.insert(hkdf_label.end(), context.cbegin(), context.cend());
552 return m_expand->derive_key(
553 length, secret, hkdf_label, std::vector<uint8_t>() );
556secure_vector<uint8_t> Cipher_State::derive_secret(
const secure_vector<uint8_t>& secret,
557 std::string_view label,
559 return hkdf_expand_label(secret, label, messages_hash, m_hash->output_length());
562std::vector<uint8_t> Cipher_State::empty_hash()
const {
564 return m_hash->final_stdvec();
568 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
570 m_read_application_traffic_secret =
571 hkdf_expand_label(m_read_application_traffic_secret,
"traffic upd", {}, m_hash->output_length());
573 derive_read_traffic_key(m_read_application_traffic_secret);
577 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
578 m_write_application_traffic_secret =
579 hkdf_expand_label(m_write_application_traffic_secret,
"traffic upd", {}, m_hash->output_length());
581 derive_write_traffic_key(m_write_application_traffic_secret);
587 zap(m_read_application_traffic_secret);
593 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
uint64_t decrypt_record_fragment(const std::vector< uint8_t > &header, secure_vector< uint8_t > &encrypted_fragment)
bool can_export_keys() const
void advance_with_client_hello(const Transcript_Hash &transcript_hash)
size_t minimum_decryption_input_length() const
void advance_with_server_finished(const Transcript_Hash &transcript_hash)
bool must_expect_unprotected_alert_traffic() const
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)
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)
secure_vector< uint8_t > psk(const Ticket_Nonce &nonce) const
void advance_with_server_hello(const Ciphersuite &cipher, secure_vector< uint8_t > &&shared_secret, const Transcript_Hash &transcript_hash)
bool is_compatible_with(const Ciphersuite &cipher) const
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
std::vector< uint8_t > Transcript_Hash
void zap(std::vector< T, Alloc > &vec)
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)