Coverage Report

Created: 2022-06-23 06:44

/src/botan/build/include/botan/internal/tls_record.h
Line
Count
Source
1
/*
2
* TLS Record Handling
3
* (C) 2004-2012 Jack Lloyd
4
*     2016 Matthias Gierlings
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8
9
#ifndef BOTAN_TLS_RECORDS_H_
10
#define BOTAN_TLS_RECORDS_H_
11
12
#include <botan/tls_algos.h>
13
#include <botan/tls_magic.h>
14
#include <botan/tls_version.h>
15
#include <botan/aead.h>
16
#include <vector>
17
#include <chrono>
18
#include <functional>
19
20
namespace Botan {
21
22
namespace TLS {
23
24
class Callbacks;
25
class Ciphersuite;
26
class Session_Keys;
27
28
class Connection_Sequence_Numbers;
29
30
/**
31
* TLS Cipher State
32
*/
33
class Connection_Cipher_State final
34
   {
35
   public:
36
      /**
37
      * Initialize a new cipher state
38
      */
39
      Connection_Cipher_State(Protocol_Version version,
40
                              Connection_Side which_side,
41
                              bool is_our_side,
42
                              const Ciphersuite& suite,
43
                              const Session_Keys& keys,
44
                              bool uses_encrypt_then_mac);
45
46
      AEAD_Mode& aead()
47
772
         {
48
772
         BOTAN_ASSERT_NONNULL(m_aead.get());
49
772
         return *m_aead.get();
50
772
         }
51
52
      std::vector<uint8_t> aead_nonce(uint64_t seq, RandomNumberGenerator& rng);
53
54
      std::vector<uint8_t> aead_nonce(const uint8_t record[], size_t record_len, uint64_t seq);
55
56
      std::vector<uint8_t> format_ad(uint64_t seq, uint8_t type,
57
                                  Protocol_Version version,
58
                                  uint16_t ptext_length);
59
60
355
      size_t nonce_bytes_from_handshake() const { return m_nonce_bytes_from_handshake; }
61
2.23k
      size_t nonce_bytes_from_record() const { return m_nonce_bytes_from_record; }
62
63
1.16k
      Nonce_Format nonce_format() const { return m_nonce_format; }
64
65
   private:
66
      std::chrono::system_clock::time_point m_start_time;
67
      std::unique_ptr<AEAD_Mode> m_aead;
68
69
      std::vector<uint8_t> m_nonce;
70
      Nonce_Format m_nonce_format;
71
      size_t m_nonce_bytes_from_handshake;
72
      size_t m_nonce_bytes_from_record;
73
   };
74
75
class Record_Header final
76
   {
77
   public:
78
      Record_Header(uint64_t sequence,
79
                    Protocol_Version version,
80
                    Record_Type type) :
81
         m_needed(0),
82
         m_sequence(sequence),
83
         m_version(version),
84
         m_type(type)
85
67.0k
         {}
86
87
      Record_Header(size_t needed) :
88
         m_needed(needed),
89
         m_sequence(0),
90
         m_version(Protocol_Version()),
91
         m_type(NO_RECORD)
92
713
         {}
93
94
67.8k
      size_t needed() const { return m_needed; }
95
96
      Protocol_Version version() const
97
83.7k
         {
98
83.7k
         BOTAN_ASSERT_NOMSG(m_needed == 0);
99
83.7k
         return m_version;
100
83.7k
         }
101
102
      uint64_t sequence() const
103
46.2k
         {
104
46.2k
         BOTAN_ASSERT_NOMSG(m_needed == 0);
105
46.2k
         return m_sequence;
106
46.2k
         }
107
108
      uint16_t epoch() const
109
1.19k
         {
110
1.19k
         return static_cast<uint16_t>(sequence() >> 48);
111
1.19k
         }
112
113
      Record_Type type() const
114
248k
         {
115
248k
         BOTAN_ASSERT_NOMSG(m_needed == 0);
116
248k
         return m_type;
117
248k
         }
118
119
   private:
120
      size_t m_needed;
121
      uint64_t m_sequence;
122
      Protocol_Version m_version;
123
      Record_Type m_type;
124
   };
125
126
/**
127
* Create an initial (unencrypted) TLS handshake record
128
* @param write_buffer the output record is placed here
129
* @param record_type the record layer type
130
* @param record_version the record layer version
131
* @param record_sequence the record layer sequence number
132
* @param message the record contents
133
* @param message_len is size of message
134
*/
135
void write_unencrypted_record(secure_vector<uint8_t>& write_buffer,
136
                              uint8_t record_type,
137
                              Protocol_Version record_version,
138
                              uint64_t record_sequence,
139
                              const uint8_t* message,
140
                              size_t message_len);
141
142
/**
143
* Create a TLS record
144
* @param write_buffer the output record is placed here
145
* @param record_type the record layer type
146
* @param record_version the record layer version
147
* @param record_sequence the record layer sequence number
148
* @param message the record contents
149
* @param message_len is size of message
150
* @param cipherstate is the writing cipher state
151
* @param rng is a random number generator
152
*/
153
void write_record(secure_vector<uint8_t>& write_buffer,
154
                  uint8_t record_type,
155
                  Protocol_Version record_version,
156
                  uint64_t record_sequence,
157
                  const uint8_t* message,
158
                  size_t message_len,
159
                  Connection_Cipher_State& cipherstate,
160
                  RandomNumberGenerator& rng);
161
162
// epoch -> cipher state
163
typedef std::function<std::shared_ptr<Connection_Cipher_State> (uint16_t)> get_cipherstate_fn;
164
165
/**
166
* Decode a TLS record
167
* @return zero if full message, else number of bytes still needed
168
*/
169
Record_Header read_record(bool is_datagram,
170
                          secure_vector<uint8_t>& read_buffer,
171
                          const uint8_t input[],
172
                          size_t input_len,
173
                          size_t& consumed,
174
                          secure_vector<uint8_t>& record_buf,
175
                          Connection_Sequence_Numbers* sequence_numbers,
176
                          const get_cipherstate_fn& get_cipherstate,
177
                          bool allow_epoch0_restart);
178
179
}
180
181
}
182
183
#endif