aboutsummaryrefslogtreecommitdiffstats
path: root/src/modes/ecb/ecb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modes/ecb/ecb.cpp')
-rw-r--r--src/modes/ecb/ecb.cpp191
1 files changed, 154 insertions, 37 deletions
diff --git a/src/modes/ecb/ecb.cpp b/src/modes/ecb/ecb.cpp
index 8da0a4802..988a8b3f2 100644
--- a/src/modes/ecb/ecb.cpp
+++ b/src/modes/ecb/ecb.cpp
@@ -9,22 +9,60 @@
namespace Botan {
+namespace {
+
+const u32bit PARALLEL_BLOCKS = BOTAN_PARALLEL_BLOCKS_ECB;
+
+}
+
/*
-* Verify the IV is not set
+* ECB_Encryption Constructor
*/
-bool ECB::valid_iv_size(u32bit iv_size) const
+ECB_Encryption::ECB_Encryption(BlockCipher* ciph,
+ BlockCipherModePaddingMethod* pad)
{
- if(iv_size == 0)
- return true;
- return false;
+ cipher = ciph;
+ padder = pad;
+
+ plaintext.create(cipher->BLOCK_SIZE);
+ ciphertext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS);
+
+ position = 0;
+ }
+
+/*
+* ECB_Encryption Constructor
+*/
+ECB_Encryption::ECB_Encryption(BlockCipher* ciph,
+ BlockCipherModePaddingMethod* pad,
+ const SymmetricKey& key)
+ {
+ cipher = ciph;
+ padder = pad;
+
+ plaintext.create(cipher->BLOCK_SIZE);
+ ciphertext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS);
+
+ position = 0;
+
+ cipher->set_key(key);
+ }
+
+/*
+* ECB_Encryption Destructor
+*/
+ECB_Encryption::~ECB_Encryption()
+ {
+ delete cipher;
+ delete padder;
}
/*
* Return an ECB mode name
*/
-std::string ECB::name() const
+std::string ECB_Encryption::name() const
{
- return (cipher->name() + "/" + mode_name + "/" + padder->name());
+ return (cipher->name() + "/ECB/" + padder->name());
}
/*
@@ -32,23 +70,34 @@ std::string ECB::name() const
*/
void ECB_Encryption::write(const byte input[], u32bit length)
{
- buffer.copy(position, input, length);
- if(position + length >= BLOCK_SIZE)
+ const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
+
+ if(position)
{
- cipher->encrypt(buffer);
- send(buffer, BLOCK_SIZE);
- input += (BLOCK_SIZE - position);
- length -= (BLOCK_SIZE - position);
- while(length >= BLOCK_SIZE)
+ plaintext.copy(position, input, length);
+
+ if(position + length >= BLOCK_SIZE)
{
- cipher->encrypt(input, buffer);
- send(buffer, BLOCK_SIZE);
- input += BLOCK_SIZE;
- length -= BLOCK_SIZE;
+ cipher->encrypt(plaintext, ciphertext);
+ send(ciphertext, BLOCK_SIZE);
+ input += (BLOCK_SIZE - position);
+ length -= (BLOCK_SIZE - position);
+ position = 0;
}
- buffer.copy(input, length);
- position = 0;
}
+
+ while(length >= BLOCK_SIZE)
+ {
+ const u32bit to_proc =
+ std::min<u32bit>(length, ciphertext.size()) / BLOCK_SIZE;
+
+ cipher->encrypt_n(input, ciphertext, to_proc);
+ send(ciphertext, to_proc * BLOCK_SIZE);
+ input += to_proc * BLOCK_SIZE;
+ length -= to_proc * BLOCK_SIZE;
+ }
+
+ plaintext.copy(position, input, length);
position += length;
}
@@ -57,6 +106,8 @@ void ECB_Encryption::write(const byte input[], u32bit length)
*/
void ECB_Encryption::end_msg()
{
+ const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
+
SecureVector<byte> padding(BLOCK_SIZE);
padder->pad(padding, padding.size(), position);
write(padding, padder->pad_bytes(BLOCK_SIZE, position));
@@ -65,27 +116,93 @@ void ECB_Encryption::end_msg()
}
/*
+* ECB_Decryption Constructor
+*/
+ECB_Decryption::ECB_Decryption(BlockCipher* ciph,
+ BlockCipherModePaddingMethod* pad)
+ {
+ cipher = ciph;
+ padder = pad;
+
+ ciphertext.create(cipher->BLOCK_SIZE);
+ plaintext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS);
+
+ position = 0;
+ }
+
+/*
+* ECB_Decryption Constructor
+*/
+ECB_Decryption::ECB_Decryption(BlockCipher* ciph,
+ BlockCipherModePaddingMethod* pad,
+ const SymmetricKey& key)
+ {
+ cipher = ciph;
+ padder = pad;
+
+ ciphertext.create(cipher->BLOCK_SIZE);
+ plaintext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS);
+
+ position = 0;
+
+ cipher->set_key(key);
+ }
+
+/*
+* ECB_Decryption Destructor
+*/
+ECB_Decryption::~ECB_Decryption()
+ {
+ delete cipher;
+ delete padder;
+ }
+
+/*
+* Return an ECB mode name
+*/
+std::string ECB_Decryption::name() const
+ {
+ return (cipher->name() + "/ECB/" + padder->name());
+ }
+
+/*
* Decrypt in ECB mode
*/
void ECB_Decryption::write(const byte input[], u32bit length)
{
- buffer.copy(position, input, length);
- if(position + length > BLOCK_SIZE)
+ const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
+
+ if(position)
{
- cipher->decrypt(buffer);
- send(buffer, BLOCK_SIZE);
- input += (BLOCK_SIZE - position);
- length -= (BLOCK_SIZE - position);
- while(length > BLOCK_SIZE)
+ ciphertext.copy(position, input, length);
+
+ if(position + length > BLOCK_SIZE)
{
- cipher->decrypt(input, buffer);
- send(buffer, BLOCK_SIZE);
- input += BLOCK_SIZE;
- length -= BLOCK_SIZE;
+ cipher->decrypt(ciphertext, plaintext);
+ send(plaintext, BLOCK_SIZE);
+ input += (BLOCK_SIZE - position);
+ length -= (BLOCK_SIZE - position);
+ position = 0;
}
- buffer.copy(input, length);
- position = 0;
}
+
+ while(length > BLOCK_SIZE)
+ {
+ /* Always leave at least 1 byte left over, to ensure that (as long
+ as the input message actually is a multiple of the block size)
+ we will have the full final block left over in end_msg so as
+ to remove the padding
+ */
+ const u32bit to_proc =
+ std::min<u32bit>(length - 1, plaintext.size()) / BLOCK_SIZE;
+
+ cipher->decrypt_n(input, plaintext, to_proc);
+ send(plaintext, to_proc * BLOCK_SIZE);
+ input += to_proc * BLOCK_SIZE;
+ length -= to_proc * BLOCK_SIZE;
+ }
+
+ ciphertext.copy(position, input, length);
position += length;
}
@@ -94,11 +211,11 @@ void ECB_Decryption::write(const byte input[], u32bit length)
*/
void ECB_Decryption::end_msg()
{
- if(position != BLOCK_SIZE)
+ if(position != cipher->BLOCK_SIZE)
throw Decoding_Error(name());
- cipher->decrypt(buffer);
- send(buffer, padder->unpad(buffer, BLOCK_SIZE));
- state = buffer;
+
+ cipher->decrypt(ciphertext);
+ send(ciphertext, padder->unpad(ciphertext, cipher->BLOCK_SIZE));
position = 0;
}