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 /src | |
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.
Diffstat (limited to 'src')
-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); }; |