Coverage Report

Created: 2022-11-24 06:56

/src/botan/build/include/botan/internal/tls_cipher_state.h
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
#ifndef BOTAN_TLS_CIPHER_STATE_H_
10
#define BOTAN_TLS_CIPHER_STATE_H_
11
12
#include <botan/secmem.h>
13
#include <botan/tls_magic.h>
14
15
#include <botan/internal/tls_transcript_hash_13.h>
16
17
namespace Botan {
18
19
class AEAD_Mode;
20
class HashFunction;
21
class HKDF_Extract;
22
class HKDF_Expand;
23
24
}
25
26
namespace Botan::TLS {
27
28
class Ciphersuite;
29
30
/**
31
 * This class implements the key schedule for TLS 1.3 as described in RFC 8446 7.1.
32
 *
33
 * Internally, it reflects the state machine pictured in the same RFC section.
34
 * It provides the following entry points and state advancement methods that
35
 * each facilitate certain cryptographic functionality:
36
 *
37
 * * init_with_psk()
38
 *   sets up the cipher state with a pre-shared key (out of band or via session
39
 *   ticket). will allow sending early data in the future
40
 *
41
 * * init_with_server_hello() / advance_with_server_hello()
42
 *   allows encrypting and decrypting handshake traffic, as well as producing
43
 *   and validating the client/server handshake finished MACs
44
 *
45
 * * advance_with_server_finished()
46
 *   allows encrypting and decrypting application traffic
47
 *
48
 * * advance_with_client_finished()
49
 *   allows negotiation of resumption PSKs
50
 *
51
 * While encrypting and decrypting records (RFC 8446 5.2) Cipher_State
52
 * internally keeps track of the current sequence numbers (RFC 8446 5.3) to
53
 * calculate the correct Per-Record Nonce. Sequence numbers are reset
54
 * appropriately, whenever traffic secrets change.
55
 *
56
 * Handshake finished MAC calculation and verification is described in RFC 8446 4.4.4.
57
 *
58
 * PSKs calculation is described in RFC 8446 4.6.1.
59
 */
60
class BOTAN_TEST_API Cipher_State
61
   {
62
   public:
63
      enum class PSK_Type
64
         {
65
         RESUMPTION,
66
         EXTERNAL
67
         };
68
69
   public:
70
      ~Cipher_State();
71
72
      /**
73
       * Construct a Cipher_State from a Pre-Shared-Key.
74
       */
75
      static std::unique_ptr<Cipher_State> init_with_psk(
76
         const Connection_Side side,
77
         const PSK_Type type,
78
         secure_vector<uint8_t>&& psk,
79
         const Ciphersuite& cipher);
80
81
      /**
82
       * Construct a Cipher_State after receiving a server hello message.
83
       */
84
      static std::unique_ptr<Cipher_State> init_with_server_hello(
85
         const Connection_Side side,
86
         secure_vector<uint8_t>&& shared_secret,
87
         const Ciphersuite& cipher,
88
         const Transcript_Hash& transcript_hash);
89
90
      /**
91
       * Transition internal secrets/keys for transporting early application data.
92
       * Note that this state transition is legal only for handshakes using PSK.
93
       */
94
      void advance_with_client_hello(const Transcript_Hash& transcript_hash);
95
96
      /**
97
       * Transition internal secrets/keys for transporting handshake data.
98
       */
99
      void advance_with_server_hello(const Ciphersuite& cipher,
100
                                     secure_vector<uint8_t>&& shared_secret,
101
                                     const Transcript_Hash& transcript_hash);
102
103
      /**
104
       * Transition internal secrets/keys for transporting application data.
105
       */
106
      void advance_with_server_finished(const Transcript_Hash& transcript_hash);
107
108
      /**
109
       * Transition to the final internal state allowing to create resumptions.
110
       */
111
      void advance_with_client_finished(const Transcript_Hash& transcript_hash);
112
113
      /**
114
       * Encrypt a TLS record fragment (RFC 8446 5.2 -- TLSInnerPlaintext) using the
115
       * currently available traffic secret keys and the current sequence number.
116
       * This will internally increment the sequence number. Hence, multiple
117
       * calls with the same input will not produce the same result.
118
       *
119
       * @returns  the sequence number of the encrypted record
120
       */
121
      uint64_t encrypt_record_fragment(const std::vector<uint8_t>& header, secure_vector<uint8_t>& fragment);
122
123
      /**
124
       * Decrypt a TLS record fragment (RFC 8446 5.2 -- TLSCiphertext.encrypted_record)
125
       * using the currently available traffic secret keys and the current sequence number.
126
       * This will internally increment the sequence number. Hence, multiple
127
       * calls with the same input will not produce the same result.
128
       *
129
       * @returns  the sequence number of the decrypted record
130
       */
131
      uint64_t decrypt_record_fragment(const std::vector<uint8_t>& header, secure_vector<uint8_t>& encrypted_fragment);
132
133
      /**
134
       * @returns  number of bytes needed to encrypt \p input_length bytes
135
       */
136
      size_t encrypt_output_length(const size_t input_length) const;
137
138
      /**
139
       * @returns  number of bytes needed to decrypt \p input_length bytes
140
       */
141
      size_t decrypt_output_length(const size_t input_length) const;
142
143
      /**
144
       * @returns  the minimum ciphertext length for decryption
145
       */
146
      size_t minimum_decryption_input_length() const;
147
148
      /**
149
       * Calculates the MAC for a PSK binder value in Client Hellos. Note that
150
       * the transcript hash passed into this method is computed from a partial
151
       * Client Hello (RFC 8446 4.2.11.2)
152
       */
153
      std::vector<uint8_t> psk_binder_mac(const Transcript_Hash& transcript_hash_with_truncated_client_hello);
154
155
      /**
156
       * Calculate the MAC for a TLS "Finished" handshake message (RFC 8446 4.4.4)
157
       */
158
      std::vector<uint8_t> finished_mac(const Transcript_Hash& transcript_hash) const;
159
160
      /**
161
       * Validate a MAC received in a TLS "Finished" handshake message (RFC 8446 4.4.4)
162
       */
163
      bool verify_peer_finished_mac(const Transcript_Hash& transcript_hash,
164
                                    const std::vector<uint8_t>& peer_mac) const;
165
166
      /**
167
       * Calculate the PSK for the given nonce (RFC 8446 4.6.1)
168
       */
169
      secure_vector<uint8_t> psk(const std::vector<uint8_t>& nonce) const;
170
171
      /**
172
       * Derive key material to export (RFC 8446 7.5 and RFC 5705)
173
       *
174
       * TODO: this does not yet support key export based on the `early_exporter_master_secret`.
175
       *
176
       * RFC 8446 7.5
177
       *    Implementations MUST use the exporter_master_secret unless explicitly
178
       *    specified by the application. The early_exporter_master_secret is
179
       *    defined for use in settings where an exporter is needed for 0-RTT data.
180
       *    A separate interface for the early exporter is RECOMMENDED [...].
181
       *
182
       * @param label     a disambiguating label string
183
       * @param context   a per-association context value
184
       * @param length    the length of the desired key in bytes
185
       * @return          key of length bytes
186
       */
187
      secure_vector<uint8_t> export_key(const std::string& label,
188
                                        const std::string& context,
189
                                        size_t length) const;
190
191
      /**
192
       * Indicates whether the appropriate secrets to export keys are available
193
       */
194
      bool can_export_keys() const
195
0
         {
196
0
         return (m_state == State::EarlyTraffic       ||
197
0
                 m_state == State::ApplicationTraffic ||
198
0
                 m_state == State::Completed) &&
199
0
                !m_exporter_master_secret.empty();
200
0
         }
201
202
      /**
203
       * Indicates whether the appropriate secrets to encrypt application traffic are available
204
       */
205
      bool can_encrypt_application_traffic() const
206
0
         {
207
0
         // TODO: when implementing early traffic (0-RTT) this will likely need
208
0
         //       to allow `State::EarlyTraffic`.
209
0
         return m_state != State::Uninitialized && m_state != State::HandshakeTraffic
210
0
                && !m_write_key.empty() && !m_write_iv.empty();
211
0
         }
212
213
      /**
214
       * @returns  true if the selected cipher primitives are compatible with
215
       *           the \p cipher suite.
216
       *
217
       * Note that cipher suites are considered "compatible" as long as the
218
       * already selected cipher primitives in this cipher state are compatible.
219
       */
220
      bool is_compatible_with(const Ciphersuite& cipher) const;
221
222
      /**
223
       * Updates the key material used for decrypting data
224
       * This is triggered after we received a Key_Update from the peer.
225
       *
226
       * Note that this must not be called before the connection is ready for
227
       * application traffic.
228
       */
229
      void update_read_keys();
230
231
      /**
232
       * Updates the key material used for encrypting data
233
       * This is triggered after we send a Key_Update to the peer.
234
       *
235
       * Note that this must not be called before the connection is ready for
236
       * application traffic.
237
       */
238
      void update_write_keys();
239
240
      /**
241
       * Remove handshake/traffic secrets for decrypting data from peer
242
       */
243
      void clear_read_keys();
244
245
      /**
246
       * Remove handshake/traffic secrets for encrypting data
247
       */
248
      void clear_write_keys();
249
250
   private:
251
      /**
252
       * @param hash_function  the negotiated hash function to be used
253
       * @param whoami         whether we play the SERVER or CLIENT
254
       */
255
      Cipher_State(Connection_Side whoami, const std::string& hash_function);
256
257
      void advance_with_psk(PSK_Type type, secure_vector<uint8_t>&& psk);
258
      void advance_without_psk();
259
260
      std::vector<uint8_t> current_nonce(const uint64_t seq_no,
261
                                         const secure_vector<uint8_t>& iv) const;
262
263
      void derive_write_traffic_key(const secure_vector<uint8_t>& traffic_secret,
264
                                    const bool handshake_traffic_secret = false);
265
      void derive_read_traffic_key(const secure_vector<uint8_t>& traffic_secret,
266
                                   const bool handshake_traffic_secret = false);
267
268
      /**
269
       * HKDF-Extract from RFC 8446 7.1
270
       */
271
      secure_vector<uint8_t> hkdf_extract(secure_vector<uint8_t>&& ikm) const;
272
273
      /**
274
       * HKDF-Expand-Label from RFC 8446 7.1
275
       */
276
      secure_vector<uint8_t> hkdf_expand_label(
277
         const secure_vector<uint8_t>& secret,
278
         const std::string&            label,
279
         const std::vector<uint8_t>&   context,
280
         const size_t                  length) const;
281
282
      /**
283
       * Derive-Secret from RFC 8446 7.1
284
       */
285
      secure_vector<uint8_t> derive_secret(
286
         const secure_vector<uint8_t>& secret,
287
         const std::string&            label,
288
         const Transcript_Hash&        messages_hash) const;
289
290
      std::vector<uint8_t> empty_hash() const;
291
292
   private:
293
      enum class State
294
         {
295
         Uninitialized,
296
         PskBinder,
297
         EarlyTraffic,
298
         HandshakeTraffic,
299
         ApplicationTraffic,
300
         Completed
301
         };
302
303
   private:
304
      State           m_state;
305
      Connection_Side m_connection_side;
306
307
      std::unique_ptr<AEAD_Mode> m_encrypt;
308
      std::unique_ptr<AEAD_Mode> m_decrypt;
309
310
      std::unique_ptr<HKDF_Extract> m_extract;
311
      std::unique_ptr<HKDF_Expand>  m_expand;
312
      std::unique_ptr<HashFunction> m_hash;
313
314
      secure_vector<uint8_t> m_salt;
315
316
      secure_vector<uint8_t> m_write_application_traffic_secret;
317
      secure_vector<uint8_t> m_read_application_traffic_secret;
318
319
      secure_vector<uint8_t> m_write_key;
320
      secure_vector<uint8_t> m_write_iv;
321
      secure_vector<uint8_t> m_read_key;
322
      secure_vector<uint8_t> m_read_iv;
323
324
      uint64_t m_write_seq_no;
325
      uint64_t m_read_seq_no;
326
327
      secure_vector<uint8_t> m_finished_key;
328
      secure_vector<uint8_t> m_peer_finished_key;
329
      secure_vector<uint8_t> m_exporter_master_secret;
330
      secure_vector<uint8_t> m_resumption_master_secret;
331
332
      secure_vector<uint8_t> m_early_secret;
333
      secure_vector<uint8_t> m_binder_key;
334
   };
335
336
}
337
338
#endif // BOTAN_TLS_CIPHER_STATE_H_