Botan 3.3.0
Crypto and TLS for C&
Public Types | Public Member Functions | Static Public Member Functions | List of all members
Botan::TLS::Cipher_State Class Reference

#include <tls_cipher_state.h>

Public Types

enum class  PSK_Type { Resumption , External }
 

Public Member Functions

void advance_with_client_finished (const Transcript_Hash &transcript_hash)
 
void advance_with_client_hello (const Transcript_Hash &transcript_hash)
 
void advance_with_server_finished (const Transcript_Hash &transcript_hash)
 
void advance_with_server_hello (const Ciphersuite &cipher, secure_vector< uint8_t > &&shared_secret, const Transcript_Hash &transcript_hash)
 
bool can_decrypt_application_traffic () const
 
bool can_encrypt_application_traffic () const
 
bool can_export_keys () const
 
void clear_read_keys ()
 
void clear_write_keys ()
 
size_t decrypt_output_length (size_t input_length) const
 
uint64_t decrypt_record_fragment (const std::vector< uint8_t > &header, secure_vector< uint8_t > &encrypted_fragment)
 
size_t encrypt_output_length (size_t input_length) const
 
uint64_t encrypt_record_fragment (const std::vector< uint8_t > &header, secure_vector< uint8_t > &fragment)
 
secure_vector< uint8_t > export_key (std::string_view label, std::string_view context, size_t length) const
 
std::vector< uint8_t > finished_mac (const Transcript_Hash &transcript_hash) const
 
std::string hash_algorithm () const
 
bool is_compatible_with (const Ciphersuite &cipher) const
 
size_t minimum_decryption_input_length () const
 
bool must_expect_unprotected_alert_traffic () const
 
Ticket_Nonce next_ticket_nonce ()
 
secure_vector< uint8_t > psk (const Ticket_Nonce &nonce) const
 
std::vector< uint8_t > psk_binder_mac (const Transcript_Hash &transcript_hash_with_truncated_client_hello) const
 
void update_read_keys ()
 
void update_write_keys ()
 
bool verify_peer_finished_mac (const Transcript_Hash &transcript_hash, const std::vector< uint8_t > &peer_mac) const
 
 ~Cipher_State ()
 

Static Public Member Functions

static std::unique_ptr< Cipher_Stateinit_with_psk (Connection_Side side, PSK_Type type, secure_vector< uint8_t > &&psk, std::string_view prf_algo)
 
static std::unique_ptr< Cipher_Stateinit_with_server_hello (Connection_Side side, secure_vector< uint8_t > &&shared_secret, const Ciphersuite &cipher, const Transcript_Hash &transcript_hash)
 

Detailed Description

This class implements the key schedule for TLS 1.3 as described in RFC 8446 7.1.

Internally, it reflects the state machine pictured in the same RFC section. It provides the following entry points and state advancement methods that each facilitate certain cryptographic functionality:

While encrypting and decrypting records (RFC 8446 5.2) Cipher_State internally keeps track of the current sequence numbers (RFC 8446 5.3) to calculate the correct Per-Record Nonce. Sequence numbers are reset appropriately, whenever traffic secrets change.

Handshake finished MAC calculation and verification is described in RFC 8446 4.4.4.

PSKs calculation is described in RFC 8446 4.6.1.

Definition at line 61 of file tls_cipher_state.h.

Member Enumeration Documentation

◆ PSK_Type

Enumerator
Resumption 
External 

Definition at line 63 of file tls_cipher_state.h.

63 {
65 External, // currently not implemented
66 };

Constructor & Destructor Documentation

◆ ~Cipher_State()

Botan::TLS::Cipher_State::~Cipher_State ( )
default

Member Function Documentation

◆ advance_with_client_finished()

void Botan::TLS::Cipher_State::advance_with_client_finished ( const Transcript_Hash & transcript_hash)

Transition to the final internal state allowing to create resumptions.

Definition at line 183 of file tls_cipher_state.cpp.

183 {
184 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic);
185
186 zap(m_finished_key);
187 zap(m_peer_finished_key);
188
189 // With the client's Finished message, the handshake is complete and
190 // we can process client application data.
191 if(m_connection_side == Connection_Side::Server) {
192 derive_read_traffic_key(m_read_application_traffic_secret);
193 } else {
194 derive_write_traffic_key(m_write_application_traffic_secret);
195 }
196
197 const auto master_secret = hkdf_extract(secure_vector<uint8_t>(m_hash->output_length(), 0x00));
198
199 m_resumption_master_secret = derive_secret(master_secret, "res master", transcript_hash);
200
201 // This was the final state change; the salt is no longer needed.
202 zap(m_salt);
203
204 m_state = State::Completed;
205}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
void zap(std::vector< T, Alloc > &vec)
Definition secmem.h:117

References BOTAN_ASSERT_NOMSG, Botan::TLS::Server, and Botan::zap().

◆ advance_with_client_hello()

void Botan::TLS::Cipher_State::advance_with_client_hello ( const Transcript_Hash & transcript_hash)

Transition internal secrets/keys for transporting early application data. Note that this state transition is legal only for handshakes using PSK.

Definition at line 138 of file tls_cipher_state.cpp.

138 {
139 BOTAN_ASSERT_NOMSG(m_state == State::PskBinder);
140
141 zap(m_binder_key);
142
143 // TODO: Currently 0-RTT is not yet implemented, hence we don't derive the
144 // early traffic secret for now.
145 //
146 // const auto client_early_traffic_secret = derive_secret(m_early_secret, "c e traffic", transcript_hash);
147 // derive_write_traffic_key(client_early_traffic_secret);
148
149 m_exporter_master_secret = derive_secret(m_early_secret, "e exp master", transcript_hash);
150
151 m_salt = derive_secret(m_early_secret, "derived", empty_hash());
152 zap(m_early_secret);
153
154 m_state = State::EarlyTraffic;
155}

References BOTAN_ASSERT_NOMSG, and Botan::zap().

◆ advance_with_server_finished()

void Botan::TLS::Cipher_State::advance_with_server_finished ( const Transcript_Hash & transcript_hash)

Transition internal secrets/keys for transporting application data.

Definition at line 157 of file tls_cipher_state.cpp.

157 {
158 BOTAN_ASSERT_NOMSG(m_state == State::HandshakeTraffic);
159
160 const auto master_secret = hkdf_extract(secure_vector<uint8_t>(m_hash->output_length(), 0x00));
161
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);
164
165 // Note: the secrets for processing client's application data
166 // are not derived before the client's Finished message
167 // was seen and the handshake can be considered finished.
168 if(m_connection_side == Connection_Side::Server) {
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);
172 } else {
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);
176 }
177
178 m_exporter_master_secret = derive_secret(master_secret, "exp master", transcript_hash);
179
180 m_state = State::ServerApplicationTraffic;
181}

References BOTAN_ASSERT_NOMSG, and Botan::TLS::Server.

◆ advance_with_server_hello()

void Botan::TLS::Cipher_State::advance_with_server_hello ( const Ciphersuite & cipher,
secure_vector< uint8_t > && shared_secret,
const Transcript_Hash & transcript_hash )

Transition internal secrets/keys for transporting handshake data.

Definition at line 461 of file tls_cipher_state.cpp.

463 {
464 BOTAN_ASSERT_NOMSG(m_state == State::EarlyTraffic);
465 BOTAN_ASSERT_NOMSG(!m_encrypt);
466 BOTAN_ASSERT_NOMSG(!m_decrypt);
468
469 m_encrypt = AEAD_Mode::create_or_throw(cipher.cipher_algo(), Cipher_Dir::Encryption);
470 m_decrypt = AEAD_Mode::create_or_throw(cipher.cipher_algo(), Cipher_Dir::Decryption);
471
472 const auto handshake_secret = hkdf_extract(std::move(shared_secret));
473
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);
476
477 if(m_connection_side == Connection_Side::Server) {
478 derive_read_traffic_key(client_handshake_traffic_secret, true);
479 derive_write_traffic_key(server_handshake_traffic_secret, true);
480 } else {
481 derive_read_traffic_key(server_handshake_traffic_secret, true);
482 derive_write_traffic_key(client_handshake_traffic_secret, true);
483 }
484
485 m_salt = derive_secret(handshake_secret, "derived", empty_hash());
486
487 m_state = State::HandshakeTraffic;
488}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:41
static std::unique_ptr< AEAD_Mode > create_or_throw(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
Definition aead.cpp:43
bool is_compatible_with(const Ciphersuite &cipher) const

References BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, Botan::TLS::Ciphersuite::cipher_algo(), Botan::AEAD_Mode::create_or_throw(), Botan::Decryption, Botan::Encryption, is_compatible_with(), and Botan::TLS::Server.

◆ can_decrypt_application_traffic()

bool Botan::TLS::Cipher_State::can_decrypt_application_traffic ( ) const

Indicates whether the appropriate secrets to decrypt application traffic are available

Definition at line 307 of file tls_cipher_state.cpp.

307 {
308 // TODO: when implementing early traffic (0-RTT) this will likely need
309 // to allow `State::EarlyTraffic`.
310
311 if(m_connection_side == Connection_Side::Client && m_state != State::ServerApplicationTraffic &&
312 m_state != State::Completed) {
313 return false;
314 }
315
316 if(m_connection_side == Connection_Side::Server && m_state != State::Completed) {
317 return false;
318 }
319
320 return !m_read_key.empty() && !m_read_iv.empty();
321}

References Botan::TLS::Client, and Botan::TLS::Server.

◆ can_encrypt_application_traffic()

bool Botan::TLS::Cipher_State::can_encrypt_application_traffic ( ) const

Indicates whether the appropriate secrets to encrypt application traffic are available

Definition at line 291 of file tls_cipher_state.cpp.

291 {
292 // TODO: when implementing early traffic (0-RTT) this will likely need
293 // to allow `State::EarlyTraffic`.
294
295 if(m_connection_side == Connection_Side::Client && m_state != State::Completed) {
296 return false;
297 }
298
299 if(m_connection_side == Connection_Side::Server && m_state != State::ServerApplicationTraffic &&
300 m_state != State::Completed) {
301 return false;
302 }
303
304 return !m_write_key.empty() && !m_write_iv.empty();
305}

References Botan::TLS::Client, and Botan::TLS::Server.

◆ can_export_keys()

bool Botan::TLS::Cipher_State::can_export_keys ( ) const
inline

Indicates whether the appropriate secrets to export keys are available

Definition at line 195 of file tls_cipher_state.h.

195 {
196 return (m_state == State::EarlyTraffic || m_state == State::ServerApplicationTraffic ||
197 m_state == State::Completed) &&
198 !m_exporter_master_secret.empty();
199 }

Referenced by export_key().

◆ clear_read_keys()

void Botan::TLS::Cipher_State::clear_read_keys ( )

Remove handshake/traffic secrets for decrypting data from peer

Definition at line 584 of file tls_cipher_state.cpp.

584 {
585 zap(m_read_key);
586 zap(m_read_iv);
587 zap(m_read_application_traffic_secret);
588}

References Botan::zap().

◆ clear_write_keys()

void Botan::TLS::Cipher_State::clear_write_keys ( )

Remove handshake/traffic secrets for encrypting data

Definition at line 590 of file tls_cipher_state.cpp.

590 {
591 zap(m_write_key);
592 zap(m_write_iv);
593 zap(m_write_application_traffic_secret);
594}

References Botan::zap().

◆ decrypt_output_length()

size_t Botan::TLS::Cipher_State::decrypt_output_length ( size_t input_length) const
Returns
number of bytes needed to decrypt input_length bytes

Definition at line 256 of file tls_cipher_state.cpp.

256 {
257 BOTAN_ASSERT_NONNULL(m_decrypt);
258 return m_decrypt->output_length(input_length);
259}
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86

References BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::next_record().

◆ decrypt_record_fragment()

uint64_t Botan::TLS::Cipher_State::decrypt_record_fragment ( const std::vector< uint8_t > & header,
secure_vector< uint8_t > & encrypted_fragment )

Decrypt a TLS record fragment (RFC 8446 5.2 – TLSCiphertext.encrypted_record) using the currently available traffic secret keys and the current sequence number. This will internally increment the sequence number. Hence, multiple calls with the same input will not produce the same result.

Returns
the sequence number of the decrypted record

Definition at line 237 of file tls_cipher_state.cpp.

238 {
239 BOTAN_ASSERT_NONNULL(m_decrypt);
240 BOTAN_ARG_CHECK(encrypted_fragment.size() >= m_decrypt->minimum_final_size(), "fragment too short to decrypt");
241
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));
245
246 m_decrypt->finish(encrypted_fragment);
247
248 return m_read_seq_no++;
249}
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29

References BOTAN_ARG_CHECK, and BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::next_record().

◆ encrypt_output_length()

size_t Botan::TLS::Cipher_State::encrypt_output_length ( size_t input_length) const
Returns
number of bytes needed to encrypt input_length bytes

Definition at line 251 of file tls_cipher_state.cpp.

251 {
252 BOTAN_ASSERT_NONNULL(m_encrypt);
253 return m_encrypt->output_length(input_length);
254}

References BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::prepare_records().

◆ encrypt_record_fragment()

uint64_t Botan::TLS::Cipher_State::encrypt_record_fragment ( const std::vector< uint8_t > & header,
secure_vector< uint8_t > & fragment )

Encrypt a TLS record fragment (RFC 8446 5.2 – TLSInnerPlaintext) using the currently available traffic secret keys and the current sequence number. This will internally increment the sequence number. Hence, multiple calls with the same input will not produce the same result.

Returns
the sequence number of the encrypted record

Definition at line 226 of file tls_cipher_state.cpp.

226 {
227 BOTAN_ASSERT_NONNULL(m_encrypt);
228
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);
233
234 return m_write_seq_no++;
235}

References BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::prepare_records().

◆ export_key()

secure_vector< uint8_t > Botan::TLS::Cipher_State::export_key ( std::string_view label,
std::string_view context,
size_t length ) const

Derive key material to export (RFC 8446 7.5 and RFC 5705)

TODO: this does not yet support key export based on the early_exporter_master_secret.

RFC 8446 7.5 Implementations MUST use the exporter_master_secret unless explicitly specified by the application. The early_exporter_master_secret is defined for use in settings where an exporter is needed for 0-RTT data. A separate interface for the early exporter is RECOMMENDED [...].

Parameters
labela disambiguating label string
contexta per-association context value
lengththe length of the desired key in bytes
Returns
key of length bytes

Definition at line 400 of file tls_cipher_state.cpp.

400 {
402
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);
407}

References BOTAN_ASSERT_NOMSG, and can_export_keys().

◆ finished_mac()

std::vector< uint8_t > Botan::TLS::Cipher_State::finished_mac ( const Transcript_Hash & transcript_hash) const

Calculate the MAC for a TLS "Finished" handshake message (RFC 8446 4.4.4)

Definition at line 359 of file tls_cipher_state.cpp.

359 {
360 BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Server || m_state == State::HandshakeTraffic);
361 BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Client || m_state == State::ServerApplicationTraffic);
362 BOTAN_ASSERT_NOMSG(!m_finished_key.empty());
363
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();
368}

References BOTAN_ASSERT_NOMSG, Botan::TLS::Client, and Botan::TLS::Server.

Referenced by Botan::TLS::Finished_13::Finished_13().

◆ hash_algorithm()

std::string Botan::TLS::Cipher_State::hash_algorithm ( ) const

The name of the hash algorithm used for the KDF in this cipher suite

Definition at line 323 of file tls_cipher_state.cpp.

323 {
324 BOTAN_ASSERT_NONNULL(m_hash);
325 return m_hash->name();
326}

References BOTAN_ASSERT_NONNULL.

Referenced by is_compatible_with().

◆ init_with_psk()

std::unique_ptr< Cipher_State > Botan::TLS::Cipher_State::init_with_psk ( Connection_Side side,
const Cipher_State::PSK_Type type,
secure_vector< uint8_t > && psk,
std::string_view prf_algo )
static

Construct a Cipher_State from a Pre-Shared-Key.

Definition at line 129 of file tls_cipher_state.cpp.

132 {
133 auto cs = std::unique_ptr<Cipher_State>(new Cipher_State(side, prf_algo));
134 cs->advance_with_psk(type, std::move(psk));
135 return cs;
136}
secure_vector< uint8_t > psk(const Ticket_Nonce &nonce) const

References psk().

◆ init_with_server_hello()

std::unique_ptr< Cipher_State > Botan::TLS::Cipher_State::init_with_server_hello ( Connection_Side side,
secure_vector< uint8_t > && shared_secret,
const Ciphersuite & cipher,
const Transcript_Hash & transcript_hash )
static

Construct a Cipher_State after receiving a server hello message.

Definition at line 119 of file tls_cipher_state.cpp.

122 {
123 auto cs = std::unique_ptr<Cipher_State>(new Cipher_State(side, cipher.prf_algo()));
124 cs->advance_without_psk();
125 cs->advance_with_server_hello(cipher, std::move(shared_secret), transcript_hash);
126 return cs;
127}

References Botan::TLS::Ciphersuite::prf_algo().

◆ is_compatible_with()

bool Botan::TLS::Cipher_State::is_compatible_with ( const Ciphersuite & cipher) const
Returns
true if the selected cipher primitives are compatible with the cipher suite.

Note that cipher suites are considered "compatible" as long as the already selected cipher primitives in this cipher state are compatible.

Definition at line 328 of file tls_cipher_state.cpp.

328 {
329 if(!cipher.usable_in_version(Protocol_Version::TLS_V13)) {
330 return false;
331 }
332
333 if(hash_algorithm() != cipher.prf_algo()) {
334 return false;
335 }
336
337 BOTAN_ASSERT_NOMSG((m_encrypt == nullptr) == (m_decrypt == nullptr));
338 // TODO: Find a better way to check that the instantiated cipher algorithm
339 // is compatible with the one required by the cipher suite.
340 // AEAD_Mode::create() sets defaults the tag length to 16 which is then
341 // reported via AEAD_Mode::name() and hinders the trivial string comparison.
342 if(m_encrypt && m_encrypt->name() != cipher.cipher_algo() && m_encrypt->name() != cipher.cipher_algo() + "(16)") {
343 return false;
344 }
345
346 return true;
347}
std::string hash_algorithm() const

References BOTAN_ASSERT_NOMSG, Botan::TLS::Ciphersuite::cipher_algo(), hash_algorithm(), Botan::TLS::Ciphersuite::prf_algo(), and Botan::TLS::Ciphersuite::usable_in_version().

Referenced by advance_with_server_hello().

◆ minimum_decryption_input_length()

size_t Botan::TLS::Cipher_State::minimum_decryption_input_length ( ) const
Returns
the minimum ciphertext length for decryption

Definition at line 261 of file tls_cipher_state.cpp.

261 {
262 BOTAN_ASSERT_NONNULL(m_decrypt);
263 return m_decrypt->minimum_final_size();
264}

References BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::Record_Layer::next_record().

◆ must_expect_unprotected_alert_traffic()

bool Botan::TLS::Cipher_State::must_expect_unprotected_alert_traffic ( ) const

Indicates whether unprotected Alert records are to be expected

Definition at line 266 of file tls_cipher_state.cpp.

266 {
267 // Client side:
268 // After successfully receiving a Server Hello we expect servers to send
269 // alerts as protected records only, just like they start protecting their
270 // handshake data at this point.
271 if(m_connection_side == Connection_Side::Client && m_state == State::EarlyTraffic) {
272 return true;
273 }
274
275 // Server side:
276 // Servers must expect clients to send unprotected alerts during the hand-
277 // shake. In particular, in the response to the server's first protected
278 // flight. We don't expect the client to send alerts protected under the
279 // early traffic secret.
280 //
281 // TODO: when implementing PSK and/or early data for the server, we might
282 // need to reconsider this decision.
283 if(m_connection_side == Connection_Side::Server &&
284 (m_state == State::HandshakeTraffic || m_state == State::ServerApplicationTraffic)) {
285 return true;
286 }
287
288 return false;
289}

References Botan::TLS::Client, and Botan::TLS::Server.

Referenced by Botan::TLS::Record_Layer::next_record().

◆ next_ticket_nonce()

Ticket_Nonce Botan::TLS::Cipher_State::next_ticket_nonce ( )

Generates a nonce value that is unique for any given Cipher_State object. Note that the number of nonces is limited to 2^16 and this method will throw if more nonces are requested.

Definition at line 388 of file tls_cipher_state.cpp.

388 {
389 BOTAN_STATE_CHECK(m_state == State::Completed);
390 if(m_ticket_nonce == std::numeric_limits<decltype(m_ticket_nonce)>::max()) {
391 throw Botan::Invalid_State("ticket nonce pool exhausted");
392 }
393
394 Ticket_Nonce retval(std::vector<uint8_t>(sizeof(m_ticket_nonce)));
395 store_be(m_ticket_nonce++, retval.data());
396
397 return retval;
398}
Strong< std::vector< uint8_t >, struct Ticket_Nonce_ > Ticket_Nonce
Used to derive the ticket's PSK from the resumption_master_secret.
constexpr void store_be(T in, OutR &&out_range)
Definition loadstor.h:358

References BOTAN_STATE_CHECK, and Botan::store_be().

◆ psk()

secure_vector< uint8_t > Botan::TLS::Cipher_State::psk ( const Ticket_Nonce & nonce) const

Calculate the PSK for the given nonce (RFC 8446 4.6.1)

Definition at line 382 of file tls_cipher_state.cpp.

382 {
383 BOTAN_ASSERT_NOMSG(m_state == State::Completed);
384
385 return derive_secret(m_resumption_master_secret, "resumption", nonce.get());
386}

References BOTAN_ASSERT_NOMSG, and Botan::detail::Strong_Base< T >::get().

Referenced by init_with_psk().

◆ psk_binder_mac()

std::vector< uint8_t > Botan::TLS::Cipher_State::psk_binder_mac ( const Transcript_Hash & transcript_hash_with_truncated_client_hello) const

Calculates the MAC for a PSK binder value in Client Hellos. Note that the transcript hash passed into this method is computed from a partial Client Hello (RFC 8446 4.2.11.2)

Definition at line 349 of file tls_cipher_state.cpp.

350 {
351 BOTAN_ASSERT_NOMSG(m_state == State::PskBinder);
352
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();
357}

References BOTAN_ASSERT_NOMSG.

◆ update_read_keys()

void Botan::TLS::Cipher_State::update_read_keys ( )

Updates the key material used for decrypting data This is triggered after we received a Key_Update from the peer.

Note that this must not be called before the connection is ready for application traffic.

Definition at line 567 of file tls_cipher_state.cpp.

567 {
568 BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
569
570 m_read_application_traffic_secret =
571 hkdf_expand_label(m_read_application_traffic_secret, "traffic upd", {}, m_hash->output_length());
572
573 derive_read_traffic_key(m_read_application_traffic_secret);
574}

References BOTAN_ASSERT_NOMSG.

◆ update_write_keys()

void Botan::TLS::Cipher_State::update_write_keys ( )

Updates the key material used for encrypting data This is triggered after we send a Key_Update to the peer.

Note that this must not be called before the connection is ready for application traffic.

Definition at line 576 of file tls_cipher_state.cpp.

576 {
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());
580
581 derive_write_traffic_key(m_write_application_traffic_secret);
582}

References BOTAN_ASSERT_NOMSG.

◆ verify_peer_finished_mac()

bool Botan::TLS::Cipher_State::verify_peer_finished_mac ( const Transcript_Hash & transcript_hash,
const std::vector< uint8_t > & peer_mac ) const

Validate a MAC received in a TLS "Finished" handshake message (RFC 8446 4.4.4)

Definition at line 370 of file tls_cipher_state.cpp.

371 {
372 BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Server || m_state == State::ServerApplicationTraffic);
373 BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Client || m_state == State::HandshakeTraffic);
374 BOTAN_ASSERT_NOMSG(!m_peer_finished_key.empty());
375
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);
380}

References BOTAN_ASSERT_NOMSG, Botan::TLS::Client, and Botan::TLS::Server.

Referenced by Botan::TLS::Finished_13::verify().


The documentation for this class was generated from the following files: