Coverage Report

Created: 2023-02-13 06:21

/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
817
         {
48
817
         BOTAN_ASSERT_NONNULL(m_aead.get());
49
817
         return *m_aead.get();
50
817
         }
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,
57
                                     Record_Type type,
58
                                     Protocol_Version version,
59
                                     uint16_t ptext_length);
60
61
477
      size_t nonce_bytes_from_handshake() const { return m_nonce_bytes_from_handshake; }
62
2.37k
      size_t nonce_bytes_from_record() const { return m_nonce_bytes_from_record; }
63
64
1.21k
      Nonce_Format nonce_format() const { return m_nonce_format; }
65
66
   private:
67
      std::chrono::system_clock::time_point m_start_time;
68
      std::unique_ptr<AEAD_Mode> m_aead;
69
70
      std::vector<uint8_t> m_nonce;
71
      Nonce_Format m_nonce_format;
72
      size_t m_nonce_bytes_from_handshake;
73
      size_t m_nonce_bytes_from_record;
74
   };
75
76
class Record_Header final
77
   {
78
   public:
79
      Record_Header(uint64_t sequence,
80
                    Protocol_Version version,
81
                    Record_Type type) :
82
         m_needed(0),
83
         m_sequence(sequence),
84
         m_version(version),
85
         m_type(type)
86
69.5k
         {}
87
88
      Record_Header(size_t needed) :
89
         m_needed(needed),
90
         m_sequence(0),
91
         m_version(Protocol_Version()),
92
         m_type(Record_Type::Invalid)
93
868
         {}
94
95
70.4k
      size_t needed() const { return m_needed; }
96
97
      Protocol_Version version() const
98
87.9k
         {
99
87.9k
         BOTAN_ASSERT_NOMSG(m_needed == 0);
100
87.9k
         return m_version;
101
87.9k
         }
102
103
      uint64_t sequence() const
104
48.9k
         {
105
48.9k
         BOTAN_ASSERT_NOMSG(m_needed == 0);
106
48.9k
         return m_sequence;
107
48.9k
         }
108
109
      uint16_t epoch() const
110
1.25k
         {
111
1.25k
         return static_cast<uint16_t>(sequence() >> 48);
112
1.25k
         }
113
114
      Record_Type type() const
115
254k
         {
116
254k
         BOTAN_ASSERT_NOMSG(m_needed == 0);
117
254k
         return m_type;
118
254k
         }
119
120
   private:
121
      size_t m_needed;
122
      uint64_t m_sequence;
123
      Protocol_Version m_version;
124
      Record_Type m_type;
125
   };
126
127
/**
128
* Create an initial (unencrypted) TLS handshake record
129
* @param write_buffer the output record is placed here
130
* @param record_type the record layer type
131
* @param record_version the record layer version
132
* @param record_sequence the record layer sequence number
133
* @param message the record contents
134
* @param message_len is size of message
135
*/
136
void write_unencrypted_record(secure_vector<uint8_t>& write_buffer,
137
                              Record_Type record_type,
138
                              Protocol_Version record_version,
139
                              uint64_t record_sequence,
140
                              const uint8_t* message,
141
                              size_t message_len);
142
143
/**
144
* Create a TLS record
145
* @param write_buffer the output record is placed here
146
* @param record_type the record layer type
147
* @param record_version the record layer version
148
* @param record_sequence the record layer sequence number
149
* @param message the record contents
150
* @param message_len is size of message
151
* @param cipherstate is the writing cipher state
152
* @param rng is a random number generator
153
*/
154
void write_record(secure_vector<uint8_t>& write_buffer,
155
                  Record_Type record_type,
156
                  Protocol_Version record_version,
157
                  uint64_t record_sequence,
158
                  const uint8_t* message,
159
                  size_t message_len,
160
                  Connection_Cipher_State& cipherstate,
161
                  RandomNumberGenerator& rng);
162
163
// epoch -> cipher state
164
typedef std::function<std::shared_ptr<Connection_Cipher_State> (uint16_t)> get_cipherstate_fn;
165
166
/**
167
* Decode a TLS record
168
* @return zero if full message, else number of bytes still needed
169
*/
170
Record_Header read_record(bool is_datagram,
171
                          secure_vector<uint8_t>& read_buffer,
172
                          const uint8_t input[],
173
                          size_t input_len,
174
                          size_t& consumed,
175
                          secure_vector<uint8_t>& record_buf,
176
                          Connection_Sequence_Numbers* sequence_numbers,
177
                          const get_cipherstate_fn& get_cipherstate,
178
                          bool allow_epoch0_restart);
179
180
}
181
182
}
183
184
#endif