aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-08-09 09:58:21 -0400
committerJack Lloyd <[email protected]>2018-08-09 09:58:21 -0400
commit42f69c656f78bc44c9bf8bde479b9cca91454ca6 (patch)
tree84ee352e3f2543f947151834821acce5f9226f1f /src
parent0ef977d5d3887e994f5aa5c6271c428428870588 (diff)
Add Tweakable_Block_Cipher class
Diffstat (limited to 'src')
-rw-r--r--src/lib/block/block_cipher.h24
-rw-r--r--src/lib/block/threefish_512/threefish_512.h5
-rw-r--r--src/tests/test_block.cpp13
3 files changed, 28 insertions, 14 deletions
diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h
index 939382fc0..5d490ae49 100644
--- a/src/lib/block/block_cipher.h
+++ b/src/lib/block/block_cipher.h
@@ -198,10 +198,26 @@ class BOTAN_PUBLIC_API(2,0) BlockCipher : public SymmetricAlgorithm
};
/**
+* Tweakable block ciphers allow setting a tweak which is a non-keyed
+* value which affects the encryption/decryption operation.
+*/
+class BOTAN_PUBLIC_API(2,8) Tweakable_Block_Cipher : public BlockCipher
+ {
+ public:
+ /**
+ * Set the tweak value. This must be called after setting a key. The value
+ * persists until either set_tweak, set_key, or clear is called.
+ * Different algorithms support different tweak length(s). If called with
+ * an unsupported length, Invalid_Argument will be thrown.
+ */
+ virtual void set_tweak(const uint8_t tweak[], size_t len) = 0;
+ };
+
+/**
* Represents a block cipher with a single fixed block size
*/
-template<size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1>
-class Block_Cipher_Fixed_Params : public BlockCipher
+template<size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1, typename BaseClass = BlockCipher>
+class Block_Cipher_Fixed_Params : public BaseClass
{
public:
enum { BLOCK_SIZE = BS };
@@ -213,7 +229,7 @@ class Block_Cipher_Fixed_Params : public BlockCipher
size_t blocks) const final override
{
xor_buf(data, mask, blocks * BS);
- encrypt_n(data, data, blocks);
+ this->encrypt_n(data, data, blocks);
xor_buf(data, mask, blocks * BS);
}
@@ -222,7 +238,7 @@ class Block_Cipher_Fixed_Params : public BlockCipher
size_t blocks) const final override
{
xor_buf(data, mask, blocks * BS);
- decrypt_n(data, data, blocks);
+ this->decrypt_n(data, data, blocks);
xor_buf(data, mask, blocks * BS);
}
diff --git a/src/lib/block/threefish_512/threefish_512.h b/src/lib/block/threefish_512/threefish_512.h
index 8b39c75c5..2e936b25f 100644
--- a/src/lib/block/threefish_512/threefish_512.h
+++ b/src/lib/block/threefish_512/threefish_512.h
@@ -15,13 +15,14 @@ namespace Botan {
/**
* Threefish-512
*/
-class BOTAN_PUBLIC_API(2,0) Threefish_512 final : public Block_Cipher_Fixed_Params<64, 64>
+class BOTAN_PUBLIC_API(2,0) Threefish_512 final :
+ public Block_Cipher_Fixed_Params<64, 64, 0, 1, Tweakable_Block_Cipher>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
- void set_tweak(const uint8_t tweak[], size_t len);
+ void set_tweak(const uint8_t tweak[], size_t len) override;
void clear() override;
std::string provider() const override;
diff --git a/src/tests/test_block.cpp b/src/tests/test_block.cpp
index 7a5c8492b..66ef9e24b 100644
--- a/src/tests/test_block.cpp
+++ b/src/tests/test_block.cpp
@@ -10,10 +10,6 @@
#include <botan/block_cipher.h>
-#if defined(BOTAN_HAS_THREEFISH_512)
- #include <botan/threefish_512.h>
-#endif
-
namespace Botan_Tests {
class Block_Cipher_Tests final : public Text_Based_Test
@@ -94,10 +90,11 @@ class Block_Cipher_Tests final : public Text_Based_Test
if(tweak.size() > 0)
{
- Botan::Threefish_512* t512 = dynamic_cast<Botan::Threefish_512*>(cipher.get());
- result.confirm("Only Threefish supports tweaks", t512);
- if(t512)
- t512->set_tweak(tweak.data(), tweak.size());
+ Botan::Tweakable_Block_Cipher* tbc = dynamic_cast<Botan::Tweakable_Block_Cipher*>(cipher.get());
+ if(tbc == nullptr)
+ result.test_failure("Tweak set in test data but cipher is not a Tweakable_Block_Cipher");
+ else
+ tbc->set_tweak(tweak.data(), tweak.size());
}
// Test that clone works and does not affect parent object