diff options
author | Jack Lloyd <[email protected]> | 2017-10-19 19:00:53 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-10-19 19:00:53 -0400 |
commit | d3c5dab077aff20a78bd582a3fd9c1591dc826a7 (patch) | |
tree | f405981ec65fb32225f77ca3540463bfad8f097a | |
parent | 03d4bceef5caeab584e03a7cf0e3ac3a3fb0d420 (diff) |
Use base CBC modes to implement TLS CBC ciphersuites
This reduces code and also lets TLS make use of parallel decryption
which it was not doing before.
-rw-r--r-- | src/lib/tls/tls_cbc/info.txt | 5 | ||||
-rw-r--r-- | src/lib/tls/tls_cbc/tls_cbc.cpp | 61 | ||||
-rw-r--r-- | src/lib/tls/tls_cbc/tls_cbc.h | 19 |
3 files changed, 36 insertions, 49 deletions
diff --git a/src/lib/tls/tls_cbc/info.txt b/src/lib/tls/tls_cbc/info.txt index 321236696..a1d2b18cc 100644 --- a/src/lib/tls/tls_cbc/info.txt +++ b/src/lib/tls/tls_cbc/info.txt @@ -5,3 +5,8 @@ TLS_CBC -> 20161008 <header:internal> tls_cbc.h </header:internal> + +<requires> +cbc +hmac +</requires> diff --git a/src/lib/tls/tls_cbc/tls_cbc.cpp b/src/lib/tls/tls_cbc/tls_cbc.cpp index a0b238498..f38419ba7 100644 --- a/src/lib/tls/tls_cbc/tls_cbc.cpp +++ b/src/lib/tls/tls_cbc/tls_cbc.cpp @@ -9,6 +9,8 @@ */ #include <botan/internal/tls_cbc.h> +#include <botan/cbc.h> + #include <botan/internal/rounding.h> #include <botan/internal/ct_utils.h> #include <botan/tls_alert.h> @@ -21,7 +23,8 @@ namespace TLS { /* * TLS_CBC_HMAC_AEAD_Mode Constructor */ -TLS_CBC_HMAC_AEAD_Mode::TLS_CBC_HMAC_AEAD_Mode(const std::string& cipher_name, +TLS_CBC_HMAC_AEAD_Mode::TLS_CBC_HMAC_AEAD_Mode(Cipher_Dir dir, + const std::string& cipher_name, size_t cipher_keylen, const std::string& mac_name, size_t mac_keylen, @@ -33,18 +36,23 @@ TLS_CBC_HMAC_AEAD_Mode::TLS_CBC_HMAC_AEAD_Mode(const std::string& cipher_name, m_mac_keylen(mac_keylen), m_use_encrypt_then_mac(use_encrypt_then_mac) { - m_cipher = BlockCipher::create_or_throw(m_cipher_name); m_mac = MessageAuthenticationCode::create_or_throw("HMAC(" + m_mac_name + ")"); + std::unique_ptr<BlockCipher> cipher = BlockCipher::create_or_throw(m_cipher_name); m_tag_size = m_mac->output_length(); - m_block_size = m_cipher->block_size(); + m_block_size = cipher->block_size(); m_iv_size = use_explicit_iv ? m_block_size : 0; + + if(dir == ENCRYPTION) + m_cbc.reset(new CBC_Encryption(cipher.release(), new Null_Padding)); + else + m_cbc.reset(new CBC_Decryption(cipher.release(), new Null_Padding)); } void TLS_CBC_HMAC_AEAD_Mode::clear() { - cipher().clear(); + cbc().clear(); mac().clear(); reset(); } @@ -85,7 +93,7 @@ void TLS_CBC_HMAC_AEAD_Mode::key_schedule(const uint8_t key[], size_t keylen) if(keylen != m_cipher_keylen + m_mac_keylen) throw Invalid_Key_Length(name(), keylen); - cipher().set_key(&key[0], m_cipher_keylen); + cbc().set_key(&key[0], m_cipher_keylen); mac().set_key(&key[m_cipher_keylen], m_mac_keylen); } @@ -145,17 +153,10 @@ void TLS_CBC_HMAC_AEAD_Encryption::cbc_encrypt_record(uint8_t buf[], size_t buf_ const size_t blocks = buf_size / block_size(); BOTAN_ASSERT(buf_size % block_size() == 0, "Valid CBC input"); - xor_buf(buf, cbc_state().data(), block_size()); - cipher().encrypt(buf); + cbc().start(cbc_state()); + cbc().process(buf, buf_size); - for(size_t i = 1; i < blocks; ++i) - { - xor_buf(&buf[block_size()*i], &buf[block_size()*(i-1)], block_size()); - cipher().encrypt(&buf[block_size()*i]); - } - - cbc_state().assign(&buf[block_size()*(blocks-1)], - &buf[block_size()*blocks]); + cbc_state().assign(buf + buf_size - block_size(), buf + buf_size); } size_t TLS_CBC_HMAC_AEAD_Encryption::output_length(size_t input_length) const @@ -253,32 +254,14 @@ uint16_t check_tls_cbc_padding(const uint8_t record[], size_t record_len) void TLS_CBC_HMAC_AEAD_Decryption::cbc_decrypt_record(uint8_t record_contents[], size_t record_len) { - if(record_len % block_size() != 0) - throw Decoding_Error("Input CBC ciphertext is not a multiple of block size"); - - const size_t blocks = record_len / block_size(); + if(record_len == 0 || record_len % block_size() != 0) + throw Decoding_Error("Received TLS CBC ciphertext with invalid length"); - BOTAN_ASSERT(blocks >= 1, "At least one ciphertext block"); - - uint8_t* buf = record_contents; - - secure_vector<uint8_t> last_ciphertext(block_size()); - copy_mem(last_ciphertext.data(), buf, block_size()); - - cipher().decrypt(buf); - xor_buf(buf, cbc_state().data(), block_size()); - - secure_vector<uint8_t> last_ciphertext2; - - for(size_t i = 1; i < blocks; ++i) - { - last_ciphertext2.assign(&buf[block_size()*i], &buf[block_size()*(i+1)]); - cipher().decrypt(&buf[block_size()*i]); - xor_buf(&buf[block_size()*i], last_ciphertext.data(), block_size()); - std::swap(last_ciphertext, last_ciphertext2); - } + cbc().start(cbc_state()); + cbc_state().assign(record_contents + record_len - block_size(), + record_contents + record_len); - cbc_state().assign(last_ciphertext.begin(), last_ciphertext.end()); + cbc().process(record_contents, record_len); } size_t TLS_CBC_HMAC_AEAD_Decryption::output_length(size_t) const diff --git a/src/lib/tls/tls_cbc/tls_cbc.h b/src/lib/tls/tls_cbc/tls_cbc.h index f09e0ad39..012b9e51f 100644 --- a/src/lib/tls/tls_cbc/tls_cbc.h +++ b/src/lib/tls/tls_cbc/tls_cbc.h @@ -45,7 +45,8 @@ class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Mode : public AEAD_Mode void reset() override final; protected: - TLS_CBC_HMAC_AEAD_Mode(const std::string& cipher_name, + TLS_CBC_HMAC_AEAD_Mode(Cipher_Dir direction, + const std::string& cipher_name, size_t cipher_keylen, const std::string& mac_name, size_t mac_keylen, @@ -59,11 +60,7 @@ class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Mode : public AEAD_Mode bool use_encrypt_then_mac() const { return m_use_encrypt_then_mac; } - BlockCipher& cipher() const - { - BOTAN_ASSERT_NONNULL(m_cipher); - return *m_cipher; - } + Cipher_Mode& cbc() const { return *m_cbc; } MessageAuthenticationCode& mac() const { @@ -91,7 +88,7 @@ class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Mode : public AEAD_Mode size_t m_block_size; bool m_use_encrypt_then_mac; - std::unique_ptr<BlockCipher> m_cipher; + std::unique_ptr<Cipher_Mode> m_cbc; std::unique_ptr<MessageAuthenticationCode> m_mac; secure_vector<uint8_t> m_cbc_state; @@ -113,7 +110,8 @@ class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Encryption final : public TLS_CBC_HMAC_AE const size_t mac_keylen, bool use_explicit_iv, bool use_encrypt_then_mac) : - TLS_CBC_HMAC_AEAD_Mode(cipher_algo, + TLS_CBC_HMAC_AEAD_Mode(ENCRYPTION, + cipher_algo, cipher_keylen, mac_algo, mac_keylen, @@ -146,7 +144,8 @@ class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Decryption final : public TLS_CBC_HMAC_AE const size_t mac_keylen, bool use_explicit_iv, bool use_encrypt_then_mac) : - TLS_CBC_HMAC_AEAD_Mode(cipher_algo, + TLS_CBC_HMAC_AEAD_Mode(DECRYPTION, + cipher_algo, cipher_keylen, mac_algo, mac_keylen, @@ -162,7 +161,7 @@ class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Decryption final : public TLS_CBC_HMAC_AE private: void cbc_decrypt_record(uint8_t record_contents[], size_t record_len); - + void perform_additional_compressions(size_t plen, size_t padlen); }; |