Botan  2.11.0
Crypto and TLS for C++11
Public Member Functions | Protected Member Functions | List of all members
Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption Class Referencefinal

#include <tls_cbc.h>

Inheritance diagram for Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption:
Botan::TLS::TLS_CBC_HMAC_AEAD_Mode

Public Member Functions

void clear () override final
 
size_t default_nonce_length () const override final
 
void finish (secure_vector< uint8_t > &final_block, size_t offset=0) override
 
Key_Length_Specification key_spec () const override final
 
size_t minimum_final_size () const override
 
std::string name () const override final
 
size_t output_length (size_t input_length) const override
 
size_t process (uint8_t buf[], size_t sz) override final
 
void reset () override final
 
void set_associated_data (const uint8_t ad[], size_t ad_len) override
 
size_t tag_size () const override final
 
 TLS_CBC_HMAC_AEAD_Decryption (std::unique_ptr< BlockCipher > cipher, std::unique_ptr< MessageAuthenticationCode > mac, const size_t cipher_keylen, const size_t mac_keylen, const Protocol_Version version, bool use_encrypt_then_mac)
 
size_t update_granularity () const override final
 
bool valid_nonce_length (size_t nl) const override final
 

Protected Member Functions

std::vector< uint8_t > & assoc_data ()
 
std::vector< uint8_t > assoc_data_with_len (uint16_t len)
 
size_t block_size () const
 
Cipher_Mode & cbc () const
 
secure_vector< uint8_t > & cbc_state ()
 
size_t cipher_keylen () const
 
bool is_datagram_protocol () const
 
size_t iv_size () const
 
MessageAuthenticationCode & mac () const
 
size_t mac_keylen () const
 
secure_vector< uint8_t > & msg ()
 
bool use_encrypt_then_mac () const
 

Detailed Description

TLS_CBC_HMAC_AEAD Decryption

Definition at line 141 of file tls_cbc.h.

Constructor & Destructor Documentation

◆ TLS_CBC_HMAC_AEAD_Decryption()

Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption::TLS_CBC_HMAC_AEAD_Decryption ( std::unique_ptr< BlockCipher >  cipher,
std::unique_ptr< MessageAuthenticationCode >  mac,
const size_t  cipher_keylen,
const size_t  mac_keylen,
const Protocol_Version  version,
bool  use_encrypt_then_mac 
)
inline

Definition at line 146 of file tls_cbc.h.

151  :
153  std::move(cipher),
154  std::move(mac),
156  mac_keylen,
157  version,
159  {}
TLS_CBC_HMAC_AEAD_Mode(Cipher_Dir direction, std::unique_ptr< BlockCipher > cipher, std::unique_ptr< MessageAuthenticationCode > mac, size_t cipher_keylen, size_t mac_keylen, Protocol_Version version, bool use_encrypt_then_mac)
Definition: tls_cbc.cpp:26
MessageAuthenticationCode & mac() const
Definition: tls_cbc.h:68
void BlockCipher * cipher
Definition: package.h:29

Member Function Documentation

◆ assoc_data()

std::vector<uint8_t>& Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::assoc_data ( )
inlineprotectedinherited

◆ assoc_data_with_len()

std::vector< uint8_t > Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::assoc_data_with_len ( uint16_t  len)
protectedinherited

Definition at line 122 of file tls_cbc.cpp.

123  {
124  std::vector<uint8_t> ad = m_ad;
125  BOTAN_ASSERT(ad.size() == 13, "Expected AAD size");
126  ad[11] = get_byte(0, len);
127  ad[12] = get_byte(1, len);
128  return ad;
129  }
std::string size_t len
Definition: pk_keys.h:305
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
class BOTAN_PUBLIC_API(2, 11) Argon2 final class BOTAN_PUBLIC_API(2, 11) Argon2_Family final void size_t const char size_t const uint8_t size_t const uint8_t size_t const uint8_t ad[]
Definition: argon2.h:87

References Botan::ad, BOTAN_ASSERT, Botan::get_byte(), and Botan::len.

Referenced by finish().

◆ block_size()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::block_size ( ) const
inlineprotectedinherited

◆ cbc()

Cipher_Mode& Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::cbc ( ) const
inlineprotectedinherited

Definition at line 66 of file tls_cbc.h.

66 { return *m_cbc; }

Referenced by Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::clear().

◆ cbc_state()

secure_vector<uint8_t>& Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::cbc_state ( )
inlineprotectedinherited

Definition at line 74 of file tls_cbc.h.

74 { return m_cbc_state; }

Referenced by Botan::TLS::TLS_CBC_HMAC_AEAD_Encryption::finish(), finish(), and Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::reset().

◆ cipher_keylen()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::cipher_keylen ( ) const
inlineprotectedinherited

Definition at line 57 of file tls_cbc.h.

57 { return m_cipher_keylen; }

◆ clear()

void Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::clear ( )
finaloverrideinherited

Definition at line 54 of file tls_cbc.cpp.

55  {
56  cbc().clear();
57  mac().clear();
58  reset();
59  }
Cipher_Mode & cbc() const
Definition: tls_cbc.h:66
MessageAuthenticationCode & mac() const
Definition: tls_cbc.h:68
void reset() override final
Definition: tls_cbc.cpp:61

References Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::cbc(), Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::mac(), and Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::reset().

◆ default_nonce_length()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::default_nonce_length ( ) const
inlinefinaloverrideinherited

Definition at line 42 of file tls_cbc.h.

42 { return m_iv_size; }

◆ finish()

void Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption::finish ( secure_vector< uint8_t > &  final_block,
size_t  offset = 0 
)
override

Definition at line 352 of file tls_cbc.cpp.

353  {
354  update(buffer, offset);
355  buffer.resize(offset);
356 
357  const size_t record_len = msg().size();
358  uint8_t* record_contents = msg().data();
359 
360  // This early exit does not leak info because all the values compared are public
361  if(record_len < tag_size() ||
362  (record_len - (use_encrypt_then_mac() ? tag_size() : 0)) % block_size() != 0)
363  {
364  throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
365  }
366 
368  {
369  const size_t enc_size = record_len - tag_size();
370  const size_t enc_iv_size = enc_size + iv_size();
371 
372  BOTAN_ASSERT_NOMSG(enc_iv_size <= 0xFFFF);
373 
374  mac().update(assoc_data_with_len(static_cast<uint16_t>(enc_iv_size)));
375  if(iv_size() > 0)
376  {
377  mac().update(cbc_state());
378  }
379  mac().update(record_contents, enc_size);
380 
381  std::vector<uint8_t> mac_buf(tag_size());
382  mac().final(mac_buf.data());
383 
384  const size_t mac_offset = enc_size;
385 
386  const bool mac_ok = constant_time_compare(&record_contents[mac_offset], mac_buf.data(), tag_size());
387 
388  if(!mac_ok)
389  {
390  throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
391  }
392 
393  cbc_decrypt_record(record_contents, enc_size);
394 
395  // 0 if padding was invalid, otherwise 1 + padding_bytes
396  const uint16_t pad_size = check_tls_cbc_padding(record_contents, enc_size);
397 
398  // No oracle here, whoever sent us this had the key since MAC check passed
399  if(pad_size == 0)
400  {
401  throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
402  }
403 
404  const uint8_t* plaintext_block = &record_contents[0];
405  const size_t plaintext_length = enc_size - pad_size;
406 
407  buffer.insert(buffer.end(), plaintext_block, plaintext_block + plaintext_length);
408  }
409  else
410  {
411  cbc_decrypt_record(record_contents, record_len);
412 
413  CT::poison(record_contents, record_len);
414 
415  // 0 if padding was invalid, otherwise 1 + padding_bytes
416  uint16_t pad_size = check_tls_cbc_padding(record_contents, record_len);
417 
418  /*
419  This mask is zero if there is not enough room in the packet to get a valid MAC.
420 
421  We have to accept empty packets, since otherwise we are not compatible
422  with how OpenSSL's countermeasure for fixing BEAST in TLS 1.0 CBC works
423  (sending empty records, instead of 1/(n-1) splitting)
424  */
425 
426  // We know the cast cannot overflow as pad_size <= 256 && tag_size <= 32
427  const auto size_ok_mask = CT::Mask<uint16_t>::is_lte(
428  static_cast<uint16_t>(tag_size() + pad_size),
429  static_cast<uint16_t>(record_len));
430 
431  pad_size = size_ok_mask.if_set_return(pad_size);
432 
433  CT::unpoison(record_contents, record_len);
434 
435  /*
436  This is unpoisoned sooner than it should. The pad_size leaks to plaintext_length and
437  then to the timing channel in the MAC computation described in the Lucky 13 paper.
438  */
439  CT::unpoison(pad_size);
440 
441  const uint8_t* plaintext_block = &record_contents[0];
442  const uint16_t plaintext_length = static_cast<uint16_t>(record_len - tag_size() - pad_size);
443 
444  mac().update(assoc_data_with_len(plaintext_length));
445  mac().update(plaintext_block, plaintext_length);
446 
447  std::vector<uint8_t> mac_buf(tag_size());
448  mac().final(mac_buf.data());
449 
450  const size_t mac_offset = record_len - (tag_size() + pad_size);
451 
452  const bool mac_ok = constant_time_compare(&record_contents[mac_offset], mac_buf.data(), tag_size());
453 
454  const auto ok_mask = size_ok_mask & CT::Mask<uint16_t>::expand(mac_ok) & CT::Mask<uint16_t>::expand(pad_size);
455 
456  CT::unpoison(ok_mask);
457 
458  if(ok_mask.is_set())
459  {
460  buffer.insert(buffer.end(), plaintext_block, plaintext_block + plaintext_length);
461  }
462  else
463  {
464  perform_additional_compressions(record_len, pad_size);
465 
466  /*
467  * In DTLS case we have to finish computing the MAC since we require the
468  * MAC state be reset for future packets. This extra timing channel may
469  * be exploitable in a Lucky13 variant.
470  */
472  mac().final(mac_buf);
473  throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure");
474  }
475  }
476  }
bool BigInt BigInt size_t size_t const std::vector< uint8_t > size_t offset
Definition: numthry.h:271
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:81
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:68
void poison(const T *p, size_t n)
Definition: ct_utils.h:48
MessageAuthenticationCode & mac() const
Definition: tls_cbc.h:68
secure_vector< uint8_t > & cbc_state()
Definition: tls_cbc.h:74
static Mask< T > is_lte(T x, T y)
Definition: ct_utils.h:173
static Mask< T > expand(T v)
Definition: ct_utils.h:123
size_t tag_size() const override final
Definition: tls_cbc.h:40
int(* update)(CTX *, const void *, CC_LONG len)
std::vector< uint8_t > assoc_data_with_len(uint16_t len)
Definition: tls_cbc.cpp:122
uint16_t check_tls_cbc_padding(const uint8_t record[], size_t record_len)
Definition: tls_cbc.cpp:224
void unpoison(const T *p, size_t n)
Definition: ct_utils.h:59
secure_vector< uint8_t > & msg()
Definition: tls_cbc.h:76

References Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::assoc_data_with_len(), Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::block_size(), BOTAN_ASSERT_NOMSG, Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::cbc_state(), Botan::TLS::check_tls_cbc_padding(), Botan::constant_time_compare(), Botan::CT::Mask< T >::expand(), Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::is_datagram_protocol(), Botan::CT::Mask< T >::is_lte(), Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::iv_size(), Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::mac(), Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::msg(), Botan::offset, Botan::CT::poison(), Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::tag_size(), Botan::CT::unpoison(), update, and Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::use_encrypt_then_mac().

◆ is_datagram_protocol()

bool Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::is_datagram_protocol ( ) const
inlineprotectedinherited

Definition at line 64 of file tls_cbc.h.

64 { return m_is_datagram; }

Referenced by finish().

◆ iv_size()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::iv_size ( ) const
inlineprotectedinherited

◆ key_spec()

Key_Length_Specification Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::key_spec ( ) const
finaloverrideinherited

Definition at line 85 of file tls_cbc.cpp.

86  {
87  return Key_Length_Specification(m_cipher_keylen + m_mac_keylen);
88  }

◆ mac()

MessageAuthenticationCode& Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::mac ( ) const
inlineprotectedinherited

Definition at line 68 of file tls_cbc.h.

69  {
70  BOTAN_ASSERT_NONNULL(m_mac);
71  return *m_mac;
72  }
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:107

References BOTAN_ASSERT_NONNULL.

Referenced by Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::clear(), Botan::TLS::TLS_CBC_HMAC_AEAD_Encryption::finish(), finish(), and Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::TLS_CBC_HMAC_AEAD_Mode().

◆ mac_keylen()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::mac_keylen ( ) const
inlineprotectedinherited

Definition at line 58 of file tls_cbc.h.

58 { return m_mac_keylen; }

◆ minimum_final_size()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption::minimum_final_size ( ) const
inlineoverride

Definition at line 163 of file tls_cbc.h.

163 { return tag_size(); }
size_t tag_size() const override final
Definition: tls_cbc.h:40

References tag_size.

◆ msg()

secure_vector<uint8_t>& Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::msg ( )
inlineprotectedinherited

Definition at line 76 of file tls_cbc.h.

76 { return m_msg; }

Referenced by Botan::TLS::TLS_CBC_HMAC_AEAD_Encryption::finish(), and finish().

◆ name()

std::string Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::name ( ) const
finaloverrideinherited

Definition at line 68 of file tls_cbc.cpp.

69  {
70  return "TLS_CBC(" + m_cipher_name + "," + m_mac_name + ")";
71  }

◆ output_length()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption::output_length ( size_t  input_length) const
override

Definition at line 265 of file tls_cbc.cpp.

266  {
267  /*
268  * We don't know this because the padding is arbitrary
269  */
270  return 0;
271  }

◆ process()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::process ( uint8_t  buf[],
size_t  sz 
)
finaloverrideinherited

Definition at line 116 of file tls_cbc.cpp.

117  {
118  m_msg.insert(m_msg.end(), buf, buf + sz);
119  return 0;
120  }
const uint8_t * buf
Definition: ffi.h:371

References buf.

◆ reset()

void Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::reset ( )
finaloverrideinherited

Definition at line 61 of file tls_cbc.cpp.

62  {
63  cbc_state().clear();
64  m_ad.clear();
65  m_msg.clear();
66  }
secure_vector< uint8_t > & cbc_state()
Definition: tls_cbc.h:74

References Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::cbc_state().

Referenced by Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::clear().

◆ set_associated_data()

void Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::set_associated_data ( const uint8_t  ad[],
size_t  ad_len 
)
overrideinherited

Definition at line 131 of file tls_cbc.cpp.

132  {
133  if(ad_len != 13)
134  throw Invalid_Argument("Invalid TLS AEAD associated data length");
135  m_ad.assign(ad, ad + ad_len);
136  }
class BOTAN_PUBLIC_API(2, 11) Argon2 final class BOTAN_PUBLIC_API(2, 11) Argon2_Family final void size_t const char size_t const uint8_t size_t const uint8_t size_t const uint8_t size_t ad_len
Definition: argon2.h:87
class BOTAN_PUBLIC_API(2, 11) Argon2 final class BOTAN_PUBLIC_API(2, 11) Argon2_Family final void size_t const char size_t const uint8_t size_t const uint8_t size_t const uint8_t ad[]
Definition: argon2.h:87

References Botan::ad, and Botan::ad_len.

Referenced by Botan::TLS::TLS_CBC_HMAC_AEAD_Encryption::set_associated_data().

◆ tag_size()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::tag_size ( ) const
inlinefinaloverrideinherited

◆ update_granularity()

size_t Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::update_granularity ( ) const
finaloverrideinherited

Definition at line 73 of file tls_cbc.cpp.

74  {
75  return 1; // just buffers anyway
76  }

◆ use_encrypt_then_mac()

bool Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::use_encrypt_then_mac ( ) const
inlineprotectedinherited

◆ valid_nonce_length()

bool Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::valid_nonce_length ( size_t  nl) const
finaloverrideinherited

Definition at line 78 of file tls_cbc.cpp.

79  {
80  if(m_cbc_state.empty())
81  return nl == block_size();
82  return nl == iv_size();
83  }
size_t nl
Definition: ffi.h:445

References Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::block_size(), Botan::TLS::TLS_CBC_HMAC_AEAD_Mode::iv_size(), and nl.


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