diff options
author | Daniel Neus <[email protected]> | 2016-07-20 22:26:26 +0200 |
---|---|---|
committer | Daniel Neus <[email protected]> | 2016-11-08 22:16:09 +0100 |
commit | 06b44d8ed339b3a467f10a326fd209b0b9496060 (patch) | |
tree | 24c3bf3f20ba697a658d6d009d0cdb7be8a3e41f /src/tests/test_modes.cpp | |
parent | 523b2a4ca48fa5cf04ea371aabe7167ce2e5cd13 (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.cpp | 71 |
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(); |