Botan  2.4.0
Crypto and TLS for C++11
Public Member Functions | List of all members
Botan::TLS::Connection_Cipher_State Class Referencefinal

#include <tls_record.h>

Public Member Functions

AEAD_Modeaead ()
 
std::vector< uint8_t > aead_nonce (uint64_t seq, RandomNumberGenerator &rng)
 
std::vector< uint8_t > aead_nonce (const uint8_t record[], size_t record_len, uint64_t seq)
 
std::chrono::seconds age () const
 
bool cbc_nonce () const
 
 Connection_Cipher_State (Protocol_Version version, Connection_Side which_side, bool is_our_side, const Ciphersuite &suite, const Session_Keys &keys, bool uses_encrypt_then_mac)
 
std::vector< uint8_t > format_ad (uint64_t seq, uint8_t type, Protocol_Version version, uint16_t ptext_length)
 
size_t nonce_bytes_from_handshake () const
 
size_t nonce_bytes_from_record () const
 

Detailed Description

TLS Cipher State

Definition at line 31 of file tls_record.h.

Constructor & Destructor Documentation

◆ Connection_Cipher_State()

Botan::TLS::Connection_Cipher_State::Connection_Cipher_State ( Protocol_Version  version,
Connection_Side  which_side,
bool  is_our_side,
const Ciphersuite suite,
const Session_Keys keys,
bool  uses_encrypt_then_mac 
)

Initialize a new cipher state

Definition at line 28 of file tls_record.cpp.

References Botan::OctetString::bits_of(), BOTAN_ASSERT, BOTAN_ASSERT_EQUAL, Botan::TLS::Ciphersuite::cipher_algo(), Botan::TLS::Ciphersuite::cipher_keylen(), Botan::TLS::CLIENT, Botan::TLS::Session_Keys::client_cipher_key(), Botan::TLS::Session_Keys::client_iv(), Botan::TLS::Session_Keys::client_mac_key(), Botan::DECRYPTION, Botan::ENCRYPTION, Botan::get_aead(), Botan::OctetString::length(), Botan::TLS::Ciphersuite::mac_algo(), Botan::TLS::Ciphersuite::mac_keylen(), nonce_bytes_from_handshake(), nonce_bytes_from_record(), Botan::TLS::Session_Keys::server_cipher_key(), Botan::TLS::Session_Keys::server_iv(), Botan::TLS::Session_Keys::server_mac_key(), Botan::TLS::Protocol_Version::supports_explicit_cbc_ivs(), and Botan::unlock().

33  :
34  m_start_time(std::chrono::system_clock::now()),
35  m_nonce_bytes_from_handshake(suite.nonce_bytes_from_handshake()),
36  m_nonce_bytes_from_record(suite.nonce_bytes_from_record())
37  {
38  SymmetricKey mac_key, cipher_key;
40 
41  if(side == CLIENT)
42  {
43  cipher_key = keys.client_cipher_key();
44  iv = keys.client_iv();
45  mac_key = keys.client_mac_key();
46  }
47  else
48  {
49  cipher_key = keys.server_cipher_key();
50  iv = keys.server_iv();
51  mac_key = keys.server_mac_key();
52  }
53 
54  BOTAN_ASSERT_EQUAL(iv.length(), nonce_bytes_from_handshake(), "Matching nonce sizes");
55 
56  m_nonce = unlock(iv.bits_of());
57 
58  if(suite.mac_algo() == "AEAD")
59  {
60  m_aead.reset(get_aead(suite.cipher_algo(), our_side ? ENCRYPTION : DECRYPTION));
61  BOTAN_ASSERT(m_aead, "Have AEAD");
62 
63  m_aead->set_key(cipher_key + mac_key);
64 
66  "Ciphersuite uses implemented IV length");
67 
68  m_cbc_nonce = false;
69  if(m_nonce.size() != 12)
70  {
71  m_nonce.resize(m_nonce.size() + 8);
72  }
73  }
74  else
75  {
76 #if defined(BOTAN_HAS_TLS_CBC)
77  // legacy CBC+HMAC mode
78  if(our_side)
79  {
80  m_aead.reset(new TLS_CBC_HMAC_AEAD_Encryption(
81  suite.cipher_algo(),
82  suite.cipher_keylen(),
83  suite.mac_algo(),
84  suite.mac_keylen(),
85  version.supports_explicit_cbc_ivs(),
86  uses_encrypt_then_mac));
87  }
88  else
89  {
90  m_aead.reset(new TLS_CBC_HMAC_AEAD_Decryption(
91  suite.cipher_algo(),
92  suite.cipher_keylen(),
93  suite.mac_algo(),
94  suite.mac_keylen(),
95  version.supports_explicit_cbc_ivs(),
96  uses_encrypt_then_mac));
97  }
98 
99  m_aead->set_key(cipher_key + mac_key);
100 
101  m_cbc_nonce = true;
102  if(version.supports_explicit_cbc_ivs())
103  m_nonce_bytes_from_record = m_nonce_bytes_from_handshake;
104  else if(our_side == false)
105  m_aead->start(iv.bits_of());
106 #else
107  throw Exception("Negotiated disabled TLS CBC+HMAC ciphersuite");
108 #endif
109  }
110  }
OctetString InitializationVector
Definition: symkey.h:141
size_t nonce_bytes_from_handshake() const
Definition: tls_record.h:54
size_t nonce_bytes_from_record() const
Definition: tls_record.h:55
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:29
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
Definition: assert.h:55
OctetString SymmetricKey
Definition: symkey.h:136
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:95
AEAD_Mode * get_aead(const std::string &algo, Cipher_Dir dir)
Definition: aead.cpp:42

Member Function Documentation

◆ aead()

AEAD_Mode* Botan::TLS::Connection_Cipher_State::aead ( )
inline

Definition at line 44 of file tls_record.h.

References aead_nonce(), format_ad(), and type.

Referenced by Botan::TLS::write_record().

44 { return m_aead.get(); }

◆ aead_nonce() [1/2]

std::vector< uint8_t > Botan::TLS::Connection_Cipher_State::aead_nonce ( uint64_t  seq,
RandomNumberGenerator rng 
)

Definition at line 112 of file tls_record.cpp.

References nonce_bytes_from_handshake(), nonce_bytes_from_record(), Botan::RandomNumberGenerator::randomize(), Botan::store_be(), and Botan::xor_buf().

Referenced by aead(), and Botan::TLS::write_record().

113  {
114  if(m_cbc_nonce)
115  {
116  if(m_nonce.size())
117  {
118  std::vector<uint8_t> nonce;
119  nonce.swap(m_nonce);
120  return nonce;
121  }
122  std::vector<uint8_t> nonce(nonce_bytes_from_record());
123  rng.randomize(nonce.data(), nonce.size());
124  return nonce;
125  }
126  else if(nonce_bytes_from_handshake() == 12)
127  {
128  std::vector<uint8_t> nonce(12);
129  store_be(seq, nonce.data() + 4);
130  xor_buf(nonce, m_nonce.data(), m_nonce.size());
131  return nonce;
132  }
133  else
134  {
135  std::vector<uint8_t> nonce = m_nonce;
136  store_be(seq, &nonce[nonce_bytes_from_handshake()]);
137  return nonce;
138  }
139  }
size_t nonce_bytes_from_handshake() const
Definition: tls_record.h:54
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:434
size_t nonce_bytes_from_record() const
Definition: tls_record.h:55
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:163

◆ aead_nonce() [2/2]

std::vector< uint8_t > Botan::TLS::Connection_Cipher_State::aead_nonce ( const uint8_t  record[],
size_t  record_len,
uint64_t  seq 
)

Definition at line 142 of file tls_record.cpp.

References Botan::copy_mem(), nonce_bytes_from_handshake(), nonce_bytes_from_record(), Botan::store_be(), and Botan::xor_buf().

143  {
144  if(m_cbc_nonce)
145  {
146  if(record_len < nonce_bytes_from_record())
147  throw Decoding_Error("Invalid CBC packet too short to be valid");
148  std::vector<uint8_t> nonce(record, record + nonce_bytes_from_record());
149  return nonce;
150  }
151  else if(nonce_bytes_from_handshake() == 12)
152  {
153  /*
154  Assumes if the suite specifies 12 bytes come from the handshake then
155  use the XOR nonce construction from draft-ietf-tls-chacha20-poly1305
156  */
157 
158  std::vector<uint8_t> nonce(12);
159  store_be(seq, nonce.data() + 4);
160  xor_buf(nonce, m_nonce.data(), m_nonce.size());
161  return nonce;
162  }
163  else if(nonce_bytes_from_record() > 0)
164  {
165  if(record_len < nonce_bytes_from_record())
166  throw Decoding_Error("Invalid AEAD packet too short to be valid");
167  std::vector<uint8_t> nonce = m_nonce;
169  return nonce;
170  }
171  else
172  {
173  /*
174  nonce_len == 0 is assumed to mean no nonce in the message but
175  instead the AEAD uses the seq number in network order.
176  */
177  std::vector<uint8_t> nonce = m_nonce;
178  store_be(seq, &nonce[nonce_bytes_from_handshake()]);
179  return nonce;
180  }
181  }
size_t nonce_bytes_from_handshake() const
Definition: tls_record.h:54
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:434
size_t nonce_bytes_from_record() const
Definition: tls_record.h:55
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:163
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:97

◆ age()

std::chrono::seconds Botan::TLS::Connection_Cipher_State::age ( ) const
inline

Definition at line 58 of file tls_record.h.

59  {
60  return std::chrono::duration_cast<std::chrono::seconds>(
61  std::chrono::system_clock::now() - m_start_time);
62  }

◆ cbc_nonce()

bool Botan::TLS::Connection_Cipher_State::cbc_nonce ( ) const
inline

Definition at line 56 of file tls_record.h.

Referenced by Botan::TLS::write_record().

56 { return m_cbc_nonce; }

◆ format_ad()

std::vector< uint8_t > Botan::TLS::Connection_Cipher_State::format_ad ( uint64_t  seq,
uint8_t  type,
Protocol_Version  version,
uint16_t  ptext_length 
)

Definition at line 184 of file tls_record.cpp.

References BOTAN_ASSERT_EQUAL, Botan::get_byte(), Botan::TLS::Protocol_Version::major_version(), Botan::TLS::Protocol_Version::minor_version(), and Botan::store_be().

Referenced by aead(), and Botan::TLS::write_record().

188  {
189  std::vector<uint8_t> ad(13);
190 
191  store_be(msg_sequence, &ad[0]);
192  ad[8] = msg_type;
193  ad[9] = version.major_version();
194  ad[10] = version.minor_version();
195  ad[11] = get_byte(0, msg_length);
196  ad[12] = get_byte(1, msg_length);
197 
198  return ad;
199  }
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:434
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39

◆ nonce_bytes_from_handshake()

size_t Botan::TLS::Connection_Cipher_State::nonce_bytes_from_handshake ( ) const
inline

Definition at line 54 of file tls_record.h.

Referenced by aead_nonce(), Connection_Cipher_State(), and Botan::TLS::write_record().

54 { return m_nonce_bytes_from_handshake; }

◆ nonce_bytes_from_record()

size_t Botan::TLS::Connection_Cipher_State::nonce_bytes_from_record ( ) const
inline

Definition at line 55 of file tls_record.h.

Referenced by aead_nonce(), Connection_Cipher_State(), and Botan::TLS::write_record().

55 { return m_nonce_bytes_from_record; }

The documentation for this class was generated from the following files: