diff options
Diffstat (limited to 'src')
154 files changed, 1089 insertions, 727 deletions
diff --git a/src/algo_base/algo_base.h b/src/algo_base/algo_base.h new file mode 100644 index 000000000..c27ea1809 --- /dev/null +++ b/src/algo_base/algo_base.h @@ -0,0 +1,47 @@ +/* +* Symmetric Algorithm Base Class +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ALGO_BASE_CLASS_H__ +#define BOTAN_ALGO_BASE_CLASS_H__ + +#include <botan/build.h> +#include <string> + +namespace Botan { + +/** +* This class represents a symmetric algorithm object. +*/ +class BOTAN_DLL Algorithm + { + public: + + /** + * Make a new object representing the same algorithm as *this + */ + virtual Algorithm* clone() const = 0; + + /** + * Zeroize internal state + */ + virtual void clear() = 0; + + /** + * @return name of this algorithm + */ + virtual std::string name() const = 0; + + Algorithm() {} + virtual ~Algorithm() {} + private: + Algorithm(const Algorithm&) {} + Algorithm& operator=(const Algorithm&) { return (*this); } + }; + +} + +#endif diff --git a/src/utils/buf_comp/buf_comp.h b/src/algo_base/buf_comp.h index 0b0ef6e16..7838571e9 100644 --- a/src/utils/buf_comp/buf_comp.h +++ b/src/algo_base/buf_comp.h @@ -1,5 +1,5 @@ /* -* BufferedComputation +* Buffered Computation * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license @@ -17,19 +17,13 @@ namespace Botan { * This class represents any kind of computation which uses an internal * state, such as hash functions or MACs */ -class BOTAN_DLL BufferedComputation +class BOTAN_DLL Buffered_Computation { public: /** - * The length of the output of this function in bytes. - * @deprecated Use output_length() - */ - const size_t OUTPUT_LENGTH; - - /** * @return length of the output of this function in bytes */ - size_t output_length() const { return OUTPUT_LENGTH; } + virtual size_t output_length() const = 0; /** * Add new input to process. @@ -134,15 +128,8 @@ class BOTAN_DLL BufferedComputation return final(); } - /** - * @param out_len the output length of this computation - */ - BufferedComputation(size_t out_len) : OUTPUT_LENGTH(out_len) {} - - virtual ~BufferedComputation() {} + virtual ~Buffered_Computation() {} private: - BufferedComputation& operator=(const BufferedComputation&); - /** * Add more data to the computation * @param input is an input buffer diff --git a/src/sym_algo/info.txt b/src/algo_base/info.txt index cfdd9b691..cfdd9b691 100644 --- a/src/sym_algo/info.txt +++ b/src/algo_base/info.txt diff --git a/src/algo_base/key_spec.h b/src/algo_base/key_spec.h new file mode 100644 index 000000000..73cd9126f --- /dev/null +++ b/src/algo_base/key_spec.h @@ -0,0 +1,88 @@ +/* +* Symmetric Key Length Specification +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_KEY_LEN_SPECIFICATION_H__ +#define BOTAN_KEY_LEN_SPECIFICATION_H__ + +#include <botan/types.h> + +namespace Botan { + +/** +* Represents the length requirements on an algorithm key +*/ +class BOTAN_DLL Key_Length_Specification + { + public: + /** + * Constructor for fixed length keys + * @param keylen the supported key length + */ + Key_Length_Specification(size_t keylen) : + min_keylen(keylen), + max_keylen(keylen), + keylen_mod(1) + { + } + + /** + * Constructor for variable length keys + * @param min_k the smallest supported key length + * @param max_k the largest supported key length + * @param k_mod the number of bytes the key must be a multiple of + */ + Key_Length_Specification(size_t min_k, + size_t max_k, + size_t k_mod = 1) : + min_keylen(min_k), + max_keylen(max_k ? max_k : min_k), + keylen_mod(k_mod) + { + } + + /** + * @param length is a key length in bytes + * @return true iff this length is a valid length for this algo + */ + bool valid_keylength(size_t length) const + { + return ((length >= min_keylen) && + (length <= max_keylen) && + (length % keylen_mod == 0)); + } + + /** + * @return minimum key length in bytes + */ + size_t minimum_keylength() const + { + return min_keylen; + } + + /** + * @return maximum key length in bytes + */ + size_t maximum_keylength() const + { + return max_keylen; + } + + /** + * @return key length multiple in bytes + */ + size_t keylength_multiple() const + { + return keylen_mod; + } + + private: + size_t min_keylen, max_keylen, keylen_mod; + }; + +} + +#endif diff --git a/src/sym_algo/sym_algo.h b/src/algo_base/sym_algo.h index 0a1423f13..705c7d00a 100644 --- a/src/sym_algo/sym_algo.h +++ b/src/algo_base/sym_algo.h @@ -8,39 +8,50 @@ #ifndef BOTAN_SYMMETRIC_ALGORITHM_H__ #define BOTAN_SYMMETRIC_ALGORITHM_H__ -#include <botan/types.h> +#include <botan/algo_base.h> +#include <botan/key_spec.h> #include <botan/exceptn.h> #include <botan/symkey.h> +#include <botan/types.h> namespace Botan { /** * This class represents a symmetric algorithm object. */ -class BOTAN_DLL SymmetricAlgorithm +class BOTAN_DLL SymmetricAlgorithm : public Algorithm { public: - /** - * The maximum allowed key length. + * @return object describing limits on key size */ - const size_t MAXIMUM_KEYLENGTH; + virtual Key_Length_Specification key_spec() const = 0; /** - * The minimal allowed key length. + * @return minimum allowed key length */ - const size_t MINIMUM_KEYLENGTH; + size_t maximum_keylength() const + { + return key_spec().maximum_keylength(); + } /** - * A valid keylength is a multiple of this value. + * @return maxmium allowed key length */ - const size_t KEYLENGTH_MULTIPLE; + size_t minimum_keylength() const + { + return key_spec().minimum_keylength(); + } /** - * The name of the algorithm. - * @return name of the algorithm + * 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. */ - virtual std::string name() const = 0; + bool valid_keylength(size_t length) const + { + return key_spec().valid_keylength(length); + } /** * Set the symmetric key of this object. @@ -60,32 +71,6 @@ class BOTAN_DLL SymmetricAlgorithm throw Invalid_Key_Length(name(), length); key_schedule(key, length); } - - /** - * 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 ((length >= MINIMUM_KEYLENGTH) && - (length <= MAXIMUM_KEYLENGTH) && - (length % KEYLENGTH_MULTIPLE == 0)); - } - - /** - * Construct a SymmetricAlgorithm. - * @param key_min the minimum allowed key length - * @param key_max the maximum allowed key length - * @param key_mod any valid key length must be a multiple of this value - */ - SymmetricAlgorithm(size_t key_min, size_t key_max, size_t key_mod) : - MAXIMUM_KEYLENGTH(key_max ? key_max : key_min), - MINIMUM_KEYLENGTH(key_min), - KEYLENGTH_MULTIPLE(key_mod) - {} - - virtual ~SymmetricAlgorithm() {} private: /** * Run the key schedule diff --git a/src/sym_algo/symkey.cpp b/src/algo_base/symkey.cpp index e8b9ddd21..56648d9c5 100644 --- a/src/sym_algo/symkey.cpp +++ b/src/algo_base/symkey.cpp @@ -28,11 +28,8 @@ OctetString::OctetString(RandomNumberGenerator& rng, */ void OctetString::change(const std::string& hex_string) { - SecureVector<byte> decoded(1 + hex_string.length() / 2); - - size_t written = hex_decode(&decoded[0], hex_string); - - bits.set(&decoded[0], written); + bits.resize(1 + hex_string.length() / 2); + bits.resize(hex_decode(&bits[0], hex_string)); } /* diff --git a/src/sym_algo/symkey.h b/src/algo_base/symkey.h index 6735b2b87..6735b2b87 100644 --- a/src/sym_algo/symkey.h +++ b/src/algo_base/symkey.h diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp index 9859a3bca..9e4f78569 100644 --- a/src/algo_factory/algo_factory.cpp +++ b/src/algo_factory/algo_factory.cpp @@ -15,6 +15,7 @@ #include <botan/stream_cipher.h> #include <botan/hash.h> #include <botan/mac.h> +#include <botan/pbkdf.h> #include <algorithm> @@ -55,6 +56,12 @@ MessageAuthenticationCode* engine_get_algo(Engine* engine, Algorithm_Factory& af) { return engine->find_mac(request, af); } +template<> +PBKDF* engine_get_algo(Engine* engine, + const SCAN_Name& request, + Algorithm_Factory& af) + { return engine->find_pbkdf(request, af); } + template<typename T> const T* factory_prototype(const std::string& algo_spec, const std::string& provider, @@ -93,6 +100,7 @@ Algorithm_Factory::Algorithm_Factory() stream_cipher_cache = new Algorithm_Cache<StreamCipher>(); hash_cache = new Algorithm_Cache<HashFunction>(); mac_cache = new Algorithm_Cache<MessageAuthenticationCode>(); + pbkdf_cache = new Algorithm_Cache<PBKDF>(); } /* @@ -104,6 +112,7 @@ Algorithm_Factory::~Algorithm_Factory() delete stream_cipher_cache; delete hash_cache; delete mac_cache; + delete pbkdf_cache; for(auto i = engines.begin(); i != engines.end(); ++i) delete *i; @@ -115,6 +124,7 @@ void Algorithm_Factory::clear_caches() stream_cipher_cache->clear_cache(); hash_cache->clear_cache(); mac_cache->clear_cache(); + pbkdf_cache->clear_cache(); } void Algorithm_Factory::add_engine(Engine* engine) @@ -137,6 +147,8 @@ void Algorithm_Factory::set_preferred_provider(const std::string& algo_spec, hash_cache->set_preferred_provider(algo_spec, provider); else if(prototype_mac(algo_spec)) mac_cache->set_preferred_provider(algo_spec, provider); + else if(prototype_pbkdf(algo_spec)) + pbkdf_cache->set_preferred_provider(algo_spec, provider); } /* @@ -169,6 +181,8 @@ Algorithm_Factory::providers_of(const std::string& algo_spec) return hash_cache->providers_of(algo_spec); else if(prototype_mac(algo_spec)) return mac_cache->providers_of(algo_spec); + else if(prototype_pbkdf(algo_spec)) + return pbkdf_cache->providers_of(algo_spec); else return std::vector<std::string>(); } @@ -219,6 +233,18 @@ Algorithm_Factory::prototype_mac(const std::string& algo_spec, } /* +* Return the prototypical object corresponding to this request +*/ +const PBKDF* +Algorithm_Factory::prototype_pbkdf(const std::string& algo_spec, + const std::string& provider) + { + return factory_prototype<PBKDF>(algo_spec, provider, + engines, + *this, pbkdf_cache); + } + +/* * Return a new block cipher corresponding to this request */ BlockCipher* @@ -267,6 +293,18 @@ Algorithm_Factory::make_mac(const std::string& algo_spec, } /* +* Return a new object corresponding to this request +*/ +PBKDF* +Algorithm_Factory::make_pbkdf(const std::string& algo_spec, + const std::string& provider) + { + if(const PBKDF* proto = prototype_pbkdf(algo_spec, provider)) + return proto->clone(); + throw Algorithm_Not_Found(algo_spec); + } + +/* * Add a new block cipher */ void Algorithm_Factory::add_block_cipher(BlockCipher* block_cipher, @@ -302,4 +340,13 @@ void Algorithm_Factory::add_mac(MessageAuthenticationCode* mac, mac_cache->add(mac, mac->name(), provider); } +/* +* Add a new PBKDF +*/ +void Algorithm_Factory::add_pbkdf(PBKDF* pbkdf, + const std::string& provider) + { + pbkdf_cache->add(pbkdf, pbkdf->name(), provider); + } + } diff --git a/src/algo_factory/algo_factory.h b/src/algo_factory/algo_factory.h index e8714bd6c..1bec2adf7 100644 --- a/src/algo_factory/algo_factory.h +++ b/src/algo_factory/algo_factory.h @@ -21,6 +21,7 @@ class BlockCipher; class StreamCipher; class HashFunction; class MessageAuthenticationCode; +class PBKDF; template<typename T> class Algorithm_Cache; @@ -160,8 +161,30 @@ class BOTAN_DLL Algorithm_Factory const std::string& provider); /** + * @param algo_spec the algorithm we want + * @param provider the provider we would like to use + * @returns pointer to const prototype object, ready to clone(), or NULL + */ + const PBKDF* prototype_pbkdf(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * @param algo_spec the algorithm we want + * @param provider the provider we would like to use + * @returns pointer to freshly created instance of the request algorithm + */ + PBKDF* make_pbkdf(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * @param algo the algorithm to add + * @param provider the provider of this algorithm + */ + void add_pbkdf(PBKDF* algo, const std::string& provider); + + /** * An iterator for the engines in this factory - * @deprecated + * @deprecated Avoid in new code */ class BOTAN_DLL Engine_Iterator { @@ -174,7 +197,8 @@ class BOTAN_DLL Algorithm_Factory /** * @param a an algorithm factory */ - Engine_Iterator(const Algorithm_Factory& a) : af(a) { n = 0; } + Engine_Iterator(const Algorithm_Factory& a) : + af(a) { n = 0; } private: const Algorithm_Factory& af; size_t n; @@ -194,6 +218,7 @@ class BOTAN_DLL Algorithm_Factory Algorithm_Cache<StreamCipher>* stream_cipher_cache; Algorithm_Cache<HashFunction>* hash_cache; Algorithm_Cache<MessageAuthenticationCode>* mac_cache; + Algorithm_Cache<PBKDF>* pbkdf_cache; }; } diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h index cbc4354ad..b06be0d55 100644 --- a/src/alloc/secmem.h +++ b/src/alloc/secmem.h @@ -110,7 +110,10 @@ class MemoryRegion MemoryRegion<T>& operator=(const MemoryRegion<T>& other) { if(this != &other) - set(&other[0], other.size()); + { + this->resize(other.size()); + this->copy(&other[0], other.size()); + } return (*this); } @@ -141,14 +144,6 @@ class MemoryRegion } /** - * Set the contents of this according to the argument. The size of - * this is increased if necessary. - * @param in the array of objects of type T to copy the contents from - * @param n the size of array in - */ - void set(const T in[], size_t n) { resize(n); copy(in, n); } - - /** * Append a single element. * @param x the element to append */ @@ -189,7 +184,8 @@ class MemoryRegion buf = 0; used = allocated = 0; alloc = other.alloc; - set(other.buf, other.used); + resize(other.size()); + copy(&other[0], other.size()); } /** @@ -285,7 +281,10 @@ class MemoryVector : public MemoryRegion<T> MemoryVector<T>& operator=(const MemoryRegion<T>& in) { if(this != &in) - this->set(&in[0], in.size()); + { + this->resize(in.size()); + this->copy(&in[0], in.size()); + } return (*this); } @@ -302,13 +301,21 @@ class MemoryVector : public MemoryRegion<T> * @param n the size of the arry in */ MemoryVector(const T in[], size_t n) - { this->init(false); this->set(in, n); } + { + this->init(false); + this->resize(n); + this->copy(in, n); + } /** * Copy constructor. */ MemoryVector(const MemoryRegion<T>& in) - { this->init(false); this->set(&in[0], in.size()); } + { + this->init(false); + this->resize(in.size()); + this->copy(&in[0], in.size()); + } }; /** @@ -323,11 +330,18 @@ class SecureVector : public MemoryRegion<T> public: /** * Copy the contents of another buffer into this buffer. - * @param in the buffer to copy the contents from + * @param other the buffer to copy the contents from * @return reference to *this */ - SecureVector<T>& operator=(const MemoryRegion<T>& in) - { if(this != &in) this->set(&in[0], in.size()); return (*this); } + SecureVector<T>& operator=(const MemoryRegion<T>& other) + { + if(this != &other) + { + this->resize(other.size()); + this->copy(&other[0], other.size()); + } + return (*this); + } /** * Create a buffer of the specified length. @@ -344,7 +358,8 @@ class SecureVector : public MemoryRegion<T> SecureVector(const T in[], size_t n) { this->init(true); - this->set(&in[0], n); + this->resize(n); + this->copy(&in[0], n); } /** @@ -355,7 +370,8 @@ class SecureVector : public MemoryRegion<T> SecureVector(const MemoryRegion<T>& in) { this->init(true); - this->set(&in[0], in.size()); + this->resize(in.size()); + this->copy(&in[0], in.size()); } }; diff --git a/src/asn1/asn1_alt.cpp b/src/asn1/asn1_alt.cpp index 8a46e2f2a..3689a4bba 100644 --- a/src/asn1/asn1_alt.cpp +++ b/src/asn1/asn1_alt.cpp @@ -17,6 +17,24 @@ namespace Botan { +namespace { + +/* +* Check if type is a known ASN.1 string type +*/ +bool is_string_type(ASN1_Tag tag) + { + return (tag == NUMERIC_STRING || + tag == PRINTABLE_STRING || + tag == VISIBLE_STRING || + tag == T61_STRING || + tag == IA5_STRING || + tag == UTF8_STRING || + tag == BMP_STRING); + } + +} + /* * Create an AlternativeName */ diff --git a/src/asn1/asn1_obj.h b/src/asn1/asn1_obj.h index 967aa6d3d..3cd8422e6 100644 --- a/src/asn1/asn1_obj.h +++ b/src/asn1/asn1_obj.h @@ -99,11 +99,6 @@ bool BOTAN_DLL operator>=(const X509_Time&, const X509_Time&); bool BOTAN_DLL operator<(const X509_Time&, const X509_Time&); bool BOTAN_DLL operator>(const X509_Time&, const X509_Time&); -/* -* Helper Functions -*/ -bool BOTAN_DLL is_string_type(ASN1_Tag); - } #endif diff --git a/src/asn1/asn1_str.cpp b/src/asn1/asn1_str.cpp index 5faf9546d..44db189f9 100644 --- a/src/asn1/asn1_str.cpp +++ b/src/asn1/asn1_str.cpp @@ -60,18 +60,6 @@ ASN1_Tag choose_encoding(const std::string& str, } /* -* Check if type is a known ASN.1 string type -*/ -bool is_string_type(ASN1_Tag tag) - { - if(tag == NUMERIC_STRING || tag == PRINTABLE_STRING || - tag == VISIBLE_STRING || tag == T61_STRING || tag == IA5_STRING || - tag == UTF8_STRING || tag == BMP_STRING) - return true; - return false; - } - -/* * Create an ASN1_String */ ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : tag(t) diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index ff81d9935..cb5d8bb41 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -21,9 +21,9 @@ namespace { typedef std::chrono::high_resolution_clock benchmark_clock; /** -* Benchmark BufferedComputation (hash or MAC) +* Benchmark Buffered_Computation (hash or MAC) */ -std::pair<u64bit, u64bit> bench_buf_comp(BufferedComputation* buf_comp, +std::pair<u64bit, u64bit> bench_buf_comp(Buffered_Computation* buf_comp, u64bit nanoseconds_max, const byte buf[], size_t buf_len) { @@ -62,7 +62,7 @@ bench_block_cipher(BlockCipher* block_cipher, std::chrono::nanoseconds max_time(nanoseconds_max); std::chrono::nanoseconds time_used(0); - block_cipher->set_key(buf, block_cipher->MAXIMUM_KEYLENGTH); + block_cipher->set_key(buf, block_cipher->maximum_keylength()); while(time_used < max_time) { @@ -90,7 +90,7 @@ bench_stream_cipher(StreamCipher* stream_cipher, { u64bit reps = 0; - stream_cipher->set_key(buf, stream_cipher->MAXIMUM_KEYLENGTH); + stream_cipher->set_key(buf, stream_cipher->maximum_keylength()); std::chrono::nanoseconds max_time(nanoseconds_max); std::chrono::nanoseconds time_used(0); @@ -129,7 +129,7 @@ bench_mac(MessageAuthenticationCode* mac, u64bit nanoseconds_max, const byte buf[], size_t buf_len) { - mac->set_key(buf, mac->MAXIMUM_KEYLENGTH); + mac->set_key(buf, mac->maximum_keylength()); return bench_buf_comp(mac, nanoseconds_max, buf, buf_len); } diff --git a/src/benchmark/info.txt b/src/benchmark/info.txt index 3a817435a..30bb679ca 100644 --- a/src/benchmark/info.txt +++ b/src/benchmark/info.txt @@ -3,7 +3,7 @@ define RUNTIME_BENCHMARKING <requires> algo_factory block -buf_comp +algo_base hash mac rng diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp index f149a0ac0..b19699dbc 100644 --- a/src/block/aes/aes.cpp +++ b/src/block/aes/aes.cpp @@ -666,8 +666,10 @@ void aes_key_schedule(const byte key[], size_t length, store_be(XEK[i], &MD[4*i]); } - EK.set(&XEK[0], length + 24); - DK.set(&XDK[0], length + 24); + EK.resize(length + 24); + DK.resize(length + 24); + copy_mem(&EK[0], &XEK[0], EK.size()); + copy_mem(&DK[0], &XDK[0], DK.size()); } } diff --git a/src/block/block_cipher.h b/src/block/block_cipher.h index b5a3c8439..8e820fc5a 100644 --- a/src/block/block_cipher.h +++ b/src/block/block_cipher.h @@ -18,19 +18,6 @@ namespace Botan { class BOTAN_DLL BlockCipher : public SymmetricAlgorithm { public: - /** - * BlockCipher constructor - * @param block_size the size of blocks this cipher processes - * @param key_min the minimum key size - * @param key_max the maximum key size - * @param key_mod the modulo restriction on the key size - */ - BlockCipher(size_t key_min, - size_t key_max = 0, - size_t key_mod = 1) : - SymmetricAlgorithm(key_min, key_max, key_mod) {} - - virtual ~BlockCipher() {} /** * @return block size of this algorithm @@ -108,11 +95,6 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm * Get a new object representing the same algorithm as *this */ virtual BlockCipher* clone() const = 0; - - /** - * Zeroize internal state - */ - virtual void clear() = 0; }; /** @@ -122,10 +104,13 @@ template<size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1> class Block_Cipher_Fixed_Params : public BlockCipher { public: - Block_Cipher_Fixed_Params() : BlockCipher(KMIN, KMAX, KMOD) {} - enum { BLOCK_SIZE = BS }; size_t block_size() const { return BS; } + + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(KMIN, KMAX, KMOD); + } }; } diff --git a/src/block/cascade/cascade.cpp b/src/block/cascade/cascade.cpp index 2701c20e7..f1b1a8f2c 100644 --- a/src/block/cascade/cascade.cpp +++ b/src/block/cascade/cascade.cpp @@ -31,10 +31,10 @@ void Cascade_Cipher::decrypt_n(const byte in[], byte out[], void Cascade_Cipher::key_schedule(const byte key[], size_t) { - const byte* key2 = key + cipher1->MAXIMUM_KEYLENGTH; + const byte* key2 = key + cipher1->maximum_keylength(); - cipher1->set_key(key , cipher1->MAXIMUM_KEYLENGTH); - cipher2->set_key(key2, cipher2->MAXIMUM_KEYLENGTH); + cipher1->set_key(key , cipher1->maximum_keylength()); + cipher2->set_key(key2, cipher2->maximum_keylength()); } void Cascade_Cipher::clear() @@ -81,7 +81,6 @@ size_t block_size_for_cascade(size_t bs, size_t bs2) } Cascade_Cipher::Cascade_Cipher(BlockCipher* c1, BlockCipher* c2) : - BlockCipher(c1->MAXIMUM_KEYLENGTH + c2->MAXIMUM_KEYLENGTH), cipher1(c1), cipher2(c2) { block = block_size_for_cascade(c1->block_size(), c2->block_size()); diff --git a/src/block/cascade/cascade.h b/src/block/cascade/cascade.h index 31ee3b336..b1376e2e0 100644 --- a/src/block/cascade/cascade.h +++ b/src/block/cascade/cascade.h @@ -23,6 +23,12 @@ class BOTAN_DLL Cascade_Cipher : public BlockCipher size_t block_size() const { return block; } + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(cipher1->maximum_keylength() + + cipher2->maximum_keylength()); + } + void clear(); std::string name() const; BlockCipher* clone() const; diff --git a/src/block/info.txt b/src/block/info.txt index b4302a6d8..c9757cadc 100644 --- a/src/block/info.txt +++ b/src/block/info.txt @@ -1,5 +1,5 @@ define BLOCK_CIPHER <requires> -sym_algo +algo_base </requires> diff --git a/src/block/lion/lion.cpp b/src/block/lion/lion.cpp index 103759e39..8c39eee65 100644 --- a/src/block/lion/lion.cpp +++ b/src/block/lion/lion.cpp @@ -109,7 +109,6 @@ void Lion::clear() * Lion Constructor */ Lion::Lion(HashFunction* hash_in, StreamCipher* sc_in, size_t block_len) : - BlockCipher(2, 2*hash_in->output_length(), 2), BLOCK_SIZE(std::max<size_t>(2*hash_in->output_length() + 1, block_len)), LEFT_SIZE(hash_in->output_length()), RIGHT_SIZE(BLOCK_SIZE - LEFT_SIZE), diff --git a/src/block/lion/lion.h b/src/block/lion/lion.h index d4eb9c327..5076f4461 100644 --- a/src/block/lion/lion.h +++ b/src/block/lion/lion.h @@ -30,6 +30,11 @@ class BOTAN_DLL Lion : public BlockCipher size_t block_size() const { return BLOCK_SIZE; } + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(2, 2*hash->output_length(), 2); + } + void clear(); std::string name() const; BlockCipher* clone() const; diff --git a/src/block/lubyrack/lubyrack.cpp b/src/block/lubyrack/lubyrack.cpp index 335570973..ef4a11e9d 100644 --- a/src/block/lubyrack/lubyrack.cpp +++ b/src/block/lubyrack/lubyrack.cpp @@ -89,8 +89,10 @@ void LubyRackoff::decrypt_n(const byte in[], byte out[], size_t blocks) const */ void LubyRackoff::key_schedule(const byte key[], size_t length) { - K1.set(key, length / 2); - K2.set(key + length / 2, length / 2); + K1.resize(length / 2); + K2.resize(length / 2); + copy_mem(&K1[0], key , length / 2); + copy_mem(&K2[0], key + length / 2, length / 2); } /* @@ -122,9 +124,7 @@ std::string LubyRackoff::name() const /* * Luby-Rackoff Constructor */ -LubyRackoff::LubyRackoff(HashFunction* h) : - BlockCipher(2, 32, 2), - hash(h) +LubyRackoff::LubyRackoff(HashFunction* h) : hash(h) { } diff --git a/src/block/lubyrack/lubyrack.h b/src/block/lubyrack/lubyrack.h index 0c267683a..81dddf579 100644 --- a/src/block/lubyrack/lubyrack.h +++ b/src/block/lubyrack/lubyrack.h @@ -24,6 +24,11 @@ class BOTAN_DLL LubyRackoff : public BlockCipher size_t block_size() const { return 2 * hash->output_length(); } + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(2, 32, 2); + } + void clear(); std::string name() const; BlockCipher* clone() const; diff --git a/src/block/serpent/serpent.h b/src/block/serpent/serpent.h index 33bd747cd..df3f039aa 100644 --- a/src/block/serpent/serpent.h +++ b/src/block/serpent/serpent.h @@ -39,7 +39,9 @@ class BOTAN_DLL Serpent : public Block_Cipher_Fixed_Params<16, 16, 32, 8> * @param ks is the new key schedule value to set */ void set_round_keys(const u32bit ks[132]) - { round_key.set(ks, 132); } + { + copy_mem(&round_key[0], ks, 132); + } private: void key_schedule(const byte key[], size_t length); diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index 03f8b8f2e..fb5e5fabc 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -2,7 +2,15 @@ #ifndef BOTAN_BUILD_CONFIG_H__ #define BOTAN_BUILD_CONFIG_H__ -/* This file was automatically generated %{timestamp} UTC */ +/* +* This file was automatically generated %{timestamp} UTC by +* %{user}@%{hostname} running '%{command_line}' +* +* Target +* - Compiler: %{cc} %{lib_opt} %{mach_opt} +* - Arch: %{submodel}/%{arch} +* - OS: %{os} +*/ #define BOTAN_VERSION_MAJOR %{version_major} #define BOTAN_VERSION_MINOR %{version_minor} @@ -57,30 +65,47 @@ %{target_compiler_defines} -#if defined(BOTAN_BUILD_COMPILER_IS_MSVC) +#if defined(_MSC_VER) // 4250: inherits via dominance (diamond inheritence issue) // 4251: needs DLL interface (STL DLL exports) #pragma warning(disable: 4250 4251) #endif -/* Module definitions */ -%{module_defines} +/* +* Compile-time deprecatation warnings +*/ +#if !defined(BOTAN_NO_DEPRECATED_WARNINGS) -/* Local configuration options */ -%{local_config} + #if defined(__clang__) + #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated)) -/* -%{user}@%{hostname} ran '%{command_line}' + #elif defined(_MSC_VER) + #define BOTAN_DEPRECATED(msg) __declspec(deprecated(msg)) + + #elif defined(__GNUG__) -Target -------- -Compiler: %{cc} %{lib_opt} %{mach_opt} -Arch: %{submodel}/%{arch} -OS: %{os} + #if BOTAN_GCC_VERSION >= 450 + #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg))) + #else + #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated)) + #endif -Modules -------- -%{mod_list} + #endif + +#endif + +#if !defined(BOTAN_DEPRECATED) + #define BOTAN_DEPRECATED(msg) +#endif + +/* +* Module availability definitions */ +%{module_defines} + +/* +* Local configuration options (if any) follow +*/ +%{local_config} #endif diff --git a/src/build-data/cc/bcc.txt b/src/build-data/cc/bcc.txt new file mode 100644 index 000000000..93306dde1 --- /dev/null +++ b/src/build-data/cc/bcc.txt @@ -0,0 +1,26 @@ +macro_name BORLAND + +binary_name bcc32 + +compile_option "-c " +output_to_option "-o" +add_include_dir_option -I +add_lib_dir_option -L +add_lib_option "" + +no_debug_flags "-O2" +debug_flags "" +check_opt_flags "-O2" +lang_flags "" +warning_flags "" + +shared_flags "" +dll_import_flags "" + +ar_command lib + +makefile_style nmake + +<mach_abi_linking> +all -> "-tM" +</mach_abi_linking> diff --git a/src/cert/certstore/certstor.h b/src/cert/certstore/certstor.h index aaa46bd4e..374013984 100644 --- a/src/cert/certstore/certstor.h +++ b/src/cert/certstore/certstor.h @@ -50,6 +50,9 @@ class BOTAN_DLL Certificate_Store const MemoryRegion<byte>& key_id) const = 0; }; +/** +* In Memory Certificate Store +*/ class BOTAN_DLL Certificate_Store_Memory : public Certificate_Store { public: diff --git a/src/cert/pkcs10/pkcs10.cpp b/src/cert/pkcs10/pkcs10.cpp index 423c9aaf1..202fd659c 100644 --- a/src/cert/pkcs10/pkcs10.cpp +++ b/src/cert/pkcs10/pkcs10.cpp @@ -175,8 +175,8 @@ std::vector<OID> PKCS10_Request::ex_constraints() const std::vector<std::string> oids = info.get("X509v3.ExtendedKeyUsage"); std::vector<OID> result; - for(u32bit j = 0; j != oids.size(); ++j) - result.push_back(OID(oids[j])); + for(size_t i = 0; i != oids.size(); ++i) + result.push_back(OID(oids[i])); return result; } diff --git a/src/cert/x509cert/x509_obj.h b/src/cert/x509cert/x509_obj.h index 6579565f9..570b00f51 100644 --- a/src/cert/x509cert/x509_obj.h +++ b/src/cert/x509cert/x509_obj.h @@ -88,6 +88,7 @@ class BOTAN_DLL X509_Object * @param out the pipe to write to * @param encoding the encoding to use */ + BOTAN_DEPRECATED("Use BER_encode or PEM_encode") void encode(Pipe& out, X509_Encoding encoding = PEM) const; virtual ~X509_Object() {} diff --git a/src/checksum/adler32/adler32.h b/src/checksum/adler32/adler32.h index 3a2441ad3..dc2872ca1 100644 --- a/src/checksum/adler32/adler32.h +++ b/src/checksum/adler32/adler32.h @@ -18,10 +18,13 @@ namespace Botan { class BOTAN_DLL Adler32 : public HashFunction { public: - void clear() { S1 = 1; S2 = 0; } std::string name() const { return "Adler32"; } + size_t output_length() const { return 4; } HashFunction* clone() const { return new Adler32; } - Adler32() : HashFunction(4) { clear(); } + + void clear() { S1 = 1; S2 = 0; } + + Adler32() { clear(); } ~Adler32() { clear(); } private: void add_data(const byte[], size_t); diff --git a/src/checksum/crc24/crc24.h b/src/checksum/crc24/crc24.h index f9786dfa4..b5faebcee 100644 --- a/src/checksum/crc24/crc24.h +++ b/src/checksum/crc24/crc24.h @@ -18,10 +18,13 @@ namespace Botan { class BOTAN_DLL CRC24 : public HashFunction { public: - void clear() { crc = 0xB704CE; } std::string name() const { return "CRC24"; } + size_t output_length() const { return 3; } HashFunction* clone() const { return new CRC24; } - CRC24() : HashFunction(3) { clear(); } + + void clear() { crc = 0xB704CE; } + + CRC24() { clear(); } ~CRC24() { clear(); } private: void add_data(const byte[], size_t); diff --git a/src/checksum/crc32/crc32.h b/src/checksum/crc32/crc32.h index aa8c366e5..dec3d0449 100644 --- a/src/checksum/crc32/crc32.h +++ b/src/checksum/crc32/crc32.h @@ -18,10 +18,13 @@ namespace Botan { class BOTAN_DLL CRC32 : public HashFunction { public: - void clear() { crc = 0xFFFFFFFF; } std::string name() const { return "CRC32"; } + size_t output_length() const { return 4; } HashFunction* clone() const { return new CRC32; } - CRC32() : HashFunction(4) { clear(); } + + void clear() { crc = 0xFFFFFFFF; } + + CRC32() { clear(); } ~CRC32() { clear(); } private: void add_data(const byte[], size_t); diff --git a/src/cms/cms_algo.cpp b/src/cms/cms_algo.cpp index 33652a6b6..a02f7e737 100644 --- a/src/cms/cms_algo.cpp +++ b/src/cms/cms_algo.cpp @@ -39,7 +39,7 @@ SecureVector<byte> do_rfc3217_wrap(RandomNumberGenerator& rng, } void end_msg() { - for(u32bit j = 0; j != buf.size(); j++) + for(size_t j = 0; j != buf.size(); j++) send(buf[buf.size()-j-1]); buf.clear(); } @@ -149,7 +149,7 @@ SecureVector<byte> CMS_Encoder::encode_params(const std::string& cipher, SymmetricKey CMS_Encoder::setup_key(RandomNumberGenerator& rng, const std::string& cipher) { - u32bit keysize = 0; + size_t keysize = 0; if(cipher == "TripleDES") keysize = 24; if(cipher == "RC2") keysize = 16; diff --git a/src/cms/cms_ealg.cpp b/src/cms/cms_ealg.cpp index 85e2d1370..57b44b80e 100644 --- a/src/cms/cms_ealg.cpp +++ b/src/cms/cms_ealg.cpp @@ -316,7 +316,7 @@ void CMS_Encoder::sign(const X509_Certificate& cert, .raw_bytes(make_econtent(data, type)); encoder.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC); - for(u32bit j = 0; j != chain.size(); j++) + for(size_t j = 0; j != chain.size(); j++) encoder.raw_bytes(chain[j].BER_encode()); encoder.raw_bytes(cert.BER_encode()).end_cons(); diff --git a/src/cms/cms_enc.cpp b/src/cms/cms_enc.cpp index 3437c15e3..cd739ef08 100644 --- a/src/cms/cms_enc.cpp +++ b/src/cms/cms_enc.cpp @@ -15,12 +15,13 @@ namespace Botan { /* * Setup the intitial layer of CMS data */ -void CMS_Encoder::set_data(const byte buf[], u32bit length) +void CMS_Encoder::set_data(const byte buf[], size_t length) { if(!data.empty()) throw Invalid_State("Cannot call CMS_Encoder::set_data here"); - data.set(buf, length); + data.resize(length); + copy_mem(&data[0], buf, length); type = "CMS.DataContent"; } diff --git a/src/cms/cms_enc.h b/src/cms/cms_enc.h index f8e9a5a8f..5dca838dd 100644 --- a/src/cms/cms_enc.h +++ b/src/cms/cms_enc.h @@ -51,10 +51,10 @@ class BOTAN_DLL CMS_Encoder std::string PEM_contents(); void set_data(const std::string&); - void set_data(const byte[], u32bit); + void set_data(const byte[], size_t); CMS_Encoder(const std::string& str) { set_data(str); } - CMS_Encoder(const byte buf[], u32bit length) { set_data(buf, length); } + CMS_Encoder(const byte buf[], size_t length) { set_data(buf, length); } private: void add_layer(const std::string&, DER_Encoder&); diff --git a/src/cms/info.txt b/src/cms/info.txt index 708f1d592..dc2110ae5 100644 --- a/src/cms/info.txt +++ b/src/cms/info.txt @@ -11,6 +11,6 @@ oid_lookup pem pubkey sha1 -sym_algo +algo_base x509cert </requires> diff --git a/src/codec/base64/base64.h b/src/codec/base64/base64.h index 551f3daf8..6daac73d8 100644 --- a/src/codec/base64/base64.h +++ b/src/codec/base64/base64.h @@ -36,7 +36,6 @@ size_t BOTAN_DLL base64_encode(char output[], * Perform base64 encoding * @param input some input * @param input_length length of input in bytes -* @param uppercase should output be upper or lower case? * @return base64adecimal representation of input */ std::string BOTAN_DLL base64_encode(const byte input[], @@ -45,7 +44,6 @@ std::string BOTAN_DLL base64_encode(const byte input[], /** * Perform base64 encoding * @param input some input -* @param uppercase should output be upper or lower case? * @return base64adecimal representation of input */ std::string BOTAN_DLL base64_encode(const MemoryRegion<byte>& input); diff --git a/src/engine/core_engine/core_engine.h b/src/engine/core_engine/core_engine.h index b8b8262ce..5386991c3 100644 --- a/src/engine/core_engine/core_engine.h +++ b/src/engine/core_engine/core_engine.h @@ -49,6 +49,9 @@ class Core_Engine : public Engine MessageAuthenticationCode* find_mac(const SCAN_Name& reqeust, Algorithm_Factory&) const; + + PBKDF* find_pbkdf(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const; }; /** diff --git a/src/engine/core_engine/info.txt b/src/engine/core_engine/info.txt index ea059b3c6..1935b0518 100644 --- a/src/engine/core_engine/info.txt +++ b/src/engine/core_engine/info.txt @@ -12,6 +12,7 @@ lookup_block.cpp lookup_hash.cpp lookup_mac.cpp lookup_stream.cpp +lookup_pbkdf.cpp </source> <requires> diff --git a/src/engine/core_engine/lookup_pbkdf.cpp b/src/engine/core_engine/lookup_pbkdf.cpp new file mode 100644 index 000000000..9e9255f0a --- /dev/null +++ b/src/engine/core_engine/lookup_pbkdf.cpp @@ -0,0 +1,52 @@ +/* +* PBKDF Lookup +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/core_engine.h> +#include <botan/scan_name.h> +#include <botan/algo_factory.h> + +#if defined(BOTAN_HAS_PBKDF1) + #include <botan/pbkdf1.h> +#endif + +#if defined(BOTAN_HAS_PBKDF2) + #include <botan/pbkdf2.h> +#endif + +#if defined(BOTAN_HAS_PGPS2K) + #include <botan/pgp_s2k.h> +#endif + +namespace Botan { + +PBKDF* Core_Engine::find_pbkdf(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const + { +#if defined(BOTAN_HAS_PBKDF1) + if(algo_spec.algo_name() == "PBKDF1" && algo_spec.arg_count() == 1) + return new PKCS5_PBKDF1(af.make_hash_function(algo_spec.arg(0))); +#endif + +#if defined(BOTAN_HAS_PBKDF2) + if(algo_spec.algo_name() == "PBKDF2" && algo_spec.arg_count() == 1) + { + if(const MessageAuthenticationCode* mac_proto = af.prototype_mac(algo_spec.arg(0))) + return new PKCS5_PBKDF2(mac_proto->clone()); + + return new PKCS5_PBKDF2(af.make_mac("HMAC(" + algo_spec.arg(0) + ")")); + } +#endif + +#if defined(BOTAN_HAS_PGPS2K) + if(algo_spec.algo_name() == "OpenPGP-S2K" && algo_spec.arg_count() == 1) + return new OpenPGP_S2K(af.make_hash_function(algo_spec.arg(0))); +#endif + + return 0; + } + +} diff --git a/src/engine/dyn_engine/dyn_engine.cpp b/src/engine/dyn_engine/dyn_engine.cpp index f48f1a06d..2d8dbae3b 100644 --- a/src/engine/dyn_engine/dyn_engine.cpp +++ b/src/engine/dyn_engine/dyn_engine.cpp @@ -32,7 +32,7 @@ Dynamically_Loaded_Engine::Dynamically_Loaded_Engine( const u32bit mod_version = get_version(); - if(mod_version != 20100908) + if(mod_version != 20101003) throw std::runtime_error("Incompatible version in " + library_path + " of " + std::to_string(mod_version)); diff --git a/src/engine/dyn_engine/dyn_engine.h b/src/engine/dyn_engine/dyn_engine.h index 46752f5a9..d8e92cb02 100644 --- a/src/engine/dyn_engine/dyn_engine.h +++ b/src/engine/dyn_engine/dyn_engine.h @@ -49,6 +49,12 @@ class BOTAN_DLL Dynamically_Loaded_Engine : public Engine return engine->find_mac(algo_spec, af); } + PBKDF* find_pbkdf(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const + { + return engine->find_pbkdf(algo_spec, af); + } + Modular_Exponentiator* mod_exp(const BigInt& n, Power_Mod::Usage_Hints hints) const { diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 958d4148f..80712a2f8 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -37,6 +37,13 @@ Engine::find_mac(const SCAN_Name&, return 0; } +PBKDF* +Engine::find_pbkdf(const SCAN_Name&, + Algorithm_Factory&) const + { + return 0; + } + Modular_Exponentiator* Engine::mod_exp(const BigInt&, Power_Mod::Usage_Hints) const diff --git a/src/engine/engine.h b/src/engine/engine.h index c9bcd6126..136fbeb23 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -9,18 +9,15 @@ #define BOTAN_ENGINE_H__ #include <botan/scan_name.h> - #include <botan/block_cipher.h> #include <botan/stream_cipher.h> #include <botan/hash.h> #include <botan/mac.h> +#include <botan/pbkdf.h> #include <botan/pow_mod.h> #include <botan/pk_keys.h> #include <botan/pk_ops.h> -#include <utility> -#include <map> - namespace Botan { class Algorithm_Factory; @@ -79,6 +76,14 @@ class BOTAN_DLL Engine Algorithm_Factory& af) const; /** + * @param algo_spec the algorithm name/specification + * @param af an algorithm factory object + * @return newly allocated object, or NULL + */ + virtual PBKDF* find_pbkdf(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const; + + /** * @param n the modulus * @param hints any use hints * @return newly allocated object, or NULL diff --git a/src/engine/info.txt b/src/engine/info.txt index 5f787cebe..0c73450bc 100644 --- a/src/engine/info.txt +++ b/src/engine/info.txt @@ -14,6 +14,7 @@ hash libstate mac numbertheory +pbkdf pubkey stream </requires> diff --git a/src/entropy/cryptoapi_rng/es_capi.cpp b/src/entropy/cryptoapi_rng/es_capi.cpp index 1de76dabb..420977a9b 100644 --- a/src/entropy/cryptoapi_rng/es_capi.cpp +++ b/src/entropy/cryptoapi_rng/es_capi.cpp @@ -50,7 +50,7 @@ class CSP_Handle } -/** +/* * Gather Entropy from Win32 CAPI */ void Win32_CAPI_EntropySource::poll(Entropy_Accumulator& accum) @@ -71,7 +71,7 @@ void Win32_CAPI_EntropySource::poll(Entropy_Accumulator& accum) } } -/** +/* * Win32_Capi_Entropysource Constructor */ Win32_CAPI_EntropySource::Win32_CAPI_EntropySource(const std::string& provs) diff --git a/src/entropy/cryptoapi_rng/es_capi.h b/src/entropy/cryptoapi_rng/es_capi.h index f55713e92..d75101923 100644 --- a/src/entropy/cryptoapi_rng/es_capi.h +++ b/src/entropy/cryptoapi_rng/es_capi.h @@ -23,7 +23,11 @@ class Win32_CAPI_EntropySource : public EntropySource void poll(Entropy_Accumulator& accum); - Win32_CAPI_EntropySource(const std::string& = ""); + /** + * Win32_Capi_Entropysource Constructor + * @param provs list of providers, separated by ':' + */ + Win32_CAPI_EntropySource(const std::string& provs = ""); private: std::vector<u64bit> prov_types; }; diff --git a/src/entropy/entropy_src.h b/src/entropy/entropy_src.h index 97ebe8bd9..d713598d9 100644 --- a/src/entropy/entropy_src.h +++ b/src/entropy/entropy_src.h @@ -94,16 +94,17 @@ class BOTAN_DLL Entropy_Accumulator }; /** -* Entropy accumulator that puts the input into a BufferedComputation +* Entropy accumulator that puts the input into a Buffered_Computation */ -class BOTAN_DLL Entropy_Accumulator_BufferedComputation : public Entropy_Accumulator +class BOTAN_DLL Entropy_Accumulator_BufferedComputation : + public Entropy_Accumulator { public: /** * @param sink the hash or MAC we are feeding the poll data into * @param goal is how many bits we want to collect in this poll */ - Entropy_Accumulator_BufferedComputation(BufferedComputation& sink, + Entropy_Accumulator_BufferedComputation(Buffered_Computation& sink, size_t goal) : Entropy_Accumulator(goal), entropy_sink(sink) {} @@ -113,7 +114,7 @@ class BOTAN_DLL Entropy_Accumulator_BufferedComputation : public Entropy_Accumul entropy_sink.update(bytes, length); } - BufferedComputation& entropy_sink; + Buffered_Computation& entropy_sink; }; /** diff --git a/src/entropy/info.txt b/src/entropy/info.txt index a048df7d9..d991577f7 100644 --- a/src/entropy/info.txt +++ b/src/entropy/info.txt @@ -1,3 +1,3 @@ <requires> -buf_comp +algo_base </requires> diff --git a/src/filters/buf_filt.h b/src/filters/buf_filt.h index 0f8443453..87180e3e1 100644 --- a/src/filters/buf_filt.h +++ b/src/filters/buf_filt.h @@ -19,14 +19,46 @@ namespace Botan { class BOTAN_DLL Buffered_Filter { public: - void write(const byte[], size_t); + /** + * Write bytes into the buffered filter, which will them emit them + * in calls to buffered_block in the subclass + * @param in the input bytes + * @param length of in in bytes + */ + void write(const byte in[], size_t length); + + /** + * Finish a message, emitting to buffered_block and buffered_final + * Will throw an exception if less than final_minimum bytes were + * written into the filter. + */ void end_msg(); + /** + * Initialize a Buffered_Filter + * @param block_size the function buffered_block will be called + * with inputs which are a multiple of this size + * @param final_minimum the function buffered_final will be called + * with at least this many bytes. + */ Buffered_Filter(size_t block_size, size_t final_minimum); virtual ~Buffered_Filter() {} protected: + /** + * The block processor, implemented by subclasses + * @param input some input bytes + * @param length the size of input, guaranteed to be a multiple + * of block_size + */ virtual void buffered_block(const byte input[], size_t length) = 0; + + /** + * The final block, implemented by subclasses + * @param input some input bytes + * @param length the size of input, guaranteed to be at least + * final_minimum bytes + */ virtual void buffered_final(const byte input[], size_t length) = 0; /** diff --git a/src/filters/codec_filt/b64_filt.h b/src/filters/codec_filt/b64_filt.h index e7cbfae1d..df3896666 100644 --- a/src/filters/codec_filt/b64_filt.h +++ b/src/filters/codec_filt/b64_filt.h @@ -67,19 +67,19 @@ class BOTAN_DLL Base64_Decoder : public Filter void write(const byte input[], size_t length); /** - * Inform the Encoder that the current message shall be closed. + * Finish up the current message */ void end_msg(); /** - * Create a base64 encoder. + * Create a base64 decoder. * @param checking the type of checking that shall be performed by * the decoder */ Base64_Decoder(Decoder_Checking checking = NONE); private: static void decode(const byte input[4], byte output[3]); - static bool is_valid(byte); + static bool is_valid(byte c); void decode_and_send(const byte[], size_t); void handle_bad_char(byte); diff --git a/src/filters/data_src.cpp b/src/filters/data_src.cpp index 9c9e19c23..da67baa98 100644 --- a/src/filters/data_src.cpp +++ b/src/filters/data_src.cpp @@ -77,27 +77,27 @@ bool DataSource_Memory::end_of_data() const /* * DataSource_Memory Constructor */ -DataSource_Memory::DataSource_Memory(const byte in[], size_t length) +DataSource_Memory::DataSource_Memory(const byte in[], size_t length) : + source(in, length) { - source.set(in, length); offset = 0; } /* * DataSource_Memory Constructor */ -DataSource_Memory::DataSource_Memory(const MemoryRegion<byte>& in) +DataSource_Memory::DataSource_Memory(const MemoryRegion<byte>& in) : + source(in) { - source = in; offset = 0; } /* * DataSource_Memory Constructor */ -DataSource_Memory::DataSource_Memory(const std::string& in) +DataSource_Memory::DataSource_Memory(const std::string& in) : + source(reinterpret_cast<const byte*>(in.data()), in.length()) { - source.set(reinterpret_cast<const byte*>(in.data()), in.length()); offset = 0; } diff --git a/src/filters/fd_unix/fd_unix.h b/src/filters/fd_unix/fd_unix.h index 0ff220e50..8335aed9e 100644 --- a/src/filters/fd_unix/fd_unix.h +++ b/src/filters/fd_unix/fd_unix.h @@ -12,11 +12,21 @@ namespace Botan { -/* -* Unix I/O Operators for Pipe +/** +* Stream output operator; dumps the results from pipe's default +* message to the output stream. +* @param out file descriptor for an open output stream +* @param pipe the pipe +*/ +int BOTAN_DLL operator<<(int out, Pipe& pipe); + +/** +* File descriptor input operator; dumps the remaining bytes of input +* to the (assumed open) pipe message. +* @param in file descriptor for an open input stream +* @param pipe the pipe */ -int BOTAN_DLL operator<<(int, Pipe&); -int BOTAN_DLL operator>>(int, Pipe&); +int BOTAN_DLL operator>>(int in, Pipe& pipe); } diff --git a/src/filters/filter.h b/src/filters/filter.h index c7003b92c..b62846075 100644 --- a/src/filters/filter.h +++ b/src/filters/filter.h @@ -69,6 +69,7 @@ class BOTAN_DLL Filter /** * @param in some input for the filter + * @param length the number of bytes of in to send */ void send(const MemoryRegion<byte>& in, size_t length) { diff --git a/src/filters/info.txt b/src/filters/info.txt index 95d411c76..51c75017d 100644 --- a/src/filters/info.txt +++ b/src/filters/info.txt @@ -40,5 +40,5 @@ libstate mac rng stream -sym_algo +algo_base </requires> diff --git a/src/filters/modes/cbc/cbc.cpp b/src/filters/modes/cbc/cbc.cpp index cb7f94fc7..b464d075f 100644 --- a/src/filters/modes/cbc/cbc.cpp +++ b/src/filters/modes/cbc/cbc.cpp @@ -177,7 +177,9 @@ void CBC_Decryption::buffered_block(const byte input[], size_t length) input + (i-1) * cipher->block_size(), cipher->block_size()); - state.set(input + (to_proc - 1) * cipher->block_size(), cipher->block_size()); + copy_mem(&state[0], + input + (to_proc - 1) * cipher->block_size(), + cipher->block_size()); send(temp, to_proc * cipher->block_size()); @@ -204,7 +206,7 @@ void CBC_Decryption::buffered_final(const byte input[], size_t length) xor_buf(temp, state, cipher->block_size()); send(temp, padder->unpad(temp, cipher->block_size())); - state.set(input, state.size()); + copy_mem(&state[0], input, state.size()); // save for IV chaining } /* diff --git a/src/filters/modes/eax/eax.h b/src/filters/modes/eax/eax.h index c3dd213a2..e8efb9398 100644 --- a/src/filters/modes/eax/eax.h +++ b/src/filters/modes/eax/eax.h @@ -53,13 +53,44 @@ class BOTAN_DLL EAX_Base : public Keyed_Filter EAX_Base(BlockCipher* cipher, size_t tag_size); void start_msg(); - const size_t BLOCK_SIZE, TAG_SIZE; + /** + * The block size of the underlying cipher + */ + const size_t BLOCK_SIZE; + + /** + * The requested tag name + */ + const size_t TAG_SIZE; + + /** + * The name of the cipher + */ std::string cipher_name; + /** + * The stream cipher (CTR mode) + */ StreamCipher* ctr; + + /** + * The MAC (CMAC) + */ MessageAuthenticationCode* cmac; - SecureVector<byte> nonce_mac, header_mac; + /** + * The MAC of the nonce + */ + SecureVector<byte> nonce_mac; + + /** + * The MAC of the header + */ + SecureVector<byte> header_mac; + + /** + * A buffer for CTR mode encryption + */ SecureVector<byte> ctr_buf; }; diff --git a/src/filters/pipe.h b/src/filters/pipe.h index 61522c8de..6df518d3e 100644 --- a/src/filters/pipe.h +++ b/src/filters/pipe.h @@ -26,7 +26,7 @@ namespace Botan { class BOTAN_DLL Pipe : public DataSource { public: - /* + /** * An opaque type that identifies a message in this Pipe */ typedef size_t message_id; @@ -288,11 +288,21 @@ class BOTAN_DLL Pipe : public DataSource bool inside_msg; }; -/* -* I/O Operators for Pipe +/** +* Stream output operator; dumps the results from pipe's default +* message to the output stream. +* @param out an output stream +* @param pipe the pipe +*/ +BOTAN_DLL std::ostream& operator<<(std::ostream& out, Pipe& pipe); + +/** +* Stream input operator; dumps the remaining bytes of input +* to the (assumed open) pipe message. +* @param in the input stream +* @param pipe the pipe */ -BOTAN_DLL std::ostream& operator<<(std::ostream&, Pipe&); -BOTAN_DLL std::istream& operator>>(std::istream&, Pipe&); +BOTAN_DLL std::istream& operator>>(std::istream& in, Pipe& pipe); } diff --git a/src/filters/pk_filts/pk_filts.cpp b/src/filters/pk_filts/pk_filts.cpp index a0a8095d6..d843d711c 100644 --- a/src/filters/pk_filts/pk_filts.cpp +++ b/src/filters/pk_filts/pk_filts.cpp @@ -83,7 +83,8 @@ void PK_Verifier_Filter::end_msg() */ void PK_Verifier_Filter::set_signature(const byte sig[], size_t length) { - signature.set(sig, length); + signature.resize(length); + copy_mem(&signature[0], sig, length); } /* diff --git a/src/filters/secqueue.h b/src/filters/secqueue.h index 82d70ef27..632ae857d 100644 --- a/src/filters/secqueue.h +++ b/src/filters/secqueue.h @@ -27,12 +27,31 @@ class BOTAN_DLL SecureQueue : public Fanout_Filter, public DataSource size_t peek(byte[], size_t, size_t = 0) const; bool end_of_data() const; + + /** + * @return number of bytes available in the queue + */ size_t size() const; + bool attachable() { return false; } - SecureQueue& operator=(const SecureQueue&); + /** + * SecureQueue assignment + * @param other the queue to copy + */ + SecureQueue& operator=(const SecureQueue& other); + + /** + * SecureQueue default constructor (creates empty queue) + */ SecureQueue(); - SecureQueue(const SecureQueue&); + + /** + * SecureQueue copy constructor + * @param other the queue to copy + */ + SecureQueue(const SecureQueue& other); + ~SecureQueue() { destroy(); } private: void destroy(); diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw/bmw_512.h index aa527c142..474b607bb 100644 --- a/src/hash/bmw/bmw_512.h +++ b/src/hash/bmw/bmw_512.h @@ -18,11 +18,13 @@ namespace Botan { class BOTAN_DLL BMW_512 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "BMW512"; } + size_t output_length() const { return 64; } HashFunction* clone() const { return new BMW_512; } - BMW_512() : MDx_HashFunction(64, 128, false, true), H(16), M(16), Q(32) + void clear(); + + BMW_512() : MDx_HashFunction(128, false, true), H(16), M(16), Q(32) { clear(); } private: void compress_n(const byte input[], size_t blocks); diff --git a/src/hash/comb4p/comb4p.cpp b/src/hash/comb4p/comb4p.cpp index 19e23879f..1ea64a5cb 100644 --- a/src/hash/comb4p/comb4p.cpp +++ b/src/hash/comb4p/comb4p.cpp @@ -35,7 +35,6 @@ void comb4p_round(MemoryRegion<byte>& out, } Comb4P::Comb4P(HashFunction* h1, HashFunction* h2) : - HashFunction(h1->output_length() + h2->output_length()), hash1(h1), hash2(h2) { if(hash1->name() == hash2->name()) diff --git a/src/hash/comb4p/comb4p.h b/src/hash/comb4p/comb4p.h index 67547f979..73e06c379 100644 --- a/src/hash/comb4p/comb4p.h +++ b/src/hash/comb4p/comb4p.h @@ -29,6 +29,11 @@ class BOTAN_DLL Comb4P : public HashFunction size_t hash_block_size() const; + size_t output_length() const + { + return hash1->output_length() + hash2->output_length(); + } + HashFunction* clone() const { return new Comb4P(hash1->clone(), hash2->clone()); diff --git a/src/hash/gost_3411/gost_3411.cpp b/src/hash/gost_3411/gost_3411.cpp index fd47ba2c7..075f26889 100644 --- a/src/hash/gost_3411/gost_3411.cpp +++ b/src/hash/gost_3411/gost_3411.cpp @@ -16,7 +16,6 @@ namespace Botan { * GOST 34.11 Constructor */ GOST_34_11::GOST_34_11() : - HashFunction(32), cipher(GOST_28147_89_Params("R3411_CryptoPro")), buffer(32), sum(32), diff --git a/src/hash/gost_3411/gost_3411.h b/src/hash/gost_3411/gost_3411.h index 64ea0f40c..fbbcb7a89 100644 --- a/src/hash/gost_3411/gost_3411.h +++ b/src/hash/gost_3411/gost_3411.h @@ -19,11 +19,12 @@ namespace Botan { class BOTAN_DLL GOST_34_11 : public HashFunction { public: - void clear(); std::string name() const { return "GOST-R-34.11-94" ; } + size_t output_length() const { return 32; } + size_t hash_block_size() const { return 32; } HashFunction* clone() const { return new GOST_34_11; } - size_t hash_block_size() const { return 32; } + void clear(); GOST_34_11(); private: diff --git a/src/hash/has160/has160.h b/src/hash/has160/has160.h index 83ed5ab56..d32361601 100644 --- a/src/hash/has160/has160.h +++ b/src/hash/has160/has160.h @@ -19,11 +19,13 @@ namespace Botan { class BOTAN_DLL HAS_160 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "HAS-160"; } + size_t output_length() const { return 20; } HashFunction* clone() const { return new HAS_160; } - HAS_160() : MDx_HashFunction(20, 64, false, true), X(20), digest(5) + void clear(); + + HAS_160() : MDx_HashFunction(64, false, true), X(20), digest(5) { clear(); } private: void compress_n(const byte[], size_t blocks); diff --git a/src/hash/hash.h b/src/hash/hash.h index 881e23817..8143e8e90 100644 --- a/src/hash/hash.h +++ b/src/hash/hash.h @@ -9,47 +9,27 @@ #define BOTAN_HASH_FUNCTION_BASE_CLASS_H__ #include <botan/buf_comp.h> +#include <botan/algo_base.h> #include <string> namespace Botan { /** -* This class represents hash function (message digest) objects. +* This class represents hash function (message digest) objects */ -class BOTAN_DLL HashFunction : public BufferedComputation +class BOTAN_DLL HashFunction : public Buffered_Computation, + public Algorithm { public: /** - * @param hash_len the output length - * @param block_len the internal block size (if applicable) - */ - HashFunction(size_t hash_len) : BufferedComputation(hash_len) {} - - virtual ~HashFunction() {} - - /** * Get a new object representing the same algorithm as *this */ virtual HashFunction* clone() const = 0; /** - * Get the name of this algorithm. - * @return name of this algorithm - */ - virtual std::string name() const = 0; - - /** * The hash block size as defined for this algorithm */ virtual size_t hash_block_size() const { return 0; } - - /** - * Reset the internal state of this object. - */ - virtual void clear() = 0; - - private: - HashFunction& operator=(const HashFunction&); }; } diff --git a/src/hash/info.txt b/src/hash/info.txt index a048df7d9..d991577f7 100644 --- a/src/hash/info.txt +++ b/src/hash/info.txt @@ -1,3 +1,3 @@ <requires> -buf_comp +algo_base </requires> diff --git a/src/hash/md2/md2.h b/src/hash/md2/md2.h index 84f213811..84e0323f7 100644 --- a/src/hash/md2/md2.h +++ b/src/hash/md2/md2.h @@ -18,13 +18,14 @@ namespace Botan { class BOTAN_DLL MD2 : public HashFunction { public: - void clear(); std::string name() const { return "MD2"; } + size_t output_length() const { return 16; } + size_t hash_block_size() const { return 16; } HashFunction* clone() const { return new MD2; } - size_t hash_block_size() const { return 16; } + void clear(); - MD2() : HashFunction(16), X(48), checksum(16), buffer(16) + MD2() : X(48), checksum(16), buffer(16) { clear(); } private: void add_data(const byte[], size_t); diff --git a/src/hash/md4/md4.h b/src/hash/md4/md4.h index 07467fdfc..d37dbe3b2 100644 --- a/src/hash/md4/md4.h +++ b/src/hash/md4/md4.h @@ -18,17 +18,27 @@ namespace Botan { class BOTAN_DLL MD4 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "MD4"; } + size_t output_length() const { return 16; } HashFunction* clone() const { return new MD4; } - MD4() : MDx_HashFunction(16, 64, false, true), M(16), digest(4) + void clear(); + + MD4() : MDx_HashFunction(64, false, true), M(16), digest(4) { clear(); } protected: void compress_n(const byte input[], size_t blocks); void copy_out(byte[]); - SecureVector<u32bit> M, digest; + /** + * The message buffer, exposed for use by subclasses (x86 asm) + */ + SecureVector<u32bit> M; + + /** + * The digest value, exposed for use by subclasses (x86 asm) + */ + SecureVector<u32bit> digest; }; } diff --git a/src/hash/md4_ia32/md4_ia32.cpp b/src/hash/md4_ia32/md4_ia32.cpp index 1e3cd64c3..98d3c7a19 100644 --- a/src/hash/md4_ia32/md4_ia32.cpp +++ b/src/hash/md4_ia32/md4_ia32.cpp @@ -9,7 +9,15 @@ namespace Botan { -extern "C" void botan_md4_ia32_compress(u32bit[4], const byte[64], u32bit[16]); +/** +* MD4 compression function in IA-32 asm +* @param digest the current digest +* @param input the input block +* @param M the message buffer +*/ +extern "C" void botan_md4_ia32_compress(u32bit digest[4], + const byte input[64], + u32bit M[16]); /* * MD4 Compression Function diff --git a/src/hash/md5/md5.h b/src/hash/md5/md5.h index f79a3ec65..92c023c92 100644 --- a/src/hash/md5/md5.h +++ b/src/hash/md5/md5.h @@ -18,17 +18,27 @@ namespace Botan { class BOTAN_DLL MD5 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "MD5"; } + size_t output_length() const { return 16; } HashFunction* clone() const { return new MD5; } - MD5() : MDx_HashFunction(16, 64, false, true), M(16), digest(4) + void clear(); + + MD5() : MDx_HashFunction(64, false, true), M(16), digest(4) { clear(); } protected: void compress_n(const byte[], size_t blocks); void copy_out(byte[]); - SecureVector<u32bit> M, digest; + /** + * The message buffer, exposed for use by subclasses (x86 asm) + */ + SecureVector<u32bit> M; + + /** + * The digest value, exposed for use by subclasses (x86 asm) + */ + SecureVector<u32bit> digest; }; } diff --git a/src/hash/mdx_hash/mdx_hash.cpp b/src/hash/mdx_hash/mdx_hash.cpp index f82c971f8..7bfcf6592 100644 --- a/src/hash/mdx_hash/mdx_hash.cpp +++ b/src/hash/mdx_hash/mdx_hash.cpp @@ -14,19 +14,15 @@ namespace Botan { /* * MDx_HashFunction Constructor */ -MDx_HashFunction::MDx_HashFunction(size_t hash_len, - size_t block_len, +MDx_HashFunction::MDx_HashFunction(size_t block_len, bool byte_end, bool bit_end, size_t cnt_size) : - HashFunction(hash_len), buffer(block_len), BIG_BYTE_ENDIAN(byte_end), BIG_BIT_ENDIAN(bit_end), COUNT_SIZE(cnt_size) { - if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size()) - throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big"); count = position = 0; } @@ -98,6 +94,8 @@ void MDx_HashFunction::write_count(byte out[]) { if(COUNT_SIZE < 8) throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8"); + if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size()) + throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big"); const u64bit bit_count = count * 8; diff --git a/src/hash/mdx_hash/mdx_hash.h b/src/hash/mdx_hash/mdx_hash.h index d1260180e..ed3381605 100644 --- a/src/hash/mdx_hash/mdx_hash.h +++ b/src/hash/mdx_hash/mdx_hash.h @@ -19,21 +19,17 @@ class BOTAN_DLL MDx_HashFunction : public HashFunction { public: /** - * @param hash_length is the output length of this hash * @param block_length is the number of bytes per block * @param big_byte_endian specifies if the hash uses big-endian bytes * @param big_bit_endian specifies if the hash uses big-endian bits * @param counter_size specifies the size of the counter var in bytes */ - MDx_HashFunction(size_t hash_length, - size_t block_length, + MDx_HashFunction(size_t block_length, bool big_byte_endian, bool big_bit_endian, size_t counter_size = 8); size_t hash_block_size() const { return buffer.size(); } - - virtual ~MDx_HashFunction() {} protected: void add_data(const byte input[], size_t length); void final_result(byte output[]); diff --git a/src/hash/par_hash/par_hash.cpp b/src/hash/par_hash/par_hash.cpp index 17b7e6b41..6e3357660 100644 --- a/src/hash/par_hash/par_hash.cpp +++ b/src/hash/par_hash/par_hash.cpp @@ -9,23 +9,6 @@ namespace Botan { -namespace { - -/* -* Return the sum of the hash sizes -*/ -size_t sum_of_hash_lengths(const std::vector<HashFunction*>& hashes) - { - size_t sum = 0; - - for(auto hash = hashes.begin(); hash != hashes.end(); ++hash) - sum += (*hash)->OUTPUT_LENGTH; - - return sum; - } - -} - /* * Update the hash */ @@ -50,6 +33,17 @@ void Parallel::final_result(byte out[]) } /* +* Return output size +*/ +size_t Parallel::output_length() const + { + size_t sum = 0; + for(size_t i = 0; i != hashes.size(); ++i) + sum += hashes[i]->output_length(); + return sum; + } + +/* * Return the name of this type */ std::string Parallel::name() const @@ -92,7 +86,7 @@ void Parallel::clear() * Parallel Constructor */ Parallel::Parallel(const std::vector<HashFunction*>& hash_in) : - HashFunction(sum_of_hash_lengths(hash_in)), hashes(hash_in) + hashes(hash_in) { } diff --git a/src/hash/par_hash/par_hash.h b/src/hash/par_hash/par_hash.h index 35154dde4..4f5395c23 100644 --- a/src/hash/par_hash/par_hash.h +++ b/src/hash/par_hash/par_hash.h @@ -23,6 +23,8 @@ class BOTAN_DLL Parallel : public HashFunction std::string name() const; HashFunction* clone() const; + size_t output_length() const; + /** * @param hashes a set of hashes to compute in parallel */ diff --git a/src/hash/rmd128/rmd128.h b/src/hash/rmd128/rmd128.h index faead3245..d64cf3c84 100644 --- a/src/hash/rmd128/rmd128.h +++ b/src/hash/rmd128/rmd128.h @@ -18,11 +18,13 @@ namespace Botan { class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "RIPEMD-128"; } + size_t output_length() const { return 16; } HashFunction* clone() const { return new RIPEMD_128; } - RIPEMD_128() : MDx_HashFunction(16, 64, false, true), M(16), digest(4) + void clear(); + + RIPEMD_128() : MDx_HashFunction(64, false, true), M(16), digest(4) { clear(); } private: void compress_n(const byte[], size_t blocks); diff --git a/src/hash/rmd160/rmd160.h b/src/hash/rmd160/rmd160.h index 69c6b4a40..5df4ad490 100644 --- a/src/hash/rmd160/rmd160.h +++ b/src/hash/rmd160/rmd160.h @@ -18,11 +18,13 @@ namespace Botan { class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "RIPEMD-160"; } + size_t output_length() const { return 20; } HashFunction* clone() const { return new RIPEMD_160; } - RIPEMD_160() : MDx_HashFunction(20, 64, false, true), M(16), digest(5) + void clear(); + + RIPEMD_160() : MDx_HashFunction(64, false, true), M(16), digest(5) { clear(); } private: void compress_n(const byte[], size_t blocks); diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp index aa6a066e8..7a42ca867 100644 --- a/src/hash/sha1/sha160.cpp +++ b/src/hash/sha1/sha160.cpp @@ -152,22 +152,4 @@ void SHA_160::clear() digest[4] = 0xC3D2E1F0; } -/* -* SHA_160 Constructor -*/ -SHA_160::SHA_160() : - MDx_HashFunction(20, 64, true, true), digest(5), W(80) - { - clear(); - } - -/* -* SHA_160 Constructor -*/ -SHA_160::SHA_160(size_t W_size) : - MDx_HashFunction(20, 64, true, true), digest(5), W(W_size) - { - clear(); - } - } diff --git a/src/hash/sha1/sha160.h b/src/hash/sha1/sha160.h index d420f8f94..c3b264861 100644 --- a/src/hash/sha1/sha160.h +++ b/src/hash/sha1/sha160.h @@ -18,11 +18,16 @@ namespace Botan { class BOTAN_DLL SHA_160 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "SHA-160"; } + size_t output_length() const { return 20; } HashFunction* clone() const { return new SHA_160; } - SHA_160(); + void clear(); + + SHA_160() : MDx_HashFunction(64, true, true), digest(5), W(80) + { + clear(); + } protected: /** * Set a custom size for the W array. Normally 80, but some @@ -30,12 +35,23 @@ class BOTAN_DLL SHA_160 : public MDx_HashFunction * constraints * @param W_size how big to make W */ - SHA_160(size_t W_size); + SHA_160(size_t W_size) : + MDx_HashFunction(64, true, true), digest(5), W(W_size) + { + clear(); + } void compress_n(const byte[], size_t blocks); void copy_out(byte[]); + /** + * The digest value, exposed for use by subclasses (asm, SSE2) + */ SecureVector<u32bit> digest; + + /** + * The message buffer, exposed for use by subclasses (asm, SSE2) + */ SecureVector<u32bit> W; }; diff --git a/src/hash/sha2_32/sha2_32.h b/src/hash/sha2_32/sha2_32.h index 3b95812b8..ffda11772 100644 --- a/src/hash/sha2_32/sha2_32.h +++ b/src/hash/sha2_32/sha2_32.h @@ -19,11 +19,13 @@ namespace Botan { class BOTAN_DLL SHA_224 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "SHA-224"; } + size_t output_length() const { return 28; } HashFunction* clone() const { return new SHA_224; } - SHA_224() : MDx_HashFunction(28, 64, true, true), W(64), digest(8) + void clear(); + + SHA_224() : MDx_HashFunction(64, true, true), W(64), digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); @@ -38,11 +40,13 @@ class BOTAN_DLL SHA_224 : public MDx_HashFunction class BOTAN_DLL SHA_256 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "SHA-256"; } + size_t output_length() const { return 32; } HashFunction* clone() const { return new SHA_256; } - SHA_256() : MDx_HashFunction(32, 64, true, true), W(64), digest(8) + void clear(); + + SHA_256() : MDx_HashFunction(64, true, true), W(64), digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); diff --git a/src/hash/sha2_64/sha2_64.h b/src/hash/sha2_64/sha2_64.h index 59e2c4c83..dcfb7224c 100644 --- a/src/hash/sha2_64/sha2_64.h +++ b/src/hash/sha2_64/sha2_64.h @@ -18,11 +18,13 @@ namespace Botan { class BOTAN_DLL SHA_384 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "SHA-384"; } + size_t output_length() const { return 48; } HashFunction* clone() const { return new SHA_384; } - SHA_384() : MDx_HashFunction(48, 128, true, true, 16), W(80), digest(8) + void clear(); + + SHA_384() : MDx_HashFunction(128, true, true, 16), W(80), digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); @@ -37,10 +39,13 @@ class BOTAN_DLL SHA_384 : public MDx_HashFunction class BOTAN_DLL SHA_512 : public MDx_HashFunction { public: - void clear(); std::string name() const { return "SHA-512"; } + size_t output_length() const { return 64; } HashFunction* clone() const { return new SHA_512; } - SHA_512() : MDx_HashFunction(64, 128, true, true, 16), W(80), digest(8) + + void clear(); + + SHA_512() : MDx_HashFunction(128, true, true, 16), W(80), digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp index b2316242a..92acf0814 100644 --- a/src/hash/skein/skein_512.cpp +++ b/src/hash/skein/skein_512.cpp @@ -1,6 +1,6 @@ /* * The Skein-512 hash function -* (C) 2009 Jack Lloyd +* (C) 2009-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -47,7 +47,7 @@ void ubi_512(MemoryRegion<u64bit>& H, } H[8] = H[0] ^ H[1] ^ H[2] ^ H[3] ^ - H[4] ^ H[5] ^ H[6] ^ H[7] ^ 0x5555555555555555; + H[4] ^ H[5] ^ H[6] ^ H[7] ^ 0x1BD11BDAA9FC1A22; T[2] = T[0] ^ T[1]; @@ -168,7 +168,6 @@ void initial_block(MemoryRegion<u64bit>& H, Skein_512::Skein_512(size_t arg_output_bits, const std::string& arg_personalization) : - HashFunction(arg_output_bits / 8), personalization(arg_personalization), output_bits(arg_output_bits), H(9), T(3), buffer(64), buf_pos(0) diff --git a/src/hash/skein/skein_512.h b/src/hash/skein/skein_512.h index 54cdd002c..8605e5991 100644 --- a/src/hash/skein/skein_512.h +++ b/src/hash/skein/skein_512.h @@ -29,6 +29,7 @@ class BOTAN_DLL Skein_512 : public HashFunction const std::string& personalization = ""); size_t hash_block_size() const { return 64; } + size_t output_length() const { return output_bits / 8; } HashFunction* clone() const; std::string name() const; diff --git a/src/hash/tiger/tiger.cpp b/src/hash/tiger/tiger.cpp index 32189952a..daa0939b9 100644 --- a/src/hash/tiger/tiger.cpp +++ b/src/hash/tiger/tiger.cpp @@ -55,7 +55,7 @@ void Tiger::compress_n(const byte input[], size_t blocks) pass(C, A, B, X, 7); mix(X); pass(B, C, A, X, 9); - for(size_t j = 3; j != PASS; ++j) + for(size_t j = 3; j != passes; ++j) { mix(X); pass(A, B, C, X, 9); @@ -161,24 +161,26 @@ void Tiger::clear() std::string Tiger::name() const { return "Tiger(" + std::to_string(output_length()) + "," + - std::to_string(PASS) + ")"; + std::to_string(passes) + ")"; } /* * Tiger Constructor */ -Tiger::Tiger(size_t hashlen, size_t pass) : - MDx_HashFunction(hashlen, 64, false, false), +Tiger::Tiger(size_t hash_len, size_t passes) : + MDx_HashFunction(64, false, false), X(8), digest(3), - PASS(pass) + hash_len(hash_len), + passes(passes) { if(output_length() != 16 && output_length() != 20 && output_length() != 24) throw Invalid_Argument("Tiger: Illegal hash output size: " + std::to_string(output_length())); - if(PASS < 3) + + if(passes < 3) throw Invalid_Argument("Tiger: Invalid number of passes: " - + std::to_string(PASS)); + + std::to_string(passes)); clear(); } diff --git a/src/hash/tiger/tiger.h b/src/hash/tiger/tiger.h index 7d753c237..09c9947fb 100644 --- a/src/hash/tiger/tiger.h +++ b/src/hash/tiger/tiger.h @@ -18,14 +18,16 @@ namespace Botan { class BOTAN_DLL Tiger : public MDx_HashFunction { public: - void clear(); std::string name() const; + size_t output_length() const { return hash_len; } HashFunction* clone() const { - return new Tiger(output_length(), PASS); + return new Tiger(output_length(), passes); } + void clear(); + /** * @param out_size specifies the output length; can be 16, 20, or 24 * @param passes to make in the algorithm @@ -45,7 +47,7 @@ class BOTAN_DLL Tiger : public MDx_HashFunction static const u64bit SBOX4[256]; SecureVector<u64bit> X, digest; - const size_t PASS; + const size_t hash_len, passes; }; } diff --git a/src/hash/whirlpool/whrlpool.h b/src/hash/whirlpool/whrlpool.h index 30bf91a34..ab7a78bc8 100644 --- a/src/hash/whirlpool/whrlpool.h +++ b/src/hash/whirlpool/whrlpool.h @@ -18,11 +18,13 @@ namespace Botan { class BOTAN_DLL Whirlpool : public MDx_HashFunction { public: - void clear(); std::string name() const { return "Whirlpool"; } + size_t output_length() const { return 64; } HashFunction* clone() const { return new Whirlpool; } - Whirlpool() : MDx_HashFunction(64, 64, true, true, 32), M(8), digest(8) + void clear(); + + Whirlpool() : MDx_HashFunction(64, true, true, 32), M(8), digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); diff --git a/src/kdf/kdf.h b/src/kdf/kdf.h index 58d59d351..3ec912cfe 100644 --- a/src/kdf/kdf.h +++ b/src/kdf/kdf.h @@ -8,6 +8,7 @@ #ifndef BOTAN_KDF_BASE_H__ #define BOTAN_KDF_BASE_H__ +#include <botan/algo_base.h> #include <botan/secmem.h> #include <botan/types.h> @@ -16,7 +17,7 @@ namespace Botan { /** * Key Derivation Function */ -class BOTAN_DLL KDF +class BOTAN_DLL KDF : public Algorithm { public: /** @@ -77,7 +78,9 @@ class BOTAN_DLL KDF const byte salt[], size_t salt_len) const; - virtual ~KDF() {} + void clear() {} + + virtual KDF* clone() const = 0; private: virtual SecureVector<byte> derive(size_t key_len, diff --git a/src/kdf/kdf1/kdf1.h b/src/kdf/kdf1/kdf1.h index fd950cd9b..f627235be 100644 --- a/src/kdf/kdf1/kdf1.h +++ b/src/kdf/kdf1/kdf1.h @@ -23,6 +23,9 @@ class BOTAN_DLL KDF1 : public KDF const byte secret[], size_t secret_len, const byte P[], size_t P_len) const; + std::string name() const { return "KDF1(" + hash->name() + ")"; } + KDF* clone() const { return new KDF1(hash->clone()); } + KDF1(HashFunction* h) : hash(h) {} KDF1(const KDF1& other) : KDF(), hash(other.hash->clone()) {} diff --git a/src/kdf/kdf2/kdf2.h b/src/kdf/kdf2/kdf2.h index f2fd7630d..e85fe6d1c 100644 --- a/src/kdf/kdf2/kdf2.h +++ b/src/kdf/kdf2/kdf2.h @@ -22,6 +22,9 @@ class BOTAN_DLL KDF2 : public KDF SecureVector<byte> derive(size_t, const byte[], size_t, const byte[], size_t) const; + std::string name() const { return "KDF2(" + hash->name() + ")"; } + KDF* clone() const { return new KDF2(hash->clone()); } + KDF2(HashFunction* h) : hash(h) {} KDF2(const KDF2& other) : KDF(), hash(other.hash->clone()) {} ~KDF2() { delete hash; } diff --git a/src/kdf/ssl_prf/info.txt b/src/kdf/ssl_prf/info.txt index 68355ff40..0ef297119 100644 --- a/src/kdf/ssl_prf/info.txt +++ b/src/kdf/ssl_prf/info.txt @@ -3,5 +3,5 @@ define SSL_V3_PRF <requires> md5 sha1 -sym_algo +algo_base </requires> diff --git a/src/kdf/ssl_prf/prf_ssl3.h b/src/kdf/ssl_prf/prf_ssl3.h index 1340b149e..b07454be2 100644 --- a/src/kdf/ssl_prf/prf_ssl3.h +++ b/src/kdf/ssl_prf/prf_ssl3.h @@ -20,6 +20,9 @@ class BOTAN_DLL SSL3_PRF : public KDF public: SecureVector<byte> derive(size_t, const byte[], size_t, const byte[], size_t) const; + + std::string name() const { return "SSL3-PRF"; } + KDF* clone() const { return new SSL3_PRF; } }; } diff --git a/src/kdf/tls_prf/prf_tls.cpp b/src/kdf/tls_prf/prf_tls.cpp index 872997c28..2b57cdd25 100644 --- a/src/kdf/tls_prf/prf_tls.cpp +++ b/src/kdf/tls_prf/prf_tls.cpp @@ -85,9 +85,8 @@ SecureVector<byte> TLS_PRF::derive(size_t key_len, /* * TLS v1.2 PRF Constructor and Destructor */ -TLS_12_PRF::TLS_12_PRF(HashFunction* hash) +TLS_12_PRF::TLS_12_PRF(MessageAuthenticationCode* mac) : hmac(mac) { - hmac = new HMAC(hash); } TLS_12_PRF::~TLS_12_PRF() diff --git a/src/kdf/tls_prf/prf_tls.h b/src/kdf/tls_prf/prf_tls.h index ee1b29df6..5237f17c0 100644 --- a/src/kdf/tls_prf/prf_tls.h +++ b/src/kdf/tls_prf/prf_tls.h @@ -24,6 +24,9 @@ class BOTAN_DLL TLS_PRF : public KDF const byte secret[], size_t secret_len, const byte seed[], size_t seed_len) const; + std::string name() const { return "TLS-PRF"; } + KDF* clone() const { return new TLS_PRF; } + TLS_PRF(); ~TLS_PRF(); private: @@ -41,7 +44,10 @@ class BOTAN_DLL TLS_12_PRF : public KDF const byte secret[], size_t secret_len, const byte seed[], size_t seed_len) const; - TLS_12_PRF(HashFunction* hash); + std::string name() const { return "TLSv12-PRF(" + hmac->name() + ")"; } + KDF* clone() const { return new TLS_12_PRF(hmac->clone()); } + + TLS_12_PRF(MessageAuthenticationCode* hmac); ~TLS_12_PRF(); private: MessageAuthenticationCode* hmac; diff --git a/src/kdf/x942_prf/prf_x942.h b/src/kdf/x942_prf/prf_x942.h index 8efc6ea45..e6093eda6 100644 --- a/src/kdf/x942_prf/prf_x942.h +++ b/src/kdf/x942_prf/prf_x942.h @@ -21,7 +21,10 @@ class BOTAN_DLL X942_PRF : public KDF SecureVector<byte> derive(size_t, const byte[], size_t, const byte[], size_t) const; - X942_PRF(const std::string&); + std::string name() const { return "X942_PRF(" + key_wrap_oid + ")"; } + KDF* clone() const { return new X942_PRF(key_wrap_oid); } + + X942_PRF(const std::string& oid); private: std::string key_wrap_oid; }; diff --git a/src/libstate/get_enc.cpp b/src/libstate/get_enc.cpp index d4ca99535..6a87268e8 100644 --- a/src/libstate/get_enc.cpp +++ b/src/libstate/get_enc.cpp @@ -9,18 +9,6 @@ #include <botan/libstate.h> #include <botan/scan_name.h> -#if defined(BOTAN_HAS_PBKDF1) - #include <botan/pbkdf1.h> -#endif - -#if defined(BOTAN_HAS_PBKDF2) - #include <botan/pbkdf2.h> -#endif - -#if defined(BOTAN_HAS_PGPS2K) - #include <botan/pgp_s2k.h> -#endif - #if defined(BOTAN_HAS_MGF1) #include <botan/mgf1.h> #endif @@ -84,29 +72,10 @@ namespace Botan { */ PBKDF* get_pbkdf(const std::string& algo_spec) { - SCAN_Name request(algo_spec); - Algorithm_Factory& af = global_state().algorithm_factory(); -#if defined(BOTAN_HAS_PBKDF1) - if(request.algo_name() == "PBKDF1" && request.arg_count() == 1) - return new PKCS5_PBKDF1(af.make_hash_function(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_PBKDF2) - if(request.algo_name() == "PBKDF2" && request.arg_count() == 1) - { - if(const MessageAuthenticationCode* mac_proto = af.prototype_mac(request.arg(0))) - return new PKCS5_PBKDF2(mac_proto->clone()); - - return new PKCS5_PBKDF2(af.make_mac("HMAC(" + request.arg(0) + ")")); - } -#endif - -#if defined(BOTAN_HAS_PGPS2K) - if(request.algo_name() == "OpenPGP-S2K" && request.arg_count() == 1) - return new OpenPGP_S2K(af.make_hash_function(request.arg(0))); -#endif + if(PBKDF* pbkdf = af.make_pbkdf(algo_spec)) + return pbkdf; throw Algorithm_Not_Found(algo_spec); } diff --git a/src/libstate/libstate.cpp b/src/libstate/libstate.cpp index 1a0addc98..588c5db1b 100644 --- a/src/libstate/libstate.cpp +++ b/src/libstate/libstate.cpp @@ -112,7 +112,7 @@ bool Library_State::is_set(const std::string& section, { std::lock_guard<std::mutex> lock(config_lock); - return search_map(config, section + "/" + key, false, true); + return config.count(section + "/" + key) != 0; } /* diff --git a/src/libstate/look_pk.h b/src/libstate/look_pk.h index c980e5f8d..bbd0e7dba 100644 --- a/src/libstate/look_pk.h +++ b/src/libstate/look_pk.h @@ -21,6 +21,7 @@ namespace Botan { * @param eme determines the algorithm and encoding * @return public key encryptor object */ +BOTAN_DEPRECATED("Instantiate object directly") inline PK_Encryptor* get_pk_encryptor(const Public_Key& key, const std::string& eme) { @@ -35,6 +36,7 @@ inline PK_Encryptor* get_pk_encryptor(const Public_Key& key, * @param eme determines the algorithm and encoding * @return public key decryptor object */ +BOTAN_DEPRECATED("Instantiate object directly") inline PK_Decryptor* get_pk_decryptor(const Private_Key& key, const std::string& eme) { @@ -50,6 +52,7 @@ inline PK_Decryptor* get_pk_decryptor(const Private_Key& key, * @param sig_format the signature format to be used * @return public key signer object */ +BOTAN_DEPRECATED("Instantiate object directly") inline PK_Signer* get_pk_signer(const Private_Key& key, const std::string& emsa, Signature_Format sig_format = IEEE_1363) @@ -66,6 +69,7 @@ inline PK_Signer* get_pk_signer(const Private_Key& key, * @param sig_format the signature format to be used * @return public key verifier object */ +BOTAN_DEPRECATED("Instantiate object directly") inline PK_Verifier* get_pk_verifier(const Public_Key& key, const std::string& emsa, Signature_Format sig_format = IEEE_1363) @@ -81,8 +85,9 @@ inline PK_Verifier* get_pk_verifier(const Public_Key& key, * @param kdf the kdf algorithm to use * @return key agreement algorithm */ +BOTAN_DEPRECATED("Instantiate object directly") inline PK_Key_Agreement* get_pk_kas(const PK_Key_Agreement_Key& key, - const std::string& kdf) + const std::string& kdf) { return new PK_Key_Agreement(key, kdf); } diff --git a/src/libstate/lookup.cpp b/src/libstate/lookup.cpp index d971618c2..f5d2c5a0c 100644 --- a/src/libstate/lookup.cpp +++ b/src/libstate/lookup.cpp @@ -62,82 +62,6 @@ u32bit output_length_of(const std::string& name) } /* -* Check if a keylength is valid for this algo -*/ -bool valid_keylength_for(u32bit key_len, const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(name)) - return bc->valid_keylength(key_len); - - if(const StreamCipher* sc = af.prototype_stream_cipher(name)) - return sc->valid_keylength(key_len); - - if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) - return mac->valid_keylength(key_len); - - throw Algorithm_Not_Found(name); - } - -/* -* Query the MINIMUM_KEYLENGTH of an algorithm -*/ -u32bit min_keylength_of(const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(name)) - return bc->MINIMUM_KEYLENGTH; - - if(const StreamCipher* sc = af.prototype_stream_cipher(name)) - return sc->MINIMUM_KEYLENGTH; - - if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) - return mac->MINIMUM_KEYLENGTH; - - throw Algorithm_Not_Found(name); - } - -/* -* Query the MAXIMUM_KEYLENGTH of an algorithm -*/ -u32bit max_keylength_of(const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(name)) - return bc->MAXIMUM_KEYLENGTH; - - if(const StreamCipher* sc = af.prototype_stream_cipher(name)) - return sc->MAXIMUM_KEYLENGTH; - - if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) - return mac->MAXIMUM_KEYLENGTH; - - throw Algorithm_Not_Found(name); - } - -/* -* Query the KEYLENGTH_MULTIPLE of an algorithm -*/ -u32bit keylength_multiple_of(const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(name)) - return bc->KEYLENGTH_MULTIPLE; - - if(const StreamCipher* sc = af.prototype_stream_cipher(name)) - return sc->KEYLENGTH_MULTIPLE; - - if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) - return mac->KEYLENGTH_MULTIPLE; - - throw Algorithm_Not_Found(name); - } - -/* * Get a cipher object */ Keyed_Filter* get_cipher(const std::string& algo_spec, diff --git a/src/libstate/lookup.h b/src/libstate/lookup.h index 178f80428..f1e1a52ca 100644 --- a/src/libstate/lookup.h +++ b/src/libstate/lookup.h @@ -299,45 +299,6 @@ BOTAN_DLL u32bit block_size_of(const std::string& algo_spec); */ BOTAN_DLL u32bit output_length_of(const std::string& algo_spec); -/** -* Find out the whether a certain key length is allowd for a given -* symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param key_len the key length in question -* @param algo_spec the name of the algorithm -* @return true if the key length is valid for that algorithm, false otherwise -*/ -BOTAN_DLL bool valid_keylength_for(u32bit key_len, - const std::string& algo_spec); - -/** -* Find out the minimum key size of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return minimum key length of the specified algorithm -*/ -BOTAN_DLL u32bit min_keylength_of(const std::string& algo_spec); - -/** -* Find out the maximum key size of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return maximum key length of the specified algorithm -*/ -BOTAN_DLL u32bit max_keylength_of(const std::string& algo_spec); - -/** -* Find out the size any valid key is a multiple of for a certain algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return size any valid key is a multiple of -*/ -BOTAN_DLL u32bit keylength_multiple_of(const std::string& algo_spec); - } #endif diff --git a/src/mac/cbc_mac/cbc_mac.cpp b/src/mac/cbc_mac/cbc_mac.cpp index 48cc8ab3e..118570e72 100644 --- a/src/mac/cbc_mac/cbc_mac.cpp +++ b/src/mac/cbc_mac/cbc_mac.cpp @@ -89,10 +89,6 @@ MessageAuthenticationCode* CBC_MAC::clone() const * CBC-MAC Constructor */ CBC_MAC::CBC_MAC(BlockCipher* e_in) : - MessageAuthenticationCode(e_in->block_size(), - e_in->MINIMUM_KEYLENGTH, - e_in->MAXIMUM_KEYLENGTH, - e_in->KEYLENGTH_MULTIPLE), e(e_in), state(e->block_size()) { position = 0; diff --git a/src/mac/cbc_mac/cbc_mac.h b/src/mac/cbc_mac/cbc_mac.h index 6b30ef764..5cc8adc67 100644 --- a/src/mac/cbc_mac/cbc_mac.h +++ b/src/mac/cbc_mac/cbc_mac.h @@ -19,9 +19,15 @@ namespace Botan { class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode { public: - void clear(); std::string name() const; MessageAuthenticationCode* clone() const; + size_t output_length() const { return e->block_size(); } + void clear(); + + Key_Length_Specification key_spec() const + { + return e->key_spec(); + } /** * @param cipher the underlying block cipher to use diff --git a/src/mac/cmac/cmac.cpp b/src/mac/cmac/cmac.cpp index 2147f9a45..7db597fff 100644 --- a/src/mac/cmac/cmac.cpp +++ b/src/mac/cmac/cmac.cpp @@ -130,12 +130,7 @@ MessageAuthenticationCode* CMAC::clone() const /* * CMAC Constructor */ -CMAC::CMAC(BlockCipher* e_in) : - MessageAuthenticationCode(e_in->block_size(), - e_in->MINIMUM_KEYLENGTH, - e_in->MAXIMUM_KEYLENGTH, - e_in->KEYLENGTH_MULTIPLE), - e(e_in) +CMAC::CMAC(BlockCipher* e_in) : e(e_in) { if(e->block_size() == 16) polynomial = 0x87; diff --git a/src/mac/cmac/cmac.h b/src/mac/cmac/cmac.h index ac929eaf3..98634bdb7 100644 --- a/src/mac/cmac/cmac.h +++ b/src/mac/cmac/cmac.h @@ -19,10 +19,17 @@ namespace Botan { class BOTAN_DLL CMAC : public MessageAuthenticationCode { public: - void clear(); std::string name() const; + size_t output_length() const { return e->block_size(); } MessageAuthenticationCode* clone() const; + void clear(); + + Key_Length_Specification key_spec() const + { + return e->key_spec(); + } + /** * CMAC's polynomial doubling operation * @param in the input diff --git a/src/mac/hmac/hmac.cpp b/src/mac/hmac/hmac.cpp index 06923138a..fc35e26ea 100644 --- a/src/mac/hmac/hmac.cpp +++ b/src/mac/hmac/hmac.cpp @@ -84,10 +84,7 @@ MessageAuthenticationCode* HMAC::clone() const /* * HMAC Constructor */ -HMAC::HMAC(HashFunction* hash_in) : - MessageAuthenticationCode(hash_in->output_length(), - 0, 2*hash_in->hash_block_size()), - hash(hash_in) +HMAC::HMAC(HashFunction* hash_in) : hash(hash_in) { if(hash->hash_block_size() == 0) throw Invalid_Argument("HMAC cannot be used with " + hash->name()); diff --git a/src/mac/hmac/hmac.h b/src/mac/hmac/hmac.h index 33af62f6a..b76a058f4 100644 --- a/src/mac/hmac/hmac.h +++ b/src/mac/hmac/hmac.h @@ -23,6 +23,13 @@ class BOTAN_DLL HMAC : public MessageAuthenticationCode std::string name() const; MessageAuthenticationCode* clone() const; + size_t output_length() const { return hash->output_length(); } + + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(0, 2*hash->hash_block_size()); + } + /** * @param hash the hash to use for HMACing */ diff --git a/src/mac/info.txt b/src/mac/info.txt index 6a74d8445..d991577f7 100644 --- a/src/mac/info.txt +++ b/src/mac/info.txt @@ -1,4 +1,3 @@ <requires> -buf_comp -sym_algo +algo_base </requires> diff --git a/src/mac/mac.h b/src/mac/mac.h index b788e06c8..d42092908 100644 --- a/src/mac/mac.h +++ b/src/mac/mac.h @@ -17,7 +17,7 @@ namespace Botan { /** * This class represents Message Authentication Code (MAC) objects. */ -class BOTAN_DLL MessageAuthenticationCode : public BufferedComputation, +class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, public SymmetricAlgorithm { public: @@ -39,26 +39,6 @@ class BOTAN_DLL MessageAuthenticationCode : public BufferedComputation, * @return name of this algorithm */ virtual std::string name() const = 0; - - /** - * Reset the internal state of this object. - */ - virtual void clear() = 0; - - /** - * @param mac_len the output length of this MAC - * @param key_min the minimum key size - * @param key_max the maximum key size - * @param key_mod the modulo restriction on the key size - */ - MessageAuthenticationCode(size_t mac_len, - size_t key_min, - size_t key_max = 0, - size_t key_mod = 1) : - BufferedComputation(mac_len), - SymmetricAlgorithm(key_min, key_max, key_mod) {} - - virtual ~MessageAuthenticationCode() {} }; } diff --git a/src/mac/ssl3mac/ssl3_mac.cpp b/src/mac/ssl3mac/ssl3_mac.cpp index fcbccc06e..a07622eb3 100644 --- a/src/mac/ssl3mac/ssl3_mac.cpp +++ b/src/mac/ssl3mac/ssl3_mac.cpp @@ -72,15 +72,13 @@ MessageAuthenticationCode* SSL3_MAC::clone() const /* * SSL3-MAC Constructor */ -SSL3_MAC::SSL3_MAC(HashFunction* hash_in) : - MessageAuthenticationCode(hash_in->output_length(), - hash_in->output_length()), - hash(hash_in) +SSL3_MAC::SSL3_MAC(HashFunction* hash_in) : hash(hash_in) { if(hash->hash_block_size() == 0) throw Invalid_Argument("SSL3-MAC cannot be used with " + hash->name()); - size_t INNER_HASH_LENGTH = + // Quirk to deal with specification bug + const size_t INNER_HASH_LENGTH = (hash->name() == "SHA-160") ? 60 : hash->hash_block_size(); i_key.resize(INNER_HASH_LENGTH); diff --git a/src/mac/ssl3mac/ssl3_mac.h b/src/mac/ssl3mac/ssl3_mac.h index 50042f3d0..a85a78263 100644 --- a/src/mac/ssl3mac/ssl3_mac.h +++ b/src/mac/ssl3mac/ssl3_mac.h @@ -19,10 +19,17 @@ namespace Botan { class BOTAN_DLL SSL3_MAC : public MessageAuthenticationCode { public: - void clear(); std::string name() const; + size_t output_length() const { return hash->output_length(); } MessageAuthenticationCode* clone() const; + void clear(); + + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(hash->output_length()); + } + /** * @param hash the underlying hash to use */ diff --git a/src/mac/x919_mac/x919_mac.cpp b/src/mac/x919_mac/x919_mac.cpp index c46ab82cb..fcbe77537 100644 --- a/src/mac/x919_mac/x919_mac.cpp +++ b/src/mac/x919_mac/x919_mac.cpp @@ -85,10 +85,6 @@ MessageAuthenticationCode* ANSI_X919_MAC::clone() const * ANSI X9.19 MAC Constructor */ ANSI_X919_MAC::ANSI_X919_MAC(BlockCipher* e_in) : - MessageAuthenticationCode(e_in->block_size(), - e_in->MINIMUM_KEYLENGTH, - 2*e_in->MAXIMUM_KEYLENGTH, - 2*e_in->KEYLENGTH_MULTIPLE), e(e_in), d(e->clone()), state(e->block_size()), position(0) { if(e->name() != "DES") diff --git a/src/mac/x919_mac/x919_mac.h b/src/mac/x919_mac/x919_mac.h index e9fe56c8d..58a005e0b 100644 --- a/src/mac/x919_mac/x919_mac.h +++ b/src/mac/x919_mac/x919_mac.h @@ -21,8 +21,14 @@ class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode public: void clear(); std::string name() const; + size_t output_length() const { return e->block_size(); } MessageAuthenticationCode* clone() const; + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(8, 16, 8); + } + /** * @param cipher the underlying block cipher to use */ diff --git a/src/math/bigint/bigint.h b/src/math/bigint/bigint.h index fc2e58073..5b3dcc2dd 100644 --- a/src/math/bigint/bigint.h +++ b/src/math/bigint/bigint.h @@ -325,6 +325,15 @@ class BOTAN_DLL BigInt const SecureVector<word>& get_reg() const { return reg; } /** + * Assign using a plain word array + */ + void assign(const word x[], size_t length) + { + reg.resize(length); + copy_mem(®[0], x, length); + } + + /** * Increase internal register buffer by n words * @param n increase by n words */ diff --git a/src/math/numbertheory/curve_gfp.h b/src/math/numbertheory/curve_gfp.h index f3c4dc1a1..1ab803ec9 100644 --- a/src/math/numbertheory/curve_gfp.h +++ b/src/math/numbertheory/curve_gfp.h @@ -33,9 +33,8 @@ class BOTAN_DLL CurveGFp * @param a first coefficient * @param b second coefficient */ - CurveGFp(const BigInt& p_in, - const BigInt& a_in, const BigInt& b_in) : - p(p_in), a(a_in), b(b_in), reducer_p(p) + CurveGFp(const BigInt& p, const BigInt& a, const BigInt& b) : + p(p), a(a), b(b), reducer_p(p) { r = 1; r <<= p.sig_words() * BOTAN_MP_WORD_BITS; diff --git a/src/math/numbertheory/powm_mnt.cpp b/src/math/numbertheory/powm_mnt.cpp index 4f626ac9d..421470364 100644 --- a/src/math/numbertheory/powm_mnt.cpp +++ b/src/math/numbertheory/powm_mnt.cpp @@ -41,7 +41,7 @@ void Montgomery_Exponentiator::set_base(const BigInt& base) &workspace[0], modulus.data(), mod_words, mod_prime); - g[0].get_reg().set(&z[0], mod_words + 1); + g[0].assign(&z[0], mod_words + 1); const BigInt& x = g[0]; const size_t x_sig = x.sig_words(); @@ -60,7 +60,7 @@ void Montgomery_Exponentiator::set_base(const BigInt& base) &workspace[0], modulus.data(), mod_words, mod_prime); - g[i].get_reg().set(&z[0], mod_words + 1); + g[i].assign(&z[0], mod_words + 1); } } @@ -87,7 +87,7 @@ BigInt Montgomery_Exponentiator::execute() const &workspace[0], modulus.data(), mod_words, mod_prime); - x.get_reg().set(&z[0], mod_words + 1); + x.assign(&z[0], mod_words + 1); } if(u32bit nibble = exp.get_substring(window_bits*(i-1), window_bits)) @@ -103,7 +103,7 @@ BigInt Montgomery_Exponentiator::execute() const &workspace[0], modulus.data(), mod_words, mod_prime); - x.get_reg().set(&z[0], mod_words + 1); + x.assign(&z[0], mod_words + 1); } } diff --git a/src/pbe/pbes1/pbes1.cpp b/src/pbe/pbes1/pbes1.cpp index 994b02d0a..ec5ebb253 100644 --- a/src/pbe/pbes1/pbes1.cpp +++ b/src/pbe/pbes1/pbes1.cpp @@ -80,12 +80,14 @@ void PBE_PKCS5v15::set_key(const std::string& passphrase) { PKCS5_PBKDF1 pbkdf(hash_function->clone()); - SymmetricKey key_and_iv = pbkdf.derive_key(16, passphrase, - &salt[0], salt.size(), - iterations); - - key.set(key_and_iv.begin(), 8); - iv.set(key_and_iv.begin() + 8, 8); + SecureVector<byte> key_and_iv = pbkdf.derive_key(16, passphrase, + &salt[0], salt.size(), + iterations).bits_of(); + + key.resize(8); + iv.resize(8); + copy_mem(&key[0], &key_and_iv[0], 8); + copy_mem(&iv[0], &key_and_iv[8], 8); } /* diff --git a/src/pbe/pbes2/pbes2.cpp b/src/pbe/pbes2/pbes2.cpp index e74609467..85afe6ffe 100644 --- a/src/pbe/pbes2/pbes2.cpp +++ b/src/pbe/pbes2/pbes2.cpp @@ -98,7 +98,7 @@ void PBE_PKCS5v20::set_key(const std::string& passphrase) void PBE_PKCS5v20::new_params(RandomNumberGenerator& rng) { iterations = 10000; - key_length = block_cipher->MAXIMUM_KEYLENGTH; + key_length = block_cipher->maximum_keylength(); salt = rng.random_vec(12); iv = rng.random_vec(block_cipher->block_size()); @@ -178,7 +178,7 @@ void PBE_PKCS5v20::decode_params(DataSource& source) hash_function = af.make_hash_function("SHA-160"); if(key_length == 0) - key_length = block_cipher->MAXIMUM_KEYLENGTH; + key_length = block_cipher->maximum_keylength(); if(salt.size() < 8) throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small"); diff --git a/src/pbkdf/info.txt b/src/pbkdf/info.txt index 861b6f760..d991577f7 100644 --- a/src/pbkdf/info.txt +++ b/src/pbkdf/info.txt @@ -1,3 +1,3 @@ <requires> -sym_algo +algo_base </requires> diff --git a/src/pbkdf/pbkdf.h b/src/pbkdf/pbkdf.h index 03e6c51cf..e951b5673 100644 --- a/src/pbkdf/pbkdf.h +++ b/src/pbkdf/pbkdf.h @@ -8,6 +8,7 @@ #ifndef BOTAN_PBKDF_H__ #define BOTAN_PBKDF_H__ +#include <botan/algo_base.h> #include <botan/symkey.h> namespace Botan { @@ -17,7 +18,7 @@ namespace Botan { * implementations. Converts a password into a key using a salt * and iterated hashing to make brute force attacks harder. */ -class BOTAN_DLL PBKDF +class BOTAN_DLL PBKDF : public Algorithm { public: @@ -26,16 +27,7 @@ class BOTAN_DLL PBKDF */ virtual PBKDF* clone() const = 0; - /** - * Get the algorithm name. - * @return name of this PBKDF algorithm - */ - virtual std::string name() const = 0; - - /** - * Clear this objects internal values. - */ - virtual void clear() {} + void clear() {} /** * Derive a key from a passphrase @@ -49,12 +41,6 @@ class BOTAN_DLL PBKDF const std::string& passphrase, const byte salt[], size_t salt_len, size_t iterations) const = 0; - - PBKDF() {} - virtual ~PBKDF() {} - - PBKDF(const PBKDF&) = delete; - PBKDF& operator=(const PBKDF&) = delete; }; /** diff --git a/src/pk_pad/eme1/eme1.cpp b/src/pk_pad/eme1/eme1.cpp index 63347e6a8..b49fb9af0 100644 --- a/src/pk_pad/eme1/eme1.cpp +++ b/src/pk_pad/eme1/eme1.cpp @@ -21,22 +21,22 @@ SecureVector<byte> EME1::pad(const byte in[], size_t in_length, { key_length /= 8; - if(in_length > key_length - 2*HASH_LENGTH - 1) + if(in_length > key_length - 2*Phash.size() - 1) throw Invalid_Argument("EME1: Input is too large"); SecureVector<byte> out(key_length); - rng.randomize(&out[0], HASH_LENGTH); + rng.randomize(&out[0], Phash.size()); - out.copy(HASH_LENGTH, &Phash[0], Phash.size()); + out.copy(Phash.size(), &Phash[0], Phash.size()); out[out.size() - in_length - 1] = 0x01; out.copy(out.size() - in_length, in, in_length); - mgf->mask(&out[0], HASH_LENGTH, - &out[HASH_LENGTH], out.size() - HASH_LENGTH); + mgf->mask(&out[0], Phash.size(), + &out[Phash.size()], out.size() - Phash.size()); - mgf->mask(&out[HASH_LENGTH], out.size() - HASH_LENGTH, - &out[0], HASH_LENGTH); + mgf->mask(&out[Phash.size()], out.size() - Phash.size(), + &out[0], Phash.size()); return out; } @@ -68,18 +68,18 @@ SecureVector<byte> EME1::unpad(const byte in[], size_t in_length, SecureVector<byte> tmp(key_length); tmp.copy(key_length - in_length, in, in_length); - mgf->mask(&tmp[HASH_LENGTH], tmp.size() - HASH_LENGTH, - &tmp[0], HASH_LENGTH); - mgf->mask(&tmp[0], HASH_LENGTH, - &tmp[HASH_LENGTH], tmp.size() - HASH_LENGTH); + mgf->mask(&tmp[Phash.size()], tmp.size() - Phash.size(), + &tmp[0], Phash.size()); + mgf->mask(&tmp[0], Phash.size(), + &tmp[Phash.size()], tmp.size() - Phash.size()); - const bool phash_ok = same_mem(&tmp[HASH_LENGTH], &Phash[0], Phash.size()); + const bool phash_ok = same_mem(&tmp[Phash.size()], &Phash[0], Phash.size()); bool delim_ok = true; size_t delim_idx = 0; // Is this vulnerable to timing attacks? - for(size_t i = HASH_LENGTH + Phash.size(); i != tmp.size(); ++i) + for(size_t i = Phash.size() + Phash.size(); i != tmp.size(); ++i) { if(tmp[i] && !delim_idx) { @@ -104,8 +104,8 @@ SecureVector<byte> EME1::unpad(const byte in[], size_t in_length, */ size_t EME1::maximum_input_size(size_t keybits) const { - if(keybits / 8 > 2*HASH_LENGTH + 1) - return ((keybits / 8) - 2*HASH_LENGTH - 1); + if(keybits / 8 > 2*Phash.size() + 1) + return ((keybits / 8) - 2*Phash.size() - 1); else return 0; } @@ -113,8 +113,7 @@ size_t EME1::maximum_input_size(size_t keybits) const /* * EME1 Constructor */ -EME1::EME1(HashFunction* hash, const std::string& P) : - HASH_LENGTH(hash->output_length()) +EME1::EME1(HashFunction* hash, const std::string& P) { Phash = hash->process(P); mgf = new MGF1(hash); diff --git a/src/pk_pad/eme1/eme1.h b/src/pk_pad/eme1/eme1.h index f99dceb8c..0d0223de0 100644 --- a/src/pk_pad/eme1/eme1.h +++ b/src/pk_pad/eme1/eme1.h @@ -34,7 +34,6 @@ class BOTAN_DLL EME1 : public EME RandomNumberGenerator&) const; SecureVector<byte> unpad(const byte[], size_t, size_t) const; - const size_t HASH_LENGTH; SecureVector<byte> Phash; MGF* mgf; }; diff --git a/src/pk_pad/hash_id/hash_id.cpp b/src/pk_pad/hash_id/hash_id.cpp index 173f02a6d..74653cb83 100644 --- a/src/pk_pad/hash_id/hash_id.cpp +++ b/src/pk_pad/hash_id/hash_id.cpp @@ -59,35 +59,30 @@ const byte TIGER_PKCS_ID[] = { */ MemoryVector<byte> pkcs_hash_id(const std::string& name) { - MemoryVector<byte> out; - // Special case for SSL/TLS RSA signatures if(name == "Parallel(MD5,SHA-160)") - return out; + return MemoryVector<byte>(); if(name == "MD2") - out.set(MD2_PKCS_ID, sizeof(MD2_PKCS_ID)); - else if(name == "MD5") - out.set(MD5_PKCS_ID, sizeof(MD5_PKCS_ID)); - else if(name == "RIPEMD-128") - out.set(RIPEMD_128_PKCS_ID, sizeof(RIPEMD_128_PKCS_ID)); - else if(name == "RIPEMD-160") - out.set(RIPEMD_160_PKCS_ID, sizeof(RIPEMD_160_PKCS_ID)); - else if(name == "SHA-160") - out.set(SHA_160_PKCS_ID, sizeof(SHA_160_PKCS_ID)); - else if(name == "SHA-224") - out.set(SHA_224_PKCS_ID, sizeof(SHA_224_PKCS_ID)); - else if(name == "SHA-256") - out.set(SHA_256_PKCS_ID, sizeof(SHA_256_PKCS_ID)); - else if(name == "SHA-384") - out.set(SHA_384_PKCS_ID, sizeof(SHA_384_PKCS_ID)); - else if(name == "SHA-512") - out.set(SHA_512_PKCS_ID, sizeof(SHA_512_PKCS_ID)); - else if(name == "Tiger(24,3)") - out.set(TIGER_PKCS_ID, sizeof(TIGER_PKCS_ID)); - - if(out.size()) - return out; + return MemoryVector<byte>(MD2_PKCS_ID, sizeof(MD2_PKCS_ID)); + if(name == "MD5") + return MemoryVector<byte>(MD5_PKCS_ID, sizeof(MD5_PKCS_ID)); + if(name == "RIPEMD-128") + return MemoryVector<byte>(RIPEMD_128_PKCS_ID, sizeof(RIPEMD_128_PKCS_ID)); + if(name == "RIPEMD-160") + return MemoryVector<byte>(RIPEMD_160_PKCS_ID, sizeof(RIPEMD_160_PKCS_ID)); + if(name == "SHA-160") + return MemoryVector<byte>(SHA_160_PKCS_ID, sizeof(SHA_160_PKCS_ID)); + if(name == "SHA-224") + return MemoryVector<byte>(SHA_224_PKCS_ID, sizeof(SHA_224_PKCS_ID)); + if(name == "SHA-256") + return MemoryVector<byte>(SHA_256_PKCS_ID, sizeof(SHA_256_PKCS_ID)); + if(name == "SHA-384") + return MemoryVector<byte>(SHA_384_PKCS_ID, sizeof(SHA_384_PKCS_ID)); + if(name == "SHA-512") + return MemoryVector<byte>(SHA_512_PKCS_ID, sizeof(SHA_512_PKCS_ID)); + if(name == "Tiger(24,3)") + return MemoryVector<byte>(TIGER_PKCS_ID, sizeof(TIGER_PKCS_ID)); throw Invalid_Argument("No PKCS #1 identifier for " + name); } diff --git a/src/pubkey/info.txt b/src/pubkey/info.txt index 956a5e369..5f36f63c4 100644 --- a/src/pubkey/info.txt +++ b/src/pubkey/info.txt @@ -39,5 +39,5 @@ pbe pem pk_pad rng -sym_algo +algo_base </requires> diff --git a/src/pubkey/pkcs8.h b/src/pubkey/pkcs8.h index 93f2f92c6..d573fb460 100644 --- a/src/pubkey/pkcs8.h +++ b/src/pubkey/pkcs8.h @@ -81,6 +81,7 @@ BOTAN_DLL std::string PEM_encode(const Private_Key& key, * @param pipe the pipe to feed the encoded key into * @param encoding the encoding type to use */ +BOTAN_DEPRECATED("Use PEM_encode or BER_encode") inline void encode(const Private_Key& key, Pipe& pipe, X509_Encoding encoding = PEM) @@ -104,6 +105,7 @@ inline void encode(const Private_Key& key, default will be chosen. * @param encoding the encoding type to use */ +BOTAN_DEPRECATED("Use PEM_encode or BER_encode") inline void encrypt_key(const Private_Key& key, Pipe& pipe, RandomNumberGenerator& rng, diff --git a/src/pubkey/pubkey.cpp b/src/pubkey/pubkey.cpp index 2e324c6f4..d0b74071c 100644 --- a/src/pubkey/pubkey.cpp +++ b/src/pubkey/pubkey.cpp @@ -45,20 +45,27 @@ PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, * Encrypt a message */ SecureVector<byte> -PK_Encryptor_EME::enc(const byte msg[], +PK_Encryptor_EME::enc(const byte in[], size_t length, RandomNumberGenerator& rng) const { - SecureVector<byte> message; if(eme) - message = eme->encode(msg, length, op->max_input_bits(), rng); - else - message.set(msg, length); + { + SecureVector<byte> encoded = + eme->encode(in, length, op->max_input_bits(), rng); + + if(8*(encoded.size() - 1) + high_bit(encoded[0]) > op->max_input_bits()) + throw Invalid_Argument("PK_Encryptor_EME: Input is too large"); - if(8*(message.size() - 1) + high_bit(message[0]) > op->max_input_bits()) - throw Invalid_Argument("PK_Encryptor_EME: Input is too large"); + return op->encrypt(&encoded[0], encoded.size(), rng); + } + else + { + if(8*(length - 1) + high_bit(in[0]) > op->max_input_bits()) + throw Invalid_Argument("PK_Encryptor_EME: Input is too large"); - return op->encrypt(&message[0], message.size(), rng); + return op->encrypt(&in[0], length, rng); + } } /* diff --git a/src/pubkey/x509_key.cpp b/src/pubkey/x509_key.cpp index d321ce338..4714b1285 100644 --- a/src/pubkey/x509_key.cpp +++ b/src/pubkey/x509_key.cpp @@ -115,7 +115,7 @@ Key_Constraints find_constraints(const Public_Key& pub_key, { const std::string name = pub_key.algo_name(); - u32bit constraints = 0; + size_t constraints = 0; if(name == "DH" || name == "ECDH") constraints |= KEY_AGREEMENT; diff --git a/src/pubkey/x509_key.h b/src/pubkey/x509_key.h index 7dd2a9db8..3fdee8cde 100644 --- a/src/pubkey/x509_key.h +++ b/src/pubkey/x509_key.h @@ -83,6 +83,7 @@ BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, * @param pipe the pipe to feed the encoded key into * @param encoding the encoding type to use */ +BOTAN_DEPRECATED("Use PEM_encode or BER_encode") inline void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding = PEM) diff --git a/src/rng/rng.h b/src/rng/rng.h index 95e1f12cb..c078ef08f 100644 --- a/src/rng/rng.h +++ b/src/rng/rng.h @@ -32,6 +32,11 @@ class BOTAN_DLL RandomNumberGenerator */ virtual void randomize(byte output[], size_t length) = 0; + /** + * Return a random vector + * @param bytes number of bytes in the result + * @return randomized vector of length bytes + */ SecureVector<byte> random_vec(size_t bytes) { SecureVector<byte> output(bytes); diff --git a/src/rng/x931_rng/x931_rng.cpp b/src/rng/x931_rng/x931_rng.cpp index 0911ce526..ac77b4344 100644 --- a/src/rng/x931_rng/x931_rng.cpp +++ b/src/rng/x931_rng/x931_rng.cpp @@ -61,7 +61,7 @@ void ANSI_X931_RNG::rekey() if(prng->is_seeded()) { - cipher->set_key(prng->random_vec(cipher->MAXIMUM_KEYLENGTH)); + cipher->set_key(prng->random_vec(cipher->maximum_keylength())); if(V.size() != BLOCK_SIZE) V.resize(BLOCK_SIZE); diff --git a/src/ssl/hello.cpp b/src/ssl/hello.cpp index 1efef9213..bec316bb1 100644 --- a/src/ssl/hello.cpp +++ b/src/ssl/hello.cpp @@ -125,7 +125,8 @@ void Client_Hello::deserialize_sslv2(const MemoryRegion<byte>& buf) c_version = static_cast<Version_Code>(make_u16bit(buf[1], buf[2])); - c_random.set(&buf[9+cipher_spec_len+sess_id_len], challenge_len); + c_random.resize(challenge_len); + copy_mem(&c_random[0], &buf[9+cipher_spec_len+sess_id_len], challenge_len); } /* diff --git a/src/ssl/s_kex.cpp b/src/ssl/s_kex.cpp index f2df58b8b..ffec0aa8f 100644 --- a/src/ssl/s_kex.cpp +++ b/src/ssl/s_kex.cpp @@ -111,7 +111,8 @@ void Server_Key_Exchange::deserialize(const MemoryRegion<byte>& buf) if(len + so_far > buf.size()) throw Decoding_Error("Server_Key_Exchange: Packet corrupted"); - values[i].set(&buf[so_far], len); + values[i].resize(len); + copy_mem(&values[i][0], &buf[so_far], len); so_far += len; if(i == 2 && so_far == buf.size()) diff --git a/src/ssl/tls_client.cpp b/src/ssl/tls_client.cpp index 206d5f028..03c8117cc 100644 --- a/src/ssl/tls_client.cpp +++ b/src/ssl/tls_client.cpp @@ -17,9 +17,9 @@ namespace Botan { namespace { -// FIXME: checks are wrong for session reuse (add a flag for that) /** * Verify the state transition is allowed +* FIXME: checks are wrong for session reuse (add a flag for that) */ void client_check_state(Handshake_Type new_msg, Handshake_State* state) { diff --git a/src/ssl/tls_client.h b/src/ssl/tls_client.h index 0ee975e0f..0268c34c1 100644 --- a/src/ssl/tls_client.h +++ b/src/ssl/tls_client.h @@ -17,7 +17,7 @@ namespace Botan { /** -* TLS Client +* SSL/TLS Client */ class BOTAN_DLL TLS_Client : public TLS_Connection { diff --git a/src/ssl/tls_record.h b/src/ssl/tls_record.h index 1f4576e31..40b6a6f8d 100644 --- a/src/ssl/tls_record.h +++ b/src/ssl/tls_record.h @@ -10,7 +10,6 @@ #include <botan/tls_session_key.h> #include <botan/tls_suites.h> -#include <botan/socket.h> #include <botan/pipe.h> #include <botan/mac.h> #include <botan/secqueue.h> @@ -19,8 +18,6 @@ using namespace std::placeholders; -namespace Botan { - /** * TLS Record Writer */ diff --git a/src/ssl/tls_server.cpp b/src/ssl/tls_server.cpp index 65f4204c8..4e071da59 100644 --- a/src/ssl/tls_server.cpp +++ b/src/ssl/tls_server.cpp @@ -85,20 +85,21 @@ void server_check_state(Handshake_Type new_msg, Handshake_State* state) /* * TLS Server Constructor */ -TLS_Server::TLS_Server(const TLS_Policy& pol, - RandomNumberGenerator& r, - Socket& sock, +TLS_Server::TLS_Server(std::tr1::function<size_t (byte[], size_t)> input_fn, + std::tr1::function<void (const byte[], size_t)> output_fn, + const TLS_Policy& policy, + RandomNumberGenerator& rng, const X509_Certificate& cert, - const Private_Key& key) : - policy(pol), - rng(r), - peer(sock), - writer(std::bind(&Socket::write, std::ref(peer), _1, _2)) + const Private_Key& cert_key) : + input_fn(input_fn), + policy(policy), + rng(rng), + writer(output_fn) { state = 0; cert_chain.push_back(cert); - private_key = PKCS8::copy_key(key, rng); + private_key = PKCS8::copy_key(cert_key, rng); try { active = false; @@ -218,7 +219,7 @@ void TLS_Server::state_machine() while(bytes_needed) { size_t to_get = std::min<size_t>(record.size(), bytes_needed); - size_t got = peer.read(&record[0], to_get); + size_t got = input_fn(&record[0], to_get); if(got == 0) { diff --git a/src/ssl/tls_server.h b/src/ssl/tls_server.h index 09a1ef40b..a6b0f9cb4 100644 --- a/src/ssl/tls_server.h +++ b/src/ssl/tls_server.h @@ -11,7 +11,6 @@ #include <botan/tls_connection.h> #include <botan/tls_record.h> #include <botan/tls_policy.h> -#include <botan/socket.h> #include <vector> namespace Botan { @@ -19,7 +18,6 @@ namespace Botan { /** * TLS Server */ - class BOTAN_DLL TLS_Server : public TLS_Connection { public: @@ -34,11 +32,14 @@ class BOTAN_DLL TLS_Server : public TLS_Connection void close(); bool is_closed() const; - // FIXME: support cert chains (!) - // FIXME: support anonymous servers - TLS_Server(const TLS_Policy& policy, + /* + * FIXME: support cert chains (!) + * FIXME: support anonymous servers + */ + TLS_Server(std::tr1::function<size_t (byte[], size_t)> input_fn, + std::tr1::function<void (const byte[], size_t)> output_fn, + const TLS_Policy& policy, RandomNumberGenerator& rng, - Socket& peer, const X509_Certificate& cert, const Private_Key& cert_key); @@ -52,9 +53,10 @@ class BOTAN_DLL TLS_Server : public TLS_Connection void process_handshake_msg(Handshake_Type, const MemoryRegion<byte>&); + std::tr1::function<size_t (byte[], size_t)> input_fn; + const TLS_Policy& policy; RandomNumberGenerator& rng; - Socket& peer; Record_Writer writer; Record_Reader reader; diff --git a/src/stream/arc4/arc4.cpp b/src/stream/arc4/arc4.cpp index 170235419..313e777a5 100644 --- a/src/stream/arc4/arc4.cpp +++ b/src/stream/arc4/arc4.cpp @@ -101,8 +101,9 @@ void ARC4::clear() /* * ARC4 Constructor */ -ARC4::ARC4(size_t s) : StreamCipher(1, 256), SKIP(s), - state(256), buffer(DEFAULT_BUFFERSIZE) +ARC4::ARC4(size_t s) : SKIP(s), + state(256), + buffer(DEFAULT_BUFFERSIZE) { clear(); } diff --git a/src/stream/arc4/arc4.h b/src/stream/arc4/arc4.h index 85ddb69b7..e3df97f83 100644 --- a/src/stream/arc4/arc4.h +++ b/src/stream/arc4/arc4.h @@ -26,6 +26,11 @@ class BOTAN_DLL ARC4 : public StreamCipher StreamCipher* clone() const { return new ARC4(SKIP); } + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(1, 256); + } + /** * @param skip skip this many initial bytes in the keystream */ diff --git a/src/stream/ctr/ctr.cpp b/src/stream/ctr/ctr.cpp index dc2f334a8..0de0b7b84 100644 --- a/src/stream/ctr/ctr.cpp +++ b/src/stream/ctr/ctr.cpp @@ -1,6 +1,6 @@ /* -* CTR-BE Mode Cipher -* (C) 1999-2009 Jack Lloyd +* Counter mode +* (C) 1999-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -15,15 +15,11 @@ namespace Botan { */ CTR_BE::CTR_BE(BlockCipher* ciph) : - StreamCipher(ciph->MINIMUM_KEYLENGTH, - ciph->MAXIMUM_KEYLENGTH, - ciph->KEYLENGTH_MULTIPLE), - permutation(ciph) + permutation(ciph), + counter(256 * permutation->block_size()), + buffer(counter.size()), + position(0) { - position = 0; - - counter.resize(permutation->parallel_bytes()); - buffer.resize(counter.size()); } /* @@ -95,20 +91,18 @@ void CTR_BE::set_iv(const byte iv[], size_t iv_len) counter.copy(0, iv, iv_len); - const size_t PARALLEL_BLOCKS = counter.size() / BLOCK_SIZE; - - for(size_t i = 1; i != PARALLEL_BLOCKS; ++i) + for(size_t i = 1; i != 256; ++i) { counter.copy(i*BLOCK_SIZE, &counter[(i-1)*BLOCK_SIZE], BLOCK_SIZE); - for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) - if(++counter[i*BLOCK_SIZE+j]) + for(u32bit j = 0; j != BLOCK_SIZE; ++j) + if(++counter[i*BLOCK_SIZE + (BLOCK_SIZE-1-j)]) break; } - permutation->encrypt_n(&counter[0], &buffer[0], PARALLEL_BLOCKS); + permutation->encrypt_n(&counter[0], &buffer[0], 256); position = 0; } @@ -118,24 +112,15 @@ void CTR_BE::set_iv(const byte iv[], size_t iv_len) void CTR_BE::increment_counter() { const size_t BLOCK_SIZE = permutation->block_size(); - const size_t PARALLEL_BLOCKS = counter.size() / BLOCK_SIZE; - for(size_t i = 0; i != PARALLEL_BLOCKS; ++i) + for(size_t i = 0; i != 256; ++i) { - byte* this_ctr = &counter[i * BLOCK_SIZE]; - - byte last_byte = this_ctr[BLOCK_SIZE-1]; - last_byte += PARALLEL_BLOCKS; - - if(this_ctr[BLOCK_SIZE-1] > last_byte) - for(s32bit j = BLOCK_SIZE - 2; j >= 0; --j) - if(++this_ctr[j]) - break; - - this_ctr[BLOCK_SIZE-1] = last_byte; + for(u32bit j = 1; j != BLOCK_SIZE; ++j) + if(++counter[i*BLOCK_SIZE + (BLOCK_SIZE-1-j)]) + break; } - permutation->encrypt_n(&counter[0], &buffer[0], PARALLEL_BLOCKS); + permutation->encrypt_n(&counter[0], &buffer[0], 256); position = 0; } diff --git a/src/stream/ctr/ctr.h b/src/stream/ctr/ctr.h index e62ab2860..64b43b0f5 100644 --- a/src/stream/ctr/ctr.h +++ b/src/stream/ctr/ctr.h @@ -26,6 +26,11 @@ class BOTAN_DLL CTR_BE : public StreamCipher bool valid_iv_length(size_t iv_len) const { return (iv_len <= permutation->block_size()); } + Key_Length_Specification key_spec() const + { + return permutation->key_spec(); + } + std::string name() const; CTR_BE* clone() const diff --git a/src/stream/info.txt b/src/stream/info.txt index 68d6c46d6..c242b47e7 100644 --- a/src/stream/info.txt +++ b/src/stream/info.txt @@ -1,5 +1,5 @@ define STREAM_CIPHER <requires> -sym_algo +algo_base </requires> diff --git a/src/stream/ofb/ofb.cpp b/src/stream/ofb/ofb.cpp index 1f25c5c14..382a2b4dd 100644 --- a/src/stream/ofb/ofb.cpp +++ b/src/stream/ofb/ofb.cpp @@ -14,11 +14,7 @@ namespace Botan { /* * OFB Constructor */ -OFB::OFB(BlockCipher* ciph) : - StreamCipher(ciph->MINIMUM_KEYLENGTH, - ciph->MAXIMUM_KEYLENGTH, - ciph->KEYLENGTH_MULTIPLE), - permutation(ciph) +OFB::OFB(BlockCipher* ciph) : permutation(ciph) { position = 0; buffer.resize(permutation->block_size()); diff --git a/src/stream/ofb/ofb.h b/src/stream/ofb/ofb.h index 587a30bab..c4d8b2601 100644 --- a/src/stream/ofb/ofb.h +++ b/src/stream/ofb/ofb.h @@ -26,6 +26,11 @@ class BOTAN_DLL OFB : public StreamCipher bool valid_iv_length(size_t iv_len) const { return (iv_len <= permutation->block_size()); } + Key_Length_Specification key_spec() const + { + return permutation->key_spec(); + } + std::string name() const; OFB* clone() const diff --git a/src/stream/salsa20/salsa20.h b/src/stream/salsa20/salsa20.h index 213cb1117..d9645015f 100644 --- a/src/stream/salsa20/salsa20.h +++ b/src/stream/salsa20/salsa20.h @@ -25,14 +25,16 @@ class BOTAN_DLL Salsa20 : public StreamCipher bool valid_iv_length(size_t iv_len) const { return (iv_len == 8 || iv_len == 24); } + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(16, 32, 16); + } + void clear(); std::string name() const; StreamCipher* clone() const { return new Salsa20; } - Salsa20() : StreamCipher(16, 32, 16), state(16), buffer(64) - { position = 0; } - - ~Salsa20() { clear(); } + Salsa20() : state(16), buffer(64), position(0) {} private: void key_schedule(const byte key[], size_t key_len); diff --git a/src/stream/stream_cipher.h b/src/stream/stream_cipher.h index 680d57f70..301e71f07 100644 --- a/src/stream/stream_cipher.h +++ b/src/stream/stream_cipher.h @@ -51,24 +51,6 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm * Get a new object representing the same algorithm as *this */ virtual StreamCipher* clone() const = 0; - - /** - * Zeroize internal state - */ - virtual void clear() = 0; - - /** - * StreamCipher constructor - * @param key_min the minimum key size - * @param key_max the maximum key size - * @param key_mod the modulo restriction on the key size - */ - StreamCipher(size_t key_min, - size_t key_max = 0, - size_t key_mod = 1) : - SymmetricAlgorithm(key_min, key_max, key_mod) {} - - virtual ~StreamCipher() {} }; } diff --git a/src/stream/turing/turing.cpp b/src/stream/turing/turing.cpp index 82e3aa2bb..619ef6682 100644 --- a/src/stream/turing/turing.cpp +++ b/src/stream/turing/turing.cpp @@ -210,13 +210,26 @@ void Turing::generate() */ u32bit Turing::fixedS(u32bit W) { - for(size_t i = 0; i != 4; ++i) - { - byte B = SBOX[get_byte(i, W)]; - W ^= rotate_left(Q_BOX[B], i*8); - W &= rotate_right(0x00FFFFFF, i*8); - W |= B << (24-i*8); - } + byte B = SBOX[get_byte(0, W)]; + W ^= Q_BOX[B]; + W &= 0x00FFFFFF; + W |= B << 24; + + B = SBOX[get_byte(1, W)]; + W ^= rotate_left(Q_BOX[B], 8); + W &= 0xFF00FFFF; + W |= B << 16; + + B = SBOX[get_byte(2, W)]; + W ^= rotate_left(Q_BOX[B], 16); + W &= 0xFFFF00FF; + W |= B << 8; + + B = SBOX[get_byte(3, W)]; + W ^= rotate_left(Q_BOX[B], 24); + W &= 0xFFFFFF00; + W |= B; + return W; } diff --git a/src/stream/turing/turing.h b/src/stream/turing/turing.h index adfabc0f1..aff314080 100644 --- a/src/stream/turing/turing.h +++ b/src/stream/turing/turing.h @@ -24,14 +24,17 @@ class BOTAN_DLL Turing : public StreamCipher bool valid_iv_length(size_t iv_len) const { return (iv_len % 4 == 0 && iv_len <= 16); } + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(4, 32, 4); + } + void clear(); std::string name() const { return "Turing"; } StreamCipher* clone() const { return new Turing; } - Turing() : StreamCipher(4, 32, 4), - S0(256), S1(256), S2(256), S3(256), - R(17), buffer(340) - { position = 0; } + Turing() : S0(256), S1(256), S2(256), S3(256), + R(17), buffer(340), position(0) {} private: void key_schedule(const byte[], size_t); diff --git a/src/stream/wid_wake/wid_wake.h b/src/stream/wid_wake/wid_wake.h index 17e77d5b5..05842a574 100644 --- a/src/stream/wid_wake/wid_wake.h +++ b/src/stream/wid_wake/wid_wake.h @@ -27,14 +27,18 @@ class BOTAN_DLL WiderWake_41_BE : public StreamCipher bool valid_iv_length(size_t iv_len) const { return (iv_len == 8); } + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(16); + } + void clear(); std::string name() const { return "WiderWake4+1-BE"; } StreamCipher* clone() const { return new WiderWake_41_BE; } - WiderWake_41_BE() : StreamCipher(16, 16, 1), - T(256), state(5), t_key(4), + WiderWake_41_BE() : T(256), state(5), t_key(4), buffer(DEFAULT_BUFFERSIZE), position(0) - { } + {} private: void key_schedule(const byte[], size_t); diff --git a/src/utils/buf_comp/info.txt b/src/utils/buf_comp/info.txt deleted file mode 100644 index b91fe5082..000000000 --- a/src/utils/buf_comp/info.txt +++ /dev/null @@ -1,3 +0,0 @@ -<requires> -alloc -</requires> diff --git a/src/utils/dyn_load/dyn_load.h b/src/utils/dyn_load/dyn_load.h index c8fb31cf0..b37a52e84 100644 --- a/src/utils/dyn_load/dyn_load.h +++ b/src/utils/dyn_load/dyn_load.h @@ -1,4 +1,4 @@ -/** +/* * Dynamically Loaded Object * (C) 2010 Jack Lloyd * @@ -12,6 +12,9 @@ namespace Botan { +/** +* Represents a DLL or shared object +*/ class Dynamically_Loaded_Library { public: diff --git a/src/utils/rotate.h b/src/utils/rotate.h index 5e3eef304..465746e0b 100644 --- a/src/utils/rotate.h +++ b/src/utils/rotate.h @@ -12,14 +12,23 @@ namespace Botan { -/* -* Word Rotation Functions +/** +* Bit rotation left +* @param input the input word +* @param rot the number of bits to rotate +* @return input rotated left by rot bits */ template<typename T> inline T rotate_left(T input, size_t rot) { return static_cast<T>((input << rot) | (input >> (8*sizeof(T)-rot)));; } +/** +* Bit rotation right +* @param input the input word +* @param rot the number of bits to rotate +* @return input rotated right by rot bits +*/ template<typename T> inline T rotate_right(T input, size_t rot) { return static_cast<T>((input >> rot) | (input << (8*sizeof(T)-rot))); diff --git a/src/utils/stl_util.h b/src/utils/stl_util.h index 0d672fc50..0eb078244 100644 --- a/src/utils/stl_util.h +++ b/src/utils/stl_util.h @@ -14,6 +14,10 @@ namespace Botan { /* * Searching through a std::map +* @param mapping the map to search +* @param key is what to look for +* @param null_result is the value to return if key is not in mapping +* @return mapping[key] or null_result */ template<typename K, typename V> inline V search_map(const std::map<K, V>& mapping, |