Botan
1.11.15
|
00001 /* 00002 * TLS Sequence Number Handling 00003 * (C) 2012 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #ifndef BOTAN_TLS_SEQ_NUMBERS_H__ 00009 #define BOTAN_TLS_SEQ_NUMBERS_H__ 00010 00011 #include <botan/types.h> 00012 #include <stdexcept> 00013 00014 namespace Botan { 00015 00016 namespace TLS { 00017 00018 class Connection_Sequence_Numbers 00019 { 00020 public: 00021 virtual void new_read_cipher_state() = 0; 00022 virtual void new_write_cipher_state() = 0; 00023 00024 virtual u16bit current_read_epoch() const = 0; 00025 virtual u16bit current_write_epoch() const = 0; 00026 00027 virtual u64bit next_write_sequence(u16bit) = 0; 00028 virtual u64bit next_read_sequence() = 0; 00029 00030 virtual bool already_seen(u64bit seq) const = 0; 00031 virtual void read_accept(u64bit seq) = 0; 00032 }; 00033 00034 class Stream_Sequence_Numbers : public Connection_Sequence_Numbers 00035 { 00036 public: 00037 void new_read_cipher_state() override { m_read_seq_no = 0; m_read_epoch += 1; } 00038 void new_write_cipher_state() override { m_write_seq_no = 0; m_write_epoch += 1; } 00039 00040 u16bit current_read_epoch() const override { return m_read_epoch; } 00041 u16bit current_write_epoch() const override { return m_write_epoch; } 00042 00043 u64bit next_write_sequence(u16bit) override { return m_write_seq_no++; } 00044 u64bit next_read_sequence() override { return m_read_seq_no; } 00045 00046 bool already_seen(u64bit) const override { return false; } 00047 void read_accept(u64bit) override { m_read_seq_no++; } 00048 private: 00049 u64bit m_write_seq_no = 0; 00050 u64bit m_read_seq_no = 0; 00051 u16bit m_read_epoch = 0; 00052 u16bit m_write_epoch = 0; 00053 }; 00054 00055 class Datagram_Sequence_Numbers : public Connection_Sequence_Numbers 00056 { 00057 public: 00058 Datagram_Sequence_Numbers() { m_write_seqs[0] = 0; } 00059 00060 void new_read_cipher_state() override { m_read_epoch += 1; } 00061 00062 void new_write_cipher_state() override 00063 { 00064 m_write_epoch += 1; 00065 m_write_seqs[m_write_epoch] = 0; 00066 } 00067 00068 u16bit current_read_epoch() const override { return m_read_epoch; } 00069 u16bit current_write_epoch() const override { return m_write_epoch; } 00070 00071 u64bit next_write_sequence(u16bit epoch) override 00072 { 00073 auto i = m_write_seqs.find(epoch); 00074 BOTAN_ASSERT(i != m_write_seqs.end(), "Found epoch"); 00075 return (static_cast<u64bit>(epoch) << 48) | i->second++; 00076 } 00077 00078 u64bit next_read_sequence() override 00079 { 00080 throw std::runtime_error("DTLS uses explicit sequence numbers"); 00081 } 00082 00083 bool already_seen(u64bit sequence) const override 00084 { 00085 const size_t window_size = sizeof(m_window_bits) * 8; 00086 00087 if(sequence > m_window_highest) 00088 return false; 00089 00090 const u64bit offset = m_window_highest - sequence; 00091 00092 if(offset >= window_size) 00093 return true; // really old? 00094 00095 return (((m_window_bits >> offset) & 1) == 1); 00096 } 00097 00098 void read_accept(u64bit sequence) override 00099 { 00100 const size_t window_size = sizeof(m_window_bits) * 8; 00101 00102 if(sequence > m_window_highest) 00103 { 00104 const size_t offset = sequence - m_window_highest; 00105 m_window_highest += offset; 00106 00107 if(offset >= window_size) 00108 m_window_bits = 0; 00109 else 00110 m_window_bits <<= offset; 00111 00112 m_window_bits |= 0x01; 00113 } 00114 else 00115 { 00116 const u64bit offset = m_window_highest - sequence; 00117 m_window_bits |= (static_cast<u64bit>(1) << offset); 00118 } 00119 } 00120 00121 private: 00122 std::map<u16bit, u64bit> m_write_seqs; 00123 u16bit m_write_epoch = 0; 00124 u16bit m_read_epoch = 0; 00125 u64bit m_window_highest = 0; 00126 u64bit m_window_bits = 0; 00127 }; 00128 00129 } 00130 00131 } 00132 00133 #endif