Coverage Report

Created: 2021-04-07 06:07

/src/botan/build/include/botan/internal/tls_record.h
Line
Count
Source (jump to first uncovered line)
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 Ciphersuite;
25
class Session_Keys;
26
27
class Connection_Sequence_Numbers;
28
29
/**
30
* TLS Cipher State
31
*/
32
class Connection_Cipher_State final
33
   {
34
   public:
35
      /**
36
      * Initialize a new cipher state
37
      */
38
      Connection_Cipher_State(Protocol_Version version,
39
                              Connection_Side which_side,
40
                              bool is_our_side,
41
                              const Ciphersuite& suite,
42
                              const Session_Keys& keys,
43
                              bool uses_encrypt_then_mac);
44
45
      AEAD_Mode& aead()
46
855
         {
47
855
         BOTAN_ASSERT_NONNULL(m_aead.get());
48
855
         return *m_aead.get();
49
855
         }
50
51
      std::vector<uint8_t> aead_nonce(uint64_t seq, RandomNumberGenerator& rng);
52
53
      std::vector<uint8_t> aead_nonce(const uint8_t record[], size_t record_len, uint64_t seq);
54
55
      std::vector<uint8_t> format_ad(uint64_t seq, uint8_t type,
56
                                  Protocol_Version version,
57
                                  uint16_t ptext_length);
58
59
606
      size_t nonce_bytes_from_handshake() const { return m_nonce_bytes_from_handshake; }
60
2.33k
      size_t nonce_bytes_from_record() const { return m_nonce_bytes_from_record; }
61
62
1.58k
      Nonce_Format nonce_format() const { return m_nonce_format; }
63
64
      std::chrono::seconds age() const
65
0
         {
66
0
         return std::chrono::duration_cast<std::chrono::seconds>(
67
0
            std::chrono::system_clock::now() - m_start_time);
68
0
         }
69
70
   private:
71
      std::chrono::system_clock::time_point m_start_time;
72
      std::unique_ptr<AEAD_Mode> m_aead;
73
74
      std::vector<uint8_t> m_nonce;
75
      Nonce_Format m_nonce_format;
76
      size_t m_nonce_bytes_from_handshake;
77
      size_t m_nonce_bytes_from_record;
78
   };
79
80
class Record_Header final
81
   {
82
   public:
83
      Record_Header(uint64_t sequence,
84
                    Protocol_Version version,
85
                    Record_Type type) :
86
         m_needed(0),
87
         m_sequence(sequence),
88
         m_version(version),
89
         m_type(type)
90
135k
         {}
91
92
      Record_Header(size_t needed) :
93
         m_needed(needed),
94
         m_sequence(0),
95
         m_version(Protocol_Version()),
96
         m_type(NO_RECORD)
97
1.06k
         {}
98
99
136k
      size_t needed() const { return m_needed; }
100
101
      Protocol_Version version() const
102
142k
         {
103
142k
         BOTAN_ASSERT_NOMSG(m_needed == 0);
104
142k
         return m_version;
105
142k
         }
106
107
      uint64_t sequence() const
108
87.7k
         {
109
87.7k
         BOTAN_ASSERT_NOMSG(m_needed == 0);
110
87.7k
         return m_sequence;
111
87.7k
         }
112
113
      uint16_t epoch() const
114
1.07k
         {
115
1.07k
         return static_cast<uint16_t>(sequence() >> 48);
116
1.07k
         }
117
118
      Record_Type type() const
119
507k
         {
120
507k
         BOTAN_ASSERT_NOMSG(m_needed == 0);
121
507k
         return m_type;
122
507k
         }
123
124
   private:
125
      size_t m_needed;
126
      uint64_t m_sequence;
127
      Protocol_Version m_version;
128
      Record_Type m_type;
129
   };
130
131
/**
132
* Create an initial (unencrypted) TLS handshake record
133
* @param write_buffer the output record is placed here
134
* @param record_type the record layer type
135
* @param record_version the record layer version
136
* @param record_sequence the record layer sequence number
137
* @param message the record contents
138
* @param message_len is size of message
139
*/
140
void write_unencrypted_record(secure_vector<uint8_t>& write_buffer,
141
                              uint8_t record_type,
142
                              Protocol_Version record_version,
143
                              uint64_t record_sequence,
144
                              const uint8_t* message,
145
                              size_t message_len);
146
147
/**
148
* Create a TLS record
149
* @param write_buffer the output record is placed here
150
* @param record_type the record layer type
151
* @param record_version the record layer version
152
* @param record_sequence the record layer sequence number
153
* @param message the record contents
154
* @param message_len is size of message
155
* @param cipherstate is the writing cipher state
156
* @param rng is a random number generator
157
*/
158
void write_record(secure_vector<uint8_t>& write_buffer,
159
                  uint8_t record_type,
160
                  Protocol_Version record_version,
161
                  uint64_t record_sequence,
162
                  const uint8_t* message,
163
                  size_t message_len,
164
                  Connection_Cipher_State& cipherstate,
165
                  RandomNumberGenerator& rng);
166
167
// epoch -> cipher state
168
typedef std::function<std::shared_ptr<Connection_Cipher_State> (uint16_t)> get_cipherstate_fn;
169
170
/**
171
* Decode a TLS record
172
* @return zero if full message, else number of bytes still needed
173
*/
174
Record_Header read_record(bool is_datagram,
175
                          secure_vector<uint8_t>& read_buffer,
176
                          const uint8_t input[],
177
                          size_t input_len,
178
                          size_t& consumed,
179
                          secure_vector<uint8_t>& record_buf,
180
                          Connection_Sequence_Numbers* sequence_numbers,
181
                          get_cipherstate_fn get_cipherstate,
182
                          bool allow_epoch0_restart);
183
184
}
185
186
}
187
188
#endif