Coverage Report

Created: 2025-04-11 06:34

/src/botan/src/lib/tls/tls13/tls_cipher_state.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* TLS cipher state implementation for TLS 1.3
3
* (C) 2022 Jack Lloyd
4
*     2022 Hannes Rantzsch, René Meusel - neXenio GmbH
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8
9
/**
10
 * Cipher_State state machine adapted from RFC 8446 7.1.
11
 *
12
 *                                     0
13
 *                                     |
14
 *                                     v
15
 *                           PSK ->  HKDF-Extract = Early Secret
16
 *                                     |
17
 *                                     +-----> Derive-Secret(., "ext binder" | "res binder", "")
18
 *                                     |                     = binder_key
19
 *                              STATE PSK BINDER
20
 * This state is reached by constructing the Cipher_State using init_with_psk().
21
 * The state can then be further advanced using advance_with_client_hello() once
22
 * the initial Client Hello is fully generated.
23
 *                                     |
24
 *                                     +-----> Derive-Secret(., "c e traffic", ClientHello)
25
 *                                     |                     = client_early_traffic_secret
26
 *                                     |
27
 *                                     +-----> Derive-Secret(., "e exp master", ClientHello)
28
 *                                     |                     = early_exporter_master_secret
29
 *                                     v
30
 *                               Derive-Secret(., "derived", "")
31
 *                                     |
32
 *                                     *
33
 *                             STATE EARLY TRAFFIC
34
 * This state is reached by calling advance_with_client_hello().
35
 * In this state the early data traffic secrets are available. TODO: implement early data.
36
 * The state can then be further advanced using advance_with_server_hello().
37
 *                                     *
38
 *                                     |
39
 *                                     v
40
 *                           (EC)DHE -> HKDF-Extract = Handshake Secret
41
 *                                     |
42
 *                                     +-----> Derive-Secret(., "c hs traffic",
43
 *                                     |                     ClientHello...ServerHello)
44
 *                                     |                     = client_handshake_traffic_secret
45
 *                                     |
46
 *                                     +-----> Derive-Secret(., "s hs traffic",
47
 *                                     |                     ClientHello...ServerHello)
48
 *                                     |                     = server_handshake_traffic_secret
49
 *                                     v
50
 *                               Derive-Secret(., "derived", "")
51
 *                                     |
52
 *                                     *
53
 *                          STATE HANDSHAKE TRAFFIC
54
 * This state is reached by constructing Cipher_State using init_with_server_hello() or
55
 * advance_with_server_hello(). In this state the handshake traffic secrets are available.
56
 * The state can then be further advanced using advance_with_server_finished().
57
 *                                     *
58
 *                                     |
59
 *                                     v
60
 *                           0 -> HKDF-Extract = Master Secret
61
 *                                     |
62
 *                                     +-----> Derive-Secret(., "c ap traffic",
63
 *                                     |                     ClientHello...server Finished)
64
 *                                     |                     = client_application_traffic_secret_0
65
 *                                     |
66
 *                                     +-----> Derive-Secret(., "s ap traffic",
67
 *                                     |                     ClientHello...server Finished)
68
 *                                     |                     = server_application_traffic_secret_0
69
 *                                     |
70
 *                                     +-----> Derive-Secret(., "exp master",
71
 *                                     |                     ClientHello...server Finished)
72
 *                                     |                     = exporter_master_secret
73
 *                                     *
74
 *                      STATE SERVER APPLICATION TRAFFIC
75
 * This state is reached by calling advance_with_server_finished(). It allows the server
76
 * to send application traffic and the client to receive it. The opposite direction is not
77
 * yet possible in this state. The state can then be further advanced using
78
 * advance_with_client_finished().
79
 *                                     *
80
 *                                     |
81
 *                                     +-----> Derive-Secret(., "res master",
82
 *                                                           ClientHello...client Finished)
83
 *                                                           = resumption_master_secret
84
 *                             STATE COMPLETED
85
 * Once this state is reached the handshake is finished, both client and server can exchange
86
 * application data and no further cipher state advances are possible.
87
 */
88
89
#include <limits>
90
#include <utility>
91
92
#include <botan/internal/tls_cipher_state.h>
93
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>
100
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>
106
107
namespace Botan::TLS {
108
109
namespace {
110
// RFC 8446 5.3
111
//    Each AEAD algorithm will specify a range of possible lengths for the
112
//    per-record nonce, from N_MIN bytes to N_MAX bytes of input [RFC5116].
113
//    The length of the TLS per-record nonce (iv_length) is set to the
114
//    larger of 8 bytes and N_MIN for the AEAD algorithm (see [RFC5116],
115
//    Section 4).
116
//
117
// N_MIN is 12 for AES_GCM and AES_CCM as per RFC 5116 and also 12 for ChaCha20 per RFC 8439.
118
constexpr size_t NONCE_LENGTH = 12;
119
}  // namespace
120
121
std::unique_ptr<Cipher_State> Cipher_State::init_with_server_hello(const Connection_Side side,
122
                                                                   secure_vector<uint8_t>&& shared_secret,
123
                                                                   const Ciphersuite& cipher,
124
                                                                   const Transcript_Hash& transcript_hash,
125
0
                                                                   const Secret_Logger& loggger) {
126
0
   auto cs = std::unique_ptr<Cipher_State>(new Cipher_State(side, cipher.prf_algo()));
127
0
   cs->advance_without_psk();
128
0
   cs->advance_with_server_hello(cipher, std::move(shared_secret), transcript_hash, loggger);
129
0
   return cs;
130
0
}
131
132
std::unique_ptr<Cipher_State> Cipher_State::init_with_psk(const Connection_Side side,
133
                                                          const Cipher_State::PSK_Type type,
134
                                                          secure_vector<uint8_t>&& psk,
135
0
                                                          std::string_view prf_algo) {
136
0
   auto cs = std::unique_ptr<Cipher_State>(new Cipher_State(side, prf_algo));
137
0
   cs->advance_with_psk(type, std::move(psk));
138
0
   return cs;
139
0
}
140
141
0
void Cipher_State::advance_with_client_hello(const Transcript_Hash& transcript_hash, const Secret_Logger& loggger) {
142
0
   BOTAN_ASSERT_NOMSG(m_state == State::PskBinder);
143
144
0
   zap(m_binder_key);
145
146
   // TODO: Currently 0-RTT is not yet implemented, hence we don't derive the
147
   //       early traffic secret for now.
148
   //
149
   // const auto client_early_traffic_secret = derive_secret(m_early_secret, "c e traffic", transcript_hash);
150
   // derive_write_traffic_key(client_early_traffic_secret);
151
152
0
   m_exporter_master_secret = derive_secret(m_early_secret, "e exp master", transcript_hash);
153
154
   // draft-thomson-tls-keylogfile-00 Section 3.1
155
   //    An implementation of TLS 1.3 use the label
156
   //    "EARLY_EXPORTER_MASTER_SECRET" to identify the secret that is using for
157
   //    early exporters
158
0
   loggger.maybe_log_secret("EARLY_EXPORTER_MASTER_SECRET", m_exporter_master_secret);
159
160
0
   m_salt = derive_secret(m_early_secret, "derived", empty_hash());
161
0
   zap(m_early_secret);
162
163
0
   m_state = State::EarlyTraffic;
164
0
}
165
166
0
void Cipher_State::advance_with_server_finished(const Transcript_Hash& transcript_hash, const Secret_Logger& loggger) {
167
0
   BOTAN_ASSERT_NOMSG(m_state == State::HandshakeTraffic);
168
169
0
   const auto master_secret = hkdf_extract(secure_vector<uint8_t>(m_hash->output_length(), 0x00));
170
171
0
   auto client_application_traffic_secret = derive_secret(master_secret, "c ap traffic", transcript_hash);
172
0
   auto server_application_traffic_secret = derive_secret(master_secret, "s ap traffic", transcript_hash);
173
174
   // draft-thomson-tls-keylogfile-00 Section 3.1
175
   //    An implementation of TLS 1.3 use the label "CLIENT_TRAFFIC_SECRET_0"
176
   //    and "SERVER_TRAFFIC_SECRET_0" to identify the secrets are using to
177
   //    protect the connection.
178
0
   loggger.maybe_log_secret("CLIENT_TRAFFIC_SECRET_0", client_application_traffic_secret);
179
0
   loggger.maybe_log_secret("SERVER_TRAFFIC_SECRET_0", server_application_traffic_secret);
180
181
   // Note: the secrets for processing client's application data
182
   //       are not derived before the client's Finished message
183
   //       was seen and the handshake can be considered finished.
184
0
   if(m_connection_side == Connection_Side::Server) {
185
0
      derive_write_traffic_key(server_application_traffic_secret);
186
0
      m_read_application_traffic_secret = std::move(client_application_traffic_secret);
187
0
      m_write_application_traffic_secret = std::move(server_application_traffic_secret);
188
0
   } else {
189
0
      derive_read_traffic_key(server_application_traffic_secret);
190
0
      m_read_application_traffic_secret = std::move(server_application_traffic_secret);
191
0
      m_write_application_traffic_secret = std::move(client_application_traffic_secret);
192
0
   }
193
194
0
   m_exporter_master_secret = derive_secret(master_secret, "exp master", transcript_hash);
195
196
   // draft-thomson-tls-keylogfile-00 Section 3.1
197
   //    An implementation of TLS 1.3 use the label "EXPORTER_SECRET" to
198
   //    identify the secret that is used in generating exporters(rfc8446
199
   //    Section 7.5).
200
0
   loggger.maybe_log_secret("EXPORTER_SECRET", m_exporter_master_secret);
201
202
0
   m_state = State::ServerApplicationTraffic;
203
0
}
204
205
0
void Cipher_State::advance_with_client_finished(const Transcript_Hash& transcript_hash) {
206
0
   BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic);
207
208
0
   zap(m_finished_key);
209
0
   zap(m_peer_finished_key);
210
211
   // With the client's Finished message, the handshake is complete and
212
   // we can process client application data.
213
0
   if(m_connection_side == Connection_Side::Server) {
214
0
      derive_read_traffic_key(m_read_application_traffic_secret);
215
0
   } else {
216
0
      derive_write_traffic_key(m_write_application_traffic_secret);
217
0
   }
218
219
0
   const auto master_secret = hkdf_extract(secure_vector<uint8_t>(m_hash->output_length(), 0x00));
220
221
0
   m_resumption_master_secret = derive_secret(master_secret, "res master", transcript_hash);
222
223
   // This was the final state change; the salt is no longer needed.
224
0
   zap(m_salt);
225
226
0
   m_state = State::Completed;
227
0
}
228
229
namespace {
230
231
0
auto current_nonce(const uint64_t seq_no, std::span<const uint8_t> iv) {
232
   // RFC 8446 5.3
233
   //    The per-record nonce for the AEAD construction is formed as follows:
234
   //
235
   //    1.  The 64-bit record sequence number is encoded in network byte
236
   //        order and padded to the left with zeros to iv_length.
237
   //
238
   //    2.  The padded sequence number is XORed with either the static
239
   //        client_write_iv or server_write_iv (depending on the role).
240
0
   std::array<uint8_t, NONCE_LENGTH> nonce{};
241
0
   store_be(std::span{nonce}.last<sizeof(seq_no)>(), seq_no);
242
0
   xor_buf(nonce, iv);
243
0
   return nonce;
244
0
}
245
246
}  // namespace
247
248
0
uint64_t Cipher_State::encrypt_record_fragment(const std::vector<uint8_t>& header, secure_vector<uint8_t>& fragment) {
249
0
   BOTAN_ASSERT_NONNULL(m_encrypt);
250
251
0
   m_encrypt->set_key(m_write_key);
252
0
   m_encrypt->set_associated_data(header);
253
0
   m_encrypt->start(current_nonce(m_write_seq_no, m_write_iv));
254
0
   m_encrypt->finish(fragment);
255
256
0
   return m_write_seq_no++;
257
0
}
258
259
uint64_t Cipher_State::decrypt_record_fragment(const std::vector<uint8_t>& header,
260
0
                                               secure_vector<uint8_t>& encrypted_fragment) {
261
0
   BOTAN_ASSERT_NONNULL(m_decrypt);
262
0
   BOTAN_ARG_CHECK(encrypted_fragment.size() >= m_decrypt->minimum_final_size(), "fragment too short to decrypt");
263
264
0
   m_decrypt->set_key(m_read_key);
265
0
   m_decrypt->set_associated_data(header);
266
0
   m_decrypt->start(current_nonce(m_read_seq_no, m_read_iv));
267
268
0
   m_decrypt->finish(encrypted_fragment);
269
270
0
   return m_read_seq_no++;
271
0
}
272
273
0
size_t Cipher_State::encrypt_output_length(const size_t input_length) const {
274
0
   BOTAN_ASSERT_NONNULL(m_encrypt);
275
0
   return m_encrypt->output_length(input_length);
276
0
}
277
278
0
size_t Cipher_State::decrypt_output_length(const size_t input_length) const {
279
0
   BOTAN_ASSERT_NONNULL(m_decrypt);
280
0
   return m_decrypt->output_length(input_length);
281
0
}
282
283
0
size_t Cipher_State::minimum_decryption_input_length() const {
284
0
   BOTAN_ASSERT_NONNULL(m_decrypt);
285
0
   return m_decrypt->minimum_final_size();
286
0
}
287
288
0
bool Cipher_State::must_expect_unprotected_alert_traffic() const {
289
   // Client side:
290
   //   After successfully receiving a Server Hello we expect servers to send
291
   //   alerts as protected records only, just like they start protecting their
292
   //   handshake data at this point.
293
0
   if(m_connection_side == Connection_Side::Client && m_state == State::EarlyTraffic) {
294
0
      return true;
295
0
   }
296
297
   // Server side:
298
   //   Servers must expect clients to send unprotected alerts during the hand-
299
   //   shake. In particular, in the response to the server's first protected
300
   //   flight. We don't expect the client to send alerts protected under the
301
   //   early traffic secret.
302
   //
303
   // TODO: when implementing PSK and/or early data for the server, we might
304
   //       need to reconsider this decision.
305
0
   if(m_connection_side == Connection_Side::Server &&
306
0
      (m_state == State::HandshakeTraffic || m_state == State::ServerApplicationTraffic)) {
307
0
      return true;
308
0
   }
309
310
0
   return false;
311
0
}
312
313
0
bool Cipher_State::can_encrypt_application_traffic() const {
314
   // TODO: when implementing early traffic (0-RTT) this will likely need
315
   //       to allow `State::EarlyTraffic`.
316
317
0
   if(m_connection_side == Connection_Side::Client && m_state != State::Completed) {
318
0
      return false;
319
0
   }
320
321
0
   if(m_connection_side == Connection_Side::Server && m_state != State::ServerApplicationTraffic &&
322
0
      m_state != State::Completed) {
323
0
      return false;
324
0
   }
325
326
0
   return !m_write_key.empty() && !m_write_iv.empty();
327
0
}
328
329
0
bool Cipher_State::can_decrypt_application_traffic() const {
330
   // TODO: when implementing early traffic (0-RTT) this will likely need
331
   //       to allow `State::EarlyTraffic`.
332
333
0
   if(m_connection_side == Connection_Side::Client && m_state != State::ServerApplicationTraffic &&
334
0
      m_state != State::Completed) {
335
0
      return false;
336
0
   }
337
338
0
   if(m_connection_side == Connection_Side::Server && m_state != State::Completed) {
339
0
      return false;
340
0
   }
341
342
0
   return !m_read_key.empty() && !m_read_iv.empty();
343
0
}
344
345
0
std::string Cipher_State::hash_algorithm() const {
346
0
   BOTAN_ASSERT_NONNULL(m_hash);
347
0
   return m_hash->name();
348
0
}
349
350
0
bool Cipher_State::is_compatible_with(const Ciphersuite& cipher) const {
351
0
   if(!cipher.usable_in_version(Protocol_Version::TLS_V13)) {
352
0
      return false;
353
0
   }
354
355
0
   if(hash_algorithm() != cipher.prf_algo()) {
356
0
      return false;
357
0
   }
358
359
0
   BOTAN_ASSERT_NOMSG((m_encrypt == nullptr) == (m_decrypt == nullptr));
360
   // TODO: Find a better way to check that the instantiated cipher algorithm
361
   //       is compatible with the one required by the cipher suite.
362
   // AEAD_Mode::create() sets defaults the tag length to 16 which is then
363
   // reported via AEAD_Mode::name() and hinders the trivial string comparison.
364
0
   if(m_encrypt && m_encrypt->name() != cipher.cipher_algo() && m_encrypt->name() != cipher.cipher_algo() + "(16)") {
365
0
      return false;
366
0
   }
367
368
0
   return true;
369
0
}
370
371
std::vector<uint8_t> Cipher_State::psk_binder_mac(
372
0
   const Transcript_Hash& transcript_hash_with_truncated_client_hello) const {
373
0
   BOTAN_ASSERT_NOMSG(m_state == State::PskBinder);
374
375
0
   auto hmac = HMAC(m_hash->new_object());
376
0
   hmac.set_key(m_binder_key);
377
0
   hmac.update(transcript_hash_with_truncated_client_hello);
378
0
   return hmac.final_stdvec();
379
0
}
380
381
0
std::vector<uint8_t> Cipher_State::finished_mac(const Transcript_Hash& transcript_hash) const {
382
0
   BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Server || m_state == State::HandshakeTraffic);
383
0
   BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Client || m_state == State::ServerApplicationTraffic);
384
0
   BOTAN_ASSERT_NOMSG(!m_finished_key.empty());
385
386
0
   auto hmac = HMAC(m_hash->new_object());
387
0
   hmac.set_key(m_finished_key);
388
0
   hmac.update(transcript_hash);
389
0
   return hmac.final_stdvec();
390
0
}
391
392
bool Cipher_State::verify_peer_finished_mac(const Transcript_Hash& transcript_hash,
393
0
                                            const std::vector<uint8_t>& peer_mac) const {
394
0
   BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Server || m_state == State::ServerApplicationTraffic);
395
0
   BOTAN_ASSERT_NOMSG(m_connection_side != Connection_Side::Client || m_state == State::HandshakeTraffic);
396
0
   BOTAN_ASSERT_NOMSG(!m_peer_finished_key.empty());
397
398
0
   auto hmac = HMAC(m_hash->new_object());
399
0
   hmac.set_key(m_peer_finished_key);
400
0
   hmac.update(transcript_hash);
401
0
   return hmac.verify_mac(peer_mac);
402
0
}
403
404
0
secure_vector<uint8_t> Cipher_State::psk(const Ticket_Nonce& nonce) const {
405
0
   BOTAN_ASSERT_NOMSG(m_state == State::Completed);
406
407
0
   return derive_secret(m_resumption_master_secret, "resumption", nonce.get());
408
0
}
409
410
0
Ticket_Nonce Cipher_State::next_ticket_nonce() {
411
0
   BOTAN_STATE_CHECK(m_state == State::Completed);
412
0
   if(m_ticket_nonce == std::numeric_limits<decltype(m_ticket_nonce)>::max()) {
413
0
      throw Botan::Invalid_State("ticket nonce pool exhausted");
414
0
   }
415
416
0
   Ticket_Nonce retval(std::vector<uint8_t>(sizeof(m_ticket_nonce)));
417
0
   store_be(m_ticket_nonce++, retval.data());
418
419
0
   return retval;
420
0
}
421
422
0
secure_vector<uint8_t> Cipher_State::export_key(std::string_view label, std::string_view context, size_t length) const {
423
0
   BOTAN_ASSERT_NOMSG(can_export_keys());
424
425
0
   m_hash->update(context);
426
0
   const auto context_hash = m_hash->final_stdvec();
427
0
   return hkdf_expand_label(
428
0
      derive_secret(m_exporter_master_secret, label, empty_hash()), "exporter", context_hash, length);
429
0
}
430
431
namespace {
432
433
0
std::unique_ptr<MessageAuthenticationCode> create_hmac(std::string_view hash) {
434
0
   return std::make_unique<HMAC>(HashFunction::create_or_throw(hash));
435
0
}
436
437
}  // namespace
438
439
Cipher_State::Cipher_State(Connection_Side whoami, std::string_view hash_function) :
440
0
      m_state(State::Uninitialized),
441
0
      m_connection_side(whoami),
442
0
      m_extract(std::make_unique<HKDF_Extract>(create_hmac(hash_function))),
443
0
      m_expand(std::make_unique<HKDF_Expand>(create_hmac(hash_function))),
444
0
      m_hash(HashFunction::create_or_throw(hash_function)),
445
0
      m_salt(m_hash->output_length(), 0x00),
446
0
      m_write_seq_no(0),
447
0
      m_read_seq_no(0),
448
0
      m_write_key_update_count(0),
449
0
      m_read_key_update_count(0),
450
0
      m_ticket_nonce(0) {}
451
452
0
Cipher_State::~Cipher_State() = default;
453
454
0
void Cipher_State::advance_without_psk() {
455
0
   BOTAN_ASSERT_NOMSG(m_state == State::Uninitialized);
456
457
   // We are not using `m_early_secret` here because the secret won't be needed
458
   // in any further state advancement methods.
459
0
   const auto early_secret = hkdf_extract(secure_vector<uint8_t>(m_hash->output_length(), 0x00));
460
0
   m_salt = derive_secret(early_secret, "derived", empty_hash());
461
462
   // Without PSK we skip the `PskBinder` state and go right to `EarlyTraffic`.
463
0
   m_state = State::EarlyTraffic;
464
0
}
465
466
0
void Cipher_State::advance_with_psk(PSK_Type type, secure_vector<uint8_t>&& psk) {
467
0
   BOTAN_ASSERT_NOMSG(m_state == State::Uninitialized);
468
469
0
   m_early_secret = hkdf_extract(std::move(psk));
470
471
0
   const char* binder_label = (type == PSK_Type::Resumption) ? "res binder" : "ext binder";
472
473
   // RFC 8446 4.2.11.2
474
   //    The PskBinderEntry is computed in the same way as the Finished message
475
   //    [...] but with the BaseKey being the binder_key derived via the key
476
   //    schedule from the corresponding PSK which is being offered.
477
   //
478
   // Hence we are doing the binder key derivation and expansion in one go.
479
0
   const auto binder_key = derive_secret(m_early_secret, binder_label, empty_hash());
480
0
   m_binder_key = hkdf_expand_label(binder_key, "finished", {}, m_hash->output_length());
481
482
0
   m_state = State::PskBinder;
483
0
}
484
485
void Cipher_State::advance_with_server_hello(const Ciphersuite& cipher,
486
                                             secure_vector<uint8_t>&& shared_secret,
487
                                             const Transcript_Hash& transcript_hash,
488
0
                                             const Secret_Logger& loggger) {
489
0
   BOTAN_ASSERT_NOMSG(m_state == State::EarlyTraffic);
490
0
   BOTAN_ASSERT_NOMSG(!m_encrypt);
491
0
   BOTAN_ASSERT_NOMSG(!m_decrypt);
492
0
   BOTAN_STATE_CHECK(is_compatible_with(cipher));
493
494
0
   m_encrypt = AEAD_Mode::create_or_throw(cipher.cipher_algo(), Cipher_Dir::Encryption);
495
0
   m_decrypt = AEAD_Mode::create_or_throw(cipher.cipher_algo(), Cipher_Dir::Decryption);
496
497
0
   const auto handshake_secret = hkdf_extract(std::move(shared_secret));
498
499
0
   const auto client_handshake_traffic_secret = derive_secret(handshake_secret, "c hs traffic", transcript_hash);
500
0
   const auto server_handshake_traffic_secret = derive_secret(handshake_secret, "s hs traffic", transcript_hash);
501
502
   // draft-thomson-tls-keylogfile-00 Section 3.1
503
   //    An implementation of TLS 1.3 use the label
504
   //    "CLIENT_HANDSHAKE_TRAFFIC_SECRET" and "SERVER_HANDSHAKE_TRAFFIC_SECRET"
505
   //    to identify the secrets are using to protect handshake messages.
506
0
   loggger.maybe_log_secret("CLIENT_HANDSHAKE_TRAFFIC_SECRET", client_handshake_traffic_secret);
507
0
   loggger.maybe_log_secret("SERVER_HANDSHAKE_TRAFFIC_SECRET", server_handshake_traffic_secret);
508
509
0
   if(m_connection_side == Connection_Side::Server) {
510
0
      derive_read_traffic_key(client_handshake_traffic_secret, true);
511
0
      derive_write_traffic_key(server_handshake_traffic_secret, true);
512
0
   } else {
513
0
      derive_read_traffic_key(server_handshake_traffic_secret, true);
514
0
      derive_write_traffic_key(client_handshake_traffic_secret, true);
515
0
   }
516
517
0
   m_salt = derive_secret(handshake_secret, "derived", empty_hash());
518
519
0
   m_state = State::HandshakeTraffic;
520
0
}
521
522
void Cipher_State::derive_write_traffic_key(const secure_vector<uint8_t>& traffic_secret,
523
0
                                            const bool handshake_traffic_secret) {
524
0
   BOTAN_ASSERT_NONNULL(m_encrypt);
525
526
0
   m_write_key = hkdf_expand_label(traffic_secret, "key", {}, m_encrypt->minimum_keylength());
527
0
   m_write_iv = hkdf_expand_label(traffic_secret, "iv", {}, NONCE_LENGTH);
528
0
   m_write_seq_no = 0;
529
530
0
   if(handshake_traffic_secret) {
531
      // Key derivation for the MAC in the "Finished" handshake message as described in RFC 8446 4.4.4
532
      // (will be cleared in advance_with_server_finished())
533
0
      m_finished_key = hkdf_expand_label(traffic_secret, "finished", {}, m_hash->output_length());
534
0
   }
535
0
}
536
537
void Cipher_State::derive_read_traffic_key(const secure_vector<uint8_t>& traffic_secret,
538
0
                                           const bool handshake_traffic_secret) {
539
0
   BOTAN_ASSERT_NONNULL(m_encrypt);
540
541
0
   m_read_key = hkdf_expand_label(traffic_secret, "key", {}, m_encrypt->minimum_keylength());
542
0
   m_read_iv = hkdf_expand_label(traffic_secret, "iv", {}, NONCE_LENGTH);
543
0
   m_read_seq_no = 0;
544
545
0
   if(handshake_traffic_secret) {
546
      // Key derivation for the MAC in the "Finished" handshake message as described in RFC 8446 4.4.4
547
      // (will be cleared in advance_with_client_finished())
548
0
      m_peer_finished_key = hkdf_expand_label(traffic_secret, "finished", {}, m_hash->output_length());
549
0
   }
550
0
}
551
552
0
secure_vector<uint8_t> Cipher_State::hkdf_extract(std::span<const uint8_t> ikm) const {
553
0
   return m_extract->derive_key(m_hash->output_length(), ikm, m_salt, std::vector<uint8_t>());
554
0
}
555
556
secure_vector<uint8_t> Cipher_State::hkdf_expand_label(const secure_vector<uint8_t>& secret,
557
                                                       std::string_view label,
558
                                                       const std::vector<uint8_t>& context,
559
0
                                                       const size_t length) const {
560
   // assemble (serialized) HkdfLabel
561
0
   secure_vector<uint8_t> hkdf_label;
562
0
   hkdf_label.reserve(2 /* length */ + (label.size() + 6 /* 'tls13 ' */ + 1 /* length field*/) +
563
0
                      (context.size() + 1 /* length field*/));
564
565
   // length
566
0
   BOTAN_ARG_CHECK(length <= std::numeric_limits<uint16_t>::max(), "invalid length");
567
0
   const auto len = static_cast<uint16_t>(length);
568
0
   hkdf_label.push_back(get_byte<0>(len));
569
0
   hkdf_label.push_back(get_byte<1>(len));
570
571
   // label
572
0
   const std::string prefix = "tls13 ";
573
0
   BOTAN_ARG_CHECK(prefix.size() + label.size() <= 255, "label too large");
574
0
   hkdf_label.push_back(static_cast<uint8_t>(prefix.size() + label.size()));
575
0
   hkdf_label.insert(hkdf_label.end(), prefix.cbegin(), prefix.cend());
576
0
   hkdf_label.insert(hkdf_label.end(), label.cbegin(), label.cend());
577
578
   // context
579
0
   BOTAN_ARG_CHECK(context.size() <= 255, "context too large");
580
0
   hkdf_label.push_back(static_cast<uint8_t>(context.size()));
581
0
   hkdf_label.insert(hkdf_label.end(), context.cbegin(), context.cend());
582
583
   // HKDF-Expand
584
0
   return m_expand->derive_key(
585
0
      length, secret, hkdf_label, std::vector<uint8_t>() /* just pleasing botan's interface */);
586
0
}
587
588
secure_vector<uint8_t> Cipher_State::derive_secret(const secure_vector<uint8_t>& secret,
589
                                                   std::string_view label,
590
0
                                                   const Transcript_Hash& messages_hash) const {
591
0
   return hkdf_expand_label(secret, label, messages_hash, m_hash->output_length());
592
0
}
593
594
0
std::vector<uint8_t> Cipher_State::empty_hash() const {
595
0
   m_hash->update("");
596
0
   return m_hash->final_stdvec();
597
0
}
598
599
0
void Cipher_State::update_read_keys(const Secret_Logger& logger) {
600
0
   BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
601
602
0
   m_read_application_traffic_secret =
603
0
      hkdf_expand_label(m_read_application_traffic_secret, "traffic upd", {}, m_hash->output_length());
604
605
0
   const auto secret_label = fmt("{}_TRAFFIC_SECRET_{}",
606
0
                                 m_connection_side == Connection_Side::Server ? "CLIENT" : "SERVER",
607
0
                                 ++m_read_key_update_count);
608
0
   logger.maybe_log_secret(secret_label, m_read_application_traffic_secret);
609
610
0
   derive_read_traffic_key(m_read_application_traffic_secret);
611
0
}
612
613
0
void Cipher_State::update_write_keys(const Secret_Logger& logger) {
614
0
   BOTAN_ASSERT_NOMSG(m_state == State::ServerApplicationTraffic || m_state == State::Completed);
615
0
   m_write_application_traffic_secret =
616
0
      hkdf_expand_label(m_write_application_traffic_secret, "traffic upd", {}, m_hash->output_length());
617
618
0
   const auto secret_label = fmt("{}_TRAFFIC_SECRET_{}",
619
0
                                 m_connection_side == Connection_Side::Server ? "SERVER" : "CLIENT",
620
0
                                 ++m_write_key_update_count);
621
0
   logger.maybe_log_secret(secret_label, m_write_application_traffic_secret);
622
623
0
   derive_write_traffic_key(m_write_application_traffic_secret);
624
0
}
625
626
0
void Cipher_State::clear_read_keys() {
627
0
   zap(m_read_key);
628
0
   zap(m_read_iv);
629
0
   zap(m_read_application_traffic_secret);
630
0
}
631
632
0
void Cipher_State::clear_write_keys() {
633
0
   zap(m_write_key);
634
0
   zap(m_write_iv);
635
0
   zap(m_write_application_traffic_secret);
636
0
}
637
638
}  // namespace Botan::TLS