aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/base/algo_registry.h4
-rw-r--r--src/lib/base/info.txt3
-rw-r--r--src/lib/base/transform.cpp20
-rw-r--r--src/lib/base/transform.h182
-rw-r--r--src/lib/compression/bzip2/bzip2.cpp12
-rw-r--r--src/lib/compression/bzip2/bzip2.h14
-rw-r--r--src/lib/compression/bzip2/info.txt2
-rw-r--r--src/lib/compression/compress_utils.h4
-rw-r--r--src/lib/compression/compression.cpp69
-rw-r--r--src/lib/compression/compression.h92
-rw-r--r--src/lib/compression/lzma/info.txt2
-rw-r--r--src/lib/compression/lzma/lzma.cpp9
-rw-r--r--src/lib/compression/lzma/lzma.h11
-rw-r--r--src/lib/compression/zlib/info.txt2
-rw-r--r--src/lib/compression/zlib/zlib.cpp31
-rw-r--r--src/lib/compression/zlib/zlib.h41
-rw-r--r--src/lib/filters/aead_filt.h6
-rw-r--r--src/lib/filters/cipher_filter.cpp114
-rw-r--r--src/lib/filters/cipher_filter.h (renamed from src/lib/filters/transform_filter.h)22
-rw-r--r--src/lib/filters/comp_filter.cpp84
-rw-r--r--src/lib/filters/comp_filter.h44
-rw-r--r--src/lib/filters/info.txt6
-rw-r--r--src/lib/filters/key_filt.cpp4
-rw-r--r--src/lib/filters/transform_filter.cpp119
-rw-r--r--src/lib/misc/pbes2/pbes2.h3
-rw-r--r--src/lib/modes/aead/aead.cpp4
-rw-r--r--src/lib/modes/cipher_mode.cpp52
-rw-r--r--src/lib/modes/cipher_mode.h153
-rw-r--r--src/lib/modes/mode_utils.h18
-rw-r--r--src/lib/stream/stream_cipher.h1
30 files changed, 549 insertions, 579 deletions
diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h
index ebc23bfca..f7e66b3e2 100644
--- a/src/lib/base/algo_registry.h
+++ b/src/lib/base/algo_registry.h
@@ -294,10 +294,6 @@ make_new_T_1X(const typename Algo_Registry<T>::Spec& spec)
#define BOTAN_REGISTER_NAMED_T_2LEN(T, type, name, provider, len1, len2) \
BOTAN_REGISTER_TYPE(T, type, name, (make_new_T_2len<type,len1,len2>), provider, BOTAN_DEFAULT_ALGORITHM_PRIO)
-// 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/base/info.txt b/src/lib/base/info.txt
index 33d22a279..7553007e5 100644
--- a/src/lib/base/info.txt
+++ b/src/lib/base/info.txt
@@ -8,15 +8,12 @@ secmem.h
scan_name.h
sym_algo.h
symkey.h
-transform.h
</header:public>
<header:internal>
algo_registry.h
</header:internal>
-define TRANSFORM 20131209
-
<requires>
block
hash
diff --git a/src/lib/base/transform.cpp b/src/lib/base/transform.cpp
deleted file mode 100644
index 8f05a33ad..000000000
--- a/src/lib/base/transform.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-* (C) 2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/algo_registry.h>
-#include <botan/transform.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/base/transform.h b/src/lib/base/transform.h
deleted file mode 100644
index cd4ee9880..000000000
--- a/src/lib/base/transform.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-* Transforms of data
-* (C) 2013 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_TRANSFORM_H__
-#define BOTAN_TRANSFORM_H__
-
-#include <botan/secmem.h>
-#include <botan/key_spec.h>
-#include <botan/exceptn.h>
-#include <botan/symkey.h>
-#include <botan/scan_name.h>
-#include <string>
-#include <vector>
-
-namespace Botan {
-
-/**
-* Interface for general transformations on data
-*/
-class BOTAN_DLL Transform
- {
- public:
- typedef SCAN_Name Spec;
-
- /**
- * Begin processing a message.
- * @param nonce the per message nonce
- */
- template<typename Alloc>
- secure_vector<byte> start(const std::vector<byte, Alloc>& nonce)
- {
- return start(nonce.data(), nonce.size());
- }
-
- /**
- * Begin processing a message.
- * @param nonce the per message nonce
- */
- template<typename Alloc>
- BOTAN_DEPRECATED("Use Transform::start")
- secure_vector<byte> start_vec(const std::vector<byte, Alloc>& nonce)
- {
- return start(nonce.data(), nonce.size());
- }
-
- /**
- * Begin processing a message.
- * @param nonce the per message nonce
- * @param nonce_len length of nonce
- */
- secure_vector<byte> start(const byte nonce[], size_t nonce_len)
- {
- return start_raw(nonce, nonce_len);
- }
-
- /**
- * Begin processing a message.
- */
- secure_vector<byte> start()
- {
- return start_raw(nullptr, 0);
- }
-
- virtual secure_vector<byte> start_raw(const byte nonce[], size_t nonce_len) = 0;
-
- /**
- * Process some data. Input must be in size update_granularity() byte blocks.
- * @param blocks in/out parameter which will possibly be resized
- * @param offset an offset into blocks to begin processing
- */
- virtual void update(secure_vector<byte>& blocks, size_t offset = 0) = 0;
-
- /**
- * Complete processing of a message.
- *
- * @param final_block in/out parameter which must be at least
- * minimum_final_size() bytes, and will be set to any final output
- * @param offset an offset into final_block to begin processing
- */
- virtual void finish(secure_vector<byte>& final_block, size_t offset = 0) = 0;
-
- /**
- * Returns the size of the output if this transform is used to process a
- * message with input_length bytes. Will throw if unable to give a precise
- * answer.
- */
- virtual size_t output_length(size_t input_length) const = 0;
-
- /**
- * @return size of required blocks to update
- */
- virtual size_t update_granularity() const = 0;
-
- /**
- * @return required minimium size to finalize() - may be any
- * length larger than this.
- */
- virtual size_t minimum_final_size() const = 0;
-
- /**
- * Return the default size for a nonce
- */
- virtual size_t default_nonce_length() const = 0;
-
- /**
- * Return true iff nonce_len is a valid length for the nonce
- */
- virtual bool valid_nonce_length(size_t nonce_len) const = 0;
-
- /**
- * Return some short name describing the provider of this tranformation.
- * Useful in cases where multiple implementations are available (eg,
- * different implementations of AES). Default "core" is used for the
- * 'standard' implementation included in the library.
- */
- virtual std::string provider() const { return "core"; }
-
- virtual std::string name() const = 0;
-
- virtual void clear() = 0;
-
- virtual ~Transform() {}
- };
-
-class BOTAN_DLL Keyed_Transform : public Transform
- {
- public:
- /**
- * @return object describing limits on key size
- */
- virtual Key_Length_Specification key_spec() const = 0;
-
- /**
- * Check whether a given key length is valid for this algorithm.
- * @param length the key length to be checked.
- * @return true if the key length is valid.
- */
- bool valid_keylength(size_t length) const
- {
- return key_spec().valid_keylength(length);
- }
-
- template<typename Alloc>
- void set_key(const std::vector<byte, Alloc>& key)
- {
- set_key(key.data(), key.size());
- }
-
- void set_key(const SymmetricKey& key)
- {
- set_key(key.begin(), key.length());
- }
-
- /**
- * Set the symmetric key of this transform
- * @param key contains the key material
- * @param length in bytes of key param
- */
- void set_key(const byte key[], size_t length)
- {
- if(!valid_keylength(length))
- throw Invalid_Key_Length(name(), length);
- key_schedule(key, length);
- }
-
- private:
- 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/compression/bzip2/bzip2.cpp b/src/lib/compression/bzip2/bzip2.cpp
index d9ada84f6..565eb09fc 100644
--- a/src/lib/compression/bzip2/bzip2.cpp
+++ b/src/lib/compression/bzip2/bzip2.cpp
@@ -39,6 +39,14 @@ class Bzip2_Compression_Stream : public Bzip2_Stream
public:
explicit Bzip2_Compression_Stream(size_t block_size)
{
+ /*
+ * Defaults to 900k blocks as the computation cost of
+ * compression is not overly affected by the size, though
+ * more memory is required.
+ */
+ if(block_size == 0 || block_size >= 9)
+ block_size = 9;
+
int rc = BZ2_bzCompressInit(streamp(), block_size, 0, 0);
if(rc == BZ_MEM_ERROR)
@@ -98,9 +106,9 @@ class Bzip2_Decompression_Stream : public Bzip2_Stream
}
-Compression_Stream* Bzip2_Compression::make_stream() const
+Compression_Stream* Bzip2_Compression::make_stream(size_t comp_level) const
{
- return new Bzip2_Compression_Stream(m_block_size);
+ return new Bzip2_Compression_Stream(comp_level);
}
Compression_Stream* Bzip2_Decompression::make_stream() const
diff --git a/src/lib/compression/bzip2/bzip2.h b/src/lib/compression/bzip2/bzip2.h
index 06c80cb8e..18216f7eb 100644
--- a/src/lib/compression/bzip2/bzip2.h
+++ b/src/lib/compression/bzip2/bzip2.h
@@ -19,21 +19,9 @@ namespace Botan {
class BOTAN_DLL Bzip2_Compression final : public Stream_Compression
{
public:
- /**
- * @param block_size in 1024 KiB increments, in range from 1 to 9.
- *
- * Lowering this does not noticably modify the compression or
- * decompression speed, though less memory is required for both
- * compression and decompression.
- */
- Bzip2_Compression(size_t block_size = 9) : m_block_size(block_size) {}
-
std::string name() const override { return "Bzip2_Compression"; }
-
private:
- Compression_Stream* make_stream() const override;
-
- const size_t m_block_size;
+ Compression_Stream* make_stream(size_t comp_level) const override;
};
/**
diff --git a/src/lib/compression/bzip2/info.txt b/src/lib/compression/bzip2/info.txt
index ea2efa6f1..bc8d780be 100644
--- a/src/lib/compression/bzip2/info.txt
+++ b/src/lib/compression/bzip2/info.txt
@@ -1,4 +1,4 @@
-define BZIP2_TRANSFORM 20141118
+define BZIP2 20160412
load_on vendor
diff --git a/src/lib/compression/compress_utils.h b/src/lib/compression/compress_utils.h
index 2a830ac4e..a60ae3c22 100644
--- a/src/lib/compression/compress_utils.h
+++ b/src/lib/compression/compress_utils.h
@@ -86,8 +86,8 @@ class Zlib_Style_Stream : public Compression_Stream
};
#define BOTAN_REGISTER_COMPRESSION(C, D) \
- BOTAN_REGISTER_T_1LEN(Transform, C, 9); \
- BOTAN_REGISTER_T_NOARGS(Transform, D)
+ BOTAN_REGISTER_T_NOARGS(Compression_Algorithm, C); \
+ BOTAN_REGISTER_T_NOARGS(Decompression_Algorithm, D)
}
diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp
index 54faec7b8..f289aa79f 100644
--- a/src/lib/compression/compression.cpp
+++ b/src/lib/compression/compression.cpp
@@ -54,9 +54,7 @@ void Compression_Alloc_Info::do_free(void* ptr)
}
}
-namespace {
-
-Compressor_Transform* do_make_compressor(const std::string& type, const std::string& suffix)
+Compression_Algorithm* make_compressor(const std::string& type)
{
const std::map<std::string, std::string> trans{
{"zlib", "Zlib"},
@@ -73,31 +71,29 @@ Compressor_Transform* do_make_compressor(const std::string& type, const std::str
if(i == trans.end())
return nullptr;
- const std::string t_name = i->second + suffix;
-
- std::unique_ptr<Transform> t(get_transform(t_name));
-
- if(!t)
- return nullptr;
-
- Compressor_Transform* r = dynamic_cast<Compressor_Transform*>(t.get());
- if(!r)
- throw Exception("Bad cast of compression object " + t_name);
-
- t.release();
- return r;
+ const SCAN_Name t_name(i->second + "_Compression");
+ return Algo_Registry<Compression_Algorithm>::global_registry().make(t_name);
}
-}
-
-Compressor_Transform* make_compressor(const std::string& type, size_t level)
+Decompression_Algorithm* make_decompressor(const std::string& type)
{
- return do_make_compressor(type, "_Compression(" + std::to_string(level) + ")");
- }
+ const std::map<std::string, std::string> trans{
+ {"zlib", "Zlib"},
+ {"deflate", "Deflate"},
+ {"gzip", "Gzip"},
+ {"gz", "Gzip"},
+ {"bzip2", "Bzip2"},
+ {"bz2", "Bzip2"},
+ {"lzma", "LZMA"},
+ {"xz", "LZMA"}};
-Compressor_Transform* make_decompressor(const std::string& type)
- {
- return do_make_compressor(type, "_Decompression");
+ auto i = trans.find(type);
+
+ if(i == trans.end())
+ return nullptr;
+
+ const SCAN_Name t_name(i->second + "_Decompression");
+ return Algo_Registry<Decompression_Algorithm>::global_registry().make(t_name);
}
void Stream_Compression::clear()
@@ -105,13 +101,9 @@ void Stream_Compression::clear()
m_stream.reset();
}
-secure_vector<byte> Stream_Compression::start_raw(const byte[], size_t nonce_len)
+void Stream_Compression::start(size_t level)
{
- if(!valid_nonce_length(nonce_len))
- throw Invalid_IV_Length(name(), nonce_len);
-
- m_stream.reset(make_stream());
- return secure_vector<byte>();
+ m_stream.reset(make_stream(level));
}
void Stream_Compression::process(secure_vector<byte>& buf, size_t offset, u32bit flags)
@@ -154,16 +146,10 @@ void Stream_Compression::process(secure_vector<byte>& buf, size_t offset, u32bit
buf.swap(m_buffer);
}
-void Stream_Compression::update(secure_vector<byte>& buf, size_t offset)
- {
- BOTAN_ASSERT(m_stream, "Initialized");
- process(buf, offset, m_stream->run_flag());
- }
-
-void Stream_Compression::flush(secure_vector<byte>& buf, size_t offset)
+void Stream_Compression::update(secure_vector<byte>& buf, size_t offset, bool flush)
{
BOTAN_ASSERT(m_stream, "Initialized");
- process(buf, offset, m_stream->flush_flag());
+ process(buf, offset, flush ? m_stream->flush_flag() : m_stream->run_flag());
}
void Stream_Compression::finish(secure_vector<byte>& buf, size_t offset)
@@ -178,14 +164,9 @@ void Stream_Decompression::clear()
m_stream.reset();
}
-secure_vector<byte> Stream_Decompression::start_raw(const byte[], size_t nonce_len)
+void Stream_Decompression::start()
{
- if(!valid_nonce_length(nonce_len))
- throw Invalid_IV_Length(name(), nonce_len);
-
m_stream.reset(make_stream());
-
- return secure_vector<byte>();
}
void Stream_Decompression::process(secure_vector<byte>& buf, size_t offset, u32bit flags)
diff --git a/src/lib/compression/compression.h b/src/lib/compression/compression.h
index 66aaacdc4..81b863dcf 100644
--- a/src/lib/compression/compression.h
+++ b/src/lib/compression/compression.h
@@ -8,32 +8,76 @@
#ifndef BOTAN_COMPRESSION_TRANSFORM_H__
#define BOTAN_COMPRESSION_TRANSFORM_H__
-#include <botan/transform.h>
+#include <botan/secmem.h>
+#include <botan/scan_name.h>
namespace Botan {
-class BOTAN_DLL Compressor_Transform : public Transform
+class BOTAN_DLL Compression_Algorithm
{
public:
- size_t update_granularity() const override final { return 1; }
+ typedef SCAN_Name Spec;
+
+ /**
+ * Begin compressing. Most compression algorithms offer a tunable
+ * time/compression tradeoff parameter generally represented by
+ * an integer in the range of 1 to 9.
+ *
+ * If 0 or a value out of range is provided, a compression algorithm
+ * specific default is used.
+ */
+ virtual void start(size_t comp_level = 0) = 0;
+
+ /**
+ * Process some data. Input must be in size update_granularity() byte blocks.
+ * @param blocks in/out parameter which will possibly be resized or swapped
+ * @param offset an offset into blocks to begin processing
+ * @param flush if true the compressor will be told to flush state
+ */
+ virtual void update(secure_vector<byte>& buf, size_t offset = 0, bool flush = false) = 0;
+
+ /**
+ * Finish compressing
+ *
+ * @param final_block in/out parameter
+ * @param offset an offset into final_block to begin processing
+ */
+ virtual void finish(secure_vector<byte>& final_block, size_t offset = 0) = 0;
+
+ virtual std::string name() const = 0;
+
+ /**
+ * Reset the state and abort the current message; start can be
+ * called again to process a new message.
+ */
+ virtual void clear() = 0;
+
+ virtual ~Compression_Algorithm() {}
+ };
+
+class BOTAN_DLL Decompression_Algorithm
+ {
+ public:
+ typedef SCAN_Name Spec;
- size_t minimum_final_size() const override final { return 0; }
+ /**
+ * Decompression does not support levels
+ */
+ virtual void start() = 0;
- size_t default_nonce_length() const override final { return 0; }
+ virtual void update(secure_vector<byte>& buf, size_t offset = 0) = 0;
- bool valid_nonce_length(size_t nonce_len) const override final
- { return nonce_len == 0; }
+ virtual void finish(secure_vector<byte>& final_block, size_t offset = 0) = 0;
- virtual void flush(secure_vector<byte>& buf, size_t offset = 0) { update(buf, offset); }
+ virtual std::string name() const = 0;
- size_t output_length(size_t) const override final
- {
- throw Exception(name() + " output length indeterminate");
- }
+ virtual void clear() = 0;
+
+ virtual ~Decompression_Algorithm() {}
};
-BOTAN_DLL Compressor_Transform* make_compressor(const std::string& type, size_t level);
-BOTAN_DLL Compressor_Transform* make_decompressor(const std::string& type);
+BOTAN_DLL Compression_Algorithm* make_compressor(const std::string& type);
+BOTAN_DLL Decompression_Algorithm* make_decompressor(const std::string& type);
class Compression_Stream
{
@@ -55,39 +99,37 @@ class Compression_Stream
virtual bool run(u32bit flags) = 0;
};
-class BOTAN_DLL Stream_Compression : public Compressor_Transform
+class Stream_Compression : public Compression_Algorithm
{
public:
- void update(secure_vector<byte>& buf, size_t offset = 0) final override;
-
- void flush(secure_vector<byte>& buf, size_t offset = 0) final override;
+ void update(secure_vector<byte>& buf, size_t offset, bool flush) final override;
- void finish(secure_vector<byte>& buf, size_t offset = 0) final override;
+ void finish(secure_vector<byte>& buf, size_t offset) final override;
void clear() final override;
private:
- secure_vector<byte> start_raw(const byte[], size_t) final override;
+ void start(size_t level) final override;
void process(secure_vector<byte>& buf, size_t offset, u32bit flags);
- virtual Compression_Stream* make_stream() const = 0;
+ virtual Compression_Stream* make_stream(size_t level) const = 0;
secure_vector<byte> m_buffer;
std::unique_ptr<Compression_Stream> m_stream;
};
-class BOTAN_DLL Stream_Decompression : public Compressor_Transform
+class Stream_Decompression : public Decompression_Algorithm
{
public:
- void update(secure_vector<byte>& buf, size_t offset = 0) final override;
+ void update(secure_vector<byte>& buf, size_t offset) final override;
- void finish(secure_vector<byte>& buf, size_t offset = 0) final override;
+ void finish(secure_vector<byte>& buf, size_t offset) final override;
void clear() final override;
private:
- secure_vector<byte> start_raw(const byte[], size_t) final override;
+ void start() final override;
void process(secure_vector<byte>& buf, size_t offset, u32bit flags);
diff --git a/src/lib/compression/lzma/info.txt b/src/lib/compression/lzma/info.txt
index 443a96919..7a712338e 100644
--- a/src/lib/compression/lzma/info.txt
+++ b/src/lib/compression/lzma/info.txt
@@ -1,4 +1,4 @@
-define LZMA_TRANSFORM 20141118
+define LZMA 20160412
load_on vendor
diff --git a/src/lib/compression/lzma/lzma.cpp b/src/lib/compression/lzma/lzma.cpp
index 3cc03a098..18701278d 100644
--- a/src/lib/compression/lzma/lzma.cpp
+++ b/src/lib/compression/lzma/lzma.cpp
@@ -58,6 +58,11 @@ class LZMA_Compression_Stream : public LZMA_Stream
public:
explicit LZMA_Compression_Stream(size_t level)
{
+ if(level == 0)
+ level = 6; // default
+ else if(level > 9)
+ level = 9; // clamp to maximum allowed value
+
lzma_ret rc = ::lzma_easy_encoder(streamp(), level, LZMA_CHECK_CRC64);
if(rc == LZMA_MEM_ERROR)
@@ -84,9 +89,9 @@ class LZMA_Decompression_Stream : public LZMA_Stream
}
-Compression_Stream* LZMA_Compression::make_stream() const
+Compression_Stream* LZMA_Compression::make_stream(size_t level) const
{
- return new LZMA_Compression_Stream(m_level);
+ return new LZMA_Compression_Stream(level);
}
Compression_Stream* LZMA_Decompression::make_stream() const
diff --git a/src/lib/compression/lzma/lzma.h b/src/lib/compression/lzma/lzma.h
index d9ea10091..63722b064 100644
--- a/src/lib/compression/lzma/lzma.h
+++ b/src/lib/compression/lzma/lzma.h
@@ -20,19 +20,10 @@ namespace Botan {
class BOTAN_DLL LZMA_Compression final : public Stream_Compression
{
public:
- /**
- * @param level how much effort to use on compressing (0 to 9);
- * higher levels are slower but tend to give better
- * compression
- */
- LZMA_Compression(size_t level = 6) : m_level(level) {}
-
std::string name() const override { return "LZMA_Compression"; }
private:
- Compression_Stream* make_stream() const override;
-
- const size_t m_level;
+ Compression_Stream* make_stream(size_t level) const override;
};
/**
diff --git a/src/lib/compression/zlib/info.txt b/src/lib/compression/zlib/info.txt
index 8b722350f..6c82c49a3 100644
--- a/src/lib/compression/zlib/info.txt
+++ b/src/lib/compression/zlib/info.txt
@@ -1,4 +1,4 @@
-define ZLIB_TRANSFORM 20141118
+define ZLIB 20160412
load_on vendor
diff --git a/src/lib/compression/zlib/zlib.cpp b/src/lib/compression/zlib/zlib.cpp
index 6df5ee931..836925a68 100644
--- a/src/lib/compression/zlib/zlib.cpp
+++ b/src/lib/compression/zlib/zlib.cpp
@@ -50,20 +50,25 @@ class Zlib_Compression_Stream : public Zlib_Stream
{
wbits = compute_window_bits(wbits, wbits_offset);
- int rc = deflateInit2(streamp(), level, Z_DEFLATED, wbits,
- 8, Z_DEFAULT_STRATEGY);
+ if(level >= 9)
+ level = 9;
+ else if(level == 0)
+ level = 6;
+
+ int rc = ::deflateInit2(streamp(), level, Z_DEFLATED, wbits, 8, Z_DEFAULT_STRATEGY);
+
if(rc != Z_OK)
throw Exception("zlib deflate initialization failed");
}
~Zlib_Compression_Stream()
{
- deflateEnd(streamp());
+ ::deflateEnd(streamp());
}
bool run(u32bit flags) override
{
- int rc = deflate(streamp(), flags);
+ int rc = ::deflate(streamp(), flags);
if(rc == Z_MEM_ERROR)
throw Exception("zlib memory allocation failure");
@@ -79,7 +84,7 @@ class Zlib_Decompression_Stream : public Zlib_Stream
public:
Zlib_Decompression_Stream(int wbits, int wbits_offset = 0)
{
- int rc = inflateInit2(streamp(), compute_window_bits(wbits, wbits_offset));
+ int rc = ::inflateInit2(streamp(), compute_window_bits(wbits, wbits_offset));
if(rc == Z_MEM_ERROR)
throw Exception("zlib memory allocation failure");
@@ -89,12 +94,12 @@ class Zlib_Decompression_Stream : public Zlib_Stream
~Zlib_Decompression_Stream()
{
- inflateEnd(streamp());
+ ::inflateEnd(streamp());
}
bool run(u32bit flags) override
{
- int rc = inflate(streamp(), flags);
+ int rc = ::inflate(streamp(), flags);
if(rc == Z_MEM_ERROR)
throw Exception("zlib memory allocation failure");
@@ -145,9 +150,9 @@ class Gzip_Decompression_Stream : public Zlib_Decompression_Stream
}
-Compression_Stream* Zlib_Compression::make_stream() const
+Compression_Stream* Zlib_Compression::make_stream(size_t level) const
{
- return new Zlib_Compression_Stream(m_level, 15);
+ return new Zlib_Compression_Stream(level, 15);
}
Compression_Stream* Zlib_Decompression::make_stream() const
@@ -155,9 +160,9 @@ Compression_Stream* Zlib_Decompression::make_stream() const
return new Zlib_Decompression_Stream(15);
}
-Compression_Stream* Deflate_Compression::make_stream() const
+Compression_Stream* Deflate_Compression::make_stream(size_t level) const
{
- return new Deflate_Compression_Stream(m_level, 15);
+ return new Deflate_Compression_Stream(level, 15);
}
Compression_Stream* Deflate_Decompression::make_stream() const
@@ -165,9 +170,9 @@ Compression_Stream* Deflate_Decompression::make_stream() const
return new Deflate_Decompression_Stream(15);
}
-Compression_Stream* Gzip_Compression::make_stream() const
+Compression_Stream* Gzip_Compression::make_stream(size_t level) const
{
- return new Gzip_Compression_Stream(m_level, 15, m_os_code);
+ return new Gzip_Compression_Stream(level, 15, m_os_code);
}
Compression_Stream* Gzip_Decompression::make_stream() const
diff --git a/src/lib/compression/zlib/zlib.h b/src/lib/compression/zlib/zlib.h
index 6a8cead14..0cedb1eab 100644
--- a/src/lib/compression/zlib/zlib.h
+++ b/src/lib/compression/zlib/zlib.h
@@ -19,20 +19,9 @@ namespace Botan {
class BOTAN_DLL Zlib_Compression final : public Stream_Compression
{
public:
- /**
- * @param level how much effort to use on compressing (0 to 9);
- * higher levels are slower but tend to give better
- * compression
- */
-
- Zlib_Compression(size_t level = 6) : m_level(level) {}
-
std::string name() const override { return "Zlib_Compression"; }
-
private:
- Compression_Stream* make_stream() const override;
-
- const size_t m_level;
+ Compression_Stream* make_stream(size_t level) const override;
};
/**
@@ -42,7 +31,6 @@ class BOTAN_DLL Zlib_Decompression final : public Stream_Decompression
{
public:
std::string name() const override { return "Zlib_Decompression"; }
-
private:
Compression_Stream* make_stream() const override;
};
@@ -53,19 +41,9 @@ class BOTAN_DLL Zlib_Decompression final : public Stream_Decompression
class BOTAN_DLL Deflate_Compression final : public Stream_Compression
{
public:
- /**
- * @param level how much effort to use on compressing (0 to 9);
- * higher levels are slower but tend to give better
- * compression
- */
- Deflate_Compression(size_t level = 6) : m_level(level) {}
-
std::string name() const override { return "Deflate_Compression"; }
-
private:
- Compression_Stream* make_stream() const override;
-
- const size_t m_level;
+ Compression_Stream* make_stream(size_t level) const override;
};
/**
@@ -75,7 +53,6 @@ class BOTAN_DLL Deflate_Decompression final : public Stream_Decompression
{
public:
std::string name() const override { return "Deflate_Decompression"; }
-
private:
Compression_Stream* make_stream() const override;
};
@@ -86,20 +63,11 @@ class BOTAN_DLL Deflate_Decompression final : public Stream_Decompression
class BOTAN_DLL Gzip_Compression final : public Stream_Compression
{
public:
- /**
- * @param level how much effort to use on compressing (0 to 9);
- * higher levels are slower but tend to give better
- * compression
- */
- Gzip_Compression(size_t level = 6, byte os_code = 255) :
- m_level(level), m_os_code(os_code) {}
+ Gzip_Compression(byte os_code = 255) : m_os_code(os_code) {}
std::string name() const override { return "Gzip_Compression"; }
-
private:
- Compression_Stream* make_stream() const override;
-
- const size_t m_level;
+ Compression_Stream* make_stream(size_t level) const override;
const byte m_os_code;
};
@@ -110,7 +78,6 @@ class BOTAN_DLL Gzip_Decompression final : public Stream_Decompression
{
public:
std::string name() const override { return "Gzip_Decompression"; }
-
private:
Compression_Stream* make_stream() const override;
};
diff --git a/src/lib/filters/aead_filt.h b/src/lib/filters/aead_filt.h
index a97b580bd..c86739fc8 100644
--- a/src/lib/filters/aead_filt.h
+++ b/src/lib/filters/aead_filt.h
@@ -8,7 +8,7 @@
#ifndef BOTAN_AEAD_FILTER_H__
#define BOTAN_AEAD_FILTER_H__
-#include <botan/transform_filter.h>
+#include <botan/cipher_filter.h>
#include <botan/aead.h>
namespace Botan {
@@ -16,10 +16,10 @@ namespace Botan {
/**
* Filter interface for AEAD Modes
*/
-class BOTAN_DLL AEAD_Filter : public Transform_Filter
+class AEAD_Filter : public Cipher_Mode_Filter
{
public:
- AEAD_Filter(AEAD_Mode* aead) : Transform_Filter(aead) {}
+ AEAD_Filter(AEAD_Mode* aead) : Cipher_Mode_Filter(aead) {}
/**
* Set associated data that is not included in the ciphertext but
diff --git a/src/lib/filters/cipher_filter.cpp b/src/lib/filters/cipher_filter.cpp
new file mode 100644
index 000000000..f91cf3aa2
--- /dev/null
+++ b/src/lib/filters/cipher_filter.cpp
@@ -0,0 +1,114 @@
+/*
+* Filter interface for Cipher_Modes
+* (C) 2013,2014 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/cipher_filter.h>
+#include <botan/internal/rounding.h>
+
+namespace Botan {
+
+namespace {
+
+size_t choose_update_size(size_t update_granularity)
+ {
+ const size_t target_size = 1024;
+
+ if(update_granularity >= target_size)
+ return update_granularity;
+
+ return round_up(target_size, update_granularity);
+ }
+
+}
+
+Cipher_Mode_Filter::Cipher_Mode_Filter(Cipher_Mode* mode) :
+ Buffered_Filter(choose_update_size(mode->update_granularity()),
+ mode->minimum_final_size()),
+ m_nonce(mode->default_nonce_length() == 0),
+ m_mode(mode),
+ m_buffer(m_mode->update_granularity())
+ {
+ }
+
+std::string Cipher_Mode_Filter::name() const
+ {
+ return m_mode->name();
+ }
+
+void Cipher_Mode_Filter::Nonce_State::update(const InitializationVector& iv)
+ {
+ m_nonce = unlock(iv.bits_of());
+ m_fresh_nonce = true;
+ }
+
+std::vector<byte> Cipher_Mode_Filter::Nonce_State::get()
+ {
+ BOTAN_ASSERT(m_fresh_nonce, "The nonce is fresh for this message");
+
+ if(!m_nonce.empty())
+ m_fresh_nonce = false;
+ return m_nonce;
+ }
+
+void Cipher_Mode_Filter::set_iv(const InitializationVector& iv)
+ {
+ m_nonce.update(iv);
+ }
+
+void Cipher_Mode_Filter::set_key(const SymmetricKey& key)
+ {
+ m_mode->set_key(key);
+ }
+
+Key_Length_Specification Cipher_Mode_Filter::key_spec() const
+ {
+ return m_mode->key_spec();
+ }
+
+bool Cipher_Mode_Filter::valid_iv_length(size_t length) const
+ {
+ return m_mode->valid_nonce_length(length);
+ }
+
+void Cipher_Mode_Filter::write(const byte input[], size_t input_length)
+ {
+ Buffered_Filter::write(input, input_length);
+ }
+
+void Cipher_Mode_Filter::end_msg()
+ {
+ Buffered_Filter::end_msg();
+ }
+
+void Cipher_Mode_Filter::start_msg()
+ {
+ send(m_mode->start(m_nonce.get()));
+ }
+
+void Cipher_Mode_Filter::buffered_block(const byte input[], size_t input_length)
+ {
+ while(input_length)
+ {
+ const size_t take = std::min(m_mode->update_granularity(), input_length);
+
+ m_buffer.assign(input, input + take);
+ m_mode->update(m_buffer);
+
+ send(m_buffer);
+
+ input += take;
+ input_length -= take;
+ }
+ }
+
+void Cipher_Mode_Filter::buffered_final(const byte input[], size_t input_length)
+ {
+ secure_vector<byte> buf(input, input + input_length);
+ m_mode->finish(buf);
+ send(buf);
+ }
+
+}
diff --git a/src/lib/filters/transform_filter.h b/src/lib/filters/cipher_filter.h
index 2ecc5cecb..e0681f82a 100644
--- a/src/lib/filters/transform_filter.h
+++ b/src/lib/filters/cipher_filter.h
@@ -1,6 +1,6 @@
/*
-* Filter interface for Transforms
-* (C) 2013 Jack Lloyd
+* Filter interface for ciphers
+* (C) 2013,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -8,20 +8,20 @@
#ifndef BOTAN_TRANSFORM_FILTER_H__
#define BOTAN_TRANSFORM_FILTER_H__
-#include <botan/transform.h>
+#include <botan/cipher_mode.h>
#include <botan/key_filt.h>
#include <botan/buf_filt.h>
namespace Botan {
/**
-* Filter interface for Transforms
+* Filter interface for cipher modes
*/
-class BOTAN_DLL Transform_Filter : public Keyed_Filter,
- private Buffered_Filter
+class BOTAN_DLL Cipher_Mode_Filter : public Keyed_Filter,
+ private Buffered_Filter
{
public:
- explicit Transform_Filter(Transform* t);
+ explicit Cipher_Mode_Filter(Cipher_Mode* t);
void set_iv(const InitializationVector& iv) override;
@@ -34,9 +34,9 @@ class BOTAN_DLL Transform_Filter : public Keyed_Filter,
std::string name() const override;
protected:
- const Transform& get_transform() const { return *m_transform; }
+ const Cipher_Mode& get_mode() const { return *m_mode; }
- Transform& get_transform() { return *m_transform; }
+ Cipher_Mode& get_mode() { return *m_mode; }
private:
void write(const byte input[], size_t input_length) override;
@@ -59,10 +59,12 @@ class BOTAN_DLL Transform_Filter : public Keyed_Filter,
};
Nonce_State m_nonce;
- std::unique_ptr<Transform> m_transform;
+ std::unique_ptr<Cipher_Mode> m_mode;
secure_vector<byte> m_buffer;
};
+// deprecated aliases, will be removed before 2.0
+typedef Cipher_Mode_Filter Transform_Filter;
typedef Transform_Filter Transformation_Filter;
}
diff --git a/src/lib/filters/comp_filter.cpp b/src/lib/filters/comp_filter.cpp
index ab11526dd..a89fd68ae 100644
--- a/src/lib/filters/comp_filter.cpp
+++ b/src/lib/filters/comp_filter.cpp
@@ -1,6 +1,6 @@
/*
* Filter interface for compression
-* (C) 2014,2015 Jack Lloyd
+* (C) 2014,2015,2016 Jack Lloyd
* (C) 2015 Matej Kenda
*
* Botan is released under the Simplified BSD License (see license.txt)
@@ -8,44 +8,83 @@
#include <botan/comp_filter.h>
#include <botan/compression.h>
+#include <botan/exceptn.h>
namespace Botan {
Compression_Filter::Compression_Filter(const std::string& type, size_t level, size_t bs) :
- Compression_Decompression_Filter(make_compressor(type, level), bs)
+ m_comp(make_compressor(type)),
+ m_buffersize(std::max<size_t>(bs, 256)),
+ m_level(level)
{
+ if(!m_comp)
+ {
+ throw Invalid_Argument("Compression type '" + type + "' not found");
+ }
}
-Decompression_Filter::Decompression_Filter(const std::string& type, size_t bs) :
- Compression_Decompression_Filter(make_decompressor(type), bs)
+std::string Compression_Filter::name() const
{
+ return m_comp->name();
}
-Compression_Decompression_Filter::Compression_Decompression_Filter(Transform* transform, size_t bs) :
- m_buffersize(std::max<size_t>(256, bs)), m_buffer(m_buffersize)
+void Compression_Filter::start_msg()
{
- if (!transform)
+ m_comp->start(m_level);
+ }
+
+void Compression_Filter::write(const byte input[], size_t input_length)
+ {
+ while(input_length)
{
- throw Invalid_Argument("Transform is null");
+ const size_t take = std::min(m_buffersize, input_length);
+ BOTAN_ASSERT(take > 0, "Consumed something");
+
+ m_buffer.assign(input, input + take);
+ m_comp->update(m_buffer);
+
+ send(m_buffer);
+
+ input += take;
+ input_length -= take;
}
- m_transform.reset(dynamic_cast<Compressor_Transform*>(transform));
- if(!m_transform)
+ }
+
+void Compression_Filter::flush()
+ {
+ m_buffer.clear();
+ m_comp->update(m_buffer, 0, true);
+ send(m_buffer);
+ }
+
+void Compression_Filter::end_msg()
+ {
+ m_buffer.clear();
+ m_comp->finish(m_buffer);
+ send(m_buffer);
+ }
+
+Decompression_Filter::Decompression_Filter(const std::string& type, size_t bs) :
+ m_comp(make_decompressor(type)),
+ m_buffersize(std::max<size_t>(bs, 256))
+ {
+ if(!m_comp)
{
- throw Invalid_Argument("Transform " + transform->name() + " is not a compressor");
+ throw Invalid_Argument("Compression type '" + type + "' not found");
}
}
-std::string Compression_Decompression_Filter::name() const
+std::string Decompression_Filter::name() const
{
- return m_transform->name();
+ return m_comp->name();
}
-void Compression_Decompression_Filter::start_msg()
+void Decompression_Filter::start_msg()
{
- send(m_transform->start());
+ m_comp->start();
}
-void Compression_Decompression_Filter::write(const byte input[], size_t input_length)
+void Decompression_Filter::write(const byte input[], size_t input_length)
{
while(input_length)
{
@@ -53,7 +92,7 @@ void Compression_Decompression_Filter::write(const byte input[], size_t input_le
BOTAN_ASSERT(take > 0, "Consumed something");
m_buffer.assign(input, input + take);
- m_transform->update(m_buffer);
+ m_comp->update(m_buffer);
send(m_buffer);
@@ -62,17 +101,10 @@ void Compression_Decompression_Filter::write(const byte input[], size_t input_le
}
}
-void Compression_Decompression_Filter::flush()
- {
- m_buffer.clear();
- m_transform->flush(m_buffer);
- send(m_buffer);
- }
-
-void Compression_Decompression_Filter::end_msg()
+void Decompression_Filter::end_msg()
{
m_buffer.clear();
- m_transform->finish(m_buffer);
+ m_comp->finish(m_buffer);
send(m_buffer);
}
diff --git a/src/lib/filters/comp_filter.h b/src/lib/filters/comp_filter.h
index bb928b640..4d347c42d 100644
--- a/src/lib/filters/comp_filter.h
+++ b/src/lib/filters/comp_filter.h
@@ -1,6 +1,6 @@
/*
* Filter interface for compression
-* (C) 2014,2015 Jack Lloyd
+* (C) 2014,2015,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -12,46 +12,50 @@
namespace Botan {
-class Transform;
-class Compressor_Transform;
+class Compression_Algorithm;
+class Decompression_Algorithm;
/**
-* Filter interface for compression/decompression
+* Filter interface for compression
*/
-class BOTAN_DLL Compression_Decompression_Filter : public Filter
+class BOTAN_DLL Compression_Filter : public Filter
{
public:
void start_msg() override;
void write(const byte input[], size_t input_length) override;
void end_msg() override;
- std::string name() const override;
+ void flush();
- protected:
- Compression_Decompression_Filter(Transform* t, size_t bs);
+ std::string name() const override;
- void flush();
+ Compression_Filter(const std::string& type,
+ size_t compression_level,
+ size_t buffer_size = 4096);
private:
- std::unique_ptr<Compressor_Transform> m_transform;
- std::size_t m_buffersize;
+ std::unique_ptr<Compression_Algorithm> m_comp;
+ size_t m_buffersize, m_level;
secure_vector<byte> m_buffer;
};
-class BOTAN_DLL Compression_Filter : public Compression_Decompression_Filter
+/**
+* Filter interface for decompression
+*/
+class BOTAN_DLL Decompression_Filter : public Filter
{
public:
- Compression_Filter(const std::string& type,
- size_t compression_level,
- size_t buffer_size = 4096);
+ void start_msg() override;
+ void write(const byte input[], size_t input_length) override;
+ void end_msg() override;
- using Compression_Decompression_Filter::flush;
- };
+ std::string name() const override;
-class BOTAN_DLL Decompression_Filter : public Compression_Decompression_Filter
- {
- public:
Decompression_Filter(const std::string& type,
size_t buffer_size = 4096);
+ private:
+ std::unique_ptr<Decompression_Algorithm> m_comp;
+ std::size_t m_buffersize;
+ secure_vector<byte> m_buffer;
};
}
diff --git a/src/lib/filters/info.txt b/src/lib/filters/info.txt
index fbecd9c87..217baea1d 100644
--- a/src/lib/filters/info.txt
+++ b/src/lib/filters/info.txt
@@ -1,4 +1,4 @@
-define FILTERS 20131128
+define FILTERS 20160415
<source>
algo_filt.cpp
@@ -14,7 +14,7 @@ pipe_io.cpp
pipe_rw.cpp
secqueue.cpp
threaded_fork.cpp
-transform_filter.cpp
+cipher_filter.cpp
</source>
<header:public>
@@ -27,7 +27,7 @@ filters.h
key_filt.h
pipe.h
secqueue.h
-transform_filter.h
+cipher_filter.h
</header:public>
<header:internal>
diff --git a/src/lib/filters/key_filt.cpp b/src/lib/filters/key_filt.cpp
index 2cc350268..0f6a67da9 100644
--- a/src/lib/filters/key_filt.cpp
+++ b/src/lib/filters/key_filt.cpp
@@ -5,7 +5,7 @@
*/
#include <botan/key_filt.h>
-#include <botan/transform_filter.h>
+#include <botan/cipher_filter.h>
namespace Botan {
@@ -14,7 +14,7 @@ Keyed_Filter* get_cipher(const std::string& algo_spec,
{
std::unique_ptr<Cipher_Mode> c(get_cipher_mode(algo_spec, direction));
if(c)
- return new Transform_Filter(c.release());
+ return new Cipher_Mode_Filter(c.release());
throw Algorithm_Not_Found(algo_spec);
}
diff --git a/src/lib/filters/transform_filter.cpp b/src/lib/filters/transform_filter.cpp
deleted file mode 100644
index 27a22f9bd..000000000
--- a/src/lib/filters/transform_filter.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-* Filter interface for Transforms
-* (C) 2013,2014 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/transform_filter.h>
-#include <botan/internal/rounding.h>
-
-namespace Botan {
-
-namespace {
-
-size_t choose_update_size(size_t update_granularity)
- {
- const size_t target_size = 1024;
-
- if(update_granularity >= target_size)
- return update_granularity;
-
- return round_up(target_size, update_granularity);
- }
-
-}
-
-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),
- m_transform(transform),
- m_buffer(m_transform->update_granularity())
- {
- }
-
-std::string Transform_Filter::name() const
- {
- return m_transform->name();
- }
-
-void Transform_Filter::Nonce_State::update(const InitializationVector& iv)
- {
- m_nonce = unlock(iv.bits_of());
- m_fresh_nonce = true;
- }
-
-std::vector<byte> Transform_Filter::Nonce_State::get()
- {
- BOTAN_ASSERT(m_fresh_nonce, "The nonce is fresh for this message");
-
- if(!m_nonce.empty())
- m_fresh_nonce = false;
- return m_nonce;
- }
-
-void Transform_Filter::set_iv(const InitializationVector& iv)
- {
- m_nonce.update(iv);
- }
-
-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 Exception("Transform " + name() + " does not accept keys");
- }
-
-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 Transform_Filter::valid_iv_length(size_t length) const
- {
- return m_transform->valid_nonce_length(length);
- }
-
-void Transform_Filter::write(const byte input[], size_t input_length)
- {
- Buffered_Filter::write(input, input_length);
- }
-
-void Transform_Filter::end_msg()
- {
- Buffered_Filter::end_msg();
- }
-
-void Transform_Filter::start_msg()
- {
- send(m_transform->start(m_nonce.get()));
- }
-
-void Transform_Filter::buffered_block(const byte input[], size_t input_length)
- {
- while(input_length)
- {
- const size_t take = std::min(m_transform->update_granularity(), input_length);
-
- m_buffer.assign(input, input + take);
- m_transform->update(m_buffer);
-
- send(m_buffer);
-
- input += take;
- input_length -= take;
- }
- }
-
-void Transform_Filter::buffered_final(const byte input[], size_t input_length)
- {
- secure_vector<byte> buf(input, input + input_length);
- m_transform->finish(buf);
- send(buf);
- }
-
-}
diff --git a/src/lib/misc/pbes2/pbes2.h b/src/lib/misc/pbes2/pbes2.h
index 90aa4f84b..ea2f9aa1d 100644
--- a/src/lib/misc/pbes2/pbes2.h
+++ b/src/lib/misc/pbes2/pbes2.h
@@ -8,8 +8,7 @@
#ifndef BOTAN_PBE_PKCS_v20_H__
#define BOTAN_PBE_PKCS_v20_H__
-#include <botan/secmem.h>
-#include <botan/transform.h>
+#include <botan/rng.h>
#include <botan/alg_id.h>
#include <chrono>
diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp
index 3d04887d0..88e6cbeaa 100644
--- a/src/lib/modes/aead/aead.cpp
+++ b/src/lib/modes/aead/aead.cpp
@@ -41,8 +41,8 @@ BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN2(CCM_Encryption, CCM_Decryption, 16, 3);
#endif
#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
-BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Encryption);
-BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Decryption);
+BOTAN_REGISTER_T_NOARGS(Cipher_Mode, ChaCha20Poly1305_Encryption);
+BOTAN_REGISTER_T_NOARGS(Cipher_Mode, ChaCha20Poly1305_Decryption);
#endif
#if defined(BOTAN_HAS_AEAD_EAX)
diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp
index acd5e23e2..e7040772c 100644
--- a/src/lib/modes/cipher_mode.cpp
+++ b/src/lib/modes/cipher_mode.cpp
@@ -29,10 +29,13 @@
namespace Botan {
+#define BOTAN_REGISTER_CIPHER_MODE(name, maker) BOTAN_REGISTER_T(Cipher_Mode, name, maker)
+#define BOTAN_REGISTER_CIPHER_MODE_NOARGS(name) BOTAN_REGISTER_T_NOARGS(Cipher_Mode, name)
+
#if defined(BOTAN_HAS_MODE_ECB)
template<typename T>
-Transform* make_ecb_mode(const Transform::Spec& spec)
+Cipher_Mode* make_ecb_mode(const Cipher_Mode::Spec& spec)
{
std::unique_ptr<BlockCipher> bc(BlockCipher::create(spec.arg(0)));
std::unique_ptr<BlockCipherModePaddingMethod> pad(get_bc_pad(spec.arg(1, "NoPadding")));
@@ -41,14 +44,14 @@ Transform* make_ecb_mode(const Transform::Spec& spec)
return nullptr;
}
-BOTAN_REGISTER_TRANSFORM(ECB_Encryption, make_ecb_mode<ECB_Encryption>);
-BOTAN_REGISTER_TRANSFORM(ECB_Decryption, make_ecb_mode<ECB_Decryption>);
+BOTAN_REGISTER_CIPHER_MODE(ECB_Encryption, make_ecb_mode<ECB_Encryption>);
+BOTAN_REGISTER_CIPHER_MODE(ECB_Decryption, make_ecb_mode<ECB_Decryption>);
#endif
#if defined(BOTAN_HAS_MODE_CBC)
template<typename CBC_T, typename CTS_T>
-Transform* make_cbc_mode(const Transform::Spec& spec)
+Cipher_Mode* make_cbc_mode(const Cipher_Mode::Spec& spec)
{
std::unique_ptr<BlockCipher> bc(BlockCipher::create(spec.arg(0)));
@@ -65,8 +68,8 @@ Transform* make_cbc_mode(const Transform::Spec& spec)
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>));
+BOTAN_REGISTER_CIPHER_MODE(CBC_Encryption, (make_cbc_mode<CBC_Encryption,CTS_Encryption>));
+BOTAN_REGISTER_CIPHER_MODE(CBC_Decryption, (make_cbc_mode<CBC_Decryption,CTS_Decryption>));
#endif
#if defined(BOTAN_HAS_MODE_CFB)
@@ -83,14 +86,17 @@ Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction)
const char* dir_string = (direction == ENCRYPTION) ? "_Encryption" : "_Decryption";
- std::unique_ptr<Transform> t;
+ Cipher_Mode::Spec spec(algo_spec, dir_string);
- t.reset(get_transform(algo_spec, provider, dir_string));
+ std::unique_ptr<Cipher_Mode> cipher_mode(
+ Algo_Registry<Cipher_Mode>::global_registry().make(
+ Cipher_Mode::Spec(algo_spec, dir_string),
+ provider)
+ );
- if(Cipher_Mode* cipher = dynamic_cast<Cipher_Mode*>(t.get()))
+ if(cipher_mode)
{
- t.release();
- return cipher;
+ return cipher_mode.release();
}
const std::vector<std::string> algo_parts = split_on(algo_spec, '/');
@@ -115,24 +121,32 @@ Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction)
const std::string mode_name = mode_info[0] + alg_args.str();
const std::string mode_name_directional = mode_info[0] + dir_string + alg_args.str();
- t.reset(get_transform(mode_name_directional, provider));
+ cipher_mode.reset(
+ Algo_Registry<Cipher_Mode>::global_registry().make(
+ Cipher_Mode::Spec(mode_name_directional),
+ provider)
+ );
- if(Cipher_Mode* cipher = dynamic_cast<Cipher_Mode*>(t.get()))
+ if(cipher_mode)
{
- t.release();
- return cipher;
+ return cipher_mode.release();
}
- t.reset(get_transform(mode_name, provider));
+ cipher_mode.reset(
+ Algo_Registry<Cipher_Mode>::global_registry().make(
+ Cipher_Mode::Spec(mode_name),
+ provider)
+ );
- if(Cipher_Mode* cipher = dynamic_cast<Cipher_Mode*>(t.get()))
+ if(cipher_mode)
{
- t.release();
- return cipher;
+ return cipher_mode.release();
}
if(auto sc = StreamCipher::create(mode_name, provider))
+ {
return new Stream_Cipher_Mode(sc.release());
+ }
return nullptr;
}
diff --git a/src/lib/modes/cipher_mode.h b/src/lib/modes/cipher_mode.h
index 63821005d..73a5f7d96 100644
--- a/src/lib/modes/cipher_mode.h
+++ b/src/lib/modes/cipher_mode.h
@@ -8,17 +8,123 @@
#ifndef BOTAN_CIPHER_MODE_H__
#define BOTAN_CIPHER_MODE_H__
-#include <botan/transform.h>
-#include <botan/stream_cipher.h>
+#include <botan/secmem.h>
+#include <botan/key_spec.h>
+#include <botan/exceptn.h>
+#include <botan/symkey.h>
+#include <botan/scan_name.h>
+#include <string>
+#include <vector>
namespace Botan {
/**
* Interface for cipher modes
*/
-class BOTAN_DLL Cipher_Mode : public Keyed_Transform
+class BOTAN_DLL Cipher_Mode
{
public:
+ typedef SCAN_Name Spec;
+
+ virtual ~Cipher_Mode() {}
+
+ /**
+ * Begin processing a message.
+ * @param nonce the per message nonce
+ */
+ template<typename Alloc>
+ secure_vector<byte> start(const std::vector<byte, Alloc>& nonce)
+ {
+ return start(nonce.data(), nonce.size());
+ }
+
+ /**
+ * Begin processing a message.
+ * @param nonce the per message nonce
+ */
+ template<typename Alloc>
+ BOTAN_DEPRECATED("Use Transform::start")
+ secure_vector<byte> start_vec(const std::vector<byte, Alloc>& nonce)
+ {
+ return start(nonce.data(), nonce.size());
+ }
+
+ /**
+ * Begin processing a message.
+ * @param nonce the per message nonce
+ * @param nonce_len length of nonce
+ */
+ secure_vector<byte> start(const byte nonce[], size_t nonce_len)
+ {
+ return start_raw(nonce, nonce_len);
+ }
+
+ /**
+ * Begin processing a message.
+ */
+ secure_vector<byte> start()
+ {
+ return start_raw(nullptr, 0);
+ }
+
+ virtual secure_vector<byte> start_raw(const byte nonce[], size_t nonce_len) = 0;
+
+ /**
+ * Process some data. Input must be in size update_granularity() byte blocks.
+ * @param blocks in/out parameter which will possibly be resized
+ * @param offset an offset into blocks to begin processing
+ */
+ virtual void update(secure_vector<byte>& blocks, size_t offset = 0) = 0;
+
+ /**
+ * Complete processing of a message.
+ *
+ * @param final_block in/out parameter which must be at least
+ * minimum_final_size() bytes, and will be set to any final output
+ * @param offset an offset into final_block to begin processing
+ */
+ virtual void finish(secure_vector<byte>& final_block, size_t offset = 0) = 0;
+
+ /**
+ * Returns the size of the output if this transform is used to process a
+ * message with input_length bytes. Will throw if unable to give a precise
+ * answer.
+ */
+ virtual size_t output_length(size_t input_length) const = 0;
+
+ /**
+ * @return size of required blocks to update
+ */
+ virtual size_t update_granularity() const = 0;
+
+ /**
+ * @return required minimium size to finalize() - may be any
+ * length larger than this.
+ */
+ virtual size_t minimum_final_size() const = 0;
+
+ /**
+ * Return the default size for a nonce
+ */
+ virtual size_t default_nonce_length() const = 0;
+
+ /**
+ * Return true iff nonce_len is a valid length for the nonce
+ */
+ virtual bool valid_nonce_length(size_t nonce_len) const = 0;
+
+ /**
+ * Return some short name describing the provider of this tranformation.
+ * Useful in cases where multiple implementations are available (eg,
+ * different implementations of AES). Default "core" is used for the
+ * 'standard' implementation included in the library.
+ */
+ virtual std::string provider() const { return "core"; }
+
+ virtual std::string name() const = 0;
+
+ virtual void clear() = 0;
+
/**
* Returns true iff this mode provides authentication as well as
* confidentiality.
@@ -29,6 +135,47 @@ class BOTAN_DLL Cipher_Mode : public Keyed_Transform
* Return the size of the authentication tag used (in bytes)
*/
virtual size_t tag_size() const { return 0; }
+
+ /**
+ * @return object describing limits on key size
+ */
+ virtual Key_Length_Specification key_spec() const = 0;
+
+ /**
+ * Check whether a given key length is valid for this algorithm.
+ * @param length the key length to be checked.
+ * @return true if the key length is valid.
+ */
+ bool valid_keylength(size_t length) const
+ {
+ return key_spec().valid_keylength(length);
+ }
+
+ template<typename Alloc>
+ void set_key(const std::vector<byte, Alloc>& key)
+ {
+ set_key(key.data(), key.size());
+ }
+
+ void set_key(const SymmetricKey& key)
+ {
+ set_key(key.begin(), key.length());
+ }
+
+ /**
+ * Set the symmetric key of this transform
+ * @param key contains the key material
+ * @param length in bytes of key param
+ */
+ void set_key(const byte key[], size_t length)
+ {
+ if(!valid_keylength(length))
+ throw Invalid_Key_Length(name(), length);
+ key_schedule(key, length);
+ }
+
+ private:
+ virtual void key_schedule(const byte key[], size_t length) = 0;
};
/**
diff --git a/src/lib/modes/mode_utils.h b/src/lib/modes/mode_utils.h
index 44524c4f6..3e4b7370b 100644
--- a/src/lib/modes/mode_utils.h
+++ b/src/lib/modes/mode_utils.h
@@ -18,7 +18,7 @@
namespace Botan {
template<typename T>
-T* make_block_cipher_mode(const Transform::Spec& spec)
+T* make_block_cipher_mode(const Cipher_Mode::Spec& spec)
{
if(std::unique_ptr<BlockCipher> bc = BlockCipher::create(spec.arg(0)))
return new T(bc.release());
@@ -26,7 +26,7 @@ T* make_block_cipher_mode(const Transform::Spec& spec)
}
template<typename T, size_t LEN1>
-T* make_block_cipher_mode_len(const Transform::Spec& spec)
+T* make_block_cipher_mode_len(const Cipher_Mode::Spec& spec)
{
if(std::unique_ptr<BlockCipher> bc = BlockCipher::create(spec.arg(0)))
{
@@ -38,7 +38,7 @@ T* make_block_cipher_mode_len(const Transform::Spec& spec)
}
template<typename T, size_t LEN1, size_t LEN2>
-T* make_block_cipher_mode_len2(const Transform::Spec& spec)
+T* make_block_cipher_mode_len2(const Cipher_Mode::Spec& spec)
{
if(std::unique_ptr<BlockCipher> bc = BlockCipher::create(spec.arg(0)))
{
@@ -51,16 +51,16 @@ T* make_block_cipher_mode_len2(const Transform::Spec& spec)
}
#define BOTAN_REGISTER_BLOCK_CIPHER_MODE(E, D) \
- BOTAN_REGISTER_NAMED_T(Transform, #E, E, make_block_cipher_mode<E>); \
- BOTAN_REGISTER_NAMED_T(Transform, #D, D, make_block_cipher_mode<D>)
+ BOTAN_REGISTER_NAMED_T(Cipher_Mode, #E, E, make_block_cipher_mode<E>); \
+ BOTAN_REGISTER_NAMED_T(Cipher_Mode, #D, D, make_block_cipher_mode<D>)
#define BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(E, D, LEN) \
- BOTAN_REGISTER_NAMED_T(Transform, #E, E, (make_block_cipher_mode_len<E, LEN>)); \
- BOTAN_REGISTER_NAMED_T(Transform, #D, D, (make_block_cipher_mode_len<D, LEN>))
+ BOTAN_REGISTER_NAMED_T(Cipher_Mode, #E, E, (make_block_cipher_mode_len<E, LEN>)); \
+ BOTAN_REGISTER_NAMED_T(Cipher_Mode, #D, D, (make_block_cipher_mode_len<D, LEN>))
#define BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN2(E, D, LEN1, LEN2) \
- BOTAN_REGISTER_NAMED_T(Transform, #E, E, (make_block_cipher_mode_len2<E, LEN1, LEN2>)); \
- BOTAN_REGISTER_NAMED_T(Transform, #D, D, (make_block_cipher_mode_len2<D, LEN1, LEN2>))
+ BOTAN_REGISTER_NAMED_T(Cipher_Mode, #E, E, (make_block_cipher_mode_len2<E, LEN1, LEN2>)); \
+ BOTAN_REGISTER_NAMED_T(Cipher_Mode, #D, D, (make_block_cipher_mode_len2<D, LEN1, LEN2>))
}
diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h
index 8c9b28147..bff1fd1a6 100644
--- a/src/lib/stream/stream_cipher.h
+++ b/src/lib/stream/stream_cipher.h
@@ -8,7 +8,6 @@
#ifndef BOTAN_STREAM_CIPHER_H__
#define BOTAN_STREAM_CIPHER_H__
-#include <botan/transform.h>
#include <botan/sym_algo.h>
#include <botan/scan_name.h>