aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cmd/compress.cpp18
-rw-r--r--src/cmd/speed.cpp4
-rw-r--r--src/lib/algo_base/algo_registry.cpp20
-rw-r--r--src/lib/algo_base/algo_registry.h146
-rw-r--r--src/lib/algo_base/scan_name.cpp16
-rw-r--r--src/lib/algo_base/scan_name.h16
-rw-r--r--src/lib/algo_base/transform.h19
-rw-r--r--src/lib/block/aes/aes.cpp7
-rw-r--r--src/lib/block/aes_ni/aes_ni.cpp7
-rw-r--r--src/lib/block/aes_ssse3/aes_ssse3.cpp6
-rw-r--r--src/lib/block/block_cipher.h2
-rw-r--r--src/lib/block/blowfish/blowfish.cpp4
-rw-r--r--src/lib/block/camellia/camellia.cpp6
-rw-r--r--src/lib/block/cascade/cascade.cpp19
-rw-r--r--src/lib/block/cast/cast128.cpp5
-rw-r--r--src/lib/block/cast/cast256.cpp5
-rw-r--r--src/lib/block/des/des.cpp6
-rw-r--r--src/lib/block/des/desx.cpp4
-rw-r--r--src/lib/block/gost_28147/gost_28147.cpp5
-rw-r--r--src/lib/block/idea/idea.cpp4
-rw-r--r--src/lib/block/idea_sse2/idea_sse2.cpp4
-rw-r--r--src/lib/block/info.txt8
-rw-r--r--src/lib/block/kasumi/kasumi.cpp5
-rw-r--r--src/lib/block/lion/lion.cpp26
-rw-r--r--src/lib/block/mars/mars.cpp5
-rw-r--r--src/lib/block/misty1/misty1.cpp14
-rw-r--r--src/lib/block/misty1/misty1.h8
-rw-r--r--src/lib/block/noekeon/noekeon.cpp5
-rw-r--r--src/lib/block/noekeon_simd/noekeon_simd.cpp3
-rw-r--r--src/lib/block/rc2/rc2.cpp5
-rw-r--r--src/lib/block/rc5/rc5.cpp6
-rw-r--r--src/lib/block/rc6/rc6.cpp6
-rw-r--r--src/lib/block/safer/safer_sk.cpp5
-rw-r--r--src/lib/block/seed/seed.cpp4
-rw-r--r--src/lib/block/serpent/serpent.cpp9
-rw-r--r--src/lib/block/serpent_simd/serp_simd.cpp4
-rw-r--r--src/lib/block/serpent_x86_32/serp_x86_32.cpp4
-rw-r--r--src/lib/block/tea/tea.cpp4
-rw-r--r--src/lib/block/threefish/threefish.cpp10
-rw-r--r--src/lib/block/threefish/threefish.h3
-rw-r--r--src/lib/block/threefish_avx2/threefish_avx2.cpp6
-rw-r--r--src/lib/block/threefish_avx2/threefish_avx2.h6
-rw-r--r--src/lib/block/twofish/twofish.cpp5
-rw-r--r--src/lib/block/xtea/xtea.cpp4
-rw-r--r--src/lib/block/xtea_simd/xtea_simd.cpp4
-rw-r--r--src/lib/compression/bzip2/bzip2.cpp2
-rw-r--r--src/lib/compression/comp_util.h5
-rw-r--r--src/lib/compression/compression.cpp59
-rw-r--r--src/lib/compression/compression.h10
-rw-r--r--src/lib/compression/lzma/lzma.cpp2
-rw-r--r--src/lib/compression/zlib/zlib.cpp4
-rw-r--r--src/lib/engine/aes_isa_eng/aes_isa_engine.cpp19
-rw-r--r--src/lib/engine/core_engine/core_modes.cpp233
-rw-r--r--src/lib/engine/core_engine/lookup_block.cpp248
-rw-r--r--src/lib/engine/simd_engine/simd_engine.cpp64
-rw-r--r--src/lib/filters/aead_filt/aead_filt.h4
-rw-r--r--src/lib/filters/comp_filter.cpp6
-rw-r--r--src/lib/filters/comp_filter.h7
-rw-r--r--src/lib/filters/transform_filter.cpp30
-rw-r--r--src/lib/filters/transform_filter.h22
-rw-r--r--src/lib/libstate/libstate.cpp8
-rw-r--r--src/lib/modes/aead/aead.cpp124
-rw-r--r--src/lib/modes/aead/ccm/ccm.cpp7
-rw-r--r--src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp6
-rw-r--r--src/lib/modes/aead/eax/eax.cpp5
-rw-r--r--src/lib/modes/aead/gcm/gcm.cpp5
-rw-r--r--src/lib/modes/aead/ocb/ocb.cpp6
-rw-r--r--src/lib/modes/aead/siv/siv.cpp7
-rw-r--r--src/lib/modes/cbc/cbc.cpp27
-rw-r--r--src/lib/modes/cfb/cfb.cpp4
-rw-r--r--src/lib/modes/cipher_mode.cpp59
-rw-r--r--src/lib/modes/cipher_mode.h2
-rw-r--r--src/lib/modes/ecb/ecb.cpp18
-rw-r--r--src/lib/modes/info.txt8
-rw-r--r--src/lib/modes/mode_pad/mode_pad.cpp20
-rw-r--r--src/lib/modes/mode_pad/mode_pad.h2
-rw-r--r--src/lib/modes/mode_utils.h76
-rw-r--r--src/lib/modes/xts/xts.cpp6
-rw-r--r--src/lib/selftest/info.txt8
-rw-r--r--src/lib/selftest/selftest.cpp319
-rw-r--r--src/lib/selftest/selftest.h60
-rw-r--r--src/lib/tls/tls_policy.cpp56
-rw-r--r--src/lib/tls/tls_policy.h22
-rw-r--r--src/lib/tls/tls_suite_info.cpp22
-rw-r--r--src/lib/utils/cpuid.cpp26
-rw-r--r--src/lib/utils/cpuid.h15
-rw-r--r--src/lib/utils/parsing.cpp10
-rwxr-xr-xsrc/scripts/tls_suite_info.py4
-rw-r--r--src/tests/test_transform.cpp16
89 files changed, 835 insertions, 1310 deletions
diff --git a/src/cmd/compress.cpp b/src/cmd/compress.cpp
index 8480801e9..646a4d587 100644
--- a/src/cmd/compress.cpp
+++ b/src/cmd/compress.cpp
@@ -11,7 +11,7 @@
namespace {
-void do_compress(Transformation& comp, std::ifstream& in, std::ostream& out)
+void do_compress(Transform& comp, std::ifstream& in, std::ostream& out)
{
secure_vector<byte> buf;
@@ -53,7 +53,13 @@ int compress(int argc, char* argv[])
const size_t level = 9;
const std::string suffix = argc == 3 ? argv[2] : "gz";
- std::unique_ptr<Transformation> compress(make_compressor(suffix, level));
+ std::unique_ptr<Transform> compress(make_compressor(suffix, level));
+
+ if(!compress)
+ {
+ std::cout << suffix << " compression not supported\n";
+ return 1;
+ }
const std::string out_file = in_file + "." + suffix;
std::ofstream out(out_file.c_str());
@@ -91,7 +97,13 @@ int uncompress(int argc, char* argv[])
std::ofstream out(out_file.c_str());
- std::unique_ptr<Transformation> decompress(make_decompressor(suffix));
+ std::unique_ptr<Transform> decompress(make_decompressor(suffix));
+
+ if(!decompress)
+ {
+ std::cout << suffix << " decompression not supported\n";
+ return 1;
+ }
do_compress(*decompress, in, out);
diff --git a/src/cmd/speed.cpp b/src/cmd/speed.cpp
index 8f19063be..4558c4250 100644
--- a/src/cmd/speed.cpp
+++ b/src/cmd/speed.cpp
@@ -121,7 +121,7 @@ void report_results(const std::string& algo,
std::cout << std::endl;
}
-void time_transform(std::unique_ptr<Transformation> tf,
+void time_transform(std::unique_ptr<Transform> tf,
RandomNumberGenerator& rng)
{
if(!tf)
@@ -162,7 +162,7 @@ void time_transform(std::unique_ptr<Transformation> tf,
void time_transform(const std::string& algo, RandomNumberGenerator& rng)
{
- std::unique_ptr<Transformation> tf;
+ std::unique_ptr<Transform> tf;
tf.reset(get_aead(algo, ENCRYPTION));
if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(tf.get()))
diff --git a/src/lib/algo_base/algo_registry.cpp b/src/lib/algo_base/algo_registry.cpp
new file mode 100644
index 000000000..c33b1b3c7
--- /dev/null
+++ b/src/lib/algo_base/algo_registry.cpp
@@ -0,0 +1,20 @@
+/*
+* (C) 2014,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/transform.h>
+#include <botan/algo_registry.h>
+
+namespace Botan {
+
+Transform* get_transform(const std::string& specstr,
+ const std::string& provider,
+ const std::string& dirstr)
+ {
+ Algo_Registry<Transform>::Spec spec(specstr, dirstr);
+ return Algo_Registry<Transform>::global_registry().make(spec, provider);
+ }
+
+}
diff --git a/src/lib/algo_base/algo_registry.h b/src/lib/algo_base/algo_registry.h
new file mode 100644
index 000000000..d40e9fc67
--- /dev/null
+++ b/src/lib/algo_base/algo_registry.h
@@ -0,0 +1,146 @@
+/*
+* (C) 2014,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_ALGO_REGISTRY_H__
+#define BOTAN_ALGO_REGISTRY_H__
+
+#include <botan/types.h>
+#include <functional>
+#include <stdexcept>
+#include <mutex>
+#include <map>
+
+namespace Botan {
+
+size_t static_provider_weight(const std::string& prov_name);
+
+template<typename T>
+class Algo_Registry
+ {
+ public:
+ typedef typename T::Spec Spec;
+
+ typedef std::function<T* (const Spec&)> maker_fn;
+
+ static Algo_Registry<T>& global_registry()
+ {
+ static Algo_Registry<T> g_registry;
+ return g_registry;
+ }
+
+ void add(const std::string& name, const std::string& provider, maker_fn fn)
+ {
+ std::unique_lock<std::mutex> lock(m_mutex);
+ // TODO: check for duplicated registrations
+ m_maker_fns[name][provider] = fn;
+ }
+
+ T* make(const Spec& spec, const std::string& provider = "")
+ {
+ maker_fn maker = find_maker(spec, provider);
+
+ try
+ {
+ return maker(spec);
+ }
+ catch(std::exception& e)
+ {
+ throw std::runtime_error("Creating '" + spec.as_string() + "' failed: " + e.what());
+ }
+ }
+
+ class Add
+ {
+ public:
+ Add(const std::string& basename, maker_fn fn, const std::string& provider = "builtin")
+ {
+ Algo_Registry<T>::global_registry().add(basename, provider, fn);
+ }
+
+ Add(bool cond, const std::string& basename, maker_fn fn, const std::string& provider)
+ {
+ if(cond)
+ Algo_Registry<T>::global_registry().add(basename, provider, fn);
+ }
+ };
+
+ private:
+ Algo_Registry() {}
+
+ maker_fn find_maker(const Spec& spec, const std::string& provider)
+ {
+ const std::string basename = spec.algo_name();
+
+ std::unique_lock<std::mutex> lock(m_mutex);
+ auto providers = m_maker_fns.find(basename);
+
+ if(providers != m_maker_fns.end() && !providers->second.empty())
+ {
+ const std::map<std::string, maker_fn>& prov = providers->second;
+
+ if(provider != "")
+ {
+ // find one explicit provider requested by user, or fail
+ auto i = prov.find(provider);
+ if(i != prov.end())
+ return i->second;
+ }
+ else
+ {
+ if(prov.size() == 1)
+ {
+ return prov.begin()->second;
+ }
+ else if(prov.size() > 1)
+ {
+ // TODO choose best of available options (how?)
+ //throw std::runtime_error("multiple choice not implemented");
+ return prov.begin()->second;
+ }
+ }
+ }
+ // Default result is a function producing a null pointer
+ return [](const Spec&) { return nullptr; };
+ }
+
+ std::mutex m_mutex;
+ std::map<std::string, std::map<std::string, maker_fn>> m_maker_fns;
+ };
+
+template<typename T> T*
+make_new_T(const typename Algo_Registry<T>::Spec&) { return new T; }
+
+template<typename T, size_t DEF_VAL> T*
+make_new_T_1len(const typename Algo_Registry<T>::Spec& spec)
+ {
+ return new T(spec.arg_as_integer(0, DEF_VAL));
+ }
+
+template<typename T> T*
+make_new_T_1str(const typename Algo_Registry<T>::Spec& spec, const std::string& def)
+ {
+ return new T(spec.arg(0, def));
+ }
+
+#define BOTAN_REGISTER_NAMED_T(T, namestr, type, maker) \
+ namespace { Algo_Registry<T>::Add g_ ## type ## _reg(namestr, maker); }
+#define BOTAN_REGISTER_T(T, name, maker) \
+ namespace { Algo_Registry<T>::Add g_ ## name ## _reg(#name, maker); }
+#define BOTAN_REGISTER_T_NOARGS(T, name) \
+ namespace { Algo_Registry<T>::Add g_ ## name ## _reg(#name, make_new_T<name>); }
+#define BOTAN_REGISTER_T_1LEN(T, name, def) \
+ namespace { Algo_Registry<T>::Add g_ ## name ## _reg(#name, make_new_T_1len<name, def>); }
+
+#define BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, T, type, name, provider) \
+ namespace { Algo_Registry<T>::Add g_ ## type ## _reg(cond, name, make_new_T<type>, provider); }
+
+// TODO move elsewhere:
+#define BOTAN_REGISTER_TRANSFORM(name, maker) BOTAN_REGISTER_T(Transform, name, maker)
+#define BOTAN_REGISTER_TRANSFORM_NOARGS(name) BOTAN_REGISTER_T_NOARGS(Transform, name)
+
+}
+
+#endif
diff --git a/src/lib/algo_base/scan_name.cpp b/src/lib/algo_base/scan_name.cpp
index 063900aae..ad34e05c1 100644
--- a/src/lib/algo_base/scan_name.cpp
+++ b/src/lib/algo_base/scan_name.cpp
@@ -65,6 +65,11 @@ deref_aliases(const std::pair<size_t, std::string>& in)
std::mutex SCAN_Name::s_alias_map_mutex;
std::map<std::string, std::string> SCAN_Name::s_alias_map;
+SCAN_Name::SCAN_Name(std::string algo_spec, const std::string& extra) : SCAN_Name(algo_spec)
+ {
+ alg_name += extra;
+ }
+
SCAN_Name::SCAN_Name(std::string algo_spec)
{
orig_algo_spec = algo_spec;
@@ -73,7 +78,7 @@ SCAN_Name::SCAN_Name(std::string algo_spec)
size_t level = 0;
std::pair<size_t, std::string> accum = std::make_pair(level, "");
- std::string decoding_error = "Bad SCAN name '" + algo_spec + "': ";
+ const std::string decoding_error = "Bad SCAN name '" + algo_spec + "': ";
algo_spec = SCAN_Name::deref_alias(algo_spec);
@@ -130,12 +135,9 @@ SCAN_Name::SCAN_Name(std::string algo_spec)
}
}
-std::string SCAN_Name::algo_name_and_args() const
+std::string SCAN_Name::all_arguments() const
{
std::string out;
-
- out = algo_name();
-
if(arg_count())
{
out += '(';
@@ -146,16 +148,14 @@ std::string SCAN_Name::algo_name_and_args() const
out += ',';
}
out += ')';
-
}
-
return out;
}
std::string SCAN_Name::arg(size_t i) const
{
if(i >= arg_count())
- throw std::range_error("SCAN_Name::argument - i out of range");
+ throw std::range_error("SCAN_Name::arg - i out of range");
return args[i];
}
diff --git a/src/lib/algo_base/scan_name.h b/src/lib/algo_base/scan_name.h
index eb64f94eb..82be8d49c 100644
--- a/src/lib/algo_base/scan_name.h
+++ b/src/lib/algo_base/scan_name.h
@@ -29,19 +29,29 @@ class BOTAN_DLL SCAN_Name
SCAN_Name(std::string algo_spec);
/**
+ * @param algo_spec A SCAN-format name
+ */
+ SCAN_Name(std::string algo_spec, const std::string& extra);
+
+ /**
* @return original input string
*/
- std::string as_string() const { return orig_algo_spec; }
+ const std::string& as_string() const { return orig_algo_spec; }
/**
* @return algorithm name
*/
- std::string algo_name() const { return alg_name; }
+ const std::string& algo_name() const { return alg_name; }
/**
* @return algorithm name plus any arguments
*/
- std::string algo_name_and_args() const;
+ std::string algo_name_and_args() const { return algo_name() + all_arguments(); }
+
+ /**
+ * @return all arguments
+ */
+ std::string all_arguments() const;
/**
* @return number of arguments
diff --git a/src/lib/algo_base/transform.h b/src/lib/algo_base/transform.h
index 444622b74..75bd5004a 100644
--- a/src/lib/algo_base/transform.h
+++ b/src/lib/algo_base/transform.h
@@ -1,5 +1,5 @@
/*
-* Transformations of data
+* Transforms of data
* (C) 2013 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
@@ -12,6 +12,7 @@
#include <botan/key_spec.h>
#include <botan/exceptn.h>
#include <botan/symkey.h>
+#include <botan/scan_name.h>
#include <string>
#include <vector>
@@ -20,9 +21,11 @@ namespace Botan {
/**
* Interface for general transformations on data
*/
-class BOTAN_DLL Transformation
+class BOTAN_DLL Transform
{
public:
+ typedef SCAN_Name Spec;
+
/**
* Begin processing a message.
* @param nonce the per message nonce
@@ -38,7 +41,7 @@ class BOTAN_DLL Transformation
* @param nonce the per message nonce
*/
template<typename Alloc>
- BOTAN_DEPRECATED("Use Transformation::start")
+ BOTAN_DEPRECATED("Use Transform::start")
secure_vector<byte> start_vec(const std::vector<byte, Alloc>& nonce)
{
return start(&nonce[0], nonce.size());
@@ -120,10 +123,10 @@ class BOTAN_DLL Transformation
virtual void clear() = 0;
- virtual ~Transformation() {}
+ virtual ~Transform() {}
};
-class BOTAN_DLL Keyed_Transform : public Transformation
+class BOTAN_DLL Keyed_Transform : public Transform
{
public:
/**
@@ -168,6 +171,12 @@ class BOTAN_DLL Keyed_Transform : public Transformation
virtual void key_schedule(const byte key[], size_t length) = 0;
};
+typedef Transform Transformation;
+
+BOTAN_DLL Transform* get_transform(const std::string& specstr,
+ const std::string& provider = "",
+ const std::string& dirstr = "");
+
}
#endif
diff --git a/src/lib/block/aes/aes.cpp b/src/lib/block/aes/aes.cpp
index 8180231ca..ff8c97b76 100644
--- a/src/lib/block/aes/aes.cpp
+++ b/src/lib/block/aes/aes.cpp
@@ -7,12 +7,15 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/aes.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_128, "AES-128");
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_192, "AES-192");
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_256, "AES-256");
+
namespace {
const byte SE[256] = {
diff --git a/src/lib/block/aes_ni/aes_ni.cpp b/src/lib/block/aes_ni/aes_ni.cpp
index aa061b3c1..256895148 100644
--- a/src/lib/block/aes_ni/aes_ni.cpp
+++ b/src/lib/block/aes_ni/aes_ni.cpp
@@ -5,12 +5,17 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/aes_ni.h>
-#include <botan/loadstor.h>
+#include <botan/cpuid.h>
#include <wmmintrin.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_128_NI, "AES-128", "aes_ni");
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_192_NI, "AES-192", "aes_ni");
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_256_NI, "AES-256", "aes_ni");
+
namespace {
__m128i aes_128_key_expansion(__m128i key, __m128i key_with_rcon)
diff --git a/src/lib/block/aes_ssse3/aes_ssse3.cpp b/src/lib/block/aes_ssse3/aes_ssse3.cpp
index 40f0a5c8e..6a8fb3ed8 100644
--- a/src/lib/block/aes_ssse3/aes_ssse3.cpp
+++ b/src/lib/block/aes_ssse3/aes_ssse3.cpp
@@ -10,11 +10,17 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/aes_ssse3.h>
+#include <botan/cpuid.h>
#include <tmmintrin.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_128_SSSE3, "AES-128", "ssse3");
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_192_SSSE3, "AES-192", "ssse3");
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_256_SSSE3, "AES-256", "ssse3");
+
namespace {
const __m128i low_nibs = _mm_set1_epi8(0x0F);
diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h
index 19dbc8e57..73e67b790 100644
--- a/src/lib/block/block_cipher.h
+++ b/src/lib/block/block_cipher.h
@@ -8,6 +8,7 @@
#ifndef BOTAN_BLOCK_CIPHER_H__
#define BOTAN_BLOCK_CIPHER_H__
+#include <botan/scan_name.h>
#include <botan/sym_algo.h>
namespace Botan {
@@ -18,6 +19,7 @@ namespace Botan {
class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
{
public:
+ typedef SCAN_Name Spec;
/**
* @return block size of this algorithm
diff --git a/src/lib/block/blowfish/blowfish.cpp b/src/lib/block/blowfish/blowfish.cpp
index d388f9d97..ece1a31fd 100644
--- a/src/lib/block/blowfish/blowfish.cpp
+++ b/src/lib/block/blowfish/blowfish.cpp
@@ -5,11 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/blowfish.h>
-#include <botan/loadstor.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Blowfish);
+
/*
* Blowfish Encryption
*/
diff --git a/src/lib/block/camellia/camellia.cpp b/src/lib/block/camellia/camellia.cpp
index 2ee4251d7..5f04c9d12 100644
--- a/src/lib/block/camellia/camellia.cpp
+++ b/src/lib/block/camellia/camellia.cpp
@@ -5,12 +5,16 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/camellia.h>
#include <botan/internal/camellia_sbox.h>
-#include <botan/loadstor.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_128, "Camellia-128");
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_192, "Camellia-192");
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_256, "Camellia-256");
+
namespace Camellia_F {
namespace {
diff --git a/src/lib/block/cascade/cascade.cpp b/src/lib/block/cascade/cascade.cpp
index 98e862de9..6c0458265 100644
--- a/src/lib/block/cascade/cascade.cpp
+++ b/src/lib/block/cascade/cascade.cpp
@@ -5,10 +5,29 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
+#include <botan/algo_registry.h>
#include <botan/cascade.h>
namespace Botan {
+namespace {
+
+Cascade_Cipher* make_cascade(const BlockCipher::Spec& spec)
+ {
+ auto& block_cipher = Algo_Registry<BlockCipher>::global_registry();
+ std::unique_ptr<BlockCipher> c1(block_cipher.make(spec.arg(0)));
+ std::unique_ptr<BlockCipher> c2(block_cipher.make(spec.arg(1)));
+
+ if(c1 && c2)
+ return new Cascade_Cipher(c1.release(), c2.release());
+ return nullptr;
+ }
+
+}
+
+BOTAN_REGISTER_NAMED_T(BlockCipher, "Cascade", Cascade_Cipher, make_cascade);
+
void Cascade_Cipher::encrypt_n(const byte in[], byte out[],
size_t blocks) const
{
diff --git a/src/lib/block/cast/cast128.cpp b/src/lib/block/cast/cast128.cpp
index e28106c55..3ac54f5e8 100644
--- a/src/lib/block/cast/cast128.cpp
+++ b/src/lib/block/cast/cast128.cpp
@@ -5,13 +5,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/cast128.h>
#include <botan/internal/cast_sboxes.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(CAST_128, "CAST-128");
+
namespace {
/*
diff --git a/src/lib/block/cast/cast256.cpp b/src/lib/block/cast/cast256.cpp
index 8dc78c11e..bbb9894e7 100644
--- a/src/lib/block/cast/cast256.cpp
+++ b/src/lib/block/cast/cast256.cpp
@@ -5,13 +5,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/cast256.h>
#include <botan/internal/cast_sboxes.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(CAST_256, "CAST-256");
+
namespace {
/*
diff --git a/src/lib/block/des/des.cpp b/src/lib/block/des/des.cpp
index 3b6c2ee4a..2994b7cb2 100644
--- a/src/lib/block/des/des.cpp
+++ b/src/lib/block/des/des.cpp
@@ -8,12 +8,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/des.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(DES);
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(TripleDES);
+
namespace {
/*
diff --git a/src/lib/block/des/desx.cpp b/src/lib/block/des/desx.cpp
index 2e5274932..92cfc83cc 100644
--- a/src/lib/block/des/desx.cpp
+++ b/src/lib/block/des/desx.cpp
@@ -5,11 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/desx.h>
-#include <botan/internal/xor_buf.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(DESX);
+
/*
* DESX Encryption
*/
diff --git a/src/lib/block/gost_28147/gost_28147.cpp b/src/lib/block/gost_28147/gost_28147.cpp
index f70072f22..90bf9328d 100644
--- a/src/lib/block/gost_28147/gost_28147.cpp
+++ b/src/lib/block/gost_28147/gost_28147.cpp
@@ -5,12 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/gost_28147.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(GOST_28147_89, "GOST-28147-89", "R3411_94_TestParam");
+
byte GOST_28147_89_Params::sbox_entry(size_t row, size_t col) const
{
byte x = sboxes[4 * col + (row / 2)];
diff --git a/src/lib/block/idea/idea.cpp b/src/lib/block/idea/idea.cpp
index 2d282461d..fa98e3754 100644
--- a/src/lib/block/idea/idea.cpp
+++ b/src/lib/block/idea/idea.cpp
@@ -5,11 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/idea.h>
-#include <botan/loadstor.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(IDEA);
+
namespace {
/*
diff --git a/src/lib/block/idea_sse2/idea_sse2.cpp b/src/lib/block/idea_sse2/idea_sse2.cpp
index 389fbdd2b..3dfd26860 100644
--- a/src/lib/block/idea_sse2/idea_sse2.cpp
+++ b/src/lib/block/idea_sse2/idea_sse2.cpp
@@ -5,11 +5,15 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/idea_sse2.h>
+#include <botan/cpuid.h>
#include <emmintrin.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_sse2(), IDEA_SSE2, "IDEA", "sse2");
+
namespace {
inline __m128i mul(__m128i X, u16bit K_16)
diff --git a/src/lib/block/info.txt b/src/lib/block/info.txt
index 70e2b2ca2..f10acaa86 100644
--- a/src/lib/block/info.txt
+++ b/src/lib/block/info.txt
@@ -3,3 +3,11 @@ define BLOCK_CIPHER 20131128
<requires>
algo_base
</requires>
+
+<header:public>
+block_cipher.h
+</header:public>
+
+<header:internal>
+block_utils.h
+</header:internal>
diff --git a/src/lib/block/kasumi/kasumi.cpp b/src/lib/block/kasumi/kasumi.cpp
index 53321e94d..d0233cf5c 100644
--- a/src/lib/block/kasumi/kasumi.cpp
+++ b/src/lib/block/kasumi/kasumi.cpp
@@ -5,12 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/kasumi.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(KASUMI);
+
namespace {
/*
diff --git a/src/lib/block/lion/lion.cpp b/src/lib/block/lion/lion.cpp
index 7e18eec56..420b92cdb 100644
--- a/src/lib/block/lion/lion.cpp
+++ b/src/lib/block/lion/lion.cpp
@@ -5,12 +5,36 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/lion.h>
-#include <botan/internal/xor_buf.h>
#include <botan/parsing.h>
+#include <botan/libstate.h>
namespace Botan {
+namespace {
+
+Lion* make_lion(const BlockCipher::Spec& spec)
+ {
+ if(spec.arg_count_between(2, 3))
+ {
+ Algorithm_Factory& af = global_state().algorithm_factory();
+ const HashFunction* hash = af.prototype_hash_function(spec.arg(0));
+ const StreamCipher* stream_cipher = af.prototype_stream_cipher(spec.arg(1));
+
+ if(hash && stream_cipher)
+ {
+ const size_t block_size = spec.arg_as_integer(2, 1024);
+ return new Lion(hash->clone(), stream_cipher->clone(), block_size);
+ }
+ }
+ return nullptr;
+ }
+
+}
+
+BOTAN_REGISTER_NAMED_T(BlockCipher, "Lion", Lion, make_lion);
+
/*
* Lion Encryption
*/
diff --git a/src/lib/block/mars/mars.cpp b/src/lib/block/mars/mars.cpp
index 6821738dd..50f264861 100644
--- a/src/lib/block/mars/mars.cpp
+++ b/src/lib/block/mars/mars.cpp
@@ -5,12 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/mars.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(MARS);
+
namespace {
/**
diff --git a/src/lib/block/misty1/misty1.cpp b/src/lib/block/misty1/misty1.cpp
index d6ffda945..23233e02f 100644
--- a/src/lib/block/misty1/misty1.cpp
+++ b/src/lib/block/misty1/misty1.cpp
@@ -5,12 +5,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/misty1.h>
-#include <botan/loadstor.h>
#include <botan/parsing.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(MISTY1);
+
namespace {
static const byte MISTY1_SBOX_S7[128] = {
@@ -257,14 +259,4 @@ void MISTY1::clear()
zap(DK);
}
-/*
-* MISTY1 Constructor
-*/
-MISTY1::MISTY1(size_t rounds)
- {
- if(rounds != 8)
- throw Invalid_Argument("MISTY1: Invalid number of rounds: "
- + std::to_string(rounds));
- }
-
}
diff --git a/src/lib/block/misty1/misty1.h b/src/lib/block/misty1/misty1.h
index 17b617283..177c2c0b5 100644
--- a/src/lib/block/misty1/misty1.h
+++ b/src/lib/block/misty1/misty1.h
@@ -13,7 +13,7 @@
namespace Botan {
/**
-* MISTY1
+* MISTY1 with 8 rounds
*/
class BOTAN_DLL MISTY1 : public Block_Cipher_Fixed_Params<8, 16>
{
@@ -24,12 +24,6 @@ class BOTAN_DLL MISTY1 : public Block_Cipher_Fixed_Params<8, 16>
void clear();
std::string name() const { return "MISTY1"; }
BlockCipher* clone() const { return new MISTY1; }
-
- /**
- * @param rounds the number of rounds. Must be 8 with the current
- * implementation
- */
- MISTY1(size_t rounds = 8);
private:
void key_schedule(const byte[], size_t);
diff --git a/src/lib/block/noekeon/noekeon.cpp b/src/lib/block/noekeon/noekeon.cpp
index aa593c95f..09a2f6c15 100644
--- a/src/lib/block/noekeon/noekeon.cpp
+++ b/src/lib/block/noekeon/noekeon.cpp
@@ -5,12 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/noekeon.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Noekeon);
+
namespace {
/*
diff --git a/src/lib/block/noekeon_simd/noekeon_simd.cpp b/src/lib/block/noekeon_simd/noekeon_simd.cpp
index 07fcf19ff..d5995ee1d 100644
--- a/src/lib/block/noekeon_simd/noekeon_simd.cpp
+++ b/src/lib/block/noekeon_simd/noekeon_simd.cpp
@@ -5,11 +5,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/noekeon_simd.h>
#include <botan/internal/simd_32.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Noekeon_SIMD, "Noekeon", "simd32");
+
/*
* Noekeon's Theta Operation
*/
diff --git a/src/lib/block/rc2/rc2.cpp b/src/lib/block/rc2/rc2.cpp
index 329b174e9..54f85ce00 100644
--- a/src/lib/block/rc2/rc2.cpp
+++ b/src/lib/block/rc2/rc2.cpp
@@ -5,12 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/rc2.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(RC2);
+
/*
* RC2 Encryption
*/
diff --git a/src/lib/block/rc5/rc5.cpp b/src/lib/block/rc5/rc5.cpp
index 45067678f..27fa0e14d 100644
--- a/src/lib/block/rc5/rc5.cpp
+++ b/src/lib/block/rc5/rc5.cpp
@@ -5,14 +5,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/rc5.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
#include <botan/parsing.h>
-#include <algorithm>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_1LEN(RC5, 12);
+
/*
* RC5 Encryption
*/
diff --git a/src/lib/block/rc6/rc6.cpp b/src/lib/block/rc6/rc6.cpp
index 183395310..e9aa5fe8b 100644
--- a/src/lib/block/rc6/rc6.cpp
+++ b/src/lib/block/rc6/rc6.cpp
@@ -5,13 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/rc6.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
-#include <algorithm>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(RC6);
+
/*
* RC6 Encryption
*/
diff --git a/src/lib/block/safer/safer_sk.cpp b/src/lib/block/safer/safer_sk.cpp
index 390e5d9bb..f5996a986 100644
--- a/src/lib/block/safer/safer_sk.cpp
+++ b/src/lib/block/safer/safer_sk.cpp
@@ -5,15 +5,16 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/safer_sk.h>
-#include <botan/rotate.h>
#include <botan/parsing.h>
-#include <botan/rotate.h>
namespace Botan {
namespace {
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1LEN(SAFER_SK, "SAFER-SK", 10);
+
const byte EXP[256] = {
0x01, 0x2D, 0xE2, 0x93, 0xBE, 0x45, 0x15, 0xAE, 0x78, 0x03, 0x87, 0xA4,
0xB8, 0x38, 0xCF, 0x3F, 0x08, 0x67, 0x09, 0x94, 0xEB, 0x26, 0xA8, 0x6B,
diff --git a/src/lib/block/seed/seed.cpp b/src/lib/block/seed/seed.cpp
index 833f9943f..316ef1e04 100644
--- a/src/lib/block/seed/seed.cpp
+++ b/src/lib/block/seed/seed.cpp
@@ -5,11 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/seed.h>
-#include <botan/loadstor.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(SEED);
+
/*
* SEED G Function
*/
diff --git a/src/lib/block/serpent/serpent.cpp b/src/lib/block/serpent/serpent.cpp
index f66cd2a32..0fd76ce8f 100644
--- a/src/lib/block/serpent/serpent.cpp
+++ b/src/lib/block/serpent/serpent.cpp
@@ -5,17 +5,18 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/serpent.h>
#include <botan/internal/serpent_sbox.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Serpent);
+
namespace {
/*
-* Serpent's Linear Transformation
+* Serpent's Linear Transform
*/
inline void transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
{
@@ -27,7 +28,7 @@ inline void transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
}
/*
-* Serpent's Inverse Linear Transformation
+* Serpent's Inverse Linear Transform
*/
inline void i_transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
{
diff --git a/src/lib/block/serpent_simd/serp_simd.cpp b/src/lib/block/serpent_simd/serp_simd.cpp
index 1a379efca..fa7f419fe 100644
--- a/src/lib/block/serpent_simd/serp_simd.cpp
+++ b/src/lib/block/serpent_simd/serp_simd.cpp
@@ -5,13 +5,15 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/serp_simd.h>
#include <botan/internal/serpent_sbox.h>
#include <botan/internal/simd_32.h>
-#include <botan/loadstor.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Serpent_SIMD, "Serpent", "simd32");
+
namespace {
#define key_xor(round, B0, B1, B2, B3) \
diff --git a/src/lib/block/serpent_x86_32/serp_x86_32.cpp b/src/lib/block/serpent_x86_32/serp_x86_32.cpp
index 5548e3496..3c326d084 100644
--- a/src/lib/block/serpent_x86_32/serp_x86_32.cpp
+++ b/src/lib/block/serpent_x86_32/serp_x86_32.cpp
@@ -5,11 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/serp_x86_32.h>
-#include <botan/loadstor.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Serpent_X86_32, "Serpent", "x86-32");
+
extern "C" {
/**
diff --git a/src/lib/block/tea/tea.cpp b/src/lib/block/tea/tea.cpp
index 01f342607..ef630f715 100644
--- a/src/lib/block/tea/tea.cpp
+++ b/src/lib/block/tea/tea.cpp
@@ -5,11 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/tea.h>
-#include <botan/loadstor.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(TEA);
+
/*
* TEA Encryption
*/
diff --git a/src/lib/block/threefish/threefish.cpp b/src/lib/block/threefish/threefish.cpp
index f6636615b..322f54881 100644
--- a/src/lib/block/threefish/threefish.cpp
+++ b/src/lib/block/threefish/threefish.cpp
@@ -5,12 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/threefish.h>
-#include <botan/rotate.h>
-#include <botan/loadstor.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Threefish_512, "Threefish-512");
+
#define THREEFISH_ROUND(X0,X1,X2,X3,X4,X5,X6,X7,ROT1,ROT2,ROT3,ROT4) \
do { \
X0 += X4; \
@@ -223,6 +224,7 @@ void Threefish_512::set_tweak(const byte tweak[], size_t len)
{
if(len != 16)
throw std::runtime_error("Unsupported twofish tweak length");
+ m_T.resize(3);
m_T[0] = load_le<u64bit>(tweak, 0);
m_T[1] = load_le<u64bit>(tweak, 1);
m_T[2] = m_T[0] ^ m_T[1];
@@ -238,6 +240,10 @@ void Threefish_512::key_schedule(const byte key[], size_t)
m_K[8] = m_K[0] ^ m_K[1] ^ m_K[2] ^ m_K[3] ^
m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22;
+
+ // Reset tweak to all zeros on key reset
+ m_T.resize(3);
+ zeroise(m_T);
}
void Threefish_512::clear()
diff --git a/src/lib/block/threefish/threefish.h b/src/lib/block/threefish/threefish.h
index 6020b8a28..373600885 100644
--- a/src/lib/block/threefish/threefish.h
+++ b/src/lib/block/threefish/threefish.h
@@ -26,9 +26,6 @@ class BOTAN_DLL Threefish_512 : public Block_Cipher_Fixed_Params<64, 64>
void clear() override;
std::string name() const override { return "Threefish-512"; }
BlockCipher* clone() const override { return new Threefish_512; }
-
- Threefish_512() : m_T(3) {}
-
protected:
const secure_vector<u64bit>& get_T() const { return m_T; }
const secure_vector<u64bit>& get_K() const { return m_K; }
diff --git a/src/lib/block/threefish_avx2/threefish_avx2.cpp b/src/lib/block/threefish_avx2/threefish_avx2.cpp
index ee0ecde85..432059585 100644
--- a/src/lib/block/threefish_avx2/threefish_avx2.cpp
+++ b/src/lib/block/threefish_avx2/threefish_avx2.cpp
@@ -1,15 +1,19 @@
/*
-* Threefish-512
+* Threefish-512 using AVX2
* (C) 2013 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/threefish_avx2.h>
+#include <botan/cpuid.h>
#include <immintrin.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_avx2(), Threefish_512_AVX2, "Threefish-512", "avx2");
+
namespace {
inline void interleave_epi64(__m256i& X0, __m256i& X1)
diff --git a/src/lib/block/threefish_avx2/threefish_avx2.h b/src/lib/block/threefish_avx2/threefish_avx2.h
index ba24f114f..d851ff0dc 100644
--- a/src/lib/block/threefish_avx2/threefish_avx2.h
+++ b/src/lib/block/threefish_avx2/threefish_avx2.h
@@ -20,6 +20,12 @@ class BOTAN_DLL Threefish_512_AVX2 : public Threefish_512
private:
void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
+
+ /* TODO:
+ void skein_feedfwd(const secure_vector<u64bit>& M,
+ const secure_vector<u64bit>& T) override;
+ */
+
BlockCipher* clone() const override { return new Threefish_512_AVX2; }
};
diff --git a/src/lib/block/twofish/twofish.cpp b/src/lib/block/twofish/twofish.cpp
index ffdf4b198..43ea41bfd 100644
--- a/src/lib/block/twofish/twofish.cpp
+++ b/src/lib/block/twofish/twofish.cpp
@@ -8,12 +8,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/twofish.h>
-#include <botan/loadstor.h>
-#include <botan/rotate.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Twofish);
+
/*
* Twofish Encryption
*/
diff --git a/src/lib/block/xtea/xtea.cpp b/src/lib/block/xtea/xtea.cpp
index 59060dff7..9fe265457 100644
--- a/src/lib/block/xtea/xtea.cpp
+++ b/src/lib/block/xtea/xtea.cpp
@@ -5,11 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/xtea.h>
-#include <botan/loadstor.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(XTEA);
+
namespace {
void xtea_encrypt_4(const byte in[32], byte out[32], const u32bit EK[64])
diff --git a/src/lib/block/xtea_simd/xtea_simd.cpp b/src/lib/block/xtea_simd/xtea_simd.cpp
index 87c7a20bf..6fd2f94c7 100644
--- a/src/lib/block/xtea_simd/xtea_simd.cpp
+++ b/src/lib/block/xtea_simd/xtea_simd.cpp
@@ -5,12 +5,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/block_utils.h>
#include <botan/xtea_simd.h>
-#include <botan/loadstor.h>
#include <botan/internal/simd_32.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), XTEA_SIMD, "XTEA", "simd32");
+
namespace {
void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64])
diff --git a/src/lib/compression/bzip2/bzip2.cpp b/src/lib/compression/bzip2/bzip2.cpp
index 471635e3e..2d1617bce 100644
--- a/src/lib/compression/bzip2/bzip2.cpp
+++ b/src/lib/compression/bzip2/bzip2.cpp
@@ -15,6 +15,8 @@
namespace Botan {
+BOTAN_REGISTER_COMPRESSION(Bzip2_Compression, Bzip2_Decompression);
+
namespace {
class Bzip2_Stream : public Zlib_Style_Stream<bz_stream, char>
diff --git a/src/lib/compression/comp_util.h b/src/lib/compression/comp_util.h
index 6e1ee1671..963eae642 100644
--- a/src/lib/compression/comp_util.h
+++ b/src/lib/compression/comp_util.h
@@ -9,6 +9,7 @@
#define BOTAN_COMPRESSION_UTILS_H__
#include <botan/compression.h>
+#include <botan/algo_registry.h>
#include <memory>
#include <unordered_map>
@@ -84,6 +85,10 @@ class Zlib_Style_Stream : public Compression_Stream
std::unique_ptr<Compression_Alloc_Info> m_allocs;
};
+#define BOTAN_REGISTER_COMPRESSION(C, D) \
+ BOTAN_REGISTER_T_1LEN(Transform, C, 9) \
+ BOTAN_REGISTER_T_NOARGS(Transform, D)
+
}
#endif
diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp
index 428271e9a..e5221aba6 100644
--- a/src/lib/compression/compression.cpp
+++ b/src/lib/compression/compression.cpp
@@ -6,67 +6,42 @@
*/
#include <botan/compression.h>
-
-#if defined(BOTAN_HAS_ZLIB_TRANSFORM)
- #include <botan/zlib.h>
-#endif
-
-#if defined(BOTAN_HAS_BZIP2_TRANSFORM)
- #include <botan/bzip2.h>
-#endif
-
-#if defined(BOTAN_HAS_LZMA_TRANSFORM)
- #include <botan/lzma.h>
-#endif
+#include <botan/algo_registry.h>
namespace Botan {
-Compressor_Transformation* make_compressor(const std::string& type, size_t level)
+Transform* make_compressor(const std::string& type, size_t level)
{
-#if defined(BOTAN_HAS_ZLIB_TRANSFORM)
+ const std::string comp_suffix = "_Compression(" + std::to_string(level) + ")";
+
if(type == "zlib")
- return new Zlib_Compression(level);
+ return get_transform("Zlib" + comp_suffix);
if(type == "deflate")
- return new Deflate_Compression(level);
+ return get_transform("Deflate" + comp_suffix);
if(type == "gzip" || type == "gz")
- return new Gzip_Compression(level);
-#endif
-
-#if defined(BOTAN_HAS_BZIP2_TRANSFORM)
+ return get_transform("Gzip" + comp_suffix);
if(type == "bzip2" || type == "bz2")
- return new Bzip2_Compression(level);
-#endif
-
-#if defined(BOTAN_HAS_LZMA_TRANSFORM)
+ return get_transform("Bzip2", comp_suffix);
if(type == "lzma" || type == "xz")
- return new LZMA_Compression(level);
-#endif
+ return get_transform("LZMA", comp_suffix);
- throw std::runtime_error("Unknown compression type " + type);
+ return nullptr;
}
-Compressor_Transformation* make_decompressor(const std::string& type)
+Transform* make_decompressor(const std::string& type)
{
-#if defined(BOTAN_HAS_ZLIB_TRANSFORM)
if(type == "zlib")
- return new Zlib_Decompression;
+ return get_transform("Zlib_Decompression");
if(type == "deflate")
- return new Deflate_Decompression;
+ return get_transform("Deflate_Decompression");
if(type == "gzip" || type == "gz")
- return new Gzip_Decompression;
-#endif
-
-#if defined(BOTAN_HAS_BZIP2_TRANSFORM)
+ return get_transform("Gzip_Decompression");
if(type == "bzip2" || type == "bz2")
- return new Bzip2_Decompression;
-#endif
-
-#if defined(BOTAN_HAS_LZMA_TRANSFORM)
+ return get_transform("Bzip2_Decompression");
if(type == "lzma" || type == "xz")
- return new LZMA_Decompression;
-#endif
+ return get_transform("LZMA_Decompression");
- throw std::runtime_error("Unknown compression type " + type);
+ return nullptr;
}
void Stream_Compression::clear()
diff --git a/src/lib/compression/compression.h b/src/lib/compression/compression.h
index b38d94f64..f70252cbe 100644
--- a/src/lib/compression/compression.h
+++ b/src/lib/compression/compression.h
@@ -12,7 +12,7 @@
namespace Botan {
-class BOTAN_DLL Compressor_Transformation : public Transformation
+class BOTAN_DLL Compressor_Transform : public Transform
{
public:
size_t update_granularity() const override { return 1; }
@@ -32,8 +32,8 @@ class BOTAN_DLL Compressor_Transformation : public Transformation
}
};
-BOTAN_DLL Compressor_Transformation* make_compressor(const std::string& type, size_t level);
-BOTAN_DLL Compressor_Transformation* make_decompressor(const std::string& type);
+BOTAN_DLL Transform* make_compressor(const std::string& type, size_t level);
+BOTAN_DLL Transform* make_decompressor(const std::string& type);
class Compression_Stream
{
@@ -55,7 +55,7 @@ class Compression_Stream
virtual bool run(u32bit flags) = 0;
};
-class BOTAN_DLL Stream_Compression : public Compressor_Transformation
+class BOTAN_DLL Stream_Compression : public Compressor_Transform
{
public:
void update(secure_vector<byte>& buf, size_t offset = 0) override;
@@ -76,7 +76,7 @@ class BOTAN_DLL Stream_Compression : public Compressor_Transformation
std::unique_ptr<Compression_Stream> m_stream;
};
-class BOTAN_DLL Stream_Decompression : public Compressor_Transformation
+class BOTAN_DLL Stream_Decompression : public Compressor_Transform
{
public:
void update(secure_vector<byte>& buf, size_t offset = 0) override;
diff --git a/src/lib/compression/lzma/lzma.cpp b/src/lib/compression/lzma/lzma.cpp
index 0aadf1513..69d73a3a1 100644
--- a/src/lib/compression/lzma/lzma.cpp
+++ b/src/lib/compression/lzma/lzma.cpp
@@ -14,6 +14,8 @@
namespace Botan {
+BOTAN_REGISTER_COMPRESSION(LZMA_Compression, LZMA_Decompression);
+
namespace {
class LZMA_Stream : public Zlib_Style_Stream<lzma_stream, byte>
diff --git a/src/lib/compression/zlib/zlib.cpp b/src/lib/compression/zlib/zlib.cpp
index 8c94e4331..24e8721e3 100644
--- a/src/lib/compression/zlib/zlib.cpp
+++ b/src/lib/compression/zlib/zlib.cpp
@@ -14,6 +14,10 @@
namespace Botan {
+BOTAN_REGISTER_COMPRESSION(Zlib_Compression, Zlib_Decompression);
+BOTAN_REGISTER_COMPRESSION(Gzip_Compression, Gzip_Decompression);
+BOTAN_REGISTER_COMPRESSION(Deflate_Compression, Deflate_Decompression);
+
namespace {
class Zlib_Stream : public Zlib_Style_Stream<z_stream, Bytef>
diff --git a/src/lib/engine/aes_isa_eng/aes_isa_engine.cpp b/src/lib/engine/aes_isa_eng/aes_isa_engine.cpp
index c73eefcd3..d581b65ad 100644
--- a/src/lib/engine/aes_isa_eng/aes_isa_engine.cpp
+++ b/src/lib/engine/aes_isa_eng/aes_isa_engine.cpp
@@ -6,11 +6,7 @@
*/
#include <botan/internal/aes_isa_engine.h>
-#include <botan/cpuid.h>
-
-#if defined(BOTAN_HAS_AES_NI)
- #include <botan/aes_ni.h>
-#endif
+#include <botan/algo_registry.h>
namespace Botan {
@@ -18,17 +14,8 @@ BlockCipher*
AES_ISA_Engine::find_block_cipher(const SCAN_Name& request,
Algorithm_Factory&) const
{
-#if defined(BOTAN_HAS_AES_NI)
- if(CPUID::has_aes_ni())
- {
- if(request.algo_name() == "AES-128")
- return new AES_128_NI;
- if(request.algo_name() == "AES-192")
- return new AES_192_NI;
- if(request.algo_name() == "AES-256")
- return new AES_256_NI;
- }
-#endif
+ if(BlockCipher* c = Algo_Registry<BlockCipher>::global_registry().make(request, "aes_ni"))
+ return c;
return nullptr;
}
diff --git a/src/lib/engine/core_engine/core_modes.cpp b/src/lib/engine/core_engine/core_modes.cpp
index 1d96e581d..02a55bcd6 100644
--- a/src/lib/engine/core_engine/core_modes.cpp
+++ b/src/lib/engine/core_engine/core_modes.cpp
@@ -11,22 +11,7 @@
#include <botan/algo_factory.h>
#include <botan/mode_pad.h>
#include <botan/transform_filter.h>
-
-#if defined(BOTAN_HAS_MODE_CFB)
- #include <botan/cfb.h>
-#endif
-
-#if defined(BOTAN_HAS_MODE_ECB)
- #include <botan/ecb.h>
-#endif
-
-#if defined(BOTAN_HAS_MODE_CBC)
- #include <botan/cbc.h>
-#endif
-
-#if defined(BOTAN_HAS_MODE_XTS)
- #include <botan/xts.h>
-#endif
+#include <botan/cipher_mode.h>
#if defined(BOTAN_HAS_OFB)
#include <botan/ofb.h>
@@ -36,194 +21,8 @@
#include <botan/ctr.h>
#endif
-#if defined(BOTAN_HAS_AEAD_FILTER)
-
-#include <botan/aead_filt.h>
-
-#if defined(BOTAN_HAS_AEAD_CCM)
- #include <botan/ccm.h>
-#endif
-
-#if defined(BOTAN_HAS_AEAD_EAX)
- #include <botan/eax.h>
-#endif
-
-#if defined(BOTAN_HAS_AEAD_OCB)
- #include <botan/ocb.h>
-#endif
-
-#if defined(BOTAN_HAS_AEAD_GCM)
- #include <botan/gcm.h>
-#endif
-
-#endif
-
namespace Botan {
-namespace {
-
-/**
-* Get a block cipher padding method by name
-*/
-BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec,
- const std::string& def_if_empty)
- {
-#if defined(BOTAN_HAS_CIPHER_MODE_PADDING)
- if(algo_spec == "NoPadding" || (algo_spec == "" && def_if_empty == "NoPadding"))
- return new Null_Padding;
-
- if(algo_spec == "PKCS7" || (algo_spec == "" && def_if_empty == "PKCS7"))
- return new PKCS7_Padding;
-
- if(algo_spec == "OneAndZeros")
- return new OneAndZeros_Padding;
-
- if(algo_spec == "X9.23")
- return new ANSI_X923_Padding;
-
-#endif
-
- throw Algorithm_Not_Found(algo_spec);
- }
-
-}
-
-Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher,
- Cipher_Dir direction,
- const std::string& mode,
- const std::string& padding)
- {
-#if defined(BOTAN_HAS_OFB)
- if(mode == "OFB")
- return new StreamCipher_Filter(new OFB(block_cipher->clone()));
-#endif
-
-#if defined(BOTAN_HAS_CTR_BE)
- if(mode == "CTR-BE")
- return new StreamCipher_Filter(new CTR_BE(block_cipher->clone()));
-#endif
-
-#if defined(BOTAN_HAS_MODE_ECB)
- if(mode == "ECB" || mode == "")
- {
- if(direction == ENCRYPTION)
- return new Transformation_Filter(
- new ECB_Encryption(block_cipher->clone(), get_bc_pad(padding, "NoPadding")));
- else
- return new Transformation_Filter(
- new ECB_Decryption(block_cipher->clone(), get_bc_pad(padding, "NoPadding")));
- }
-#endif
-
- if(mode == "CBC")
- {
-#if defined(BOTAN_HAS_MODE_CBC)
- if(padding == "CTS")
- {
- if(direction == ENCRYPTION)
- return new Transformation_Filter(new CTS_Encryption(block_cipher->clone()));
- else
- return new Transformation_Filter(new CTS_Decryption(block_cipher->clone()));
- }
-
- if(direction == ENCRYPTION)
- return new Transformation_Filter(
- new CBC_Encryption(block_cipher->clone(), get_bc_pad(padding, "PKCS7")));
- else
- return new Transformation_Filter(
- new CBC_Decryption(block_cipher->clone(), get_bc_pad(padding, "PKCS7")));
-#else
- return nullptr;
-#endif
- }
-
-#if defined(BOTAN_HAS_MODE_XTS)
- if(mode == "XTS")
- {
- if(direction == ENCRYPTION)
- return new Transformation_Filter(new XTS_Encryption(block_cipher->clone()));
- else
- return new Transformation_Filter(new XTS_Decryption(block_cipher->clone()));
- }
-#endif
-
- if(mode.find("CFB") != std::string::npos ||
- mode.find("EAX") != std::string::npos ||
- mode.find("GCM") != std::string::npos ||
- mode.find("OCB") != std::string::npos ||
- mode.find("CCM") != std::string::npos)
- {
- std::vector<std::string> algo_info = parse_algorithm_name(mode);
- const std::string mode_name = algo_info[0];
-
- size_t bits = 8 * block_cipher->block_size();
- if(algo_info.size() > 1)
- bits = to_u32bit(algo_info[1]);
-
-#if defined(BOTAN_HAS_MODE_CFB)
- if(mode_name == "CFB")
- {
- if(direction == ENCRYPTION)
- return new Transformation_Filter(new CFB_Encryption(block_cipher->clone(), bits));
- else
- return new Transformation_Filter(new CFB_Decryption(block_cipher->clone(), bits));
- }
-#endif
-
- if(bits % 8 != 0)
- throw std::invalid_argument("AEAD interface does not support non-octet length tags");
-
-#if defined(BOTAN_HAS_AEAD_FILTER)
-
- const size_t tag_size = bits / 8;
-
-#if defined(BOTAN_HAS_AEAD_CCM)
- if(mode_name == "CCM")
- {
- const size_t L = (algo_info.size() == 3) ? to_u32bit(algo_info[2]) : 3;
- if(direction == ENCRYPTION)
- return new AEAD_Filter(new CCM_Encryption(block_cipher->clone(), tag_size, L));
- else
- return new AEAD_Filter(new CCM_Decryption(block_cipher->clone(), tag_size, L));
- }
-#endif
-
-#if defined(BOTAN_HAS_AEAD_EAX)
- if(mode_name == "EAX")
- {
- if(direction == ENCRYPTION)
- return new AEAD_Filter(new EAX_Encryption(block_cipher->clone(), tag_size));
- else
- return new AEAD_Filter(new EAX_Decryption(block_cipher->clone(), tag_size));
- }
-#endif
-
-#if defined(BOTAN_HAS_AEAD_OCB)
- if(mode_name == "OCB")
- {
- if(direction == ENCRYPTION)
- return new AEAD_Filter(new OCB_Encryption(block_cipher->clone(), tag_size));
- else
- return new AEAD_Filter(new OCB_Decryption(block_cipher->clone(), tag_size));
- }
-#endif
-
-#if defined(BOTAN_HAS_AEAD_GCM)
- if(mode_name == "GCM")
- {
- if(direction == ENCRYPTION)
- return new AEAD_Filter(new GCM_Encryption(block_cipher->clone(), tag_size));
- else
- return new AEAD_Filter(new GCM_Decryption(block_cipher->clone(), tag_size));
- }
-#endif
-
-#endif
- }
-
- return nullptr;
- }
-
/*
* Get a cipher object
*/
@@ -253,27 +52,23 @@ Keyed_Filter* Core_Engine::get_cipher(const std::string& algo_spec,
throw Lookup_Error("Cipher specification '" + algo_spec +
"' is missing mode identifier");
- std::string mode = algo_parts[1];
+ const std::string mode = algo_parts[1];
- std::string padding;
- if(algo_parts.size() == 3)
- padding = algo_parts[2];
- else
- padding = (mode == "CBC") ? "PKCS7" : "NoPadding";
+#if defined(BOTAN_HAS_OFB)
+ if(mode == "OFB")
+ return new StreamCipher_Filter(new OFB(block_cipher->clone()));
+#endif
- if(mode == "ECB" && padding == "CTS")
- return nullptr;
- else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding")
- throw Invalid_Algorithm_Name(algo_spec);
+#if defined(BOTAN_HAS_CTR_BE)
+ if(mode == "CTR-BE")
+ return new StreamCipher_Filter(new CTR_BE(block_cipher->clone()));
+#endif
- Keyed_Filter* filt = get_cipher_mode(block_cipher, direction, mode, padding);
- if(filt)
- return filt;
+ std::unique_ptr<Cipher_Mode> c(get_cipher_mode(algo_spec, direction));
+ if(c)
+ return new Transform_Filter(c.release());
- if(padding != "NoPadding")
- throw Algorithm_Not_Found(cipher_name + "/" + mode + "/" + padding);
- else
- throw Algorithm_Not_Found(cipher_name + "/" + mode);
+ throw Algorithm_Not_Found(algo_spec);
}
}
diff --git a/src/lib/engine/core_engine/lookup_block.cpp b/src/lib/engine/core_engine/lookup_block.cpp
index 703e578ac..98186403e 100644
--- a/src/lib/engine/core_engine/lookup_block.cpp
+++ b/src/lib/engine/core_engine/lookup_block.cpp
@@ -7,101 +7,7 @@
#include <botan/internal/core_engine.h>
#include <botan/scan_name.h>
-#include <botan/algo_factory.h>
-
-#if defined(BOTAN_HAS_AES)
- #include <botan/aes.h>
-#endif
-
-#if defined(BOTAN_HAS_BLOWFISH)
- #include <botan/blowfish.h>
-#endif
-
-#if defined(BOTAN_HAS_CAMELLIA)
- #include <botan/camellia.h>
-#endif
-
-#if defined(BOTAN_HAS_CAST)
- #include <botan/cast128.h>
- #include <botan/cast256.h>
-#endif
-
-#if defined(BOTAN_HAS_CASCADE)
- #include <botan/cascade.h>
-#endif
-
-#if defined(BOTAN_HAS_DES)
- #include <botan/des.h>
- #include <botan/desx.h>
-#endif
-
-#if defined(BOTAN_HAS_GOST_28147_89)
- #include <botan/gost_28147.h>
-#endif
-
-#if defined(BOTAN_HAS_IDEA)
- #include <botan/idea.h>
-#endif
-
-#if defined(BOTAN_HAS_KASUMI)
- #include <botan/kasumi.h>
-#endif
-
-#if defined(BOTAN_HAS_LION)
- #include <botan/lion.h>
-#endif
-
-#if defined(BOTAN_HAS_MARS)
- #include <botan/mars.h>
-#endif
-
-#if defined(BOTAN_HAS_MISTY1)
- #include <botan/misty1.h>
-#endif
-
-#if defined(BOTAN_HAS_NOEKEON)
- #include <botan/noekeon.h>
-#endif
-
-#if defined(BOTAN_HAS_RC2)
- #include <botan/rc2.h>
-#endif
-
-#if defined(BOTAN_HAS_RC5)
- #include <botan/rc5.h>
-#endif
-
-#if defined(BOTAN_HAS_RC6)
- #include <botan/rc6.h>
-#endif
-
-#if defined(BOTAN_HAS_SAFER)
- #include <botan/safer_sk.h>
-#endif
-
-#if defined(BOTAN_HAS_SEED)
- #include <botan/seed.h>
-#endif
-
-#if defined(BOTAN_HAS_SERPENT)
- #include <botan/serpent.h>
-#endif
-
-#if defined(BOTAN_HAS_TEA)
- #include <botan/tea.h>
-#endif
-
-#if defined(BOTAN_HAS_TWOFISH)
- #include <botan/twofish.h>
-#endif
-
-#if defined(BOTAN_HAS_THREEFISH_512)
- #include <botan/threefish.h>
-#endif
-
-#if defined(BOTAN_HAS_XTEA)
- #include <botan/xtea.h>
-#endif
+#include <botan/algo_registry.h>
namespace Botan {
@@ -109,156 +15,10 @@ namespace Botan {
* Look for an algorithm with this name
*/
BlockCipher* Core_Engine::find_block_cipher(const SCAN_Name& request,
- Algorithm_Factory& af) const
+ Algorithm_Factory&) const
{
-
-#if defined(BOTAN_HAS_AES)
- if(request.algo_name() == "AES-128")
- return new AES_128;
- if(request.algo_name() == "AES-192")
- return new AES_192;
- if(request.algo_name() == "AES-256")
- return new AES_256;
-#endif
-
-#if defined(BOTAN_HAS_BLOWFISH)
- if(request.algo_name() == "Blowfish")
- return new Blowfish;
-#endif
-
-#if defined(BOTAN_HAS_CAMELLIA)
- if(request.algo_name() == "Camellia-128")
- return new Camellia_128;
- if(request.algo_name() == "Camellia-192")
- return new Camellia_192;
- if(request.algo_name() == "Camellia-256")
- return new Camellia_256;
-#endif
-
-#if defined(BOTAN_HAS_CAST)
- if(request.algo_name() == "CAST-128")
- return new CAST_128;
- if(request.algo_name() == "CAST-256")
- return new CAST_256;
-#endif
-
-#if defined(BOTAN_HAS_DES)
- if(request.algo_name() == "DES")
- return new DES;
- if(request.algo_name() == "DESX")
- return new DESX;
- if(request.algo_name() == "TripleDES")
- return new TripleDES;
-#endif
-
-#if defined(BOTAN_HAS_GOST_28147_89)
- if(request.algo_name() == "GOST-28147-89")
- return new GOST_28147_89(request.arg(0, "R3411_94_TestParam"));
-#endif
-
-#if defined(BOTAN_HAS_IDEA)
- if(request.algo_name() == "IDEA")
- return new IDEA;
-#endif
-
-#if defined(BOTAN_HAS_KASUMI)
- if(request.algo_name() == "KASUMI")
- return new KASUMI;
-#endif
-
-#if defined(BOTAN_HAS_MARS)
- if(request.algo_name() == "MARS")
- return new MARS;
-#endif
-
-#if defined(BOTAN_HAS_MISTY1)
- if(request.algo_name() == "MISTY1")
- return new MISTY1(request.arg_as_integer(0, 8));
-#endif
-
-#if defined(BOTAN_HAS_NOEKEON)
- if(request.algo_name() == "Noekeon")
- return new Noekeon;
-#endif
-
-#if defined(BOTAN_HAS_RC2)
- if(request.algo_name() == "RC2")
- return new RC2;
-#endif
-
-#if defined(BOTAN_HAS_RC5)
- if(request.algo_name() == "RC5")
- return new RC5(request.arg_as_integer(0, 12));
-#endif
-
-#if defined(BOTAN_HAS_RC6)
- if(request.algo_name() == "RC6")
- return new RC6;
-#endif
-
-#if defined(BOTAN_HAS_SAFER)
- if(request.algo_name() == "SAFER-SK")
- return new SAFER_SK(request.arg_as_integer(0, 10));
-#endif
-
-#if defined(BOTAN_HAS_SEED)
- if(request.algo_name() == "SEED")
- return new SEED;
-#endif
-
-#if defined(BOTAN_HAS_SERPENT)
- if(request.algo_name() == "Serpent")
- return new Serpent;
-#endif
-
-#if defined(BOTAN_HAS_TEA)
- if(request.algo_name() == "TEA")
- return new TEA;
-#endif
-
-#if defined(BOTAN_HAS_TWOFISH)
- if(request.algo_name() == "Twofish")
- return new Twofish;
-#endif
-
-#if defined(BOTAN_HAS_TWOFISH)
- if(request.algo_name() == "Threefish-512")
- return new Threefish_512;
-#endif
-
-#if defined(BOTAN_HAS_XTEA)
- if(request.algo_name() == "XTEA")
- return new XTEA;
-#endif
-
-#if defined(BOTAN_HAS_CASCADE)
- if(request.algo_name() == "Cascade" && request.arg_count() == 2)
- {
- const BlockCipher* c1 = af.prototype_block_cipher(request.arg(0));
- const BlockCipher* c2 = af.prototype_block_cipher(request.arg(1));
-
- if(c1 && c2)
- return new Cascade_Cipher(c1->clone(), c2->clone());
- }
-#endif
-
-#if defined(BOTAN_HAS_LION)
- if(request.algo_name() == "Lion" && request.arg_count_between(2, 3))
- {
- const size_t block_size = request.arg_as_integer(2, 1024);
-
- const HashFunction* hash =
- af.prototype_hash_function(request.arg(0));
-
- const StreamCipher* stream_cipher =
- af.prototype_stream_cipher(request.arg(1));
-
- if(!hash || !stream_cipher)
- return nullptr;
-
- return new Lion(hash->clone(), stream_cipher->clone(), block_size);
- }
-#endif
+ if(BlockCipher* c = Algo_Registry<BlockCipher>::global_registry().make(request, "builtin"))
+ return c;
return nullptr;
}
diff --git a/src/lib/engine/simd_engine/simd_engine.cpp b/src/lib/engine/simd_engine/simd_engine.cpp
index af5f5d524..35d9cdad4 100644
--- a/src/lib/engine/simd_engine/simd_engine.cpp
+++ b/src/lib/engine/simd_engine/simd_engine.cpp
@@ -6,33 +6,9 @@
*/
#include <botan/internal/simd_engine.h>
-#include <botan/internal/simd_32.h>
+#include <botan/algo_registry.h>
#include <botan/cpuid.h>
-#if defined(BOTAN_HAS_AES_SSSE3)
- #include <botan/aes_ssse3.h>
-#endif
-
-#if defined(BOTAN_HAS_SERPENT_SIMD)
- #include <botan/serp_simd.h>
-#endif
-
-#if defined(BOTAN_HAS_THREEFISH_512_AVX2)
- #include <botan/threefish_avx2.h>
-#endif
-
-#if defined(BOTAN_HAS_NOEKEON_SIMD)
- #include <botan/noekeon_simd.h>
-#endif
-
-#if defined(BOTAN_HAS_XTEA_SIMD)
- #include <botan/xtea_simd.h>
-#endif
-
-#if defined(BOTAN_HAS_IDEA_SSE2)
- #include <botan/idea_sse2.h>
-#endif
-
#if defined(BOTAN_HAS_SHA1_SSE2)
#include <botan/sha1_sse2.h>
#endif
@@ -43,39 +19,19 @@ BlockCipher*
SIMD_Engine::find_block_cipher(const SCAN_Name& request,
Algorithm_Factory&) const
{
-#if defined(BOTAN_HAS_AES_SSSE3)
- if(request.algo_name() == "AES-128" && CPUID::has_ssse3())
- return new AES_128_SSSE3;
- if(request.algo_name() == "AES-192" && CPUID::has_ssse3())
- return new AES_192_SSSE3;
- if(request.algo_name() == "AES-256" && CPUID::has_ssse3())
- return new AES_256_SSSE3;
-#endif
+ auto& block_cipher = Algo_Registry<BlockCipher>::global_registry();
-#if defined(BOTAN_HAS_IDEA_SSE2)
- if(request.algo_name() == "IDEA" && CPUID::has_sse2())
- return new IDEA_SSE2;
-#endif
+ if(BlockCipher* c = block_cipher.make(request, "avx2"))
+ return c;
-#if defined(BOTAN_HAS_NOEKEON_SIMD)
- if(request.algo_name() == "Noekeon" && SIMD_32::enabled())
- return new Noekeon_SIMD;
-#endif
+ if(BlockCipher* c = block_cipher.make(request, "ssse3"))
+ return c;
-#if defined(BOTAN_HAS_THREEFISH_512_AVX2)
- if(request.algo_name() == "Threefish-512" && CPUID::has_avx2())
- return new Threefish_512_AVX2;
-#endif
-
-#if defined(BOTAN_HAS_SERPENT_SIMD)
- if(request.algo_name() == "Serpent" && SIMD_32::enabled())
- return new Serpent_SIMD;
-#endif
+ if(BlockCipher* c = block_cipher.make(request, "sse2"))
+ return c;
-#if defined(BOTAN_HAS_XTEA_SIMD)
- if(request.algo_name() == "XTEA" && SIMD_32::enabled())
- return new XTEA_SIMD;
-#endif
+ if(BlockCipher* c = block_cipher.make(request, "simd32"))
+ return c;
return nullptr;
}
diff --git a/src/lib/filters/aead_filt/aead_filt.h b/src/lib/filters/aead_filt/aead_filt.h
index 52e448a7a..a97b580bd 100644
--- a/src/lib/filters/aead_filt/aead_filt.h
+++ b/src/lib/filters/aead_filt/aead_filt.h
@@ -16,10 +16,10 @@ namespace Botan {
/**
* Filter interface for AEAD Modes
*/
-class BOTAN_DLL AEAD_Filter : public Transformation_Filter
+class BOTAN_DLL AEAD_Filter : public Transform_Filter
{
public:
- AEAD_Filter(AEAD_Mode* aead) : Transformation_Filter(aead) {}
+ AEAD_Filter(AEAD_Mode* aead) : Transform_Filter(aead) {}
/**
* Set associated data that is not included in the ciphertext but
diff --git a/src/lib/filters/comp_filter.cpp b/src/lib/filters/comp_filter.cpp
index b7694ce24..4c5dfac68 100644
--- a/src/lib/filters/comp_filter.cpp
+++ b/src/lib/filters/comp_filter.cpp
@@ -20,9 +20,11 @@ Decompression_Filter::Decompression_Filter(const std::string& type) :
{
}
-Compression_Decompression_Filter::Compression_Decompression_Filter(Compressor_Transformation* transform) :
- m_transform(transform)
+Compression_Decompression_Filter::Compression_Decompression_Filter(Transform* transform)
{
+ m_transform.reset(dynamic_cast<Compressor_Transform*>(transform));
+ if(!m_transform)
+ throw std::invalid_argument("Transform " + transform->name() + " is not a compressor");
}
std::string Compression_Decompression_Filter::name() const
diff --git a/src/lib/filters/comp_filter.h b/src/lib/filters/comp_filter.h
index 7bfa5b568..2284d8963 100644
--- a/src/lib/filters/comp_filter.h
+++ b/src/lib/filters/comp_filter.h
@@ -12,7 +12,8 @@
namespace Botan {
-class Compressor_Transformation;
+class Transform;
+class Compressor_Transform;
/**
* Filter interface for compression/decompression
@@ -27,11 +28,11 @@ class BOTAN_DLL Compression_Decompression_Filter : public Filter
std::string name() const override;
protected:
- Compression_Decompression_Filter(Compressor_Transformation* t);
+ Compression_Decompression_Filter(Transform* t);
void flush();
private:
- std::unique_ptr<Compressor_Transformation> m_transform;
+ std::unique_ptr<Compressor_Transform> m_transform;
secure_vector<byte> m_buffer;
};
diff --git a/src/lib/filters/transform_filter.cpp b/src/lib/filters/transform_filter.cpp
index b084bf42e..1b709012e 100644
--- a/src/lib/filters/transform_filter.cpp
+++ b/src/lib/filters/transform_filter.cpp
@@ -1,5 +1,5 @@
/*
-* Filter interface for Transformations
+* Filter interface for Transforms
* (C) 2013,2014 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
@@ -24,7 +24,7 @@ size_t choose_update_size(size_t update_granularity)
}
-Transformation_Filter::Transformation_Filter(Transformation* transform) :
+Transform_Filter::Transform_Filter(Transform* transform) :
Buffered_Filter(choose_update_size(transform->update_granularity()),
transform->minimum_final_size()),
m_nonce(transform->default_nonce_length() == 0),
@@ -33,18 +33,18 @@ Transformation_Filter::Transformation_Filter(Transformation* transform) :
{
}
-std::string Transformation_Filter::name() const
+std::string Transform_Filter::name() const
{
return m_transform->name();
}
-void Transformation_Filter::Nonce_State::update(const InitializationVector& iv)
+void Transform_Filter::Nonce_State::update(const InitializationVector& iv)
{
m_nonce = unlock(iv.bits_of());
m_fresh_nonce = true;
}
-std::vector<byte> Transformation_Filter::Nonce_State::get()
+std::vector<byte> Transform_Filter::Nonce_State::get()
{
BOTAN_ASSERT(m_fresh_nonce, "The nonce is fresh for this message");
@@ -53,47 +53,47 @@ std::vector<byte> Transformation_Filter::Nonce_State::get()
return m_nonce;
}
-void Transformation_Filter::set_iv(const InitializationVector& iv)
+void Transform_Filter::set_iv(const InitializationVector& iv)
{
m_nonce.update(iv);
}
-void Transformation_Filter::set_key(const SymmetricKey& key)
+void Transform_Filter::set_key(const SymmetricKey& key)
{
if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(m_transform.get()))
keyed->set_key(key);
else if(key.length() != 0)
- throw std::runtime_error("Transformation " + name() + " does not accept keys");
+ throw std::runtime_error("Transform " + name() + " does not accept keys");
}
-Key_Length_Specification Transformation_Filter::key_spec() const
+Key_Length_Specification Transform_Filter::key_spec() const
{
if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(m_transform.get()))
return keyed->key_spec();
return Key_Length_Specification(0);
}
-bool Transformation_Filter::valid_iv_length(size_t length) const
+bool Transform_Filter::valid_iv_length(size_t length) const
{
return m_transform->valid_nonce_length(length);
}
-void Transformation_Filter::write(const byte input[], size_t input_length)
+void Transform_Filter::write(const byte input[], size_t input_length)
{
Buffered_Filter::write(input, input_length);
}
-void Transformation_Filter::end_msg()
+void Transform_Filter::end_msg()
{
Buffered_Filter::end_msg();
}
-void Transformation_Filter::start_msg()
+void Transform_Filter::start_msg()
{
send(m_transform->start(m_nonce.get()));
}
-void Transformation_Filter::buffered_block(const byte input[], size_t input_length)
+void Transform_Filter::buffered_block(const byte input[], size_t input_length)
{
while(input_length)
{
@@ -109,7 +109,7 @@ void Transformation_Filter::buffered_block(const byte input[], size_t input_leng
}
}
-void Transformation_Filter::buffered_final(const byte input[], size_t input_length)
+void Transform_Filter::buffered_final(const byte input[], size_t input_length)
{
secure_vector<byte> buf(input, input + input_length);
m_transform->finish(buf);
diff --git a/src/lib/filters/transform_filter.h b/src/lib/filters/transform_filter.h
index 86bd7580e..3dd68405b 100644
--- a/src/lib/filters/transform_filter.h
+++ b/src/lib/filters/transform_filter.h
@@ -1,12 +1,12 @@
/*
-* Filter interface for Transformations
+* Filter interface for Transforms
* (C) 2013 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
-#ifndef BOTAN_TRANSFORMATION_FILTER_H__
-#define BOTAN_TRANSFORMATION_FILTER_H__
+#ifndef BOTAN_TRANSFORM_FILTER_H__
+#define BOTAN_TRANSFORM_FILTER_H__
#include <botan/transform.h>
#include <botan/key_filt.h>
@@ -15,13 +15,13 @@
namespace Botan {
/**
-* Filter interface for Transformations
+* Filter interface for Transforms
*/
-class BOTAN_DLL Transformation_Filter : public Keyed_Filter,
- private Buffered_Filter
+class BOTAN_DLL Transform_Filter : public Keyed_Filter,
+ private Buffered_Filter
{
public:
- Transformation_Filter(Transformation* t);
+ Transform_Filter(Transform* t);
void set_iv(const InitializationVector& iv) override;
@@ -34,9 +34,9 @@ class BOTAN_DLL Transformation_Filter : public Keyed_Filter,
std::string name() const override;
protected:
- const Transformation& get_transform() const { return *m_transform; }
+ const Transform& get_transform() const { return *m_transform; }
- Transformation& get_transform() { return *m_transform; }
+ Transform& get_transform() { return *m_transform; }
private:
void write(const byte input[], size_t input_length) override;
@@ -59,10 +59,12 @@ class BOTAN_DLL Transformation_Filter : public Keyed_Filter,
};
Nonce_State m_nonce;
- std::unique_ptr<Transformation> m_transform;
+ std::unique_ptr<Transform> m_transform;
secure_vector<byte> m_buffer;
};
+typedef Transform_Filter Transformation_Filter;
+
}
#endif
diff --git a/src/lib/libstate/libstate.cpp b/src/lib/libstate/libstate.cpp
index 6ce9c7eae..67ee7d358 100644
--- a/src/lib/libstate/libstate.cpp
+++ b/src/lib/libstate/libstate.cpp
@@ -14,10 +14,6 @@
#include <botan/internal/stl_util.h>
#include <algorithm>
-#if defined(BOTAN_HAS_SELFTESTS)
- #include <botan/selftest.h>
-#endif
-
#if defined(BOTAN_HAS_ENGINE_ASSEMBLER)
#include <botan/internal/asm_engine.h>
#endif
@@ -99,10 +95,6 @@ void Library_State::initialize()
m_sources = entropy_sources();
m_global_prng.reset(new Serialized_RNG());
-
-#if defined(BOTAN_HAS_SELFTESTS)
- confirm_startup_self_tests(algorithm_factory());
-#endif
}
}
diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp
index b1cce73e0..1f2099d2e 100644
--- a/src/lib/modes/aead/aead.cpp
+++ b/src/lib/modes/aead/aead.cpp
@@ -1,135 +1,23 @@
/*
-* Interface for AEAD modes
-* (C) 2013 Jack Lloyd
+* (C) 2013,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/aead.h>
-#include <botan/block_cipher.h>
-#include <botan/libstate.h>
-
-#if defined(BOTAN_HAS_AEAD_CCM)
- #include <botan/ccm.h>
-#endif
-
-#if defined(BOTAN_HAS_AEAD_EAX)
- #include <botan/eax.h>
-#endif
-
-#if defined(BOTAN_HAS_AEAD_GCM)
- #include <botan/gcm.h>
-#endif
-
-#if defined(BOTAN_HAS_AEAD_SIV)
- #include <botan/siv.h>
-#endif
-
-#if defined(BOTAN_HAS_AEAD_OCB)
- #include <botan/ocb.h>
-#endif
-
-#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
- #include <botan/chacha20poly1305.h>
-#endif
namespace Botan {
AEAD_Mode* get_aead(const std::string& algo_spec, Cipher_Dir direction)
{
-#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
- if(algo_spec == "ChaCha20Poly1305")
- {
- if(direction == ENCRYPTION)
- return new ChaCha20Poly1305_Encryption;
- else
- return new ChaCha20Poly1305_Decryption;
- }
-#endif
-
- Algorithm_Factory& af = global_state().algorithm_factory();
-
- const std::vector<std::string> algo_parts = split_on(algo_spec, '/');
- if(algo_parts.empty())
- throw Invalid_Algorithm_Name(algo_spec);
-
- if(algo_parts.size() < 2)
- return nullptr;
-
- const std::string cipher_name = algo_parts[0];
- const BlockCipher* cipher = af.prototype_block_cipher(cipher_name);
- if(!cipher)
- return nullptr;
-
- const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
-
- if(mode_info.empty())
- return nullptr;
-
- const std::string mode_name = mode_info[0];
-
- const size_t tag_size = (mode_info.size() > 1) ? to_u32bit(mode_info[1]) : cipher->block_size();
-
-#if defined(BOTAN_HAS_AEAD_CCM)
- if(mode_name == "CCM-8")
- {
- if(direction == ENCRYPTION)
- return new CCM_Encryption(cipher->clone(), 8, 3);
- else
- return new CCM_Decryption(cipher->clone(), 8, 3);
- }
-
- if(mode_name == "CCM" || mode_name == "CCM-8")
- {
- const size_t L = (mode_info.size() > 2) ? to_u32bit(mode_info[2]) : 3;
-
- if(direction == ENCRYPTION)
- return new CCM_Encryption(cipher->clone(), tag_size, L);
- else
- return new CCM_Decryption(cipher->clone(), tag_size, L);
- }
-#endif
-
-#if defined(BOTAN_HAS_AEAD_EAX)
- if(mode_name == "EAX")
- {
- if(direction == ENCRYPTION)
- return new EAX_Encryption(cipher->clone(), tag_size);
- else
- return new EAX_Decryption(cipher->clone(), tag_size);
- }
-#endif
-
-#if defined(BOTAN_HAS_AEAD_SIV)
- if(mode_name == "SIV")
- {
- BOTAN_ASSERT(tag_size == 16, "Valid tag size for SIV");
- if(direction == ENCRYPTION)
- return new SIV_Encryption(cipher->clone());
- else
- return new SIV_Decryption(cipher->clone());
- }
-#endif
-
-#if defined(BOTAN_HAS_AEAD_GCM)
- if(mode_name == "GCM")
- {
- if(direction == ENCRYPTION)
- return new GCM_Encryption(cipher->clone(), tag_size);
- else
- return new GCM_Decryption(cipher->clone(), tag_size);
- }
-#endif
+ std::unique_ptr<Cipher_Mode> mode(get_cipher_mode(algo_spec, direction));
-#if defined(BOTAN_HAS_AEAD_OCB)
- if(mode_name == "OCB")
+ if(AEAD_Mode* aead = dynamic_cast<AEAD_Mode*>(mode.get()))
{
- if(direction == ENCRYPTION)
- return new OCB_Encryption(cipher->clone(), tag_size);
- else
- return new OCB_Decryption(cipher->clone(), tag_size);
+ mode.release();
+ return aead;
}
-#endif
return nullptr;
}
diff --git a/src/lib/modes/aead/ccm/ccm.cpp b/src/lib/modes/aead/ccm/ccm.cpp
index e0b247ddb..cc692e364 100644
--- a/src/lib/modes/aead/ccm/ccm.cpp
+++ b/src/lib/modes/aead/ccm/ccm.cpp
@@ -5,13 +5,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/ccm.h>
#include <botan/parsing.h>
-#include <botan/internal/xor_buf.h>
-#include <algorithm>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN2(CCM_Encryption, CCM_Decryption, 16, 3);
+
/*
* CCM_Mode Constructor
*/
@@ -57,7 +58,7 @@ size_t CCM_Mode::update_granularity() const
/*
This value does not particularly matter as regardless CCM_Mode::update
buffers all input, so in theory this could be 1. However as for instance
- Transformation_Filter creates update_granularity() byte buffers, use a
+ Transform_Filter creates update_granularity() byte buffers, use a
somewhat large size to avoid bouncing on a tiny buffer.
*/
return m_cipher->parallel_bytes();
diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp
index 0961f1dc8..a278156eb 100644
--- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp
+++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp
@@ -5,14 +5,16 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/chacha20poly1305.h>
#include <botan/chacha.h>
#include <botan/poly1305.h>
-#include <botan/loadstor.h>
-#include <algorithm>
namespace Botan {
+BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Encryption);
+BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Decryption);
+
bool ChaCha20Poly1305_Mode::valid_nonce_length(size_t n) const
{
return (n == 8 || n == 12);
diff --git a/src/lib/modes/aead/eax/eax.cpp b/src/lib/modes/aead/eax/eax.cpp
index 289278a52..3b0c94416 100644
--- a/src/lib/modes/aead/eax/eax.cpp
+++ b/src/lib/modes/aead/eax/eax.cpp
@@ -5,15 +5,16 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/eax.h>
#include <botan/cmac.h>
#include <botan/ctr.h>
#include <botan/parsing.h>
-#include <botan/internal/xor_buf.h>
-#include <algorithm>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(EAX_Encryption, EAX_Decryption, 0);
+
namespace {
/*
diff --git a/src/lib/modes/aead/gcm/gcm.cpp b/src/lib/modes/aead/gcm/gcm.cpp
index 0acaa57e9..e4a2ad85c 100644
--- a/src/lib/modes/aead/gcm/gcm.cpp
+++ b/src/lib/modes/aead/gcm/gcm.cpp
@@ -6,9 +6,8 @@
*/
#include <botan/gcm.h>
+#include <botan/internal/mode_utils.h>
#include <botan/ctr.h>
-#include <botan/internal/xor_buf.h>
-#include <botan/loadstor.h>
#if defined(BOTAN_HAS_GCM_CLMUL)
#include <botan/internal/clmul.h>
@@ -17,6 +16,8 @@
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(GCM_Encryption, GCM_Decryption, 16);
+
void GHASH::gcm_multiply(secure_vector<byte>& x) const
{
#if defined(BOTAN_HAS_GCM_CLMUL)
diff --git a/src/lib/modes/aead/ocb/ocb.cpp b/src/lib/modes/aead/ocb/ocb.cpp
index 2ba30b2f9..2ba6d3ee6 100644
--- a/src/lib/modes/aead/ocb/ocb.cpp
+++ b/src/lib/modes/aead/ocb/ocb.cpp
@@ -5,14 +5,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/ocb.h>
#include <botan/cmac.h>
-#include <botan/internal/xor_buf.h>
-#include <botan/internal/bit_ops.h>
-#include <algorithm>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(OCB_Encryption, OCB_Decryption, 16);
+
// Has to be in Botan namespace so unique_ptr can reference it
class L_computer
{
diff --git a/src/lib/modes/aead/siv/siv.cpp b/src/lib/modes/aead/siv/siv.cpp
index b183bd6a0..c1416e209 100644
--- a/src/lib/modes/aead/siv/siv.cpp
+++ b/src/lib/modes/aead/siv/siv.cpp
@@ -5,15 +5,16 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/siv.h>
#include <botan/cmac.h>
#include <botan/ctr.h>
#include <botan/parsing.h>
-#include <botan/internal/xor_buf.h>
-#include <algorithm>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_MODE(SIV_Encryption, SIV_Decryption);
+
SIV_Mode::SIV_Mode(BlockCipher* cipher) :
m_name(cipher->name() + "/SIV"),
m_ctr(new CTR_BE(cipher->clone())),
@@ -44,7 +45,7 @@ size_t SIV_Mode::update_granularity() const
/*
This value does not particularly matter as regardless SIV_Mode::update
buffers all input, so in theory this could be 1. However as for instance
- Transformation_Filter creates update_granularity() byte buffers, use a
+ Transform_Filter creates update_granularity() byte buffers, use a
somewhat large size to avoid bouncing on a tiny buffer.
*/
return 128;
diff --git a/src/lib/modes/cbc/cbc.cpp b/src/lib/modes/cbc/cbc.cpp
index e89635a5d..e54553d16 100644
--- a/src/lib/modes/cbc/cbc.cpp
+++ b/src/lib/modes/cbc/cbc.cpp
@@ -5,13 +5,34 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/cbc.h>
-#include <botan/loadstor.h>
-#include <botan/internal/xor_buf.h>
-#include <botan/internal/rounding.h>
+#include <botan/mode_pad.h>
namespace Botan {
+template<typename CBC_T, typename CTS_T>
+Transform* make_cbc_mode(const Transform::Spec& spec)
+ {
+ Algorithm_Factory& af = global_state().algorithm_factory();
+ const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0));
+
+ if(bc)
+ {
+ const std::string padding = spec.arg(1, "PKCS7");
+
+ if(padding == "CTS")
+ return new CTS_T(bc->clone());
+ else
+ return new CBC_T(bc->clone(), get_bc_pad(padding));
+ }
+
+ return nullptr;
+ }
+
+BOTAN_REGISTER_TRANSFORM(CBC_Encryption, (make_cbc_mode<CBC_Encryption,CTS_Encryption>));
+BOTAN_REGISTER_TRANSFORM(CBC_Decryption, (make_cbc_mode<CBC_Decryption,CTS_Decryption>));
+
CBC_Mode::CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) :
m_cipher(cipher),
m_padding(padding),
diff --git a/src/lib/modes/cfb/cfb.cpp b/src/lib/modes/cfb/cfb.cpp
index 5c33ee3cb..c1fd98dfb 100644
--- a/src/lib/modes/cfb/cfb.cpp
+++ b/src/lib/modes/cfb/cfb.cpp
@@ -5,12 +5,14 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/cfb.h>
#include <botan/parsing.h>
-#include <botan/internal/xor_buf.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(CFB_Encryption, CFB_Decryption, 0);
+
CFB_Mode::CFB_Mode(BlockCipher* cipher, size_t feedback_bits) :
m_cipher(cipher),
m_feedback_bytes(feedback_bits ? feedback_bits / 8 : cipher->block_size())
diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp
new file mode 100644
index 000000000..ded7b4c81
--- /dev/null
+++ b/src/lib/modes/cipher_mode.cpp
@@ -0,0 +1,59 @@
+/*
+* Cipher Modes
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/cipher_mode.h>
+#include <sstream>
+
+namespace Botan {
+
+Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction)
+ {
+ const char* dir_string = (direction == ENCRYPTION) ? "_Encryption" : "_Decryption";
+
+ const std::string provider = "";
+
+ std::unique_ptr<Transform> t;
+
+ t.reset(get_transform(algo_spec, provider, dir_string));
+
+ if(Cipher_Mode* cipher = dynamic_cast<Cipher_Mode*>(t.get()))
+ {
+ t.release();
+ return cipher;
+ }
+
+ const std::vector<std::string> algo_parts = split_on(algo_spec, '/');
+ if(algo_parts.size() < 2)
+ return nullptr;
+
+ const std::string cipher_name = algo_parts[0];
+ const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
+
+ if(mode_info.empty())
+ return nullptr;
+
+ std::ostringstream t_name;
+
+ t_name << mode_info[0] << dir_string << '(' << cipher_name;
+ for(size_t i = 1; i < mode_info.size(); ++i)
+ t_name << ',' << mode_info[i];
+ for(size_t i = 2; i < algo_parts.size(); ++i)
+ t_name << ',' << algo_parts[i];
+ t_name << ')';
+
+ t.reset(get_transform(t_name.str(), provider));
+
+ if(Cipher_Mode* cipher = dynamic_cast<Cipher_Mode*>(t.get()))
+ {
+ t.release();
+ return cipher;
+ }
+
+ return nullptr;
+ }
+
+}
diff --git a/src/lib/modes/cipher_mode.h b/src/lib/modes/cipher_mode.h
index 2f75fad1c..691852214 100644
--- a/src/lib/modes/cipher_mode.h
+++ b/src/lib/modes/cipher_mode.h
@@ -25,6 +25,8 @@ class BOTAN_DLL Cipher_Mode : public Keyed_Transform
virtual bool authenticated() const { return false; }
};
+BOTAN_DLL Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction);
+
}
#endif
diff --git a/src/lib/modes/ecb/ecb.cpp b/src/lib/modes/ecb/ecb.cpp
index 53f54da99..1db272d12 100644
--- a/src/lib/modes/ecb/ecb.cpp
+++ b/src/lib/modes/ecb/ecb.cpp
@@ -5,13 +5,25 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/ecb.h>
-#include <botan/loadstor.h>
-#include <botan/internal/xor_buf.h>
-#include <botan/internal/rounding.h>
namespace Botan {
+template<typename T>
+Transform* make_ecb_mode(const Transform::Spec& spec)
+ {
+ Algorithm_Factory& af = global_state().algorithm_factory();
+ const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0));
+ BlockCipherModePaddingMethod* pad = get_bc_pad(spec.arg(1, "NoPadding"));
+ if(bc && pad)
+ return new T(bc->clone(), pad);
+ return nullptr;
+ }
+
+BOTAN_REGISTER_TRANSFORM(ECB_Encryption, make_ecb_mode<ECB_Encryption>);
+BOTAN_REGISTER_TRANSFORM(ECB_Decryption, make_ecb_mode<ECB_Decryption>);
+
ECB_Mode::ECB_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) :
m_cipher(cipher),
m_padding(padding)
diff --git a/src/lib/modes/info.txt b/src/lib/modes/info.txt
index 0dcb0cd59..b3d6d3b5f 100644
--- a/src/lib/modes/info.txt
+++ b/src/lib/modes/info.txt
@@ -2,3 +2,11 @@
<requires>
block
</requires>
+
+<header:public>
+cipher_mode.h
+</header:public>
+
+<header:internal>
+mode_utils.h
+</header:internal>
diff --git a/src/lib/modes/mode_pad/mode_pad.cpp b/src/lib/modes/mode_pad/mode_pad.cpp
index 946cd92c7..ecf241821 100644
--- a/src/lib/modes/mode_pad/mode_pad.cpp
+++ b/src/lib/modes/mode_pad/mode_pad.cpp
@@ -10,6 +10,26 @@
namespace Botan {
+/**
+* Get a block cipher padding method by name
+*/
+BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec)
+ {
+ if(algo_spec == "NoPadding")
+ return new Null_Padding;
+
+ if(algo_spec == "PKCS7")
+ return new PKCS7_Padding;
+
+ if(algo_spec == "OneAndZeros")
+ return new OneAndZeros_Padding;
+
+ if(algo_spec == "X9.23")
+ return new ANSI_X923_Padding;
+
+ return nullptr;
+ }
+
/*
* Pad with PKCS #7 Method
*/
diff --git a/src/lib/modes/mode_pad/mode_pad.h b/src/lib/modes/mode_pad/mode_pad.h
index c60e25849..c4d5baf2e 100644
--- a/src/lib/modes/mode_pad/mode_pad.h
+++ b/src/lib/modes/mode_pad/mode_pad.h
@@ -119,6 +119,8 @@ class BOTAN_DLL Null_Padding : public BlockCipherModePaddingMethod
std::string name() const { return "NoPadding"; }
};
+BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec);
+
}
#endif
diff --git a/src/lib/modes/mode_utils.h b/src/lib/modes/mode_utils.h
new file mode 100644
index 000000000..0333403a3
--- /dev/null
+++ b/src/lib/modes/mode_utils.h
@@ -0,0 +1,76 @@
+/*
+* Helper include for mode implementations
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_MODE_UTILS_H__
+#define BOTAN_MODE_UTILS_H__
+
+#include <botan/cipher_mode.h>
+#include <botan/algo_registry.h>
+#include <botan/block_cipher.h>
+#include <botan/libstate.h>
+#include <botan/loadstor.h>
+#include <botan/internal/xor_buf.h>
+#include <botan/internal/rounding.h>
+#include <botan/internal/bit_ops.h>
+#include <algorithm>
+
+namespace Botan {
+
+template<typename T>
+T* make_block_cipher_mode(const Transform::Spec& spec)
+ {
+ Algorithm_Factory& af = global_state().algorithm_factory();
+
+ if(const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0)))
+ return new T(bc->clone());
+ return nullptr;
+ }
+
+template<typename T, size_t LEN1>
+T* make_block_cipher_mode_len(const Transform::Spec& spec)
+ {
+ Algorithm_Factory& af = global_state().algorithm_factory();
+
+ if(const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0)))
+ {
+ const size_t len1 = spec.arg_as_integer(1, LEN1);
+ return new T(bc->clone(), len1);
+ }
+
+ return nullptr;
+ }
+
+template<typename T, size_t LEN1, size_t LEN2>
+T* make_block_cipher_mode_len2(const Transform::Spec& spec)
+ {
+ Algorithm_Factory& af = global_state().algorithm_factory();
+
+ if(const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0)))
+ {
+ const size_t len1 = spec.arg_as_integer(1, LEN1);
+ const size_t len2 = spec.arg_as_integer(2, LEN2);
+ return new T(bc->clone(), len1, len2);
+ }
+
+ return nullptr;
+ }
+
+#define BOTAN_REGISTER_BLOCK_CIPHER_MODE(E, D) \
+ namespace { Algo_Registry<Transform>::Add g_ ## E ## _reg(#E, make_block_cipher_mode<E>); \
+ Algo_Registry<Transform>::Add g_ ## D ## _reg(#D, make_block_cipher_mode<D>); }
+
+#define BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(E, D, LEN) \
+ namespace { Algo_Registry<Transform>::Add g_ ## E ## _reg(#E, make_block_cipher_mode_len<E, LEN>); \
+ Algo_Registry<Transform>::Add g_ ## D ## _reg(#D, make_block_cipher_mode_len<D, LEN>); }
+
+#define BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN2(E, D, LEN1, LEN2) \
+ namespace { Algo_Registry<Transform>::Add g_ ## E ## _reg(#E, make_block_cipher_mode_len2<E, LEN1, LEN2>); \
+ Algo_Registry<Transform>::Add g_ ## D ## _reg(#D, make_block_cipher_mode_len2<D, LEN1, LEN2>); }
+
+}
+
+#endif
diff --git a/src/lib/modes/xts/xts.cpp b/src/lib/modes/xts/xts.cpp
index cd3a0c653..a4095580c 100644
--- a/src/lib/modes/xts/xts.cpp
+++ b/src/lib/modes/xts/xts.cpp
@@ -5,13 +5,13 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/mode_utils.h>
#include <botan/xts.h>
-#include <botan/loadstor.h>
-#include <botan/internal/xor_buf.h>
-#include <botan/internal/rounding.h>
namespace Botan {
+BOTAN_REGISTER_BLOCK_CIPHER_MODE(XTS_Encryption, XTS_Decryption);
+
namespace {
void poly_double_128(byte out[], const byte in[])
diff --git a/src/lib/selftest/info.txt b/src/lib/selftest/info.txt
deleted file mode 100644
index 265cc0bac..000000000
--- a/src/lib/selftest/info.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-define SELFTESTS 20131128
-
-<requires>
-algo_factory
-filters
-aead_filt
-core_engine
-</requires>
diff --git a/src/lib/selftest/selftest.cpp b/src/lib/selftest/selftest.cpp
deleted file mode 100644
index f7e9ce01c..000000000
--- a/src/lib/selftest/selftest.cpp
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
-* Startup Self Tests
-* (C) 1999-2007,2013 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/selftest.h>
-#include <botan/filters.h>
-#include <botan/aead_filt.h>
-#include <botan/hex.h>
-#include <botan/internal/core_engine.h>
-#include <botan/internal/stl_util.h>
-
-namespace Botan {
-
-namespace {
-
-/*
-* Perform a Known Answer Test
-*/
-std::string test_filter_kat(Filter* filter,
- const std::string& input,
- const std::string& expected)
- {
- try
- {
- Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder);
- pipe.process_msg(input);
-
- const std::string got = pipe.read_all_as_string();
-
- const bool same = (got == expected);
-
- if(same)
- return "passed";
- else
- return (std::string("got ") + got + " expected " + expected);
- }
- catch(std::exception& e)
- {
- return std::string("exception ") + e.what();
- }
- }
-
-}
-
-/*
-* Run a set of KATs
-*/
-std::map<std::string, std::string>
-algorithm_kat_detailed(const SCAN_Name& algo_name,
- const std::map<std::string, std::string>& vars,
- Algorithm_Factory& af)
- {
- const std::string& algo = algo_name.algo_name_and_args();
-
- std::vector<std::string> providers = af.providers_of(algo);
- std::map<std::string, std::string> all_results;
-
- if(providers.empty()) // no providers, nothing to do
- return all_results;
-
- const std::string input = search_map(vars, std::string("input"));
- const std::string output = search_map(vars, std::string("output"));
-
- SymmetricKey key(search_map(vars, std::string("key")));
- InitializationVector iv(search_map(vars, std::string("iv")));
-
- for(size_t i = 0; i != providers.size(); ++i)
- {
- const std::string provider = providers[i];
-
- if(const HashFunction* proto =
- af.prototype_hash_function(algo, provider))
- {
- Filter* filt = new Hash_Filter(proto->clone());
- all_results[provider] = test_filter_kat(filt, input, output);
- }
- else if(const MessageAuthenticationCode* proto =
- af.prototype_mac(algo, provider))
- {
- Keyed_Filter* filt = new MAC_Filter(proto->clone(), key);
- all_results[provider] = test_filter_kat(filt, input, output);
- }
- else if(const StreamCipher* proto =
- af.prototype_stream_cipher(algo, provider))
- {
- Keyed_Filter* filt = new StreamCipher_Filter(proto->clone());
- filt->set_key(key);
- filt->set_iv(iv);
-
- all_results[provider] = test_filter_kat(filt, input, output);
- }
- else if(const BlockCipher* proto =
- af.prototype_block_cipher(algo, provider))
- {
- std::unique_ptr<Keyed_Filter> enc(get_cipher_mode(proto, ENCRYPTION,
- algo_name.cipher_mode(),
- algo_name.cipher_mode_pad()));
-
- std::unique_ptr<Keyed_Filter> dec(get_cipher_mode(proto, DECRYPTION,
- algo_name.cipher_mode(),
- algo_name.cipher_mode_pad()));
-
- if(!enc || !dec)
- continue;
-
- enc->set_key(key);
-
- if(enc->valid_iv_length(iv.length()))
- enc->set_iv(iv);
- else if(!enc->valid_iv_length(0))
- throw Invalid_IV_Length(algo, iv.length());
-
- dec->set_key(key);
-
- if(dec->valid_iv_length(iv.length()))
- dec->set_iv(iv);
- else if(!dec->valid_iv_length(0))
- throw Invalid_IV_Length(algo, iv.length());
-
- const std::vector<byte> ad = hex_decode(search_map(vars, std::string("ad")));
-
- if(!ad.empty())
- {
- if(AEAD_Filter* enc_aead = dynamic_cast<AEAD_Filter*>(enc.get()))
- {
- enc_aead->set_associated_data(&ad[0], ad.size());
-
- if(AEAD_Filter* dec_aead = dynamic_cast<AEAD_Filter*>(dec.get()))
- dec_aead->set_associated_data(&ad[0], ad.size());
- }
- }
-
- all_results[provider + " (encrypt)"] = test_filter_kat(enc.release(), input, output);
- all_results[provider + " (decrypt)"] = test_filter_kat(dec.release(), output, input);
- }
- }
-
- return all_results;
- }
-
-std::map<std::string, bool>
-algorithm_kat(const SCAN_Name& algo_name,
- const std::map<std::string, std::string>& vars,
- Algorithm_Factory& af)
- {
- const auto result = algorithm_kat_detailed(algo_name, vars, af);
-
- std::map<std::string, bool> pass_or_fail;
-
- for(auto i : result)
- pass_or_fail[i.first] = (i.second == "passed");
-
- return pass_or_fail;
- }
-
-namespace {
-
-void verify_results(const std::string& algo,
- const std::map<std::string, std::string>& results)
- {
- for(auto i = results.begin(); i != results.end(); ++i)
- {
- if(i->second != "passed")
- throw Self_Test_Failure(algo + " self-test failed (" + i->second + ")" +
- " with provider " + i->first);
- }
- }
-
-void hash_test(Algorithm_Factory& af,
- const std::string& name,
- const std::string& in,
- const std::string& out)
- {
- std::map<std::string, std::string> vars;
- vars["input"] = in;
- vars["output"] = out;
-
- verify_results(name, algorithm_kat_detailed(name, vars, af));
- }
-
-void mac_test(Algorithm_Factory& af,
- const std::string& name,
- const std::string& in,
- const std::string& out,
- const std::string& key)
- {
- std::map<std::string, std::string> vars;
- vars["input"] = in;
- vars["output"] = out;
- vars["key"] = key;
-
- verify_results(name, algorithm_kat_detailed(name, vars, af));
- }
-
-/*
-* Perform a KAT for a cipher
-*/
-void cipher_kat(Algorithm_Factory& af,
- const std::string& algo,
- const std::string& key_str,
- const std::string& iv_str,
- const std::string& in,
- const std::string& ecb_out,
- const std::string& cbc_out,
- const std::string& cfb_out,
- const std::string& ofb_out,
- const std::string& ctr_out)
- {
- SymmetricKey key(key_str);
- InitializationVector iv(iv_str);
-
- std::map<std::string, std::string> vars;
- vars["key"] = key_str;
- vars["iv"] = iv_str;
- vars["input"] = in;
-
- std::map<std::string, bool> results;
-
- vars["output"] = ecb_out;
- verify_results(algo + "/ECB", algorithm_kat_detailed(algo + "/ECB", vars, af));
-
- vars["output"] = cbc_out;
- verify_results(algo + "/CBC",
- algorithm_kat_detailed(algo + "/CBC/NoPadding", vars, af));
-
- vars["output"] = cfb_out;
- verify_results(algo + "/CFB", algorithm_kat_detailed(algo + "/CFB", vars, af));
-
- vars["output"] = ofb_out;
- verify_results(algo + "/OFB", algorithm_kat_detailed(algo + "/OFB", vars, af));
-
- vars["output"] = ctr_out;
- verify_results(algo + "/CTR", algorithm_kat_detailed(algo + "/CTR-BE", vars, af));
- }
-
-}
-
-/*
-* Perform Self Tests
-*/
-bool passes_self_tests(Algorithm_Factory& af)
- {
- try
- {
- confirm_startup_self_tests(af);
- }
- catch(Self_Test_Failure)
- {
- return false;
- }
-
- return true;
- }
-
-/*
-* Perform Self Tests
-*/
-void confirm_startup_self_tests(Algorithm_Factory& af)
- {
- cipher_kat(af, "AES-128",
- "2B7E151628AED2A6ABF7158809CF4F3C",
- "000102030405060708090A0B0C0D0E0F",
- "6BC1BEE22E409F96E93D7E117393172A"
- "AE2D8A571E03AC9C9EB76FAC45AF8E51",
- "3AD77BB40D7A3660A89ECAF32466EF97"
- "F5D3D58503B9699DE785895A96FDBAAF",
- "7649ABAC8119B246CEE98E9B12E9197D"
- "5086CB9B507219EE95DB113A917678B2",
- "3B3FD92EB72DAD20333449F8E83CFB4A"
- "C8A64537A0B3A93FCDE3CDAD9F1CE58B",
- "3B3FD92EB72DAD20333449F8E83CFB4A"
- "7789508D16918F03F53C52DAC54ED825",
- "3B3FD92EB72DAD20333449F8E83CFB4A"
- "010C041999E03F36448624483E582D0E");
-
- hash_test(af, "SHA-1",
- "", "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709");
-
- hash_test(af, "SHA-1",
- "616263", "A9993E364706816ABA3E25717850C26C9CD0D89D");
-
- hash_test(af, "SHA-1",
- "6162636462636465636465666465666765666768666768696768696A"
- "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071",
- "84983E441C3BD26EBAAE4AA1F95129E5E54670F1");
-
- mac_test(af, "HMAC(SHA-1)",
- "4869205468657265",
- "B617318655057264E28BC0B6FB378C8EF146BE00",
- "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B");
-
- hash_test(af, "SHA-256",
- "",
- "E3B0C44298FC1C149AFBF4C8996FB924"
- "27AE41E4649B934CA495991B7852B855");
-
- hash_test(af, "SHA-256",
- "616263",
- "BA7816BF8F01CFEA414140DE5DAE2223"
- "B00361A396177A9CB410FF61F20015AD");
-
- hash_test(af, "SHA-256",
- "6162636462636465636465666465666765666768666768696768696A"
- "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071",
- "248D6A61D20638B8E5C026930C3E6039"
- "A33CE45964FF2167F6ECEDD419DB06C1");
-
- mac_test(af, "HMAC(SHA-256)",
- "4869205468657265",
- "198A607EB44BFBC69903A0F1CF2BBDC5"
- "BA0AA3F3D9AE3C1C7A3B1696A0B68CF7",
- "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"
- "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B");
- }
-
-}
diff --git a/src/lib/selftest/selftest.h b/src/lib/selftest/selftest.h
deleted file mode 100644
index 6ed552dc3..000000000
--- a/src/lib/selftest/selftest.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-* Startup Self Test
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_SELF_TESTS_H__
-#define BOTAN_SELF_TESTS_H__
-
-#include <botan/algo_factory.h>
-#include <botan/scan_name.h>
-#include <map>
-#include <string>
-
-namespace Botan {
-
-/**
-* Run a set of self tests on some basic algorithms like AES and SHA-1
-* @param af an algorithm factory
-* @throws Self_Test_Error if a failure occured
-*/
-BOTAN_DLL void confirm_startup_self_tests(Algorithm_Factory& af);
-
-/**
-* Run a set of self tests on some basic algorithms like AES and SHA-1
-* @param af an algorithm factory
-* @returns false if a failure occured, otherwise true
-*/
-BOTAN_DLL bool passes_self_tests(Algorithm_Factory& af);
-
-/**
-* Run a set of algorithm KATs (known answer tests)
-* @param algo_name the algorithm we are testing
-* @param vars a set of input variables for this test, all
- hex encoded. Keys used: "input", "output", "key", and "iv"
-* @param af an algorithm factory
-* @returns map from provider name to test result for that provider
-*/
-BOTAN_DLL std::map<std::string, bool>
-algorithm_kat(const SCAN_Name& algo_name,
- const std::map<std::string, std::string>& vars,
- Algorithm_Factory& af);
-
-/**
-* Run a set of algorithm KATs (known answer tests)
-* @param algo_name the algorithm we are testing
-* @param vars a set of input variables for this test, all
- hex encoded. Keys used: "input", "output", "key", and "iv"
-* @param af an algorithm factory
-* @returns map from provider name to test result for that provider
-*/
-BOTAN_DLL std::map<std::string, std::string>
-algorithm_kat_detailed(const SCAN_Name& algo_name,
- const std::map<std::string, std::string>& vars,
- Algorithm_Factory& af);
-
-}
-
-#endif
diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp
index 7bbf7cd7e..f50cf1f3e 100644
--- a/src/lib/tls/tls_policy.cpp
+++ b/src/lib/tls/tls_policy.cpp
@@ -17,7 +17,7 @@ namespace TLS {
std::vector<std::string> Policy::allowed_ciphers() const
{
- return std::vector<std::string>({
+ return {
//"AES-256/OCB(12)",
//"AES-128/OCB(12)",
"ChaCha20Poly1305",
@@ -25,8 +25,8 @@ std::vector<std::string> Policy::allowed_ciphers() const
"AES-128/GCM",
"AES-256/CCM",
"AES-128/CCM",
- "AES-256/CCM-8",
- "AES-128/CCM-8",
+ "AES-256/CCM(8)",
+ "AES-128/CCM(8)",
//"Camellia-256/GCM",
//"Camellia-128/GCM",
"AES-256",
@@ -36,35 +36,35 @@ std::vector<std::string> Policy::allowed_ciphers() const
//"SEED"
//"3DES",
//"RC4",
- });
+ };
}
std::vector<std::string> Policy::allowed_signature_hashes() const
{
- return std::vector<std::string>({
+ return {
"SHA-512",
"SHA-384",
"SHA-256",
"SHA-224",
//"SHA-1",
//"MD5",
- });
+ };
}
std::vector<std::string> Policy::allowed_macs() const
{
- return std::vector<std::string>({
+ return {
"AEAD",
"SHA-384",
"SHA-256",
"SHA-1",
//"MD5",
- });
+ };
}
std::vector<std::string> Policy::allowed_key_exchange_methods() const
{
- return std::vector<std::string>({
+ return {
"SRP_SHA",
//"ECDHE_PSK",
//"DHE_PSK",
@@ -72,22 +72,22 @@ std::vector<std::string> Policy::allowed_key_exchange_methods() const
"ECDH",
"DH",
"RSA",
- });
+ };
}
std::vector<std::string> Policy::allowed_signature_methods() const
{
- return std::vector<std::string>({
+ return {
"ECDSA",
"RSA",
"DSA",
//""
- });
+ };
}
std::vector<std::string> Policy::allowed_ecc_curves() const
{
- return std::vector<std::string>({
+ return {
"brainpool512r1",
"secp521r1",
"brainpool384r1",
@@ -102,7 +102,7 @@ std::vector<std::string> Policy::allowed_ecc_curves() const
//"secp160r2",
//"secp160r1",
//"secp160k1",
- });
+ };
}
/*
@@ -352,6 +352,34 @@ void Policy::print(std::ostream& o) const
o << "minimum_dh_group_size = " << minimum_dh_group_size() << '\n';
}
+std::vector<std::string> Strict_Policy::allowed_ciphers() const
+ {
+ return { "ChaCha20Poly1305", "AES-256/GCM", "AES-128/GCM" };
+ }
+
+std::vector<std::string> Strict_Policy::allowed_signature_hashes() const
+ {
+ return { "SHA-512", "SHA-384"};
+ }
+
+std::vector<std::string> Strict_Policy::allowed_macs() const
+ {
+ return { "AEAD" };
+ }
+
+std::vector<std::string> Strict_Policy::allowed_key_exchange_methods() const
+ {
+ return { "ECDH" };
+ }
+
+bool Strict_Policy::acceptable_protocol_version(Protocol_Version version) const
+ {
+ if(version.is_datagram_protocol())
+ return (version >= Protocol_Version::DTLS_V12);
+ else
+ return (version >= Protocol_Version::TLS_V12);
+ }
+
}
}
diff --git a/src/lib/tls/tls_policy.h b/src/lib/tls/tls_policy.h
index 247510326..581d04bcd 100644
--- a/src/lib/tls/tls_policy.h
+++ b/src/lib/tls/tls_policy.h
@@ -229,27 +229,15 @@ class BOTAN_DLL Datagram_Policy : public Policy
class BOTAN_DLL Strict_Policy : public Policy
{
public:
- std::vector<std::string> allowed_ciphers() const override
- {
- return { "ChaCha20Poly1305", "AES-256/GCM", "AES-128/GCM" };
- }
+ std::vector<std::string> allowed_ciphers() const override;
- std::vector<std::string> allowed_signature_hashes() const override
- { return { "SHA-512", "SHA-384"}; }
+ std::vector<std::string> allowed_signature_hashes() const override;
- std::vector<std::string> allowed_macs() const override
- { return { "AEAD" }; }
+ std::vector<std::string> allowed_macs() const override;
- std::vector<std::string> allowed_key_exchange_methods() const override
- { return { "ECDH" }; }
+ std::vector<std::string> allowed_key_exchange_methods() const override;
- bool acceptable_protocol_version(Protocol_Version version) const override
- {
- if(version.is_datagram_protocol())
- return (version >= Protocol_Version::DTLS_V12);
- else
- return (version >= Protocol_Version::TLS_V12);
- }
+ bool acceptable_protocol_version(Protocol_Version version) const override;
};
class BOTAN_DLL Text_Policy : public Policy
diff --git a/src/lib/tls/tls_suite_info.cpp b/src/lib/tls/tls_suite_info.cpp
index 60777672a..02d277173 100644
--- a/src/lib/tls/tls_suite_info.cpp
+++ b/src/lib/tls/tls_suite_info.cpp
@@ -3,7 +3,7 @@
*
* This file was automatically generated from the IANA assignments
* (tls-parameters.txt hash 4bc98b6f75ad5b63952b5f457fa7adbfef60f095)
-* by ./src/scripts/tls_suite_info.py on 2015-01-21
+* by ./src/scripts/tls_suite_info.py on 2015-01-30
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -124,7 +124,7 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
return Ciphersuite(0xC09E, "RSA", "DH", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256");
case 0xC0A2: // DHE_RSA_WITH_AES_128_CCM_8
- return Ciphersuite(0xC0A2, "RSA", "DH", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0A2, "RSA", "DH", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256");
case 0x009E: // DHE_RSA_WITH_AES_128_GCM_SHA256
return Ciphersuite(0x009E, "RSA", "DH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256");
@@ -142,7 +142,7 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
return Ciphersuite(0xC09F, "RSA", "DH", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256");
case 0xC0A3: // DHE_RSA_WITH_AES_256_CCM_8
- return Ciphersuite(0xC0A3, "RSA", "DH", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0A3, "RSA", "DH", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256");
case 0x009F: // DHE_RSA_WITH_AES_256_GCM_SHA384
return Ciphersuite(0x009F, "RSA", "DH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384");
@@ -232,7 +232,7 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
return Ciphersuite(0xC0AC, "ECDSA", "ECDH", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256");
case 0xC0AE: // ECDHE_ECDSA_WITH_AES_128_CCM_8
- return Ciphersuite(0xC0AE, "ECDSA", "ECDH", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0AE, "ECDSA", "ECDH", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256");
case 0xC02B: // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
return Ciphersuite(0xC02B, "ECDSA", "ECDH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256");
@@ -250,7 +250,7 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
return Ciphersuite(0xC0AD, "ECDSA", "ECDH", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256");
case 0xC0AF: // ECDHE_ECDSA_WITH_AES_256_CCM_8
- return Ciphersuite(0xC0AF, "ECDSA", "ECDH", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0AF, "ECDSA", "ECDH", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256");
case 0xC02C: // ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
return Ciphersuite(0xC02C, "ECDSA", "ECDH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384");
@@ -364,10 +364,10 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
return Ciphersuite(0xC016, "", "ECDH", "RC4", 16, 0, 0, "SHA-1", 20);
case 0xC0AA: // PSK_DHE_WITH_AES_128_CCM_8
- return Ciphersuite(0xC0AA, "", "DHE_PSK", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0AA, "", "DHE_PSK", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256");
case 0xC0AB: // PSK_DHE_WITH_AES_256_CCM_8
- return Ciphersuite(0xC0AB, "", "DHE_PSK", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0AB, "", "DHE_PSK", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256");
case 0x008B: // PSK_WITH_3DES_EDE_CBC_SHA
return Ciphersuite(0x008B, "", "PSK", "3DES", 24, 8, 0, "SHA-1", 20);
@@ -382,7 +382,7 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
return Ciphersuite(0xC0A4, "", "PSK", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256");
case 0xC0A8: // PSK_WITH_AES_128_CCM_8
- return Ciphersuite(0xC0A8, "", "PSK", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0A8, "", "PSK", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256");
case 0x00A8: // PSK_WITH_AES_128_GCM_SHA256
return Ciphersuite(0x00A8, "", "PSK", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256");
@@ -400,7 +400,7 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
return Ciphersuite(0xC0A5, "", "PSK", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256");
case 0xC0A9: // PSK_WITH_AES_256_CCM_8
- return Ciphersuite(0xC0A9, "", "PSK", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0A9, "", "PSK", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256");
case 0x00A9: // PSK_WITH_AES_256_GCM_SHA384
return Ciphersuite(0x00A9, "", "PSK", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384");
@@ -436,7 +436,7 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
return Ciphersuite(0xC09C, "RSA", "RSA", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256");
case 0xC0A0: // RSA_WITH_AES_128_CCM_8
- return Ciphersuite(0xC0A0, "RSA", "RSA", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0A0, "RSA", "RSA", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256");
case 0x009C: // RSA_WITH_AES_128_GCM_SHA256
return Ciphersuite(0x009C, "RSA", "RSA", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256");
@@ -451,7 +451,7 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
return Ciphersuite(0xC09D, "RSA", "RSA", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256");
case 0xC0A1: // RSA_WITH_AES_256_CCM_8
- return Ciphersuite(0xC0A1, "RSA", "RSA", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256");
+ return Ciphersuite(0xC0A1, "RSA", "RSA", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256");
case 0x009D: // RSA_WITH_AES_256_GCM_SHA384
return Ciphersuite(0x009D, "RSA", "RSA", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384");
diff --git a/src/lib/utils/cpuid.cpp b/src/lib/utils/cpuid.cpp
index 7b7b27f7c..9dd2297e4 100644
--- a/src/lib/utils/cpuid.cpp
+++ b/src/lib/utils/cpuid.cpp
@@ -73,9 +73,10 @@
namespace Botan {
-u64bit CPUID::m_x86_processor_flags[2] = { 0, 0 };
-size_t CPUID::m_cache_line_size = 0;
-bool CPUID::m_altivec_capable = false;
+u64bit CPUID::g_x86_processor_flags[2] = { 0, 0 };
+size_t CPUID::g_cache_line_size = 0;
+bool CPUID::g_altivec_capable = false;
+bool CPUID::g_initialized = false;
namespace {
@@ -183,9 +184,12 @@ void CPUID::print(std::ostream& o)
void CPUID::initialize()
{
+ if(g_initialized)
+ return;
+
#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
if(altivec_check_sysctl() || altivec_check_pvr_emul())
- m_altivec_capable = true;
+ g_altivec_capable = true;
#endif
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
@@ -205,22 +209,22 @@ void CPUID::initialize()
X86_CPUID(1, cpuid);
- m_x86_processor_flags[0] = (static_cast<u64bit>(cpuid[2]) << 32) | cpuid[3];
+ g_x86_processor_flags[0] = (static_cast<u64bit>(cpuid[2]) << 32) | cpuid[3];
if(is_intel)
- m_cache_line_size = 8 * get_byte(2, cpuid[1]);
+ g_cache_line_size = 8 * get_byte(2, cpuid[1]);
if(max_supported_sublevel >= 7)
{
clear_mem(cpuid, 4);
X86_CPUID_SUBLEVEL(7, 0, cpuid);
- m_x86_processor_flags[1] = (static_cast<u64bit>(cpuid[2]) << 32) | cpuid[1];
+ g_x86_processor_flags[1] = (static_cast<u64bit>(cpuid[2]) << 32) | cpuid[1];
}
if(is_amd)
{
X86_CPUID(0x80000005, cpuid);
- m_cache_line_size = get_byte(3, cpuid[2]);
+ g_cache_line_size = get_byte(3, cpuid[2]);
}
#endif
@@ -230,9 +234,11 @@ void CPUID::initialize()
* If we don't have access to CPUID, we can still safely assume that
* any x86-64 processor has SSE2 and RDTSC
*/
- if(m_x86_processor_flags[0] == 0)
- m_x86_processor_flags[0] = (1 << CPUID_SSE2_BIT) | (1 << CPUID_RDTSC_BIT);
+ if(g_x86_processor_flags[0] == 0)
+ g_x86_processor_flags[0] = (1 << CPUID_SSE2_BIT) | (1 << CPUID_RDTSC_BIT);
#endif
+
+ g_initialized = true;
}
}
diff --git a/src/lib/utils/cpuid.h b/src/lib/utils/cpuid.h
index cbbdcad6d..14901199c 100644
--- a/src/lib/utils/cpuid.h
+++ b/src/lib/utils/cpuid.h
@@ -27,7 +27,7 @@ class BOTAN_DLL CPUID
/**
* Return a best guess of the cache line size
*/
- static size_t cache_line_size() { return m_cache_line_size; }
+ static size_t cache_line_size() { return g_cache_line_size; }
/**
* Check if the processor supports RDTSC
@@ -116,7 +116,7 @@ class BOTAN_DLL CPUID
/**
* Check if the processor supports AltiVec/VMX
*/
- static bool has_altivec() { return m_altivec_capable; }
+ static bool has_altivec() { return g_altivec_capable; }
static void print(std::ostream& o);
private:
@@ -140,12 +140,15 @@ class BOTAN_DLL CPUID
static bool x86_processor_flags_has(u64bit bit)
{
- return ((m_x86_processor_flags[bit/64] >> (bit % 64)) & 1);
+ if(!g_initialized)
+ initialize();
+ return ((g_x86_processor_flags[bit/64] >> (bit % 64)) & 1);
}
- static u64bit m_x86_processor_flags[2];
- static size_t m_cache_line_size;
- static bool m_altivec_capable;
+ static bool g_initialized;
+ static u64bit g_x86_processor_flags[2];
+ static size_t g_cache_line_size;
+ static bool g_altivec_capable;
};
}
diff --git a/src/lib/utils/parsing.cpp b/src/lib/utils/parsing.cpp
index ff8d5f0fb..36b168290 100644
--- a/src/lib/utils/parsing.cpp
+++ b/src/lib/utils/parsing.cpp
@@ -10,12 +10,20 @@
#include <botan/charset.h>
#include <botan/get_byte.h>
#include <set>
+#include <stdexcept>
namespace Botan {
u32bit to_u32bit(const std::string& str)
{
- return std::stoul(str, nullptr);
+ try
+ {
+ return std::stoul(str, nullptr);
+ }
+ catch(std::exception&)
+ {
+ throw std::runtime_error("Could not read '" + str + "' as decimal string");
+ }
}
/*
diff --git a/src/scripts/tls_suite_info.py b/src/scripts/tls_suite_info.py
index d569352ef..613332b14 100755
--- a/src/scripts/tls_suite_info.py
+++ b/src/scripts/tls_suite_info.py
@@ -49,7 +49,7 @@ def to_ciphersuite_info(code, name):
cipher += ['CCM']
mac_algo = 'SHA256'
elif mac_algo == 'CCM_8':
- cipher += ['CCM-8']
+ cipher += ['CCM(8)']
mac_algo = 'SHA256'
cipher_info = {
@@ -123,7 +123,7 @@ def to_ciphersuite_info(code, name):
if cipher_algo not in stream_ciphers:
mode = cipher[-1]
- if mode not in ['CBC', 'GCM', 'CCM-8', 'CCM', 'OCB']:
+ if mode not in ['CBC', 'GCM', 'CCM(8)', 'CCM', 'OCB']:
print "#warning Unknown mode %s" % (' '.join(cipher))
ivlen = 8 if cipher_algo == '3DES' else 16
diff --git a/src/tests/test_transform.cpp b/src/tests/test_transform.cpp
index 41d992944..a4a26b0a7 100644
--- a/src/tests/test_transform.cpp
+++ b/src/tests/test_transform.cpp
@@ -15,24 +15,20 @@ using namespace Botan;
namespace {
-Transformation* get_transform(const std::string& algo)
- {
- throw std::runtime_error("Unknown transform " + algo);
- }
-
secure_vector<byte> transform_test(const std::string& algo,
const secure_vector<byte>& nonce,
- const secure_vector<byte>& /*key*/,
+ const secure_vector<byte>& key,
const secure_vector<byte>& in)
{
- std::unique_ptr<Transformation> transform(get_transform(algo));
+ std::unique_ptr<Transform> t(get_transform(algo));
- //transform->set_key(key);
- transform->start(nonce);
+ if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(t.get()))
+ keyed->set_key(key);
secure_vector<byte> out = in;
- transform->update(out, 0);
+ t->start(nonce);
+ t->finish(out);
return out;
}