diff options
Diffstat (limited to 'src/cts.cpp')
-rw-r--r-- | src/cts.cpp | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/cts.cpp b/src/cts.cpp new file mode 100644 index 000000000..673df84b8 --- /dev/null +++ b/src/cts.cpp @@ -0,0 +1,175 @@ +/************************************************* +* CTS Mode Source File * +* (C) 1999-2006 The Botan Project * +*************************************************/ + +#include <botan/cts.h> +#include <botan/lookup.h> +#include <botan/bit_ops.h> +#include <algorithm> + +namespace Botan { + +/************************************************* +* CTS Encryption Constructor * +*************************************************/ +CTS_Encryption::CTS_Encryption(const std::string& cipher_name) : + BlockCipherMode(cipher_name, "CTS", block_size_of(cipher_name), 0, 2) + { + } + +/************************************************* +* CTS Encryption Constructor * +*************************************************/ +CTS_Encryption::CTS_Encryption(const std::string& cipher_name, + const SymmetricKey& key, + const InitializationVector& iv) : + BlockCipherMode(cipher_name, "CTS", block_size_of(cipher_name), 0, 2) + { + set_key(key); + set_iv(iv); + } + +/************************************************* +* Encrypt a block * +*************************************************/ +void CTS_Encryption::encrypt(const byte block[]) + { + xor_buf(state, block, BLOCK_SIZE); + cipher->encrypt(state); + send(state, BLOCK_SIZE); + } + +/************************************************* +* Encrypt in CTS mode * +*************************************************/ +void CTS_Encryption::write(const byte input[], u32bit length) + { + u32bit copied = std::min(BUFFER_SIZE - position, length); + buffer.copy(position, input, copied); + length -= copied; + input += copied; + position += copied; + + if(length == 0) return; + + encrypt(buffer); + if(length > BLOCK_SIZE) + { + encrypt(buffer + BLOCK_SIZE); + while(length > 2*BLOCK_SIZE) + { + encrypt(input); + length -= BLOCK_SIZE; + input += BLOCK_SIZE; + } + position = 0; + } + else + { + copy_mem(buffer.begin(), buffer + BLOCK_SIZE, BLOCK_SIZE); + position = BLOCK_SIZE; + } + buffer.copy(position, input, length); + position += length; + } + +/************************************************* +* Finish encrypting in CTS mode * +*************************************************/ +void CTS_Encryption::end_msg() + { + if(position < BLOCK_SIZE + 1) + throw Exception("CTS_Encryption: insufficient data to encrypt"); + xor_buf(state, buffer, BLOCK_SIZE); + cipher->encrypt(state); + SecureVector<byte> cn = state; + clear_mem(buffer + position, BUFFER_SIZE - position); + encrypt(buffer + BLOCK_SIZE); + send(cn, position - BLOCK_SIZE); + } + +/************************************************* +* CTS Decryption Constructor * +*************************************************/ +CTS_Decryption::CTS_Decryption(const std::string& cipher_name) : + BlockCipherMode(cipher_name, "CTS", block_size_of(cipher_name), 0, 2) + { + temp.create(BLOCK_SIZE); + } + +/************************************************* +* CTS Decryption Constructor * +*************************************************/ +CTS_Decryption::CTS_Decryption(const std::string& cipher_name, + const SymmetricKey& key, + const InitializationVector& iv) : + BlockCipherMode(cipher_name, "CTS", block_size_of(cipher_name), 0, 2) + { + temp.create(BLOCK_SIZE); + set_key(key); + set_iv(iv); + } + +/************************************************* +* Decrypt a block * +*************************************************/ +void CTS_Decryption::decrypt(const byte block[]) + { + cipher->decrypt(block, temp); + xor_buf(temp, state, BLOCK_SIZE); + send(temp, BLOCK_SIZE); + state.copy(block, BLOCK_SIZE); + } + +/************************************************* +* Decrypt in CTS mode * +*************************************************/ +void CTS_Decryption::write(const byte input[], u32bit length) + { + u32bit copied = std::min(BUFFER_SIZE - position, length); + buffer.copy(position, input, copied); + length -= copied; + input += copied; + position += copied; + + if(length == 0) return; + + decrypt(buffer); + if(length > BLOCK_SIZE) + { + decrypt(buffer + BLOCK_SIZE); + while(length > 2*BLOCK_SIZE) + { + decrypt(input); + length -= BLOCK_SIZE; + input += BLOCK_SIZE; + } + position = 0; + } + else + { + copy_mem(buffer.begin(), buffer + BLOCK_SIZE, BLOCK_SIZE); + position = BLOCK_SIZE; + } + buffer.copy(position, input, length); + position += length; + } + +/************************************************* +* Finish decrypting in CTS mode * +*************************************************/ +void CTS_Decryption::end_msg() + { + cipher->decrypt(buffer, temp); + xor_buf(temp, buffer + BLOCK_SIZE, position - BLOCK_SIZE); + SecureVector<byte> xn = temp; + copy_mem(buffer + position, xn + (position - BLOCK_SIZE), + BUFFER_SIZE - position); + cipher->decrypt(buffer + BLOCK_SIZE, temp); + xor_buf(temp, state, BLOCK_SIZE); + send(temp, BLOCK_SIZE); + send(xn, position - BLOCK_SIZE); + } + +} |