aboutsummaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/allocate.h35
-rw-r--r--src/core/base.cpp199
-rw-r--r--src/core/base.h146
-rw-r--r--src/core/botan.h11
-rw-r--r--src/core/data_src.cpp203
-rw-r--r--src/core/data_src.h78
-rw-r--r--src/core/def_powm.cpp22
-rw-r--r--src/core/defalloc.cpp98
-rw-r--r--src/core/defalloc.h41
-rw-r--r--src/core/eng_def.h46
-rw-r--r--src/core/enums.h69
-rw-r--r--src/core/exceptn.cpp60
-rw-r--r--src/core/exceptn.h195
-rw-r--r--src/core/info.txt45
-rw-r--r--src/core/kdf.cpp66
-rw-r--r--src/core/kdf.h50
-rw-r--r--src/core/libstate/def_alg.cpp650
-rw-r--r--src/core/libstate/def_mode.cpp177
-rw-r--r--src/core/libstate/eng_base.cpp326
-rw-r--r--src/core/libstate/engine.cpp420
-rw-r--r--src/core/libstate/engine.h140
-rw-r--r--src/core/libstate/get_enc.cpp228
-rw-r--r--src/core/libstate/get_pbe.cpp87
-rw-r--r--src/core/libstate/get_pbe.h22
-rw-r--r--src/core/libstate/info.txt31
-rw-r--r--src/core/libstate/init.h50
-rw-r--r--src/core/libstate/init_def.cpp60
-rw-r--r--src/core/libstate/init_opt.cpp102
-rw-r--r--src/core/libstate/libstate.cpp294
-rw-r--r--src/core/libstate/libstate.h90
-rw-r--r--src/core/libstate/look_add.h28
-rw-r--r--src/core/libstate/look_pk.cpp74
-rw-r--r--src/core/libstate/look_pk.h38
-rw-r--r--src/core/libstate/lookup.cpp239
-rw-r--r--src/core/libstate/lookup.h98
-rw-r--r--src/core/libstate/modules.cpp126
-rw-r--r--src/core/libstate/modules.h54
-rw-r--r--src/core/libstate/oids.cpp74
-rw-r--r--src/core/libstate/oids.h36
-rw-r--r--src/core/libstate/policy.cpp492
-rw-r--r--src/core/mem_pool.cpp260
-rw-r--r--src/core/mem_pool.h74
-rw-r--r--src/core/mutex.h54
-rw-r--r--src/core/pk_pad.cpp48
-rw-r--r--src/core/pk_pad.h58
-rw-r--r--src/core/rng.cpp149
-rw-r--r--src/core/rng.h66
-rw-r--r--src/core/s2k.cpp53
-rw-r--r--src/core/s2k.h45
-rw-r--r--src/core/secmem.h217
-rw-r--r--src/core/selftest/info.txt24
-rw-r--r--src/core/selftest/selftest.cpp163
-rw-r--r--src/core/selftest/selftest.h20
-rw-r--r--src/core/symkey.cpp139
-rw-r--r--src/core/symkey.h60
55 files changed, 6730 insertions, 0 deletions
diff --git a/src/core/allocate.h b/src/core/allocate.h
new file mode 100644
index 000000000..efbb77291
--- /dev/null
+++ b/src/core/allocate.h
@@ -0,0 +1,35 @@
+/*************************************************
+* Allocator Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_ALLOCATOR_H__
+#define BOTAN_ALLOCATOR_H__
+
+#include <botan/types.h>
+#include <string>
+
+namespace Botan {
+
+/*************************************************
+* Allocator Interface *
+*************************************************/
+class BOTAN_DLL Allocator
+ {
+ public:
+ static Allocator* get(bool);
+
+ virtual void* allocate(u32bit) = 0;
+ virtual void deallocate(void*, u32bit) = 0;
+
+ virtual std::string type() const = 0;
+
+ virtual void init() {}
+ virtual void destroy() {}
+
+ virtual ~Allocator() {}
+ };
+
+}
+
+#endif
diff --git a/src/core/base.cpp b/src/core/base.cpp
new file mode 100644
index 000000000..eb38d0c85
--- /dev/null
+++ b/src/core/base.cpp
@@ -0,0 +1,199 @@
+/*************************************************
+* Base Classes Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/base.h>
+#include <botan/version.h>
+
+namespace Botan {
+
+/*************************************************
+* SymmetricAlgorithm Constructor *
+*************************************************/
+SymmetricAlgorithm::SymmetricAlgorithm(u32bit key_min, u32bit key_max,
+ u32bit key_mod) :
+ MAXIMUM_KEYLENGTH(key_max ? key_max : key_min),
+ MINIMUM_KEYLENGTH(key_min),
+ KEYLENGTH_MULTIPLE(key_mod)
+ {
+ }
+
+/*************************************************
+* Query if the keylength is valid *
+*************************************************/
+bool SymmetricAlgorithm::valid_keylength(u32bit length) const
+ {
+ return ((length >= MINIMUM_KEYLENGTH) &&
+ (length <= MAXIMUM_KEYLENGTH) &&
+ (length % KEYLENGTH_MULTIPLE == 0));
+ }
+
+/*************************************************
+* Set the key *
+*************************************************/
+void SymmetricAlgorithm::set_key(const SymmetricKey& algo_key)
+ throw(Invalid_Key_Length)
+ {
+ set_key(algo_key.begin(), algo_key.length());
+ }
+
+/*************************************************
+* Set the key *
+*************************************************/
+void SymmetricAlgorithm::set_key(const byte algo_key[], u32bit length)
+ throw(Invalid_Key_Length)
+ {
+ if(!valid_keylength(length))
+ throw Invalid_Key_Length(name(), length);
+ key(algo_key, length);
+ }
+
+/*************************************************
+* BlockCipher Constructor *
+*************************************************/
+BlockCipher::BlockCipher(u32bit block, u32bit key_min, u32bit key_max,
+ u32bit key_mod) :
+ SymmetricAlgorithm(key_min, key_max, key_mod),
+ BLOCK_SIZE(block)
+ {
+ }
+
+/*************************************************
+* StreamCipher Constructor *
+*************************************************/
+StreamCipher::StreamCipher(u32bit key_min, u32bit key_max, u32bit key_mod,
+ u32bit iv_len) :
+ SymmetricAlgorithm(key_min, key_max, key_mod), IV_LENGTH(iv_len)
+ {
+ }
+
+/*************************************************
+* BufferedComputation Constructor *
+*************************************************/
+BufferedComputation::BufferedComputation(u32bit olen) : OUTPUT_LENGTH(olen)
+ {
+ }
+
+/*************************************************
+* HashFunction Constructor *
+*************************************************/
+HashFunction::HashFunction(u32bit hlen, u32bit blen) :
+ BufferedComputation(hlen), HASH_BLOCK_SIZE(blen)
+ {
+ }
+
+/*************************************************
+* MessageAuthenticationCode Constructor *
+*************************************************/
+MessageAuthenticationCode::MessageAuthenticationCode(u32bit mlen,
+ u32bit key_min,
+ u32bit key_max,
+ u32bit key_mod) :
+ BufferedComputation(mlen),
+ SymmetricAlgorithm(key_min, key_max, key_mod)
+ {
+ }
+
+/*************************************************
+* Default MAC verification operation *
+*************************************************/
+bool MessageAuthenticationCode::verify_mac(const byte mac[], u32bit length)
+ {
+ SecureVector<byte> our_mac = final();
+ if(our_mac.size() != length)
+ return false;
+ for(u32bit j = 0; j != length; ++j)
+ if(mac[j] != our_mac[j])
+ return false;
+ return true;
+ }
+
+/*************************************************
+* Default StreamCipher Resync Operation *
+*************************************************/
+void StreamCipher::resync(const byte[], u32bit length)
+ {
+ if(length)
+ throw Exception("The stream cipher " + name() +
+ " does not support resyncronization");
+ }
+
+/*************************************************
+* Default StreamCipher Seek Operation *
+*************************************************/
+void StreamCipher::seek(u32bit)
+ {
+ throw Exception("The stream cipher " + name() + " does not support seek()");
+ }
+
+/*************************************************
+* Hashing/MACing *
+*************************************************/
+void BufferedComputation::update(const byte in[], u32bit n)
+ {
+ add_data(in, n);
+ }
+
+/*************************************************
+* Hashing/MACing *
+*************************************************/
+void BufferedComputation::update(const MemoryRegion<byte>& in)
+ {
+ add_data(in, in.size());
+ }
+
+/*************************************************
+* Hashing/MACing *
+*************************************************/
+void BufferedComputation::update(const std::string& str)
+ {
+ update(reinterpret_cast<const byte*>(str.data()), str.size());
+ }
+
+/*************************************************
+* Hashing/MACing *
+*************************************************/
+void BufferedComputation::update(byte in)
+ {
+ update(&in, 1);
+ }
+
+/*************************************************
+* Hashing/MACing *
+*************************************************/
+SecureVector<byte> BufferedComputation::final()
+ {
+ SecureVector<byte> output(OUTPUT_LENGTH);
+ final_result(output);
+ return output;
+ }
+
+/*************************************************
+* Hashing/MACing *
+*************************************************/
+SecureVector<byte> BufferedComputation::process(const byte in[], u32bit len)
+ {
+ update(in, len);
+ return final();
+ }
+
+/*************************************************
+* Hashing/MACing *
+*************************************************/
+SecureVector<byte> BufferedComputation::process(const MemoryRegion<byte>& in)
+ {
+ update(in, in.size());
+ return final();
+ }
+
+/*************************************************
+* Hashing/MACing *
+*************************************************/
+SecureVector<byte> BufferedComputation::process(const std::string& in)
+ {
+ update(in);
+ return final();
+ }
+
+}
diff --git a/src/core/base.h b/src/core/base.h
new file mode 100644
index 000000000..b05feaacb
--- /dev/null
+++ b/src/core/base.h
@@ -0,0 +1,146 @@
+/*************************************************
+* Base Classes Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_BASE_H__
+#define BOTAN_BASE_H__
+
+#include <botan/exceptn.h>
+#include <botan/symkey.h>
+
+namespace Botan {
+
+/*************************************************
+* Constants *
+*************************************************/
+static const u32bit DEFAULT_BUFFERSIZE = BOTAN_DEFAULT_BUFFER_SIZE;
+
+/*************************************************
+* Symmetric Algorithm *
+*************************************************/
+class BOTAN_DLL SymmetricAlgorithm
+ {
+ public:
+ const u32bit MAXIMUM_KEYLENGTH, MINIMUM_KEYLENGTH, KEYLENGTH_MULTIPLE;
+
+ virtual std::string name() const = 0;
+
+ void set_key(const SymmetricKey&) throw(Invalid_Key_Length);
+ void set_key(const byte[], u32bit) throw(Invalid_Key_Length);
+ bool valid_keylength(u32bit) const;
+ SymmetricAlgorithm(u32bit, u32bit, u32bit);
+ virtual ~SymmetricAlgorithm() {}
+ private:
+ virtual void key(const byte[], u32bit) = 0;
+ };
+
+/*************************************************
+* Block Cipher *
+*************************************************/
+class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
+ {
+ public:
+ const u32bit BLOCK_SIZE;
+
+ void encrypt(const byte in[], byte out[]) const { enc(in, out); }
+ void decrypt(const byte in[], byte out[]) const { dec(in, out); }
+ void encrypt(byte block[]) const { enc(block, block); }
+ void decrypt(byte block[]) const { dec(block, block); }
+
+ virtual BlockCipher* clone() const = 0;
+ virtual void clear() throw() = 0;
+
+ BlockCipher(u32bit, u32bit, u32bit = 0, u32bit = 1);
+ virtual ~BlockCipher() {}
+ private:
+ virtual void enc(const byte[], byte[]) const = 0;
+ virtual void dec(const byte[], byte[]) const = 0;
+ };
+
+/*************************************************
+* Stream Cipher *
+*************************************************/
+class BOTAN_DLL StreamCipher : public SymmetricAlgorithm
+ {
+ public:
+ const u32bit IV_LENGTH;
+ void encrypt(const byte i[], byte o[], u32bit len) { cipher(i, o, len); }
+ void decrypt(const byte i[], byte o[], u32bit len) { cipher(i, o, len); }
+ void encrypt(byte in[], u32bit len) { cipher(in, in, len); }
+ void decrypt(byte in[], u32bit len) { cipher(in, in, len); }
+
+ virtual void resync(const byte[], u32bit);
+ virtual void seek(u32bit);
+
+ virtual StreamCipher* clone() const = 0;
+ virtual void clear() throw() = 0;
+
+ StreamCipher(u32bit, u32bit = 0, u32bit = 1, u32bit = 0);
+ virtual ~StreamCipher() {}
+ private:
+ virtual void cipher(const byte[], byte[], u32bit) = 0;
+ };
+
+/*************************************************
+* Buffered Computation *
+*************************************************/
+class BOTAN_DLL BufferedComputation
+ {
+ public:
+ const u32bit OUTPUT_LENGTH;
+ void update(const byte[], u32bit);
+ void update(const MemoryRegion<byte>&);
+ void update(const std::string&);
+ void update(byte);
+ void final(byte out[]) { final_result(out); }
+ SecureVector<byte> final();
+ SecureVector<byte> process(const byte[], u32bit);
+ SecureVector<byte> process(const MemoryRegion<byte>&);
+ SecureVector<byte> process(const std::string&);
+ BufferedComputation(u32bit);
+ virtual ~BufferedComputation() {}
+ private:
+ BufferedComputation& operator=(const BufferedComputation&);
+ virtual void add_data(const byte[], u32bit) = 0;
+ virtual void final_result(byte[]) = 0;
+ };
+
+/*************************************************
+* Hash Function *
+*************************************************/
+class BOTAN_DLL HashFunction : public BufferedComputation
+ {
+ public:
+ const u32bit HASH_BLOCK_SIZE;
+
+ virtual HashFunction* clone() const = 0;
+ virtual std::string name() const = 0;
+ virtual void clear() throw() = 0;
+
+ HashFunction(u32bit, u32bit = 0);
+ virtual ~HashFunction() {}
+ private:
+ HashFunction& operator=(const HashFunction&);
+ };
+
+/*************************************************
+* Message Authentication Code *
+*************************************************/
+class BOTAN_DLL MessageAuthenticationCode : public BufferedComputation,
+ public SymmetricAlgorithm
+ {
+ public:
+ virtual bool verify_mac(const byte[], u32bit);
+
+ virtual MessageAuthenticationCode* clone() const = 0;
+ virtual std::string name() const = 0;
+ virtual void clear() throw() = 0;
+
+ MessageAuthenticationCode(u32bit, u32bit, u32bit = 0, u32bit = 1);
+ virtual ~MessageAuthenticationCode() {}
+ };
+
+}
+
+#endif
diff --git a/src/core/botan.h b/src/core/botan.h
new file mode 100644
index 000000000..70261398a
--- /dev/null
+++ b/src/core/botan.h
@@ -0,0 +1,11 @@
+/*************************************************
+* Botan Core Interface Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/base.h>
+#include <botan/rng.h>
+#include <botan/init.h>
+#include <botan/lookup.h>
+#include <botan/version.h>
+#include <botan/parsing.h>
diff --git a/src/core/data_src.cpp b/src/core/data_src.cpp
new file mode 100644
index 000000000..1ec1ae090
--- /dev/null
+++ b/src/core/data_src.cpp
@@ -0,0 +1,203 @@
+/*************************************************
+* DataSource Source File *
+* (C) 1999-2007 Jack Lloyd *
+* 2005 Matthew Gregan *
+*************************************************/
+
+#include <botan/data_src.h>
+#include <fstream>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* Read a single byte from the DataSource *
+*************************************************/
+u32bit DataSource::read_byte(byte& out)
+ {
+ return read(&out, 1);
+ }
+
+/*************************************************
+* Peek a single byte from the DataSource *
+*************************************************/
+u32bit DataSource::peek_byte(byte& out) const
+ {
+ return peek(&out, 1, 0);
+ }
+
+/*************************************************
+* Discard the next N bytes of the data *
+*************************************************/
+u32bit DataSource::discard_next(u32bit n)
+ {
+ u32bit discarded = 0;
+ byte dummy;
+ for(u32bit j = 0; j != n; ++j)
+ discarded = read_byte(dummy);
+ return discarded;
+ }
+
+/*************************************************
+* Read from a memory buffer *
+*************************************************/
+u32bit DataSource_Memory::read(byte out[], u32bit length)
+ {
+ u32bit got = std::min(source.size() - offset, length);
+ copy_mem(out, source + offset, got);
+ offset += got;
+ return got;
+ }
+
+/*************************************************
+* Peek into a memory buffer *
+*************************************************/
+u32bit DataSource_Memory::peek(byte out[], u32bit length,
+ u32bit peek_offset) const
+ {
+ const u32bit bytes_left = source.size() - offset;
+ if(peek_offset >= bytes_left) return 0;
+
+ u32bit got = std::min(bytes_left - peek_offset, length);
+ copy_mem(out, source + offset + peek_offset, got);
+ return got;
+ }
+
+/*************************************************
+* Check if the memory buffer is empty *
+*************************************************/
+bool DataSource_Memory::end_of_data() const
+ {
+ return (offset == source.size());
+ }
+
+/*************************************************
+* DataSource_Memory Constructor *
+*************************************************/
+DataSource_Memory::DataSource_Memory(const byte in[], u32bit length)
+ {
+ source.set(in, length);
+ offset = 0;
+ }
+
+/*************************************************
+* DataSource_Memory Constructor *
+*************************************************/
+DataSource_Memory::DataSource_Memory(const MemoryRegion<byte>& in)
+ {
+ source = in;
+ offset = 0;
+ }
+
+/*************************************************
+* DataSource_Memory Constructor *
+*************************************************/
+DataSource_Memory::DataSource_Memory(const std::string& in)
+ {
+ source.set(reinterpret_cast<const byte*>(in.data()), in.length());
+ offset = 0;
+ }
+
+/*************************************************
+* Read from a stream *
+*************************************************/
+u32bit DataSource_Stream::read(byte out[], u32bit length)
+ {
+ source->read(reinterpret_cast<char*>(out), length);
+ if(source->bad())
+ throw Stream_IO_Error("DataSource_Stream::read: Source failure");
+
+ u32bit got = source->gcount();
+ total_read += got;
+ return got;
+ }
+
+/*************************************************
+* Peek into a stream *
+*************************************************/
+u32bit DataSource_Stream::peek(byte out[], u32bit length, u32bit offset) const
+ {
+ if(end_of_data())
+ throw Invalid_State("DataSource_Stream: Cannot peek when out of data");
+
+ u32bit got = 0;
+
+ if(offset)
+ {
+ SecureVector<byte> buf(offset);
+ source->read(reinterpret_cast<char*>(buf.begin()), buf.size());
+ if(source->bad())
+ throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
+ got = source->gcount();
+ }
+
+ if(got == offset)
+ {
+ source->read(reinterpret_cast<char*>(out), length);
+ if(source->bad())
+ throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
+ got = source->gcount();
+ }
+
+ if(source->eof())
+ source->clear();
+ source->seekg(total_read, std::ios::beg);
+
+ return got;
+ }
+
+/*************************************************
+* Check if the stream is empty or in error *
+*************************************************/
+bool DataSource_Stream::end_of_data() const
+ {
+ return (!source->good());
+ }
+
+/*************************************************
+* Return a human-readable ID for this stream *
+*************************************************/
+std::string DataSource_Stream::id() const
+ {
+ return identifier;
+ }
+
+/*************************************************
+* DataSource_Stream Constructor *
+*************************************************/
+DataSource_Stream::DataSource_Stream(const std::string& path,
+ bool use_binary) :
+ identifier(path), owner(true)
+ {
+ if(use_binary)
+ source = new std::ifstream(path.c_str(), std::ios::binary);
+ else
+ source = new std::ifstream(path.c_str());
+
+ if(!source->good())
+ throw Stream_IO_Error("DataSource: Failure opening file " + path);
+
+ total_read = 0;
+ }
+
+/*************************************************
+* DataSource_Stream Constructor *
+*************************************************/
+DataSource_Stream::DataSource_Stream(std::istream& in,
+ const std::string& name) :
+ identifier(name), owner(false)
+ {
+ source = &in;
+ total_read = 0;
+ }
+
+/*************************************************
+* DataSource_Stream Destructor *
+*************************************************/
+DataSource_Stream::~DataSource_Stream()
+ {
+ if(owner)
+ delete source;
+ }
+
+}
diff --git a/src/core/data_src.h b/src/core/data_src.h
new file mode 100644
index 000000000..f7285e8fb
--- /dev/null
+++ b/src/core/data_src.h
@@ -0,0 +1,78 @@
+/*************************************************
+* DataSource Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_DATA_SRC_H__
+#define BOTAN_DATA_SRC_H__
+
+#include <botan/base.h>
+#include <iosfwd>
+
+namespace Botan {
+
+/*************************************************
+* Generic DataSource Interface *
+*************************************************/
+class BOTAN_DLL DataSource
+ {
+ public:
+ virtual u32bit read(byte[], u32bit) = 0;
+ virtual u32bit peek(byte[], u32bit, u32bit) const = 0;
+ virtual bool end_of_data() const = 0;
+ virtual std::string id() const { return ""; }
+
+ u32bit read_byte(byte&);
+ u32bit peek_byte(byte&) const;
+ u32bit discard_next(u32bit);
+
+ DataSource() {}
+ virtual ~DataSource() {}
+ private:
+ DataSource& operator=(const DataSource&) { return (*this); }
+ DataSource(const DataSource&);
+ };
+
+/*************************************************
+* Memory-Based DataSource *
+*************************************************/
+class BOTAN_DLL DataSource_Memory : public DataSource
+ {
+ public:
+ u32bit read(byte[], u32bit);
+ u32bit peek(byte[], u32bit, u32bit) const;
+ bool end_of_data() const;
+
+ DataSource_Memory(const std::string&);
+ DataSource_Memory(const byte[], u32bit);
+ DataSource_Memory(const MemoryRegion<byte>&);
+ private:
+ SecureVector<byte> source;
+ u32bit offset;
+ };
+
+/*************************************************
+* Stream-Based DataSource *
+*************************************************/
+class BOTAN_DLL DataSource_Stream : public DataSource
+ {
+ public:
+ u32bit read(byte[], u32bit);
+ u32bit peek(byte[], u32bit, u32bit) const;
+ bool end_of_data() const;
+ std::string id() const;
+
+ DataSource_Stream(std::istream&, const std::string& id = "");
+ DataSource_Stream(const std::string&, bool = false);
+ ~DataSource_Stream();
+ private:
+ const std::string identifier;
+ const bool owner;
+
+ std::istream* source;
+ u32bit total_read;
+ };
+
+}
+
+#endif
diff --git a/src/core/def_powm.cpp b/src/core/def_powm.cpp
new file mode 100644
index 000000000..a28438f5b
--- /dev/null
+++ b/src/core/def_powm.cpp
@@ -0,0 +1,22 @@
+/*************************************************
+* Modular Exponentiation Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/eng_def.h>
+#include <botan/def_powm.h>
+
+namespace Botan {
+
+/*************************************************
+* Choose a modular exponentation algorithm *
+*************************************************/
+Modular_Exponentiator*
+Default_Engine::mod_exp(const BigInt& n, Power_Mod::Usage_Hints hints) const
+ {
+ if(n.is_odd())
+ return new Montgomery_Exponentiator(n, hints);
+ return new Fixed_Window_Exponentiator(n, hints);
+ }
+
+}
diff --git a/src/core/defalloc.cpp b/src/core/defalloc.cpp
new file mode 100644
index 000000000..5fb8e1447
--- /dev/null
+++ b/src/core/defalloc.cpp
@@ -0,0 +1,98 @@
+/*************************************************
+* Basic Allocators Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/defalloc.h>
+#include <botan/libstate.h>
+#include <botan/util.h>
+#include <cstdlib>
+#include <cstring>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Perform Memory Allocation *
+*************************************************/
+void* do_malloc(u32bit n, bool do_lock)
+ {
+ void* ptr = std::malloc(n);
+
+ if(!ptr)
+ return 0;
+
+ if(do_lock)
+ lock_mem(ptr, n);
+
+ std::memset(ptr, 0, n);
+ return ptr;
+ }
+
+/*************************************************
+* Perform Memory Deallocation *
+*************************************************/
+void do_free(void* ptr, u32bit n, bool do_lock)
+ {
+ if(!ptr)
+ return;
+
+ std::memset(ptr, 0, n);
+ if(do_lock)
+ unlock_mem(ptr, n);
+
+ std::free(ptr);
+ }
+
+}
+
+/*************************************************
+* Malloc_Allocator's Allocation *
+*************************************************/
+void* Malloc_Allocator::allocate(u32bit n)
+ {
+ return do_malloc(n, false);
+ }
+
+/*************************************************
+* Malloc_Allocator's Deallocation *
+*************************************************/
+void Malloc_Allocator::deallocate(void* ptr, u32bit n)
+ {
+ do_free(ptr, n, false);
+ }
+
+/*************************************************
+* Locking_Allocator's Allocation *
+*************************************************/
+void* Locking_Allocator::alloc_block(u32bit n)
+ {
+ return do_malloc(n, true);
+ }
+
+/*************************************************
+* Locking_Allocator's Deallocation *
+*************************************************/
+void Locking_Allocator::dealloc_block(void* ptr, u32bit n)
+ {
+ do_free(ptr, n, true);
+ }
+
+/*************************************************
+* Get an allocator *
+*************************************************/
+Allocator* Allocator::get(bool locking)
+ {
+ std::string type = "";
+ if(!locking)
+ type = "malloc";
+
+ Allocator* alloc = global_state().get_allocator(type);
+ if(alloc)
+ return alloc;
+
+ throw Exception("Couldn't find an allocator to use in get_allocator");
+ }
+
+}
diff --git a/src/core/defalloc.h b/src/core/defalloc.h
new file mode 100644
index 000000000..dc01ee47f
--- /dev/null
+++ b/src/core/defalloc.h
@@ -0,0 +1,41 @@
+/*************************************************
+* Basic Allocators Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_BASIC_ALLOC_H__
+#define BOTAN_BASIC_ALLOC_H__
+
+#include <botan/mem_pool.h>
+
+namespace Botan {
+
+/*************************************************
+* Malloc Allocator *
+*************************************************/
+class BOTAN_DLL Malloc_Allocator : public Allocator
+ {
+ public:
+ void* allocate(u32bit);
+ void deallocate(void*, u32bit);
+
+ std::string type() const { return "malloc"; }
+ };
+
+/*************************************************
+* Locking Allocator *
+*************************************************/
+class BOTAN_DLL Locking_Allocator : public Pooling_Allocator
+ {
+ public:
+ Locking_Allocator(Mutex* m) : Pooling_Allocator(m) {}
+
+ std::string type() const { return "locking"; }
+ private:
+ void* alloc_block(u32bit);
+ void dealloc_block(void*, u32bit);
+ };
+
+}
+
+#endif
diff --git a/src/core/eng_def.h b/src/core/eng_def.h
new file mode 100644
index 000000000..95f1fc0f7
--- /dev/null
+++ b/src/core/eng_def.h
@@ -0,0 +1,46 @@
+/*************************************************
+* Default Engine Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_DEFAULT_ENGINE_H__
+#define BOTAN_DEFAULT_ENGINE_H__
+
+#include <botan/engine.h>
+
+namespace Botan {
+
+/*************************************************
+* Default Engine *
+*************************************************/
+class BOTAN_DLL Default_Engine : public Engine
+ {
+ public:
+ IF_Operation* if_op(const BigInt&, const BigInt&, const BigInt&,
+ const BigInt&, const BigInt&, const BigInt&,
+ const BigInt&, const BigInt&) const;
+ DSA_Operation* dsa_op(const DL_Group&, const BigInt&,
+ const BigInt&) const;
+ NR_Operation* nr_op(const DL_Group&, const BigInt&, const BigInt&) const;
+ ELG_Operation* elg_op(const DL_Group&, const BigInt&,
+ const BigInt&) const;
+ DH_Operation* dh_op(const DL_Group&, const BigInt&) const;
+
+ Modular_Exponentiator* mod_exp(const BigInt&,
+ Power_Mod::Usage_Hints) const;
+
+ Keyed_Filter* get_cipher(const std::string&, Cipher_Dir);
+ private:
+ BlockCipher* find_block_cipher(const std::string&) const;
+ StreamCipher* find_stream_cipher(const std::string&) const;
+ HashFunction* find_hash(const std::string&) const;
+ MessageAuthenticationCode* find_mac(const std::string&) const;
+
+ class S2K* find_s2k(const std::string&) const;
+ class BlockCipherModePaddingMethod*
+ find_bc_pad(const std::string&) const;
+ };
+
+}
+
+#endif
diff --git a/src/core/enums.h b/src/core/enums.h
new file mode 100644
index 000000000..e083cdc01
--- /dev/null
+++ b/src/core/enums.h
@@ -0,0 +1,69 @@
+/*************************************************
+* Enumerations Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_ENUMS_H__
+#define BOTAN_ENUMS_H__
+
+#include <botan/types.h>
+
+namespace Botan {
+
+/*************************************************
+* X.509v3 Key Constraints *
+*************************************************/
+enum Key_Constraints {
+ NO_CONSTRAINTS = 0,
+ DIGITAL_SIGNATURE = 32768,
+ NON_REPUDIATION = 16384,
+ KEY_ENCIPHERMENT = 8192,
+ DATA_ENCIPHERMENT = 4096,
+ KEY_AGREEMENT = 2048,
+ KEY_CERT_SIGN = 1024,
+ CRL_SIGN = 512,
+ ENCIPHER_ONLY = 256,
+ DECIPHER_ONLY = 128
+};
+
+/*************************************************
+* X.509v2 CRL Reason Code *
+*************************************************/
+enum CRL_Code {
+ UNSPECIFIED = 0,
+ KEY_COMPROMISE = 1,
+ CA_COMPROMISE = 2,
+ AFFILIATION_CHANGED = 3,
+ SUPERSEDED = 4,
+ CESSATION_OF_OPERATION = 5,
+ CERTIFICATE_HOLD = 6,
+ REMOVE_FROM_CRL = 8,
+ PRIVLEDGE_WITHDRAWN = 9,
+ AA_COMPROMISE = 10,
+
+ DELETE_CRL_ENTRY = 0xFF00,
+ OCSP_GOOD = 0xFF01,
+ OCSP_UNKNOWN = 0xFF02
+};
+
+/*************************************************
+* Various Other Enumerations *
+*************************************************/
+enum Decoder_Checking { NONE, IGNORE_WS, FULL_CHECK };
+
+enum X509_Encoding { RAW_BER, PEM };
+
+enum Cipher_Dir { ENCRYPTION, DECRYPTION };
+
+enum Character_Set {
+ LOCAL_CHARSET,
+ UCS2_CHARSET,
+ UTF8_CHARSET,
+ LATIN1_CHARSET
+};
+
+static const u32bit NO_CERT_PATH_LIMIT = 0xFFFFFFF0;
+
+}
+
+#endif
diff --git a/src/core/exceptn.cpp b/src/core/exceptn.cpp
new file mode 100644
index 000000000..29357afa5
--- /dev/null
+++ b/src/core/exceptn.cpp
@@ -0,0 +1,60 @@
+/*************************************************
+* Exceptions Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/exceptn.h>
+#include <botan/parsing.h>
+
+namespace Botan {
+
+/*************************************************
+* Constructor for Invalid_Key_Length *
+*************************************************/
+Invalid_Key_Length::Invalid_Key_Length(const std::string& name, u32bit length)
+ {
+ set_msg(name + " cannot accept a key of length " + to_string(length));
+ }
+
+/*************************************************
+* Constructor for Invalid_Block_Size *
+*************************************************/
+Invalid_Block_Size::Invalid_Block_Size(const std::string& mode,
+ const std::string& pad)
+ {
+ set_msg("Padding method " + pad + " cannot be used with " + mode);
+ }
+
+/*************************************************
+* Constructor for Invalid_IV_Length *
+*************************************************/
+Invalid_IV_Length::Invalid_IV_Length(const std::string& mode, u32bit bad_len)
+ {
+ set_msg("IV length " + to_string(bad_len) + " is invalid for " + mode);
+ }
+
+/*************************************************
+* Constructor for Algorithm_Not_Found *
+*************************************************/
+Algorithm_Not_Found::Algorithm_Not_Found(const std::string& name)
+ {
+ set_msg("Could not find any algorithm named \"" + name + "\"");
+ }
+
+/*************************************************
+* Constructor for Invalid_Algorithm_Name *
+*************************************************/
+Invalid_Algorithm_Name::Invalid_Algorithm_Name(const std::string& name)
+ {
+ set_msg("Invalid algorithm name: " + name);
+ }
+
+/*************************************************
+* Constructor for Config_Error *
+*************************************************/
+Config_Error::Config_Error(const std::string& err, u32bit line)
+ {
+ set_msg("Config error at line " + to_string(line) + ": " + err);
+ }
+
+}
diff --git a/src/core/exceptn.h b/src/core/exceptn.h
new file mode 100644
index 000000000..3bfec2fd2
--- /dev/null
+++ b/src/core/exceptn.h
@@ -0,0 +1,195 @@
+/*************************************************
+* Exceptions Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_EXCEPTION_H__
+#define BOTAN_EXCEPTION_H__
+
+#include <botan/types.h>
+#include <exception>
+#include <string>
+
+namespace Botan {
+
+/*************************************************
+* Exception Base Class *
+*************************************************/
+class BOTAN_DLL Exception : public std::exception
+ {
+ public:
+ const char* what() const throw() { return msg.c_str(); }
+ Exception(const std::string& m = "Unknown error") { set_msg(m); }
+ virtual ~Exception() throw() {}
+ protected:
+ void set_msg(const std::string& m) { msg = "Botan: " + m; }
+ private:
+ std::string msg;
+ };
+
+/*************************************************
+* Invalid_Argument Exception *
+*************************************************/
+struct BOTAN_DLL Invalid_Argument : public Exception
+ {
+ Invalid_Argument(const std::string& err = "") : Exception(err) {}
+ };
+
+/*************************************************
+* Invalid_Key_Length Exception *
+*************************************************/
+struct BOTAN_DLL Invalid_Key_Length : public Invalid_Argument
+ {
+ Invalid_Key_Length(const std::string&, u32bit);
+ };
+
+/*************************************************
+* Invalid_Block_Size Exception *
+*************************************************/
+struct BOTAN_DLL Invalid_Block_Size : public Invalid_Argument
+ {
+ Invalid_Block_Size(const std::string&, const std::string&);
+ };
+
+/*************************************************
+* Invalid_IV_Length Exception *
+*************************************************/
+struct BOTAN_DLL Invalid_IV_Length : public Invalid_Argument
+ {
+ Invalid_IV_Length(const std::string&, u32bit);
+ };
+
+/*************************************************
+* Invalid_State Exception *
+*************************************************/
+struct BOTAN_DLL Invalid_State : public Exception
+ {
+ Invalid_State(const std::string& err) : Exception(err) {}
+ };
+
+/*************************************************
+* PRNG_Unseeded Exception *
+*************************************************/
+struct BOTAN_DLL PRNG_Unseeded : public Invalid_State
+ {
+ PRNG_Unseeded(const std::string& algo) :
+ Invalid_State("PRNG not seeded: " + algo) {}
+ };
+
+/*************************************************
+* Policy_Violation Exception *
+*************************************************/
+struct BOTAN_DLL Policy_Violation : public Invalid_State
+ {
+ Policy_Violation(const std::string& err) :
+ Invalid_State("Policy violation: " + err) {}
+ };
+
+/*************************************************
+* Lookup_Error Exception *
+*************************************************/
+struct BOTAN_DLL Lookup_Error : public Exception
+ {
+ Lookup_Error(const std::string& err) : Exception(err) {}
+ };
+
+/*************************************************
+* Algorithm_Not_Found Exception *
+*************************************************/
+struct BOTAN_DLL Algorithm_Not_Found : public Exception
+ {
+ Algorithm_Not_Found(const std::string&);
+ };
+
+/*************************************************
+* Format_Error Exception *
+*************************************************/
+struct BOTAN_DLL Format_Error : public Exception
+ {
+ Format_Error(const std::string& err = "") : Exception(err) {}
+ };
+
+/*************************************************
+* Invalid_Algorithm_Name Exception *
+*************************************************/
+struct BOTAN_DLL Invalid_Algorithm_Name : public Format_Error
+ {
+ Invalid_Algorithm_Name(const std::string&);
+ };
+
+/*************************************************
+* Encoding_Error Exception *
+*************************************************/
+struct BOTAN_DLL Encoding_Error : public Format_Error
+ {
+ Encoding_Error(const std::string& name) :
+ Format_Error("Encoding error: " + name) {}
+ };
+
+/*************************************************
+* Decoding_Error Exception *
+*************************************************/
+struct BOTAN_DLL Decoding_Error : public Format_Error
+ {
+ Decoding_Error(const std::string& name) :
+ Format_Error("Decoding error: " + name) {}
+ };
+
+/*************************************************
+* Invalid_OID Exception *
+*************************************************/
+struct BOTAN_DLL Invalid_OID : public Decoding_Error
+ {
+ Invalid_OID(const std::string& oid) :
+ Decoding_Error("Invalid ASN.1 OID: " + oid) {}
+ };
+
+/*************************************************
+* Stream_IO_Error Exception *
+*************************************************/
+struct BOTAN_DLL Stream_IO_Error : public Exception
+ {
+ Stream_IO_Error(const std::string& err) :
+ Exception("I/O error: " + err) {}
+ };
+
+/*************************************************
+* Configuration Error Exception *
+*************************************************/
+struct BOTAN_DLL Config_Error : public Format_Error
+ {
+ Config_Error(const std::string& err) :
+ Format_Error("Config error: " + err) {}
+ Config_Error(const std::string&, u32bit);
+ };
+
+/*************************************************
+* Integrity Failure Exception *
+*************************************************/
+struct BOTAN_DLL Integrity_Failure : public Exception
+ {
+ Integrity_Failure(const std::string& err) :
+ Exception("Integrity failure: " + err) {}
+ };
+
+/*************************************************
+* Internal_Error Exception *
+*************************************************/
+struct BOTAN_DLL Internal_Error : public Exception
+ {
+ Internal_Error(const std::string& err) :
+ Exception("Internal error: " + err) {}
+ };
+
+/*************************************************
+* Self Test Failure Exception *
+*************************************************/
+struct BOTAN_DLL Self_Test_Failure : public Internal_Error
+ {
+ Self_Test_Failure(const std::string& err) :
+ Internal_Error("Self test failed: " + err) {}
+ };
+
+}
+
+#endif
diff --git a/src/core/info.txt b/src/core/info.txt
new file mode 100644
index 000000000..9331d56dd
--- /dev/null
+++ b/src/core/info.txt
@@ -0,0 +1,45 @@
+realname "Botan Core Module"
+
+load_on auto
+
+define CORE_MODULE
+
+<requires>
+aes
+sha1
+sha2
+hmac
+filters
+libstate
+timer_base
+</requires>
+
+<add>
+allocate.h
+base.cpp
+base.h
+botan.h
+data_src.cpp
+data_src.h
+def_powm.cpp
+defalloc.cpp
+defalloc.h
+eng_def.h
+enums.h
+exceptn.cpp
+exceptn.h
+kdf.cpp
+kdf.h
+mem_pool.cpp
+mem_pool.h
+mutex.h
+pk_pad.cpp
+pk_pad.h
+rng.cpp
+rng.h
+s2k.cpp
+s2k.h
+secmem.h
+symkey.cpp
+symkey.h
+</add>
diff --git a/src/core/kdf.cpp b/src/core/kdf.cpp
new file mode 100644
index 000000000..a96f86e99
--- /dev/null
+++ b/src/core/kdf.cpp
@@ -0,0 +1,66 @@
+/*************************************************
+* KDF Base Class Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/kdf.h>
+
+namespace Botan {
+
+/*************************************************
+* Derive a key *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+ const MemoryRegion<byte>& secret,
+ const std::string& salt) const
+ {
+ return derive_key(key_len, secret, secret.size(),
+ reinterpret_cast<const byte*>(salt.data()),
+ salt.length());
+ }
+
+/*************************************************
+* Derive a key *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+ const MemoryRegion<byte>& secret,
+ const byte salt[], u32bit salt_len) const
+ {
+ return derive_key(key_len, secret.begin(), secret.size(),
+ salt, salt_len);
+ }
+
+/*************************************************
+* Derive a key *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+ const MemoryRegion<byte>& secret,
+ const MemoryRegion<byte>& salt) const
+ {
+ return derive_key(key_len, secret.begin(), secret.size(),
+ salt.begin(), salt.size());
+ }
+
+/*************************************************
+* Derive a key *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+ const byte secret[], u32bit secret_len,
+ const std::string& salt) const
+ {
+ return derive_key(key_len, secret, secret_len,
+ reinterpret_cast<const byte*>(salt.data()),
+ salt.length());
+ }
+
+/*************************************************
+* Derive a key *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+ const byte secret[], u32bit secret_len,
+ const byte salt[], u32bit salt_len) const
+ {
+ return derive(key_len, secret, secret_len, salt, salt_len);
+ }
+
+}
diff --git a/src/core/kdf.h b/src/core/kdf.h
new file mode 100644
index 000000000..7d0c1866b
--- /dev/null
+++ b/src/core/kdf.h
@@ -0,0 +1,50 @@
+/*************************************************
+* KDF/MGF Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_KDF_BASE_H__
+#define BOTAN_KDF_BASE_H__
+
+#include <botan/secmem.h>
+#include <botan/types.h>
+
+namespace Botan {
+
+/*************************************************
+* Key Derivation Function *
+*************************************************/
+class BOTAN_DLL KDF
+ {
+ public:
+ SecureVector<byte> derive_key(u32bit, const MemoryRegion<byte>&,
+ const std::string& = "") const;
+ SecureVector<byte> derive_key(u32bit, const MemoryRegion<byte>&,
+ const MemoryRegion<byte>&) const;
+ SecureVector<byte> derive_key(u32bit, const MemoryRegion<byte>&,
+ const byte[], u32bit) const;
+
+ SecureVector<byte> derive_key(u32bit, const byte[], u32bit,
+ const std::string& = "") const;
+ SecureVector<byte> derive_key(u32bit, const byte[], u32bit,
+ const byte[], u32bit) const;
+
+ virtual ~KDF() {}
+ private:
+ virtual SecureVector<byte> derive(u32bit, const byte[], u32bit,
+ const byte[], u32bit) const = 0;
+ };
+
+/*************************************************
+* Mask Generation Function *
+*************************************************/
+class BOTAN_DLL MGF
+ {
+ public:
+ virtual void mask(const byte[], u32bit, byte[], u32bit) const = 0;
+ virtual ~MGF() {}
+ };
+
+}
+
+#endif
diff --git a/src/core/libstate/def_alg.cpp b/src/core/libstate/def_alg.cpp
new file mode 100644
index 000000000..0445550f7
--- /dev/null
+++ b/src/core/libstate/def_alg.cpp
@@ -0,0 +1,650 @@
+/*************************************************
+* Default Engine Algorithms Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/eng_def.h>
+#include <botan/lookup.h>
+#include <botan/libstate.h>
+#include <botan/parsing.h>
+
+#if defined(BOTAN_HAS_AES)
+ #include <botan/aes.h>
+#endif
+
+#if defined(BOTAN_HAS_BLOWFISH)
+ #include <botan/blowfish.h>
+#endif
+
+#if defined(BOTAN_HAS_CAST)
+ #include <botan/cast128.h>
+ #include <botan/cast256.h>
+#endif
+
+#if defined(BOTAN_HAS_DES)
+ #include <botan/des.h>
+#endif
+
+#if defined(BOTAN_HAS_GOST)
+ #include <botan/gost.h>
+#endif
+
+#if defined(BOTAN_HAS_IDEA)
+ #include <botan/idea.h>
+#endif
+
+#if defined(BOTAN_HAS_KASUMI)
+ #include <botan/kasumi.h>
+#endif
+
+#if defined(BOTAN_HAS_LION)
+ #include <botan/lion.h>
+#endif
+
+#if defined(BOTAN_HAS_LUBY_RACKOFF)
+ #include <botan/lubyrack.h>
+#endif
+
+#if defined(BOTAN_HAS_MARS)
+ #include <botan/mars.h>
+#endif
+
+#if defined(BOTAN_HAS_MISTY1)
+ #include <botan/misty1.h>
+#endif
+
+#if defined(BOTAN_HAS_NOEKEON)
+ #include <botan/noekeon.h>
+#endif
+
+#if defined(BOTAN_HAS_RC2)
+ #include <botan/rc2.h>
+#endif
+
+#if defined(BOTAN_HAS_RC5)
+ #include <botan/rc5.h>
+#endif
+
+#if defined(BOTAN_HAS_RC6)
+ #include <botan/rc6.h>
+#endif
+
+#if defined(BOTAN_HAS_SAFER)
+ #include <botan/safer_sk.h>
+#endif
+
+#if defined(BOTAN_HAS_SEED)
+ #include <botan/seed.h>
+#endif
+
+#if defined(BOTAN_HAS_SERPENT)
+ #include <botan/serpent.h>
+#endif
+
+#if defined(BOTAN_HAS_SERPENT_IA32)
+ #include <botan/serp_ia32.h>
+#endif
+
+#if defined(BOTAN_HAS_SKIPJACK)
+ #include <botan/skipjack.h>
+#endif
+
+#if defined(BOTAN_HAS_SQUARE)
+ #include <botan/square.h>
+#endif
+
+#if defined(BOTAN_HAS_TEA)
+ #include <botan/tea.h>
+#endif
+
+#if defined(BOTAN_HAS_TWOFISH)
+ #include <botan/twofish.h>
+#endif
+
+#if defined(BOTAN_HAS_XTEA)
+ #include <botan/xtea.h>
+#endif
+
+#if defined(BOTAN_HAS_ARC4)
+ #include <botan/arc4.h>
+#endif
+
+#if defined(BOTAN_HAS_SALSA20)
+ #include <botan/salsa20.h>
+#endif
+
+#if defined(BOTAN_HAS_TURING)
+ #include <botan/turing.h>
+#endif
+
+#if defined(BOTAN_HAS_WID_WAKE)
+ #include <botan/wid_wake.h>
+#endif
+
+#if defined(BOTAN_HAS_CIPHER_MODE_PADDING)
+ #include <botan/mode_pad.h>
+#endif
+
+#if defined(BOTAN_HAS_ADLER32)
+ #include <botan/adler32.h>
+#endif
+
+#if defined(BOTAN_HAS_CRC24)
+ #include <botan/crc24.h>
+#endif
+
+#if defined(BOTAN_HAS_CRC32)
+ #include <botan/crc32.h>
+#endif
+
+#if defined(BOTAN_HAS_FORK_256)
+ #include <botan/fork256.h>
+#endif
+
+#if defined(BOTAN_HAS_HAS_160)
+ #include <botan/has160.h>
+#endif
+
+#if defined(BOTAN_HAS_MD2)
+ #include <botan/md2.h>
+#endif
+
+#if defined(BOTAN_HAS_MD4)
+ #include <botan/md4.h>
+#endif
+
+#if defined(BOTAN_HAS_MD4_IA32)
+ #include <botan/md4_ia32.h>
+#endif
+
+#if defined(BOTAN_HAS_MD5)
+ #include <botan/md5.h>
+#endif
+
+#if defined(BOTAN_HAS_MD5_IA32)
+ #include <botan/md5_ia32.h>
+#endif
+
+#if defined(BOTAN_HAS_RIPEMD_128)
+ #include <botan/rmd128.h>
+#endif
+
+#if defined(BOTAN_HAS_RIPEMD_160)
+ #include <botan/rmd160.h>
+#endif
+
+#if defined(BOTAN_HAS_SHA1)
+ #include <botan/sha160.h>
+#endif
+
+#if defined(BOTAN_HAS_SHA1_IA32)
+ #include <botan/sha1_ia32.h>
+#endif
+
+#if defined(BOTAN_HAS_SHA1_SSE2)
+ #include <botan/sha1_sse2.h>
+#endif
+
+#if defined(BOTAN_HAS_SHA1_AMD64)
+ #include <botan/sha1_amd64.h>
+#endif
+
+#if defined(BOTAN_HAS_SHA2)
+ #include <botan/sha256.h>
+ #include <botan/sha_64.h>
+#endif
+
+#if defined(BOTAN_HAS_TIGER)
+ #include <botan/tiger.h>
+#endif
+
+#if defined(BOTAN_HAS_WHIRLPOOL)
+ #include <botan/whrlpool.h>
+#endif
+
+#if defined(BOTAN_HAS_PARALLEL_HASH)
+ #include <botan/par_hash.h>
+#endif
+
+#if defined(BOTAN_HAS_CBC_MAC)
+ #include <botan/cbc_mac.h>
+#endif
+
+#if defined(BOTAN_HAS_CMAC)
+ #include <botan/cmac.h>
+#endif
+
+#if defined(BOTAN_HAS_HMAC)
+ #include <botan/hmac.h>
+#endif
+
+#if defined(BOTAN_HAS_SSL3_MAC)
+ #include <botan/ssl3_mac.h>
+#endif
+
+#if defined(BOTAN_HAS_ANSI_X919_MAC)
+ #include <botan/x919_mac.h>
+#endif
+
+#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 {
+
+/*************************************************
+* Some macros to simplify control flow *
+*************************************************/
+#define HANDLE_TYPE_NO_ARGS(NAME, TYPE) \
+ if(algo_name == NAME) \
+ { \
+ if(name.size() == 1) \
+ return new TYPE; \
+ throw Invalid_Algorithm_Name(algo_spec); \
+ }
+
+#define HANDLE_TYPE_ONE_U32BIT(NAME, TYPE, DEFAULT) \
+ if(algo_name == NAME) \
+ { \
+ if(name.size() == 1) \
+ return new TYPE(DEFAULT); \
+ if(name.size() == 2) \
+ return new TYPE(to_u32bit(name[1])); \
+ throw Invalid_Algorithm_Name(algo_spec); \
+ }
+
+#define HANDLE_TYPE_TWO_U32BIT(NAME, TYPE, DEFAULT) \
+ if(algo_name == NAME) \
+ { \
+ if(name.size() == 1) \
+ return new TYPE(DEFAULT); \
+ if(name.size() == 2) \
+ return new TYPE(to_u32bit(name[1])); \
+ if(name.size() == 3) \
+ return new TYPE(to_u32bit(name[1]), to_u32bit(name[2])); \
+ throw Invalid_Algorithm_Name(algo_spec); \
+ }
+
+#define HANDLE_TYPE_ONE_STRING(NAME, TYPE) \
+ if(algo_name == NAME) \
+ { \
+ if(name.size() == 2) \
+ return new TYPE(name[1]); \
+ throw Invalid_Algorithm_Name(algo_spec); \
+ }
+
+/*************************************************
+* Look for an algorithm with this name *
+*************************************************/
+BlockCipher*
+Default_Engine::find_block_cipher(const std::string& algo_spec) const
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ if(name.empty())
+ return 0;
+ const std::string algo_name = global_state().deref_alias(name[0]);
+
+#if defined(BOTAN_HAS_AES)
+ HANDLE_TYPE_NO_ARGS("AES", AES);
+ HANDLE_TYPE_NO_ARGS("AES-128", AES_128);
+ HANDLE_TYPE_NO_ARGS("AES-192", AES_192);
+ HANDLE_TYPE_NO_ARGS("AES-256", AES_256);
+#endif
+
+#if defined(BOTAN_HAS_BLOWFISH)
+ HANDLE_TYPE_NO_ARGS("Blowfish", Blowfish);
+#endif
+
+#if defined(BOTAN_HAS_CAST)
+ HANDLE_TYPE_NO_ARGS("CAST-128", CAST_128);
+ HANDLE_TYPE_NO_ARGS("CAST-256", CAST_256);
+#endif
+
+#if defined(BOTAN_HAS_DES)
+ HANDLE_TYPE_NO_ARGS("DES", DES);
+ HANDLE_TYPE_NO_ARGS("DESX", DESX);
+ HANDLE_TYPE_NO_ARGS("TripleDES", TripleDES);
+#endif
+
+#if defined(BOTAN_HAS_GOST)
+ HANDLE_TYPE_NO_ARGS("GOST", GOST);
+#endif
+
+#if defined(BOTAN_HAS_IDEA)
+ HANDLE_TYPE_NO_ARGS("IDEA", IDEA);
+#endif
+
+#if defined(BOTAN_HAS_KASUMI)
+ HANDLE_TYPE_NO_ARGS("KASUMI", KASUMI);
+#endif
+
+#if defined(BOTAN_HAS_MARS)
+ HANDLE_TYPE_NO_ARGS("MARS", MARS);
+#endif
+
+#if defined(BOTAN_HAS_MISTY1)
+ HANDLE_TYPE_ONE_U32BIT("MISTY1", MISTY1, 8);
+#endif
+
+#if defined(BOTAN_HAS_NOEKEON)
+ HANDLE_TYPE_NO_ARGS("Noekeon", Noekeon);
+#endif
+
+#if defined(BOTAN_HAS_RC2)
+ HANDLE_TYPE_NO_ARGS("RC2", RC2);
+#endif
+
+#if defined(BOTAN_HAS_RC5)
+ HANDLE_TYPE_ONE_U32BIT("RC5", RC5, 12);
+#endif
+
+#if defined(BOTAN_HAS_RC6)
+ HANDLE_TYPE_NO_ARGS("RC6", RC6);
+#endif
+
+#if defined(BOTAN_HAS_SAFER)
+ HANDLE_TYPE_ONE_U32BIT("SAFER-SK", SAFER_SK, 10);
+#endif
+
+#if defined(BOTAN_HAS_SEED)
+ HANDLE_TYPE_NO_ARGS("SEED", SEED);
+#endif
+
+#if defined(BOTAN_HAS_SERPENT_IA32)
+ HANDLE_TYPE_NO_ARGS("Serpent", Serpent_IA32);
+#elif defined(BOTAN_HAS_SERPENT)
+ HANDLE_TYPE_NO_ARGS("Serpent", Serpent);
+#endif
+
+#if defined(BOTAN_HAS_SKIPJACK)
+ HANDLE_TYPE_NO_ARGS("Skipjack", Skipjack);
+#endif
+
+#if defined(BOTAN_HAS_SQUARE)
+ HANDLE_TYPE_NO_ARGS("Square", Square);
+#endif
+
+#if defined(BOTAN_HAS_TEA)
+ HANDLE_TYPE_NO_ARGS("TEA", TEA);
+#endif
+
+#if defined(BOTAN_HAS_TWOFISH)
+ HANDLE_TYPE_NO_ARGS("Twofish", Twofish);
+#endif
+
+#if defined(BOTAN_HAS_XTEA)
+ HANDLE_TYPE_NO_ARGS("XTEA", XTEA);
+#endif
+
+#if defined(BOTAN_HAS_LUBY_RACKOFF)
+ if(algo_name == "Luby-Rackoff" && name.size() >= 2)
+ {
+ HashFunction* hash = get_hash(name[1]);
+ if(hash)
+ return new LubyRackoff(hash);
+ }
+#endif
+
+#if defined(BOTAN_HAS_LION)
+ if(algo_name == "Lion")
+ {
+ if(name.size() != 4)
+ throw Invalid_Algorithm_Name(algo_spec);
+
+ return new Lion(get_hash(name[1]), get_stream_cipher(name[2]),
+ to_u32bit(name[3]));
+ }
+#endif
+
+ return 0;
+ }
+
+/*************************************************
+* Look for an algorithm with this name *
+*************************************************/
+StreamCipher*
+Default_Engine::find_stream_cipher(const std::string& algo_spec) const
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ if(name.empty())
+ return 0;
+ const std::string algo_name = global_state().deref_alias(name[0]);
+
+#if defined(BOTAN_HAS_ARC4)
+ HANDLE_TYPE_ONE_U32BIT("ARC4", ARC4, 0);
+ HANDLE_TYPE_ONE_U32BIT("RC4_drop", ARC4, 768);
+#endif
+
+#if defined(BOTAN_HAS_SALSA20)
+ HANDLE_TYPE_NO_ARGS("Salsa20", Salsa20);
+#endif
+
+#if defined(BOTAN_HAS_TURING)
+ HANDLE_TYPE_NO_ARGS("Turing", Turing);
+#endif
+
+#if defined(BOTAN_HAS_WID_WAKE)
+ HANDLE_TYPE_NO_ARGS("WiderWake4+1-BE", WiderWake_41_BE);
+#endif
+
+ return 0;
+ }
+
+/*************************************************
+* Look for an algorithm with this name *
+*************************************************/
+HashFunction*
+Default_Engine::find_hash(const std::string& algo_spec) const
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ if(name.empty())
+ return 0;
+ const std::string algo_name = global_state().deref_alias(name[0]);
+
+#if defined(BOTAN_HAS_ADLER32)
+ HANDLE_TYPE_NO_ARGS("Adler32", Adler32);
+#endif
+
+#if defined(BOTAN_HAS_CRC24)
+ HANDLE_TYPE_NO_ARGS("CRC24", CRC24);
+#endif
+
+#if defined(BOTAN_HAS_CRC32)
+ HANDLE_TYPE_NO_ARGS("CRC32", CRC32);
+#endif
+
+#if defined(BOTAN_HAS_FORK_256)
+ HANDLE_TYPE_NO_ARGS("FORK-256", FORK_256);
+#endif
+
+#if defined(BOTAN_HAS_HAS_160)
+ HANDLE_TYPE_NO_ARGS("HAS-160", HAS_160);
+#endif
+
+#if defined(BOTAN_HAS_MD2)
+ HANDLE_TYPE_NO_ARGS("MD2", MD2);
+#endif
+
+#if defined(BOTAN_HAS_MD4_IA32)
+ HANDLE_TYPE_NO_ARGS("MD4", MD4_IA32);
+#elif defined(BOTAN_HAS_MD4)
+ HANDLE_TYPE_NO_ARGS("MD4", MD4);
+#endif
+
+#if defined(BOTAN_HAS_MD5_IA32)
+ HANDLE_TYPE_NO_ARGS("MD5", MD5_IA32);
+#elif defined(BOTAN_HAS_MD5)
+ HANDLE_TYPE_NO_ARGS("MD5", MD5);
+#endif
+
+#if defined(BOTAN_HAS_RIPEMD_128)
+ HANDLE_TYPE_NO_ARGS("RIPEMD-128", RIPEMD_128);
+#endif
+
+#if defined(BOTAN_HAS_RIPEMD_160)
+ HANDLE_TYPE_NO_ARGS("RIPEMD-160", RIPEMD_160);
+#endif
+
+#if defined(BOTAN_HAS_SHA1_SSE2)
+ HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160_SSE2);
+#elif defined(BOTAN_HAS_SHA1_AMD64)
+ HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160_AMD64);
+#elif defined(BOTAN_HAS_SHA1_IA32)
+ HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160_IA32);
+#elif defined(BOTAN_HAS_SHA1)
+ HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160);
+#endif
+
+#if defined(BOTAN_HAS_SHA2)
+ HANDLE_TYPE_NO_ARGS("SHA-256", SHA_256);
+ HANDLE_TYPE_NO_ARGS("SHA-384", SHA_384);
+ HANDLE_TYPE_NO_ARGS("SHA-512", SHA_512);
+#endif
+
+#if defined(BOTAN_HAS_TIGER)
+ HANDLE_TYPE_TWO_U32BIT("Tiger", Tiger, 24);
+#endif
+
+#if defined(BOTAN_HAS_WHIRLPOOL)
+ HANDLE_TYPE_NO_ARGS("Whirlpool", Whirlpool);
+#endif
+
+#if defined(BOTAN_HAS_PARALLEL_HASH)
+ if(algo_name == "Parallel")
+ {
+ if(name.size() < 2)
+ throw Invalid_Algorithm_Name(algo_spec);
+ name.erase(name.begin());
+ return new Parallel(name);
+ }
+#endif
+
+ return 0;
+ }
+
+/*************************************************
+* Look for an algorithm with this name *
+*************************************************/
+MessageAuthenticationCode*
+Default_Engine::find_mac(const std::string& algo_spec) const
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ if(name.empty())
+ return 0;
+ const std::string algo_name = global_state().deref_alias(name[0]);
+
+#if defined(BOTAN_HAS_CBC_MAC)
+ if(algo_name == "CBC-MAC")
+ {
+ if(name.size() == 2)
+ return new CBC_MAC(get_block_cipher(name[1]));
+ throw Invalid_Algorithm_Name(algo_spec);
+ }
+#endif
+
+#if defined(BOTAN_HAS_CMAC)
+ if(algo_name == "CMAC")
+ {
+ if(name.size() == 2)
+ return new CMAC(get_block_cipher(name[1]));
+ throw Invalid_Algorithm_Name(algo_spec);
+ }
+#endif
+
+#if defined(BOTAN_HAS_HMAC)
+ if(algo_name == "HMAC")
+ {
+ if(name.size() == 2)
+ return new HMAC(get_hash(name[1]));
+ throw Invalid_Algorithm_Name(algo_spec);
+ }
+#endif
+
+#if defined(BOTAN_HAS_SSL3_MAC)
+ if(algo_name == "SSL3-MAC")
+ {
+ if(name.size() == 2)
+ return new SSL3_MAC(get_hash(name[1]));
+ throw Invalid_Algorithm_Name(algo_spec);
+ }
+#endif
+
+#if defined(BOTAN_HAS_ANSI_X919_MAC)
+ if(algo_name == "X9.19-MAC")
+ {
+ if(name.size() == 1)
+ return new ANSI_X919_MAC(get_block_cipher("DES"));
+ throw Invalid_Algorithm_Name(algo_spec);
+ }
+#endif
+
+ return 0;
+ }
+
+/*************************************************
+* Look for an algorithm with this name *
+*************************************************/
+S2K* Default_Engine::find_s2k(const std::string& algo_spec) const
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ if(name.empty())
+ return 0;
+
+ const std::string algo_name = global_state().deref_alias(name[0]);
+
+#if defined(BOTAN_HAS_PBKDF1)
+ if(algo_name == "PBKDF1")
+ {
+ if(name.size() == 2)
+ return new PKCS5_PBKDF1(get_hash(name[1]));
+ throw Invalid_Algorithm_Name(algo_spec);
+ }
+#endif
+
+#if defined(BOTAN_HAS_PBKDF2)
+ if(algo_name == "PBKDF2")
+ {
+ if(name.size() == 2)
+ return new PKCS5_PBKDF2(get_mac("HMAC(" + name[1] + ")"));
+ throw Invalid_Algorithm_Name(algo_spec);
+ }
+#endif
+
+#if defined(BOTAN_HAS_PGPS2K)
+ HANDLE_TYPE_ONE_STRING("OpenPGP-S2K", OpenPGP_S2K);
+#endif
+
+ return 0;
+ }
+
+/*************************************************
+* Look for an algorithm with this name *
+*************************************************/
+BlockCipherModePaddingMethod*
+Default_Engine::find_bc_pad(const std::string& algo_spec) const
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ if(name.empty())
+ return 0;
+
+ const std::string algo_name = global_state().deref_alias(name[0]);
+
+#if defined(BOTAN_HAS_CIPHER_MODE_PADDING)
+ HANDLE_TYPE_NO_ARGS("PKCS7", PKCS7_Padding);
+ HANDLE_TYPE_NO_ARGS("OneAndZeros", OneAndZeros_Padding);
+ HANDLE_TYPE_NO_ARGS("X9.23", ANSI_X923_Padding);
+ HANDLE_TYPE_NO_ARGS("NoPadding", Null_Padding);
+#endif
+
+ return 0;
+ }
+
+}
diff --git a/src/core/libstate/def_mode.cpp b/src/core/libstate/def_mode.cpp
new file mode 100644
index 000000000..b062cc34b
--- /dev/null
+++ b/src/core/libstate/def_mode.cpp
@@ -0,0 +1,177 @@
+/*************************************************
+* Default Engine Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/eng_def.h>
+#include <botan/parsing.h>
+#include <botan/filters.h>
+#include <botan/lookup.h>
+
+#if defined(BOTAN_HAS_ECB)
+ #include <botan/ecb.h>
+#endif
+
+#if defined(BOTAN_HAS_CBC)
+ #include <botan/cbc.h>
+#endif
+
+#if defined(BOTAN_HAS_CTS)
+ #include <botan/cts.h>
+#endif
+
+#if defined(BOTAN_HAS_CFB)
+ #include <botan/cfb.h>
+#endif
+
+#if defined(BOTAN_HAS_OFB)
+ #include <botan/ofb.h>
+#endif
+
+#if defined(BOTAN_HAS_CTR)
+ #include <botan/ctr.h>
+#endif
+
+#if defined(BOTAN_HAS_EAX)
+ #include <botan/eax.h>
+#endif
+
+namespace Botan {
+
+/*************************************************
+* Get a cipher object *
+*************************************************/
+Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec,
+ Cipher_Dir direction)
+ {
+ std::vector<std::string> algo_parts = split_on(algo_spec, '/');
+ if(algo_parts.empty())
+ throw Invalid_Algorithm_Name(algo_spec);
+
+ const std::string cipher = algo_parts[0];
+
+ if(have_stream_cipher(cipher))
+ {
+ if(algo_parts.size() == 1)
+ return new StreamCipher_Filter(cipher);
+ return 0;
+ }
+ else if(have_block_cipher(cipher))
+ {
+ if(algo_parts.size() != 2 && algo_parts.size() != 3)
+ return 0;
+
+ std::string mode = algo_parts[1];
+ u32bit bits = 0;
+
+ if(mode.find("CFB") != std::string::npos ||
+ mode.find("EAX") != std::string::npos)
+ {
+ std::vector<std::string> algo_info = parse_algorithm_name(mode);
+ mode = algo_info[0];
+ if(algo_info.size() == 1)
+ bits = 8*block_size_of(cipher);
+ else if(algo_info.size() == 2)
+ bits = to_u32bit(algo_info[1]);
+ else
+ throw Invalid_Algorithm_Name(algo_spec);
+ }
+
+ std::string padding;
+ if(algo_parts.size() == 3)
+ padding = algo_parts[2];
+ else
+ padding = (mode == "CBC") ? "PKCS7" : "NoPadding";
+
+ if(mode == "ECB" && padding == "CTS")
+ return 0;
+ else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding")
+ throw Invalid_Algorithm_Name(algo_spec);
+
+ if(mode == "OFB")
+ {
+#if defined(BOTAN_HAS_OFB)
+ return new OFB(cipher);
+#else
+ return 0;
+#endif
+ }
+ else if(mode == "CTR-BE")
+ {
+#if defined(BOTAN_HAS_CTR)
+ return new CTR_BE(cipher);
+#else
+ return 0;
+#endif
+ }
+ else if(mode == "ECB" || mode == "CBC" || mode == "CTS" ||
+ mode == "CFB" || mode == "EAX")
+ {
+ if(mode == "ECB")
+ {
+#if defined(BOTAN_HAS_ECB)
+ if(direction == ENCRYPTION)
+ return new ECB_Encryption(cipher, padding);
+ else
+ return new ECB_Decryption(cipher, padding);
+#else
+ return 0;
+#endif
+ }
+ else if(mode == "CFB")
+ {
+#if defined(BOTAN_HAS_CFB)
+ if(direction == ENCRYPTION)
+ return new CFB_Encryption(cipher, bits);
+ else
+ return new CFB_Decryption(cipher, bits);
+#else
+ return 0;
+#endif
+ }
+ else if(mode == "CBC")
+ {
+ if(padding == "CTS")
+ {
+#if defined(BOTAN_HAS_CTS)
+ if(direction == ENCRYPTION)
+ return new CTS_Encryption(cipher);
+ else
+ return new CTS_Decryption(cipher);
+#else
+ return 0;
+#endif
+ }
+
+#if defined(BOTAN_HAS_CBC)
+ if(direction == ENCRYPTION)
+ return new CBC_Encryption(cipher, padding);
+ else
+ return new CBC_Decryption(cipher, padding);
+#else
+ return 0;
+#endif
+ }
+ else if(mode == "EAX")
+ {
+#if defined(BOTAN_HAS_EAX)
+ if(direction == ENCRYPTION)
+ return new EAX_Encryption(cipher, bits);
+ else
+ return new EAX_Decryption(cipher, bits);
+#else
+ return 0;
+#endif
+ }
+ else
+ throw Internal_Error("get_mode: " + cipher + "/"
+ + mode + "/" + padding);
+ }
+ else
+ return 0;
+ }
+
+ return 0;
+ }
+
+}
diff --git a/src/core/libstate/eng_base.cpp b/src/core/libstate/eng_base.cpp
new file mode 100644
index 000000000..bd6b53447
--- /dev/null
+++ b/src/core/libstate/eng_base.cpp
@@ -0,0 +1,326 @@
+/*************************************************
+* Basic No-Op Engine Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/engine.h>
+#include <botan/libstate.h>
+#include <botan/stl_util.h>
+#include <botan/lookup.h>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Algorithm Cache *
+*************************************************/
+template<typename T>
+class Algorithm_Cache_Impl : public Engine::Algorithm_Cache<T>
+ {
+ public:
+ T* get(const std::string& name) const
+ {
+ Mutex_Holder lock(mutex);
+ return search_map(mappings, name);
+ }
+
+ void add(T* algo, const std::string& index_name = "") const
+ {
+ if(!algo)
+ return;
+
+ Mutex_Holder lock(mutex);
+
+ const std::string name =
+ (index_name != "" ? index_name : algo->name());
+
+ if(mappings.find(name) != mappings.end())
+ delete mappings[name];
+ mappings[name] = algo;
+ }
+
+ Algorithm_Cache_Impl()
+ {
+ mutex = global_state().get_mutex();
+ }
+
+ ~Algorithm_Cache_Impl()
+ {
+ typename std::map<std::string, T*>::iterator i = mappings.begin();
+
+ while(i != mappings.end())
+ {
+ delete i->second;
+ ++i;
+ }
+ delete mutex;
+ }
+ private:
+ Mutex* mutex;
+ mutable std::map<std::string, T*> mappings;
+ };
+
+}
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+IF_Operation* Engine::if_op(const BigInt&, const BigInt&, const BigInt&,
+ const BigInt&, const BigInt&, const BigInt&,
+ const BigInt&, const BigInt&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+DSA_Operation* Engine::dsa_op(const DL_Group&, const BigInt&,
+ const BigInt&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+NR_Operation* Engine::nr_op(const DL_Group&, const BigInt&,
+ const BigInt&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+ELG_Operation* Engine::elg_op(const DL_Group&, const BigInt&,
+ const BigInt&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+DH_Operation* Engine::dh_op(const DL_Group&, const BigInt&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+ECDSA_Operation* Engine::ecdsa_op(const EC_Domain_Params&,
+ const BigInt&,
+ const PointGFp&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+ECKAEG_Operation* Engine::eckaeg_op(const EC_Domain_Params&,
+ const BigInt&,
+ const PointGFp&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+Modular_Exponentiator* Engine::mod_exp(const BigInt&,
+ Power_Mod::Usage_Hints) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Acquire a BlockCipher *
+*************************************************/
+const BlockCipher* Engine::block_cipher(const std::string& name) const
+ {
+ return lookup_algo(cache_of_bc, global_state().deref_alias(name),
+ this, &Engine::find_block_cipher);
+ }
+
+/*************************************************
+* Acquire a StreamCipher *
+*************************************************/
+const StreamCipher* Engine::stream_cipher(const std::string& name) const
+ {
+ return lookup_algo(cache_of_sc, global_state().deref_alias(name),
+ this, &Engine::find_stream_cipher);
+ }
+
+/*************************************************
+* Acquire a HashFunction *
+*************************************************/
+const HashFunction* Engine::hash(const std::string& name) const
+ {
+ return lookup_algo(cache_of_hf, global_state().deref_alias(name),
+ this, &Engine::find_hash);
+ }
+
+/*************************************************
+* Acquire a MessageAuthenticationCode *
+*************************************************/
+const MessageAuthenticationCode* Engine::mac(const std::string& name) const
+ {
+ return lookup_algo(cache_of_mac, global_state().deref_alias(name),
+ this, &Engine::find_mac);
+ }
+
+/*************************************************
+* Acquire a S2K object *
+*************************************************/
+const S2K* Engine::s2k(const std::string& name) const
+ {
+ return lookup_algo(cache_of_s2k, global_state().deref_alias(name),
+ this, &Engine::find_s2k);
+ }
+
+/*************************************************
+* Acquire a cipher padding object *
+*************************************************/
+const BlockCipherModePaddingMethod*
+Engine::bc_pad(const std::string& name) const
+ {
+ return lookup_algo(cache_of_bc_pad, global_state().deref_alias(name),
+ this, &Engine::find_bc_pad);
+ }
+
+/*************************************************
+* Add a block cipher to the lookup table *
+*************************************************/
+void Engine::add_algorithm(BlockCipher* algo) const
+ {
+ cache_of_bc->add(algo);
+ }
+
+/*************************************************
+* Add a stream cipher to the lookup table *
+*************************************************/
+void Engine::add_algorithm(StreamCipher* algo) const
+ {
+ cache_of_sc->add(algo);
+ }
+
+/*************************************************
+* Add a hash function to the lookup table *
+*************************************************/
+void Engine::add_algorithm(HashFunction* algo) const
+ {
+ cache_of_hf->add(algo);
+ }
+
+/*************************************************
+* Add a MAC to the lookup table *
+*************************************************/
+void Engine::add_algorithm(MessageAuthenticationCode* algo) const
+ {
+ cache_of_mac->add(algo);
+ }
+
+/*************************************************
+* Add a S2K to the lookup table *
+*************************************************/
+void Engine::add_algorithm(S2K* algo) const
+ {
+ cache_of_s2k->add(algo);
+ }
+
+/*************************************************
+* Add a cipher pad method to the lookup table *
+*************************************************/
+void Engine::add_algorithm(BlockCipherModePaddingMethod* algo) const
+ {
+ cache_of_bc_pad->add(algo);
+ }
+
+/*************************************************
+* Create an Engine *
+*************************************************/
+Engine::Engine()
+ {
+ cache_of_bc = new Algorithm_Cache_Impl<BlockCipher>();
+ cache_of_sc = new Algorithm_Cache_Impl<StreamCipher>();
+ cache_of_hf = new Algorithm_Cache_Impl<HashFunction>();
+ cache_of_mac = new Algorithm_Cache_Impl<MessageAuthenticationCode>();
+ cache_of_s2k = new Algorithm_Cache_Impl<S2K>();
+ cache_of_bc_pad =
+ new Algorithm_Cache_Impl<BlockCipherModePaddingMethod>();
+ }
+
+/*************************************************
+* Destroy an Engine *
+*************************************************/
+Engine::~Engine()
+ {
+ delete cache_of_bc;
+ delete cache_of_sc;
+ delete cache_of_hf;
+ delete cache_of_mac;
+ delete cache_of_s2k;
+ delete cache_of_bc_pad;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+BlockCipher* Engine::find_block_cipher(const std::string&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+StreamCipher* Engine::find_stream_cipher(const std::string&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+HashFunction* Engine::find_hash(const std::string&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+MessageAuthenticationCode* Engine::find_mac(const std::string&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+S2K* Engine::find_s2k(const std::string&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+BlockCipherModePaddingMethod* Engine::find_bc_pad(const std::string&) const
+ {
+ return 0;
+ }
+
+/*************************************************
+* Basic No-Op Engine Implementation *
+*************************************************/
+Keyed_Filter* Engine::get_cipher(const std::string&, Cipher_Dir)
+ {
+ return 0;
+ }
+
+}
diff --git a/src/core/libstate/engine.cpp b/src/core/libstate/engine.cpp
new file mode 100644
index 000000000..14c1c9c50
--- /dev/null
+++ b/src/core/libstate/engine.cpp
@@ -0,0 +1,420 @@
+/*************************************************
+* Engine Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/engine.h>
+#include <botan/libstate.h>
+#include <botan/lookup.h>
+#include <botan/look_add.h>
+#include <botan/eng_def.h>
+
+namespace Botan {
+
+namespace Engine_Core {
+
+/*************************************************
+* Acquire an IF op *
+*************************************************/
+IF_Operation* if_op(const BigInt& e, const BigInt& n, const BigInt& d,
+ const BigInt& p, const BigInt& q, const BigInt& d1,
+ const BigInt& d2, const BigInt& c)
+ {
+ Library_State::Engine_Iterator i(global_state());
+
+ while(const Engine* engine = i.next())
+ {
+ IF_Operation* op = engine->if_op(e, n, d, p, q, d1, d2, c);
+ if(op)
+ return op;
+ }
+
+ throw Lookup_Error("Engine_Core::if_op: Unable to find a working engine");
+ }
+
+/*************************************************
+* Acquire a DSA op *
+*************************************************/
+DSA_Operation* dsa_op(const DL_Group& group, const BigInt& y, const BigInt& x)
+ {
+ Library_State::Engine_Iterator i(global_state());
+
+ while(const Engine* engine = i.next())
+ {
+ DSA_Operation* op = engine->dsa_op(group, y, x);
+ if(op)
+ return op;
+ }
+
+ throw Lookup_Error("Engine_Core::dsa_op: Unable to find a working engine");
+ }
+
+/*************************************************
+* Acquire a NR op *
+*************************************************/
+NR_Operation* nr_op(const DL_Group& group, const BigInt& y, const BigInt& x)
+ {
+ Library_State::Engine_Iterator i(global_state());
+
+ while(const Engine* engine = i.next())
+ {
+ NR_Operation* op = engine->nr_op(group, y, x);
+ if(op)
+ return op;
+ }
+
+ throw Lookup_Error("Engine_Core::nr_op: Unable to find a working engine");
+ }
+
+/*************************************************
+* Acquire an ElGamal op *
+*************************************************/
+ELG_Operation* elg_op(const DL_Group& group, const BigInt& y, const BigInt& x)
+ {
+ Library_State::Engine_Iterator i(global_state());
+
+ while(const Engine* engine = i.next())
+ {
+ ELG_Operation* op = engine->elg_op(group, y, x);
+ if(op)
+ return op;
+ }
+
+ throw Lookup_Error("Engine_Core::elg_op: Unable to find a working engine");
+ }
+
+/*************************************************
+* Acquire a DH op *
+*************************************************/
+DH_Operation* dh_op(const DL_Group& group, const BigInt& x)
+ {
+ Library_State::Engine_Iterator i(global_state());
+
+ while(const Engine* engine = i.next())
+ {
+ DH_Operation* op = engine->dh_op(group, x);
+ if(op)
+ return op;
+ }
+
+ throw Lookup_Error("Engine_Core::dh_op: Unable to find a working engine");
+ }
+
+/*************************************************
+* Acquire an ECDSA op *
+*************************************************/
+ECDSA_Operation* ecdsa_op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key)
+ {
+ Library_State::Engine_Iterator i(global_state());
+
+ while(const Engine* engine = i.next())
+ {
+ ECDSA_Operation* op = engine->ecdsa_op(dom_pars, priv_key, pub_key);
+ if(op)
+ return op;
+ }
+
+ throw Lookup_Error("Engine_Core::ecdsa_op: Unable to find a working engine");
+ }
+
+/*************************************************
+* Acquire a ECKAEG op *
+*************************************************/
+ECKAEG_Operation* eckaeg_op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key)
+ {
+ Library_State::Engine_Iterator i(global_state());
+
+ while(const Engine* engine = i.next())
+ {
+ ECKAEG_Operation* op = engine->eckaeg_op(dom_pars, priv_key, pub_key);
+ if(op)
+ return op;
+ }
+
+ throw Lookup_Error("Engine_Core::eckaeg_op: Unable to find a working engine");
+ }
+
+/*************************************************
+* Acquire a modular exponentiator *
+*************************************************/
+Modular_Exponentiator* mod_exp(const BigInt& n, Power_Mod::Usage_Hints hints)
+ {
+ Library_State::Engine_Iterator i(global_state());
+
+ while(const Engine* engine = i.next())
+ {
+ Modular_Exponentiator* op = engine->mod_exp(n, hints);
+
+ if(op)
+ return op;
+ }
+
+ throw Lookup_Error("Engine_Core::mod_exp: Unable to find a working engine");
+ }
+
+}
+
+/*************************************************
+* Acquire a block cipher *
+*************************************************/
+const BlockCipher* retrieve_block_cipher(Library_State& libstate,
+ const std::string& name)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(const Engine* engine = i.next())
+ {
+ const BlockCipher* algo = engine->block_cipher(name);
+ if(algo)
+ return algo;
+ }
+
+ return 0;
+ }
+
+/*************************************************
+* Acquire a stream cipher *
+*************************************************/
+const StreamCipher* retrieve_stream_cipher(Library_State& libstate,
+ const std::string& name)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(const Engine* engine = i.next())
+ {
+ const StreamCipher* algo = engine->stream_cipher(name);
+ if(algo)
+ return algo;
+ }
+
+ return 0;
+ }
+
+/*************************************************
+* Acquire a hash function *
+*************************************************/
+const HashFunction* retrieve_hash(Library_State& libstate,
+ const std::string& name)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(const Engine* engine = i.next())
+ {
+ const HashFunction* algo = engine->hash(name);
+ if(algo)
+ return algo;
+ }
+
+ return 0;
+ }
+
+/*************************************************
+* Acquire an authentication code *
+*************************************************/
+const MessageAuthenticationCode* retrieve_mac(Library_State& libstate,
+ const std::string& name)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(const Engine* engine = i.next())
+ {
+ const MessageAuthenticationCode* algo = engine->mac(name);
+ if(algo)
+ return algo;
+ }
+
+ return 0;
+ }
+
+/*************************************************
+* Acquire a string-to-key algorithm *
+*************************************************/
+const S2K* retrieve_s2k(Library_State& libstate,
+ const std::string& name)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(const Engine* engine = i.next())
+ {
+ const S2K* algo = engine->s2k(name);
+ if(algo)
+ return algo;
+ }
+
+ return 0;
+ }
+
+/*************************************************
+* Retrieve a block cipher padding method *
+*************************************************/
+const BlockCipherModePaddingMethod* retrieve_bc_pad(Library_State& libstate,
+ const std::string& name)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(const Engine* engine = i.next())
+ {
+ const BlockCipherModePaddingMethod* algo = engine->bc_pad(name);
+ if(algo)
+ return algo;
+ }
+
+ return 0;
+ }
+
+/*************************************************
+* Add a new block cipher *
+*************************************************/
+void add_algorithm(Library_State& libstate, BlockCipher* algo)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(Engine* engine_base = i.next())
+ {
+ Default_Engine* engine = dynamic_cast<Default_Engine*>(engine_base);
+ if(engine)
+ {
+ engine->add_algorithm(algo);
+ return;
+ }
+ }
+
+ throw Invalid_State("add_algorithm: Couldn't find the Default_Engine");
+ }
+
+/*************************************************
+* Add a new stream cipher *
+*************************************************/
+void add_algorithm(Library_State& libstate, StreamCipher* algo)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(Engine* engine_base = i.next())
+ {
+ Default_Engine* engine = dynamic_cast<Default_Engine*>(engine_base);
+ if(engine)
+ {
+ engine->add_algorithm(algo);
+ return;
+ }
+ }
+
+ throw Invalid_State("add_algorithm: Couldn't find the Default_Engine");
+ }
+
+/*************************************************
+* Add a new hash function *
+*************************************************/
+void add_algorithm(Library_State& libstate, HashFunction* algo)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(Engine* engine_base = i.next())
+ {
+ Default_Engine* engine = dynamic_cast<Default_Engine*>(engine_base);
+ if(engine)
+ {
+ engine->add_algorithm(algo);
+ return;
+ }
+ }
+
+ throw Invalid_State("add_algorithm: Couldn't find the Default_Engine");
+ }
+
+/*************************************************
+* Add a new authentication code *
+*************************************************/
+void add_algorithm(Library_State& libstate,
+ MessageAuthenticationCode* algo)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(Engine* engine_base = i.next())
+ {
+ Default_Engine* engine = dynamic_cast<Default_Engine*>(engine_base);
+ if(engine)
+ {
+ engine->add_algorithm(algo);
+ return;
+ }
+ }
+
+ throw Invalid_State("add_algorithm: Couldn't find the Default_Engine");
+ }
+
+/*************************************************
+* Add a padding method to the lookup table *
+*************************************************/
+void add_algorithm(Library_State& libstate,
+ BlockCipherModePaddingMethod* algo)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(Engine* engine_base = i.next())
+ {
+ Default_Engine* engine = dynamic_cast<Default_Engine*>(engine_base);
+ if(engine)
+ {
+ engine->add_algorithm(algo);
+ return;
+ }
+ }
+
+ throw Invalid_State("add_algorithm: Couldn't find the Default_Engine");
+ }
+
+/*************************************************
+* Get a cipher object *
+*************************************************/
+Keyed_Filter* get_cipher(Library_State& libstate,
+ const std::string& algo_spec,
+ Cipher_Dir direction)
+ {
+ Library_State::Engine_Iterator i(libstate);
+
+ while(Engine* engine = i.next())
+ {
+ Keyed_Filter* algo = engine->get_cipher(algo_spec, direction);
+ if(algo)
+ return algo;
+ }
+
+ throw Algorithm_Not_Found(algo_spec);
+ }
+
+/*************************************************
+* Get a cipher object *
+*************************************************/
+Keyed_Filter* get_cipher(Library_State& libstate,
+ const std::string& algo_spec,
+ const SymmetricKey& key,
+ const InitializationVector& iv,
+ Cipher_Dir direction)
+ {
+ Keyed_Filter* cipher = get_cipher(libstate, algo_spec, direction);
+ cipher->set_key(key);
+
+ if(iv.length())
+ cipher->set_iv(iv);
+
+ return cipher;
+ }
+
+/*************************************************
+* Get a cipher object *
+*************************************************/
+Keyed_Filter* get_cipher(Library_State& libstate,
+ const std::string& algo_spec,
+ const SymmetricKey& key,
+ Cipher_Dir direction)
+ {
+ return get_cipher(libstate, algo_spec,
+ key, InitializationVector(), direction);
+ }
+
+}
diff --git a/src/core/libstate/engine.h b/src/core/libstate/engine.h
new file mode 100644
index 000000000..74449c959
--- /dev/null
+++ b/src/core/libstate/engine.h
@@ -0,0 +1,140 @@
+/*************************************************
+* Engine Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_ENGINE_H__
+#define BOTAN_ENGINE_H__
+
+#include <botan/base.h>
+#include <botan/mutex.h>
+#include <botan/ec_dompar.h>
+#include <botan/pk_ops.h>
+#include <botan/pow_mod.h>
+#include <botan/basefilt.h>
+#include <botan/enums.h>
+#include <utility>
+#include <map>
+
+namespace Botan {
+
+/*************************************************
+* Engine Base Class *
+*************************************************/
+class BOTAN_DLL Engine
+ {
+ public:
+ template<typename T>
+ class BOTAN_DLL Algorithm_Cache
+ {
+ public:
+ virtual T* get(const std::string&) const = 0;
+ virtual void add(T* algo, const std::string& = "") const = 0;
+ virtual ~Algorithm_Cache() {}
+ };
+
+ virtual IF_Operation* if_op(const BigInt&, const BigInt&, const BigInt&,
+ const BigInt&, const BigInt&, const BigInt&,
+ const BigInt&, const BigInt&) const;
+ virtual DSA_Operation* dsa_op(const DL_Group&, const BigInt&,
+ const BigInt&) const;
+ virtual NR_Operation* nr_op(const DL_Group&, const BigInt&,
+ const BigInt&) const;
+ virtual ELG_Operation* elg_op(const DL_Group&, const BigInt&,
+ const BigInt&) const;
+ virtual DH_Operation* dh_op(const DL_Group&, const BigInt&) const;
+
+ virtual ECDSA_Operation* ecdsa_op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key) const;
+
+ virtual ECKAEG_Operation* eckaeg_op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key) const;
+
+ virtual Modular_Exponentiator* mod_exp(const BigInt&,
+ Power_Mod::Usage_Hints) const;
+
+ virtual Keyed_Filter* get_cipher(const std::string&, Cipher_Dir);
+
+ const BlockCipher* block_cipher(const std::string&) const;
+ const StreamCipher* stream_cipher(const std::string&) const;
+ const HashFunction* hash(const std::string&) const;
+ const MessageAuthenticationCode* mac(const std::string&) const;
+ const class S2K* s2k(const std::string&) const;
+ const class BlockCipherModePaddingMethod*
+ bc_pad(const std::string&) const;
+
+ void add_algorithm(BlockCipher*) const;
+ void add_algorithm(StreamCipher*) const;
+ void add_algorithm(HashFunction*) const;
+ void add_algorithm(MessageAuthenticationCode*) const;
+ void add_algorithm(class S2K*) const;
+ void add_algorithm(class BlockCipherModePaddingMethod*) const;
+
+ Engine();
+ virtual ~Engine();
+ private:
+ virtual BlockCipher* find_block_cipher(const std::string&) const;
+ virtual StreamCipher* find_stream_cipher(const std::string&) const;
+ virtual HashFunction* find_hash(const std::string&) const;
+ virtual MessageAuthenticationCode* find_mac(const std::string&) const;
+ virtual class S2K* find_s2k(const std::string&) const;
+ virtual class BlockCipherModePaddingMethod*
+ find_bc_pad(const std::string&) const;
+
+ template<typename T>
+ const T* lookup_algo(const Algorithm_Cache<T>* cache,
+ const std::string& name,
+ const Engine* engine,
+ T* (Engine::*find)(const std::string&) const) const
+ {
+ T* algo = cache->get(name);
+ if(!algo)
+ {
+ algo = (engine->*find)(name);
+ if(algo)
+ cache->add(algo, name);
+ }
+ return algo;
+ }
+
+ Algorithm_Cache<BlockCipher>* cache_of_bc;
+ Algorithm_Cache<StreamCipher>* cache_of_sc;
+ Algorithm_Cache<HashFunction>* cache_of_hf;
+ Algorithm_Cache<MessageAuthenticationCode>* cache_of_mac;
+ Algorithm_Cache<BlockCipherModePaddingMethod>* cache_of_bc_pad;
+ Algorithm_Cache<S2K>* cache_of_s2k;
+ };
+
+namespace Engine_Core {
+
+/*************************************************
+* Get an operation from an Engine *
+*************************************************/
+Modular_Exponentiator* mod_exp(const BigInt&, Power_Mod::Usage_Hints);
+
+IF_Operation* if_op(const BigInt&, const BigInt&, const BigInt&,
+ const BigInt&, const BigInt&, const BigInt&,
+ const BigInt&, const BigInt&);
+
+DSA_Operation* dsa_op(const DL_Group&, const BigInt&, const BigInt&);
+NR_Operation* nr_op(const DL_Group&, const BigInt&, const BigInt&);
+
+ELG_Operation* elg_op(const DL_Group&, const BigInt&, const BigInt&);
+
+DH_Operation* dh_op(const DL_Group&, const BigInt&);
+
+ECDSA_Operation* ecdsa_op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key);
+
+ECKAEG_Operation* eckaeg_op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key);
+
+}
+
+}
+
+#endif
diff --git a/src/core/libstate/get_enc.cpp b/src/core/libstate/get_enc.cpp
new file mode 100644
index 000000000..2459ef0a6
--- /dev/null
+++ b/src/core/libstate/get_enc.cpp
@@ -0,0 +1,228 @@
+/*************************************************
+* EMSA/EME/KDF/MGF Retrieval Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/lookup.h>
+#include <botan/libstate.h>
+#include <botan/parsing.h>
+#include <botan/util.h>
+
+#if defined(BOTAN_HAS_MGF1)
+ #include <botan/mgf1.h>
+#endif
+
+#if defined(BOTAN_HAS_EMSA1)
+ #include <botan/emsa1.h>
+#endif
+
+#if defined(BOTAN_HAS_EMSA2)
+ #include <botan/emsa2.h>
+#endif
+
+#if defined(BOTAN_HAS_EMSA3)
+ #include <botan/emsa3.h>
+#endif
+
+#if defined(BOTAN_HAS_EMSA4)
+ #include <botan/emsa4.h>
+#endif
+
+#if defined(BOTAN_HAS_EMSA_RAW)
+ #include <botan/emsa_raw.h>
+#endif
+
+#if defined(BOTAN_HAS_EME1)
+ #include <botan/eme1.h>
+#endif
+
+#if defined(BOTAN_HAS_EME_PKCS1v15)
+ #include <botan/eme_pkcs.h>
+#endif
+
+#if defined(BOTAN_HAS_KDF1)
+ #include <botan/kdf1.h>
+#endif
+
+#if defined(BOTAN_HAS_KDF2)
+ #include <botan/kdf2.h>
+#endif
+
+#if defined(BOTAN_HAS_X942_PRF)
+ #include <botan/prf_x942.h>
+#endif
+
+#if defined(BOTAN_HAS_SSL_V3_PRF)
+ #include <botan/prf_ssl3.h>
+#endif
+
+#if defined(BOTAN_HAS_TLS_V10_PRF)
+ #include <botan/prf_tls.h>
+#endif
+
+namespace Botan {
+
+/*************************************************
+* Get an EMSA by name *
+*************************************************/
+EMSA* get_emsa(const std::string& algo_spec)
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ const std::string emsa_name = global_state().deref_alias(name[0]);
+
+#if defined(BOTAN_HAS_EMSA_RAW)
+ if(emsa_name == "Raw")
+ {
+ if(name.size() == 1)
+ return new EMSA_Raw;
+ }
+#endif
+
+#if defined(BOTAN_HAS_EMSA1)
+ if(emsa_name == "EMSA1")
+ {
+ if(name.size() == 2)
+ return new EMSA1(get_hash(name[1]));
+ }
+#endif
+
+#if defined(BOTAN_HAS_EMSA2)
+ if(emsa_name == "EMSA2")
+ {
+ if(name.size() == 2)
+ return new EMSA2(get_hash(name[1]));
+ }
+#endif
+
+#if defined(BOTAN_HAS_EMSA3)
+ if(emsa_name == "EMSA3")
+ {
+ if(name.size() == 2)
+ return new EMSA3(get_hash(name[1]));
+ }
+#endif
+
+#if defined(BOTAN_HAS_EMSA4)
+ if(emsa_name == "EMSA4")
+ {
+ // EMSA4 is hardcoded to use MGF1
+ if(name.size() >= 3 && name[2] != "MGF1")
+ throw Algorithm_Not_Found(algo_spec);
+
+ if(name.size() == 2 || name.size() == 3)
+ return new EMSA4(get_hash(name[1]));
+ else if(name.size() == 4)
+ return new EMSA4(get_hash(name[1]), to_u32bit(name[3]));
+ }
+#endif
+
+ throw Algorithm_Not_Found(algo_spec);
+ }
+
+/*************************************************
+* Get an EME by name *
+*************************************************/
+EME* get_eme(const std::string& algo_spec)
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ const std::string eme_name = global_state().deref_alias(name[0]);
+
+#if defined(BOTAN_HAS_EME_PKCS1v15)
+ if(eme_name == "PKCS1v15")
+ {
+ if(name.size() == 1)
+ return new EME_PKCS1v15;
+ }
+#endif
+
+#if defined(BOTAN_HAS_EME1)
+ if(eme_name == "EME1")
+ {
+ if(name.size() >= 2)
+ {
+ if(name.size() >= 3)
+ {
+ // EME1 is hardcoded for MGF1
+ if(name[2] != "MGF1")
+ throw Algorithm_Not_Found(algo_spec);
+ }
+
+ return new EME1(get_hash(name[1]));
+ }
+ }
+#endif
+
+ throw Algorithm_Not_Found(algo_spec);
+ }
+
+/*************************************************
+* Get an KDF by name *
+*************************************************/
+KDF* get_kdf(const std::string& algo_spec)
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ const std::string kdf_name = global_state().deref_alias(name[0]);
+
+#if defined(BOTAN_HAS_KDF1)
+ if(kdf_name == "KDF1")
+ {
+ if(name.size() == 2)
+ return new KDF1(get_hash(name[1]));
+ }
+#endif
+
+#if defined(BOTAN_HAS_KDF2)
+ if(kdf_name == "KDF2")
+ {
+ if(name.size() == 2)
+ return new KDF2(get_hash(name[1]));
+ }
+#endif
+
+#if defined(BOTAN_HAS_X942_PRF)
+ if(kdf_name == "X9.42-PRF")
+ {
+ if(name.size() == 2)
+ return new X942_PRF(name[1]);
+ }
+#endif
+
+#if defined(BOTAN_HAS_TLS_V10_PRF)
+ if(kdf_name == "TLS-PRF")
+ {
+ if(name.size() == 1)
+ return new TLS_PRF;
+ }
+#endif
+
+#if defined(BOTAN_HAS_SSL_V3_PRF)
+ if(kdf_name == "SSL3-PRF")
+ {
+ if(name.size() == 1)
+ return new SSL3_PRF;
+ }
+#endif
+
+ throw Algorithm_Not_Found(algo_spec);
+ }
+
+/*************************************************
+* Get a MGF by name *
+*************************************************/
+MGF* get_mgf(const std::string& algo_spec)
+ {
+ std::vector<std::string> name = parse_algorithm_name(algo_spec);
+ const std::string mgf_name = global_state().deref_alias(name[0]);
+
+#ifdef BOTAN_HAS_MGF1
+ if(mgf_name == "MGF1")
+ {
+ if(name.size() == 2)
+ return new MGF1(get_hash(name[1]));
+ }
+#endif
+
+ throw Algorithm_Not_Found(algo_spec);
+ }
+
+}
diff --git a/src/core/libstate/get_pbe.cpp b/src/core/libstate/get_pbe.cpp
new file mode 100644
index 000000000..cd1ed2aa4
--- /dev/null
+++ b/src/core/libstate/get_pbe.cpp
@@ -0,0 +1,87 @@
+/*************************************************
+* PBE Retrieval Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/get_pbe.h>
+#include <botan/oids.h>
+#include <botan/parsing.h>
+
+#if defined(BOTAN_HAS_PBE_PKCS_V15)
+ #include <botan/pbes1.h>
+#endif
+
+#if defined(BOTAN_HAS_PBE_PKCS_V20)
+ #include <botan/pbes2.h>
+#endif
+
+namespace Botan {
+
+/*************************************************
+* Get an encryption PBE, set new parameters *
+*************************************************/
+PBE* get_pbe(const std::string& pbe_name)
+ {
+ std::vector<std::string> algo_name;
+ algo_name = parse_algorithm_name(pbe_name);
+
+ if(algo_name.size() != 3)
+ throw Invalid_Algorithm_Name(pbe_name);
+
+ const std::string pbe = algo_name[0];
+ const std::string digest = algo_name[1];
+ const std::string cipher = algo_name[2];
+
+ PBE* pbe_obj = 0;
+
+#if defined(BOTAN_HAS_PBE_PKCS_V15)
+ if(!pbe_obj && pbe == "PBE-PKCS5v15")
+ pbe_obj = new PBE_PKCS5v15(digest, cipher, ENCRYPTION);
+#endif
+
+#if defined(BOTAN_HAS_PBE_PKCS_V20)
+ if(!pbe_obj && pbe == "PBE-PKCS5v20")
+ pbe_obj = new PBE_PKCS5v20(digest, cipher);
+#endif
+
+ if(!pbe_obj)
+ throw Algorithm_Not_Found(pbe_name);
+
+ return pbe_obj;
+ }
+
+/*************************************************
+* Get a decryption PBE, decode parameters *
+*************************************************/
+PBE* get_pbe(const OID& pbe_oid, DataSource& params)
+ {
+ std::vector<std::string> algo_name;
+ algo_name = parse_algorithm_name(OIDS::lookup(pbe_oid));
+
+ if(algo_name.size() < 1)
+ throw Invalid_Algorithm_Name(pbe_oid.as_string());
+ const std::string pbe_algo = algo_name[0];
+
+ if(pbe_algo == "PBE-PKCS5v15")
+ {
+#if defined(BOTAN_HAS_PBE_PKCS_V15)
+ if(algo_name.size() != 3)
+ throw Invalid_Algorithm_Name(pbe_oid.as_string());
+ const std::string digest = algo_name[1];
+ const std::string cipher = algo_name[2];
+ PBE* pbe = new PBE_PKCS5v15(digest, cipher, DECRYPTION);
+ pbe->decode_params(params);
+ return pbe;
+#endif
+ }
+ else if(pbe_algo == "PBE-PKCS5v20")
+ {
+#if defined(BOTAN_HAS_PBE_PKCS_V20)
+ return new PBE_PKCS5v20(params);
+#endif
+ }
+
+ throw Algorithm_Not_Found(pbe_oid.as_string());
+ }
+
+}
diff --git a/src/core/libstate/get_pbe.h b/src/core/libstate/get_pbe.h
new file mode 100644
index 000000000..e7b434c1f
--- /dev/null
+++ b/src/core/libstate/get_pbe.h
@@ -0,0 +1,22 @@
+/*************************************************
+* PBE Lookup Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_LOOKUP_PBE_H__
+#define BOTAN_LOOKUP_PBE_H__
+
+#include <botan/pbe.h>
+#include <string>
+
+namespace Botan {
+
+/*************************************************
+* Get a PBE object *
+*************************************************/
+BOTAN_DLL PBE* get_pbe(const std::string&);
+BOTAN_DLL PBE* get_pbe(const OID&, DataSource&);
+
+}
+
+#endif
diff --git a/src/core/libstate/info.txt b/src/core/libstate/info.txt
new file mode 100644
index 000000000..f160ca771
--- /dev/null
+++ b/src/core/libstate/info.txt
@@ -0,0 +1,31 @@
+realname "Botan Libstate Module"
+
+load_on auto
+
+define LIBSTATE_MODULE
+
+<add>
+def_alg.cpp
+def_mode.cpp
+eng_base.cpp
+engine.cpp
+engine.h
+get_enc.cpp
+get_pbe.cpp
+get_pbe.h
+init.h
+init_def.cpp
+init_opt.cpp
+libstate.cpp
+libstate.h
+look_add.h
+look_pk.cpp
+look_pk.h
+lookup.cpp
+lookup.h
+modules.cpp
+modules.h
+oids.cpp
+oids.h
+policy.cpp
+</add>
diff --git a/src/core/libstate/init.h b/src/core/libstate/init.h
new file mode 100644
index 000000000..f4296a868
--- /dev/null
+++ b/src/core/libstate/init.h
@@ -0,0 +1,50 @@
+/*************************************************
+* Library Initialization Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_INIT_H__
+#define BOTAN_INIT_H__
+
+#include <botan/build.h>
+#include <string>
+#include <map>
+
+namespace Botan {
+
+/*************************************************
+* Options for initializing the library *
+*************************************************/
+class BOTAN_DLL InitializerOptions
+ {
+ public:
+ bool thread_safe() const;
+ bool use_engines() const;
+ bool secure_memory() const;
+ bool fips_mode() const;
+ bool self_test() const;
+
+ InitializerOptions(const std::string&);
+ private:
+ std::map<std::string, std::string> args;
+ };
+
+/*************************************************
+* Library Initialization/Shutdown Object *
+*************************************************/
+class BOTAN_DLL LibraryInitializer
+ {
+ public:
+ static void initialize(const std::string& = "");
+ static void initialize(const InitializerOptions&);
+ static void initialize(const InitializerOptions&, class Modules&);
+ static void deinitialize();
+
+ LibraryInitializer(const std::string& args = "") { initialize(args); }
+ LibraryInitializer(const InitializerOptions& args) { initialize(args); }
+ ~LibraryInitializer() { deinitialize(); }
+ };
+
+}
+
+#endif
diff --git a/src/core/libstate/init_def.cpp b/src/core/libstate/init_def.cpp
new file mode 100644
index 000000000..03f97252e
--- /dev/null
+++ b/src/core/libstate/init_def.cpp
@@ -0,0 +1,60 @@
+/*************************************************
+* Default Initialization Function Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/init.h>
+#include <botan/libstate.h>
+#include <botan/modules.h>
+
+namespace Botan {
+
+/*************************************************
+* Library Initialization *
+*************************************************/
+void LibraryInitializer::initialize(const InitializerOptions& args,
+ Modules& modules)
+ {
+ try
+ {
+ set_global_state(new Library_State);
+
+ global_state().initialize(args, modules);
+ }
+ catch(...)
+ {
+ deinitialize();
+ throw;
+ }
+ }
+
+/*************************************************
+* Library Shutdown *
+*************************************************/
+void LibraryInitializer::deinitialize()
+ {
+ set_global_state(0);
+ }
+
+/*************************************************
+* Library Initialization *
+*************************************************/
+void LibraryInitializer::initialize(const std::string& arg_string)
+ {
+ InitializerOptions args(arg_string);
+ Builtin_Modules modules(args);
+
+ initialize(args, modules);
+ }
+
+/*************************************************
+* Library Initialization *
+*************************************************/
+void LibraryInitializer::initialize(const InitializerOptions& args)
+ {
+ Builtin_Modules modules(args);
+
+ initialize(args, modules);
+ }
+
+}
diff --git a/src/core/libstate/init_opt.cpp b/src/core/libstate/init_opt.cpp
new file mode 100644
index 000000000..5c4fbee65
--- /dev/null
+++ b/src/core/libstate/init_opt.cpp
@@ -0,0 +1,102 @@
+/*************************************************
+* Initialization Options Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/init.h>
+#include <botan/parsing.h>
+#include <botan/stl_util.h>
+#include <botan/exceptn.h>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Check for an arbitrary boolean-valued option *
+*************************************************/
+bool boolean_arg(const std::map<std::string, std::string>& args,
+ const std::string& key, bool not_found = false)
+ {
+ std::map<std::string, std::string>::const_iterator i = args.find(key);
+ if(i == args.end())
+ return not_found;
+
+ std::string value = i->second;
+
+ if(value == "1" || value == "true" || value == "yes" || value == "on")
+ return true;
+ if(value == "0" || value == "false" || value == "no" || value == "off")
+ return false;
+ if(value == "default")
+ return not_found;
+
+ throw Invalid_Argument("InitializerOptions: Bad argument for boolean " +
+ key + " of '" + value + "'");
+ }
+
+}
+
+/*************************************************
+* Check if thread safety was requested *
+*************************************************/
+bool InitializerOptions::thread_safe() const
+ {
+ return boolean_arg(args, "thread_safe");
+ }
+
+/*************************************************
+* Check if secure allocation was requested *
+*************************************************/
+bool InitializerOptions::secure_memory() const
+ {
+ return boolean_arg(args, "secure_memory");
+ }
+
+/*************************************************
+* Check if using engines was requested *
+*************************************************/
+bool InitializerOptions::use_engines() const
+ {
+ return boolean_arg(args, "use_engines");
+ }
+
+/*************************************************
+* Check if FIPS mode was requested *
+*************************************************/
+bool InitializerOptions::fips_mode() const
+ {
+ return boolean_arg(args, "fips140");
+ }
+
+/*************************************************
+* Check if startup self tests were requested *
+*************************************************/
+bool InitializerOptions::self_test() const
+ {
+ return boolean_arg(args, "selftest", true);
+ }
+
+/*************************************************
+* Setup an InitializerOptions *
+*************************************************/
+InitializerOptions::InitializerOptions(const std::string& arg_string)
+ {
+ const std::vector<std::string> arg_list = split_on(arg_string, ' ');
+
+ for(u32bit j = 0; j != arg_list.size(); ++j)
+ {
+ if(arg_list[j].size() == 0)
+ continue;
+
+ if(arg_list[j].find('=') == std::string::npos)
+ args[arg_list[j]] = "true";
+ else
+ {
+ std::vector<std::string> name_and_value = split_on(arg_list[j], '=');
+ args[name_and_value[0]] = name_and_value[1];
+ }
+ }
+ }
+
+}
diff --git a/src/core/libstate/libstate.cpp b/src/core/libstate/libstate.cpp
new file mode 100644
index 000000000..60bb24fee
--- /dev/null
+++ b/src/core/libstate/libstate.cpp
@@ -0,0 +1,294 @@
+/*************************************************
+* Library Internal/Global State Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/libstate.h>
+#include <botan/modules.h>
+#include <botan/engine.h>
+#include <botan/stl_util.h>
+#include <botan/mutex.h>
+#include <botan/charset.h>
+#include <botan/lookup.h>
+#include <algorithm>
+
+#if defined(BOTAN_HAS_SELFTEST)
+ #include <botan/selftest.h>
+#endif
+
+namespace Botan {
+
+/*************************************************
+* Botan's global state *
+*************************************************/
+namespace {
+
+Library_State* global_lib_state = 0;
+
+}
+
+/*************************************************
+* Access the global state object *
+*************************************************/
+Library_State& global_state()
+ {
+ if(!global_lib_state)
+ LibraryInitializer::initialize();
+ return (*global_lib_state);
+ }
+
+/*************************************************
+* Set a new global state object *
+*************************************************/
+void set_global_state(Library_State* new_state)
+ {
+ delete swap_global_state(new_state);
+ }
+
+/*************************************************
+* Swap two global state objects *
+*************************************************/
+Library_State* swap_global_state(Library_State* new_state)
+ {
+ Library_State* old_state = global_lib_state;
+ global_lib_state = new_state;
+ return old_state;
+ }
+
+/*************************************************
+* Increment the Engine iterator *
+*************************************************/
+Engine* Library_State::Engine_Iterator::next()
+ {
+ return lib.get_engine_n(n++);
+ }
+
+/*************************************************
+* Get a new mutex object *
+*************************************************/
+Mutex* Library_State::get_mutex() const
+ {
+ return mutex_factory->make();
+ }
+
+/*************************************************
+* Get an allocator by its name *
+*************************************************/
+Allocator* Library_State::get_allocator(const std::string& type) const
+ {
+ Mutex_Holder lock(allocator_lock);
+
+ if(type != "")
+ return search_map<std::string, Allocator*>(alloc_factory, type, 0);
+
+ if(!cached_default_allocator)
+ {
+ std::string chosen = this->option("base/default_allocator");
+
+ if(chosen == "")
+ chosen = "malloc";
+
+ cached_default_allocator =
+ search_map<std::string, Allocator*>(alloc_factory, chosen, 0);
+ }
+
+ return cached_default_allocator;
+ }
+
+/*************************************************
+* Create a new name to object mapping *
+*************************************************/
+void Library_State::add_allocator(Allocator* allocator)
+ {
+ Mutex_Holder lock(allocator_lock);
+
+ allocator->init();
+
+ allocators.push_back(allocator);
+ alloc_factory[allocator->type()] = allocator;
+ }
+
+/*************************************************
+* Set the default allocator type *
+*************************************************/
+void Library_State::set_default_allocator(const std::string& type)
+ {
+ Mutex_Holder lock(allocator_lock);
+
+ if(type == "")
+ return;
+
+ this->set("conf", "base/default_allocator", type);
+ cached_default_allocator = 0;
+ }
+
+/*************************************************
+* Get an engine out of the list *
+*************************************************/
+Engine* Library_State::get_engine_n(u32bit n) const
+ {
+ Mutex_Holder lock(engine_lock);
+
+ if(n >= engines.size())
+ return 0;
+ return engines[n];
+ }
+
+/*************************************************
+* Add a new engine to the list *
+*************************************************/
+void Library_State::add_engine(Engine* engine)
+ {
+ Mutex_Holder lock(engine_lock);
+ engines.insert(engines.begin(), engine);
+ }
+
+/*************************************************
+* Get a configuration value *
+*************************************************/
+std::string Library_State::get(const std::string& section,
+ const std::string& key) const
+ {
+ Mutex_Holder lock(config_lock);
+
+ return search_map<std::string, std::string>(config,
+ section + "/" + key, "");
+ }
+
+/*************************************************
+* See if a particular option has been set *
+*************************************************/
+bool Library_State::is_set(const std::string& section,
+ const std::string& key) const
+ {
+ Mutex_Holder lock(config_lock);
+
+ return search_map(config, section + "/" + key, false, true);
+ }
+
+/*************************************************
+* Set a configuration value *
+*************************************************/
+void Library_State::set(const std::string& section, const std::string& key,
+ const std::string& value, bool overwrite)
+ {
+ Mutex_Holder lock(config_lock);
+
+ std::string full_key = section + "/" + key;
+
+ std::map<std::string, std::string>::const_iterator i =
+ config.find(full_key);
+
+ if(overwrite || i == config.end() || i->second == "")
+ config[full_key] = value;
+ }
+
+/*************************************************
+* Add an alias *
+*************************************************/
+void Library_State::add_alias(const std::string& key, const std::string& value)
+ {
+ set("alias", key, value);
+ }
+
+/*************************************************
+* Dereference an alias to a fixed name *
+*************************************************/
+std::string Library_State::deref_alias(const std::string& key) const
+ {
+ std::string result = key;
+ while(is_set("alias", result))
+ result = get("alias", result);
+ return result;
+ }
+
+/*************************************************
+* Set/Add an option *
+*************************************************/
+void Library_State::set_option(const std::string key,
+ const std::string& value)
+ {
+ set("conf", key, value);
+ }
+
+/*************************************************
+* Get an option value *
+*************************************************/
+std::string Library_State::option(const std::string& key) const
+ {
+ return get("conf", key);
+ }
+
+/*************************************************
+* Load a set of modules *
+*************************************************/
+void Library_State::initialize(const InitializerOptions& args,
+ Modules& modules)
+ {
+ if(mutex_factory)
+ throw Invalid_State("Library_State has already been initialized");
+
+ mutex_factory = modules.mutex_factory(args.thread_safe());
+
+ if(!mutex_factory)
+ throw Invalid_State("Could not acquire a mutex module at init");
+
+ allocator_lock = get_mutex();
+ engine_lock = get_mutex();
+ config_lock = get_mutex();
+
+ cached_default_allocator = 0;
+
+ std::vector<Allocator*> mod_allocs = modules.allocators(mutex_factory);
+ for(u32bit j = 0; j != mod_allocs.size(); ++j)
+ add_allocator(mod_allocs[j]);
+
+ set_default_allocator(modules.default_allocator());
+
+ load_default_config();
+
+ std::vector<Engine*> mod_engines = modules.engines();
+ for(u32bit j = 0; j != mod_engines.size(); ++j)
+ engines.push_back(mod_engines[j]);
+
+#if defined(BOTAN_HAS_SELFTEST)
+ if(args.fips_mode() || args.self_test())
+ {
+ if(!passes_self_tests())
+ throw Self_Test_Failure("Initialization self-tests");
+ }
+#endif
+ }
+
+/*************************************************
+* Library_State Constructor *
+*************************************************/
+Library_State::Library_State()
+ {
+ mutex_factory = 0;
+ allocator_lock = engine_lock = config_lock = 0;
+ cached_default_allocator = 0;
+ }
+
+/*************************************************
+* Library_State Destructor *
+*************************************************/
+Library_State::~Library_State()
+ {
+ std::for_each(engines.begin(), engines.end(), del_fun<Engine>());
+
+ cached_default_allocator = 0;
+
+ for(u32bit j = 0; j != allocators.size(); ++j)
+ {
+ allocators[j]->destroy();
+ delete allocators[j];
+ }
+
+ delete allocator_lock;
+ delete engine_lock;
+ delete mutex_factory;
+ delete config_lock;
+ }
+
+}
diff --git a/src/core/libstate/libstate.h b/src/core/libstate/libstate.h
new file mode 100644
index 000000000..4b1221c84
--- /dev/null
+++ b/src/core/libstate/libstate.h
@@ -0,0 +1,90 @@
+/*************************************************
+* Library Internal/Global State Header File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_LIB_STATE_H__
+#define BOTAN_LIB_STATE_H__
+
+#include <botan/base.h>
+#include <botan/init.h>
+#include <string>
+#include <vector>
+#include <map>
+
+namespace Botan {
+
+/*************************************************
+* Global State Container Base *
+*************************************************/
+class BOTAN_DLL Library_State
+ {
+ public:
+ Library_State();
+ ~Library_State();
+
+ void initialize(const InitializerOptions&, Modules&);
+
+ void load(Modules&);
+
+ void add_engine(class Engine*);
+
+ class BOTAN_DLL Engine_Iterator
+ {
+ public:
+ class Engine* next();
+ Engine_Iterator(const Library_State& l) : lib(l) { n = 0; }
+ private:
+ const Library_State& lib;
+ u32bit n;
+ };
+ friend class Engine_Iterator;
+
+ Allocator* get_allocator(const std::string& = "") const;
+ void add_allocator(Allocator*);
+ void set_default_allocator(const std::string&);
+
+ std::string get(const std::string&, const std::string&) const;
+ bool is_set(const std::string&, const std::string&) const;
+ void set(const std::string&, const std::string&,
+ const std::string&, bool = true);
+
+ std::string option(const std::string&) const;
+ void set_option(const std::string, const std::string&);
+
+ void add_alias(const std::string&, const std::string&);
+ std::string deref_alias(const std::string&) const;
+
+ class Mutex* get_mutex() const;
+ private:
+ void load_default_config();
+
+ Library_State(const Library_State&) {}
+ Library_State& operator=(const Library_State&) { return (*this); }
+
+ class Engine* get_engine_n(u32bit) const;
+
+ class Mutex_Factory* mutex_factory;
+
+ std::map<std::string, std::string> config;
+ class Mutex* config_lock;
+
+ class Mutex* allocator_lock;
+ std::map<std::string, Allocator*> alloc_factory;
+ mutable Allocator* cached_default_allocator;
+ std::vector<Allocator*> allocators;
+
+ class Mutex* engine_lock;
+ std::vector<class Engine*> engines;
+ };
+
+/*************************************************
+* Global State *
+*************************************************/
+BOTAN_DLL Library_State& global_state();
+BOTAN_DLL void set_global_state(Library_State*);
+BOTAN_DLL Library_State* swap_global_state(Library_State*);
+
+}
+
+#endif
diff --git a/src/core/libstate/look_add.h b/src/core/libstate/look_add.h
new file mode 100644
index 000000000..8c170049d
--- /dev/null
+++ b/src/core/libstate/look_add.h
@@ -0,0 +1,28 @@
+/*************************************************
+* Lookup Table Management Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_LOOKUP_MANGEMENT_H__
+#define BOTAN_LOOKUP_MANGEMENT_H__
+
+#include <botan/base.h>
+#include <botan/libstate.h>
+#include <botan/mode_pad.h>
+#include <botan/s2k.h>
+
+namespace Botan {
+
+/*************************************************
+* Add an algorithm to the lookup table *
+*************************************************/
+BOTAN_DLL void add_algorithm(Library_State&, BlockCipher*);
+BOTAN_DLL void add_algorithm(Library_State&, StreamCipher*);
+BOTAN_DLL void add_algorithm(Library_State&, HashFunction*);
+BOTAN_DLL void add_algorithm(Library_State&, MessageAuthenticationCode*);
+BOTAN_DLL void add_algorithm(Library_State&, S2K*);
+BOTAN_DLL void add_algorithm(Library_State&, BlockCipherModePaddingMethod*);
+
+}
+
+#endif
diff --git a/src/core/libstate/look_pk.cpp b/src/core/libstate/look_pk.cpp
new file mode 100644
index 000000000..a4062b57c
--- /dev/null
+++ b/src/core/libstate/look_pk.cpp
@@ -0,0 +1,74 @@
+/*************************************************
+* PK Algorithm Lookup Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/look_pk.h>
+#include <botan/lookup.h>
+
+namespace Botan {
+
+/*************************************************
+* Get a PK_Encryptor object *
+*************************************************/
+PK_Encryptor* get_pk_encryptor(const PK_Encrypting_Key& key,
+ const std::string& eme)
+ {
+ return new PK_Encryptor_MR_with_EME(key, eme);
+ }
+
+/*************************************************
+* Get a PK_Decryptor object *
+*************************************************/
+PK_Decryptor* get_pk_decryptor(const PK_Decrypting_Key& key,
+ const std::string& eme)
+ {
+ return new PK_Decryptor_MR_with_EME(key, eme);
+ }
+
+/*************************************************
+* Get a PK_Signer object *
+*************************************************/
+PK_Signer* get_pk_signer(const PK_Signing_Key& key,
+ const std::string& encoding,
+ Signature_Format sig_format)
+ {
+ PK_Signer* signer = new PK_Signer(key, encoding);
+ signer->set_output_format(sig_format);
+ return signer;
+ }
+
+/*************************************************
+* Get a PK_Verifier object *
+*************************************************/
+PK_Verifier* get_pk_verifier(const PK_Verifying_with_MR_Key& key,
+ const std::string& encoding,
+ Signature_Format sig_format)
+ {
+ PK_Verifier* verifier = new PK_Verifier_with_MR(key, encoding);
+ verifier->set_input_format(sig_format);
+ return verifier;
+ }
+
+/*************************************************
+* Get a PK_Verifier object *
+*************************************************/
+PK_Verifier* get_pk_verifier(const PK_Verifying_wo_MR_Key& key,
+ const std::string& encoding,
+ Signature_Format sig_format)
+ {
+ PK_Verifier* verifier = new PK_Verifier_wo_MR(key, encoding);
+ verifier->set_input_format(sig_format);
+ return verifier;
+ }
+
+/*************************************************
+* Get a PK_Key_Agreement object *
+*************************************************/
+PK_Key_Agreement* get_pk_kas(const PK_Key_Agreement_Key& key,
+ const std::string& kdf)
+ {
+ return new PK_Key_Agreement(key, kdf);
+ }
+
+}
diff --git a/src/core/libstate/look_pk.h b/src/core/libstate/look_pk.h
new file mode 100644
index 000000000..63756ad22
--- /dev/null
+++ b/src/core/libstate/look_pk.h
@@ -0,0 +1,38 @@
+/*************************************************
+* PK Algorithm Lookup Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_PK_LOOKUP_H__
+#define BOTAN_PK_LOOKUP_H__
+
+#include <botan/pubkey.h>
+
+namespace Botan {
+
+/*************************************************
+* Get an PK algorithm object *
+*************************************************/
+BOTAN_DLL PK_Encryptor* get_pk_encryptor(const PK_Encrypting_Key&,
+ const std::string&);
+
+BOTAN_DLL PK_Decryptor* get_pk_decryptor(const PK_Decrypting_Key&,
+ const std::string&);
+
+BOTAN_DLL PK_Signer* get_pk_signer(const PK_Signing_Key&,
+ const std::string&,
+ Signature_Format = IEEE_1363);
+
+BOTAN_DLL PK_Verifier* get_pk_verifier(const PK_Verifying_with_MR_Key&,
+ const std::string&,
+ Signature_Format = IEEE_1363);
+BOTAN_DLL PK_Verifier* get_pk_verifier(const PK_Verifying_wo_MR_Key&,
+ const std::string&,
+ Signature_Format = IEEE_1363);
+
+BOTAN_DLL PK_Key_Agreement* get_pk_kas(const PK_Key_Agreement_Key&,
+ const std::string&);
+
+}
+
+#endif
diff --git a/src/core/libstate/lookup.cpp b/src/core/libstate/lookup.cpp
new file mode 100644
index 000000000..8e65afb93
--- /dev/null
+++ b/src/core/libstate/lookup.cpp
@@ -0,0 +1,239 @@
+/*************************************************
+* Algorithm Retrieval Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/lookup.h>
+#include <botan/libstate.h>
+
+namespace Botan {
+
+/*************************************************
+* Get a block cipher by name *
+*************************************************/
+BlockCipher* get_block_cipher(const std::string& name)
+ {
+ const BlockCipher* cipher = retrieve_block_cipher(global_state(), name);
+ if(cipher)
+ return cipher->clone();
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Get a stream cipher by name *
+*************************************************/
+StreamCipher* get_stream_cipher(const std::string& name)
+ {
+ const StreamCipher* cipher = retrieve_stream_cipher(global_state(), name);
+ if(cipher)
+ return cipher->clone();
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Get a hash function by name *
+*************************************************/
+HashFunction* get_hash(const std::string& name)
+ {
+ const HashFunction* hash = retrieve_hash(global_state(), name);
+ if(hash)
+ return hash->clone();
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Get a MAC by name *
+*************************************************/
+MessageAuthenticationCode* get_mac(const std::string& name)
+ {
+ const MessageAuthenticationCode* mac = retrieve_mac(global_state(), name);
+ if(mac)
+ return mac->clone();
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Get a S2K algorithm by name *
+*************************************************/
+S2K* get_s2k(const std::string& name)
+ {
+ const S2K* s2k = retrieve_s2k(global_state(), name);
+ if(s2k)
+ return s2k->clone();
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Get a block cipher padding method by name *
+*************************************************/
+const BlockCipherModePaddingMethod* get_bc_pad(const std::string& name)
+ {
+ const BlockCipherModePaddingMethod* pad =
+ retrieve_bc_pad(global_state(), name);
+
+ if(pad)
+ return pad;
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Query if an algorithm exists *
+*************************************************/
+bool have_algorithm(const std::string& name)
+ {
+ if(retrieve_block_cipher(global_state(), name))
+ return true;
+ if(retrieve_stream_cipher(global_state(), name))
+ return true;
+ if(retrieve_hash(global_state(), name))
+ return true;
+ if(retrieve_mac(global_state(), name))
+ return true;
+ return false;
+ }
+
+/*************************************************
+* Query if Botan has the named block cipher *
+*************************************************/
+bool have_block_cipher(const std::string& name)
+ {
+ return (retrieve_block_cipher(global_state(), name) != 0);
+ }
+
+/*************************************************
+* Query if Botan has the named stream cipher *
+*************************************************/
+bool have_stream_cipher(const std::string& name)
+ {
+ return (retrieve_stream_cipher(global_state(), name) != 0);
+ }
+
+/*************************************************
+* Query if Botan has the named hash function *
+*************************************************/
+bool have_hash(const std::string& name)
+ {
+ return (retrieve_hash(global_state(), name) != 0);
+ }
+
+/*************************************************
+* Query if Botan has the named MAC *
+*************************************************/
+bool have_mac(const std::string& name)
+ {
+ return (retrieve_mac(global_state(), name) != 0);
+ }
+
+/*************************************************
+* Query the block size of a cipher or hash *
+*************************************************/
+u32bit block_size_of(const std::string& name)
+ {
+ const BlockCipher* cipher = retrieve_block_cipher(global_state(), name);
+ if(cipher)
+ return cipher->BLOCK_SIZE;
+
+ const HashFunction* hash = retrieve_hash(global_state(), name);
+ if(hash)
+ return hash->HASH_BLOCK_SIZE;
+
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Query the OUTPUT_LENGTH of a hash or MAC *
+*************************************************/
+u32bit output_length_of(const std::string& name)
+ {
+ const HashFunction* hash = retrieve_hash(global_state(), name);
+ if(hash)
+ return hash->OUTPUT_LENGTH;
+
+ const MessageAuthenticationCode* mac = retrieve_mac(global_state(), name);
+ if(mac)
+ return mac->OUTPUT_LENGTH;
+
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Check if a keylength is valid for this algo *
+*************************************************/
+bool valid_keylength_for(u32bit key_len, const std::string& name)
+ {
+ const BlockCipher* bc = retrieve_block_cipher(global_state(), name);
+ if(bc)
+ return bc->valid_keylength(key_len);
+
+ const StreamCipher* sc = retrieve_stream_cipher(global_state(), name);
+ if(sc)
+ return sc->valid_keylength(key_len);
+
+ const MessageAuthenticationCode* mac = retrieve_mac(global_state(), name);
+ if(mac)
+ 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)
+ {
+ const BlockCipher* bc = retrieve_block_cipher(global_state(), name);
+ if(bc)
+ return bc->MINIMUM_KEYLENGTH;
+
+ const StreamCipher* sc = retrieve_stream_cipher(global_state(), name);
+ if(sc)
+ return sc->MINIMUM_KEYLENGTH;
+
+ const MessageAuthenticationCode* mac = retrieve_mac(global_state(), name);
+ if(mac)
+ return mac->MINIMUM_KEYLENGTH;
+
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Query the MAXIMUM_KEYLENGTH of an algorithm *
+*************************************************/
+u32bit max_keylength_of(const std::string& name)
+ {
+ const BlockCipher* bc = retrieve_block_cipher(global_state(), name);
+ if(bc)
+ return bc->MAXIMUM_KEYLENGTH;
+
+ const StreamCipher* sc = retrieve_stream_cipher(global_state(), name);
+ if(sc)
+ return sc->MAXIMUM_KEYLENGTH;
+
+ const MessageAuthenticationCode* mac = retrieve_mac(global_state(), name);
+ if(mac)
+ return mac->MAXIMUM_KEYLENGTH;
+
+ throw Algorithm_Not_Found(name);
+ }
+
+/*************************************************
+* Query the KEYLENGTH_MULTIPLE of an algorithm *
+*************************************************/
+u32bit keylength_multiple_of(const std::string& name)
+ {
+ const BlockCipher* bc = retrieve_block_cipher(global_state(), name);
+ if(bc)
+ return bc->KEYLENGTH_MULTIPLE;
+
+ const StreamCipher* sc = retrieve_stream_cipher(global_state(), name);
+ if(sc)
+ return sc->KEYLENGTH_MULTIPLE;
+
+ const MessageAuthenticationCode* mac = retrieve_mac(global_state(), name);
+ if(mac)
+ return mac->KEYLENGTH_MULTIPLE;
+
+ throw Algorithm_Not_Found(name);
+ }
+
+}
diff --git a/src/core/libstate/lookup.h b/src/core/libstate/lookup.h
new file mode 100644
index 000000000..016ad4618
--- /dev/null
+++ b/src/core/libstate/lookup.h
@@ -0,0 +1,98 @@
+/*************************************************
+* Algorithm Lookup Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_LOOKUP_H__
+#define BOTAN_LOOKUP_H__
+
+#include <botan/base.h>
+#include <botan/enums.h>
+#include <botan/filters.h>
+#include <botan/mode_pad.h>
+#include <botan/kdf.h>
+#include <botan/pk_pad.h>
+#include <botan/libstate.h>
+#include <botan/s2k.h>
+
+namespace Botan {
+
+/*************************************************
+* Retrieve an object from the lookup table *
+*************************************************/
+BOTAN_DLL const BlockCipher*
+retrieve_block_cipher(Library_State&, const std::string&);
+
+BOTAN_DLL const StreamCipher*
+retrieve_stream_cipher(Library_State&, const std::string&);
+
+BOTAN_DLL const HashFunction*
+retrieve_hash(Library_State&, const std::string&);
+
+BOTAN_DLL const MessageAuthenticationCode*
+retrieve_mac(Library_State&, const std::string&);
+
+BOTAN_DLL const S2K* retrieve_s2k(Library_State&, const std::string&);
+
+BOTAN_DLL const BlockCipherModePaddingMethod*
+retrieve_bc_pad(Library_State&, const std::string&);
+
+/*************************************************
+* Get an algorithm object *
+*************************************************/
+BOTAN_DLL BlockCipher* get_block_cipher(const std::string&);
+BOTAN_DLL StreamCipher* get_stream_cipher(const std::string&);
+BOTAN_DLL HashFunction* get_hash(const std::string&);
+BOTAN_DLL MessageAuthenticationCode* get_mac(const std::string&);
+BOTAN_DLL S2K* get_s2k(const std::string&);
+BOTAN_DLL const BlockCipherModePaddingMethod* get_bc_pad(const std::string&);
+
+/*************************************************
+* Get an EMSA/EME/KDF/MGF function *
+*************************************************/
+BOTAN_DLL EME* get_eme(const std::string&);
+BOTAN_DLL EMSA* get_emsa(const std::string&);
+BOTAN_DLL MGF* get_mgf(const std::string&);
+BOTAN_DLL KDF* get_kdf(const std::string&);
+
+/*************************************************
+* Get a cipher object *
+*************************************************/
+BOTAN_DLL Keyed_Filter* get_cipher(Library_State&,
+ const std::string&,
+ const SymmetricKey&,
+ const InitializationVector&,
+ Cipher_Dir);
+
+BOTAN_DLL Keyed_Filter* get_cipher(Library_State&,
+ const std::string&,
+ const SymmetricKey&,
+ Cipher_Dir);
+
+BOTAN_DLL Keyed_Filter* get_cipher(Library_State&,
+ const std::string&, Cipher_Dir);
+
+/*************************************************
+* Check to see if an algorithm exists *
+*************************************************/
+BOTAN_DLL bool have_algorithm(const std::string&);
+
+BOTAN_DLL bool have_block_cipher(const std::string&);
+BOTAN_DLL bool have_stream_cipher(const std::string&);
+BOTAN_DLL bool have_hash(const std::string&);
+BOTAN_DLL bool have_mac(const std::string&);
+
+/*************************************************
+* Query information about an algorithm *
+*************************************************/
+BOTAN_DLL u32bit block_size_of(const std::string&);
+BOTAN_DLL u32bit output_length_of(const std::string&);
+
+BOTAN_DLL bool valid_keylength_for(u32bit, const std::string&);
+BOTAN_DLL u32bit min_keylength_of(const std::string&);
+BOTAN_DLL u32bit max_keylength_of(const std::string&);
+BOTAN_DLL u32bit keylength_multiple_of(const std::string&);
+
+}
+
+#endif
diff --git a/src/core/libstate/modules.cpp b/src/core/libstate/modules.cpp
new file mode 100644
index 000000000..bdebc3460
--- /dev/null
+++ b/src/core/libstate/modules.cpp
@@ -0,0 +1,126 @@
+/*************************************************
+* Module Factory Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/modules.h>
+#include <botan/defalloc.h>
+#include <botan/eng_def.h>
+#include <botan/parsing.h>
+
+#if defined(BOTAN_HAS_MUTEX_PTHREAD)
+ #include <botan/mux_pthr.h>
+#elif defined(BOTAN_HAS_MUTEX_WIN32)
+ #include <botan/mux_win32.h>
+#elif defined(BOTAN_HAS_MUTEX_QT)
+ #include <botan/mux_qt.h>
+#endif
+
+#if defined(BOTAN_HAS_MUTEX_NOOP)
+ #include <botan/mux_noop.h>
+#endif
+
+#if defined(BOTAN_HAS_ALLOC_MMAP)
+ #include <botan/mmap_mem.h>
+#endif
+
+#if defined(BOTAN_HAS_ENGINE_GNU_MP)
+ #include <botan/eng_gmp.h>
+#endif
+
+#if defined(BOTAN_HAS_ENGINE_OPENSSL)
+ #include <botan/eng_ossl.h>
+#endif
+
+namespace Botan {
+
+/*************************************************
+* Return a mutex factory, if available *
+*************************************************/
+Mutex_Factory* Builtin_Modules::mutex_factory(bool thread_safe) const
+ {
+ if(!thread_safe)
+ {
+#if defined(BOTAN_HAS_MUTEX_NOOP)
+ return new Noop_Mutex_Factory;
+#endif
+ }
+
+#if defined(BOTAN_HAS_MUTEX_PTHREAD)
+ return new Pthread_Mutex_Factory;
+#elif defined(BOTAN_HAS_MUTEX_WIN32)
+ return new Win32_Mutex_Factory;
+#elif defined(BOTAN_HAS_MUTEX_QT)
+ return new Qt_Mutex_Factory;
+#else
+ return 0;
+#endif
+ }
+
+/*************************************************
+* Find any usable allocators *
+*************************************************/
+std::vector<Allocator*> Builtin_Modules::allocators(Mutex_Factory* mf) const
+ {
+ std::vector<Allocator*> allocators;
+
+#if defined(BOTAN_HAS_ALLOC_MMAP)
+ allocators.push_back(new MemoryMapping_Allocator(mf->make()));
+#endif
+
+ allocators.push_back(new Locking_Allocator(mf->make()));
+ allocators.push_back(new Malloc_Allocator);
+
+ return allocators;
+ }
+
+/*************************************************
+* Return the default allocator *
+*************************************************/
+std::string Builtin_Modules::default_allocator() const
+ {
+ if(should_lock)
+ {
+#if defined(BOTAN_HAS_ALLOC_MMAP)
+ return "mmap";
+#else
+ return "locking";
+#endif
+ }
+ else
+ return "malloc";
+ }
+
+/*************************************************
+* Find any usable engines *
+*************************************************/
+std::vector<Engine*> Builtin_Modules::engines() const
+ {
+ std::vector<Engine*> engines;
+
+ if(use_engines)
+ {
+#if defined(BOTAN_HAS_ENGINE_GNU_MP)
+ engines.push_back(new GMP_Engine);
+#endif
+
+#if defined(BOTAN_HAS_ENGINE_OPENSSL)
+ engines.push_back(new OpenSSL_Engine);
+#endif
+ }
+
+ engines.push_back(new Default_Engine);
+
+ return engines;
+ }
+
+/*************************************************
+* Builtin_Modules Constructor *
+*************************************************/
+Builtin_Modules::Builtin_Modules(const InitializerOptions& args) :
+ should_lock(args.secure_memory()),
+ use_engines(args.use_engines())
+ {
+ }
+
+}
diff --git a/src/core/libstate/modules.h b/src/core/libstate/modules.h
new file mode 100644
index 000000000..abbfbb2c6
--- /dev/null
+++ b/src/core/libstate/modules.h
@@ -0,0 +1,54 @@
+/*************************************************
+* Module Factory Header File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_MODULE_FACTORIES_H__
+#define BOTAN_MODULE_FACTORIES_H__
+
+#include <botan/init.h>
+#include <botan/mutex.h>
+#include <string>
+#include <vector>
+
+namespace Botan {
+
+/*************************************************
+* Module Builder Interface *
+*************************************************/
+class BOTAN_DLL Modules
+ {
+ public:
+ virtual class Mutex_Factory* mutex_factory(bool) const = 0;
+
+ virtual std::string default_allocator() const = 0;
+
+ virtual std::vector<class Allocator*>
+ allocators(Mutex_Factory*) const = 0;
+
+ virtual std::vector<class Engine*> engines() const = 0;
+
+ virtual ~Modules() {}
+ };
+
+/*************************************************
+* Built In Modules *
+*************************************************/
+class BOTAN_DLL Builtin_Modules : public Modules
+ {
+ public:
+ class Mutex_Factory* mutex_factory(bool) const;
+
+ std::string default_allocator() const;
+
+ std::vector<class Allocator*> allocators(Mutex_Factory*) const;
+ std::vector<class Engine*> engines() const;
+
+ Builtin_Modules(const InitializerOptions&);
+ private:
+ const bool should_lock, use_engines;
+ };
+
+}
+
+#endif
diff --git a/src/core/libstate/oids.cpp b/src/core/libstate/oids.cpp
new file mode 100644
index 000000000..0823625ea
--- /dev/null
+++ b/src/core/libstate/oids.cpp
@@ -0,0 +1,74 @@
+/*************************************************
+* OID Registry Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/oids.h>
+#include <botan/libstate.h>
+
+namespace Botan {
+
+namespace OIDS {
+
+/*************************************************
+* Register an OID to string mapping *
+*************************************************/
+void add_oid(const OID& oid, const std::string& name)
+ {
+ const std::string oid_str = oid.as_string();
+
+ if(!global_state().is_set("oid2str", oid_str))
+ global_state().set("oid2str", oid_str, name);
+ if(!global_state().is_set("str2oid", name))
+ global_state().set("str2oid", name, oid_str);
+ }
+
+/*************************************************
+* Do an OID to string lookup *
+*************************************************/
+std::string lookup(const OID& oid)
+ {
+ std::string name = global_state().get("oid2str", oid.as_string());
+ if(name == "")
+ return oid.as_string();
+ return name;
+ }
+
+/*************************************************
+* Do a string to OID lookup *
+*************************************************/
+OID lookup(const std::string& name)
+ {
+ std::string value = global_state().get("str2oid", name);
+ if(value != "")
+ return OID(value);
+
+ try
+ {
+ return OID(name);
+ }
+ catch(Exception)
+ {
+ throw Lookup_Error("No object identifier found for " + name);
+ }
+ }
+
+/*************************************************
+* Check to see if an OID exists in the table *
+*************************************************/
+bool have_oid(const std::string& name)
+ {
+ return global_state().is_set("str2oid", name);
+ }
+
+/*************************************************
+* Check to see if an OID exists in the table *
+*************************************************/
+bool name_of(const OID& oid, const std::string& name)
+ {
+ return (oid == lookup(name));
+ }
+
+}
+
+}
diff --git a/src/core/libstate/oids.h b/src/core/libstate/oids.h
new file mode 100644
index 000000000..b5be0e01f
--- /dev/null
+++ b/src/core/libstate/oids.h
@@ -0,0 +1,36 @@
+/*************************************************
+* OID Registry Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_OIDS_H__
+#define BOTAN_OIDS_H__
+
+#include <botan/asn1_oid.h>
+
+namespace Botan {
+
+namespace OIDS {
+
+/*************************************************
+* Register an OID to string mapping *
+*************************************************/
+BOTAN_DLL void add_oid(const OID&, const std::string&);
+
+/*************************************************
+* See if an OID exists in the internal table *
+*************************************************/
+BOTAN_DLL bool have_oid(const std::string&);
+
+/*************************************************
+* Perform OID<->string mappings *
+*************************************************/
+BOTAN_DLL std::string lookup(const OID&);
+BOTAN_DLL OID lookup(const std::string&);
+BOTAN_DLL bool name_of(const OID&, const std::string&);
+
+}
+
+}
+
+#endif
diff --git a/src/core/libstate/policy.cpp b/src/core/libstate/policy.cpp
new file mode 100644
index 000000000..39810760b
--- /dev/null
+++ b/src/core/libstate/policy.cpp
@@ -0,0 +1,492 @@
+/*************************************************
+* Default Policy Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/libstate.h>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* OID loading helper function *
+*************************************************/
+void add_oid(Library_State& config,
+ const std::string& oid_str,
+ const std::string& name)
+ {
+ if(!config.is_set("oid2str", oid_str))
+ config.set("oid2str", oid_str, name);
+ if(!config.is_set("str2oid", name))
+ config.set("str2oid", name, oid_str);
+ }
+
+/*************************************************
+* Load all of the default OIDs *
+*************************************************/
+void set_default_oids(Library_State& config)
+ {
+ add_oid(config, "1.2.840.113549.1.1.1", "RSA");
+ add_oid(config, "2.5.8.1.1", "RSA");
+ add_oid(config, "1.2.840.10040.4.1", "DSA");
+ add_oid(config, "1.2.840.10046.2.1", "DH");
+ add_oid(config, "1.3.6.1.4.1.3029.1.2.1", "ELG");
+ add_oid(config, "1.3.6.1.4.1.25258.1.1", "RW");
+ add_oid(config, "1.3.6.1.4.1.25258.1.2", "NR");
+
+ add_oid(config, "1.3.14.3.2.7", "DES/CBC");
+ add_oid(config, "1.2.840.113549.3.7", "TripleDES/CBC");
+ add_oid(config, "1.2.840.113549.3.2", "RC2/CBC");
+ add_oid(config, "1.2.840.113533.7.66.10", "CAST-128/CBC");
+ add_oid(config, "2.16.840.1.101.3.4.1.2", "AES-128/CBC");
+ add_oid(config, "2.16.840.1.101.3.4.1.22", "AES-192/CBC");
+ add_oid(config, "2.16.840.1.101.3.4.1.42", "AES-256/CBC");
+
+ add_oid(config, "1.2.840.113549.2.5", "MD5");
+ add_oid(config, "1.3.6.1.4.1.11591.12.2", "Tiger(24,3)");
+
+ add_oid(config, "1.3.14.3.2.26", "SHA-160");
+ add_oid(config, "2.16.840.1.101.3.4.2.4", "SHA-224");
+ add_oid(config, "2.16.840.1.101.3.4.2.1", "SHA-256");
+ add_oid(config, "2.16.840.1.101.3.4.2.2", "SHA-384");
+ add_oid(config, "2.16.840.1.101.3.4.2.3", "SHA-512");
+
+ add_oid(config, "1.2.840.113549.1.9.16.3.6", "KeyWrap.TripleDES");
+ add_oid(config, "1.2.840.113549.1.9.16.3.7", "KeyWrap.RC2");
+ add_oid(config, "1.2.840.113533.7.66.15", "KeyWrap.CAST-128");
+ add_oid(config, "2.16.840.1.101.3.4.1.5", "KeyWrap.AES-128");
+ add_oid(config, "2.16.840.1.101.3.4.1.25", "KeyWrap.AES-192");
+ add_oid(config, "2.16.840.1.101.3.4.1.45", "KeyWrap.AES-256");
+
+ add_oid(config, "1.2.840.113549.1.9.16.3.8", "Compression.Zlib");
+
+ add_oid(config, "1.2.840.113549.1.1.1", "RSA/EME-PKCS1-v1_5");
+ add_oid(config, "1.2.840.113549.1.1.2", "RSA/EMSA3(MD2)");
+ add_oid(config, "1.2.840.113549.1.1.4", "RSA/EMSA3(MD5)");
+ add_oid(config, "1.2.840.113549.1.1.5", "RSA/EMSA3(SHA-160)");
+ add_oid(config, "1.2.840.113549.1.1.11", "RSA/EMSA3(SHA-256)");
+ add_oid(config, "1.2.840.113549.1.1.12", "RSA/EMSA3(SHA-384)");
+ add_oid(config, "1.2.840.113549.1.1.13", "RSA/EMSA3(SHA-512)");
+ add_oid(config, "1.3.36.3.3.1.2", "RSA/EMSA3(RIPEMD-160)");
+
+ add_oid(config, "1.2.840.10040.4.3", "DSA/EMSA1(SHA-160)");
+ add_oid(config, "2.16.840.1.101.3.4.3.1", "DSA/EMSA1(SHA-224)");
+ add_oid(config, "2.16.840.1.101.3.4.3.2", "DSA/EMSA1(SHA-256)");
+
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.1.1", "RW/EMSA2(RIPEMD-160)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.1.2", "RW/EMSA2(SHA-160)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.1.3", "RW/EMSA2(SHA-224)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.1.4", "RW/EMSA2(SHA-256)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.1.5", "RW/EMSA2(SHA-384)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.1.6", "RW/EMSA2(SHA-512)");
+
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.2.1", "RW/EMSA4(RIPEMD-160)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.2.2", "RW/EMSA4(SHA-160)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.2.3", "RW/EMSA4(SHA-224)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.2.4", "RW/EMSA4(SHA-256)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.2.5", "RW/EMSA4(SHA-384)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.1.2.6", "RW/EMSA4(SHA-512)");
+
+ add_oid(config, "1.3.6.1.4.1.25258.2.2.1.1", "NR/EMSA2(RIPEMD-160)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.2.1.2", "NR/EMSA2(SHA-160)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.2.1.3", "NR/EMSA2(SHA-224)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.2.1.4", "NR/EMSA2(SHA-256)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.2.1.5", "NR/EMSA2(SHA-384)");
+ add_oid(config, "1.3.6.1.4.1.25258.2.2.1.6", "NR/EMSA2(SHA-512)");
+
+ add_oid(config, "2.5.4.3", "X520.CommonName");
+ add_oid(config, "2.5.4.4", "X520.Surname");
+ add_oid(config, "2.5.4.5", "X520.SerialNumber");
+ add_oid(config, "2.5.4.6", "X520.Country");
+ add_oid(config, "2.5.4.7", "X520.Locality");
+ add_oid(config, "2.5.4.8", "X520.State");
+ add_oid(config, "2.5.4.10", "X520.Organization");
+ add_oid(config, "2.5.4.11", "X520.OrganizationalUnit");
+ add_oid(config, "2.5.4.12", "X520.Title");
+ add_oid(config, "2.5.4.42", "X520.GivenName");
+ add_oid(config, "2.5.4.43", "X520.Initials");
+ add_oid(config, "2.5.4.44", "X520.GenerationalQualifier");
+ add_oid(config, "2.5.4.46", "X520.DNQualifier");
+ add_oid(config, "2.5.4.65", "X520.Pseudonym");
+
+ add_oid(config, "1.2.840.113549.1.5.12", "PKCS5.PBKDF2");
+ add_oid(config, "1.2.840.113549.1.5.1", "PBE-PKCS5v15(MD2,DES/CBC)");
+ add_oid(config, "1.2.840.113549.1.5.4", "PBE-PKCS5v15(MD2,RC2/CBC)");
+ add_oid(config, "1.2.840.113549.1.5.3", "PBE-PKCS5v15(MD5,DES/CBC)");
+ add_oid(config, "1.2.840.113549.1.5.6", "PBE-PKCS5v15(MD5,RC2/CBC)");
+ add_oid(config, "1.2.840.113549.1.5.10", "PBE-PKCS5v15(SHA-160,DES/CBC)");
+ add_oid(config, "1.2.840.113549.1.5.11", "PBE-PKCS5v15(SHA-160,RC2/CBC)");
+ add_oid(config, "1.2.840.113549.1.5.13", "PBE-PKCS5v20");
+
+ add_oid(config, "1.2.840.113549.1.9.1", "PKCS9.EmailAddress");
+ add_oid(config, "1.2.840.113549.1.9.2", "PKCS9.UnstructuredName");
+ add_oid(config, "1.2.840.113549.1.9.3", "PKCS9.ContentType");
+ add_oid(config, "1.2.840.113549.1.9.4", "PKCS9.MessageDigest");
+ add_oid(config, "1.2.840.113549.1.9.7", "PKCS9.ChallengePassword");
+ add_oid(config, "1.2.840.113549.1.9.14", "PKCS9.ExtensionRequest");
+
+ add_oid(config, "1.2.840.113549.1.7.1", "CMS.DataContent");
+ add_oid(config, "1.2.840.113549.1.7.2", "CMS.SignedData");
+ add_oid(config, "1.2.840.113549.1.7.3", "CMS.EnvelopedData");
+ add_oid(config, "1.2.840.113549.1.7.5", "CMS.DigestedData");
+ add_oid(config, "1.2.840.113549.1.7.6", "CMS.EncryptedData");
+ add_oid(config, "1.2.840.113549.1.9.16.1.2", "CMS.AuthenticatedData");
+ add_oid(config, "1.2.840.113549.1.9.16.1.9", "CMS.CompressedData");
+
+ add_oid(config, "2.5.29.14", "X509v3.SubjectKeyIdentifier");
+ add_oid(config, "2.5.29.15", "X509v3.KeyUsage");
+ add_oid(config, "2.5.29.17", "X509v3.SubjectAlternativeName");
+ add_oid(config, "2.5.29.18", "X509v3.IssuerAlternativeName");
+ add_oid(config, "2.5.29.19", "X509v3.BasicConstraints");
+ add_oid(config, "2.5.29.20", "X509v3.CRLNumber");
+ add_oid(config, "2.5.29.21", "X509v3.ReasonCode");
+ add_oid(config, "2.5.29.23", "X509v3.HoldInstructionCode");
+ add_oid(config, "2.5.29.24", "X509v3.InvalidityDate");
+ add_oid(config, "2.5.29.32", "X509v3.CertificatePolicies");
+ add_oid(config, "2.5.29.35", "X509v3.AuthorityKeyIdentifier");
+ add_oid(config, "2.5.29.36", "X509v3.PolicyConstraints");
+ add_oid(config, "2.5.29.37", "X509v3.ExtendedKeyUsage");
+
+ add_oid(config, "2.5.29.32.0", "X509v3.AnyPolicy");
+
+ add_oid(config, "1.3.6.1.5.5.7.3.1", "PKIX.ServerAuth");
+ add_oid(config, "1.3.6.1.5.5.7.3.2", "PKIX.ClientAuth");
+ add_oid(config, "1.3.6.1.5.5.7.3.3", "PKIX.CodeSigning");
+ add_oid(config, "1.3.6.1.5.5.7.3.4", "PKIX.EmailProtection");
+ add_oid(config, "1.3.6.1.5.5.7.3.5", "PKIX.IPsecEndSystem");
+ add_oid(config, "1.3.6.1.5.5.7.3.6", "PKIX.IPsecTunnel");
+ add_oid(config, "1.3.6.1.5.5.7.3.7", "PKIX.IPsecUser");
+ add_oid(config, "1.3.6.1.5.5.7.3.8", "PKIX.TimeStamping");
+ add_oid(config, "1.3.6.1.5.5.7.3.9", "PKIX.OCSPSigning");
+
+ add_oid(config, "1.3.6.1.5.5.7.8.5", "PKIX.XMPPAddr");
+ }
+
+/*************************************************
+* Set the default algorithm aliases *
+*************************************************/
+void set_default_aliases(Library_State& config)
+ {
+ config.add_alias("OpenPGP.Cipher.1", "IDEA");
+ config.add_alias("OpenPGP.Cipher.2", "TripleDES");
+ config.add_alias("OpenPGP.Cipher.3", "CAST-128");
+ config.add_alias("OpenPGP.Cipher.4", "Blowfish");
+ config.add_alias("OpenPGP.Cipher.5", "SAFER-SK(13)");
+ config.add_alias("OpenPGP.Cipher.7", "AES-128");
+ config.add_alias("OpenPGP.Cipher.8", "AES-192");
+ config.add_alias("OpenPGP.Cipher.9", "AES-256");
+ config.add_alias("OpenPGP.Cipher.10", "Twofish");
+
+ config.add_alias("OpenPGP.Digest.1", "MD5");
+ config.add_alias("OpenPGP.Digest.2", "SHA-1");
+ config.add_alias("OpenPGP.Digest.3", "RIPEMD-160");
+ config.add_alias("OpenPGP.Digest.5", "MD2");
+ config.add_alias("OpenPGP.Digest.6", "Tiger(24,3)");
+ config.add_alias("OpenPGP.Digest.7", "HAVAL(20,5)");
+ config.add_alias("OpenPGP.Digest.8", "SHA-256");
+
+ config.add_alias("TLS.Digest.0", "Parallel(MD5,SHA-160)");
+
+ config.add_alias("EME-PKCS1-v1_5", "PKCS1v15");
+ config.add_alias("OAEP-MGF1", "EME1");
+ config.add_alias("EME-OAEP", "EME1");
+ config.add_alias("X9.31", "EMSA2");
+ config.add_alias("EMSA-PKCS1-v1_5", "EMSA3");
+ config.add_alias("PSS-MGF1", "EMSA4");
+ config.add_alias("EMSA-PSS", "EMSA4");
+
+ config.add_alias("Rijndael", "AES");
+ config.add_alias("3DES", "TripleDES");
+ config.add_alias("DES-EDE", "TripleDES");
+ config.add_alias("CAST5", "CAST-128");
+ config.add_alias("SHA1", "SHA-160");
+ config.add_alias("SHA-1", "SHA-160");
+ config.add_alias("SEAL", "SEAL-3.0-BE");
+ config.add_alias("MARK-4", "ARC4(256)");
+ config.add_alias("OMAC", "CMAC");
+ }
+
+/*************************************************
+* Set the default configuration toggles *
+*************************************************/
+void set_default_config(Library_State& config)
+ {
+ config.set_option("base/default_allocator", "malloc");
+
+ config.set_option("pk/test/public", "basic");
+ config.set_option("pk/test/private", "basic");
+ config.set_option("pk/test/private_gen", "all");
+
+ config.set_option("x509/exts/basic_constraints", "critical");
+ config.set_option("x509/exts/subject_key_id", "yes");
+ config.set_option("x509/exts/authority_key_id", "yes");
+ config.set_option("x509/exts/subject_alternative_name", "yes");
+ config.set_option("x509/exts/issuer_alternative_name", "no");
+ config.set_option("x509/exts/key_usage", "critical");
+ config.set_option("x509/exts/extended_key_usage", "yes");
+ config.set_option("x509/exts/crl_number", "yes");
+ }
+
+/*************************************************
+* Set the built-in discrete log groups *
+*************************************************/
+void set_default_dl_groups(Library_State& config)
+ {
+ config.set("dl", "modp/ietf/768",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIHIAmEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxObIlFK"
+ "CHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjo2IP//"
+ "////////AgECAmB//////////+SH7VEQtGEaYmMxRcBuDmiUgScERTPmOgEF31Md"
+ "ic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4obp/Catrao4SLyQtq7MS8/Y3omIXTT"
+ "HRsQf/////////8="
+ "-----END X942 DH PARAMETERS-----");
+
+ config.set("dl", "modp/ietf/1024",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIIBCgKBgQD//////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAILvqY7E5si"
+ "UUoIeY40BN3vlRmzzTpDGzArCm3yXxQ3T+E1bW1RwkXkhbV2Yl5+xvRMQummN+1r"
+ "C/9ctvQGt+3uOGv7Womfpa6fJBF8Sx/mSShmUezmU4H//////////wIBAgKBgH//"
+ "////////5IftURC0YRpiYzFFwG4OaJSBJwRFM+Y6AQXfUx2JzZEopQQ8xxoCbvfK"
+ "jNnmnSGNmBWFNvkvihun8Jq2tqjhIvJC2rsxLz9jeiYhdNMb9rWF/65begNb9vcc"
+ "Nf2tRM/S10+SCL4lj/MklDMo9nMpwP//////////"
+ "-----END X942 DH PARAMETERS-----");
+
+ config.set("dl", "modp/ietf/1536",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIIBigKBwQD//////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAILvqY7E5si"
+ "UUoIeY40BN3vlRmzzTpDGzArCm3yXxQ3T+E1bW1RwkXkhbV2Yl5+xvRMQummN+1r"
+ "C/9ctvQGt+3uOGv7Womfpa6fJBF8Sx/mSShmUezkWz3CAHy4oWO/BZjaSDYcVdOa"
+ "aRY/qP0kz1+DZV0j3KOtlhxi81YghVK7ntUpB3CWlm1nDDVOSryYBPF0bAjKI3Mn"
+ "//////////8CAQICgcB//////////+SH7VEQtGEaYmMxRcBuDmiUgScERTPmOgEF"
+ "31Mdic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4obp/Catrao4SLyQtq7MS8/Y3om"
+ "IXTTG/a1hf+uW3oDW/b3HDX9rUTP0tdPkgi+JY/zJJQzKPZyLZ7hAD5cULHfgsxt"
+ "JBsOKunNNIsf1H6SZ6/Bsq6R7lHWyw4xeasQQqldz2qUg7hLSzazhhqnJV5MAni6"
+ "NgRlEbmT//////////8="
+ "-----END X942 DH PARAMETERS-----");
+
+ config.set("dl", "modp/ietf/2048",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIICDAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
+ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
+ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
+ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
+ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
+ "5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAgKCAQB//////////+SH7VEQtGEa"
+ "YmMxRcBuDmiUgScERTPmOgEF31Mdic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4ob"
+ "p/Catrao4SLyQtq7MS8/Y3omIXTTG/a1hf+uW3oDW/b3HDX9rUTP0tdPkgi+JY/z"
+ "JJQzKPZyLZ7hAD5cULHfgsxtJBsOKunNNIsf1H6SZ6/Bsq6R7lHWyw4xeasQQqld"
+ "z2qUg7hLSzazhhqnJV5MAni6NgRlDBC+GUgvIxcbZx3xzzuWDAdDAc2TwdF2A9FH"
+ "2uKu+DemKWTvFeX7SqwLjBzKpL51SrVyiukTDEx9AogKuUctRVZVNH//////////"
+ "-----END X942 DH PARAMETERS-----");
+
+ config.set("dl", "modp/ietf/3072",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIIDDAKCAYEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
+ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
+ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
+ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
+ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
+ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
+ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
+ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqTrS"
+ "yv//////////AgECAoIBgH//////////5IftURC0YRpiYzFFwG4OaJSBJwRFM+Y6"
+ "AQXfUx2JzZEopQQ8xxoCbvfKjNnmnSGNmBWFNvkvihun8Jq2tqjhIvJC2rsxLz9j"
+ "eiYhdNMb9rWF/65begNb9vccNf2tRM/S10+SCL4lj/MklDMo9nItnuEAPlxQsd+C"
+ "zG0kGw4q6c00ix/UfpJnr8GyrpHuUdbLDjF5qxBCqV3PapSDuEtLNrOGGqclXkwC"
+ "eLo2BGUMEL4ZSC8jFxtnHfHPO5YMB0MBzZPB0XYD0Ufa4q74N6YpZO8V5ftKrAuM"
+ "HMqkvnVKtXKK6RMMTH0CiAq5Ry1FVWIW1pmLhoIoPRnUKpDV745dMnZ9woIsbfeF"
+ "RXU4q66DBj7Zy4fC03DyY9X610ZthJnrj0ZKcCUSsM7ncekTDWl3NfiX/QNsxQQy"
+ "bDsBOZ9kNTIpD5WMC72QBl3wi6u9MK62O4TEYF1so3EEcSfQOnLVmKHtrf5wfohH"
+ "JcFokFSdaWV//////////w=="
+ "-----END X942 DH PARAMETERS-----");
+
+ config.set("dl", "modp/ietf/4096",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIIEDAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
+ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
+ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
+ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
+ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
+ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
+ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
+ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI"
+ "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O"
+ "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI"
+ "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQICggIA"
+ "f//////////kh+1RELRhGmJjMUXAbg5olIEnBEUz5joBBd9THYnNkSilBDzHGgJu"
+ "98qM2eadIY2YFYU2+S+KG6fwmra2qOEi8kLauzEvP2N6JiF00xv2tYX/rlt6A1v2"
+ "9xw1/a1Ez9LXT5IIviWP8ySUMyj2ci2e4QA+XFCx34LMbSQbDirpzTSLH9R+kmev"
+ "wbKuke5R1ssOMXmrEEKpXc9qlIO4S0s2s4YapyVeTAJ4ujYEZQwQvhlILyMXG2cd"
+ "8c87lgwHQwHNk8HRdgPRR9rirvg3pilk7xXl+0qsC4wcyqS+dUq1corpEwxMfQKI"
+ "CrlHLUVVYhbWmYuGgig9GdQqkNXvjl0ydn3Cgixt94VFdTirroMGPtnLh8LTcPJj"
+ "1frXRm2EmeuPRkpwJRKwzudx6RMNaXc1+Jf9A2zFBDJsOwE5n2Q1MikPlYwLvZAG"
+ "XfCLq70wrrY7hMRgXWyjcQRxJ9A6ctWYoe2t/nB+iEclwWiQVJCEAI05HglTw/Nr"
+ "xDjNCF7dLZNM4ZOMNXpxHg1KNBpbCoXtEsH05RVqJnRt3eFtgm9HfJdHfgoP32VT"
+ "FD4so6c14C7M2Usn0Ehh0RGd0MMorfP2j7CUuGdxa9fcDe67ELgkDmgDSJPq2C1U"
+ "ydp1TEbH7uDDf9vuSFNgR6b6GuSaAxjM//////////8="
+ "-----END X942 DH PARAMETERS-----");
+
+ config.set("dl", "modp/ietf/6144",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIIGDAKCAwEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
+ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
+ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
+ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
+ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
+ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
+ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
+ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI"
+ "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O"
+ "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI"
+ "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG"
+ "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU"
+ "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId"
+ "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha"
+ "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/"
+ "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebcxA"
+ "JP//////////AoIDAH//////////5IftURC0YRpiYzFFwG4OaJSBJwRFM+Y6AQXf"
+ "Ux2JzZEopQQ8xxoCbvfKjNnmnSGNmBWFNvkvihun8Jq2tqjhIvJC2rsxLz9jeiYh"
+ "dNMb9rWF/65begNb9vccNf2tRM/S10+SCL4lj/MklDMo9nItnuEAPlxQsd+CzG0k"
+ "Gw4q6c00ix/UfpJnr8GyrpHuUdbLDjF5qxBCqV3PapSDuEtLNrOGGqclXkwCeLo2"
+ "BGUMEL4ZSC8jFxtnHfHPO5YMB0MBzZPB0XYD0Ufa4q74N6YpZO8V5ftKrAuMHMqk"
+ "vnVKtXKK6RMMTH0CiAq5Ry1FVWIW1pmLhoIoPRnUKpDV745dMnZ9woIsbfeFRXU4"
+ "q66DBj7Zy4fC03DyY9X610ZthJnrj0ZKcCUSsM7ncekTDWl3NfiX/QNsxQQybDsB"
+ "OZ9kNTIpD5WMC72QBl3wi6u9MK62O4TEYF1so3EEcSfQOnLVmKHtrf5wfohHJcFo"
+ "kFSQhACNOR4JU8Pza8Q4zQhe3S2TTOGTjDV6cR4NSjQaWwqF7RLB9OUVaiZ0bd3h"
+ "bYJvR3yXR34KD99lUxQ+LKOnNeAuzNlLJ9BIYdERndDDKK3z9o+wlLhncWvX3A3u"
+ "uxC4JA5oA0iT6tgtVMnadUxGx+7gw3/b7khTYEem+hrkmgFCSRth/VppPjgTYOpu"
+ "WTATI29kuo87Ht0b3vx/ygNWzymHcu2cF6CYANdYNSn2yBPsGIvLk9hDLUSMbR9t"
+ "9efNinaiZzZdZ2pdje2/iiPzZhKlmZAoqJXr16E33HoAm8ZpX6zB5QDjJcl2eBl1"
+ "Cui5DoH6QWvnNzp/e2qvOBejTAZBWtQgGMgFjk8s8+S/32P0eZHUvT8bZkRfB46i"
+ "2/+sLWKl6gPZFaCqVWZHtr9fpHDsCmYvaQfAG/BTy4r3eU3xlANQ6sXb4u07eqhV"
+ "HsUP3/h1jOZY0Ynqrm0rZPYXeUsZHD/0a7ceAjQCH0ezH6Qwdwlflq2Fujprc0p8"
+ "jzbmIBJ//////////wIBAg=="
+ "-----END X942 DH PARAMETERS-----");
+
+ config.set("dl", "modp/ietf/8192",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIIIDAKCBAEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
+ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
+ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
+ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
+ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
+ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
+ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
+ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI"
+ "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O"
+ "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI"
+ "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG"
+ "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU"
+ "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId"
+ "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha"
+ "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/"
+ "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebb4R"
+ "WXSjkm8S/uXkOHd8tqky34zYvsTQc7kxujvIMraNndMAdB+nv4r8R+0ldvaTa6Qk"
+ "ZjqrY5xa5PVoNCO0dCvxyXgjjxbL451lLeP9uL78hIrZIiIuBKQDfAcT61eoGiPw"
+ "xzRz/GRs6jBrS8vIhi+Dhd36nUt/osCH6HloMwPtW906Bis89bOieKZtKhP4P0T4"
+ "Ld8xDuB0q2o2RZfomaAlXcFk8xzFCEaFHfmrSBld7X6hsdUQvX7nTXP682vDHs+i"
+ "aDWQRvTrh5+SQAlDi0gcbNeImgAu1e44K8kZDab8Am5HlVjkR1Z36aqeMFDidlaU"
+ "38gfVuiAuW5xYMmA3Zjt09///////////wKCBAB//////////+SH7VEQtGEaYmMx"
+ "RcBuDmiUgScERTPmOgEF31Mdic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4obp/Ca"
+ "trao4SLyQtq7MS8/Y3omIXTTG/a1hf+uW3oDW/b3HDX9rUTP0tdPkgi+JY/zJJQz"
+ "KPZyLZ7hAD5cULHfgsxtJBsOKunNNIsf1H6SZ6/Bsq6R7lHWyw4xeasQQqldz2qU"
+ "g7hLSzazhhqnJV5MAni6NgRlDBC+GUgvIxcbZx3xzzuWDAdDAc2TwdF2A9FH2uKu"
+ "+DemKWTvFeX7SqwLjBzKpL51SrVyiukTDEx9AogKuUctRVViFtaZi4aCKD0Z1CqQ"
+ "1e+OXTJ2fcKCLG33hUV1OKuugwY+2cuHwtNw8mPV+tdGbYSZ649GSnAlErDO53Hp"
+ "Ew1pdzX4l/0DbMUEMmw7ATmfZDUyKQ+VjAu9kAZd8IurvTCutjuExGBdbKNxBHEn"
+ "0Dpy1Zih7a3+cH6IRyXBaJBUkIQAjTkeCVPD82vEOM0IXt0tk0zhk4w1enEeDUo0"
+ "GlsKhe0SwfTlFWomdG3d4W2Cb0d8l0d+Cg/fZVMUPiyjpzXgLszZSyfQSGHREZ3Q"
+ "wyit8/aPsJS4Z3Fr19wN7rsQuCQOaANIk+rYLVTJ2nVMRsfu4MN/2+5IU2BHpvoa"
+ "5JoBQkkbYf1aaT44E2DqblkwEyNvZLqPOx7dG978f8oDVs8ph3LtnBegmADXWDUp"
+ "9sgT7BiLy5PYQy1EjG0fbfXnzYp2omc2XWdqXY3tv4oj82YSpZmQKKiV69ehN9x6"
+ "AJvGaV+sweUA4yXJdngZdQrouQ6B+kFr5zc6f3tqrzgXo0wGQVrUIBjIBY5PLPPk"
+ "v99j9HmR1L0/G2ZEXweOotv/rC1ipeoD2RWgqlVmR7a/X6Rw7ApmL2kHwBvwU8uK"
+ "93lN8ZQDUOrF2+LtO3qoVR7FD9/4dYzmWNGJ6q5tK2T2F3lLGRw/9Gu3HgI0Ah9H"
+ "sx+kMHcJX5athbo6a3NKfI823wisulHJN4l/cvIcO75bVJlvxmxfYmg53JjdHeQZ"
+ "W0bO6YA6D9PfxX4j9pK7e0m10hIzHVWxzi1yerQaEdo6FfjkvBHHi2XxzrKW8f7c"
+ "X35CRWyRERcCUgG+A4n1q9QNEfhjmjn+MjZ1GDWl5eRDF8HC7v1Opb/RYEP0PLQZ"
+ "gfat7p0DFZ562dE8UzaVCfwfonwW75iHcDpVtRsiy/RM0BKu4LJ5jmKEI0KO/NWk"
+ "DK72v1DY6ohev3Omuf15teGPZ9E0GsgjenXDz8kgBKHFpA42a8RNABdq9xwV5IyG"
+ "034BNyPKrHIjqzv01U8YKHE7K0pv5A+rdEBctziwZMBuzHbp7///////////AgEC"
+ "-----END X942 DH PARAMETERS-----");
+
+ config.set("dl", "dsa/jce/512",
+ "-----BEGIN DSA PARAMETERS-----"
+ "MIGdAkEA/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQT"
+ "xeEu0ImbzRMqzVDZkVG9xD7nN1kuFwIVAJYu3cw2nLqOuyYO5rahJtk0bjjFAkEA"
+ "3gtU76vylwh+5iPVylWIxkgo70/eT/uuHs0gBndrBbEbgeo83pvDlkwWh8UyW/Q9"
+ "fM76DQqGvl3/3dDRFD3NdQ=="
+ "-----END DSA PARAMETERS-----");
+
+ config.set("dl", "dsa/jce/768",
+ "-----BEGIN DSA PARAMETERS-----"
+ "MIHdAmEA6eZCWZ01XzfJf/01ZxILjiXJzUPpJ7OpZw++xdiQFBki0sOzrSSACTeZ"
+ "hp0ehGqrSfqwrSbSzmoiIZ1HC859d31KIfvpwnC1f2BwAvPO+Dk2lM9F7jaIwRqM"
+ "VqsSej2vAhUAnNvYTJ8awvOND4D0KrlS5zOL9RECYQDe7p717RUWzn5pXmcrjO5F"
+ "5s17NuDmOF+JS6hhY/bz5sbU6KgRRtQBfe/dccvZD6Akdlm4i3zByJT0gmn9Txqs"
+ "CjBTjf9rP8ds+xMcnnlltYhYqwpDtVczWRKoqlR/lWg="
+ "-----END DSA PARAMETERS-----");
+
+ config.set("dl", "dsa/jce/1024",
+ "-----BEGIN DSA PARAMETERS-----"
+ "MIIBHgKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9"
+ "jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX"
+ "58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8V"
+ "IwvMspK5gqLrhAvwWBz1AoGARpYDUS4wJ4zTlHWV2yLuyYJqYyKtyXNE9B10DDJX"
+ "JMj577qn1NgD/4xgnc0QDrxb38+tfGpCX66nhuogUOvpg1HqH9of3yTWlHqmuaoj"
+ "dmlTgC9NfUqOy6BtGXaKJJH/sW0O+cQ6mbX3FnL/bwoktETQc20E04oaEyLa9s3Y"
+ "jJ0="
+ "-----END DSA PARAMETERS-----");
+
+ config.set("dl", "dsa/botan/2048",
+ "-----BEGIN DSA PARAMETERS-----"
+ "MIICLAKCAQEAkcSKT9+898Aq6V59oSYSK13Shk9Vm4fo50oobVL1m9HeaN/WRdDg"
+ "DGDAgAMYkZgDdO61lKUyv9Z7mgnqxLhmOgeRDmjzlGX7cEDSXfE5MuusQ0elMOy6"
+ "YchU+biA08DDZgCAWHxFVm2t4mvVo5S+CTtMDyS1r/747GxbPlf7iQJam8FnaZMh"
+ "MeFtPJTvyrGNDfBhIDzFPmEDvHLVWUv9QMplOA9EqahR3LB1SV/AM6ilgHGhvXj+"
+ "BS9mVVZI60txnSr+i0iA+NrW8VgYuhePiSdMhwvpuW6wjEbEAEDMLv4d+xsYaN0x"
+ "nePDSjKmOrbrEiQgmkGWgMx5AtFyjU354QIhAIzX1FD4bwrZTu5M5GmodW0evRBY"
+ "JBlD6v+ws1RYXpJNAoIBAA2fXgdhtNvRgz1qsalhoJlsXyIwP3LYTBQPZ8Qx2Uq1"
+ "cVvqgaDJjTnOS8941rnryJXTT+idlAkdWEhhXvFfXobxHZb2yWniA936WDVkIKSc"
+ "tES1lbkBqTPP4HZ7WU8YoHt/kd7NukRriJkPePL/kfL+fNQ/0uRtGOraH3u2YCxh"
+ "f27zpLKE8v2boQo2BC3o+oeiyjZZf+yBFXoUheRAQd8CgwERy4gLvm7UlIFIhvll"
+ "zcMTX1zPE4Nyi/ZbgG+WksCxDWxMCcdabKO0ATyxarLBBfa+I66pAA6rIXiYX5cs"
+ "mAV+HIbkTnIYaI6krg82NtzKdFydzU5q/7Z8y8E9YTE="
+ "-----END DSA PARAMETERS-----");
+
+ config.set("dl", "dsa/botan/3072",
+ "-----BEGIN DSA PARAMETERS-----"
+ "MIIDLAKCAYEA5LUIgHWWY1heFCRgyi2d/xMviuTIQN2jomZoiRJP5WOLhOiim3rz"
+ "+hIJvmv8S1By7Tsrc4e68/hX9HioAijvNgC3az3Pth0g00RlslBtLK+H3259wM6R"
+ "vS0Wekb2rcwxxTHk+cervbkq3fNbCoBsZikqX14X6WTdCZkDczrEKKs12A6m9oW/"
+ "uovkBo5UGK5eytno/wc94rY+Tn6tNciptwtb1Hz7iNNztm83kxk5sKtxvVWVgJCG"
+ "2gFVM30YWg5Ps2pRmxtiArhZHmACRJzxzTpmOE9tIHOxzXO+ypO68eGmEX0COPIi"
+ "rh7X/tGFqJDn9n+rj+uXU8wTSlGD3+h64llfe1wtn7tCJJ/dWVE+HTOWs+sv2GaE"
+ "8oWoRI/nV6ApiBxAdguU75Gb35dAw4OJWZ7FGm6btRmo4GhJHpzgovz+PLYNZs8N"
+ "+tIKjsaEBIaEphREV1vRck1zUrRKdgB3s71r04XOWwpyUMwL92jagpI4Buuc+7E4"
+ "hDcxthggjHWbAiEAs+vTZOxp74zzuvZDt1c0sWM5suSeXN4bWcHp+0DuDFsCggGA"
+ "K+0h7vg5ZKIwrom7px2ffDnFL8gim047x+WUTTKdoQ8BDqyee69sAJ/E6ylgcj4r"
+ "Vt9GY+TDrIAOkljeL3ZJ0gZ4KJP4Ze/KSY0u7zAHTqXop6smJxKk2UovOwuaku5A"
+ "D7OKPMWaXcfkNtXABLIuNQKDgbUck0B+sy1K4P1Cy0XhLQ7O6KJiOO3iCCp7FSIR"
+ "PGbO+NdFxs88uUX4TS9N4W1Epx3hmCcOE/A1U8iLjTI60LlIob8hA6lJl5tu0W+1"
+ "88lT2Vt8jojKZ9z1pjb7nKOdkkIV96iE7Wx+48ltjZcVQnl0t8Q1EoLhPTdz99KL"
+ "RS8QiSoTx1hzKN6kgntrNpsqjcFyrcWD9R8qZZjFSD5bxGewL5HQWcQC0Y4sJoD3"
+ "dqoG9JKAoscsF8xC1bbnQMXEsas8UcLtCSviotiwU65Xc9FCXtKwjwbi3VBZLfGk"
+ "eMFVkc39EVZP+I/zi3IdQjkv2kcyEtz9jS2IqXagCv/m//tDCjWeZMorNRyiQSOU"
+ "-----END DSA PARAMETERS-----");
+ }
+}
+
+/*************************************************
+* Set the default policy *
+*************************************************/
+void Library_State::load_default_config()
+ {
+ set_default_config(*this);
+ set_default_aliases(*this);
+ set_default_oids(*this);
+ set_default_dl_groups(*this);
+ }
+
+}
diff --git a/src/core/mem_pool.cpp b/src/core/mem_pool.cpp
new file mode 100644
index 000000000..c99d627ad
--- /dev/null
+++ b/src/core/mem_pool.cpp
@@ -0,0 +1,260 @@
+/*************************************************
+* Pooling Allocator Source File *
+* (C) 1999-2008 Jack Lloyd *
+* 2005 Matthew Gregan *
+* 2005-2006 Matt Johnston *
+*************************************************/
+
+#include <botan/mem_pool.h>
+#include <botan/util.h>
+#include <botan/mem_ops.h>
+#include <algorithm>
+#include <exception>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Memory Allocation Exception *
+*************************************************/
+struct Memory_Exhaustion : public std::bad_alloc
+ {
+ const char* what() const throw()
+ { return "Ran out of memory, allocation failed"; }
+ };
+
+}
+
+/*************************************************
+* Memory_Block Constructor *
+*************************************************/
+Pooling_Allocator::Memory_Block::Memory_Block(void* buf)
+ {
+ buffer = static_cast<byte*>(buf);
+ bitmap = 0;
+ buffer_end = buffer + (BLOCK_SIZE * BITMAP_SIZE);
+ }
+
+/*************************************************
+* See if ptr is contained by this block *
+*************************************************/
+bool Pooling_Allocator::Memory_Block::contains(void* ptr,
+ u32bit length) const throw()
+ {
+ return ((buffer <= ptr) &&
+ (buffer_end >= static_cast<byte*>(ptr) + length * BLOCK_SIZE));
+ }
+
+/*************************************************
+* Allocate some memory, if possible *
+*************************************************/
+byte* Pooling_Allocator::Memory_Block::alloc(u32bit n) throw()
+ {
+ if(n == 0 || n > BITMAP_SIZE)
+ return 0;
+
+ if(n == BITMAP_SIZE)
+ {
+ if(bitmap)
+ return 0;
+ else
+ {
+ bitmap = ~bitmap;
+ return buffer;
+ }
+ }
+
+ bitmap_type mask = (static_cast<bitmap_type>(1) << n) - 1;
+ u32bit offset = 0;
+
+ while(bitmap & mask)
+ {
+ mask <<= 1;
+ ++offset;
+
+ if((bitmap & mask) == 0)
+ break;
+ if(mask >> 63)
+ break;
+ }
+
+ if(bitmap & mask)
+ return 0;
+
+ bitmap |= mask;
+ return buffer + offset * BLOCK_SIZE;
+ }
+
+/*************************************************
+* Mark this memory as free, if we own it *
+*************************************************/
+void Pooling_Allocator::Memory_Block::free(void* ptr, u32bit blocks) throw()
+ {
+ clear_mem(static_cast<byte*>(ptr), blocks * BLOCK_SIZE);
+
+ const u32bit offset = (static_cast<byte*>(ptr) - buffer) / BLOCK_SIZE;
+
+ if(offset == 0 && blocks == BITMAP_SIZE)
+ bitmap = ~bitmap;
+ else
+ {
+ for(u32bit j = 0; j != blocks; ++j)
+ bitmap &= ~(static_cast<bitmap_type>(1) << (j+offset));
+ }
+ }
+
+/*************************************************
+* Pooling_Allocator Constructor *
+*************************************************/
+Pooling_Allocator::Pooling_Allocator(Mutex* m) : mutex(m)
+ {
+ last_used = blocks.begin();
+ }
+
+/*************************************************
+* Pooling_Allocator Destructor *
+*************************************************/
+Pooling_Allocator::~Pooling_Allocator()
+ {
+ delete mutex;
+ if(blocks.size())
+ throw Invalid_State("Pooling_Allocator: Never released memory");
+ }
+
+/*************************************************
+* Free all remaining memory *
+*************************************************/
+void Pooling_Allocator::destroy()
+ {
+ Mutex_Holder lock(mutex);
+
+ blocks.clear();
+
+ for(u32bit j = 0; j != allocated.size(); ++j)
+ dealloc_block(allocated[j].first, allocated[j].second);
+ allocated.clear();
+ }
+
+/*************************************************
+* Allocation *
+*************************************************/
+void* Pooling_Allocator::allocate(u32bit n)
+ {
+ const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
+ const u32bit BLOCK_SIZE = Memory_Block::block_size();
+
+ Mutex_Holder lock(mutex);
+
+ if(n <= BITMAP_SIZE * BLOCK_SIZE)
+ {
+ const u32bit block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE;
+
+ byte* mem = allocate_blocks(block_no);
+ if(mem)
+ return mem;
+
+ get_more_core(PREF_SIZE);
+
+ mem = allocate_blocks(block_no);
+ if(mem)
+ return mem;
+
+ throw Memory_Exhaustion();
+ }
+
+ void* new_buf = alloc_block(n);
+ if(new_buf)
+ return new_buf;
+
+ throw Memory_Exhaustion();
+ }
+
+/*************************************************
+* Deallocation *
+*************************************************/
+void Pooling_Allocator::deallocate(void* ptr, u32bit n)
+ {
+ const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
+ const u32bit BLOCK_SIZE = Memory_Block::block_size();
+
+ if(ptr == 0 && n == 0)
+ return;
+
+ Mutex_Holder lock(mutex);
+
+ if(n > BITMAP_SIZE * BLOCK_SIZE)
+ dealloc_block(ptr, n);
+ else
+ {
+ const u32bit block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE;
+
+ std::vector<Memory_Block>::iterator i =
+ std::lower_bound(blocks.begin(), blocks.end(), Memory_Block(ptr));
+
+ if(i == blocks.end() || !i->contains(ptr, block_no))
+ throw Invalid_State("Pointer released to the wrong allocator");
+
+ i->free(ptr, block_no);
+ }
+ }
+
+/*************************************************
+* Try to get some memory from an existing block *
+*************************************************/
+byte* Pooling_Allocator::allocate_blocks(u32bit n)
+ {
+ if(blocks.empty())
+ return 0;
+
+ std::vector<Memory_Block>::iterator i = last_used;
+
+ do
+ {
+ byte* mem = i->alloc(n);
+ if(mem)
+ {
+ last_used = i;
+ return mem;
+ }
+
+ ++i;
+ if(i == blocks.end())
+ i = blocks.begin();
+ }
+ while(i != last_used);
+
+ return 0;
+ }
+
+/*************************************************
+* Allocate more memory for the pool *
+*************************************************/
+void Pooling_Allocator::get_more_core(u32bit in_bytes)
+ {
+ const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
+ const u32bit BLOCK_SIZE = Memory_Block::block_size();
+
+ const u32bit TOTAL_BLOCK_SIZE = BLOCK_SIZE * BITMAP_SIZE;
+
+ const u32bit in_blocks = round_up(in_bytes, BLOCK_SIZE) / TOTAL_BLOCK_SIZE;
+ const u32bit to_allocate = in_blocks * TOTAL_BLOCK_SIZE;
+
+ void* ptr = alloc_block(to_allocate);
+ if(ptr == 0)
+ throw Memory_Exhaustion();
+
+ allocated.push_back(std::make_pair(ptr, to_allocate));
+
+ for(u32bit j = 0; j != in_blocks; ++j)
+ {
+ byte* byte_ptr = static_cast<byte*>(ptr);
+ blocks.push_back(Memory_Block(byte_ptr + j * TOTAL_BLOCK_SIZE));
+ }
+
+ std::sort(blocks.begin(), blocks.end());
+ last_used = std::lower_bound(blocks.begin(), blocks.end(),
+ Memory_Block(ptr));
+ }
+
+}
diff --git a/src/core/mem_pool.h b/src/core/mem_pool.h
new file mode 100644
index 000000000..b74e08a8d
--- /dev/null
+++ b/src/core/mem_pool.h
@@ -0,0 +1,74 @@
+/*************************************************
+* Pooling Allocator Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_POOLING_ALLOCATOR_H__
+#define BOTAN_POOLING_ALLOCATOR_H__
+
+#include <botan/allocate.h>
+#include <botan/exceptn.h>
+#include <botan/mutex.h>
+#include <utility>
+#include <vector>
+
+namespace Botan {
+
+/*************************************************
+* Pooling Allocator *
+*************************************************/
+class BOTAN_DLL Pooling_Allocator : public Allocator
+ {
+ public:
+ void* allocate(u32bit);
+ void deallocate(void*, u32bit);
+
+ void destroy();
+
+ Pooling_Allocator(Mutex*);
+ ~Pooling_Allocator();
+ private:
+ void get_more_core(u32bit);
+ byte* allocate_blocks(u32bit);
+
+ virtual void* alloc_block(u32bit) = 0;
+ virtual void dealloc_block(void*, u32bit) = 0;
+
+ class BOTAN_DLL Memory_Block
+ {
+ public:
+ Memory_Block(void*);
+
+ static u32bit bitmap_size() { return BITMAP_SIZE; }
+ static u32bit block_size() { return BLOCK_SIZE; }
+
+ bool contains(void*, u32bit) const throw();
+ byte* alloc(u32bit) throw();
+ void free(void*, u32bit) throw();
+
+ bool operator<(const Memory_Block& other) const
+ {
+ if(buffer < other.buffer && other.buffer < buffer_end)
+ return false;
+ return (buffer < other.buffer);
+ }
+ private:
+ typedef u64bit bitmap_type;
+ static const u32bit BITMAP_SIZE = 8 * sizeof(bitmap_type);
+ static const u32bit BLOCK_SIZE = 64;
+
+ bitmap_type bitmap;
+ byte* buffer, *buffer_end;
+ };
+
+ static const u32bit PREF_SIZE = BOTAN_MEM_POOL_CHUNK_SIZE;
+
+ std::vector<Memory_Block> blocks;
+ std::vector<Memory_Block>::iterator last_used;
+ std::vector<std::pair<void*, u32bit> > allocated;
+ Mutex* mutex;
+ };
+
+}
+
+#endif
diff --git a/src/core/mutex.h b/src/core/mutex.h
new file mode 100644
index 000000000..e30b48eb0
--- /dev/null
+++ b/src/core/mutex.h
@@ -0,0 +1,54 @@
+/*************************************************
+* Mutex Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_MUTEX_H__
+#define BOTAN_MUTEX_H__
+
+#include <botan/exceptn.h>
+
+namespace Botan {
+
+/*************************************************
+* Mutex Base Class *
+*************************************************/
+class BOTAN_DLL Mutex
+ {
+ public:
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
+ virtual ~Mutex() {}
+ };
+
+/*************************************************
+* Mutex Factory *
+*************************************************/
+class BOTAN_DLL Mutex_Factory
+ {
+ public:
+ virtual Mutex* make() = 0;
+ virtual ~Mutex_Factory() {}
+ };
+
+/*************************************************
+* Mutex Holding Class *
+*************************************************/
+class BOTAN_DLL Mutex_Holder
+ {
+ public:
+ Mutex_Holder(Mutex* m) : mux(m)
+ {
+ if(!mux)
+ throw Invalid_Argument("Mutex_Holder: Argument was NULL");
+ mux->lock();
+ }
+
+ ~Mutex_Holder() { mux->unlock(); }
+ private:
+ Mutex* mux;
+ };
+
+}
+
+#endif
diff --git a/src/core/pk_pad.cpp b/src/core/pk_pad.cpp
new file mode 100644
index 000000000..23dc9a95b
--- /dev/null
+++ b/src/core/pk_pad.cpp
@@ -0,0 +1,48 @@
+/*************************************************
+* EME/EMSA Base Class Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/pk_pad.h>
+
+namespace Botan {
+
+/*************************************************
+* Encode a message *
+*************************************************/
+SecureVector<byte> EME::encode(const byte msg[], u32bit msg_len,
+ u32bit key_bits,
+ RandomNumberGenerator& rng) const
+ {
+ return pad(msg, msg_len, key_bits, rng);
+ }
+
+/*************************************************
+* Encode a message *
+*************************************************/
+SecureVector<byte> EME::encode(const MemoryRegion<byte>& msg,
+ u32bit key_bits,
+ RandomNumberGenerator& rng) const
+ {
+ return pad(msg, msg.size(), key_bits, rng);
+ }
+
+/*************************************************
+* Decode a message *
+*************************************************/
+SecureVector<byte> EME::decode(const byte msg[], u32bit msg_len,
+ u32bit key_bits) const
+ {
+ return unpad(msg, msg_len, key_bits);
+ }
+
+/*************************************************
+* Decode a message *
+*************************************************/
+SecureVector<byte> EME::decode(const MemoryRegion<byte>& msg,
+ u32bit key_bits) const
+ {
+ return unpad(msg, msg.size(), key_bits);
+ }
+
+}
diff --git a/src/core/pk_pad.h b/src/core/pk_pad.h
new file mode 100644
index 000000000..ed1742155
--- /dev/null
+++ b/src/core/pk_pad.h
@@ -0,0 +1,58 @@
+/*************************************************
+* EME/EMSA Classes Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_PUBKEY_PAD_H__
+#define BOTAN_PUBKEY_PAD_H__
+
+#include <botan/base.h>
+#include <botan/rng.h>
+
+namespace Botan {
+
+/*************************************************
+* Encoding Method for Encryption *
+*************************************************/
+class BOTAN_DLL EME
+ {
+ public:
+ virtual u32bit maximum_input_size(u32bit) const = 0;
+
+ SecureVector<byte> encode(const byte[], u32bit, u32bit,
+ RandomNumberGenerator&) const;
+ SecureVector<byte> encode(const MemoryRegion<byte>&, u32bit,
+ RandomNumberGenerator&) const;
+
+ SecureVector<byte> decode(const byte[], u32bit, u32bit) const;
+ SecureVector<byte> decode(const MemoryRegion<byte>&, u32bit) const;
+
+ virtual ~EME() {}
+ private:
+ virtual SecureVector<byte> pad(const byte[], u32bit, u32bit,
+ RandomNumberGenerator&) const = 0;
+
+ virtual SecureVector<byte> unpad(const byte[], u32bit, u32bit) const = 0;
+ };
+
+/*************************************************
+* Encoding Method for Signatures, Appendix *
+*************************************************/
+class BOTAN_DLL EMSA
+ {
+ public:
+ virtual void update(const byte[], u32bit) = 0;
+ virtual SecureVector<byte> raw_data() = 0;
+
+ virtual SecureVector<byte> encoding_of(const MemoryRegion<byte>&,
+ u32bit,
+ RandomNumberGenerator& rng) = 0;
+
+ virtual bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&,
+ u32bit) throw() = 0;
+ virtual ~EMSA() {}
+ };
+
+}
+
+#endif
diff --git a/src/core/rng.cpp b/src/core/rng.cpp
new file mode 100644
index 000000000..3790f3c4e
--- /dev/null
+++ b/src/core/rng.cpp
@@ -0,0 +1,149 @@
+/*************************************************
+* Random Number Generator Base Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/rng.h>
+#include <botan/lookup.h>
+#include <botan/util.h>
+#include <botan/parsing.h>
+#include <botan/timers.h>
+
+#if defined(BOTAN_HAS_RANDPOOL)
+ #include <botan/randpool.h>
+#endif
+
+#if defined(BOTAN_HAS_X931_RNG)
+ #include <botan/x931_rng.h>
+#endif
+
+#if defined(BOTAN_HAS_TIMER_HARDWARE)
+ #include <botan/tm_hard.h>
+#elif defined(BOTAN_HAS_TIMER_POSIX)
+ #include <botan/tm_posix.h>
+#elif defined(BOTAN_HAS_TIMER_UNIX)
+ #include <botan/tm_unix.h>
+#elif defined(BOTAN_HAS_TIMER_WIN32)
+ #include <botan/tm_win32.h>
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_DEVICE)
+ #include <botan/es_dev.h>
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_EGD)
+ #include <botan/es_egd.h>
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_UNIX)
+ #include <botan/es_unix.h>
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_BEOS)
+ #include <botan/es_beos.h>
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI)
+ #include <botan/es_capi.h>
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
+ #include <botan/es_win32.h>
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_FTW)
+ #include <botan/es_ftw.h>
+#endif
+
+namespace Botan {
+
+/*************************************************
+* Default fast poll for EntropySources *
+*************************************************/
+u32bit EntropySource::fast_poll(byte buf[], u32bit len)
+ {
+ return this->slow_poll(buf, len);
+ }
+
+/*************************************************
+* Get a single random byte *
+*************************************************/
+byte RandomNumberGenerator::next_byte()
+ {
+ byte out;
+ this->randomize(&out, 1);
+ return out;
+ }
+
+/*************************************************
+* Create and seed a new RNG object *
+*************************************************/
+RandomNumberGenerator* RandomNumberGenerator::make_rng()
+ {
+#if defined(BOTAN_HAS_RANDPOOL)
+
+ /* Randpool is required for make_rng to work */
+ RandomNumberGenerator* rng = new Randpool(get_block_cipher("AES-256"),
+ get_mac("HMAC(SHA-256)"));
+
+
+ /* If X9.31 is available, wrap the Randpool algorithm in it */
+#if defined(BOTAN_HAS_X931_RNG)
+ rng = new ANSI_X931_RNG(get_block_cipher("AES-256"), rng);
+#endif
+
+#if defined(BOTAN_HAS_TIMER_HARDWARE)
+ rng->add_entropy_source(new Hardware_Timer);
+#elif defined(BOTAN_HAS_TIMER_POSIX)
+ rng->add_entropy_source(new POSIX_Timer);
+#elif defined(BOTAN_HAS_TIMER_UNIX)
+ rng->add_entropy_source(new Unix_Timer);
+#elif defined(BOTAN_HAS_TIMER_WIN32)
+ rng->add_entropy_source(new Win32_Timer);
+#else
+ rng->add_entropy_source(new Timer);
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_DEVICE)
+ rng->add_entropy_source(
+ new Device_EntropySource(
+ split_on("/dev/random:/dev/srandom:/dev/urandom", ':')
+ )
+ );
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_EGD)
+ rng->add_entropy_source(
+ new EGD_EntropySource(split_on("/var/run/egd-pool:/dev/egd-pool", ':'))
+ );
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI)
+ rng->add_entropy_source(new Win32_CAPI_EntropySource);
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
+ rng->add_entropy_source(new Win32_EntropySource);
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_UNIX)
+ rng->add_entropy_source(
+ new Unix_EntropySource(split_on("/bin:/sbin:/usr/bin:/usr/sbin", ':'))
+ );
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_BEOS)
+ rng->add_entropy_source(new BeOS_EntropySource);
+#endif
+
+#if defined(BOTAN_HAS_ENTROPY_SRC_FTW)
+ rng->add_entropy_source(new FTW_EntropySource("/proc"));
+#endif
+
+ return rng;
+#endif
+
+ throw Algorithm_Not_Found("RandomNumberGenerator::make_rng - no RNG object available");
+ }
+
+}
diff --git a/src/core/rng.h b/src/core/rng.h
new file mode 100644
index 000000000..f8b9a7f62
--- /dev/null
+++ b/src/core/rng.h
@@ -0,0 +1,66 @@
+/*************************************************
+* RandomNumberGenerator Header File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_RANDOM_NUMBER_GENERATOR__
+#define BOTAN_RANDOM_NUMBER_GENERATOR__
+
+#include <botan/exceptn.h>
+
+namespace Botan {
+
+/*************************************************
+* Entropy Source *
+*************************************************/
+class BOTAN_DLL EntropySource
+ {
+ public:
+ virtual u32bit slow_poll(byte[], u32bit) = 0;
+ virtual u32bit fast_poll(byte[], u32bit);
+ virtual ~EntropySource() {}
+ };
+
+/*************************************************
+* Random Number Generator *
+*************************************************/
+class BOTAN_DLL RandomNumberGenerator
+ {
+ public:
+ static RandomNumberGenerator* make_rng();
+
+ virtual void randomize(byte[], u32bit) = 0;
+ virtual bool is_seeded() const = 0;
+ virtual void clear() throw() = 0;
+
+ byte next_byte();
+
+ virtual void reseed() {}
+ virtual void add_entropy_source(EntropySource*) = 0;
+ virtual void add_entropy(const byte[], u32bit) = 0;
+
+ RandomNumberGenerator() {}
+ virtual ~RandomNumberGenerator() {}
+ private:
+ RandomNumberGenerator(const RandomNumberGenerator&) {}
+ RandomNumberGenerator& operator=(const RandomNumberGenerator&)
+ { return (*this); }
+ };
+
+/*************************************************
+* Null Random Number Generator *
+*************************************************/
+class BOTAN_DLL Null_RNG : public RandomNumberGenerator
+ {
+ public:
+ void randomize(byte[], u32bit) { throw PRNG_Unseeded("Null_RNG"); }
+ void clear() throw() {};
+
+ bool is_seeded() const { return false; }
+ void add_entropy(const byte[], u32bit) {}
+ void add_entropy_source(EntropySource* es) { delete es; }
+ };
+
+}
+
+#endif
diff --git a/src/core/s2k.cpp b/src/core/s2k.cpp
new file mode 100644
index 000000000..9c67aef10
--- /dev/null
+++ b/src/core/s2k.cpp
@@ -0,0 +1,53 @@
+/*************************************************
+* S2K Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/s2k.h>
+
+namespace Botan {
+
+/*************************************************
+* Derive a key from a passphrase *
+*************************************************/
+OctetString S2K::derive_key(u32bit key_len,
+ const std::string& passphrase) const
+ {
+ return derive(key_len, passphrase, salt, salt.size(), iterations());
+ }
+
+/*************************************************
+* Set the number of iterations *
+*************************************************/
+void S2K::set_iterations(u32bit i)
+ {
+ iter = i;
+ }
+
+/*************************************************
+* Change the salt *
+*************************************************/
+void S2K::change_salt(const byte new_salt[], u32bit length)
+ {
+ salt.set(new_salt, length);
+ }
+
+/*************************************************
+* Change the salt *
+*************************************************/
+void S2K::change_salt(const MemoryRegion<byte>& new_salt)
+ {
+ change_salt(new_salt.begin(), new_salt.size());
+ }
+
+/*************************************************
+* Create a new random salt *
+*************************************************/
+void S2K::new_random_salt(RandomNumberGenerator& rng,
+ u32bit length)
+ {
+ salt.create(length);
+ rng.randomize(salt, length);
+ }
+
+}
diff --git a/src/core/s2k.h b/src/core/s2k.h
new file mode 100644
index 000000000..031592513
--- /dev/null
+++ b/src/core/s2k.h
@@ -0,0 +1,45 @@
+/*************************************************
+* S2K Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_S2K_H__
+#define BOTAN_S2K_H__
+
+#include <botan/symkey.h>
+#include <botan/rng.h>
+
+namespace Botan {
+
+/*************************************************
+* S2K Interface *
+*************************************************/
+class BOTAN_DLL S2K
+ {
+ public:
+ virtual S2K* clone() const = 0;
+ virtual std::string name() const = 0;
+ virtual void clear() {}
+
+ OctetString derive_key(u32bit, const std::string&) const;
+
+ void set_iterations(u32bit);
+ void change_salt(const byte[], u32bit);
+ void change_salt(const MemoryRegion<byte>&);
+ void new_random_salt(RandomNumberGenerator& rng, u32bit);
+
+ u32bit iterations() const { return iter; }
+ SecureVector<byte> current_salt() const { return salt; }
+
+ S2K() { iter = 0; }
+ virtual ~S2K() {}
+ private:
+ virtual OctetString derive(u32bit, const std::string&,
+ const byte[], u32bit, u32bit) const = 0;
+ SecureVector<byte> salt;
+ u32bit iter;
+ };
+
+}
+
+#endif
diff --git a/src/core/secmem.h b/src/core/secmem.h
new file mode 100644
index 000000000..37adf7f42
--- /dev/null
+++ b/src/core/secmem.h
@@ -0,0 +1,217 @@
+/*************************************************
+* Secure Memory Buffers Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__
+#define BOTAN_SECURE_MEMORY_BUFFERS_H__
+
+#include <botan/allocate.h>
+#include <botan/mem_ops.h>
+
+namespace Botan {
+
+/*************************************************
+* Variable Length Memory Buffer *
+*************************************************/
+template<typename T>
+class MemoryRegion
+ {
+ public:
+ u32bit size() const { return used; }
+ u32bit is_empty() const { return (used == 0); }
+ u32bit has_items() const { return (used != 0); }
+
+ operator T* () { return buf; }
+ operator const T* () const { return buf; }
+
+ T* begin() { return buf; }
+ const T* begin() const { return buf; }
+
+ T* end() { return (buf + size()); }
+ const T* end() const { return (buf + size()); }
+
+ bool operator==(const MemoryRegion<T>& other) const
+ {
+ return (size() == other.size() &&
+ same_mem(buf, other.buf, size()));
+ }
+
+ bool operator<(const MemoryRegion<T>&) const;
+
+ bool operator!=(const MemoryRegion<T>& in) const
+ { return (!(*this == in)); }
+ MemoryRegion<T>& operator=(const MemoryRegion<T>& in)
+ { if(this != &in) set(in); return (*this); }
+
+ void copy(const T in[], u32bit n)
+ { copy(0, in, n); }
+ void copy(u32bit off, const T in[], u32bit n)
+ { copy_mem(buf + off, in, (n > size() - off) ? (size() - off) : n); }
+
+ void set(const T in[], u32bit n) { create(n); copy(in, n); }
+ void set(const MemoryRegion<T>& in) { set(in.begin(), in.size()); }
+
+ void append(const T data[], u32bit n)
+ { grow_to(size()+n); copy(size() - n, data, n); }
+ void append(T x) { append(&x, 1); }
+ void append(const MemoryRegion<T>& x) { append(x.begin(), x.size()); }
+
+ void clear() { clear_mem(buf, allocated); }
+ void destroy() { create(0); }
+
+ void create(u32bit);
+ void grow_to(u32bit);
+ void swap(MemoryRegion<T>&);
+
+ ~MemoryRegion() { deallocate(buf, allocated); }
+ protected:
+ MemoryRegion() { buf = 0; alloc = 0; used = allocated = 0; }
+ MemoryRegion(const MemoryRegion<T>& other)
+ {
+ buf = 0;
+ used = allocated = 0;
+ alloc = other.alloc;
+ set(other.buf, other.used);
+ }
+
+ void init(bool locking, u32bit length = 0)
+ { alloc = Allocator::get(locking); create(length); }
+ private:
+ T* allocate(u32bit n)
+ {
+ return static_cast<T*>(alloc->allocate(sizeof(T)*n));
+ }
+
+ void deallocate(T* p, u32bit n)
+ { alloc->deallocate(p, sizeof(T)*n); }
+
+ T* buf;
+ u32bit used;
+ u32bit allocated;
+ Allocator* alloc;
+ };
+
+/*************************************************
+* Create a new buffer *
+*************************************************/
+template<typename T>
+void MemoryRegion<T>::create(u32bit n)
+ {
+ if(n <= allocated) { clear(); used = n; return; }
+ deallocate(buf, allocated);
+ buf = allocate(n);
+ allocated = used = n;
+ }
+
+/*************************************************
+* Increase the size of the buffer *
+*************************************************/
+template<typename T>
+void MemoryRegion<T>::grow_to(u32bit n)
+ {
+ if(n > used && n <= allocated)
+ {
+ clear_mem(buf + used, n - used);
+ used = n;
+ return;
+ }
+ else if(n > allocated)
+ {
+ T* new_buf = allocate(n);
+ copy_mem(new_buf, buf, used);
+ deallocate(buf, allocated);
+ buf = new_buf;
+ allocated = used = n;
+ }
+ }
+
+/*************************************************
+* Compare this buffer with another one *
+*************************************************/
+template<typename T>
+bool MemoryRegion<T>::operator<(const MemoryRegion<T>& in) const
+ {
+ if(size() < in.size()) return true;
+ if(size() > in.size()) return false;
+
+ for(u32bit j = 0; j != size(); j++)
+ {
+ if(buf[j] < in[j]) return true;
+ if(buf[j] > in[j]) return false;
+ }
+
+ return false;
+ }
+
+/*************************************************
+* Swap this buffer with another one *
+*************************************************/
+template<typename T>
+void MemoryRegion<T>::swap(MemoryRegion<T>& x)
+ {
+ std::swap(buf, x.buf);
+ std::swap(used, x.used);
+ std::swap(allocated, x.allocated);
+ std::swap(alloc, x.alloc);
+ }
+
+/*************************************************
+* Unlocked Variable Length Buffer *
+*************************************************/
+template<typename T>
+class MemoryVector : public MemoryRegion<T>
+ {
+ public:
+ MemoryVector<T>& operator=(const MemoryRegion<T>& in)
+ { if(this != &in) set(in); return (*this); }
+
+ MemoryVector(u32bit n = 0) { MemoryRegion<T>::init(false, n); }
+ MemoryVector(const T in[], u32bit n)
+ { MemoryRegion<T>::init(false); set(in, n); }
+ MemoryVector(const MemoryRegion<T>& in)
+ { MemoryRegion<T>::init(false); set(in); }
+ MemoryVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
+ { MemoryRegion<T>::init(false); set(in1); append(in2); }
+ };
+
+/*************************************************
+* Locked Variable Length Buffer *
+*************************************************/
+template<typename T>
+class SecureVector : public MemoryRegion<T>
+ {
+ public:
+ SecureVector<T>& operator=(const MemoryRegion<T>& in)
+ { if(this != &in) set(in); return (*this); }
+
+ SecureVector(u32bit n = 0) { MemoryRegion<T>::init(true, n); }
+ SecureVector(const T in[], u32bit n)
+ { MemoryRegion<T>::init(true); set(in, n); }
+ SecureVector(const MemoryRegion<T>& in)
+ { MemoryRegion<T>::init(true); set(in); }
+ SecureVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
+ { MemoryRegion<T>::init(true); set(in1); append(in2); }
+ };
+
+/*************************************************
+* Locked Fixed Length Buffer *
+*************************************************/
+template<typename T, u32bit L>
+class SecureBuffer : public MemoryRegion<T>
+ {
+ public:
+ SecureBuffer<T,L>& operator=(const SecureBuffer<T,L>& in)
+ { if(this != &in) set(in); return (*this); }
+
+ SecureBuffer() { MemoryRegion<T>::init(true, L); }
+ SecureBuffer(const T in[], u32bit n)
+ { MemoryRegion<T>::init(true, L); copy(in, n); }
+ private:
+ SecureBuffer<T, L>& operator=(const MemoryRegion<T>& in)
+ { if(this != &in) set(in); return (*this); }
+ };
+
+}
+
+#endif
diff --git a/src/core/selftest/info.txt b/src/core/selftest/info.txt
new file mode 100644
index 000000000..e786437d5
--- /dev/null
+++ b/src/core/selftest/info.txt
@@ -0,0 +1,24 @@
+realname "Selftests"
+
+define SELFTESTS
+
+load_on auto
+
+<add>
+selftest.cpp
+selftest.h
+</add>
+
+<requires>
+hex
+des
+aes
+sha1
+sha2
+hmac
+ecb
+cbc
+cfb
+ofb
+ctr
+</requires>
diff --git a/src/core/selftest/selftest.cpp b/src/core/selftest/selftest.cpp
new file mode 100644
index 000000000..0dede1c9d
--- /dev/null
+++ b/src/core/selftest/selftest.cpp
@@ -0,0 +1,163 @@
+/*************************************************
+* Startup Self Tests Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/selftest.h>
+#include <botan/libstate.h>
+#include <botan/lookup.h>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Perform a Known Answer Test *
+*************************************************/
+void do_kat(const std::string& in, const std::string& out,
+ const std::string& algo_name, Filter* filter)
+ {
+ if(out.length())
+ {
+ Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder);
+ pipe.process_msg(in);
+
+ if(out != pipe.read_all_as_string())
+ throw Self_Test_Failure("FIPS-140 " + algo_name + " test");
+ }
+ }
+
+/*************************************************
+* Perform a KAT for a cipher *
+*************************************************/
+void cipher_kat(const std::string& in, const std::string& out,
+ const std::string& key, const std::string& iv,
+ const std::string& cipher)
+ {
+ do_kat(in, out, cipher,
+ get_cipher(global_state(), cipher, key, iv, ENCRYPTION));
+ do_kat(out, in, cipher,
+ get_cipher(global_state(), cipher, key, iv, DECRYPTION));
+ }
+
+/*************************************************
+* Perform a KAT for a cipher *
+*************************************************/
+void cipher_kat(const std::string& cipher, const std::string& key,
+ const std::string& iv, const std::string& in,
+ const std::string& ecb_out, const std::string& cbc_out,
+ const std::string& cfb_out, const std::string& ofb_out,
+ const std::string& ctr_out)
+ {
+ if(!have_block_cipher(cipher))
+ return;
+
+ cipher_kat(in, ecb_out, key, "", cipher + "/ECB");
+ cipher_kat(in, cbc_out, key, iv, cipher + "/CBC/NoPadding");
+ cipher_kat(in, cfb_out, key, iv, cipher + "/CFB");
+ cipher_kat(in, ofb_out, key, iv, cipher + "/OFB");
+ cipher_kat(in, ctr_out, key, iv, cipher + "/CTR-BE");
+ }
+
+/*************************************************
+* Perform a KAT for a hash *
+*************************************************/
+void hash_kat(const std::string& hash, const std::string& in,
+ const std::string& out)
+ {
+ if(!have_hash(hash))
+ return;
+ do_kat(in, out, hash, new Hash_Filter(hash));
+ }
+
+/*************************************************
+* Perform a KAT for a MAC *
+*************************************************/
+void mac_kat(const std::string& mac, const std::string& in,
+ const std::string& out, const std::string& key)
+ {
+ if(!have_mac(mac))
+ return;
+ do_kat(in, out, mac, new MAC_Filter(mac, key));
+ }
+
+}
+
+/*************************************************
+* Perform FIPS 140 Self Tests *
+*************************************************/
+bool passes_self_tests()
+ {
+ try {
+ cipher_kat("DES", "0123456789ABCDEF", "1234567890ABCDEF",
+ "4E6F77206973207468652074696D6520666F7220616C6C20",
+ "3FA40E8A984D48156A271787AB8883F9893D51EC4B563B53",
+ "E5C7CDDE872BF27C43E934008C389C0F683788499A7C05F6",
+ "F3096249C7F46E51A69E839B1A92F78403467133898EA622",
+ "F3096249C7F46E5135F24A242EEB3D3F3D6D5BE3255AF8C3",
+ "F3096249C7F46E51163A8CA0FFC94C27FA2F80F480B86F75");
+
+ cipher_kat("TripleDES",
+ "385D7189A5C3D485E1370AA5D408082B5CCCCB5E19F2D90E",
+ "C141B5FCCD28DC8A",
+ "6E1BD7C6120947A464A6AAB293A0F89A563D8D40D3461B68",
+ "64EAAD4ACBB9CEAD6C7615E7C7E4792FE587D91F20C7D2F4",
+ "6235A461AFD312973E3B4F7AA7D23E34E03371F8E8C376C9",
+ "E26BA806A59B0330DE40CA38E77A3E494BE2B212F6DD624B",
+ "E26BA806A59B03307DE2BCC25A08BA40A8BA335F5D604C62",
+ "E26BA806A59B03303C62C2EFF32D3ACDD5D5F35EBCC53371");
+
+ cipher_kat("AES",
+ "2B7E151628AED2A6ABF7158809CF4F3C",
+ "000102030405060708090A0B0C0D0E0F",
+ "6BC1BEE22E409F96E93D7E117393172A"
+ "AE2D8A571E03AC9C9EB76FAC45AF8E51",
+ "3AD77BB40D7A3660A89ECAF32466EF97"
+ "F5D3D58503B9699DE785895A96FDBAAF",
+ "7649ABAC8119B246CEE98E9B12E9197D"
+ "5086CB9B507219EE95DB113A917678B2",
+ "3B3FD92EB72DAD20333449F8E83CFB4A"
+ "C8A64537A0B3A93FCDE3CDAD9F1CE58B",
+ "3B3FD92EB72DAD20333449F8E83CFB4A"
+ "7789508D16918F03F53C52DAC54ED825",
+ "3B3FD92EB72DAD20333449F8E83CFB4A"
+ "010C041999E03F36448624483E582D0E");
+
+ hash_kat("SHA-1", "", "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709");
+ hash_kat("SHA-1", "616263", "A9993E364706816ABA3E25717850C26C9CD0D89D");
+ hash_kat("SHA-1",
+ "6162636462636465636465666465666765666768666768696768696A"
+ "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071",
+ "84983E441C3BD26EBAAE4AA1F95129E5E54670F1");
+
+ hash_kat("SHA-256", "",
+ "E3B0C44298FC1C149AFBF4C8996FB924"
+ "27AE41E4649B934CA495991B7852B855");
+ hash_kat("SHA-256", "616263",
+ "BA7816BF8F01CFEA414140DE5DAE2223"
+ "B00361A396177A9CB410FF61F20015AD");
+ hash_kat("SHA-256",
+ "6162636462636465636465666465666765666768666768696768696A"
+ "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071",
+ "248D6A61D20638B8E5C026930C3E6039"
+ "A33CE45964FF2167F6ECEDD419DB06C1");
+
+ mac_kat("HMAC(SHA-1)", "4869205468657265",
+ "B617318655057264E28BC0B6FB378C8EF146BE00",
+ "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B");
+
+ mac_kat("HMAC(SHA-256)", "4869205468657265",
+ "198A607EB44BFBC69903A0F1CF2BBDC5"
+ "BA0AA3F3D9AE3C1C7A3B1696A0B68CF7",
+ "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"
+ "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B");
+ }
+ catch(std::exception& e)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/src/core/selftest/selftest.h b/src/core/selftest/selftest.h
new file mode 100644
index 000000000..ff011a32c
--- /dev/null
+++ b/src/core/selftest/selftest.h
@@ -0,0 +1,20 @@
+/*************************************************
+* Startup Self Test Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_SELF_TEST_H__
+#define BOTAN_SELF_TEST_H__
+
+#include <botan/base.h>
+
+namespace Botan {
+
+/*************************************************
+* Self Tests *
+*************************************************/
+BOTAN_DLL bool passes_self_tests();
+
+}
+
+#endif
diff --git a/src/core/symkey.cpp b/src/core/symkey.cpp
new file mode 100644
index 000000000..7cc1bce64
--- /dev/null
+++ b/src/core/symkey.cpp
@@ -0,0 +1,139 @@
+/*************************************************
+* OctetString Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/symkey.h>
+#include <botan/xor_buf.h>
+#include <botan/rng.h>
+#include <botan/pipe.h>
+#include <botan/hex.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* Create an OctetString from RNG output *
+*************************************************/
+OctetString::OctetString(RandomNumberGenerator& rng,
+ u32bit length)
+ {
+ bits.create(length);
+ rng.randomize(bits, length);
+ }
+
+/*************************************************
+* Create an OctetString from a hex string *
+*************************************************/
+void OctetString::change(const std::string& hex_string)
+ {
+ SecureVector<byte> hex;
+ for(u32bit j = 0; j != hex_string.length(); ++j)
+ if(Hex_Decoder::is_valid(hex_string[j]))
+ hex.append(hex_string[j]);
+
+ if(hex.size() % 2 != 0)
+ throw Invalid_Argument("OctetString: hex string must encode full bytes");
+ bits.create(hex.size() / 2);
+ for(u32bit j = 0; j != bits.size(); ++j)
+ bits[j] = Hex_Decoder::decode(hex.begin() + 2*j);
+ }
+
+/*************************************************
+* Create an OctetString from a byte string *
+*************************************************/
+void OctetString::change(const byte in[], u32bit n)
+ {
+ bits.create(n);
+ bits.copy(in, n);
+ }
+
+/*************************************************
+* Set the parity of each key byte to odd *
+*************************************************/
+void OctetString::set_odd_parity()
+ {
+ const byte ODD_PARITY[256] = {
+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07, 0x08, 0x08, 0x0B, 0x0B,
+ 0x0D, 0x0D, 0x0E, 0x0E, 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
+ 0x19, 0x19, 0x1A, 0x1A, 0x1C, 0x1C, 0x1F, 0x1F, 0x20, 0x20, 0x23, 0x23,
+ 0x25, 0x25, 0x26, 0x26, 0x29, 0x29, 0x2A, 0x2A, 0x2C, 0x2C, 0x2F, 0x2F,
+ 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37, 0x38, 0x38, 0x3B, 0x3B,
+ 0x3D, 0x3D, 0x3E, 0x3E, 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
+ 0x49, 0x49, 0x4A, 0x4A, 0x4C, 0x4C, 0x4F, 0x4F, 0x51, 0x51, 0x52, 0x52,
+ 0x54, 0x54, 0x57, 0x57, 0x58, 0x58, 0x5B, 0x5B, 0x5D, 0x5D, 0x5E, 0x5E,
+ 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67, 0x68, 0x68, 0x6B, 0x6B,
+ 0x6D, 0x6D, 0x6E, 0x6E, 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
+ 0x79, 0x79, 0x7A, 0x7A, 0x7C, 0x7C, 0x7F, 0x7F, 0x80, 0x80, 0x83, 0x83,
+ 0x85, 0x85, 0x86, 0x86, 0x89, 0x89, 0x8A, 0x8A, 0x8C, 0x8C, 0x8F, 0x8F,
+ 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97, 0x98, 0x98, 0x9B, 0x9B,
+ 0x9D, 0x9D, 0x9E, 0x9E, 0xA1, 0xA1, 0xA2, 0xA2, 0xA4, 0xA4, 0xA7, 0xA7,
+ 0xA8, 0xA8, 0xAB, 0xAB, 0xAD, 0xAD, 0xAE, 0xAE, 0xB0, 0xB0, 0xB3, 0xB3,
+ 0xB5, 0xB5, 0xB6, 0xB6, 0xB9, 0xB9, 0xBA, 0xBA, 0xBC, 0xBC, 0xBF, 0xBF,
+ 0xC1, 0xC1, 0xC2, 0xC2, 0xC4, 0xC4, 0xC7, 0xC7, 0xC8, 0xC8, 0xCB, 0xCB,
+ 0xCD, 0xCD, 0xCE, 0xCE, 0xD0, 0xD0, 0xD3, 0xD3, 0xD5, 0xD5, 0xD6, 0xD6,
+ 0xD9, 0xD9, 0xDA, 0xDA, 0xDC, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE3, 0xE3,
+ 0xE5, 0xE5, 0xE6, 0xE6, 0xE9, 0xE9, 0xEA, 0xEA, 0xEC, 0xEC, 0xEF, 0xEF,
+ 0xF1, 0xF1, 0xF2, 0xF2, 0xF4, 0xF4, 0xF7, 0xF7, 0xF8, 0xF8, 0xFB, 0xFB,
+ 0xFD, 0xFD, 0xFE, 0xFE };
+
+ for(u32bit j = 0; j != bits.size(); ++j)
+ bits[j] = ODD_PARITY[bits[j]];
+ }
+
+/*************************************************
+* Hex encode an OctetString *
+*************************************************/
+std::string OctetString::as_string() const
+ {
+ Pipe pipe(new Hex_Encoder);
+ pipe.process_msg(bits);
+ return pipe.read_all_as_string();
+ }
+
+/*************************************************
+* XOR Operation for OctetStrings *
+*************************************************/
+OctetString& OctetString::operator^=(const OctetString& k)
+ {
+ if(&k == this) { bits.clear(); return (*this); }
+ xor_buf(bits.begin(), k.begin(), std::min(length(), k.length()));
+ return (*this);
+ }
+
+/*************************************************
+* Equality Operation for OctetStrings *
+*************************************************/
+bool operator==(const OctetString& s1, const OctetString& s2)
+ {
+ return (s1.bits_of() == s2.bits_of());
+ }
+
+/*************************************************
+* Unequality Operation for OctetStrings *
+*************************************************/
+bool operator!=(const OctetString& s1, const OctetString& s2)
+ {
+ return !(s1 == s2);
+ }
+
+/*************************************************
+* Append Operation for OctetStrings *
+*************************************************/
+OctetString operator+(const OctetString& k1, const OctetString& k2)
+ {
+ return OctetString(SecureVector<byte>(k1.bits_of(), k2.bits_of()));
+ }
+
+/*************************************************
+* XOR Operation for OctetStrings *
+*************************************************/
+OctetString operator^(const OctetString& k1, const OctetString& k2)
+ {
+ SecureVector<byte> ret(std::max(k1.length(), k2.length()));
+ ret.copy(k1.begin(), k1.length());
+ xor_buf(ret, k2.begin(), k2.length());
+ return OctetString(ret);
+ }
+
+}
diff --git a/src/core/symkey.h b/src/core/symkey.h
new file mode 100644
index 000000000..f3211eb0f
--- /dev/null
+++ b/src/core/symkey.h
@@ -0,0 +1,60 @@
+/*************************************************
+* OctetString Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_SYMKEY_H__
+#define BOTAN_SYMKEY_H__
+
+#include <botan/secmem.h>
+#include <string>
+
+namespace Botan {
+
+/*************************************************
+* Octet String *
+*************************************************/
+class BOTAN_DLL OctetString
+ {
+ public:
+ u32bit length() const { return bits.size(); }
+ SecureVector<byte> bits_of() const { return bits; }
+
+ const byte* begin() const { return bits.begin(); }
+ const byte* end() const { return bits.end(); }
+
+ std::string as_string() const;
+
+ OctetString& operator^=(const OctetString&);
+
+ void set_odd_parity();
+
+ void change(const std::string&);
+ void change(const byte[], u32bit);
+ void change(const MemoryRegion<byte>& in) { bits = in; }
+
+ OctetString(class RandomNumberGenerator&, u32bit len);
+ OctetString(const std::string& str = "") { change(str); }
+ OctetString(const byte in[], u32bit len) { change(in, len); }
+ OctetString(const MemoryRegion<byte>& in) { change(in); }
+ private:
+ SecureVector<byte> bits;
+ };
+
+/*************************************************
+* Operations on Octet Strings *
+*************************************************/
+BOTAN_DLL bool operator==(const OctetString&, const OctetString&);
+BOTAN_DLL bool operator!=(const OctetString&, const OctetString&);
+BOTAN_DLL OctetString operator+(const OctetString&, const OctetString&);
+BOTAN_DLL OctetString operator^(const OctetString&, const OctetString&);
+
+/*************************************************
+* Alternate Names *
+*************************************************/
+typedef OctetString SymmetricKey;
+typedef OctetString InitializationVector;
+
+}
+
+#endif