aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-10-19 19:00:53 -0400
committerJack Lloyd <[email protected]>2017-10-19 19:00:53 -0400
commitd3c5dab077aff20a78bd582a3fd9c1591dc826a7 (patch)
treef405981ec65fb32225f77ca3540463bfad8f097a /src
parent03d4bceef5caeab584e03a7cf0e3ac3a3fb0d420 (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.txt5
-rw-r--r--src/lib/tls/tls_cbc/tls_cbc.cpp61
-rw-r--r--src/lib/tls/tls_cbc/tls_cbc.h19
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);
};