11#include <botan/internal/tls_cbc.h>
13#include <botan/internal/cbc.h>
15#include <botan/tls_alert.h>
16#include <botan/tls_exceptn.h>
17#include <botan/internal/ct_utils.h>
18#include <botan/internal/loadstor.h>
19#include <botan/internal/rounding.h>
27 std::unique_ptr<BlockCipher> cipher,
28 std::unique_ptr<MessageAuthenticationCode> mac,
32 bool use_encrypt_then_mac) :
34 m_mac_name(mac->
name()),
35 m_cipher_keylen(cipher_keylen),
36 m_mac_keylen(mac_keylen),
37 m_use_encrypt_then_mac(use_encrypt_then_mac) {
39 m_block_size = cipher->block_size();
41 m_iv_size = m_block_size;
45 m_mac = std::move(
mac);
49 m_cbc = std::make_unique<CBC_Encryption>(std::move(cipher), std::move(
null_padding));
51 m_cbc = std::make_unique<CBC_Decryption>(std::move(cipher), std::move(
null_padding));
68 return "TLS_CBC(" + m_cipher_name +
"," + m_mac_name +
")";
80 if(m_cbc_state.empty()) {
94void TLS_CBC_HMAC_AEAD_Mode::key_schedule(std::span<const uint8_t> key) {
97 if(
key.size() != m_cipher_keylen + m_mac_keylen) {
105void TLS_CBC_HMAC_AEAD_Mode::start_msg(
const uint8_t nonce[],
size_t nonce_len) {
113 m_cbc_state.assign(nonce, nonce +
nonce_len);
117size_t TLS_CBC_HMAC_AEAD_Mode::process_msg(uint8_t buf[],
size_t sz) {
118 m_msg.insert(m_msg.end(), buf, buf +
sz);
123 std::vector<uint8_t>
ad = m_ad;
131 BOTAN_ARG_CHECK(
idx == 0,
"TLS 1.2 CBC/HMAC: cannot handle non-zero index in set_associated_data_n");
132 if(
ad.size() != 13) {
135 m_ad.assign(
ad.begin(),
ad.end());
153 size_t padding_length) {
234 if(record_len == 0 || record_len > 0xFFFF) {
238 const uint16_t rec16 =
static_cast<uint16_t
>(record_len);
245 const uint16_t to_check = std::min<uint16_t>(256,
static_cast<uint16_t
>(record_len));
246 const uint8_t pad_byte = record[record_len - 1];
247 const uint16_t pad_bytes = 1 + pad_byte;
251 for(uint16_t i = rec16 - to_check; i != rec16; ++i) {
252 const uint16_t offset = rec16 - i;
255 pad_invalid |= in_pad_range & ~pad_correct;
258 return pad_invalid.if_not_set_return(pad_bytes);
261void TLS_CBC_HMAC_AEAD_Decryption::cbc_decrypt_record(uint8_t record_contents[],
size_t record_len) {
263 throw Decoding_Error(
"Received TLS CBC ciphertext with invalid length");
321void TLS_CBC_HMAC_AEAD_Decryption::perform_additional_compressions(
size_t plen,
size_t padlen) {
324 if(
mac().
name() ==
"HMAC(SHA-384)") {
332 const uint16_t
L1 =
static_cast<uint16_t
>(13 +
plen -
tag_size());
349 std::vector<uint8_t> data(
data_len);
354void TLS_CBC_HMAC_AEAD_Decryption::finish_msg(secure_vector<uint8_t>& buffer,
size_t offset) {
363 throw TLS_Exception(Alert::BadRecordMac,
"Message authentication failure");
386 throw TLS_Exception(Alert::BadRecordMac,
"Message authentication failure");
396 throw TLS_Exception(Alert::BadRecordMac,
"Message authentication failure");
463 throw TLS_Exception(Alert::BadRecordMac,
"Message authentication failure");
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_DEBUG_ASSERT(expr)
#define BOTAN_ARG_CHECK(expr, msg)
#define BOTAN_ASSERT(expr, assertion_made)
void update(const uint8_t in[], size_t length)
virtual size_t output_length() const =0
void final(uint8_t out[])
static constexpr Mask< T > is_lte(T x, T y)
static constexpr Mask< T > expand(T v)
static constexpr Mask< T > is_equal(T x, T y)
static constexpr Mask< T > is_lt(T x, T y)
void start(std::span< const uint8_t > nonce)
size_t process(std::span< uint8_t > msg)
void set_key(const SymmetricKey &key)
virtual bool has_keying_material() const =0
bool is_datagram_protocol() const
size_t output_length(size_t input_length) const override
void set_associated_data_n(size_t idx, std::span< const uint8_t > ad) override
size_t output_length(size_t input_length) const override
size_t update_granularity() const final
void set_associated_data_n(size_t idx, std::span< const uint8_t > ad) override
size_t block_size() const
secure_vector< uint8_t > & cbc_state()
Key_Length_Specification key_spec() const final
bool has_keying_material() const final
size_t ideal_granularity() const final
std::vector< uint8_t > assoc_data_with_len(uint16_t len)
std::string name() const final
bool use_encrypt_then_mac() const
bool is_datagram_protocol() const
std::vector< uint8_t > & assoc_data()
secure_vector< uint8_t > & msg()
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)
MessageAuthenticationCode & mac() const
Cipher_Mode & cbc() const
size_t tag_size() const final
bool valid_nonce_length(size_t nl) const final
std::string m_cipher_name
int(* update)(CTX *, const void *, CC_LONG len)
void poison(const T *p, size_t n)
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
constexpr void unpoison(const T *p, size_t n)
uint16_t check_tls_cbc_padding(const uint8_t record[], size_t record_len)
std::vector< T, secure_allocator< T > > secure_vector
constexpr void copy_mem(T *out, const T *in, size_t n)
size_t round_up(size_t n, size_t align_to)
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)