Botan  2.13.0
Crypto and TLS for C++11
tls_seq_numbers.h
Go to the documentation of this file.
1 /*
2 * TLS Sequence Number Handling
3 * (C) 2012 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_TLS_SEQ_NUMBERS_H_
9 #define BOTAN_TLS_SEQ_NUMBERS_H_
10 
11 #include <botan/types.h>
12 #include <map>
13 
14 namespace Botan {
15 
16 namespace TLS {
17 
19  {
20  public:
21  virtual ~Connection_Sequence_Numbers() = default;
22 
23  virtual void new_read_cipher_state() = 0;
24  virtual void new_write_cipher_state() = 0;
25 
26  virtual uint16_t current_read_epoch() const = 0;
27  virtual uint16_t current_write_epoch() const = 0;
28 
29  virtual uint64_t next_write_sequence(uint16_t) = 0;
30  virtual uint64_t next_read_sequence() = 0;
31 
32  virtual bool already_seen(uint64_t seq) const = 0;
33  virtual void read_accept(uint64_t seq) = 0;
34 
35  virtual void reset() = 0;
36  };
37 
39  {
40  public:
42 
43  void reset() override
44  {
45  m_write_seq_no = 0;
46  m_read_seq_no = 0;
47  m_read_epoch = 0;
48  m_write_epoch = 0;
49  }
50 
51  void new_read_cipher_state() override { m_read_seq_no = 0; m_read_epoch++; }
52  void new_write_cipher_state() override { m_write_seq_no = 0; m_write_epoch++; }
53 
54  uint16_t current_read_epoch() const override { return m_read_epoch; }
55  uint16_t current_write_epoch() const override { return m_write_epoch; }
56 
57  uint64_t next_write_sequence(uint16_t) override { return m_write_seq_no++; }
58  uint64_t next_read_sequence() override { return m_read_seq_no; }
59 
60  bool already_seen(uint64_t) const override { return false; }
61  void read_accept(uint64_t) override { m_read_seq_no++; }
62 
63  private:
64  uint64_t m_write_seq_no;
65  uint64_t m_read_seq_no;
66  uint16_t m_read_epoch;
67  uint16_t m_write_epoch;
68  };
69 
71  {
72  public:
74 
75  void reset() override
76  {
77  m_write_seqs.clear();
78  m_write_seqs[0] = 0;
79  m_write_epoch = 0;
80  m_read_epoch = 0;
81  m_window_highest = 0;
82  m_window_bits = 0;
83  }
84 
85  void new_read_cipher_state() override { m_read_epoch++; }
86 
87  void new_write_cipher_state() override
88  {
89  m_write_epoch++;
90  m_write_seqs[m_write_epoch] = 0;
91  }
92 
93  uint16_t current_read_epoch() const override { return m_read_epoch; }
94  uint16_t current_write_epoch() const override { return m_write_epoch; }
95 
96  uint64_t next_write_sequence(uint16_t epoch) override
97  {
98  auto i = m_write_seqs.find(epoch);
99  BOTAN_ASSERT(i != m_write_seqs.end(), "Found epoch");
100  return (static_cast<uint64_t>(epoch) << 48) | i->second++;
101  }
102 
103  uint64_t next_read_sequence() override
104  {
105  throw Invalid_State("DTLS uses explicit sequence numbers");
106  }
107 
108  bool already_seen(uint64_t sequence) const override
109  {
110  const size_t window_size = sizeof(m_window_bits) * 8;
111 
112  if(sequence > m_window_highest)
113  {
114  return false;
115  }
116 
117  const uint64_t offset = m_window_highest - sequence;
118 
119  if(offset >= window_size)
120  {
121  return true; // really old?
122  }
123 
124  return (((m_window_bits >> offset) & 1) == 1);
125  }
126 
127  void read_accept(uint64_t sequence) override
128  {
129  const size_t window_size = sizeof(m_window_bits) * 8;
130 
131  if(sequence > m_window_highest)
132  {
133  const uint64_t offset = sequence - m_window_highest;
134  m_window_highest += offset;
135 
136  if(offset >= window_size)
137  m_window_bits = 0;
138  else
139  m_window_bits <<= offset;
140 
141  m_window_bits |= 0x01;
142  }
143  else
144  {
145  const uint64_t offset = m_window_highest - sequence;
146  m_window_bits |= (static_cast<uint64_t>(1) << offset);
147  }
148  }
149 
150  private:
151  std::map<uint16_t, uint64_t> m_write_seqs;
152  uint16_t m_write_epoch = 0;
153  uint16_t m_read_epoch = 0;
154  uint64_t m_window_highest = 0;
155  uint64_t m_window_bits = 0;
156  };
157 
158 }
159 
160 }
161 
162 #endif
bool already_seen(uint64_t) const override
virtual bool already_seen(uint64_t seq) const =0
int(* final)(unsigned char *, CTX *)
void read_accept(uint64_t) override
bool already_seen(uint64_t sequence) const override
uint16_t current_write_epoch() const override
void read_accept(uint64_t sequence) override
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
virtual ~Connection_Sequence_Numbers()=default
uint64_t next_write_sequence(uint16_t) override
uint16_t current_read_epoch() const override
uint16_t current_write_epoch() const override
Definition: alg_id.cpp:13
virtual uint64_t next_write_sequence(uint16_t)=0
uint16_t current_read_epoch() const override
uint64_t next_write_sequence(uint16_t epoch) override
virtual uint16_t current_write_epoch() const =0
virtual void read_accept(uint64_t seq)=0
uint64_t next_read_sequence() override
virtual uint16_t current_read_epoch() const =0