Botan 3.0.0-alpha0
Crypto and TLS for C&
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
14namespace Botan {
15
16namespace 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 // We've received a later sequence which advances our window
134 const uint64_t offset = sequence - m_window_highest;
135 m_window_highest += offset;
136
137 if(offset >= window_size)
138 m_window_bits = 0;
139 else
140 m_window_bits <<= offset;
141
142 m_window_bits |= 0x01;
143 }
144 else
145 {
146 const uint64_t offset = m_window_highest - sequence;
147
148 if(offset < window_size)
149 {
150 // We've received an old sequence but still within our window
151 m_window_bits |= (static_cast<uint64_t>(1) << offset);
152 }
153 else
154 {
155 // This occurs only if we have reset state (DTLS reconnection case)
156 m_window_highest = sequence;
157 m_window_bits = 0;
158 }
159 }
160 }
161
162 private:
163 std::map<uint16_t, uint64_t> m_write_seqs;
164 uint16_t m_write_epoch = 0;
165 uint16_t m_read_epoch = 0;
166 uint64_t m_window_highest = 0;
167 uint64_t m_window_bits = 0;
168 };
169
170}
171
172}
173
174#endif
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:54
virtual uint16_t current_read_epoch() const =0
virtual ~Connection_Sequence_Numbers()=default
virtual void read_accept(uint64_t seq)=0
virtual uint16_t current_write_epoch() const =0
virtual bool already_seen(uint64_t seq) const =0
virtual uint64_t next_write_sequence(uint16_t)=0
void read_accept(uint64_t sequence) override
uint16_t current_read_epoch() const override
uint16_t current_write_epoch() const override
uint64_t next_write_sequence(uint16_t epoch) override
bool already_seen(uint64_t sequence) const override
uint64_t next_write_sequence(uint16_t) override
uint64_t next_read_sequence() override
void read_accept(uint64_t) override
uint16_t current_read_epoch() const override
bool already_seen(uint64_t) const override
uint16_t current_write_epoch() const override
int(* final)(unsigned char *, CTX *)
Definition: alg_id.cpp:13