aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/test_modes.cpp
diff options
context:
space:
mode:
authorDaniel Neus <[email protected]>2016-07-20 22:26:26 +0200
committerDaniel Neus <[email protected]>2016-11-08 22:16:09 +0100
commit06b44d8ed339b3a467f10a326fd209b0b9496060 (patch)
tree24c3bf3f20ba697a658d6d009d0cdb7be8a3e41f /src/tests/test_modes.cpp
parent523b2a4ca48fa5cf04ea371aabe7167ce2e5cd13 (diff)
Cipher_Mode and AEAD_Mode improvements
See PR #552 - Add Cipher_Mode::reset() which resets just the message specific state and allows encrypting again under the existing key - In Cipher_Mode::clear() (at some planes) use cipher->clear() instead of resetting the pointer which would make the cipher object unusable - EAX_Decryption::output_length() bugfix?! Now its possible to decrypt an empty ciphertext (just a tag) - Bugfix for GCM_Decryption::finish() - set tag length in GCM_Mode::name() - Cipher_Mode tests: add tests for reset()and process() - AEAD_Mode tests: add tests for reset(), clear(), update() and process()
Diffstat (limited to 'src/tests/test_modes.cpp')
-rw-r--r--src/tests/test_modes.cpp71
1 files changed, 70 insertions, 1 deletions
diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp
index ada4d5b82..4949d1c98 100644
--- a/src/tests/test_modes.cpp
+++ b/src/tests/test_modes.cpp
@@ -1,5 +1,6 @@
/*
* (C) 2014,2015 Jack Lloyd
+* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -44,22 +45,90 @@ class Cipher_Mode_Tests : public Text_Based_Test
result.test_eq("mode not authenticated", enc->authenticated(), false);
+ // Test to make sure reset() resets what we need it to
+ enc->set_key(mutate_vec(key));
+ Botan::secure_vector<byte> garbage = Test::rng().random_vec(enc->update_granularity());
+ enc->start(mutate_vec(nonce));
+ enc->update(garbage);
+
+ enc->reset();
+
enc->set_key(key);
enc->start(nonce);
Botan::secure_vector<uint8_t> buf(input.begin(), input.end());
// TODO: should first update if possible
enc->finish(buf);
-
result.test_eq("encrypt", buf, expected);
+ // additionally test process() if possible
+ size_t update_granularity = enc->update_granularity();
+ size_t input_length = input.size();
+ size_t min_final_bytes = enc->minimum_final_size();
+ if(input_length > (update_granularity + min_final_bytes))
+ {
+ // reset state first
+ enc->reset();
+
+ enc->start(nonce);
+ buf.assign(input.begin(), input.end());
+
+ // we can process at max input_length
+ const size_t max_blocks_to_process = (input_length - min_final_bytes) / update_granularity;
+ const size_t bytes_to_process = max_blocks_to_process * update_granularity;
+
+ const size_t bytes_written = enc->process(buf.data(), bytes_to_process);
+
+ result.test_eq("correct number of bytes processed", bytes_written, bytes_to_process);
+
+ const size_t remaining = input_length - bytes_to_process;
+
+ enc->finish(buf, bytes_to_process);
+ result.test_eq("encrypt", buf, expected);
+ }
+
+ // decryption
buf.assign(expected.begin(), expected.end());
+ // Test to make sure reset() resets what we need it to
+ dec->set_key(mutate_vec(key));
+ garbage = Test::rng().random_vec(dec->update_granularity());
+ dec->start(mutate_vec(nonce));
+ dec->update(garbage);
+
+ dec->reset();
+
dec->set_key(key);
dec->start(nonce);
dec->finish(buf);
result.test_eq("decrypt", buf, input);
+ // additionally test process() if possible
+ update_granularity = dec->update_granularity();
+ input_length = expected.size();
+ min_final_bytes = dec->minimum_final_size();
+ if(input_length > (update_granularity + min_final_bytes))
+ {
+ // reset state first
+ dec->reset();
+
+ dec->start(nonce);
+ buf.assign(expected.begin(), expected.end());
+
+ // we can process at max input_length
+ const size_t max_blocks_to_process = (input_length - min_final_bytes) / update_granularity;
+ const size_t bytes_to_process = max_blocks_to_process * update_granularity;
+
+ const size_t bytes_written = dec->process(buf.data(), bytes_to_process);
+
+ result.test_eq("correct number of bytes processed", bytes_written, bytes_to_process);
+
+ const size_t remaining = input_length - bytes_to_process;
+
+ dec->finish(buf, bytes_to_process);
+ result.test_eq("decrypt", buf, input);
+ }
+
enc->clear();
dec->clear();