aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRené Korthaus <[email protected]>2016-07-07 15:14:28 +0200
committerRené Korthaus <[email protected]>2016-07-11 10:43:04 +0200
commit5fb452e9045cf8179faca5c76e7fa8c0fcd815cc (patch)
tree6b6d11defac283f88dea540edb89e91257c709a1
parent2b3f4270371d376e1500b68f4955548b659d2011 (diff)
Add test vectors for block cipher padding modes
Exports get_bc_pad() to be used from tests. Adds separate handcrafted tests for block cipher padding modes. They were previously only tested implicitly during the block cipher modes of operation tests, though not all padding modes were covered. And in case a mode of operation is not part of the enabled modules, the previously tested padding modes are not covered at all. Fixes an off-by-one bug in the previously untested ANSI X9.23 padding mode, where the number of zero bytes in the pad was one more than allowed by the standard.
-rw-r--r--src/lib/modes/mode_pad/mode_pad.cpp4
-rw-r--r--src/lib/modes/mode_pad/mode_pad.h3
-rw-r--r--src/tests/data/pad.vec83
-rw-r--r--src/tests/test_pad.cpp59
4 files changed, 147 insertions, 2 deletions
diff --git a/src/lib/modes/mode_pad/mode_pad.cpp b/src/lib/modes/mode_pad/mode_pad.cpp
index 0f1df9e8a..7b4546c86 100644
--- a/src/lib/modes/mode_pad/mode_pad.cpp
+++ b/src/lib/modes/mode_pad/mode_pad.cpp
@@ -69,8 +69,10 @@ void ANSI_X923_Padding::add_padding(secure_vector<byte>& buffer,
{
const byte pad_value = static_cast<byte>(block_size - last_byte_pos);
- for(size_t i = last_byte_pos; i < block_size; ++i)
+ for(size_t i = last_byte_pos; i < block_size-1; ++i)
+ {
buffer.push_back(0);
+ }
buffer.push_back(pad_value);
}
diff --git a/src/lib/modes/mode_pad/mode_pad.h b/src/lib/modes/mode_pad/mode_pad.h
index 0a775b1ea..bc2b7c132 100644
--- a/src/lib/modes/mode_pad/mode_pad.h
+++ b/src/lib/modes/mode_pad/mode_pad.h
@@ -32,6 +32,7 @@ class BOTAN_DLL BlockCipherModePaddingMethod
/**
* @param block the last block
* @param size the of the block
+ * @return number of padding bytes
*/
virtual size_t unpad(const byte block[],
size_t size) const = 0;
@@ -119,7 +120,7 @@ class BOTAN_DLL Null_Padding final : public BlockCipherModePaddingMethod
std::string name() const override { return "NoPadding"; }
};
-BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec);
+BOTAN_DLL BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec);
}
diff --git a/src/tests/data/pad.vec b/src/tests/data/pad.vec
new file mode 100644
index 000000000..3c47959c9
--- /dev/null
+++ b/src/tests/data/pad.vec
@@ -0,0 +1,83 @@
+[NoPadding]
+In = FFFFFF
+Out = FFFFFF
+Blocksize = 16
+
+In = FFFFFFFF
+Out = FFFFFFFF
+Blocksize = 32
+
+In = FFFFFFFFFFFF
+Out = FFFFFFFFFFFF
+Blocksize = 64
+
+In = FFFFFFFFFFFFFFFF
+Out = FFFFFFFFFFFFFFFF
+Blocksize = 8
+
+In = FFFFFFFFFFFFFFFFFF
+Out = FFFFFFFFFFFFFFFFFF
+Blocksize = 8
+
+[PKCS7]
+In = FFFFFF
+Out = FFFFFF0D0D0D0D0D0D0D0D0D0D0D0D0D
+Blocksize = 16
+
+In = FFFFFFFF
+Out = FFFFFFFF1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C
+Blocksize = 32
+
+In = FFFFFFFFFFFF
+Out = FFFFFFFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A
+Blocksize = 64
+
+In = FFFFFFFFFFFFFFFF
+Out = FFFFFFFFFFFFFFFF0808080808080808
+Blocksize = 8
+
+In = FFFFFFFFFFFFFFFFFF
+Out = FFFFFFFFFFFFFFFFFF07070707070707
+Blocksize = 8
+
+[OneAndZeros]
+In = FFFFFF
+Out = FFFFFF80000000000000000000000000
+Blocksize = 16
+
+In = FFFFFFFF
+Out = FFFFFFFF80000000000000000000000000000000000000000000000000000000
+Blocksize = 32
+
+In = FFFFFFFFFFFF
+Out = FFFFFFFFFFFF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Blocksize = 64
+
+In = FFFFFFFFFFFFFFFF
+Out = FFFFFFFFFFFFFFFF8000000000000000
+Blocksize = 8
+
+In = FFFFFFFFFFFFFFFFFF
+Out = FFFFFFFFFFFFFFFFFF80000000000000
+Blocksize = 8
+
+[X9.23]
+In = FFFFFF
+Out = FFFFFF0000000000000000000000000D
+Blocksize = 16
+
+In = FFFFFFFF
+Out = FFFFFFFF0000000000000000000000000000000000000000000000000000001C
+Blocksize = 32
+
+In = FFFFFFFFFFFF
+Out = FFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003A
+Blocksize = 64
+
+In = FFFFFFFFFFFFFFFF
+Out = FFFFFFFFFFFFFFFF0000000000000008
+Blocksize = 8
+
+In = FFFFFFFFFFFFFFFFFF
+Out = FFFFFFFFFFFFFFFFFF00000000000007
+Blocksize = 8 \ No newline at end of file
diff --git a/src/tests/test_pad.cpp b/src/tests/test_pad.cpp
new file mode 100644
index 000000000..43ac3dfb5
--- /dev/null
+++ b/src/tests/test_pad.cpp
@@ -0,0 +1,59 @@
+/*
+* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+
+#if defined(BOTAN_HAS_CIPHER_MODE_PADDING)
+ #include <botan/mode_pad.h>
+#endif
+
+namespace Botan_Tests {
+
+#if defined(BOTAN_HAS_CIPHER_MODE_PADDING)
+
+class Cipher_Mode_Padding_Tests : public Text_Based_Test
+ {
+ public:
+ Cipher_Mode_Padding_Tests() :
+ Text_Based_Test("pad.vec", {"In", "Out", "Blocksize"})
+ {}
+
+ Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
+ {
+ const std::vector<uint8_t> input = get_req_bin(vars, "In");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
+ const size_t block_size = get_req_sz(vars, "Blocksize");
+
+ Test::Result result(algo);
+
+ std::unique_ptr<Botan::BlockCipherModePaddingMethod> pad(Botan::get_bc_pad(algo));
+
+ if(!pad)
+ {
+ result.test_failure("Invalid padding method: " + algo);
+ return result;
+ }
+
+ Botan::secure_vector<uint8_t> buf(input.begin(), input.end());
+ pad->add_padding(buf, input.size() % block_size, block_size);
+ result.test_eq("pad", buf, expected);
+
+ buf.assign(expected.begin(), expected.end());
+
+ const size_t last_block = ( buf.size() < block_size ) ? 0 : buf.size() - block_size;
+ const size_t pad_bytes = block_size - pad->unpad(&buf[last_block], block_size);
+ buf.resize(buf.size() - pad_bytes); // remove padding
+ result.test_eq("unpad", buf, input);
+
+ return result;
+ }
+ };
+
+BOTAN_REGISTER_TEST("bc-padding", Cipher_Mode_Padding_Tests);
+
+#endif
+
+}