diff options
Diffstat (limited to 'src/libs/3rdparty/botan/botan.h')
-rw-r--r-- | src/libs/3rdparty/botan/botan.h | 16208 |
1 files changed, 0 insertions, 16208 deletions
diff --git a/src/libs/3rdparty/botan/botan.h b/src/libs/3rdparty/botan/botan.h deleted file mode 100644 index d7b90cc92f..0000000000 --- a/src/libs/3rdparty/botan/botan.h +++ /dev/null @@ -1,16208 +0,0 @@ -/* -* Botan 1.10.2 Amalgamation -* (C) 1999-2011 Jack Lloyd and others -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_AMALGAMATION_H__ -#define BOTAN_AMALGAMATION_H__ - -#ifdef USE_SYSTEM_BOTAN -#include <botan/auto_rng.h> -#include <botan/cbc.h> -#include <botan/ctr.h> -#include <botan/der_enc.h> -#include <botan/dh.h> -#include <botan/dl_group.h> -#include <botan/dsa.h> -#include <botan/ec_group.h> -#include <botan/ecdh.h> -#include <botan/ecdsa.h> -#include <botan/hmac.h> -#include <botan/init.h> -#include <botan/lookup.h> -#include <botan/pem.h> -#include <botan/pubkey.h> -#include <botan/rsa.h> -#include <botan/ui.h> -#else - -#include <QtGlobal> - -#include <iosfwd> -#include <map> -#include <exception> -#include <string> -#include <algorithm> -#include <cstring> -#include <stdexcept> -#include <vector> -#include <utility> - -#define BOTAN_VERSION_MAJOR 1 -#define BOTAN_VERSION_MINOR 10 -#define BOTAN_VERSION_PATCH 2 -#define BOTAN_VERSION_DATESTAMP 0 - -#define BOTAN_VERSION_VC_REVISION "mtn:2bf8ad2c501213efb4cf9b219330b87666988e91" - -#define BOTAN_DISTRIBUTION_INFO "unspecified" - -#ifndef BOTAN_DLL -#define BOTAN_DLL Q_DECL_IMPORT -#endif - -/* Chunk sizes */ -#define BOTAN_DEFAULT_BUFFER_SIZE 4096 -#define BOTAN_MEM_POOL_CHUNK_SIZE 64*1024 -#define BOTAN_BLOCK_CIPHER_PAR_MULT 4 - -/* BigInt toggles */ -#define BOTAN_MP_WORD_BITS 32 -#define BOTAN_KARAT_MUL_THRESHOLD 32 -#define BOTAN_KARAT_SQR_THRESHOLD 32 - -/* PK key consistency checking toggles */ -#define BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD 1 -#define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD 0 -#define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_GENERATE 1 - -/* Should we use GCC-style inline assembler? */ -#if !defined(BOTAN_USE_GCC_INLINE_ASM) && defined(__GNUG__) - #define BOTAN_USE_GCC_INLINE_ASM 1 -#endif - -#if !defined(BOTAN_USE_GCC_INLINE_ASM) - #define BOTAN_USE_GCC_INLINE_ASM 0 -#endif - -#ifdef __GNUC__ - #define BOTAN_GCC_VERSION \ - (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__) -#else - #define BOTAN_GCC_VERSION 0 -#endif - -#define BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN -#define BOTAN_TARGET_CPU_IS_X86_FAMILY -#define BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK 1 - -#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) || \ - defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - #define BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS -#endif - -#if defined(_MSC_VER) - // 4250: inherits via dominance (diamond inheritence issue) - // 4251: needs DLL interface (STL DLL exports) - #pragma warning(disable: 4250 4251) -#endif - -/* -* Compile-time deprecatation warnings -*/ -#if !defined(BOTAN_NO_DEPRECATED_WARNINGS) - - #if defined(__clang__) - #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated)) - - #elif defined(_MSC_VER) - #define BOTAN_DEPRECATED(msg) __declspec(deprecated(msg)) - - #elif defined(__GNUG__) - - #if BOTAN_GCC_VERSION >= 450 && !defined(__INTEL_COMPILER) - #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg))) - #else - #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated)) - #endif - - #endif - -#endif - -#if !defined(BOTAN_DEPRECATED) - #define BOTAN_DEPRECATED(msg) -#endif - -/* -* Module availability definitions -*/ -#define BOTAN_HAS_ADLER32 -#define BOTAN_HAS_AES -#define BOTAN_HAS_ALGORITHM_FACTORY -#define BOTAN_HAS_ANSI_X919_MAC -#define BOTAN_HAS_ARC4 -#define BOTAN_HAS_ASN1 -#define BOTAN_HAS_AUTO_SEEDING_RNG -#define BOTAN_HAS_BASE64_CODEC -#define BOTAN_HAS_BCRYPT -#define BOTAN_HAS_BIGINT -#define BOTAN_HAS_BIGINT_MATH -#define BOTAN_HAS_BIGINT_MP -#define BOTAN_HAS_BLOCK_CIPHER -#define BOTAN_HAS_BLOWFISH -#define BOTAN_HAS_BMW_512 -#define BOTAN_HAS_CAMELLIA -#define BOTAN_HAS_CASCADE -#define BOTAN_HAS_CAST -#define BOTAN_HAS_CBC -#define BOTAN_HAS_CBC_MAC -#define BOTAN_HAS_CERTIFICATE_STORE -#define BOTAN_HAS_CFB -#define BOTAN_HAS_CIPHER_MODE_PADDING -#define BOTAN_HAS_CMAC -#define BOTAN_HAS_CODEC_FILTERS -#define BOTAN_HAS_COMB4P -#define BOTAN_HAS_CORE_ENGINE -#define BOTAN_HAS_CRC24 -#define BOTAN_HAS_CRC32 -#define BOTAN_HAS_CRYPTO_BOX -#define BOTAN_HAS_CTR_BE -#define BOTAN_HAS_CTS -#define BOTAN_HAS_DES -#define BOTAN_HAS_DIFFIE_HELLMAN -#define BOTAN_HAS_DLIES -#define BOTAN_HAS_DL_GROUP -#define BOTAN_HAS_DL_PUBLIC_KEY_FAMILY -#define BOTAN_HAS_DSA -#define BOTAN_HAS_EAX -#define BOTAN_HAS_ECB -#define BOTAN_HAS_ECC_GROUP -#define BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO -#define BOTAN_HAS_ECDH -#define BOTAN_HAS_ECDSA -#define BOTAN_HAS_EC_CURVE_GFP -#define BOTAN_HAS_ELGAMAL -#define BOTAN_HAS_EME1 -#define BOTAN_HAS_EME_PKCS1v15 -#define BOTAN_HAS_EMSA1 -#define BOTAN_HAS_EMSA1_BSI -#define BOTAN_HAS_EMSA2 -#define BOTAN_HAS_EMSA3 -#define BOTAN_HAS_EMSA4 -#define BOTAN_HAS_EMSA_RAW -#define BOTAN_HAS_ENGINES -#define BOTAN_HAS_ENGINE_SIMD -#define BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER -#define BOTAN_HAS_FILTERS -#define BOTAN_HAS_FPE_FE1 -#define BOTAN_HAS_GOST_28147_89 -#define BOTAN_HAS_GOST_34_10_2001 -#define BOTAN_HAS_GOST_34_11 -#define BOTAN_HAS_HASH_ID -#define BOTAN_HAS_HAS_160 -#define BOTAN_HAS_HEX_CODEC -#define BOTAN_HAS_HMAC -#define BOTAN_HAS_HMAC_RNG -#define BOTAN_HAS_IDEA -#define BOTAN_HAS_IF_PUBLIC_KEY_FAMILY -#define BOTAN_HAS_KASUMI -#define BOTAN_HAS_KDF1 -#define BOTAN_HAS_KDF2 -#define BOTAN_HAS_KDF_BASE -#define BOTAN_HAS_KECCAK -#define BOTAN_HAS_KEYPAIR_TESTING -#define BOTAN_HAS_LIBSTATE_MODULE -#define BOTAN_HAS_LION -#define BOTAN_HAS_LUBY_RACKOFF -#define BOTAN_HAS_MARS -#define BOTAN_HAS_MD2 -#define BOTAN_HAS_MD4 -#define BOTAN_HAS_MD5 -#define BOTAN_HAS_MDX_HASH_FUNCTION -#define BOTAN_HAS_MGF1 -#define BOTAN_HAS_MISTY1 -#define BOTAN_HAS_MUTEX_NOOP -#define BOTAN_HAS_MUTEX_WRAPPERS -#define BOTAN_HAS_NOEKEON -#define BOTAN_HAS_NOEKEON_SIMD -#define BOTAN_HAS_NYBERG_RUEPPEL -#define BOTAN_HAS_OFB -#define BOTAN_HAS_OID_LOOKUP -#define BOTAN_HAS_OPENPGP_CODEC -#define BOTAN_HAS_PACKAGE_TRANSFORM -#define BOTAN_HAS_PARALLEL_HASH -#define BOTAN_HAS_PASSHASH9 -#define BOTAN_HAS_PASSWORD_BASED_ENCRYPTION -#define BOTAN_HAS_PBE_PKCS_V15 -#define BOTAN_HAS_PBE_PKCS_V20 -#define BOTAN_HAS_PBKDF1 -#define BOTAN_HAS_PBKDF2 -#define BOTAN_HAS_PEM_CODEC -#define BOTAN_HAS_PGPS2K -#define BOTAN_HAS_PKCS10_REQUESTS -#define BOTAN_HAS_PK_PADDING -#define BOTAN_HAS_PUBLIC_KEY_CRYPTO -#define BOTAN_HAS_PUBLIC_KEY_CRYPTO -#define BOTAN_HAS_RANDPOOL -#define BOTAN_HAS_RC2 -#define BOTAN_HAS_RC5 -#define BOTAN_HAS_RC6 -#define BOTAN_HAS_RFC3394_KEYWRAP -#define BOTAN_HAS_RIPEMD_128 -#define BOTAN_HAS_RIPEMD_160 -#define BOTAN_HAS_RSA -#define BOTAN_HAS_RUNTIME_BENCHMARKING -#define BOTAN_HAS_RW -#define BOTAN_HAS_SAFER -#define BOTAN_HAS_SALSA20 -#define BOTAN_HAS_SEED -#define BOTAN_HAS_SELFTESTS -#define BOTAN_HAS_SERPENT -#define BOTAN_HAS_SERPENT_SIMD -#define BOTAN_HAS_SHA1 -#define BOTAN_HAS_SHA2_32 -#define BOTAN_HAS_SHA2_64 -#define BOTAN_HAS_SIMD_32 -#define BOTAN_HAS_SIMD_SCALAR -#define BOTAN_HAS_SKEIN_512 -#define BOTAN_HAS_SKIPJACK -#define BOTAN_HAS_SQUARE -#define BOTAN_HAS_SRP6 -#define BOTAN_HAS_SSL3_MAC -#define BOTAN_HAS_SSL_V3_PRF -#define BOTAN_HAS_STREAM_CIPHER -#define BOTAN_HAS_TEA -#define BOTAN_HAS_THRESHOLD_SECRET_SHARING -#define BOTAN_HAS_TIGER -#define BOTAN_HAS_TLS_V10_PRF -#define BOTAN_HAS_TURING -#define BOTAN_HAS_TWOFISH -#define BOTAN_HAS_UTIL_FUNCTIONS -#define BOTAN_HAS_WHIRLPOOL -#define BOTAN_HAS_WID_WAKE -#define BOTAN_HAS_X509_CA -#define BOTAN_HAS_X509_CERTIFICATES -#define BOTAN_HAS_X509_CRL -#define BOTAN_HAS_X509_SELF_SIGNED -#define BOTAN_HAS_X509_STORE -#define BOTAN_HAS_X931_RNG -#define BOTAN_HAS_X942_PRF -#define BOTAN_HAS_XTEA -#define BOTAN_HAS_XTEA_SIMD -#define BOTAN_HAS_XTS - -/* -* Local configuration options (if any) follow -*/ - - -#include <stddef.h> - -/** -* The primary namespace for the botan library -*/ -namespace Botan { - -/** -* Typedef representing an unsigned 8-bit quantity -*/ -typedef unsigned char byte; - -/** -* Typedef representing an unsigned 16-bit quantity -*/ -typedef unsigned short u16bit; - -/** -* Typedef representing an unsigned 32-bit quantity -*/ -typedef unsigned int u32bit; - -/** -* Typedef representing a signed 32-bit quantity -*/ -typedef signed int s32bit; - -/** -* Typedef representing an unsigned 64-bit quantity -*/ -#if defined(_MSC_VER) || defined(__BORLANDC__) - typedef unsigned __int64 u64bit; -#elif defined(__KCC) - typedef unsigned __long_long u64bit; -#elif defined(__GNUG__) - __extension__ typedef unsigned long long u64bit; -#else - typedef unsigned long long u64bit; -#endif - -/** -* A default buffer size; typically a memory page -*/ -static const size_t DEFAULT_BUFFERSIZE = BOTAN_DEFAULT_BUFFER_SIZE; - -} - -namespace Botan_types { - -using Botan::byte; -using Botan::u32bit; - -} - - -namespace Botan { - -/** -* Allocator Interface -*/ -class BOTAN_DLL Allocator - { - public: - /** - * Acquire a pointer to an allocator - * @param locking is true if the allocator should attempt to - * secure the memory (eg for using to store keys) - * @return pointer to an allocator; ownership remains with library, - * so do not delete - */ - static Allocator* get(bool locking); - - /** - * Allocate a block of memory - * @param n how many bytes to allocate - * @return pointer to n bytes of memory - */ - virtual void* allocate(size_t n) = 0; - - /** - * Deallocate memory allocated with allocate() - * @param ptr the pointer returned by allocate() - * @param n the size of the block pointed to by ptr - */ - virtual void deallocate(void* ptr, size_t n) = 0; - - /** - * @return name of this allocator type - */ - virtual std::string type() const = 0; - - /** - * Initialize the allocator - */ - virtual void init() {} - - /** - * Shutdown the allocator - */ - virtual void destroy() {} - - virtual ~Allocator() Q_DECL_NOEXCEPT_EXPR(false) {} - }; - -} - - -namespace Botan { - -/** -* Copy memory -* @param out the destination array -* @param in the source array -* @param n the number of elements of in/out -*/ -template<typename T> inline void copy_mem(T* out, const T* in, size_t n) - { - std::memmove(out, in, sizeof(T)*n); - } - -/** -* Zeroize memory -* @param ptr a pointer to an array -* @param n the number of Ts pointed to by ptr -*/ -template<typename T> inline void clear_mem(T* ptr, size_t n) - { - if(n) // avoid glibc warning if n == 0 - std::memset(ptr, 0, sizeof(T)*n); - } - -/** -* Set memory to a fixed value -* @param ptr a pointer to an array -* @param n the number of Ts pointed to by ptr -* @param val the value to set each byte to -*/ -template<typename T> -inline void set_mem(T* ptr, size_t n, byte val) - { - std::memset(ptr, val, sizeof(T)*n); - } - -/** -* Memory comparison, input insensitive -* @param p1 a pointer to an array -* @param p2 a pointer to another array -* @param n the number of Ts in p1 and p2 -* @return true iff p1[i] == p2[i] forall i in [0...n) -*/ -template<typename T> inline bool same_mem(const T* p1, const T* p2, size_t n) - { - bool is_same = true; - - for(size_t i = 0; i != n; ++i) - is_same &= (p1[i] == p2[i]); - - return is_same; - } - -} - - -namespace Botan { - -/** -* This class represents variable length memory buffers. -*/ -template<typename T> -class MemoryRegion - { - public: - /** - * Find out the size of the buffer, i.e. how many objects of type T it - * contains. - * @return size of the buffer - */ - size_t size() const { return used; } - - /** - * Find out whether this buffer is empty. - * @return true if the buffer is empty, false otherwise - */ - bool empty() const { return (used == 0); } - - /** - * Get a pointer to the first element in the buffer. - * @return pointer to the first element in the buffer - */ - operator T* () { return buf; } - - /** - * Get a constant pointer to the first element in the buffer. - * @return constant pointer to the first element in the buffer - */ - operator const T* () const { return buf; } - - /** - * Get a pointer to the first element in the buffer. - * @return pointer to the first element in the buffer - */ - T* begin() { return buf; } - - /** - * Get a constant pointer to the first element in the buffer. - * @return constant pointer to the first element in the buffer - */ - const T* begin() const { return buf; } - - /** - * Get a pointer to one past the last element in the buffer. - * @return pointer to one past the last element in the buffer - */ - T* end() { return (buf + size()); } - - /** - * Get a const pointer to one past the last element in the buffer. - * @return const pointer to one past the last element in the buffer - */ - const T* end() const { return (buf + size()); } - - /** - * Check two buffers for equality. - * @return true iff the content of both buffers is byte-wise equal - */ - bool operator==(const MemoryRegion<T>& other) const - { - return (size() == other.size() && - same_mem(buf, other.buf, size())); - } - - /** - * Compare two buffers - * @return true iff this is ordered before other - */ - bool operator<(const MemoryRegion<T>& other) const; - - /** - * Check two buffers for inequality. - * @return false if the content of both buffers is byte-wise equal, true - * otherwise. - */ - bool operator!=(const MemoryRegion<T>& other) const - { return (!(*this == other)); } - - /** - * Copy the contents of another buffer into this buffer. - * The former contents of *this are discarded. - * @param other the buffer to copy the contents from. - * @return reference to *this - */ - MemoryRegion<T>& operator=(const MemoryRegion<T>& other) - { - if(this != &other) - { - this->resize(other.size()); - this->copy(&other[0], other.size()); - } - return (*this); - } - - /** - * Copy the contents of an array of objects of type T into this buffer. - * The former contents of *this are discarded. - * The length of *this must be at least n, otherwise memory errors occur. - * @param in the array to copy the contents from - * @param n the length of in - */ - void copy(const T in[], size_t n) - { - copy_mem(buf, in, std::min(n, size())); - } - - /** - * Copy the contents of an array of objects of type T into this buffer. - * The former contents of *this are discarded. - * The length of *this must be at least n, otherwise memory errors occur. - * @param off the offset position inside this buffer to start inserting - * the copied bytes - * @param in the array to copy the contents from - * @param n the length of in - */ - void copy(size_t off, const T in[], size_t n) - { - copy_mem(buf + off, in, std::min(n, size() - off)); - } - - /** - * Append a single element. - * @param x the element to append - */ - void push_back(T x) - { - resize(size() + 1); - buf[size()-1] = x; - } - - /** - * Reset this buffer to an empty buffer with size zero. - */ - void clear() { resize(0); } - - /** - * Inserts or erases elements at the end such that the size - * becomes n, leaving elements in the range 0...n unmodified if - * set or otherwise zero-initialized - * @param n length of the new buffer - */ - void resize(size_t n); - - /** - * Swap this buffer with another object. - */ - void swap(MemoryRegion<T>& other); - - virtual ~MemoryRegion() { deallocate(buf, allocated); } - protected: - MemoryRegion() : buf(0), used(0), allocated(0), alloc(0) {} - - /** - * Copy constructor - * @param other the other region to copy - */ - MemoryRegion(const MemoryRegion<T>& other) : - buf(0), - used(0), - allocated(0), - alloc(other.alloc) - { - resize(other.size()); - copy(&other[0], other.size()); - } - - /** - * @param locking should we use a locking allocator - * @param length the initial length to use - */ - void init(bool locking, size_t length = 0) - { alloc = Allocator::get(locking); resize(length); } - - private: - T* allocate(size_t n) - { - return static_cast<T*>(alloc->allocate(sizeof(T)*n)); - } - - void deallocate(T* p, size_t n) - { if(alloc && p && n) alloc->deallocate(p, sizeof(T)*n); } - - T* buf; - size_t used; - size_t allocated; - Allocator* alloc; - }; - -/* -* Change the size of the buffer -*/ -template<typename T> -void MemoryRegion<T>::resize(size_t n) - { - if(n <= allocated) - { - size_t zap = std::min(used, n); - clear_mem(buf + zap, allocated - zap); - used = n; - } - else - { - 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>& other) const - { - const size_t min_size = std::min(size(), other.size()); - - // This should probably be rewritten to run in constant time - for(size_t i = 0; i != min_size; ++i) - { - if(buf[i] < other[i]) - return true; - if(buf[i] > other[i]) - return false; - } - - // First min_size bytes are equal, shorter is first - return (size() < other.size()); - } - -/* -* 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); - } - -/** -* This class represents variable length buffers that do not -* make use of memory locking. -*/ -template<typename T> -class MemoryVector : public MemoryRegion<T> - { - public: - /** - * Copy the contents of another buffer into this buffer. - * @param in the buffer to copy the contents from - * @return reference to *this - */ - MemoryVector<T>& operator=(const MemoryRegion<T>& in) - { - if(this != &in) - { - this->resize(in.size()); - this->copy(&in[0], in.size()); - } - return (*this); - } - - /** - * Create a buffer of the specified length. - * @param n the length of the buffer to create. - */ - MemoryVector(size_t n = 0) { this->init(false, n); } - - /** - * Create a buffer with the specified contents. - * @param in the array containing the data to be initially copied - * into the newly created buffer - * @param n the size of the arry in - */ - MemoryVector(const T in[], size_t n) - { - this->init(false); - this->resize(n); - this->copy(in, n); - } - - /** - * Copy constructor. - */ - MemoryVector(const MemoryRegion<T>& in) - { - this->init(false); - this->resize(in.size()); - this->copy(&in[0], in.size()); - } - }; - -/** -* This class represents variable length buffers using the operating -* systems capability to lock memory, i.e. keeping it from being -* swapped out to disk. In this way, a security hole allowing attackers -* to find swapped out secret keys is closed. -*/ -template<typename T> -class SecureVector : public MemoryRegion<T> - { - public: - /** - * Copy the contents of another buffer into this buffer. - * @param other the buffer to copy the contents from - * @return reference to *this - */ - SecureVector<T>& operator=(const MemoryRegion<T>& other) - { - if(this != &other) - { - this->resize(other.size()); - this->copy(&other[0], other.size()); - } - return (*this); - } - - /** - * Create a buffer of the specified length. - * @param n the length of the buffer to create. - */ - SecureVector(size_t n = 0) { this->init(true, n); } - - /** - * Create a buffer with the specified contents. - * @param in the array containing the data to be initially copied - * into the newly created buffer - * @param n the size of the array in - */ - SecureVector(const T in[], size_t n) - { - this->init(true); - this->resize(n); - this->copy(&in[0], n); - } - - /** - * Create a buffer with contents specified contents. - * @param in the buffer holding the contents that will be - * copied into the newly created buffer. - */ - SecureVector(const MemoryRegion<T>& in) - { - this->init(true); - this->resize(in.size()); - this->copy(&in[0], in.size()); - } - }; - -template<typename T> -MemoryRegion<T>& operator+=(MemoryRegion<T>& out, - const MemoryRegion<T>& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.size()); - copy_mem(&out[copy_offset], &in[0], in.size()); - return out; - } - -template<typename T> -MemoryRegion<T>& operator+=(MemoryRegion<T>& out, - T in) - { - out.push_back(in); - return out; - } - -template<typename T, typename L> -MemoryRegion<T>& operator+=(MemoryRegion<T>& out, - const std::pair<const T*, L>& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.second); - copy_mem(&out[copy_offset], in.first, in.second); - return out; - } - -template<typename T, typename L> -MemoryRegion<T>& operator+=(MemoryRegion<T>& out, - const std::pair<T*, L>& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.second); - copy_mem(&out[copy_offset], in.first, in.second); - return out; - } - -/** -* Zeroise the values; length remains unchanged -* @param vec the vector to zeroise -*/ -template<typename T> -void zeroise(MemoryRegion<T>& vec) - { - clear_mem(&vec[0], vec.size()); - } - -} - -namespace std { - -template<typename T> -inline void swap(Botan::MemoryRegion<T>& x, Botan::MemoryRegion<T>& y) - { - x.swap(y); - } - -} - - -namespace Botan { - -/** -* Byte extraction -* @param byte_num which byte to extract, 0 == highest byte -* @param input the value to extract from -* @return byte byte_num of input -*/ -template<typename T> inline byte get_byte(size_t byte_num, T input) - { - return static_cast<byte>( - input >> ((sizeof(T)-1-(byte_num&(sizeof(T)-1))) << 3) - ); - } - -} - - -namespace Botan { - -/** -* This class represents any kind of computation which uses an internal -* state, such as hash functions or MACs -*/ -class BOTAN_DLL Buffered_Computation - { - public: - /** - * @return length of the output of this function in bytes - */ - virtual size_t output_length() const = 0; - - /** - * Add new input to process. - * @param in the input to process as a byte array - * @param length of param in in bytes - */ - void update(const byte in[], size_t length) { add_data(in, length); } - - /** - * Add new input to process. - * @param in the input to process as a MemoryRegion - */ - void update(const MemoryRegion<byte>& in) - { - add_data(&in[0], in.size()); - } - - /** - * Add an integer in big-endian order - * @param in the value - */ - template<typename T> void update_be(const T in) - { - for(size_t i = 0; i != sizeof(T); ++i) - { - byte b = get_byte(i, in); - add_data(&b, 1); - } - } - - /** - * Add new input to process. - * @param str the input to process as a std::string. Will be interpreted - * as a byte array based on - * the strings encoding. - */ - void update(const std::string& str) - { - add_data(reinterpret_cast<const byte*>(str.data()), str.size()); - } - - /** - * Process a single byte. - * @param in the byte to process - */ - void update(byte in) { add_data(&in, 1); } - - /** - * Complete the computation and retrieve the - * final result. - * @param out The byte array to be filled with the result. - * Must be of length output_length() - */ - void final(byte out[]) { final_result(out); } - - /** - * Complete the computation and retrieve the - * final result. - * @return SecureVector holding the result - */ - SecureVector<byte> final() - { - SecureVector<byte> output(output_length()); - final_result(&output[0]); - return output; - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process as a byte array - * @param length the length of the byte array - * @result the result of the call to final() - */ - SecureVector<byte> process(const byte in[], size_t length) - { - add_data(in, length); - return final(); - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process - * @result the result of the call to final() - */ - SecureVector<byte> process(const MemoryRegion<byte>& in) - { - add_data(&in[0], in.size()); - return final(); - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process as a string - * @result the result of the call to final() - */ - SecureVector<byte> process(const std::string& in) - { - update(in); - return final(); - } - - virtual ~Buffered_Computation() {} - private: - /** - * Add more data to the computation - * @param input is an input buffer - * @param length is the length of input in bytes - */ - virtual void add_data(const byte input[], size_t length) = 0; - - /** - * Write the final output to out - * @param out is an output buffer of output_length() - */ - virtual void final_result(byte out[]) = 0; - }; - -} - - -namespace Botan { - -/** -* Class used to accumulate the poll results of EntropySources -*/ -class BOTAN_DLL Entropy_Accumulator - { - public: - /** - * Initialize an Entropy_Accumulator - * @param goal is how many bits we would like to collect - */ - Entropy_Accumulator(size_t goal) : - entropy_goal(goal), collected_bits(0) {} - - virtual ~Entropy_Accumulator() {} - - /** - * Get a cached I/O buffer (purely for minimizing allocation - * overhead to polls) - * - * @param size requested size for the I/O buffer - * @return cached I/O buffer for repeated polls - */ - MemoryRegion<byte>& get_io_buffer(size_t size) - { io_buffer.resize(size); return io_buffer; } - - /** - * @return number of bits collected so far - */ - size_t bits_collected() const - { return static_cast<size_t>(collected_bits); } - - /** - * @return if our polling goal has been achieved - */ - bool polling_goal_achieved() const - { return (collected_bits >= entropy_goal); } - - /** - * @return how many bits we need to reach our polling goal - */ - size_t desired_remaining_bits() const - { - if(collected_bits >= entropy_goal) - return 0; - return static_cast<size_t>(entropy_goal - collected_bits); - } - - /** - * Add entropy to the accumulator - * @param bytes the input bytes - * @param length specifies how many bytes the input is - * @param entropy_bits_per_byte is a best guess at how much - * entropy per byte is in this input - */ - void add(const void* bytes, size_t length, double entropy_bits_per_byte) - { - add_bytes(reinterpret_cast<const byte*>(bytes), length); - collected_bits += entropy_bits_per_byte * length; - } - - /** - * Add entropy to the accumulator - * @param v is some value - * @param entropy_bits_per_byte is a best guess at how much - * entropy per byte is in this input - */ - template<typename T> - void add(const T& v, double entropy_bits_per_byte) - { - add(&v, sizeof(T), entropy_bits_per_byte); - } - private: - virtual void add_bytes(const byte bytes[], size_t length) = 0; - - SecureVector<byte> io_buffer; - size_t entropy_goal; - double collected_bits; - }; - -/** -* Entropy accumulator that puts the input into a Buffered_Computation -*/ -class BOTAN_DLL Entropy_Accumulator_BufferedComputation : - public Entropy_Accumulator - { - public: - /** - * @param sink the hash or MAC we are feeding the poll data into - * @param goal is how many bits we want to collect in this poll - */ - Entropy_Accumulator_BufferedComputation(Buffered_Computation& sink, - size_t goal) : - Entropy_Accumulator(goal), entropy_sink(sink) {} - - private: - virtual void add_bytes(const byte bytes[], size_t length) - { - entropy_sink.update(bytes, length); - } - - Buffered_Computation& entropy_sink; - }; - -/** -* Abstract interface to a source of (hopefully unpredictable) system entropy -*/ -class BOTAN_DLL EntropySource - { - public: - /** - * @return name identifying this entropy source - */ - virtual std::string name() const = 0; - - /** - * Perform an entropy gathering poll - * @param accum is an accumulator object that will be given entropy - */ - virtual void poll(Entropy_Accumulator& accum) = 0; - - virtual ~EntropySource() {} - }; - -} - - -namespace Botan { - -/** -* Parse a SCAN-style algorithm name -* @param scan_name the name -* @return the name components -*/ -BOTAN_DLL std::vector<std::string> -parse_algorithm_name(const std::string& scan_name); - -/** -* Split a string -* @param str the input string -* @param delim the delimitor -* @return string split by delim -*/ -BOTAN_DLL std::vector<std::string> split_on( - const std::string& str, char delim); - -/** -* Parse an ASN.1 OID -* @param oid the OID in string form -* @return OID components -*/ -BOTAN_DLL std::vector<u32bit> parse_asn1_oid(const std::string& oid); - -/** -* Compare two names using the X.509 comparison algorithm -* @param name1 the first name -* @param name2 the second name -* @return true if name1 is the same as name2 by the X.509 comparison rules -*/ -BOTAN_DLL bool x500_name_cmp(const std::string& name1, - const std::string& name2); - -/** -* Convert a number to a string -* @param n the integer to convert to a string -* @param min_len the min length of the output string -* @return n convert to a string -*/ -BOTAN_DLL std::string to_string(u64bit n, size_t min_len = 0); - -/** -* Convert a string to a number -* @param str the string to convert -* @return number value of the string -*/ -BOTAN_DLL u32bit to_u32bit(const std::string& str); - -/** -* Convert a time specification to a number -* @param timespec the time specification -* @return number of seconds represented by timespec -*/ -BOTAN_DLL u32bit timespec_to_u32bit(const std::string& timespec); - -/** -* Convert a string representation of an IPv4 address to a number -* @param ip_str the string representation -* @return integer IPv4 address -*/ -BOTAN_DLL u32bit string_to_ipv4(const std::string& ip_str); - -/** -* Convert an IPv4 address to a string -* @param ip_addr the IPv4 address to convert -* @return string representation of the IPv4 address -*/ -BOTAN_DLL std::string ipv4_to_string(u32bit ip_addr); - -} - - -namespace Botan { - -typedef std::runtime_error Exception; -typedef std::invalid_argument Invalid_Argument; - -/** -* Invalid_State Exception -*/ -struct BOTAN_DLL Invalid_State : public Exception - { - Invalid_State(const std::string& err) : - Exception(err) - {} - }; - -/** -* Lookup_Error Exception -*/ -struct BOTAN_DLL Lookup_Error : public Exception - { - Lookup_Error(const std::string& err) : - Exception(err) - {} - }; - -/** -* Internal_Error Exception -*/ -struct BOTAN_DLL Internal_Error : public Exception - { - Internal_Error(const std::string& err) : - Exception("Internal error: " + err) - {} - }; - -/** -* Invalid_Key_Length Exception -*/ -struct BOTAN_DLL Invalid_Key_Length : public Invalid_Argument - { - Invalid_Key_Length(const std::string& name, size_t length) : - Invalid_Argument(name + " cannot accept a key of length " + - to_string(length)) - {} - }; - -/** -* Invalid_Block_Size Exception -*/ -struct BOTAN_DLL Invalid_Block_Size : public Invalid_Argument - { - Invalid_Block_Size(const std::string& mode, - const std::string& pad) : - Invalid_Argument("Padding method " + pad + - " cannot be used with " + mode) - {} - }; - -/** -* Invalid_IV_Length Exception -*/ -struct BOTAN_DLL Invalid_IV_Length : public Invalid_Argument - { - Invalid_IV_Length(const std::string& mode, size_t bad_len) : - Invalid_Argument("IV length " + to_string(bad_len) + - " is invalid for " + mode) - {} - }; - -/** -* 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) - {} - }; - -/** -* Algorithm_Not_Found Exception -*/ -struct BOTAN_DLL Algorithm_Not_Found : public Lookup_Error - { - Algorithm_Not_Found(const std::string& name) : - Lookup_Error("Could not find any algorithm named \"" + name + "\"") - {} - }; - -/** -* Invalid_Algorithm_Name Exception -*/ -struct BOTAN_DLL Invalid_Algorithm_Name : public Invalid_Argument - { - Invalid_Algorithm_Name(const std::string& name): - Invalid_Argument("Invalid algorithm name: " + name) - {} - }; - -/** -* Encoding_Error Exception -*/ -struct BOTAN_DLL Encoding_Error : public Invalid_Argument - { - Encoding_Error(const std::string& name) : - Invalid_Argument("Encoding error: " + name) {} - }; - -/** -* Decoding_Error Exception -*/ -struct BOTAN_DLL Decoding_Error : public Invalid_Argument - { - Decoding_Error(const std::string& name) : - Invalid_Argument("Decoding error: " + name) {} - }; - -/** -* Integrity_Failure Exception -*/ -struct BOTAN_DLL Integrity_Failure : public Exception - { - Integrity_Failure(const std::string& msg) : - Exception("Integrity failure: " + msg) {} - }; - -/** -* 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) - {} - }; - -/** -* 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) - {} - }; - -/** -* Memory Allocation Exception -*/ -struct BOTAN_DLL Memory_Exhaustion : public std::bad_alloc - { - const char* what() const throw() - { return "Ran out of memory, allocation failed"; } - }; - -} - - -namespace Botan { - -/** -* This class represents a random number (RNG) generator object. -*/ -class BOTAN_DLL RandomNumberGenerator - { - public: - /** - * Create a seeded and active RNG object for general application use - */ - static RandomNumberGenerator* make_rng(); - - /** - * Randomize a byte array. - * @param output the byte array to hold the random output. - * @param length the length of the byte array output. - */ - virtual void randomize(byte output[], size_t length) = 0; - - /** - * Return a random vector - * @param bytes number of bytes in the result - * @return randomized vector of length bytes - */ - SecureVector<byte> random_vec(size_t bytes) - { - SecureVector<byte> output(bytes); - randomize(&output[0], output.size()); - return output; - } - - /** - * Return a random byte - * @return random byte - */ - byte next_byte(); - - /** - * Check whether this RNG is seeded. - * @return true if this RNG was already seeded, false otherwise. - */ - virtual bool is_seeded() const { return true; } - - /** - * Clear all internally held values of this RNG. - */ - virtual void clear() = 0; - - /** - * Return the name of this object - */ - virtual std::string name() const = 0; - - /** - * Seed this RNG using the entropy sources it contains. - * @param bits_to_collect is the number of bits of entropy to - attempt to gather from the entropy sources - */ - virtual void reseed(size_t bits_to_collect) = 0; - - /** - * Add this entropy source to the RNG object - * @param source the entropy source which will be retained and used by RNG - */ - virtual void add_entropy_source(EntropySource* source) = 0; - - /** - * Add entropy to this RNG. - * @param in a byte array containg the entropy to be added - * @param length the length of the byte array in - */ - virtual void add_entropy(const byte in[], size_t length) = 0; - - RandomNumberGenerator() {} - virtual ~RandomNumberGenerator() {} - private: - RandomNumberGenerator(const RandomNumberGenerator&) {} - RandomNumberGenerator& operator=(const RandomNumberGenerator&) - { return (*this); } - }; - -/** -* Null/stub RNG - fails if you try to use it for anything -*/ -class BOTAN_DLL Null_RNG : public RandomNumberGenerator - { - public: - void randomize(byte[], size_t) { throw PRNG_Unseeded("Null_RNG"); } - void clear() {} - std::string name() const { return "Null_RNG"; } - - void reseed(size_t) {} - bool is_seeded() const { return false; } - void add_entropy(const byte[], size_t) {} - void add_entropy_source(EntropySource* es) { delete es; } - }; - -} - - -namespace Botan { - -/** -* Encoding Method for Signatures, Appendix -*/ -class BOTAN_DLL EMSA - { - public: - /** - * Add more data to the signature computation - * @param input some data - * @param length length of input in bytes - */ - virtual void update(const byte input[], size_t length) = 0; - - /** - * @return raw hash - */ - virtual SecureVector<byte> raw_data() = 0; - - /** - * Return the encoding of a message - * @param msg the result of raw_data() - * @param output_bits the desired output bit size - * @param rng a random number generator - * @return encoded signature - */ - virtual SecureVector<byte> encoding_of(const MemoryRegion<byte>& msg, - size_t output_bits, - RandomNumberGenerator& rng) = 0; - - /** - * Verify the encoding - * @param coded the received (coded) message representative - * @param raw the computed (local, uncoded) message representative - * @param key_bits the size of the key in bits - * @return true if coded is a valid encoding of raw, otherwise false - */ - virtual bool verify(const MemoryRegion<byte>& coded, - const MemoryRegion<byte>& raw, - size_t key_bits) = 0; - virtual ~EMSA() {} - }; - -} - - -namespace Botan { - -/** -* This class represents an algorithm of some kind -*/ -class BOTAN_DLL Algorithm - { - public: - - /** - * Zeroize internal state - */ - virtual void clear() = 0; - - /** - * @return name of this algorithm - */ - virtual std::string name() const = 0; - - Algorithm() {} - virtual ~Algorithm() {} - private: - Algorithm(const Algorithm&) {} - Algorithm& operator=(const Algorithm&) { return (*this); } - }; - -} - - -namespace Botan { - -/** -* This class represents hash function (message digest) objects -*/ -class BOTAN_DLL HashFunction : public Buffered_Computation, - public Algorithm - { - public: - /** - * Get a new object representing the same algorithm as *this - */ - virtual HashFunction* clone() const = 0; - - /** - * The hash block size as defined for this algorithm - */ - virtual size_t hash_block_size() const { return 0; } - }; - -} - - -namespace Botan { - -/** -* EMSA1 from IEEE 1363 -* Essentially, sign the hash directly -*/ -class BOTAN_DLL EMSA1 : public EMSA - { - public: - /** - * @param h the hash object to use - */ - EMSA1(HashFunction* h) : hash(h) {} - ~EMSA1() { delete hash; } - protected: - /** - * @return const pointer to the underlying hash - */ - const HashFunction* hash_ptr() const { return hash; } - private: - void update(const byte[], size_t); - SecureVector<byte> raw_data(); - - SecureVector<byte> encoding_of(const MemoryRegion<byte>&, size_t, - RandomNumberGenerator& rng); - - bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - size_t); - - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* Keccak[1600], a SHA-3 candidate -*/ -class BOTAN_DLL Keccak_1600 : public HashFunction - { - public: - - /** - * @param output_bits the size of the hash output; must be one of - * 224, 256, 384, or 512 - */ - Keccak_1600(size_t output_bits = 512); - - size_t hash_block_size() const { return bitrate / 8; } - size_t output_length() const { return output_bits / 8; } - - HashFunction* clone() const; - std::string name() const; - void clear(); - private: - void add_data(const byte input[], size_t length); - void final_result(byte out[]); - - size_t output_bits, bitrate; - SecureVector<u64bit> S; - size_t S_pos; - }; - -} - - -namespace Botan { - -/** -A class encapsulating a SCAN name (similar to JCE conventions) -http://www.users.zetnet.co.uk/hopwood/crypto/scan/ -*/ -class BOTAN_DLL SCAN_Name - { - public: - /** - * @param algo_spec A SCAN-format name - */ - SCAN_Name(std::string algo_spec); - - /** - * @return original input string - */ - std::string as_string() const { return orig_algo_spec; } - - /** - * @return algorithm name - */ - std::string algo_name() const { return alg_name; } - - /** - * @return algorithm name plus any arguments - */ - std::string algo_name_and_args() const; - - /** - * @return number of arguments - */ - size_t arg_count() const { return args.size(); } - - /** - * @param lower is the lower bound - * @param upper is the upper bound - * @return if the number of arguments is between lower and upper - */ - bool arg_count_between(size_t lower, size_t upper) const - { return ((arg_count() >= lower) && (arg_count() <= upper)); } - - /** - * @param i which argument - * @return ith argument - */ - std::string arg(size_t i) const; - - /** - * @param i which argument - * @param def_value the default value - * @return ith argument or the default value - */ - std::string arg(size_t i, const std::string& def_value) const; - - /** - * @param i which argument - * @param def_value the default value - * @return ith argument as an integer, or the default value - */ - size_t arg_as_integer(size_t i, size_t def_value) const; - - /** - * @return cipher mode (if any) - */ - std::string cipher_mode() const - { return (mode_info.size() >= 1) ? mode_info[0] : ""; } - - /** - * @return cipher mode padding (if any) - */ - std::string cipher_mode_pad() const - { return (mode_info.size() >= 2) ? mode_info[1] : ""; } - - private: - std::string orig_algo_spec; - std::string alg_name; - std::vector<std::string> args; - std::vector<std::string> mode_info; - }; - -} - - -namespace Botan { - -/** -* Represents the length requirements on an algorithm key -*/ -class BOTAN_DLL Key_Length_Specification - { - public: - /** - * Constructor for fixed length keys - * @param keylen the supported key length - */ - Key_Length_Specification(size_t keylen) : - min_keylen(keylen), - max_keylen(keylen), - keylen_mod(1) - { - } - - /** - * Constructor for variable length keys - * @param min_k the smallest supported key length - * @param max_k the largest supported key length - * @param k_mod the number of bytes the key must be a multiple of - */ - Key_Length_Specification(size_t min_k, - size_t max_k, - size_t k_mod = 1) : - min_keylen(min_k), - max_keylen(max_k ? max_k : min_k), - keylen_mod(k_mod) - { - } - - /** - * @param length is a key length in bytes - * @return true iff this length is a valid length for this algo - */ - bool valid_keylength(size_t length) const - { - return ((length >= min_keylen) && - (length <= max_keylen) && - (length % keylen_mod == 0)); - } - - /** - * @return minimum key length in bytes - */ - size_t minimum_keylength() const - { - return min_keylen; - } - - /** - * @return maximum key length in bytes - */ - size_t maximum_keylength() const - { - return max_keylen; - } - - /** - * @return key length multiple in bytes - */ - size_t keylength_multiple() const - { - return keylen_mod; - } - - private: - size_t min_keylen, max_keylen, keylen_mod; - }; - -} - - -namespace Botan { - -/** -* Octet String -*/ -class BOTAN_DLL OctetString - { - public: - /** - * @return size of this octet string in bytes - */ - size_t length() const { return bits.size(); } - - /** - * @return this object as a SecureVector<byte> - */ - SecureVector<byte> bits_of() const { return bits; } - - /** - * @return start of this string - */ - const byte* begin() const { return &bits[0]; } - - /** - * @return end of this string - */ - const byte* end() const { return &bits[bits.size()]; } - - /** - * @return this encoded as hex - */ - std::string as_string() const; - - /** - * XOR the contents of another octet string into this one - * @param other octet string - * @return reference to this - */ - OctetString& operator^=(const OctetString& other); - - /** - * Force to have odd parity - */ - void set_odd_parity(); - - /** - * Change the contents of this octet string - * @param hex_string a hex encoded bytestring - */ - void change(const std::string& hex_string); - - /** - * Change the contents of this octet string - * @param in the input - * @param length of in in bytes - */ - void change(const byte in[], size_t length); - - /** - * Change the contents of this octet string - * @param in the input - */ - void change(const MemoryRegion<byte>& in) { bits = in; } - - /** - * Create a new random OctetString - * @param rng is a random number generator - * @param len is the desired length in bytes - */ - OctetString(class RandomNumberGenerator& rng, size_t len); - - /** - * Create a new OctetString - * @param str is a hex encoded string - */ - OctetString(const std::string& str = "") { change(str); } - - /** - * Create a new OctetString - * @param in is an array - * @param len is the length of in in bytes - */ - OctetString(const byte in[], size_t len) { change(in, len); } - - /** - * Create a new OctetString - * @param in a bytestring - */ - OctetString(const MemoryRegion<byte>& in) { change(in); } - private: - SecureVector<byte> bits; - }; - -/** -* Compare two strings -* @param x an octet string -* @param y an octet string -* @return if x is equal to y -*/ -BOTAN_DLL bool operator==(const OctetString& x, - const OctetString& y); - -/** -* Compare two strings -* @param x an octet string -* @param y an octet string -* @return if x is not equal to y -*/ -BOTAN_DLL bool operator!=(const OctetString& x, - const OctetString& y); - -/** -* Concatenate two strings -* @param x an octet string -* @param y an octet string -* @return x concatenated with y -*/ -BOTAN_DLL OctetString operator+(const OctetString& x, - const OctetString& y); - -/** -* XOR two strings -* @param x an octet string -* @param y an octet string -* @return x XORed with y -*/ -BOTAN_DLL OctetString operator^(const OctetString& x, - const OctetString& y); - - -/** -* Alternate name for octet string showing intent to use as a key -*/ -typedef OctetString SymmetricKey; - -/** -* Alternate name for octet string showing intent to use as an IV -*/ -typedef OctetString InitializationVector; - -} - - -namespace Botan { - -/** -* This class represents a symmetric algorithm object. -*/ -class BOTAN_DLL SymmetricAlgorithm : public Algorithm - { - public: - /** - * @return object describing limits on key size - */ - virtual Key_Length_Specification key_spec() const = 0; - - /** - * @return minimum allowed key length - */ - size_t maximum_keylength() const - { - return key_spec().maximum_keylength(); - } - - /** - * @return maxmium allowed key length - */ - size_t minimum_keylength() const - { - return key_spec().minimum_keylength(); - } - - /** - * Check whether a given key length is valid for this algorithm. - * @param length the key length to be checked. - * @return true if the key length is valid. - */ - bool valid_keylength(size_t length) const - { - return key_spec().valid_keylength(length); - } - - /** - * Set the symmetric key of this object. - * @param key the SymmetricKey to be set. - */ - void set_key(const SymmetricKey& key) - { set_key(key.begin(), key.length()); } - - /** - * Set the symmetric key of this object. - * @param key the to be set as a byte array. - * @param length in bytes of key param - */ - void set_key(const byte key[], size_t length) - { - if(!valid_keylength(length)) - throw Invalid_Key_Length(name(), length); - key_schedule(key, length); - } - private: - /** - * Run the key schedule - * @param key the key - * @param length of key - */ - virtual void key_schedule(const byte key[], size_t length) = 0; - }; - -/** -* The two possible directions for cipher filters, determining whether they -* actually perform encryption or decryption. -*/ -enum Cipher_Dir { ENCRYPTION, DECRYPTION }; - -} - - -namespace Botan { - -/** -* This class represents a block cipher object. -*/ -class BOTAN_DLL BlockCipher : public SymmetricAlgorithm - { - public: - - /** - * @return block size of this algorithm - */ - virtual size_t block_size() const = 0; - - /** - * @return native parallelism of this cipher in blocks - */ - virtual size_t parallelism() const { return 1; } - - /** - * @return prefererred parallelism of this cipher in bytes - */ - size_t parallel_bytes() const - { - return parallelism() * block_size() * BOTAN_BLOCK_CIPHER_PAR_MULT; - } - - /** - * Encrypt a block. - * @param in The plaintext block to be encrypted as a byte array. - * Must be of length block_size(). - * @param out The byte array designated to hold the encrypted block. - * Must be of length block_size(). - */ - void encrypt(const byte in[], byte out[]) const - { encrypt_n(in, out, 1); } - - /** - * Decrypt a block. - * @param in The ciphertext block to be decypted as a byte array. - * Must be of length block_size(). - * @param out The byte array designated to hold the decrypted block. - * Must be of length block_size(). - */ - void decrypt(const byte in[], byte out[]) const - { decrypt_n(in, out, 1); } - - /** - * Encrypt a block. - * @param block the plaintext block to be encrypted - * Must be of length block_size(). Will hold the result when the function - * has finished. - */ - void encrypt(byte block[]) const { encrypt_n(block, block, 1); } - - /** - * Decrypt a block. - * @param block the ciphertext block to be decrypted - * Must be of length block_size(). Will hold the result when the function - * has finished. - */ - void decrypt(byte block[]) const { decrypt_n(block, block, 1); } - - /** - * Encrypt one or more blocks - * @param in the input buffer (multiple of block_size()) - * @param out the output buffer (same size as in) - * @param blocks the number of blocks to process - */ - virtual void encrypt_n(const byte in[], byte out[], - size_t blocks) const = 0; - - /** - * Decrypt one or more blocks - * @param in the input buffer (multiple of block_size()) - * @param out the output buffer (same size as in) - * @param blocks the number of blocks to process - */ - virtual void decrypt_n(const byte in[], byte out[], - size_t blocks) const = 0; - - /** - * Get a new object representing the same algorithm as *this - */ - virtual BlockCipher* clone() const = 0; - }; - -/** -* Represents a block cipher with a single fixed block size -*/ -template<size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1> -class Block_Cipher_Fixed_Params : public BlockCipher - { - public: - enum { BLOCK_SIZE = BS }; - size_t block_size() const { return BS; } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(KMIN, KMAX, KMOD); - } - }; - -} - - -namespace Botan { - -/** -* Base class for all stream ciphers -*/ -class BOTAN_DLL StreamCipher : public SymmetricAlgorithm - { - public: - /** - * Encrypt or decrypt a message - * @param in the plaintext - * @param out the byte array to hold the output, i.e. the ciphertext - * @param len the length of both in and out in bytes - */ - virtual void cipher(const byte in[], byte out[], size_t len) = 0; - - /** - * Encrypt or decrypt a message - * @param buf the plaintext / ciphertext - * @param len the length of buf in bytes - */ - void cipher1(byte buf[], size_t len) - { cipher(buf, buf, len); } - - /** - * Resync the cipher using the IV - * @param iv the initialization vector - * @param iv_len the length of the IV in bytes - */ - virtual void set_iv(const byte iv[], size_t iv_len); - - /** - * @param iv_len the length of the IV in bytes - * @return if the length is valid for this algorithm - */ - virtual bool valid_iv_length(size_t iv_len) const; - - /** - * Get a new object representing the same algorithm as *this - */ - virtual StreamCipher* clone() const = 0; - }; - -} - - -namespace Botan { - -/** -* This class represents Message Authentication Code (MAC) objects. -*/ -class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, - public SymmetricAlgorithm - { - public: - /** - * Verify a MAC. - * @param in the MAC to verify as a byte array - * @param length the length of param in - * @return true if the MAC is valid, false otherwise - */ - virtual bool verify_mac(const byte in[], size_t length); - - /** - * Get a new object representing the same algorithm as *this - */ - virtual MessageAuthenticationCode* clone() const = 0; - - /** - * Get the name of this algorithm. - * @return name of this algorithm - */ - virtual std::string name() const = 0; - }; - -} - - -namespace Botan { - -/** -* Base class for PBKDF (password based key derivation function) -* implementations. Converts a password into a key using a salt -* and iterated hashing to make brute force attacks harder. -*/ -class BOTAN_DLL PBKDF : public Algorithm - { - public: - - /** - * @return new instance of this same algorithm - */ - virtual PBKDF* clone() const = 0; - - void clear() {} - - /** - * Derive a key from a passphrase - * @param output_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * @param iterations the number of iterations to use (use 10K or more) - */ - virtual OctetString derive_key(size_t output_len, - const std::string& passphrase, - const byte salt[], size_t salt_len, - size_t iterations) const = 0; - }; - -/** -* For compatability with 1.8 -*/ -typedef PBKDF S2K; - -} - - -namespace Botan { - -#if (BOTAN_MP_WORD_BITS == 8) - typedef byte word; -#elif (BOTAN_MP_WORD_BITS == 16) - typedef u16bit word; -#elif (BOTAN_MP_WORD_BITS == 32) - typedef u32bit word; -#elif (BOTAN_MP_WORD_BITS == 64) - typedef u64bit word; -#else - #error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64 -#endif - -const word MP_WORD_MASK = ~static_cast<word>(0); -const word MP_WORD_TOP_BIT = static_cast<word>(1) << (8*sizeof(word) - 1); -const word MP_WORD_MAX = MP_WORD_MASK; - -} - - -namespace Botan { - -/** -* Arbitrary precision integer -*/ -class BOTAN_DLL BigInt - { - public: - /** - * Base enumerator for encoding and decoding - */ - enum Base { Octal = 8, Decimal = 10, Hexadecimal = 16, Binary = 256 }; - - /** - * Sign symbol definitions for positive and negative numbers - */ - enum Sign { Negative = 0, Positive = 1 }; - - /** - * Number types (currently only power-of-2 supported) - */ - enum NumberType { Power2 }; - - /** - * DivideByZero Exception - */ - struct BOTAN_DLL DivideByZero : public Exception - { DivideByZero() : Exception("BigInt divide by zero") {} }; - - /** - * += operator - * @param y the BigInt to add to this - */ - BigInt& operator+=(const BigInt& y); - - /** - * -= operator - * @param y the BigInt to subtract from this - */ - BigInt& operator-=(const BigInt& y); - - /** - * *= operator - * @param y the BigInt to multiply with this - */ - BigInt& operator*=(const BigInt& y); - - /** - * /= operator - * @param y the BigInt to divide this by - */ - BigInt& operator/=(const BigInt& y); - - /** - * Modulo operator - * @param y the modulus to reduce this by - */ - BigInt& operator%=(const BigInt& y); - - /** - * Modulo operator - * @param y the modulus (word) to reduce this by - */ - word operator%=(word y); - - /** - * Left shift operator - * @param shift the number of bits to shift this left by - */ - BigInt& operator<<=(size_t shift); - - /** - * Right shift operator - * @param shift the number of bits to shift this right by - */ - BigInt& operator>>=(size_t shift); - - /** - * Increment operator - */ - BigInt& operator++() { return (*this += 1); } - - /** - * Decrement operator - */ - BigInt& operator--() { return (*this -= 1); } - - /** - * Postfix increment operator - */ - BigInt operator++(int) { BigInt x = (*this); ++(*this); return x; } - - /** - * Postfix decrement operator - */ - BigInt operator--(int) { BigInt x = (*this); --(*this); return x; } - - /** - * Unary negation operator - * @return negative this - */ - BigInt operator-() const; - - /** - * ! operator - * @return true iff this is zero, otherwise false - */ - bool operator !() const { return (!is_nonzero()); } - - /** - * [] operator (array access) - * @param i a word index - * @return the word at index i - */ - word& operator[](size_t i) { return reg[i]; } - - /** - * [] operator (array access) - * @param i a word index - * @return the word at index i - */ - const word& operator[](size_t i) const { return reg[i]; } - - /** - * Zeroize the BigInt - */ - void clear() { zeroise(reg); } - - /** - * Compare this to another BigInt - * @param n the BigInt value to compare with - * @param check_signs include sign in comparison? - * @result if (this<n) return -1, if (this>n) return 1, if both - * values are identical return 0 [like Perl's <=> operator] - */ - s32bit cmp(const BigInt& n, bool check_signs = true) const; - - /** - * Test if the integer has an even value - * @result true if the integer is even, false otherwise - */ - bool is_even() const { return (get_bit(0) == 0); } - - /** - * Test if the integer has an odd value - * @result true if the integer is odd, false otherwise - */ - bool is_odd() const { return (get_bit(0) == 1); } - - /** - * Test if the integer is not zero - * @result true if the integer is non-zero, false otherwise - */ - bool is_nonzero() const { return (!is_zero()); } - - /** - * Test if the integer is zero - * @result true if the integer is zero, false otherwise - */ - bool is_zero() const - { - const size_t sw = sig_words(); - - for(size_t i = 0; i != sw; ++i) - if(reg[i]) - return false; - return true; - } - - /** - * Set bit at specified position - * @param n bit position to set - */ - void set_bit(size_t n); - - /** - * Clear bit at specified position - * @param n bit position to clear - */ - void clear_bit(size_t n); - - /** - * Clear all but the lowest n bits - * @param n amount of bits to keep - */ - void mask_bits(size_t n); - - /** - * Return bit value at specified position - * @param n the bit offset to test - * @result true, if the bit at position n is set, false otherwise - */ - bool get_bit(size_t n) const; - - /** - * Return (a maximum of) 32 bits of the complete value - * @param offset the offset to start extracting - * @param length amount of bits to extract (starting at offset) - * @result the integer extracted from the register starting at - * offset with specified length - */ - u32bit get_substring(size_t offset, size_t length) const; - - /** - * Convert this value into a u32bit, if it is in the range - * [0 ... 2**32-1], or otherwise throw an exception. - * @result the value as a u32bit if conversion is possible - */ - u32bit to_u32bit() const; - - /** - * @param n the offset to get a byte from - * @result byte at offset n - */ - byte byte_at(size_t n) const; - - /** - * Return the word at a specified position of the internal register - * @param n position in the register - * @return value at position n - */ - word word_at(size_t n) const - { return ((n < size()) ? reg[n] : 0); } - - /** - * Tests if the sign of the integer is negative - * @result true, iff the integer has a negative sign - */ - bool is_negative() const { return (sign() == Negative); } - - /** - * Tests if the sign of the integer is positive - * @result true, iff the integer has a positive sign - */ - bool is_positive() const { return (sign() == Positive); } - - /** - * Return the sign of the integer - * @result the sign of the integer - */ - Sign sign() const { return (signedness); } - - /** - * @result the opposite sign of the represented integer value - */ - Sign reverse_sign() const; - - /** - * Flip the sign of this BigInt - */ - void flip_sign(); - - /** - * Set sign of the integer - * @param sign new Sign to set - */ - void set_sign(Sign sign); - - /** - * @result absolute (positive) value of this - */ - BigInt abs() const; - - /** - * Give size of internal register - * @result size of internal register in words - */ - size_t size() const { return get_reg().size(); } - - /** - * Return how many words we need to hold this value - * @result significant words of the represented integer value - */ - size_t sig_words() const - { - const word* x = ®[0]; - size_t sig = reg.size(); - - while(sig && (x[sig-1] == 0)) - sig--; - return sig; - } - - /** - * Give byte length of the integer - * @result byte length of the represented integer value - */ - size_t bytes() const; - - /** - * Get the bit length of the integer - * @result bit length of the represented integer value - */ - size_t bits() const; - - /** - * Return a pointer to the big integer word register - * @result a pointer to the start of the internal register of - * the integer value - */ - const word* data() const { return ®[0]; } - - /** - * return a reference to the internal register containing the value - * @result a reference to the word-array (SecureVector<word>) - * with the internal register value (containing the integer - * value) - */ - SecureVector<word>& get_reg() { return reg; } - - /** - * return a const reference to the internal register containing the value - * @result a const reference to the word-array (SecureVector<word>) - * with the internal register value (containing the integer value) - */ - const SecureVector<word>& get_reg() const { return reg; } - - /** - * Assign using a plain word array - */ - void assign(const word x[], size_t length) - { - reg.resize(length); - copy_mem(®[0], x, length); - } - - /** - * Increase internal register buffer by n words - * @param n increase by n words - */ - void grow_reg(size_t n); - - void grow_to(size_t n); - - /** - * Fill BigInt with a random number with size of bitsize - * @param rng the random number generator to use - * @param bitsize number of bits the created random value should have - */ - void randomize(RandomNumberGenerator& rng, size_t bitsize = 0); - - /** - * Store BigInt-value in a given byte array - * @param buf destination byte array for the integer value - */ - void binary_encode(byte buf[]) const; - - /** - * Read integer value from a byte array with given size - * @param buf byte array buffer containing the integer - * @param length size of buf - */ - void binary_decode(const byte buf[], size_t length); - - /** - * Read integer value from a byte array (MemoryRegion<byte>) - * @param buf the array to load from - */ - void binary_decode(const MemoryRegion<byte>& buf); - - /** - * @param base the base to measure the size for - * @return size of this integer in base base - */ - size_t encoded_size(Base base = Binary) const; - - /** - * @param rng a random number generator - * @param min the minimum value - * @param max the maximum value - * @return random integer between min and max - */ - static BigInt random_integer(RandomNumberGenerator& rng, - const BigInt& min, - const BigInt& max); - - /** - * Encode the integer value from a BigInt to a SecureVector of bytes - * @param n the BigInt to use as integer source - * @param base number-base of resulting byte array representation - * @result SecureVector of bytes containing the integer with given base - */ - static SecureVector<byte> encode(const BigInt& n, Base base = Binary); - - /** - * Encode the integer value from a BigInt to a byte array - * @param buf destination byte array for the encoded integer - * value with given base - * @param n the BigInt to use as integer source - * @param base number-base of resulting byte array representation - */ - static void encode(byte buf[], const BigInt& n, Base base = Binary); - - /** - * Create a BigInt from an integer in a byte array - * @param buf the binary value to load - * @param length size of buf - * @param base number-base of the integer in buf - * @result BigInt representing the integer in the byte array - */ - static BigInt decode(const byte buf[], size_t length, - Base base = Binary); - - /** - * Create a BigInt from an integer in a byte array - * @param buf the binary value to load - * @param base number-base of the integer in buf - * @result BigInt representing the integer in the byte array - */ - static BigInt decode(const MemoryRegion<byte>& buf, - Base base = Binary); - - /** - * Encode a BigInt to a byte array according to IEEE 1363 - * @param n the BigInt to encode - * @param bytes the length of the resulting SecureVector<byte> - * @result a SecureVector<byte> containing the encoded BigInt - */ - static SecureVector<byte> encode_1363(const BigInt& n, size_t bytes); - - /** - * Swap this value with another - * @param other BigInt to swap values with - */ - void swap(BigInt& other); - - /** - * Create empty BigInt - */ - BigInt() { signedness = Positive; } - - /** - * Create BigInt from 64 bit integer - * @param n initial value of this BigInt - */ - BigInt(u64bit n); - - /** - * Copy Constructor - * @param other the BigInt to copy - */ - BigInt(const BigInt& other); - - /** - * Create BigInt from a string. If the string starts with 0x the - * rest of the string will be interpreted as hexadecimal digits. - * If the string starts with 0 and the second character is NOT an - * 'x' the string will be interpreted as octal digits. If the - * string starts with non-zero digit, it will be interpreted as a - * decimal number. - * - * @param str the string to parse for an integer value - */ - BigInt(const std::string& str); - - /** - * Create a BigInt from an integer in a byte array - * @param buf the byte array holding the value - * @param length size of buf - * @param base is the number base of the integer in buf - */ - BigInt(const byte buf[], size_t length, Base base = Binary); - - /** - * Create a random BigInt of the specified size - * @param rng random number generator - * @param bits size in bits - */ - BigInt(RandomNumberGenerator& rng, size_t bits); - - /** - * Create BigInt of specified size, all zeros - * @param sign the sign - * @param n size of the internal register in words - */ - BigInt(Sign sign, size_t n); - - /** - * Create a number of the specified type and size - * @param type the type of number to create. For Power2, - * will create the integer 2^n - * @param n a size/length parameter, interpretation depends upon - * the value of type - */ - BigInt(NumberType type, size_t n); - - private: - SecureVector<word> reg; - Sign signedness; - }; - -/* -* Arithmetic Operators -*/ -BigInt BOTAN_DLL operator+(const BigInt& x, const BigInt& y); -BigInt BOTAN_DLL operator-(const BigInt& x, const BigInt& y); -BigInt BOTAN_DLL operator*(const BigInt& x, const BigInt& y); -BigInt BOTAN_DLL operator/(const BigInt& x, const BigInt& d); -BigInt BOTAN_DLL operator%(const BigInt& x, const BigInt& m); -word BOTAN_DLL operator%(const BigInt& x, word m); -BigInt BOTAN_DLL operator<<(const BigInt& x, size_t n); -BigInt BOTAN_DLL operator>>(const BigInt& x, size_t n); - -/* -* Comparison Operators -*/ -inline bool operator==(const BigInt& a, const BigInt& b) - { return (a.cmp(b) == 0); } -inline bool operator!=(const BigInt& a, const BigInt& b) - { return (a.cmp(b) != 0); } -inline bool operator<=(const BigInt& a, const BigInt& b) - { return (a.cmp(b) <= 0); } -inline bool operator>=(const BigInt& a, const BigInt& b) - { return (a.cmp(b) >= 0); } -inline bool operator<(const BigInt& a, const BigInt& b) - { return (a.cmp(b) < 0); } -inline bool operator>(const BigInt& a, const BigInt& b) - { return (a.cmp(b) > 0); } - -/* -* I/O Operators -*/ -BOTAN_DLL std::ostream& operator<<(std::ostream&, const BigInt&); -BOTAN_DLL std::istream& operator>>(std::istream&, BigInt&); - -} - -namespace std { - -template<> -inline void swap(Botan::BigInt& x, Botan::BigInt& y) - { - x.swap(y); - } - -} - - -namespace Botan { - -/** -* Modular Exponentiator Interface -*/ -class BOTAN_DLL Modular_Exponentiator - { - public: - virtual void set_base(const BigInt&) = 0; - virtual void set_exponent(const BigInt&) = 0; - virtual BigInt execute() const = 0; - virtual Modular_Exponentiator* copy() const = 0; - virtual ~Modular_Exponentiator() {} - }; - -/** -* Modular Exponentiator Proxy -*/ -class BOTAN_DLL Power_Mod - { - public: - - enum Usage_Hints { - NO_HINTS = 0x0000, - - BASE_IS_FIXED = 0x0001, - BASE_IS_SMALL = 0x0002, - BASE_IS_LARGE = 0x0004, - BASE_IS_2 = 0x0008, - - EXP_IS_FIXED = 0x0100, - EXP_IS_SMALL = 0x0200, - EXP_IS_LARGE = 0x0400 - }; - - /* - * Try to choose a good window size - */ - static size_t window_bits(size_t exp_bits, size_t base_bits, - Power_Mod::Usage_Hints hints); - - void set_modulus(const BigInt&, Usage_Hints = NO_HINTS) const; - void set_base(const BigInt&) const; - void set_exponent(const BigInt&) const; - - BigInt execute() const; - - Power_Mod& operator=(const Power_Mod&); - - Power_Mod(const BigInt& = 0, Usage_Hints = NO_HINTS); - Power_Mod(const Power_Mod&); - virtual ~Power_Mod(); - private: - mutable Modular_Exponentiator* core; - Usage_Hints hints; - }; - -/** -* Fixed Exponent Modular Exponentiator Proxy -*/ -class BOTAN_DLL Fixed_Exponent_Power_Mod : public Power_Mod - { - public: - BigInt operator()(const BigInt& b) const - { set_base(b); return execute(); } - - Fixed_Exponent_Power_Mod() {} - Fixed_Exponent_Power_Mod(const BigInt&, const BigInt&, - Usage_Hints = NO_HINTS); - }; - -/** -* Fixed Base Modular Exponentiator Proxy -*/ -class BOTAN_DLL Fixed_Base_Power_Mod : public Power_Mod - { - public: - BigInt operator()(const BigInt& e) const - { set_exponent(e); return execute(); } - - Fixed_Base_Power_Mod() {} - Fixed_Base_Power_Mod(const BigInt&, const BigInt&, - Usage_Hints = NO_HINTS); - }; - -} - - -namespace Botan { - -/** -* ASN.1 Type and Class Tags -*/ -enum ASN1_Tag { - UNIVERSAL = 0x00, - APPLICATION = 0x40, - CONTEXT_SPECIFIC = 0x80, - PRIVATE = 0xC0, - - CONSTRUCTED = 0x20, - - EOC = 0x00, - BOOLEAN = 0x01, - INTEGER = 0x02, - BIT_STRING = 0x03, - OCTET_STRING = 0x04, - NULL_TAG = 0x05, - OBJECT_ID = 0x06, - ENUMERATED = 0x0A, - SEQUENCE = 0x10, - SET = 0x11, - - UTF8_STRING = 0x0C, - NUMERIC_STRING = 0x12, - PRINTABLE_STRING = 0x13, - T61_STRING = 0x14, - IA5_STRING = 0x16, - VISIBLE_STRING = 0x1A, - BMP_STRING = 0x1E, - - UTC_TIME = 0x17, - GENERALIZED_TIME = 0x18, - - NO_OBJECT = 0xFF00, - DIRECTORY_STRING = 0xFF01 -}; - -/** -* Basic ASN.1 Object Interface -*/ -class BOTAN_DLL ASN1_Object - { - public: - /** - * Encode whatever this object is into to - * @param to the DER_Encoder that will be written to - */ - virtual void encode_into(class DER_Encoder& to) const = 0; - - /** - * Decode whatever this object is from from - * @param from the BER_Decoder that will be read from - */ - virtual void decode_from(class BER_Decoder& from) = 0; - - virtual ~ASN1_Object() {} - }; - -/** -* BER Encoded Object -*/ -class BOTAN_DLL BER_Object - { - public: - void assert_is_a(ASN1_Tag, ASN1_Tag); - - ASN1_Tag type_tag, class_tag; - SecureVector<byte> value; - }; - -/* -* ASN.1 Utility Functions -*/ -class DataSource; - -namespace ASN1 { - -SecureVector<byte> put_in_sequence(const MemoryRegion<byte>& val); -std::string to_string(const BER_Object& obj); - -/** -* Heuristics tests; is this object possibly BER? -* @param src a data source that will be peeked at but not modified -*/ -bool maybe_BER(DataSource& src); - -} - -/** -* General BER Decoding Error Exception -*/ -struct BOTAN_DLL BER_Decoding_Error : public Decoding_Error - { - BER_Decoding_Error(const std::string&); - }; - -/** -* Exception For Incorrect BER Taggings -*/ -struct BOTAN_DLL BER_Bad_Tag : public BER_Decoding_Error - { - BER_Bad_Tag(const std::string& msg, ASN1_Tag tag); - BER_Bad_Tag(const std::string& msg, ASN1_Tag tag1, ASN1_Tag tag2); - }; - -} - - -namespace Botan { - -/** -* This class represents ASN.1 object identifiers. -*/ -class BOTAN_DLL OID : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - /** - * Find out whether this OID is empty - * @return true is no OID value is set - */ - bool is_empty() const { return id.size() == 0; } - - /** - * Get this OID as list (vector) of its components. - * @return vector representing this OID - */ - std::vector<u32bit> get_id() const { return id; } - - /** - * Get this OID as a string - * @return string representing this OID - */ - std::string as_string() const; - - /** - * Compare two OIDs. - * @return true if they are equal, false otherwise - */ - bool operator==(const OID&) const; - - /** - * Reset this instance to an empty OID. - */ - void clear(); - - /** - * Add a component to this OID. - * @param new_comp the new component to add to the end of this OID - * @return reference to *this - */ - OID& operator+=(u32bit new_comp); - - /** - * Construct an OID from a string. - * @param str a string in the form "a.b.c" etc., where a,b,c are numbers - */ - OID(const std::string& str = ""); - private: - std::vector<u32bit> id; - }; - -/** -* Append another component onto the OID. -* @param oid the OID to add the new component to -* @param new_comp the new component to add -*/ -OID operator+(const OID& oid, u32bit new_comp); - -/** -* Compare two OIDs. -* @param a the first OID -* @param b the second OID -* @return true if a is not equal to b -*/ -bool operator!=(const OID& a, const OID& b); - -/** -* Compare two OIDs. -* @param a the first OID -* @param b the second OID -* @return true if a is lexicographically smaller than b -*/ -bool operator<(const OID& a, const OID& b); - -} - - -namespace Botan { - -/** -* Algorithm Identifier -*/ -class BOTAN_DLL AlgorithmIdentifier : public ASN1_Object - { - public: - enum Encoding_Option { USE_NULL_PARAM }; - - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - AlgorithmIdentifier() {} - AlgorithmIdentifier(const OID&, Encoding_Option); - AlgorithmIdentifier(const std::string&, Encoding_Option); - - AlgorithmIdentifier(const OID&, const MemoryRegion<byte>&); - AlgorithmIdentifier(const std::string&, const MemoryRegion<byte>&); - - OID oid; - SecureVector<byte> parameters; - }; - -/* -* Comparison Operations -*/ -bool BOTAN_DLL operator==(const AlgorithmIdentifier&, - const AlgorithmIdentifier&); -bool BOTAN_DLL operator!=(const AlgorithmIdentifier&, - const AlgorithmIdentifier&); - -} - - -namespace Botan { - -/** -* Public Key Base Class. -*/ -class BOTAN_DLL Public_Key - { - public: - /** - * Get the name of the underlying public key scheme. - * @return name of the public key scheme - */ - virtual std::string algo_name() const = 0; - - /** - * Get the OID of the underlying public key scheme. - * @return OID of the public key scheme - */ - virtual OID get_oid() const; - - /** - * Test the key values for consistency. - * @param rng rng to use - * @param strong whether to perform strong and lengthy version - * of the test - * @return true if the test is passed - */ - virtual bool check_key(RandomNumberGenerator& rng, - bool strong) const = 0; - - /** - * Find out the number of message parts supported by this scheme. - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return size of the message parts in bits - */ - virtual size_t message_part_size() const { return 0; } - - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message size in bits - */ - virtual size_t max_input_bits() const = 0; - - /** - * @return X.509 AlgorithmIdentifier for this key - */ - virtual AlgorithmIdentifier algorithm_identifier() const = 0; - - /** - * @return X.509 subject key encoding for this key object - */ - virtual MemoryVector<byte> x509_subject_public_key() const = 0; - - virtual ~Public_Key() {} - protected: - /** - * Self-test after loading a key - * @param rng a random number generator - */ - virtual void load_check(RandomNumberGenerator& rng) const; - }; - -/** -* Private Key Base Class -*/ -class BOTAN_DLL Private_Key : public virtual Public_Key - { - public: - /** - * @return PKCS #8 private key encoding for this key object - */ - virtual MemoryVector<byte> pkcs8_private_key() const = 0; - - /** - * @return PKCS #8 AlgorithmIdentifier for this key - * Might be different from the X.509 identifier, but normally is not - */ - virtual AlgorithmIdentifier pkcs8_algorithm_identifier() const - { return algorithm_identifier(); } - - protected: - /** - * Self-test after loading a key - * @param rng a random number generator - */ - void load_check(RandomNumberGenerator& rng) const; - - /** - * Self-test after generating a key - * @param rng a random number generator - */ - void gen_check(RandomNumberGenerator& rng) const; - }; - -/** -* PK Secret Value Derivation Key -*/ -class BOTAN_DLL PK_Key_Agreement_Key : public virtual Private_Key - { - public: - /* - * @return public component of this key - */ - virtual MemoryVector<byte> public_value() const = 0; - - virtual ~PK_Key_Agreement_Key() {} - }; - -/* -* Typedefs -*/ -typedef PK_Key_Agreement_Key PK_KA_Key; -typedef Public_Key X509_PublicKey; -typedef Private_Key PKCS8_PrivateKey; - -} - - -namespace Botan { - -namespace PK_Ops { - -/** -* Public key encryption interface -*/ -class BOTAN_DLL Encryption - { - public: - virtual size_t max_input_bits() const = 0; - - virtual SecureVector<byte> encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) = 0; - - virtual ~Encryption() {} - }; - -/** -* Public key decryption interface -*/ -class BOTAN_DLL Decryption - { - public: - virtual size_t max_input_bits() const = 0; - - virtual SecureVector<byte> decrypt(const byte msg[], - size_t msg_len) = 0; - - virtual ~Decryption() {} - }; - -/** -* Public key signature creation interface -*/ -class BOTAN_DLL Signature - { - public: - /** - * Find out the number of message parts supported by this scheme. - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return size of the message parts - */ - virtual size_t message_part_size() const { return 0; } - - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message in bits - */ - virtual size_t max_input_bits() const = 0; - - /* - * Perform a signature operation - * @param msg the message - * @param msg_len the length of msg in bytes - * @param rng a random number generator - */ - virtual SecureVector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) = 0; - - virtual ~Signature() {} - }; - -/** -* Public key signature verification interface -*/ -class BOTAN_DLL Verification - { - public: - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message in bits - */ - virtual size_t max_input_bits() const = 0; - - /** - * Find out the number of message parts supported by this scheme. - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return size of the message parts - */ - virtual size_t message_part_size() const { return 0; } - - /** - * @return boolean specifying if this key type supports message - * recovery and thus if you need to call verify() or verify_mr() - */ - virtual bool with_recovery() const = 0; - - /* - * Perform a signature check operation - * @param msg the message - * @param msg_len the length of msg in bytes - * @param sig the signature - * @param sig_len the length of sig in bytes - * @returns if signature is a valid one for message - */ - virtual bool verify(const byte[], size_t, - const byte[], size_t) - { - throw Invalid_State("Message recovery required"); - } - - /* - * Perform a signature operation (with message recovery) - * Only call this if with_recovery() returns true - * @param msg the message - * @param msg_len the length of msg in bytes - * @returns recovered message - */ - virtual SecureVector<byte> verify_mr(const byte[], - size_t) - { - throw Invalid_State("Message recovery not supported"); - } - - virtual ~Verification() {} - }; - -/** -* A generic key agreement Operation (eg DH or ECDH) -*/ -class BOTAN_DLL Key_Agreement - { - public: - /* - * Perform a key agreement operation - * @param w the other key value - * @param w_len the length of w in bytes - * @returns the agreed key - */ - virtual SecureVector<byte> agree(const byte w[], size_t w_len) = 0; - - virtual ~Key_Agreement() {} - }; - -} - -} - - -namespace Botan { - -class Algorithm_Factory; -class Keyed_Filter; - -/** -* Base class for all engines. All non-pure virtual functions simply -* return NULL, indicating the algorithm in question is not -* supported. Subclasses can reimplement whichever function(s) -* they want to hook in a particular type. -*/ -class BOTAN_DLL Engine - { - public: - virtual ~Engine() {} - - /** - * @return name of this engine - */ - virtual std::string provider_name() const = 0; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual BlockCipher* - find_block_cipher(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual StreamCipher* - find_stream_cipher(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual HashFunction* - find_hash(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual MessageAuthenticationCode* - find_mac(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual PBKDF* find_pbkdf(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param n the modulus - * @param hints any use hints - * @return newly allocated object, or NULL - */ - virtual Modular_Exponentiator* - mod_exp(const BigInt& n, - Power_Mod::Usage_Hints hints) const; - - /** - * Return a new cipher object - * @param algo_spec the algorithm name/specification - * @param dir specifies if encryption or decryption is desired - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual Keyed_Filter* get_cipher(const std::string& algo_spec, - Cipher_Dir dir, - Algorithm_Factory& af); - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Key_Agreement* - get_key_agreement_op(const Private_Key& key) const; - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Signature* - get_signature_op(const Private_Key& key) const; - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Verification* - get_verify_op(const Public_Key& key) const; - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Encryption* - get_encryption_op(const Public_Key& key) const; - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Decryption* - get_decryption_op(const Private_Key& key) const; - }; - -} - - -namespace Botan { - -/** -* Dynamically_Loaded_Engine just proxies the requests to the underlying -* Engine object, and handles load/unload details -*/ -class BOTAN_DLL Dynamically_Loaded_Engine : public Engine - { - public: - /** - * @param lib_path full pathname to DLL to load - */ - Dynamically_Loaded_Engine(const std::string& lib_path); - - ~Dynamically_Loaded_Engine(); - - std::string provider_name() const { return engine->provider_name(); } - - BlockCipher* find_block_cipher(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_block_cipher(algo_spec, af); - } - - StreamCipher* find_stream_cipher(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_stream_cipher(algo_spec, af); - } - - HashFunction* find_hash(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_hash(algo_spec, af); - } - - MessageAuthenticationCode* find_mac(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_mac(algo_spec, af); - } - - PBKDF* find_pbkdf(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_pbkdf(algo_spec, af); - } - - Modular_Exponentiator* mod_exp(const BigInt& n, - Power_Mod::Usage_Hints hints) const - { - return engine->mod_exp(n, hints); - } - - Keyed_Filter* get_cipher(const std::string& algo_spec, - Cipher_Dir dir, - Algorithm_Factory& af) - { - return engine->get_cipher(algo_spec, dir, af); - } - - PK_Ops::Key_Agreement* - get_key_agreement_op(const Private_Key& key) const - { - return engine->get_key_agreement_op(key); - } - - PK_Ops::Signature* - get_signature_op(const Private_Key& key) const - { - return engine->get_signature_op(key); - } - - PK_Ops::Verification* - get_verify_op(const Public_Key& key) const - { - return engine->get_verify_op(key); - } - - PK_Ops::Encryption* - get_encryption_op(const Public_Key& key) const - { - return engine->get_encryption_op(key); - } - - PK_Ops::Decryption* - get_decryption_op(const Private_Key& key) const - { - return engine->get_decryption_op(key); - } - - private: - class Dynamically_Loaded_Library* lib; - Engine* engine; - }; - -} - - -namespace Botan { - -/** -* Simple String -*/ -class BOTAN_DLL ASN1_String : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - std::string value() const; - std::string iso_8859() const; - - ASN1_Tag tagging() const; - - ASN1_String(const std::string& = ""); - ASN1_String(const std::string&, ASN1_Tag); - private: - std::string iso_8859_str; - ASN1_Tag tag; - }; - -} - - -namespace Botan { - -/** -* Attribute -*/ -class BOTAN_DLL Attribute : public ASN1_Object - { - public: - void encode_into(class DER_Encoder& to) const; - void decode_from(class BER_Decoder& from); - - OID oid; - MemoryVector<byte> parameters; - - Attribute() {} - Attribute(const OID&, const MemoryRegion<byte>&); - Attribute(const std::string&, const MemoryRegion<byte>&); - }; - -/** -* X.509 Time -*/ -class BOTAN_DLL X509_Time : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - std::string as_string() const; - std::string readable_string() const; - bool time_is_set() const; - - s32bit cmp(const X509_Time&) const; - - void set_to(const std::string&); - void set_to(const std::string&, ASN1_Tag); - - X509_Time(u64bit); - X509_Time(const std::string& = ""); - X509_Time(const std::string&, ASN1_Tag); - private: - bool passes_sanity_check() const; - u32bit year, month, day, hour, minute, second; - ASN1_Tag tag; - }; - -/** -* Alternative Name -*/ -class BOTAN_DLL AlternativeName : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - std::multimap<std::string, std::string> contents() const; - - void add_attribute(const std::string&, const std::string&); - std::multimap<std::string, std::string> get_attributes() const; - - void add_othername(const OID&, const std::string&, ASN1_Tag); - std::multimap<OID, ASN1_String> get_othernames() const; - - bool has_items() const; - - AlternativeName(const std::string& = "", const std::string& = "", - const std::string& = "", const std::string& = ""); - private: - std::multimap<std::string, std::string> alt_info; - std::multimap<OID, ASN1_String> othernames; - }; - -/* -* Comparison Operations -*/ -bool BOTAN_DLL operator==(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator!=(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator<=(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator>=(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator<(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator>(const X509_Time&, const X509_Time&); - -} - - -namespace Botan { - -/** -* This class represents an abstract data source object. -*/ -class BOTAN_DLL DataSource - { - public: - /** - * Read from the source. Moves the internal offset so that every - * call to read will return a new portion of the source. - * - * @param out the byte array to write the result to - * @param length the length of the byte array out - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t read(byte out[], size_t length) = 0; - - /** - * Read from the source but do not modify the internal - * offset. Consecutive calls to peek() will return portions of - * the source starting at the same position. - * - * @param out the byte array to write the output to - * @param length the length of the byte array out - * @param peek_offset the offset into the stream to read at - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t peek(byte out[], size_t length, - size_t peek_offset) const = 0; - - /** - * Test whether the source still has data that can be read. - * @return true if there is still data to read, false otherwise - */ - virtual bool end_of_data() const = 0; - /** - * return the id of this data source - * @return std::string representing the id of this data source - */ - virtual std::string id() const { return ""; } - - /** - * Read one byte. - * @param out the byte to read to - * @return length in bytes that was actually read and put - * into out - */ - size_t read_byte(byte& out); - - /** - * Peek at one byte. - * @param out an output byte - * @return length in bytes that was actually read and put - * into out - */ - size_t peek_byte(byte& out) const; - - /** - * Discard the next N bytes of the data - * @param N the number of bytes to discard - * @return number of bytes actually discarded - */ - size_t discard_next(size_t N); - - DataSource() {} - virtual ~DataSource() {} - private: - DataSource& operator=(const DataSource&) { return (*this); } - DataSource(const DataSource&); - }; - -/** -* This class represents a Memory-Based DataSource -*/ -class BOTAN_DLL DataSource_Memory : public DataSource - { - public: - size_t read(byte[], size_t); - size_t peek(byte[], size_t, size_t) const; - bool end_of_data() const; - - /** - * Construct a memory source that reads from a string - * @param in the string to read from - */ - DataSource_Memory(const std::string& in); - - /** - * Construct a memory source that reads from a byte array - * @param in the byte array to read from - * @param length the length of the byte array - */ - DataSource_Memory(const byte in[], size_t length); - - /** - * Construct a memory source that reads from a MemoryRegion - * @param in the MemoryRegion to read from - */ - DataSource_Memory(const MemoryRegion<byte>& in); - private: - SecureVector<byte> source; - size_t offset; - }; - -/** -* This class represents a Stream-Based DataSource. -*/ -class BOTAN_DLL DataSource_Stream : public DataSource - { - public: - size_t read(byte[], size_t); - size_t peek(byte[], size_t, size_t) const; - bool end_of_data() const; - std::string id() const; - - DataSource_Stream(std::istream&, - const std::string& id = "<std::istream>"); - - /** - * Construct a Stream-Based DataSource from file - * @param file the name of the file - * @param use_binary whether to treat the file as binary or not - */ - DataSource_Stream(const std::string& file, bool use_binary = false); - - ~DataSource_Stream(); - private: - const std::string identifier; - - std::istream* source_p; - std::istream& source; - size_t total_read; - }; - -} - - -namespace Botan { - -/** -* This class represents general abstract filter objects. -*/ -class BOTAN_DLL Filter - { - public: - /** - * @return descriptive name for this filter - */ - virtual std::string name() const = 0; - - /** - * Write a portion of a message to this filter. - * @param input the input as a byte array - * @param length the length of the byte array input - */ - virtual void write(const byte input[], size_t length) = 0; - - /** - * Start a new message. Must be closed by end_msg() before another - * message can be started. - */ - virtual void start_msg() {} - - /** - * Notify that the current message is finished; flush buffers and - * do end-of-message processing (if any). - */ - virtual void end_msg() {} - - /** - * Check whether this filter is an attachable filter. - * @return true if this filter is attachable, false otherwise - */ - virtual bool attachable() { return true; } - - virtual ~Filter() {} - protected: - /** - * @param in some input for the filter - * @param length the length of in - */ - void send(const byte in[], size_t length); - - /** - * @param in some input for the filter - */ - void send(byte in) { send(&in, 1); } - - /** - * @param in some input for the filter - */ - void send(const MemoryRegion<byte>& in) { send(&in[0], in.size()); } - - /** - * @param in some input for the filter - * @param length the number of bytes of in to send - */ - void send(const MemoryRegion<byte>& in, size_t length) - { - send(&in[0], length); - } - - Filter(); - private: - Filter(const Filter&) {} - Filter& operator=(const Filter&) { return (*this); } - - /** - * Start a new message in *this and all following filters. Only for - * internal use, not intended for use in client applications. - */ - void new_msg(); - - /** - * End a new message in *this and all following filters. Only for - * internal use, not intended for use in client applications. - */ - void finish_msg(); - - friend class Pipe; - friend class Fanout_Filter; - - size_t total_ports() const; - size_t current_port() const { return port_num; } - - /** - * Set the active port - * @param new_port the new value - */ - void set_port(size_t new_port); - - size_t owns() const { return filter_owns; } - - /** - * Attach another filter to this one - * @param f filter to attach - */ - void attach(Filter* f); - - /** - * @param filters the filters to set - * @param count number of items in filters - */ - void set_next(Filter* filters[], size_t count); - Filter* get_next() const; - - SecureVector<byte> write_queue; - std::vector<Filter*> next; - size_t port_num, filter_owns; - - // true if filter belongs to a pipe --> prohibit filter sharing! - bool owned; - }; - -/** -* This is the abstract Fanout_Filter base class. -**/ -class BOTAN_DLL Fanout_Filter : public Filter - { - protected: - /** - * Increment the number of filters past us that we own - */ - void incr_owns() { ++filter_owns; } - - void set_port(size_t n) { Filter::set_port(n); } - - void set_next(Filter* f[], size_t n) { Filter::set_next(f, n); } - - void attach(Filter* f) { Filter::attach(f); } - }; - -/** -* The type of checking to be performed by decoders: -* NONE - no checks, IGNORE_WS - perform checks, but ignore -* whitespaces, FULL_CHECK - perform checks, also complain -* about white spaces. -*/ -enum Decoder_Checking { NONE, IGNORE_WS, FULL_CHECK }; - -} - - -namespace Botan { - -/** -* This class represents pipe objects. -* A set of filters can be placed into a pipe, and information flows -* through the pipe until it reaches the end, where the output is -* collected for retrieval. If you're familiar with the Unix shell -* environment, this design will sound quite familiar. -*/ -class BOTAN_DLL Pipe : public DataSource - { - public: - /** - * An opaque type that identifies a message in this Pipe - */ - typedef size_t message_id; - - /** - * Exception if you use an invalid message as an argument to - * read, remaining, etc - */ - struct BOTAN_DLL Invalid_Message_Number : public Invalid_Argument - { - /** - * @param where the error occured - * @param msg the invalid message id that was used - */ - Invalid_Message_Number(const std::string& where, message_id msg) : - Invalid_Argument("Pipe::" + where + ": Invalid message number " + - to_string(msg)) - {} - }; - - /** - * A meta-id for whatever the last message is - */ - static const message_id LAST_MESSAGE; - - /** - * A meta-id for the default message (set with set_default_msg) - */ - static const message_id DEFAULT_MESSAGE; - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the byte array to write - * @param length the length of the byte array in - */ - void write(const byte in[], size_t length); - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the MemoryRegion containing the data to write - */ - void write(const MemoryRegion<byte>& in); - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the string containing the data to write - */ - void write(const std::string& in); - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the DataSource to read the data from - */ - void write(DataSource& in); - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in a single byte to be written - */ - void write(byte in); - - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the byte array containing the data to write - * @param length the length of the byte array to write - */ - void process_msg(const byte in[], size_t length); - - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the MemoryRegion containing the data to write - */ - void process_msg(const MemoryRegion<byte>& in); - - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the string containing the data to write - */ - void process_msg(const std::string& in); - - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the DataSource providing the data to write - */ - void process_msg(DataSource& in); - - /** - * Find out how many bytes are ready to read. - * @param msg the number identifying the message - * for which the information is desired - * @return number of bytes that can still be read - */ - size_t remaining(message_id msg = DEFAULT_MESSAGE) const; - - /** - * Read the default message from the pipe. Moves the internal - * offset so that every call to read will return a new portion of - * the message. - * - * @param output the byte array to write the read bytes to - * @param length the length of the byte array output - * @return number of bytes actually read into output - */ - size_t read(byte output[], size_t length); - - /** - * Read a specified message from the pipe. Moves the internal - * offset so that every call to read will return a new portion of - * the message. - * @param output the byte array to write the read bytes to - * @param length the length of the byte array output - * @param msg the number identifying the message to read from - * @return number of bytes actually read into output - */ - size_t read(byte output[], size_t length, message_id msg); - - /** - * Read a single byte from the pipe. Moves the internal offset so - * that every call to read will return a new portion of the - * message. - * - * @param output the byte to write the result to - * @param msg the message to read from - * @return number of bytes actually read into output - */ - size_t read(byte& output, message_id msg = DEFAULT_MESSAGE); - - /** - * Read the full contents of the pipe. - * @param msg the number identifying the message to read from - * @return SecureVector holding the contents of the pipe - */ - SecureVector<byte> read_all(message_id msg = DEFAULT_MESSAGE); - - /** - * Read the full contents of the pipe. - * @param msg the number identifying the message to read from - * @return string holding the contents of the pipe - */ - std::string read_all_as_string(message_id = DEFAULT_MESSAGE); - - /** Read from the default message but do not modify the internal - * offset. Consecutive calls to peek() will return portions of - * the message starting at the same position. - * @param output the byte array to write the peeked message part to - * @param length the length of the byte array output - * @param offset the offset from the current position in message - * @return number of bytes actually peeked and written into output - */ - size_t peek(byte output[], size_t length, size_t offset) const; - - /** Read from the specified message but do not modify the - * internal offset. Consecutive calls to peek() will return - * portions of the message starting at the same position. - * @param output the byte array to write the peeked message part to - * @param length the length of the byte array output - * @param offset the offset from the current position in message - * @param msg the number identifying the message to peek from - * @return number of bytes actually peeked and written into output - */ - size_t peek(byte output[], size_t length, - size_t offset, message_id msg) const; - - /** Read a single byte from the specified message but do not - * modify the internal offset. Consecutive calls to peek() will - * return portions of the message starting at the same position. - * @param output the byte to write the peeked message byte to - * @param offset the offset from the current position in message - * @param msg the number identifying the message to peek from - * @return number of bytes actually peeked and written into output - */ - size_t peek(byte& output, size_t offset, - message_id msg = DEFAULT_MESSAGE) const; - - /** - * @return currently set default message - */ - size_t default_msg() const { return default_read; } - - /** - * Set the default message - * @param msg the number identifying the message which is going to - * be the new default message - */ - void set_default_msg(message_id msg); - - /** - * Get the number of messages the are in this pipe. - * @return number of messages the are in this pipe - */ - message_id message_count() const; - - /** - * Test whether this pipe has any data that can be read from. - * @return true if there is more data to read, false otherwise - */ - bool end_of_data() const; - - /** - * Start a new message in the pipe. A potential other message in this pipe - * must be closed with end_msg() before this function may be called. - */ - void start_msg(); - - /** - * End the current message. - */ - void end_msg(); - - /** - * Insert a new filter at the front of the pipe - * @param filt the new filter to insert - */ - void prepend(Filter* filt); - - /** - * Insert a new filter at the back of the pipe - * @param filt the new filter to insert - */ - void append(Filter* filt); - - /** - * Remove the first filter at the front of the pipe. - */ - void pop(); - - /** - * Reset this pipe to an empty pipe. - */ - void reset(); - - /** - * Construct a Pipe of up to four filters. The filters are set up - * in the same order as the arguments. - */ - Pipe(Filter* = 0, Filter* = 0, Filter* = 0, Filter* = 0); - - /** - * Construct a Pipe from range of filters passed as an array - * @param filters the set of filters to use - * @param count the number of elements in filters - */ - Pipe(Filter* filters[], size_t count); - ~Pipe(); - private: - Pipe(const Pipe&) : DataSource() {} - Pipe& operator=(const Pipe&) { return (*this); } - void init(); - void destruct(Filter*); - void find_endpoints(Filter*); - void clear_endpoints(Filter*); - - message_id get_message_no(const std::string&, message_id) const; - - Filter* pipe; - class Output_Buffers* outputs; - message_id default_read; - bool inside_msg; - }; - -/** -* Stream output operator; dumps the results from pipe's default -* message to the output stream. -* @param out an output stream -* @param pipe the pipe -*/ -BOTAN_DLL std::ostream& operator<<(std::ostream& out, Pipe& pipe); - -/** -* Stream input operator; dumps the remaining bytes of input -* to the (assumed open) pipe message. -* @param in the input stream -* @param pipe the pipe -*/ -BOTAN_DLL std::istream& operator>>(std::istream& in, Pipe& pipe); - -} - -#if defined(BOTAN_HAS_PIPE_UNIXFD_IO) - -namespace Botan { - -/** -* Stream output operator; dumps the results from pipe's default -* message to the output stream. -* @param out file descriptor for an open output stream -* @param pipe the pipe -*/ -int BOTAN_DLL operator<<(int out, Pipe& pipe); - -/** -* File descriptor input operator; dumps the remaining bytes of input -* to the (assumed open) pipe message. -* @param in file descriptor for an open input stream -* @param pipe the pipe -*/ -int BOTAN_DLL operator>>(int in, Pipe& pipe); - -} - -#endif - - -namespace Botan { - -/** -* BER Decoding Object -*/ -class BOTAN_DLL BER_Decoder - { - public: - BER_Object get_next_object(); - void push_back(const BER_Object&); - - bool more_items() const; - BER_Decoder& verify_end(); - BER_Decoder& discard_remaining(); - - BER_Decoder start_cons(ASN1_Tag, ASN1_Tag = UNIVERSAL); - BER_Decoder& end_cons(); - - BER_Decoder& raw_bytes(MemoryRegion<byte>&); - - BER_Decoder& decode_null(); - BER_Decoder& decode(bool&); - BER_Decoder& decode(size_t&); - BER_Decoder& decode(class BigInt&); - BER_Decoder& decode(MemoryRegion<byte>&, ASN1_Tag); - - BER_Decoder& decode(bool&, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(size_t&, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(class BigInt&, - ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(MemoryRegion<byte>&, ASN1_Tag, - ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - - BER_Decoder& decode(class ASN1_Object&); - - BER_Decoder& decode_octet_string_bigint(class BigInt&); - - template<typename T> - BER_Decoder& decode_optional(T& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag, - const T& default_value = T()); - - template<typename T> - BER_Decoder& decode_list(std::vector<T>& out, - bool clear_out = true); - - template<typename T> - BER_Decoder& decode_and_check(const T& expected, - const std::string& error_msg) - { - T actual; - decode(actual); - - if(actual != expected) - throw Decoding_Error(error_msg); - - return (*this); - } - - BER_Decoder& decode_optional_string(MemoryRegion<byte>&, - ASN1_Tag, u16bit); - - BER_Decoder(DataSource&); - BER_Decoder(const byte[], size_t); - BER_Decoder(const MemoryRegion<byte>&); - BER_Decoder(const BER_Decoder&); - ~BER_Decoder(); - private: - BER_Decoder& operator=(const BER_Decoder&) { return (*this); } - - BER_Decoder* parent; - DataSource* source; - BER_Object pushed; - mutable bool owns; - }; - -/* -* Decode an OPTIONAL or DEFAULT element -*/ -template<typename T> -BER_Decoder& BER_Decoder::decode_optional(T& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag, - const T& default_value) - { - BER_Object obj = get_next_object(); - - if(obj.type_tag == type_tag && obj.class_tag == class_tag) - { - if(class_tag & CONSTRUCTED) - BER_Decoder(obj.value).decode(out).verify_end(); - else - { - push_back(obj); - decode(out, type_tag, class_tag); - } - } - else - { - out = default_value; - push_back(obj); - } - - return (*this); - } - -/* -* Decode a list of homogenously typed values -*/ -template<typename T> -BER_Decoder& BER_Decoder::decode_list(std::vector<T>& vec, bool clear_it) - { - if(clear_it) - vec.clear(); - - while(more_items()) - { - T value; - decode(value); - vec.push_back(value); - } - return (*this); - } - -} - - -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 -}; - -/** -* BER Decoding Function for key constraints -*/ -namespace BER { - -void BOTAN_DLL decode(BER_Decoder&, Key_Constraints&); - -} - -/** -* 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 -*/ - -/** -* The two types of X509 encoding supported by Botan. -*/ -enum X509_Encoding { RAW_BER, PEM }; - -} - - -namespace Botan { - -/** -* This class represents abstract X.509 signed objects as -* in the X.500 SIGNED macro -*/ -class BOTAN_DLL X509_Object - { - public: - /** - * The underlying data that is to be or was signed - * @return data that is or was signed - */ - MemoryVector<byte> tbs_data() const; - - /** - * @return signature on tbs_data() - */ - MemoryVector<byte> signature() const; - - /** - * @return signature algorithm that was used to generate signature - */ - AlgorithmIdentifier signature_algorithm() const; - - /** - * @return hash algorithm that was used to generate signature - */ - std::string hash_used_for_signature() const; - - /** - * Create a signed X509 object. - * @param signer the signer used to sign the object - * @param rng the random number generator to use - * @param alg_id the algorithm identifier of the signature scheme - * @param tbs the tbs bits to be signed - * @return signed X509 object - */ - static MemoryVector<byte> make_signed(class PK_Signer* signer, - RandomNumberGenerator& rng, - const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& tbs); - - /** - * Check the signature on this data - * @param key the public key purportedly used to sign this data - * @return true if the signature is valid, otherwise false - */ - bool check_signature(class Public_Key& key) const; - - /** - * Check the signature on this data - * @param key the public key purportedly used to sign this data - * the pointer will be deleted after use - * @return true if the signature is valid, otherwise false - */ - bool check_signature(class Public_Key* key) const; - - /** - * @return BER encoding of this - */ - MemoryVector<byte> BER_encode() const; - - /** - * @return PEM encoding of this - */ - std::string PEM_encode() const; - - /** - * Encode this to a pipe - * @deprecated use BER_encode or PEM_encode instead - * @param out the pipe to write to - * @param encoding the encoding to use - */ - BOTAN_DEPRECATED("Use BER_encode or PEM_encode") - void encode(Pipe& out, X509_Encoding encoding = PEM) const; - - virtual ~X509_Object() {} - protected: - X509_Object(DataSource& src, const std::string& pem_labels); - X509_Object(const std::string& file, const std::string& pem_labels); - - void do_decode(); - X509_Object() {} - AlgorithmIdentifier sig_algo; - MemoryVector<byte> tbs_bits, sig; - private: - virtual void force_decode() = 0; - void init(DataSource&, const std::string&); - void decode_info(DataSource&); - std::vector<std::string> PEM_labels_allowed; - std::string PEM_label_pref; - }; - -} - - -namespace Botan { - -/** -* Distinguished Name -*/ -class BOTAN_DLL X509_DN : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - std::multimap<OID, std::string> get_attributes() const; - std::vector<std::string> get_attribute(const std::string&) const; - - std::multimap<std::string, std::string> contents() const; - - void add_attribute(const std::string&, const std::string&); - void add_attribute(const OID&, const std::string&); - - static std::string deref_info_field(const std::string&); - - MemoryVector<byte> get_bits() const; - - X509_DN(); - X509_DN(const std::multimap<OID, std::string>&); - X509_DN(const std::multimap<std::string, std::string>&); - private: - std::multimap<OID, ASN1_String> dn_info; - MemoryVector<byte> dn_bits; - }; - -bool BOTAN_DLL operator==(const X509_DN&, const X509_DN&); -bool BOTAN_DLL operator!=(const X509_DN&, const X509_DN&); -bool BOTAN_DLL operator<(const X509_DN&, const X509_DN&); - -} - - -namespace Botan { - -/** -* This namespace contains functions for handling X.509 public keys -*/ -namespace X509 { - -/** -* BER encode a key -* @param key the public key to encode -* @return BER encoding of this key -*/ -BOTAN_DLL MemoryVector<byte> BER_encode(const Public_Key& key); - -/** -* PEM encode a public key into a string. -* @param key the key to encode -* @return PEM encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Public_Key& key); - -/** -* Create a public key from a data source. -* @param source the source providing the DER or PEM encoded key -* @return new public key object -*/ -BOTAN_DLL Public_Key* load_key(DataSource& source); - -/** -* Create a public key from a file -* @param filename pathname to the file to load -* @return new public key object -*/ -BOTAN_DLL Public_Key* load_key(const std::string& filename); - -/** -* Create a public key from a memory region. -* @param enc the memory region containing the DER or PEM encoded key -* @return new public key object -*/ -BOTAN_DLL Public_Key* load_key(const MemoryRegion<byte>& enc); - -/** -* Copy a key. -* @param key the public key to copy -* @return new public key object -*/ -BOTAN_DLL Public_Key* copy_key(const Public_Key& key); - -/** -* Create the key constraints for a specific public key. -* @param pub_key the public key from which the basic set of -* constraints to be placed in the return value is derived -* @param limits additional limits that will be incorporated into the -* return value -* @return combination of key type specific constraints and -* additional limits -*/ -BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits); - -/** -* Encode a key into a pipe. -* @deprecated Use PEM_encode or BER_encode instead -* -* @param key the public key to encode -* @param pipe the pipe to feed the encoded key into -* @param encoding the encoding type to use -*/ -BOTAN_DEPRECATED("Use PEM_encode or BER_encode") -inline void encode(const Public_Key& key, - Pipe& pipe, - X509_Encoding encoding = PEM) - { - if(encoding == PEM) - pipe.write(X509::PEM_encode(key)); - else - pipe.write(X509::BER_encode(key)); - } - -} - -} - - -namespace Botan { - -/** -* Data Store -*/ -class BOTAN_DLL Data_Store - { - public: - /** - * A search function - */ - class BOTAN_DLL Matcher - { - public: - virtual bool operator()(const std::string&, - const std::string&) const = 0; - - virtual std::pair<std::string, std::string> - transform(const std::string&, const std::string&) const; - - virtual ~Matcher() {} - }; - - bool operator==(const Data_Store&) const; - - std::multimap<std::string, std::string> - search_with(const Matcher&) const; - - std::vector<std::string> get(const std::string&) const; - - std::string get1(const std::string&) const; - - MemoryVector<byte> get1_memvec(const std::string&) const; - u32bit get1_u32bit(const std::string&, u32bit = 0) const; - - bool has_value(const std::string&) const; - - void add(const std::multimap<std::string, std::string>&); - void add(const std::string&, const std::string&); - void add(const std::string&, u32bit); - void add(const std::string&, const MemoryRegion<byte>&); - private: - std::multimap<std::string, std::string> contents; - }; - -} - - -namespace Botan { - -/** -* This class represents X.509 Certificate -*/ -class BOTAN_DLL X509_Certificate : public X509_Object - { - public: - /** - * Get the public key associated with this certificate. - * @return subject public key of this certificate - */ - Public_Key* subject_public_key() const; - - /** - * Get the issuer certificate DN. - * @return issuer DN of this certificate - */ - X509_DN issuer_dn() const; - - /** - * Get the subject certificate DN. - * @return subject DN of this certificate - */ - X509_DN subject_dn() const; - - /** - * Get a value for a specific subject_info parameter name. - * @param name the name of the paramter to look up. Possible names are - * "X509.Certificate.version", "X509.Certificate.serial", - * "X509.Certificate.start", "X509.Certificate.end", - * "X509.Certificate.v2.key_id", "X509.Certificate.public_key", - * "X509v3.BasicConstraints.path_constraint", - * "X509v3.BasicConstraints.is_ca", "X509v3.ExtendedKeyUsage", - * "X509v3.CertificatePolicies", "X509v3.SubjectKeyIdentifier" or - * "X509.Certificate.serial". - * @return value(s) of the specified parameter - */ - std::vector<std::string> subject_info(const std::string& name) const; - - /** - * Get a value for a specific subject_info parameter name. - * @param name the name of the paramter to look up. Possible names are - * "X509.Certificate.v2.key_id" or "X509v3.AuthorityKeyIdentifier". - * @return value(s) of the specified parameter - */ - std::vector<std::string> issuer_info(const std::string& name) const; - - /** - * Get the notBefore of the certificate. - * @return notBefore of the certificate - */ - std::string start_time() const; - - /** - * Get the notAfter of the certificate. - * @return notAfter of the certificate - */ - std::string end_time() const; - - /** - * Get the X509 version of this certificate object. - * @return X509 version - */ - u32bit x509_version() const; - - /** - * Get the serial number of this certificate. - * @return certificates serial number - */ - MemoryVector<byte> serial_number() const; - - /** - * Get the DER encoded AuthorityKeyIdentifier of this certificate. - * @return DER encoded AuthorityKeyIdentifier - */ - MemoryVector<byte> authority_key_id() const; - - /** - * Get the DER encoded SubjectKeyIdentifier of this certificate. - * @return DER encoded SubjectKeyIdentifier - */ - MemoryVector<byte> subject_key_id() const; - - /** - * Check whether this certificate is self signed. - * @return true if this certificate is self signed - */ - bool is_self_signed() const { return self_signed; } - - /** - * Check whether this certificate is a CA certificate. - * @return true if this certificate is a CA certificate - */ - bool is_CA_cert() const; - - /** - * Get the path limit as defined in the BasicConstraints extension of - * this certificate. - * @return path limit - */ - u32bit path_limit() const; - - /** - * Get the key constraints as defined in the KeyUsage extension of this - * certificate. - * @return key constraints - */ - Key_Constraints constraints() const; - - /** - * Get the key constraints as defined in the ExtendedKeyUsage - * extension of this - * certificate. - * @return key constraints - */ - std::vector<std::string> ex_constraints() const; - - /** - * Get the policies as defined in the CertificatePolicies extension - * of this certificate. - * @return certificate policies - */ - std::vector<std::string> policies() const; - - /** - * @return a string describing the certificate - */ - std::string to_string() const; - - /** - * Check to certificates for equality. - * @return true both certificates are (binary) equal - */ - bool operator==(const X509_Certificate& other) const; - - /** - * Create a certificate from a data source providing the DER or - * PEM encoded certificate. - * @param source the data source - */ - X509_Certificate(DataSource& source); - - /** - * Create a certificate from a file containing the DER or PEM - * encoded certificate. - * @param filename the name of the certificate file - */ - X509_Certificate(const std::string& filename); - private: - void force_decode(); - friend class X509_CA; - X509_Certificate() {} - - Data_Store subject, issuer; - bool self_signed; - }; - -/** -* Check two certificates for inequality -* @return true if the arguments represent different certificates, -* false if they are binary identical -*/ -BOTAN_DLL bool operator!=(const X509_Certificate&, const X509_Certificate&); - -/* -* Data Store Extraction Operations -*/ -BOTAN_DLL X509_DN create_dn(const Data_Store&); -BOTAN_DLL AlternativeName create_alt_name(const Data_Store&); - -} - - -namespace Botan { - -/** -* This class represents CRL entries -*/ -class BOTAN_DLL CRL_Entry : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - /** - * Get the serial number of the certificate associated with this entry. - * @return certificate's serial number - */ - MemoryVector<byte> serial_number() const { return serial; } - - /** - * Get the revocation date of the certificate associated with this entry - * @return certificate's revocation date - */ - X509_Time expire_time() const { return time; } - - /** - * Get the entries reason code - * @return reason code - */ - CRL_Code reason_code() const { return reason; } - - /** - * Construct an empty CRL entry. - */ - CRL_Entry(bool throw_on_unknown_critical_extension = false); - - /** - * Construct an CRL entry. - * @param cert the certificate to revoke - * @param reason the reason code to set in the entry - */ - CRL_Entry(const X509_Certificate& cert, - CRL_Code reason = UNSPECIFIED); - - private: - bool throw_on_unknown_critical; - MemoryVector<byte> serial; - X509_Time time; - CRL_Code reason; - }; - -/** -* Test two CRL entries for equality in all fields. -*/ -BOTAN_DLL bool operator==(const CRL_Entry&, const CRL_Entry&); - -/** -* Test two CRL entries for inequality in at least one field. -*/ -BOTAN_DLL bool operator!=(const CRL_Entry&, const CRL_Entry&); - -} - - -namespace Botan { - -/** -* This class represents X.509 Certificate Revocation Lists (CRLs). -*/ -class BOTAN_DLL X509_CRL : public X509_Object - { - public: - /** - * This class represents CRL related errors. - */ - struct BOTAN_DLL X509_CRL_Error : public Exception - { - X509_CRL_Error(const std::string& error) : - Exception("X509_CRL: " + error) {} - }; - - /** - * Get the entries of this CRL in the form of a vector. - * @return vector containing the entries of this CRL. - */ - std::vector<CRL_Entry> get_revoked() const; - - /** - * Get the issuer DN of this CRL. - * @return CRLs issuer DN - */ - X509_DN issuer_dn() const; - - /** - * Get the AuthorityKeyIdentifier of this CRL. - * @return this CRLs AuthorityKeyIdentifier - */ - MemoryVector<byte> authority_key_id() const; - - /** - * Get the serial number of this CRL. - * @return CRLs serial number - */ - u32bit crl_number() const; - - /** - * Get the CRL's thisUpdate value. - * @return CRLs thisUpdate - */ - X509_Time this_update() const; - - /** - * Get the CRL's nextUpdate value. - * @return CRLs nextdUpdate - */ - X509_Time next_update() const; - - /** - * Construct a CRL from a data source. - * @param source the data source providing the DER or PEM encoded CRL. - * @param throw_on_unknown_critical should we throw an exception - * if an unknown CRL extension marked as critical is encountered. - */ - X509_CRL(DataSource& source, bool throw_on_unknown_critical = false); - - /** - * Construct a CRL from a file containing the DER or PEM encoded CRL. - * @param filename the name of the CRL file - * @param throw_on_unknown_critical should we throw an exception - * if an unknown CRL extension marked as critical is encountered. - */ - X509_CRL(const std::string& filename, - bool throw_on_unknown_critical = false); - private: - void force_decode(); - - bool throw_on_unknown_critical; - std::vector<CRL_Entry> revoked; - Data_Store info; - }; - -} - - -namespace Botan { - -/** -* Luby-Rackoff block cipher construction -*/ -class BOTAN_DLL LubyRackoff : public BlockCipher - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - size_t block_size() const { return 2 * hash->output_length(); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(2, 32, 2); - } - - void clear(); - std::string name() const; - BlockCipher* clone() const; - - /** - * @param hash function to use to form the block cipher - */ - LubyRackoff(HashFunction* hash); - ~LubyRackoff() { delete hash; } - private: - void key_schedule(const byte[], size_t); - - HashFunction* hash; - SecureVector<byte> K1, K2; - }; - -} - - -namespace Botan { - -/** -* EMSA2 from IEEE 1363 -* Useful for Rabin-Williams -*/ -class BOTAN_DLL EMSA2 : public EMSA - { - public: - /** - * @param hash the hash object to use - */ - EMSA2(HashFunction* hash); - ~EMSA2() { delete hash; } - private: - void update(const byte[], size_t); - SecureVector<byte> raw_data(); - - SecureVector<byte> encoding_of(const MemoryRegion<byte>&, size_t, - RandomNumberGenerator& rng); - - bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - size_t); - - SecureVector<byte> empty_hash; - HashFunction* hash; - byte hash_id; - }; - -} - - -namespace Botan { - -/** -* Fused multiply-add -* @param a an integer -* @param b an integer -* @param c an integer -* @return (a*b)+c -*/ -BigInt BOTAN_DLL mul_add(const BigInt& a, - const BigInt& b, - const BigInt& c); - -/** -* Fused subtract-multiply -* @param a an integer -* @param b an integer -* @param c an integer -* @return (a-b)*c -*/ -BigInt BOTAN_DLL sub_mul(const BigInt& a, - const BigInt& b, - const BigInt& c); - -/** -* Return the absolute value -* @param n an integer -* @return absolute value of n -*/ -inline BigInt abs(const BigInt& n) { return n.abs(); } - -/** -* Compute the greatest common divisor -* @param x a positive integer -* @param y a positive integer -* @return gcd(x,y) -*/ -BigInt BOTAN_DLL gcd(const BigInt& x, const BigInt& y); - -/** -* Least common multiple -* @param x a positive integer -* @param y a positive integer -* @return z, smallest integer such that z % x == 0 and z % y == 0 -*/ -BigInt BOTAN_DLL lcm(const BigInt& x, const BigInt& y); - -/** -* @param x an integer -* @return (x*x) -*/ -BigInt BOTAN_DLL square(const BigInt& x); - -/** -* Modular inversion -* @param x a positive integer -* @param modulus a positive integer -* @return y st (x*y) % modulus == 1 -*/ -BigInt BOTAN_DLL inverse_mod(const BigInt& x, - const BigInt& modulus); - -/** -* Compute the Jacobi symbol. If n is prime, this is equivalent -* to the Legendre symbol. -* @see http://mathworld.wolfram.com/JacobiSymbol.html -* -* @param a is a non-negative integer -* @param n is an odd integer > 1 -* @return (n / m) -*/ -s32bit BOTAN_DLL jacobi(const BigInt& a, - const BigInt& n); - -/** -* Modular exponentation -* @param b an integer base -* @param x a positive exponent -* @param m a positive modulus -* @return (b^x) % m -*/ -BigInt BOTAN_DLL power_mod(const BigInt& b, - const BigInt& x, - const BigInt& m); - -/** -* Compute the square root of x modulo a prime using the -* Shanks-Tonnelli algorithm -* -* @param x the input -* @param p the prime -* @return y such that (y*y)%p == x, or -1 if no such integer -*/ -BigInt BOTAN_DLL ressol(const BigInt& x, const BigInt& p); - -/** -* @param x an integer -* @return count of the zero bits in x, or, equivalently, the largest -* value of n such that 2^n divides x evently -*/ -size_t BOTAN_DLL low_zero_bits(const BigInt& x); - -/** -* Primality Testing -* @param n a positive integer to test for primality -* @param rng a random number generator -* @param level how hard to test -* @return true if all primality tests passed, otherwise false -*/ -bool BOTAN_DLL primality_test(const BigInt& n, - RandomNumberGenerator& rng, - size_t level = 1); - -/** -* Quickly check for primality -* @param n a positive integer to test for primality -* @param rng a random number generator -* @return true if all primality tests passed, otherwise false -*/ -inline bool quick_check_prime(const BigInt& n, RandomNumberGenerator& rng) - { return primality_test(n, rng, 0); } - -/** -* Check for primality -* @param n a positive integer to test for primality -* @param rng a random number generator -* @return true if all primality tests passed, otherwise false -*/ -inline bool check_prime(const BigInt& n, RandomNumberGenerator& rng) - { return primality_test(n, rng, 1); } - -/** -* Verify primality - this function is slow but useful if you want to -* ensure that a possibly malicious entity did not provide you with -* something that 'looks like' a prime -* @param n a positive integer to test for primality -* @param rng a random number generator -* @return true if all primality tests passed, otherwise false -*/ -inline bool verify_prime(const BigInt& n, RandomNumberGenerator& rng) - { return primality_test(n, rng, 2); } - -/** -* Randomly generate a prime -* @param rng a random number generator -* @param bits how large the resulting prime should be in bits -* @param coprime a positive integer the result should be coprime to -* @param equiv a non-negative number that the result should be - equivalent to modulo equiv_mod -* @param equiv_mod the modulus equiv should be checked against -* @return random prime with the specified criteria -*/ -BigInt BOTAN_DLL random_prime(RandomNumberGenerator& rng, - size_t bits, const BigInt& coprime = 1, - size_t equiv = 1, size_t equiv_mod = 2); - -/** -* Return a 'safe' prime, of the form p=2*q+1 with q prime -* @param rng a random number generator -* @param bits is how long the resulting prime should be -* @return prime randomly chosen from safe primes of length bits -*/ -BigInt BOTAN_DLL random_safe_prime(RandomNumberGenerator& rng, - size_t bits); - -class Algorithm_Factory; - -/** -* Generate DSA parameters using the FIPS 186 kosherizer -* @param rng a random number generator -* @param af an algorithm factory -* @param p_out where the prime p will be stored -* @param q_out where the prime q will be stored -* @param pbits how long p will be in bits -* @param qbits how long q will be in bits -* @return random seed used to generate this parameter set -*/ -SecureVector<byte> BOTAN_DLL -generate_dsa_primes(RandomNumberGenerator& rng, - Algorithm_Factory& af, - BigInt& p_out, BigInt& q_out, - size_t pbits, size_t qbits); - -/** -* Generate DSA parameters using the FIPS 186 kosherizer -* @param rng a random number generator -* @param af an algorithm factory -* @param p_out where the prime p will be stored -* @param q_out where the prime q will be stored -* @param pbits how long p will be in bits -* @param qbits how long q will be in bits -* @param seed the seed used to generate the parameters -* @return true if seed generated a valid DSA parameter set, otherwise - false. p_out and q_out are only valid if true was returned. -*/ -bool BOTAN_DLL -generate_dsa_primes(RandomNumberGenerator& rng, - Algorithm_Factory& af, - BigInt& p_out, BigInt& q_out, - size_t pbits, size_t qbits, - const MemoryRegion<byte>& seed); - -/** -* The size of the PRIMES[] array -*/ -const size_t PRIME_TABLE_SIZE = 6541; - -/** -* A const array of all primes less than 65535 -*/ -extern const u16bit BOTAN_DLL PRIMES[]; - -} - - -namespace Botan { - -/** -* This class represents an elliptic curve over GF(p) -*/ -class BOTAN_DLL CurveGFp - { - public: - - /** - * Create an uninitialized CurveGFp - */ - CurveGFp() : p_words(0), p_dash(0) {} - - /** - * Construct the elliptic curve E: y^2 = x^3 + ax + b over GF(p) - * @param p prime number of the field - * @param a first coefficient - * @param b second coefficient - */ - CurveGFp(const BigInt& p, const BigInt& a, const BigInt& b) : - p(p), a(a), b(b), p_words(p.sig_words()) - { - BigInt r(BigInt::Power2, p_words * BOTAN_MP_WORD_BITS); - - p_dash = (((r * inverse_mod(r, p)) - 1) / p).word_at(0); - - r2 = (r * r) % p; - a_r = (a * r) % p; - b_r = (b * r) % p; - } - - // CurveGFp(const CurveGFp& other) = default; - // CurveGFp& operator=(const CurveGFp& other) = default; - - /** - * @return curve coefficient a - */ - const BigInt& get_a() const { return a; } - - /** - * @return curve coefficient b - */ - const BigInt& get_b() const { return b; } - - /** - * Get prime modulus of the field of the curve - * @return prime modulus of the field of the curve - */ - const BigInt& get_p() const { return p; } - - /** - * @return Montgomery parameter r^2 % p - */ - const BigInt& get_r2() const { return r2; } - - /** - * @return a * r mod p - */ - const BigInt& get_a_r() const { return a_r; } - - /** - * @return b * r mod p - */ - const BigInt& get_b_r() const { return b_r; } - - /** - * @return Montgomery parameter p-dash - */ - word get_p_dash() const { return p_dash; } - - /** - * @return p.sig_words() - */ - size_t get_p_words() const { return p_words; } - - /** - * swaps the states of *this and other, does not throw - * @param other curve to swap values with - */ - void swap(CurveGFp& other) - { - std::swap(p, other.p); - - std::swap(a, other.a); - std::swap(b, other.b); - - std::swap(a_r, other.a_r); - std::swap(b_r, other.b_r); - - std::swap(p_words, other.p_words); - - std::swap(r2, other.r2); - std::swap(p_dash, other.p_dash); - } - - /** - * Equality operator - * @param other curve to compare with - * @return true iff this is the same curve as other - */ - bool operator==(const CurveGFp& other) const - { - /* - Relies on choice of R, but that is fixed by constructor based - on size of p - */ - return (p == other.p && a_r == other.a_r && b_r == other.b_r); - } - - private: - // Curve parameters - BigInt p, a, b; - - size_t p_words; // cache of p.sig_words() - - // Montgomery parameters - BigInt r2, a_r, b_r; - word p_dash; - }; - -/** -* Equality operator -* @param lhs a curve -* @param rhs a curve -* @return true iff lhs is not the same as rhs -*/ -inline bool operator!=(const CurveGFp& lhs, const CurveGFp& rhs) - { - return !(lhs == rhs); - } - -} - -namespace std { - -template<> inline -void swap<Botan::CurveGFp>(Botan::CurveGFp& curve1, - Botan::CurveGFp& curve2) - { - curve1.swap(curve2); - } - -} // namespace std - - -namespace Botan { - -/** -* Exception thrown if you try to convert a zero point to an affine -* coordinate -*/ -struct BOTAN_DLL Illegal_Transformation : public Exception - { - Illegal_Transformation(const std::string& err = - "Requested transformation is not possible") : - Exception(err) {} - }; - -/** -* Exception thrown if some form of illegal point is decoded -*/ -struct BOTAN_DLL Illegal_Point : public Exception - { - Illegal_Point(const std::string& err = "Malformed ECP point detected") : - Exception(err) {} - }; - -/** -* This class represents one point on a curve of GF(p) -*/ -class BOTAN_DLL PointGFp - { - public: - enum Compression_Type { - UNCOMPRESSED = 0, - COMPRESSED = 1, - HYBRID = 2 - }; - - /** - * Construct an uninitialized PointGFp - */ - PointGFp() {} - - /** - * Construct the zero point - * @param curve The base curve - */ - PointGFp(const CurveGFp& curve); - - /** - * Construct a point from its affine coordinates - * @param curve the base curve - * @param x affine x coordinate - * @param y affine y coordinate - */ - PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y); - - //PointGFp(const PointGFp& other) = default; - //PointGFp& operator=(const PointGFp& other) = default; - - /** - * += Operator - * @param rhs the PointGFp to add to the local value - * @result resulting PointGFp - */ - PointGFp& operator+=(const PointGFp& rhs); - - /** - * -= Operator - * @param rhs the PointGFp to subtract from the local value - * @result resulting PointGFp - */ - PointGFp& operator-=(const PointGFp& rhs); - - /** - * *= Operator - * @param scalar the PointGFp to multiply with *this - * @result resulting PointGFp - */ - PointGFp& operator*=(const BigInt& scalar); - - /** - * Multiplication Operator - * @param scalar the scalar value - * @param point the point value - * @return scalar*point on the curve - */ - friend BOTAN_DLL PointGFp operator*(const BigInt& scalar, const PointGFp& point); - - /** - * Multiexponentiation - * @param p1 a point - * @param z1 a scalar - * @param p2 a point - * @param z2 a scalar - * @result (p1 * z1 + p2 * z2) - */ - friend BOTAN_DLL PointGFp multi_exponentiate( - const PointGFp& p1, const BigInt& z1, - const PointGFp& p2, const BigInt& z2); - - /** - * Negate this point - * @return *this - */ - PointGFp& negate() - { - if(!is_zero()) - coord_y = curve.get_p() - coord_y; - return *this; - } - - /** - * Return base curve of this point - * @result the curve over GF(p) of this point - */ - const CurveGFp& get_curve() const { return curve; } - - /** - * get affine x coordinate - * @result affine x coordinate - */ - BigInt get_affine_x() const; - - /** - * get affine y coordinate - * @result affine y coordinate - */ - BigInt get_affine_y() const; - - /** - * Is this the point at infinity? - * @result true, if this point is at infinity, false otherwise. - */ - bool is_zero() const - { return (coord_x.is_zero() && coord_z.is_zero()); } - - /** - * Checks whether the point is to be found on the underlying - * curve; used to prevent fault attacks. - * @return if the point is on the curve - */ - bool on_the_curve() const; - - /** - * swaps the states of *this and other, does not throw! - * @param other the object to swap values with - */ - void swap(PointGFp& other); - - /** - * Equality operator - */ - bool operator==(const PointGFp& other) const; - private: - - /** - * Montgomery multiplication/reduction - * @param x first multiplicand - * @param y second multiplicand - * @param workspace temp space - */ - BigInt monty_mult(const BigInt& x, const BigInt& y) const - { - BigInt result; - monty_mult(result, x, y); - return result; - } - - /** - * Montgomery multiplication/reduction - * @warning z cannot alias x or y - * @param z output - * @param x first multiplicand - * @param y second multiplicand - */ - void monty_mult(BigInt& z, const BigInt& x, const BigInt& y) const; - - /** - * Montgomery squaring/reduction - * @param x multiplicand - */ - BigInt monty_sqr(const BigInt& x) const - { - BigInt result; - monty_sqr(result, x); - return result; - } - - /** - * Montgomery squaring/reduction - * @warning z cannot alias x - * @param z output - * @param x multiplicand - */ - void monty_sqr(BigInt& z, const BigInt& x) const; - - /** - * Point addition - * @param workspace temp space, at least 11 elements - */ - void add(const PointGFp& other, std::vector<BigInt>& workspace); - - /** - * Point doubling - * @param workspace temp space, at least 9 elements - */ - void mult2(std::vector<BigInt>& workspace); - - CurveGFp curve; - BigInt coord_x, coord_y, coord_z; - mutable SecureVector<word> ws; // workspace for Montgomery - }; - -// relational operators -inline bool operator!=(const PointGFp& lhs, const PointGFp& rhs) - { - return !(rhs == lhs); - } - -// arithmetic operators -inline PointGFp operator-(const PointGFp& lhs) - { - return PointGFp(lhs).negate(); - } - -inline PointGFp operator+(const PointGFp& lhs, const PointGFp& rhs) - { - PointGFp tmp(lhs); - return tmp += rhs; - } - -inline PointGFp operator-(const PointGFp& lhs, const PointGFp& rhs) - { - PointGFp tmp(lhs); - return tmp -= rhs; - } - -inline PointGFp operator*(const PointGFp& point, const BigInt& scalar) - { - return scalar * point; - } - -// encoding and decoding -SecureVector<byte> BOTAN_DLL EC2OSP(const PointGFp& point, byte format); - -PointGFp BOTAN_DLL OS2ECP(const byte data[], size_t data_len, - const CurveGFp& curve); - -inline PointGFp OS2ECP(const MemoryRegion<byte>& data, const CurveGFp& curve) - { return OS2ECP(&data[0], data.size(), curve); } - -} - -namespace std { - -template<> -inline void swap<Botan::PointGFp>(Botan::PointGFp& x, Botan::PointGFp& y) - { x.swap(y); } - -} - - -namespace Botan { - -/** -* This class represents elliptic curce domain parameters -*/ -enum EC_Group_Encoding { - EC_DOMPAR_ENC_EXPLICIT = 0, - EC_DOMPAR_ENC_IMPLICITCA = 1, - EC_DOMPAR_ENC_OID = 2 -}; - -/** -* Class representing an elliptic curve -*/ -class BOTAN_DLL EC_Group - { - public: - - /** - * Construct Domain paramers from specified parameters - * @param curve elliptic curve - * @param base_point a base point - * @param order the order of the base point - * @param cofactor the cofactor - */ - EC_Group(const CurveGFp& curve, - const PointGFp& base_point, - const BigInt& order, - const BigInt& cofactor) : - curve(curve), - base_point(base_point), - order(order), - cofactor(cofactor), - oid("") - {} - - /** - * Decode a BER encoded ECC domain parameter set - * @param ber_encoding the bytes of the BER encoding - */ - EC_Group(const MemoryRegion<byte>& ber_encoding); - - /** - * Create an EC domain by OID (or throw if unknown) - * @param oid the OID of the EC domain to create - */ - EC_Group(const OID& oid); - - /** - * Create an EC domain from PEM encoding (as from PEM_encode), - * or from an OID name (eg "secp160r1", or "1.3.132.0.8") - * @param pem_or_oid PEM-encoded data, or an OID - */ - EC_Group(const std::string& pem_or_oid = ""); - - /** - * Create the DER encoding of this domain - * @param form of encoding to use - * @returns bytes encododed as DER - */ - SecureVector<byte> DER_encode(EC_Group_Encoding form) const; - - /** - * Return the PEM encoding (always in explicit form) - * @return string containing PEM data - */ - std::string PEM_encode() const; - - /** - * Return domain parameter curve - * @result domain parameter curve - */ - const CurveGFp& get_curve() const { return curve; } - - /** - * Return domain parameter curve - * @result domain parameter curve - */ - const PointGFp& get_base_point() const { return base_point; } - - /** - * Return the order of the base point - * @result order of the base point - */ - const BigInt& get_order() const { return order; } - - /** - * Return the cofactor - * @result the cofactor - */ - const BigInt& get_cofactor() const { return cofactor; } - - bool initialized() const { return !base_point.is_zero(); } - - /** - * Return the OID of these domain parameters - * @result the OID - */ - std::string get_oid() const { return oid; } - - bool operator==(const EC_Group& other) const - { - return ((get_curve() == other.get_curve()) && - (get_base_point() == other.get_base_point()) && - (get_order() == other.get_order()) && - (get_cofactor() == other.get_cofactor())); - } - - private: - CurveGFp curve; - PointGFp base_point; - BigInt order, cofactor; - std::string oid; - }; - -inline bool operator!=(const EC_Group& lhs, - const EC_Group& rhs) - { - return !(lhs == rhs); - } - -// For compatability with 1.8 -typedef EC_Group EC_Domain_Params; - -} - - -namespace Botan { - -/** -* User Interface -* Only really used for callbacks for PKCS #8 decryption -*/ -class BOTAN_DLL User_Interface - { - public: - enum UI_Result { OK, CANCEL_ACTION }; - - virtual std::string get_passphrase(const std::string&, - const std::string&, - UI_Result&) const; - User_Interface(const std::string& = ""); - virtual ~User_Interface() {} - protected: - std::string preset_passphrase; - mutable bool first_try; - }; - -} - - -namespace Botan { - -/** -* PKCS #8 General Exception -*/ -struct BOTAN_DLL PKCS8_Exception : public Decoding_Error - { - PKCS8_Exception(const std::string& error) : - Decoding_Error("PKCS #8: " + error) {} - }; - -/** -* This namespace contains functions for handling PKCS #8 private keys -*/ -namespace PKCS8 { - -/** -* BER encode a private key -* @param key the private key to encode -* @return BER encoded key -*/ -BOTAN_DLL SecureVector<byte> BER_encode(const Private_Key& key); - -/** -* Get a string containing a PEM encoded private key. -* @param key the key to encode -* @return encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key); - -/** -* Encrypt a key using PKCS #8 encryption -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbe_algo the name of the desired password-based encryption - algorithm; if empty ("") a reasonable (portable/secure) - default will be chosen. -* @return encrypted key in binary BER form -*/ -BOTAN_DLL SecureVector<byte> BER_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = ""); - -/** -* Get a string containing a PEM encoded private key, encrypting it with a -* password. -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbe_algo the name of the desired password-based encryption - algorithm; if empty ("") a reasonable (portable/secure) - default will be chosen. -* @return encrypted key in PEM form -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = ""); - - -/** -* Encode a private key into a pipe. -* @deprecated Use PEM_encode or BER_encode instead -* -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param encoding the encoding type to use -*/ -BOTAN_DEPRECATED("Use PEM_encode or BER_encode") -inline void encode(const Private_Key& key, - Pipe& pipe, - X509_Encoding encoding = PEM) - { - if(encoding == PEM) - pipe.write(PKCS8::PEM_encode(key)); - else - pipe.write(PKCS8::BER_encode(key)); - } - -/** -* Encode and encrypt a private key into a pipe. -* @deprecated Use PEM_encode or BER_encode instead -* -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param pass the password to use for encryption -* @param rng the rng to use -* @param pbe_algo the name of the desired password-based encryption - algorithm; if empty ("") a reasonable (portable/secure) - default will be chosen. -* @param encoding the encoding type to use -*/ -BOTAN_DEPRECATED("Use PEM_encode or BER_encode") -inline void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = "", - X509_Encoding encoding = PEM) - { - if(encoding == PEM) - pipe.write(PKCS8::PEM_encode(key, rng, pass, pbe_algo)); - else - pipe.write(PKCS8::BER_encode(key, rng, pass, pbe_algo)); - } - -/** -* Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Copy an existing encoded key object. -* @param key the key to copy -* @param rng the rng to use -* @return new copy of the key -*/ -BOTAN_DLL Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng); - -} - -} - - -namespace Botan { - -/** -* This class represents abstract ECC public keys. When encoding a key -* via an encoder that can be accessed via the corresponding member -* functions, the key will decide upon its internally stored encoding -* information whether to encode itself with or without domain -* parameters, or using the domain parameter oid. Furthermore, a public -* key without domain parameters can be decoded. In that case, it -* cannot be used for verification until its domain parameters are set -* by calling the corresponding member function. -*/ -class BOTAN_DLL EC_PublicKey : public virtual Public_Key - { - public: - EC_PublicKey(const EC_Group& dom_par, - const PointGFp& pub_point); - - EC_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits); - - /** - * Get the public point of this key. - * @throw Invalid_State is thrown if the - * domain parameters of this point are not set - * @result the public point of this key - */ - const PointGFp& public_point() const { return public_key; } - - AlgorithmIdentifier algorithm_identifier() const; - - MemoryVector<byte> x509_subject_public_key() const; - - bool check_key(RandomNumberGenerator& rng, - bool strong) const; - - /** - * Get the domain parameters of this key. - * @throw Invalid_State is thrown if the - * domain parameters of this point are not set - * @result the domain parameters of this key - */ - const EC_Group& domain() const { return domain_params; } - - /** - * Set the domain parameter encoding to be used when encoding this key. - * @param enc the encoding to use - */ - void set_parameter_encoding(EC_Group_Encoding enc); - - /** - * Return the DER encoding of this keys domain in whatever format - * is preset for this particular key - */ - MemoryVector<byte> DER_domain() const - { return domain().DER_encode(domain_format()); } - - /** - * Get the domain parameter encoding to be used when encoding this key. - * @result the encoding to use - */ - EC_Group_Encoding domain_format() const - { return domain_encoding; } - protected: - EC_PublicKey() : domain_encoding(EC_DOMPAR_ENC_EXPLICIT) {} - - EC_Group domain_params; - PointGFp public_key; - EC_Group_Encoding domain_encoding; - }; - -/** -* This abstract class represents ECC private keys -*/ -class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey, - public virtual Private_Key - { - public: - EC_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& private_key); - - EC_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits); - - MemoryVector<byte> pkcs8_private_key() const; - - /** - * Get the private key value of this key object. - * @result the private key value of this key object - */ - const BigInt& private_value() const; - protected: - EC_PrivateKey() {} - - BigInt private_key; - }; - -} - - -namespace Botan { - -/** -* GOST-34.10 Public Key -*/ -class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey - { - public: - - /** - * Construct a public key from a given public point. - * @param dom_par the domain parameters associated with this key - * @param public_point the public point defining this key - */ - GOST_3410_PublicKey(const EC_Group& dom_par, - const PointGFp& public_point) : - EC_PublicKey(dom_par, public_point) {} - - /** - * Construct from X.509 algorithm id and subject public key bits - */ - GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits); - - /** - * Get this keys algorithm name. - * @result this keys algorithm name - */ - std::string algo_name() const { return "GOST-34.10"; } - - AlgorithmIdentifier algorithm_identifier() const; - - MemoryVector<byte> x509_subject_public_key() const; - - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - - * @result the maximum number of input bits - */ - size_t max_input_bits() const { return domain().get_order().bits(); } - - size_t message_parts() const { return 2; } - - size_t message_part_size() const - { return domain().get_order().bytes(); } - - protected: - GOST_3410_PublicKey() {} - }; - -/** -* GOST-34.10 Private Key -*/ -class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, - public EC_PrivateKey - { - public: - - GOST_3410_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - EC_PrivateKey(alg_id, key_bits) {} - - /** - * Generate a new private key - * @param rng a random number generator - * @param domain parameters to used for this key - * @param x the private key; if zero, a new random key is generated - */ - GOST_3410_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& x = 0) : - EC_PrivateKey(rng, domain, x) {} - - AlgorithmIdentifier pkcs8_algorithm_identifier() const - { return EC_PublicKey::algorithm_identifier(); } - }; - -/** -* GOST-34.10 signature operation -*/ -class BOTAN_DLL GOST_3410_Signature_Operation : public PK_Ops::Signature - { - public: - GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - SecureVector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - private: - const PointGFp& base_point; - const BigInt& order; - const BigInt& x; - }; - -/** -* GOST-34.10 verification operation -*/ -class BOTAN_DLL GOST_3410_Verification_Operation : public PK_Ops::Verification - { - public: - GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - bool with_recovery() const { return false; } - - bool verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len); - private: - const PointGFp& base_point; - const PointGFp& public_point; - const BigInt& order; - }; - -} - - -namespace Botan { - -/** -* MDx Hash Function Base Class -*/ -class BOTAN_DLL MDx_HashFunction : public HashFunction - { - public: - /** - * @param block_length is the number of bytes per block - * @param big_byte_endian specifies if the hash uses big-endian bytes - * @param big_bit_endian specifies if the hash uses big-endian bits - * @param counter_size specifies the size of the counter var in bytes - */ - MDx_HashFunction(size_t block_length, - bool big_byte_endian, - bool big_bit_endian, - size_t counter_size = 8); - - size_t hash_block_size() const { return buffer.size(); } - protected: - void add_data(const byte input[], size_t length); - void final_result(byte output[]); - - /** - * Run the hash's compression function over a set of blocks - * @param blocks the input - * @param block_n the number of blocks - */ - virtual void compress_n(const byte blocks[], size_t block_n) = 0; - - void clear(); - - /** - * Copy the output to the buffer - * @param buffer to put the output into - */ - virtual void copy_out(byte buffer[]) = 0; - - /** - * Write the count, if used, to this spot - * @param out where to write the counter to - */ - virtual void write_count(byte out[]); - private: - SecureVector<byte> buffer; - u64bit count; - size_t position; - - const bool BIG_BYTE_ENDIAN, BIG_BIT_ENDIAN; - const size_t COUNT_SIZE; - }; - -} - - -namespace Botan { - -/** -* HAS-160, a Korean hash function standardized in -* TTAS.KO-12.0011/R1. Used in conjuction with KCDSA -*/ -class BOTAN_DLL HAS_160 : public MDx_HashFunction - { - public: - std::string name() const { return "HAS-160"; } - size_t output_length() const { return 20; } - HashFunction* clone() const { return new HAS_160; } - - void clear(); - - HAS_160() : MDx_HashFunction(64, false, true), X(20), digest(5) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector<u32bit> X, digest; - }; - -} - - -namespace Botan { - -/** -* This class represents the Library Initialization/Shutdown Object. It -* has to exceed the lifetime of any Botan object used in an -* application. You can call initialize/deinitialize or use -* LibraryInitializer in the RAII style. -*/ -class BOTAN_DLL LibraryInitializer - { - public: - /** - * Initialize the library - * @param options a string listing initialization options - */ - static void initialize(const std::string& options = ""); - - /** - * Shutdown the library - */ - static void deinitialize(); - - /** - * Initialize the library - * @param options a string listing initialization options - */ - LibraryInitializer(const std::string& options = "") - { LibraryInitializer::initialize(options); } - - ~LibraryInitializer() { LibraryInitializer::deinitialize(); } - }; - -} - - -namespace Botan { - -/* -* Forward declare to avoid recursive dependency between this header -* and libstate.h -*/ -class Library_State; - -/** -* Namespace for management of the global state -*/ -namespace Global_State_Management { - -/** -* Access the global library state -* @return reference to the global library state -*/ -BOTAN_DLL Library_State& global_state(); - -/** -* Set the global state object -* @param state the new global state to use -*/ -BOTAN_DLL void set_global_state(Library_State* state); - -/** -* Set the global state object unless it is already set -* @param state the new global state to use -* @return true if the state parameter is now being used as the global -* state, or false if one was already set, in which case the -* parameter was deleted immediately -*/ -BOTAN_DLL bool set_global_state_unless_set(Library_State* state); - -/** -* Swap the current state for another -* @param new_state the new state object to use -* @return previous state (or NULL if none) -*/ -BOTAN_DLL Library_State* swap_global_state(Library_State* new_state); - -/** -* Query if the library is currently initialized -* @return true iff the library is initialized -*/ -BOTAN_DLL bool global_state_exists(); - -} - -/* -* Insert into Botan ns for convenience/backwards compatability -*/ -using Global_State_Management::global_state; - -} - - -namespace Botan { - -/** -* Forward declarations (don't need full definitions here) -*/ -class BlockCipher; -class StreamCipher; -class HashFunction; -class MessageAuthenticationCode; -class PBKDF; - -template<typename T> class Algorithm_Cache; - -class Engine; -class Mutex_Factory; - -/** -* Algorithm Factory -*/ -class BOTAN_DLL Algorithm_Factory - { - public: - /** - * Constructor - * @param mf a mutex factory - */ - Algorithm_Factory(Mutex_Factory& mf); - - /** - * Destructor - */ - ~Algorithm_Factory(); - - /** - * @param engine to add (Algorithm_Factory takes ownership) - */ - void add_engine(Engine* engine); - - /** - * Clear out any cached objects - */ - void clear_caches(); - - /** - * @param algo_spec the algorithm we are querying - * @returns list of providers of this algorithm - */ - std::vector<std::string> providers_of(const std::string& algo_spec); - - /** - * @param algo_spec the algorithm we are setting a provider for - * @param provider the provider we would like to use - */ - void set_preferred_provider(const std::string& algo_spec, - const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const BlockCipher* - prototype_block_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - BlockCipher* make_block_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_block_cipher(BlockCipher* algo, const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const StreamCipher* - prototype_stream_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - StreamCipher* make_stream_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_stream_cipher(StreamCipher* algo, const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const HashFunction* - prototype_hash_function(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - HashFunction* make_hash_function(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_hash_function(HashFunction* algo, const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const MessageAuthenticationCode* - prototype_mac(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - MessageAuthenticationCode* make_mac(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_mac(MessageAuthenticationCode* algo, - const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const PBKDF* prototype_pbkdf(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - PBKDF* make_pbkdf(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_pbkdf(PBKDF* algo, const std::string& provider); - - /** - * An iterator for the engines in this factory - * @deprecated Avoid in new code - */ - class BOTAN_DLL Engine_Iterator - { - public: - /** - * @return next engine in the sequence - */ - Engine* next() { return af.get_engine_n(n++); } - - /** - * @param a an algorithm factory - */ - Engine_Iterator(const Algorithm_Factory& a) : - af(a) { n = 0; } - private: - const Algorithm_Factory& af; - size_t n; - }; - friend class Engine_Iterator; - - private: - Algorithm_Factory(const Algorithm_Factory&) {} - Algorithm_Factory& operator=(const Algorithm_Factory&) - { return (*this); } - - Engine* get_engine_n(size_t n) const; - - std::vector<Engine*> engines; - - Algorithm_Cache<BlockCipher>* block_cipher_cache; - Algorithm_Cache<StreamCipher>* stream_cipher_cache; - Algorithm_Cache<HashFunction>* hash_cache; - Algorithm_Cache<MessageAuthenticationCode>* mac_cache; - Algorithm_Cache<PBKDF>* pbkdf_cache; - }; - -} - - - -namespace Botan { - -class Mutex; - -/** -* Global state container aka the buritto at the center of it all -*/ -class BOTAN_DLL Library_State - { - public: - Library_State(); - ~Library_State(); - - /** - * @param thread_safe should a mutex be used for serialization - */ - void initialize(bool thread_safe); - - /** - * @return global Algorithm_Factory - */ - Algorithm_Factory& algorithm_factory() const; - - /** - * @return global RandomNumberGenerator - */ - RandomNumberGenerator& global_rng(); - - /** - * @param name the name of the allocator - * @return allocator matching this name, or NULL - */ - Allocator* get_allocator(const std::string& name = "") const; - - /** - * Add a new allocator to the list of available ones - * @param alloc the allocator to add - */ - void add_allocator(Allocator* alloc); - - /** - * Set the default allocator - * @param name the name of the allocator to use as the default - */ - void set_default_allocator(const std::string& name); - - /** - * Get a parameter value as std::string. - * @param section the section of the desired key - * @param key the desired keys name - * @result the value of the parameter - */ - std::string get(const std::string& section, - const std::string& key) const; - - /** - * Check whether a certain parameter is set or not. - * @param section the section of the desired key - * @param key the desired keys name - * @result true if the parameters value is set, - * false otherwise - */ - bool is_set(const std::string& section, - const std::string& key) const; - - /** - * Set a configuration parameter. - * @param section the section of the desired key - * @param key the desired keys name - * @param value the new value - * @param overwrite if set to true, the parameters value - * will be overwritten even if it is already set, otherwise - * no existing values will be overwritten. - */ - void set(const std::string& section, - const std::string& key, - const std::string& value, - bool overwrite = true); - - /** - * Add a parameter value to the "alias" section. - * @param key the name of the parameter which shall have a new alias - * @param value the new alias - */ - void add_alias(const std::string& key, - const std::string& value); - - /** - * Resolve an alias. - * @param alias the alias to resolve. - * @return what the alias stands for - */ - std::string deref_alias(const std::string& alias) const; - - /** - * @return newly created Mutex (free with delete) - */ - Mutex* get_mutex() const; - private: - static RandomNumberGenerator* make_global_rng(Algorithm_Factory& af, - Mutex* mutex); - - void load_default_config(); - - Library_State(const Library_State&) {} - Library_State& operator=(const Library_State&) { return (*this); } - - class Mutex_Factory* mutex_factory; - - Mutex* global_rng_lock; - RandomNumberGenerator* global_rng_ptr; - - Mutex* config_lock; - std::map<std::string, std::string> config; - - Mutex* allocator_lock; - std::string default_allocator_name; - std::map<std::string, Allocator*> alloc_factory; - mutable Allocator* cached_default_allocator; - std::vector<Allocator*> allocators; - - Algorithm_Factory* m_algorithm_factory; - }; - -} - - - -namespace Botan { - -/** -* BitBucket is a filter which simply discards all inputs -*/ -struct BOTAN_DLL BitBucket : public Filter - { - void write(const byte[], size_t) {} - - std::string name() const { return "BitBucket"; } - }; - -/** -* This class represents Filter chains. A Filter chain is an ordered -* concatenation of Filters, the input to a Chain sequentially passes -* through all the Filters contained in the Chain. -*/ - -class BOTAN_DLL Chain : public Fanout_Filter - { - public: - void write(const byte input[], size_t length) { send(input, length); } - - std::string name() const; - - /** - * Construct a chain of up to four filters. The filters are set - * up in the same order as the arguments. - */ - Chain(Filter* = 0, Filter* = 0, Filter* = 0, Filter* = 0); - - /** - * Construct a chain from range of filters - * @param filter_arr the list of filters - * @param length how many filters - */ - Chain(Filter* filter_arr[], size_t length); - }; - -/** -* This class represents a fork filter, whose purpose is to fork the -* flow of data. It causes an input message to result in n messages at -* the end of the filter, where n is the number of forks. -*/ -class BOTAN_DLL Fork : public Fanout_Filter - { - public: - void write(const byte input[], size_t length) { send(input, length); } - void set_port(size_t n) { Fanout_Filter::set_port(n); } - - std::string name() const; - - /** - * Construct a Fork filter with up to four forks. - */ - Fork(Filter*, Filter*, Filter* = 0, Filter* = 0); - - /** - * Construct a Fork from range of filters - * @param filter_arr the list of filters - * @param length how many filters - */ - Fork(Filter* filter_arr[], size_t length); - }; - -} - - -namespace Botan { - -/** -* This class represents keyed filters, i.e. filters that have to be -* fed with a key in order to function. -*/ -class BOTAN_DLL Keyed_Filter : public Filter - { - public: - /** - * Set the key of this filter - * @param key the key to use - */ - virtual void set_key(const SymmetricKey& key) = 0; - - /** - * Set the initialization vector of this filter. Note: you should - * call set_iv() only after you have called set_key() - * @param iv the initialization vector to use - */ - virtual void set_iv(const InitializationVector& iv); - - /** - * Check whether a key length is valid for this filter - * @param length the key length to be checked for validity - * @return true if the key length is valid, false otherwise - */ - virtual bool valid_keylength(size_t length) const = 0; - - /** - * Check whether an IV length is valid for this filter - * @param length the IV length to be checked for validity - * @return true if the IV length is valid, false otherwise - */ - virtual bool valid_iv_length(size_t length) const - { return (length == 0); } - }; - -} - - -namespace Botan { - -/** -* This class represents abstract data sink objects. -*/ -class BOTAN_DLL DataSink : public Filter - { - public: - bool attachable() { return false; } - DataSink() {} - virtual ~DataSink() {} - private: - DataSink& operator=(const DataSink&) { return (*this); } - DataSink(const DataSink&); - }; - -/** -* This class represents a data sink which writes its output to a stream. -*/ -class BOTAN_DLL DataSink_Stream : public DataSink - { - public: - std::string name() const { return identifier; } - - void write(const byte[], size_t); - - /** - * Construct a DataSink_Stream from a stream. - * @param stream the stream to write to - * @param name identifier - */ - DataSink_Stream(std::ostream& stream, - const std::string& name = "<std::ostream>"); - - /** - * Construct a DataSink_Stream from a stream. - * @param pathname the name of the file to open a stream to - * @param use_binary indicates whether to treat the file - * as a binary file or not - */ - DataSink_Stream(const std::string& pathname, - bool use_binary = false); - - ~DataSink_Stream(); - private: - const std::string identifier; - - std::ostream* sink_p; - std::ostream& sink; - }; - -} - - - -#if defined(BOTAN_HAS_CODEC_FILTERS) - -namespace Botan { - -/** -* This class represents a Base64 encoder. -*/ -class BOTAN_DLL Base64_Encoder : public Filter - { - public: - std::string name() const { return "Base64_Encoder"; } - - /** - * Input a part of a message to the encoder. - * @param input the message to input as a byte array - * @param length the length of the byte array input - */ - void write(const byte input[], size_t length); - - /** - * Inform the Encoder that the current message shall be closed. - */ - void end_msg(); - - /** - * Create a base64 encoder. - * @param breaks whether to use line breaks in the output - * @param length the length of the lines of the output - * @param t_n whether to use a trailing newline - */ - Base64_Encoder(bool breaks = false, size_t length = 72, - bool t_n = false); - private: - void encode_and_send(const byte input[], size_t length, - bool final_inputs = false); - void do_output(const byte output[], size_t length); - - const size_t line_length; - const bool trailing_newline; - MemoryVector<byte> in, out; - size_t position, out_position; - }; - -/** -* This object represents a Base64 decoder. -*/ -class BOTAN_DLL Base64_Decoder : public Filter - { - public: - std::string name() const { return "Base64_Decoder"; } - - /** - * Input a part of a message to the decoder. - * @param input the message to input as a byte array - * @param length the length of the byte array input - */ - void write(const byte input[], size_t length); - - /** - * Finish up the current message - */ - void end_msg(); - - /** - * Create a base64 decoder. - * @param checking the type of checking that shall be performed by - * the decoder - */ - Base64_Decoder(Decoder_Checking checking = NONE); - private: - const Decoder_Checking checking; - MemoryVector<byte> in, out; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Converts arbitrary binary data to hex strings, optionally with -* newlines inserted -*/ -class BOTAN_DLL Hex_Encoder : public Filter - { - public: - /** - * Whether to use uppercase or lowercase letters for the encoded string. - */ - enum Case { Uppercase, Lowercase }; - - std::string name() const { return "Hex_Encoder"; } - - void write(const byte in[], size_t length); - void end_msg(); - - /** - * Create a hex encoder. - * @param the_case the case to use in the encoded strings. - */ - Hex_Encoder(Case the_case); - - /** - * Create a hex encoder. - * @param newlines should newlines be used - * @param line_length if newlines are used, how long are lines - * @param the_case the case to use in the encoded strings - */ - Hex_Encoder(bool newlines = false, - size_t line_length = 72, - Case the_case = Uppercase); - private: - void encode_and_send(const byte[], size_t); - - const Case casing; - const size_t line_length; - MemoryVector<byte> in, out; - size_t position, counter; - }; - -/** -* Converts hex strings to bytes -*/ -class BOTAN_DLL Hex_Decoder : public Filter - { - public: - std::string name() const { return "Hex_Decoder"; } - - void write(const byte[], size_t); - void end_msg(); - - /** - * Construct a Hex Decoder using the specified - * character checking. - * @param checking the checking to use during decoding. - */ - Hex_Decoder(Decoder_Checking checking = NONE); - private: - const Decoder_Checking checking; - MemoryVector<byte> in, out; - size_t position; - }; - -} - -#endif - -namespace Botan { - -/** -* Stream Cipher Filter. -*/ -class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter - { - public: - - std::string name() const { return cipher->name(); } - - /** - * Write input data - * @param input data - * @param input_len length of input in bytes - */ - void write(const byte input[], size_t input_len); - - bool valid_iv_length(size_t iv_len) const - { return cipher->valid_iv_length(iv_len); } - - /** - * Set the initialization vector for this filter. - * @param iv the initialization vector to set - */ - void set_iv(const InitializationVector& iv); - - /** - * Set the key of this filter. - * @param key the key to set - */ - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - /** - * Check whether a key length is valid for this filter. - * @param length the key length to be checked for validity - * @return true if the key length is valid, false otherwise - */ - bool valid_keylength(size_t length) const - { return cipher->valid_keylength(length); } - - /** - * Construct a stream cipher filter. - * @param cipher_obj a cipher object to use - */ - StreamCipher_Filter(StreamCipher* cipher_obj); - - /** - * Construct a stream cipher filter. - * @param cipher_obj a cipher object to use - * @param key the key to use inside this filter - */ - StreamCipher_Filter(StreamCipher* cipher_obj, const SymmetricKey& key); - - /** - * Construct a stream cipher filter. - * @param cipher the name of the desired cipher - */ - StreamCipher_Filter(const std::string& cipher); - - /** - * Construct a stream cipher filter. - * @param cipher the name of the desired cipher - * @param key the key to use inside this filter - */ - StreamCipher_Filter(const std::string& cipher, const SymmetricKey& key); - - ~StreamCipher_Filter() { delete cipher; } - private: - SecureVector<byte> buffer; - StreamCipher* cipher; - }; - -/** -* Hash Filter. -*/ -class BOTAN_DLL Hash_Filter : public Filter - { - public: - void write(const byte input[], size_t len) { hash->update(input, len); } - void end_msg(); - - std::string name() const { return hash->name(); } - - /** - * Construct a hash filter. - * @param hash_fun the hash function to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the hashfunction - * hash. Otherwise, specify a smaller value here so that the - * output of the hash algorithm will be cut off. - */ - Hash_Filter(HashFunction* hash_fun, size_t len = 0) : - OUTPUT_LENGTH(len), hash(hash_fun) {} - - /** - * Construct a hash filter. - * @param request the name of the hash algorithm to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the hashfunction - * hash. Otherwise, specify a smaller value here so that the - * output of the hash algorithm will be cut off. - */ - Hash_Filter(const std::string& request, size_t len = 0); - - ~Hash_Filter() { delete hash; } - private: - const size_t OUTPUT_LENGTH; - HashFunction* hash; - }; - -/** -* MessageAuthenticationCode Filter. -*/ -class BOTAN_DLL MAC_Filter : public Keyed_Filter - { - public: - void write(const byte input[], size_t len) { mac->update(input, len); } - void end_msg(); - - std::string name() const { return mac->name(); } - - /** - * Set the key of this filter. - * @param key the key to set - */ - void set_key(const SymmetricKey& key) { mac->set_key(key); } - - /** - * Check whether a key length is valid for this filter. - * @param length the key length to be checked for validity - * @return true if the key length is valid, false otherwise - */ - bool valid_keylength(size_t length) const - { return mac->valid_keylength(length); } - - /** - * Construct a MAC filter. The MAC key will be left empty. - * @param mac_obj the MAC to use - * @param out_len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(MessageAuthenticationCode* mac_obj, - size_t out_len = 0) : OUTPUT_LENGTH(out_len) - { - mac = mac_obj; - } - - /** - * Construct a MAC filter. - * @param mac_obj the MAC to use - * @param key the MAC key to use - * @param out_len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(MessageAuthenticationCode* mac_obj, - const SymmetricKey& key, - size_t out_len = 0) : OUTPUT_LENGTH(out_len) - { - mac = mac_obj; - mac->set_key(key); - } - - /** - * Construct a MAC filter. The MAC key will be left empty. - * @param mac the name of the MAC to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(const std::string& mac, size_t len = 0); - - /** - * Construct a MAC filter. - * @param mac the name of the MAC to use - * @param key the MAC key to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(const std::string& mac, const SymmetricKey& key, - size_t len = 0); - - ~MAC_Filter() { delete mac; } - private: - const size_t OUTPUT_LENGTH; - MessageAuthenticationCode* mac; - }; - -} - - -namespace Botan { - -/** -* Block Cipher Mode Padding Method -* This class is pretty limited, it cannot deal well with -* randomized padding methods, or any padding method that -* wants to add more than one block. For instance, it should -* be possible to define cipher text stealing mode as simply -* a padding mode for CBC, which happens to consume the last -* two block (and requires use of the block cipher). -*/ -class BOTAN_DLL BlockCipherModePaddingMethod - { - public: - /** - * @param block output buffer - * @param size of the block - * @param current_position in the last block - */ - virtual void pad(byte block[], - size_t size, - size_t current_position) const = 0; - - /** - * @param block the last block - * @param size the of the block - */ - virtual size_t unpad(const byte block[], - size_t size) const = 0; - - /** - * @param block_size of the cipher - * @param position in the current block - * @return number of padding bytes that will be appended - */ - virtual size_t pad_bytes(size_t block_size, - size_t position) const; - - /** - * @param block_size of the cipher - * @return valid block size for this padding mode - */ - virtual bool valid_blocksize(size_t block_size) const = 0; - - /** - * @return name of the mode - */ - virtual std::string name() const = 0; - - /** - * virtual destructor - */ - virtual ~BlockCipherModePaddingMethod() {} - }; - -/** -* PKCS#7 Padding -*/ -class BOTAN_DLL PKCS7_Padding : public BlockCipherModePaddingMethod - { - public: - void pad(byte[], size_t, size_t) const; - size_t unpad(const byte[], size_t) const; - bool valid_blocksize(size_t) const; - std::string name() const { return "PKCS7"; } - }; - -/** -* ANSI X9.23 Padding -*/ -class BOTAN_DLL ANSI_X923_Padding : public BlockCipherModePaddingMethod - { - public: - void pad(byte[], size_t, size_t) const; - size_t unpad(const byte[], size_t) const; - bool valid_blocksize(size_t) const; - std::string name() const { return "X9.23"; } - }; - -/** -* One And Zeros Padding -*/ -class BOTAN_DLL OneAndZeros_Padding : public BlockCipherModePaddingMethod - { - public: - void pad(byte[], size_t, size_t) const; - size_t unpad(const byte[], size_t) const; - bool valid_blocksize(size_t) const; - std::string name() const { return "OneAndZeros"; } - }; - -/** -* Null Padding -*/ -class BOTAN_DLL Null_Padding : public BlockCipherModePaddingMethod - { - public: - void pad(byte[], size_t, size_t) const { return; } - size_t unpad(const byte[], size_t size) const { return size; } - size_t pad_bytes(size_t, size_t) const { return 0; } - bool valid_blocksize(size_t) const { return true; } - std::string name() const { return "NoPadding"; } - }; - -} - - -namespace Botan { - -/** -* Key Derivation Function -*/ -class BOTAN_DLL KDF : public Algorithm - { - public: - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param salt a diversifier - */ - SecureVector<byte> derive_key(size_t key_len, - const MemoryRegion<byte>& secret, - const std::string& salt = "") const; - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param salt a diversifier - */ - SecureVector<byte> derive_key(size_t key_len, - const MemoryRegion<byte>& secret, - const MemoryRegion<byte>& salt) const; - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param salt a diversifier - * @param salt_len size of salt in bytes - */ - SecureVector<byte> derive_key(size_t key_len, - const MemoryRegion<byte>& secret, - const byte salt[], - size_t salt_len) const; - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param secret_len size of secret in bytes - * @param salt a diversifier - */ - SecureVector<byte> derive_key(size_t key_len, - const byte secret[], - size_t secret_len, - const std::string& salt = "") const; - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param secret_len size of secret in bytes - * @param salt a diversifier - * @param salt_len size of salt in bytes - */ - SecureVector<byte> derive_key(size_t key_len, - const byte secret[], - size_t secret_len, - const byte salt[], - size_t salt_len) const; - - void clear() {} - - virtual KDF* clone() const = 0; - private: - virtual SecureVector<byte> - derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte salt[], size_t salt_len) const = 0; - }; - -/** -* Mask Generation Function -*/ -class BOTAN_DLL MGF - { - public: - virtual void mask(const byte in[], size_t in_len, - byte out[], size_t out_len) const = 0; - - virtual ~MGF() {} - }; - -} - - -namespace Botan { - -/** -* Encoding Method for Encryption -*/ -class BOTAN_DLL EME - { - public: - /** - * Return the maximum input size in bytes we can support - * @param keybits the size of the key in bits - * @return upper bound of input in bytes - */ - virtual size_t maximum_input_size(size_t keybits) const = 0; - - /** - * Encode an input - * @param in the plaintext - * @param in_length length of plaintext in bytes - * @param key_length length of the key in bits - * @param rng a random number generator - * @return encoded plaintext - */ - SecureVector<byte> encode(const byte in[], - size_t in_length, - size_t key_length, - RandomNumberGenerator& rng) const; - - /** - * Encode an input - * @param in the plaintext - * @param key_length length of the key in bits - * @param rng a random number generator - * @return encoded plaintext - */ - SecureVector<byte> encode(const MemoryRegion<byte>& in, - size_t key_length, - RandomNumberGenerator& rng) const; - - /** - * Decode an input - * @param in the encoded plaintext - * @param in_length length of encoded plaintext in bytes - * @param key_length length of the key in bits - * @return plaintext - */ - SecureVector<byte> decode(const byte in[], - size_t in_length, - size_t key_length) const; - - /** - * Decode an input - * @param in the encoded plaintext - * @param key_length length of the key in bits - * @return plaintext - */ - SecureVector<byte> decode(const MemoryRegion<byte>& in, - size_t key_length) const; - - virtual ~EME() {} - private: - /** - * Encode an input - * @param in the plaintext - * @param in_length length of plaintext in bytes - * @param key_length length of the key in bits - * @param rng a random number generator - * @return encoded plaintext - */ - virtual SecureVector<byte> pad(const byte in[], - size_t in_length, - size_t key_length, - RandomNumberGenerator& rng) const = 0; - - /** - * Decode an input - * @param in the encoded plaintext - * @param in_length length of encoded plaintext in bytes - * @param key_length length of the key in bits - * @return plaintext - */ - virtual SecureVector<byte> unpad(const byte in[], - size_t in_length, - size_t key_length) const = 0; - }; - -} - - -namespace Botan { - -/** -* Retrieve an object prototype from the global factory -* @param algo_spec an algorithm name -* @return constant prototype object (use clone to create usable object), - library retains ownership -*/ -inline const BlockCipher* -retrieve_block_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.prototype_block_cipher(algo_spec); - } - -/** -* Retrieve an object prototype from the global factory -* @param algo_spec an algorithm name -* @return constant prototype object (use clone to create usable object), - library retains ownership -*/ -inline const StreamCipher* -retrieve_stream_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.prototype_stream_cipher(algo_spec); - } - -/** -* Retrieve an object prototype from the global factory -* @param algo_spec an algorithm name -* @return constant prototype object (use clone to create usable object), - library retains ownership -*/ -inline const HashFunction* -retrieve_hash(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.prototype_hash_function(algo_spec); - } - -/** -* Retrieve an object prototype from the global factory -* @param algo_spec an algorithm name -* @return constant prototype object (use clone to create usable object), - library retains ownership -*/ -inline const MessageAuthenticationCode* -retrieve_mac(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.prototype_mac(algo_spec); - } - -/* -* Get an algorithm object -* NOTE: these functions create and return new objects, letting the -* caller assume ownership of them -*/ - -/** -* Block cipher factory method. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the desired block cipher -* @return pointer to the block cipher object -*/ -inline BlockCipher* get_block_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.make_block_cipher(algo_spec); - } - -/** -* Stream cipher factory method. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the desired stream cipher -* @return pointer to the stream cipher object -*/ -inline StreamCipher* get_stream_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.make_stream_cipher(algo_spec); - } - -/** -* Hash function factory method. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the desired hash function -* @return pointer to the hash function object -*/ -inline HashFunction* get_hash(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.make_hash_function(algo_spec); - } - -/** -* MAC factory method. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the desired MAC -* @return pointer to the MAC object -*/ -inline MessageAuthenticationCode* get_mac(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.make_mac(algo_spec); - } - -/** -* Password based key derivation function factory method -* @param algo_spec the name of the desired PBKDF algorithm -* @return pointer to newly allocated object of that type -*/ -BOTAN_DLL PBKDF* get_pbkdf(const std::string& algo_spec); - -/** -* @deprecated Use get_pbkdf -* @param algo_spec the name of the desired algorithm -* @return pointer to newly allocated object of that type -*/ -inline PBKDF* get_s2k(const std::string& algo_spec) - { - return get_pbkdf(algo_spec); - } - -/* -* Get an EMSA/EME/KDF/MGF function -*/ -// NOTE: these functions create and return new objects, letting the -// caller assume ownership of them - -/** -* Factory method for EME (message-encoding methods for encryption) objects -* @param algo_spec the name of the EME to create -* @return pointer to newly allocated object of that type -*/ -BOTAN_DLL EME* get_eme(const std::string& algo_spec); - -/** -* Factory method for EMSA (message-encoding methods for signatures -* with appendix) objects -* @param algo_spec the name of the EME to create -* @return pointer to newly allocated object of that type -*/ -BOTAN_DLL EMSA* get_emsa(const std::string& algo_spec); - -/** -* Factory method for KDF (key derivation function) -* @param algo_spec the name of the KDF to create -* @return pointer to newly allocated object of that type -*/ -BOTAN_DLL KDF* get_kdf(const std::string& algo_spec); - -/* -* Get a cipher object -*/ - -/** -* Factory method for general symmetric cipher filters. -* @param algo_spec the name of the desired cipher -* @param key the key to be used for encryption/decryption performed by -* the filter -* @param iv the initialization vector to be used -* @param direction determines whether the filter will be an encrypting -* or decrypting filter -* @return pointer to newly allocated encryption or decryption filter -*/ -BOTAN_DLL Keyed_Filter* get_cipher(const std::string& algo_spec, - const SymmetricKey& key, - const InitializationVector& iv, - Cipher_Dir direction); - -/** -* Factory method for general symmetric cipher filters. -* @param algo_spec the name of the desired cipher -* @param key the key to be used for encryption/decryption performed by -* the filter -* @param direction determines whether the filter will be an encrypting -* or decrypting filter -* @return pointer to the encryption or decryption filter -*/ -BOTAN_DLL Keyed_Filter* get_cipher(const std::string& algo_spec, - const SymmetricKey& key, - Cipher_Dir direction); - -/** -* Factory method for general symmetric cipher filters. No key will be -* set in the filter. -* -* @param algo_spec the name of the desired cipher -* @param direction determines whether the filter will be an encrypting or -* decrypting filter -* @return pointer to the encryption or decryption filter -*/ -BOTAN_DLL Keyed_Filter* get_cipher(const std::string& algo_spec, - Cipher_Dir direction); - -/** -* Check if an algorithm exists. -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -BOTAN_DLL bool have_algorithm(const std::string& algo_spec); - -/** -* Check if a block cipher algorithm exists. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -inline bool have_block_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return (af.prototype_block_cipher(algo_spec) != 0); - } - -/** -* Check if a stream cipher algorithm exists. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -inline bool have_stream_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return (af.prototype_stream_cipher(algo_spec) != 0); - } - -/** -* Check if a hash algorithm exists. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -inline bool have_hash(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return (af.prototype_hash_function(algo_spec) != 0); - } - -/** -* Check if a MAC algorithm exists. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -inline bool have_mac(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return (af.prototype_mac(algo_spec) != 0); - } - -/* -* Query information about an algorithm -*/ - -/** -* Find out the block size of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return block size of the specified algorithm -*/ -BOTAN_DLL size_t block_size_of(const std::string& algo_spec); - -/** -* Find out the output length of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return output length of the specified algorithm -*/ -BOTAN_DLL size_t output_length_of(const std::string& algo_spec); - -/** -* Find out the minimum key size of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return minimum key length of the specified algorithm -*/ -BOTAN_DEPRECATED("Retrieve object you want and then call key_spec") -BOTAN_DLL size_t min_keylength_of(const std::string& algo_spec); - -/** -* Find out the maximum key size of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return maximum key length of the specified algorithm -*/ -BOTAN_DEPRECATED("Retrieve object you want and then call key_spec") -BOTAN_DLL size_t max_keylength_of(const std::string& algo_spec); - -/** -* Find out the size any valid key is a multiple of for a certain algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return size any valid key is a multiple of -*/ -BOTAN_DEPRECATED("Retrieve object you want and then call key_spec") -BOTAN_DLL size_t keylength_multiple_of(const std::string& algo_spec); - -} - - -namespace Botan { - -/* -* Get information describing the version -*/ - -/** -* Get a human-readable string identifying the version of Botan. -* No particular format should be assumed. -* @return version string -*/ -BOTAN_DLL std::string version_string(); - -/** -* Return the date this version of botan was released, in an integer of -* the form YYYYMMDD. For instance a version released on May 21, 2013 -* would return the integer 20130521. If the currently running version -* is not an official release, this function will return 0 instead. -* -* @return release date, or zero if unreleased -*/ -BOTAN_DLL u32bit version_datestamp(); - -/** -* Get the major version number. -* @return major version number -*/ -BOTAN_DLL u32bit version_major(); - -/** -* Get the minor version number. -* @return minor version number -*/ -BOTAN_DLL u32bit version_minor(); - -/** -* Get the patch number. -* @return patch number -*/ -BOTAN_DLL u32bit version_patch(); - -/* -* Macros for compile-time version checks -*/ -#define BOTAN_VERSION_CODE_FOR(a,b,c) ((a << 16) | (b << 8) | (c)) - -/** -* Compare using BOTAN_VERSION_CODE_FOR, as in -* # if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,8,0) -* # error "Botan version too old" -* # endif -*/ -#define BOTAN_VERSION_CODE BOTAN_VERSION_CODE_FOR(BOTAN_VERSION_MAJOR, \ - BOTAN_VERSION_MINOR, \ - BOTAN_VERSION_PATCH) - -} - - - -#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - -namespace Botan { - -/** -* An automatically seeded PRNG -*/ -class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator - { - public: - void randomize(byte out[], size_t len) - { rng->randomize(out, len); } - - bool is_seeded() const { return rng->is_seeded(); } - - void clear() { rng->clear(); } - - std::string name() const { return rng->name(); } - - void reseed(size_t poll_bits = 256) { rng->reseed(poll_bits); } - - void add_entropy_source(EntropySource* es) - { rng->add_entropy_source(es); } - - void add_entropy(const byte in[], size_t len) - { rng->add_entropy(in, len); } - - AutoSeeded_RNG() { rng = &global_state().global_rng(); } - private: - RandomNumberGenerator* rng; - }; - -} - -#endif - - -namespace Botan { - -/** -* PKCS #10 Certificate Request. -*/ -class BOTAN_DLL PKCS10_Request : public X509_Object - { - public: - /** - * Get the subject public key. - * @return subject public key - */ - Public_Key* subject_public_key() const; - - /** - * Get the raw DER encoded public key. - * @return raw DER encoded public key - */ - MemoryVector<byte> raw_public_key() const; - - /** - * Get the subject DN. - * @return subject DN - */ - X509_DN subject_dn() const; - - /** - * Get the subject alternative name. - * @return subject alternative name. - */ - AlternativeName subject_alt_name() const; - - /** - * Get the key constraints for the key associated with this - * PKCS#10 object. - * @return key constraints - */ - Key_Constraints constraints() const; - - /** - * Get the extendend key constraints (if any). - * @return extended key constraints - */ - std::vector<OID> ex_constraints() const; - - /** - * Find out whether this is a CA request. - * @result true if it is a CA request, false otherwise. - */ - bool is_CA() const; - - /** - * Return the constraint on the path length defined - * in the BasicConstraints extension. - * @return path limit - */ - u32bit path_limit() const; - - /** - * Get the challenge password for this request - * @return challenge password for this request - */ - std::string challenge_password() const; - - /** - * Create a PKCS#10 Request from a data source. - * @param source the data source providing the DER encoded request - */ - PKCS10_Request(DataSource& source); - - /** - * Create a PKCS#10 Request from a file. - * @param filename the name of the file containing the DER or PEM - * encoded request file - */ - PKCS10_Request(const std::string& filename); - private: - void force_decode(); - void handle_attribute(const Attribute&); - - Data_Store info; - }; - -} - - -namespace Botan { - -/** -* Options for X.509 certificates. -*/ -class BOTAN_DLL X509_Cert_Options - { - public: - /** - * the subject common name - */ - std::string common_name; - - /** - * the subject counry - */ - std::string country; - - /** - * the subject organization - */ - std::string organization; - - /** - * the subject organizational unit - */ - std::string org_unit; - - /** - * the subject locality - */ - std::string locality; - - /** - * the subject state - */ - std::string state; - - /** - * the subject serial number - */ - std::string serial_number; - - /** - * the subject email adress - */ - std::string email; - - /** - * the subject URI - */ - std::string uri; - - /** - * the subject IPv4 address - */ - std::string ip; - - /** - * the subject DNS - */ - std::string dns; - - /** - * the subject XMPP - */ - std::string xmpp; - - /** - * the subject challenge password - */ - std::string challenge; - - /** - * the subject notBefore - */ - X509_Time start; - /** - * the subject notAfter - */ - X509_Time end; - - /** - * Indicates whether the certificate request - */ - bool is_CA; - - /** - * Indicates the BasicConstraints path limit - */ - size_t path_limit; - - /** - * The key constraints for the subject public key - */ - Key_Constraints constraints; - - /** - * The key extended constraints for the subject public key - */ - std::vector<OID> ex_constraints; - - /** - * Check the options set in this object for validity. - */ - void sanity_check() const; - - /** - * Mark the certificate as a CA certificate and set the path limit. - * @param limit the path limit to be set in the BasicConstraints extension. - */ - void CA_key(size_t limit = 1); - - /** - * Set the notBefore of the certificate. - * @param time the notBefore value of the certificate - */ - void not_before(const std::string& time); - - /** - * Set the notAfter of the certificate. - * @param time the notAfter value of the certificate - */ - void not_after(const std::string& time); - - /** - * Add the key constraints of the KeyUsage extension. - * @param constr the constraints to set - */ - void add_constraints(Key_Constraints constr); - - /** - * Add constraints to the ExtendedKeyUsage extension. - * @param oid the oid to add - */ - void add_ex_constraint(const OID& oid); - - /** - * Add constraints to the ExtendedKeyUsage extension. - * @param name the name to look up the oid to add - */ - void add_ex_constraint(const std::string& name); - - /** - * Construct a new options object - * @param opts define the common name of this object. An example for this - * parameter would be "common_name/country/organization/organizational_unit". - * @param expire_time the expiration time (from the current clock in seconds) - */ - X509_Cert_Options(const std::string& opts = "", - u32bit expire_time = 365 * 24 * 60 * 60); - }; - -namespace X509 { - -/** -* Create a self-signed X.509 certificate. -* @param opts the options defining the certificate to create -* @param key the private key used for signing, i.e. the key -* associated with this self-signed certificate -* @param hash_fn the hash function to use -* @param rng the rng to use -* @return newly created self-signed certificate -*/ -BOTAN_DLL X509_Certificate -create_self_signed_cert(const X509_Cert_Options& opts, - const Private_Key& key, - const std::string& hash_fn, - RandomNumberGenerator& rng); - -/** -* Create a PKCS#10 certificate request. -* @param opts the options defining the request to create -* @param key the key used to sign this request -* @param rng the rng to use -* @param hash_fn the hash function to use -* @return newly created PKCS#10 request -*/ -BOTAN_DLL PKCS10_Request create_cert_req(const X509_Cert_Options& opts, - const Private_Key& key, - const std::string& hash_fn, - RandomNumberGenerator& rng); - -} - -} - - -namespace Botan { - -class BigInt; -class ASN1_Object; - -/** -* General DER Encoding Object -*/ -class BOTAN_DLL DER_Encoder - { - public: - SecureVector<byte> get_contents(); - - DER_Encoder& start_cons(ASN1_Tag type_tag, - ASN1_Tag class_tag = UNIVERSAL); - DER_Encoder& end_cons(); - - DER_Encoder& start_explicit(u16bit type_tag); - DER_Encoder& end_explicit(); - - DER_Encoder& raw_bytes(const byte val[], size_t len); - DER_Encoder& raw_bytes(const MemoryRegion<byte>& val); - - DER_Encoder& encode_null(); - DER_Encoder& encode(bool b); - DER_Encoder& encode(size_t s); - DER_Encoder& encode(const BigInt& n); - DER_Encoder& encode(const MemoryRegion<byte>& v, ASN1_Tag real_type); - DER_Encoder& encode(const byte val[], size_t len, ASN1_Tag real_type); - - DER_Encoder& encode(bool b, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - DER_Encoder& encode(size_t s, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - DER_Encoder& encode(const BigInt& n, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - DER_Encoder& encode(const MemoryRegion<byte>& v, - ASN1_Tag real_type, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - DER_Encoder& encode(const byte v[], size_t len, - ASN1_Tag real_type, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - template<typename T> - DER_Encoder& encode_optional(const T& value, const T& default_value) - { - if(value != default_value) - encode(value); - return (*this); - } - - template<typename T> - DER_Encoder& encode_list(const std::vector<T>& values) - { - for(size_t i = 0; i != values.size(); ++i) - encode(values[i]); - return (*this); - } - - DER_Encoder& encode(const ASN1_Object& obj); - DER_Encoder& encode_if(bool pred, DER_Encoder& enc); - - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const byte rep[], size_t length); - - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const MemoryRegion<byte>& rep); - - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const std::string& str); - - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - byte val); - - private: - class DER_Sequence - { - public: - ASN1_Tag tag_of() const; - SecureVector<byte> get_contents(); - void add_bytes(const byte[], size_t); - DER_Sequence(ASN1_Tag, ASN1_Tag); - private: - ASN1_Tag type_tag, class_tag; - SecureVector<byte> contents; - std::vector< SecureVector<byte> > set_contents; - }; - - SecureVector<byte> contents; - std::vector<DER_Sequence> subsequences; - }; - -} - - -namespace Botan { - -/** -* EME1, aka OAEP -*/ -class BOTAN_DLL EME1 : public EME - { - public: - size_t maximum_input_size(size_t) const; - - /** - * @param hash object to use for hashing (takes ownership) - * @param P an optional label. Normally empty. - */ - EME1(HashFunction* hash, const std::string& P = ""); - - ~EME1() { delete mgf; } - private: - SecureVector<byte> pad(const byte[], size_t, size_t, - RandomNumberGenerator&) const; - SecureVector<byte> unpad(const byte[], size_t, size_t) const; - - SecureVector<byte> Phash; - MGF* mgf; - }; - -} - - -namespace Botan { - -/** -* The two types of signature format supported by Botan. -*/ -enum Signature_Format { IEEE_1363, DER_SEQUENCE }; - -/** -* Enum marking if protection against fault attacks should be used -*/ -enum Fault_Protection { - ENABLE_FAULT_PROTECTION, - DISABLE_FAULT_PROTECTION -}; - -/** -* Public Key Encryptor -*/ -class BOTAN_DLL PK_Encryptor - { - public: - - /** - * Encrypt a message. - * @param in the message as a byte array - * @param length the length of the above byte array - * @param rng the random number source to use - * @return encrypted message - */ - SecureVector<byte> encrypt(const byte in[], size_t length, - RandomNumberGenerator& rng) const - { - return enc(in, length, rng); - } - - /** - * Encrypt a message. - * @param in the message - * @param rng the random number source to use - * @return encrypted message - */ - SecureVector<byte> encrypt(const MemoryRegion<byte>& in, - RandomNumberGenerator& rng) const - { - return enc(&in[0], in.size(), rng); - } - - /** - * Return the maximum allowed message size in bytes. - * @return maximum message size in bytes - */ - virtual size_t maximum_input_size() const = 0; - - PK_Encryptor() {} - virtual ~PK_Encryptor() {} - private: - PK_Encryptor(const PK_Encryptor&) {} - PK_Encryptor& operator=(const PK_Encryptor&) { return *this; } - - virtual SecureVector<byte> enc(const byte[], size_t, - RandomNumberGenerator&) const = 0; - }; - -/** -* Public Key Decryptor -*/ -class BOTAN_DLL PK_Decryptor - { - public: - /** - * Decrypt a ciphertext. - * @param in the ciphertext as a byte array - * @param length the length of the above byte array - * @return decrypted message - */ - SecureVector<byte> decrypt(const byte in[], size_t length) const - { - return dec(in, length); - } - - /** - * Decrypt a ciphertext. - * @param in the ciphertext - * @return decrypted message - */ - SecureVector<byte> decrypt(const MemoryRegion<byte>& in) const - { - return dec(&in[0], in.size()); - } - - PK_Decryptor() {} - virtual ~PK_Decryptor() {} - private: - PK_Decryptor(const PK_Decryptor&) {} - PK_Decryptor& operator=(const PK_Decryptor&) { return *this; } - - virtual SecureVector<byte> dec(const byte[], size_t) const = 0; - }; - -/** -* Public Key Signer. Use the sign_message() functions for small -* messages. Use multiple calls update() to process large messages and -* generate the signature by finally calling signature(). -*/ -class BOTAN_DLL PK_Signer - { - public: - /** - * Sign a message. - * @param in the message to sign as a byte array - * @param length the length of the above byte array - * @param rng the rng to use - * @return signature - */ - SecureVector<byte> sign_message(const byte in[], size_t length, - RandomNumberGenerator& rng); - - /** - * Sign a message. - * @param in the message to sign - * @param rng the rng to use - * @return signature - */ - SecureVector<byte> sign_message(const MemoryRegion<byte>& in, - RandomNumberGenerator& rng) - { return sign_message(&in[0], in.size(), rng); } - - /** - * Add a message part (single byte). - * @param in the byte to add - */ - void update(byte in) { update(&in, 1); } - - /** - * Add a message part. - * @param in the message part to add as a byte array - * @param length the length of the above byte array - */ - void update(const byte in[], size_t length); - - /** - * Add a message part. - * @param in the message part to add - */ - void update(const MemoryRegion<byte>& in) { update(&in[0], in.size()); } - - /** - * Get the signature of the so far processed message (provided by the - * calls to update()). - * @param rng the rng to use - * @return signature of the total message - */ - SecureVector<byte> signature(RandomNumberGenerator& rng); - - /** - * Set the output format of the signature. - * @param format the signature format to use - */ - void set_output_format(Signature_Format format) { sig_format = format; } - - /** - * Construct a PK Signer. - * @param key the key to use inside this signer - * @param emsa the EMSA to use - * An example would be "EMSA1(SHA-224)". - * @param format the signature format to use - * @param prot says if fault protection should be enabled - */ - PK_Signer(const Private_Key& key, - const std::string& emsa, - Signature_Format format = IEEE_1363, - Fault_Protection prot = ENABLE_FAULT_PROTECTION); - - ~PK_Signer() { delete op; delete verify_op; delete emsa; } - private: - bool self_test_signature(const MemoryRegion<byte>& msg, - const MemoryRegion<byte>& sig) const; - - PK_Signer(const PK_Signer&) {} - PK_Signer& operator=(const PK_Signer&) { return *this; } - - PK_Ops::Signature* op; - PK_Ops::Verification* verify_op; - EMSA* emsa; - Signature_Format sig_format; - }; - -/** -* Public Key Verifier. Use the verify_message() functions for small -* messages. Use multiple calls update() to process large messages and -* verify the signature by finally calling check_signature(). -*/ -class BOTAN_DLL PK_Verifier - { - public: - /** - * Verify a signature. - * @param msg the message that the signature belongs to, as a byte array - * @param msg_length the length of the above byte array msg - * @param sig the signature as a byte array - * @param sig_length the length of the above byte array sig - * @return true if the signature is valid - */ - bool verify_message(const byte msg[], size_t msg_length, - const byte sig[], size_t sig_length); - /** - * Verify a signature. - * @param msg the message that the signature belongs to - * @param sig the signature - * @return true if the signature is valid - */ - bool verify_message(const MemoryRegion<byte>& msg, - const MemoryRegion<byte>& sig) - { - return verify_message(&msg[0], msg.size(), - &sig[0], sig.size()); - } - - /** - * Add a message part (single byte) of the message corresponding to the - * signature to be verified. - * @param in the byte to add - */ - void update(byte in) { update(&in, 1); } - - /** - * Add a message part of the message corresponding to the - * signature to be verified. - * @param msg_part the new message part as a byte array - * @param length the length of the above byte array - */ - void update(const byte msg_part[], size_t length); - - /** - * Add a message part of the message corresponding to the - * signature to be verified. - * @param in the new message part - */ - void update(const MemoryRegion<byte>& in) - { update(&in[0], in.size()); } - - /** - * Check the signature of the buffered message, i.e. the one build - * by successive calls to update. - * @param sig the signature to be verified as a byte array - * @param length the length of the above byte array - * @return true if the signature is valid, false otherwise - */ - bool check_signature(const byte sig[], size_t length); - - /** - * Check the signature of the buffered message, i.e. the one build - * by successive calls to update. - * @param sig the signature to be verified - * @return true if the signature is valid, false otherwise - */ - bool check_signature(const MemoryRegion<byte>& sig) - { - return check_signature(&sig[0], sig.size()); - } - - /** - * Set the format of the signatures fed to this verifier. - * @param format the signature format to use - */ - void set_input_format(Signature_Format format); - - /** - * Construct a PK Verifier. - * @param pub_key the public key to verify against - * @param emsa the EMSA to use (eg "EMSA3(SHA-1)") - * @param format the signature format to use - */ - PK_Verifier(const Public_Key& pub_key, - const std::string& emsa, - Signature_Format format = IEEE_1363); - - ~PK_Verifier() { delete op; delete emsa; } - private: - PK_Verifier(const PK_Verifier&) {} - PK_Verifier& operator=(const PK_Verifier&) { return *this; } - - bool validate_signature(const MemoryRegion<byte>& msg, - const byte sig[], size_t sig_len); - - PK_Ops::Verification* op; - EMSA* emsa; - Signature_Format sig_format; - }; - -/** -* Key used for key agreement -*/ -class BOTAN_DLL PK_Key_Agreement - { - public: - - /* - * Perform Key Agreement Operation - * @param key_len the desired key output size - * @param in the other parties key - * @param in_len the length of in in bytes - * @param params extra derivation params - * @param params_len the length of params in bytes - */ - SymmetricKey derive_key(size_t key_len, - const byte in[], - size_t in_len, - const byte params[], - size_t params_len) const; - - /* - * Perform Key Agreement Operation - * @param key_len the desired key output size - * @param in the other parties key - * @param in_len the length of in in bytes - * @param params extra derivation params - * @param params_len the length of params in bytes - */ - SymmetricKey derive_key(size_t key_len, - const MemoryRegion<byte>& in, - const byte params[], - size_t params_len) const - { - return derive_key(key_len, &in[0], in.size(), - params, params_len); - } - - /* - * Perform Key Agreement Operation - * @param key_len the desired key output size - * @param in the other parties key - * @param in_len the length of in in bytes - * @param params extra derivation params - */ - SymmetricKey derive_key(size_t key_len, - const byte in[], size_t in_len, - const std::string& params = "") const - { - return derive_key(key_len, in, in_len, - reinterpret_cast<const byte*>(params.data()), - params.length()); - } - - /* - * Perform Key Agreement Operation - * @param key_len the desired key output size - * @param in the other parties key - * @param params extra derivation params - */ - SymmetricKey derive_key(size_t key_len, - const MemoryRegion<byte>& in, - const std::string& params = "") const - { - return derive_key(key_len, &in[0], in.size(), - reinterpret_cast<const byte*>(params.data()), - params.length()); - } - - /** - * Construct a PK Key Agreement. - * @param key the key to use - * @param kdf name of the KDF to use (or 'Raw' for no KDF) - */ - PK_Key_Agreement(const PK_Key_Agreement_Key& key, - const std::string& kdf); - - ~PK_Key_Agreement() { delete op; delete kdf; } - private: - PK_Key_Agreement(const PK_Key_Agreement_Key&) {} - PK_Key_Agreement& operator=(const PK_Key_Agreement&) { return *this; } - - PK_Ops::Key_Agreement* op; - KDF* kdf; - }; - -/** -* Encryption with an MR algorithm and an EME. -*/ -class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor - { - public: - size_t maximum_input_size() const; - - /** - * Construct an instance. - * @param key the key to use inside the decryptor - * @param eme the EME to use - */ - PK_Encryptor_EME(const Public_Key& key, - const std::string& eme); - - ~PK_Encryptor_EME() { delete op; delete eme; } - private: - SecureVector<byte> enc(const byte[], size_t, - RandomNumberGenerator& rng) const; - - PK_Ops::Encryption* op; - const EME* eme; - }; - -/** -* Decryption with an MR algorithm and an EME. -*/ -class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor - { - public: - /** - * Construct an instance. - * @param key the key to use inside the encryptor - * @param eme the EME to use - */ - PK_Decryptor_EME(const Private_Key& key, - const std::string& eme); - - ~PK_Decryptor_EME() { delete op; delete eme; } - private: - SecureVector<byte> dec(const byte[], size_t) const; - - PK_Ops::Decryption* op; - const EME* eme; - }; - -/* -* Typedefs for compatability with 1.8 -*/ -typedef PK_Encryptor_EME PK_Encryptor_MR_with_EME; -typedef PK_Decryptor_EME PK_Decryptor_MR_with_EME; - -} - - -namespace Botan { - -/** -* DES -*/ -class BOTAN_DLL DES : public Block_Cipher_Fixed_Params<8, 8> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(round_key); } - std::string name() const { return "DES"; } - BlockCipher* clone() const { return new DES; } - - DES() : round_key(32) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector<u32bit> round_key; - }; - -/** -* Triple DES -*/ -class BOTAN_DLL TripleDES : public Block_Cipher_Fixed_Params<8, 16, 24, 8> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(round_key); } - std::string name() const { return "TripleDES"; } - BlockCipher* clone() const { return new TripleDES; } - - TripleDES() : round_key(96) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector<u32bit> round_key; - }; - -/* -* DES Tables -*/ -extern const u32bit DES_SPBOX1[256]; -extern const u32bit DES_SPBOX2[256]; -extern const u32bit DES_SPBOX3[256]; -extern const u32bit DES_SPBOX4[256]; -extern const u32bit DES_SPBOX5[256]; -extern const u32bit DES_SPBOX6[256]; -extern const u32bit DES_SPBOX7[256]; -extern const u32bit DES_SPBOX8[256]; - -extern const u64bit DES_IPTAB1[256]; -extern const u64bit DES_IPTAB2[256]; -extern const u64bit DES_FPTAB1[256]; -extern const u64bit DES_FPTAB2[256]; - -} - - -namespace Botan { - -/** -* DESX -*/ -class BOTAN_DLL DESX : public Block_Cipher_Fixed_Params<8, 24> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { des.clear(); zeroise(K1); zeroise(K2); } - std::string name() const { return "DESX"; } - BlockCipher* clone() const { return new DESX; } - - DESX() : K1(8), K2(8) {} - private: - void key_schedule(const byte[], size_t); - SecureVector<byte> K1, K2; - DES des; - }; - -} - - -namespace Botan { - -/** -* The GOST 28147-89 block cipher uses a set of 4 bit Sboxes, however -* the standard does not actually define these Sboxes; they are -* considered a local configuration issue. Several different sets are -* used. -*/ -class BOTAN_DLL GOST_28147_89_Params - { - public: - /** - * @param row the row - * @param col the column - * @return sbox entry at this row/column - */ - byte sbox_entry(size_t row, size_t col) const; - - /** - * @return name of this parameter set - */ - std::string param_name() const { return name; } - - /** - * Default GOST parameters are the ones given in GOST R 34.11 for - * testing purposes; these sboxes are also used by Crypto++, and, - * at least according to Wikipedia, the Central Bank of Russian - * Federation - * @param name of the parameter set - */ - GOST_28147_89_Params(const std::string& name = "R3411_94_TestParam"); - private: - const byte* sboxes; - std::string name; - }; - -/** -* GOST 28147-89 -*/ -class BOTAN_DLL GOST_28147_89 : public Block_Cipher_Fixed_Params<8, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - - std::string name() const; - BlockCipher* clone() const { return new GOST_28147_89(SBOX); } - - /** - * @param params the sbox parameters to use - */ - GOST_28147_89(const GOST_28147_89_Params& params); - private: - GOST_28147_89(const SecureVector<u32bit>& other_SBOX) : - SBOX(other_SBOX), EK(8) {} - - void key_schedule(const byte[], size_t); - - SecureVector<u32bit> SBOX; - SecureVector<u32bit> EK; - }; - -} - - -namespace Botan { - -/** -* GOST 34.11 -*/ -class BOTAN_DLL GOST_34_11 : public HashFunction - { - public: - std::string name() const { return "GOST-R-34.11-94" ; } - size_t output_length() const { return 32; } - size_t hash_block_size() const { return 32; } - HashFunction* clone() const { return new GOST_34_11; } - - void clear(); - - GOST_34_11(); - private: - void compress_n(const byte input[], size_t blocks); - - void add_data(const byte[], size_t); - void final_result(byte[]); - - GOST_28147_89 cipher; - SecureVector<byte> buffer, sum, hash; - size_t position; - u64bit count; - }; - -} - - -namespace Botan { - -/** -* SHA-384 -*/ -class BOTAN_DLL SHA_384 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-384"; } - size_t output_length() const { return 48; } - HashFunction* clone() const { return new SHA_384; } - - void clear(); - - SHA_384() : MDx_HashFunction(128, true, true, 16), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector<u64bit> digest; - }; - -/** -* SHA-512 -*/ -class BOTAN_DLL SHA_512 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-512"; } - size_t output_length() const { return 64; } - HashFunction* clone() const { return new SHA_512; } - - void clear(); - - SHA_512() : MDx_HashFunction(128, true, true, 16), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector<u64bit> digest; - }; - -} - - -namespace Botan { - -/** -* Password Based Encryption (PBE) Filter. -*/ -class BOTAN_DLL PBE : public Filter - { - public: - /** - * Set this filter's key. - * @param pw the password to be used for the encryption - */ - virtual void set_key(const std::string& pw) = 0; - - /** - * Create a new random salt value and set the default iterations value. - * @param rng a random number generator - */ - virtual void new_params(RandomNumberGenerator& rng) = 0; - - /** - * DER encode the params (the number of iterations and the salt value) - * @return encoded params - */ - virtual MemoryVector<byte> encode_params() const = 0; - - /** - * Decode params and use them inside this Filter. - * @param src a data source to read the encoded params from - */ - virtual void decode_params(DataSource& src) = 0; - - /** - * Get this PBE's OID. - * @return object identifier - */ - virtual OID get_oid() const = 0; - }; - -} - - -namespace Botan { - -/** -* KDF1, from IEEE 1363 -*/ -class BOTAN_DLL KDF1 : public KDF - { - public: - SecureVector<byte> derive(size_t, - const byte secret[], size_t secret_len, - const byte P[], size_t P_len) const; - - std::string name() const { return "KDF1(" + hash->name() + ")"; } - KDF* clone() const { return new KDF1(hash->clone()); } - - KDF1(HashFunction* h) : hash(h) {} - KDF1(const KDF1& other) : KDF(), hash(other.hash->clone()) {} - - ~KDF1() { delete hash; } - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* MISTY1 -*/ -class BOTAN_DLL MISTY1 : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); zeroise(DK); } - std::string name() const { return "MISTY1"; } - BlockCipher* clone() const { return new MISTY1; } - - /** - * @param rounds the number of rounds. Must be 8 with the current - * implementation - */ - MISTY1(size_t rounds = 8); - private: - void key_schedule(const byte[], size_t); - - SecureVector<u16bit> EK, DK; - }; - -} - - -namespace Botan { - -/** -* 32-bit cyclic redundancy check -*/ -class BOTAN_DLL CRC32 : public HashFunction - { - public: - std::string name() const { return "CRC32"; } - size_t output_length() const { return 4; } - HashFunction* clone() const { return new CRC32; } - - void clear() { crc = 0xFFFFFFFF; } - - CRC32() { clear(); } - ~CRC32() { clear(); } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - u32bit crc; - }; - -} - - -namespace Botan { - -namespace PEM_Code { - -/* -* PEM Encoding/Decoding -*/ -BOTAN_DLL std::string encode(const byte[], size_t, - const std::string&, size_t = 64); -BOTAN_DLL std::string encode(const MemoryRegion<byte>&, - const std::string&, size_t = 64); - -BOTAN_DLL SecureVector<byte> decode(DataSource&, std::string&); -BOTAN_DLL SecureVector<byte> decode_check_label(DataSource&, - const std::string&); -BOTAN_DLL bool matches(DataSource&, const std::string& = "", - size_t search_range = 4096); - -} - -} - - -namespace Botan { - -/** -* XTEA -*/ -class BOTAN_DLL XTEA : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - std::string name() const { return "XTEA"; } - BlockCipher* clone() const { return new XTEA; } - - XTEA() : EK(64) {} - protected: - /** - * @return const reference to the key schedule - */ - const SecureVector<u32bit>& get_EK() const { return EK; } - - private: - void key_schedule(const byte[], size_t); - SecureVector<u32bit> EK; - }; - -} - - -namespace Botan { - -/** -* KASUMI, the block cipher used in 3G telephony -*/ -class BOTAN_DLL KASUMI : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - std::string name() const { return "KASUMI"; } - BlockCipher* clone() const { return new KASUMI; } - - KASUMI() : EK(64) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector<u16bit> EK; - }; - -} - - -namespace Botan { - -/** -* This class represents discrete logarithm groups. It holds a prime p, -* a prime q = (p-1)/2 and g = x^((p-1)/q) mod p. -*/ -class BOTAN_DLL DL_Group - { - public: - /** - * Get the prime p. - * @return prime p - */ - const BigInt& get_p() const; - - /** - * Get the prime q. - * @return prime q - */ - const BigInt& get_q() const; - - /** - * Get the base g. - * @return base g - */ - const BigInt& get_g() const; - - /** - * The DL group encoding format variants. - */ - enum Format { - ANSI_X9_42, - ANSI_X9_57, - PKCS_3, - - DSA_PARAMETERS = ANSI_X9_57, - DH_PARAMETERS = ANSI_X9_42, - X942_DH_PARAMETERS = ANSI_X9_42, - PKCS3_DH_PARAMETERS = PKCS_3 - }; - - /** - * Determine the prime creation for DL groups. - */ - enum PrimeType { Strong, Prime_Subgroup, DSA_Kosherizer }; - - /** - * Perform validity checks on the group. - * @param rng the rng to use - * @param strong whether to perform stronger by lengthier tests - * @return true if the object is consistent, false otherwise - */ - bool verify_group(RandomNumberGenerator& rng, bool strong) const; - - /** - * Encode this group into a string using PEM encoding. - * @param format the encoding format - * @return string holding the PEM encoded group - */ - std::string PEM_encode(Format format) const; - - /** - * Encode this group into a string using DER encoding. - * @param format the encoding format - * @return string holding the DER encoded group - */ - SecureVector<byte> DER_encode(Format format) const; - - /** - * Decode a DER/BER encoded group into this instance. - * @param src a DataSource providing the encoded group - * @param format the format of the encoded group - */ - void BER_decode(DataSource& src, Format format); - - /** - * Decode a PEM encoded group into this instance. - * @param src a DataSource providing the encoded group - */ - void PEM_decode(DataSource& src); - - /** - * Construct a DL group with uninitialized internal value. - * Use this constructor is you wish to set the groups values - * from a DER or PEM encoded group. - */ - DL_Group(); - - /** - * Construct a DL group that is registered in the configuration. - * @param name the name that is configured in the global configuration - * for the desired group. If no configuration file is specified, - * the default values from the file policy.cpp will be used. For instance, - * use "modp/ietf/768" as name. - */ - DL_Group(const std::string& name); - - /** - * Create a new group randomly. - * @param rng the random number generator to use - * @param type specifies how the creation of primes p and q shall - * be performed. If type=Strong, then p will be determined as a - * safe prime, and q will be chosen as (p-1)/2. If - * type=Prime_Subgroup and qbits = 0, then the size of q will be - * determined according to the estimated difficulty of the DL - * problem. If type=DSA_Kosherizer, DSA primes will be created. - * @param pbits the number of bits of p - * @param qbits the number of bits of q. Leave it as 0 to have - * the value determined according to pbits. - */ - DL_Group(RandomNumberGenerator& rng, PrimeType type, - size_t pbits, size_t qbits = 0); - - /** - * Create a DSA group with a given seed. - * @param rng the random number generator to use - * @param seed the seed to use to create the random primes - * @param pbits the desired bit size of the prime p - * @param qbits the desired bit size of the prime q. - */ - DL_Group(RandomNumberGenerator& rng, const MemoryRegion<byte>& seed, - size_t pbits = 1024, size_t qbits = 0); - - /** - * Create a DL group. The prime q will be determined according to p. - * @param p the prime p - * @param g the base g - */ - DL_Group(const BigInt& p, const BigInt& g); - - /** - * Create a DL group. - * @param p the prime p - * @param q the prime q - * @param g the base g - */ - DL_Group(const BigInt& p, const BigInt& q, const BigInt& g); - private: - static BigInt make_dsa_generator(const BigInt&, const BigInt&); - - void init_check() const; - void initialize(const BigInt&, const BigInt&, const BigInt&); - bool initialized; - BigInt p, q, g; - }; - -} - - -namespace Botan { - -/** -* This class represents discrete logarithm (DL) public keys. -*/ -class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - AlgorithmIdentifier algorithm_identifier() const; - - MemoryVector<byte> x509_subject_public_key() const; - - /** - * Get the DL domain parameters of this key. - * @return DL domain parameters of this key - */ - const DL_Group& get_domain() const { return group; } - - /** - * Get the public value y with y = g^x mod p where x is the secret key. - */ - const BigInt& get_y() const { return y; } - - /** - * Get the prime p of the underlying DL group. - * @return prime p - */ - const BigInt& group_p() const { return group.get_p(); } - - /** - * Get the prime q of the underlying DL group. - * @return prime q - */ - const BigInt& group_q() const { return group.get_q(); } - - /** - * Get the generator g of the underlying DL group. - * @return generator g - */ - const BigInt& group_g() const { return group.get_g(); } - - /** - * Get the underlying groups encoding format. - * @return encoding format - */ - virtual DL_Group::Format group_format() const = 0; - - DL_Scheme_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits, - DL_Group::Format group_format); - - protected: - DL_Scheme_PublicKey() {} - - /** - * The DL public key - */ - BigInt y; - - /** - * The DL group - */ - DL_Group group; - }; - -/** -* This class represents discrete logarithm (DL) private keys. -*/ -class BOTAN_DLL DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey, - public virtual Private_Key - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - /** - * Get the secret key x. - * @return secret key - */ - const BigInt& get_x() const { return x; } - - MemoryVector<byte> pkcs8_private_key() const; - - DL_Scheme_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits, - DL_Group::Format group_format); - - protected: - DL_Scheme_PrivateKey() {} - - /** - * The DL private key - */ - BigInt x; - }; - -} - - -namespace Botan { - -/** -* Modular Reducer (using Barrett's technique) -*/ -class BOTAN_DLL Modular_Reducer - { - public: - const BigInt& get_modulus() const { return modulus; } - - BigInt reduce(const BigInt& x) const; - - /** - * Multiply mod p - * @param x - * @param y - * @return (x * y) % p - */ - BigInt multiply(const BigInt& x, const BigInt& y) const - { return reduce(x * y); } - - /** - * Square mod p - * @param x - * @return (x * x) % p - */ - BigInt square(const BigInt& x) const - { return reduce(Botan::square(x)); } - - /** - * Cube mod p - * @param x - * @return (x * x * x) % p - */ - BigInt cube(const BigInt& x) const - { return multiply(x, this->square(x)); } - - bool initialized() const { return (mod_words != 0); } - - Modular_Reducer() { mod_words = 0; } - Modular_Reducer(const BigInt& mod); - private: - BigInt modulus, modulus_2, mu; - size_t mod_words; - }; - -} - - -namespace Botan { - -/** -* Blinding Function Object -*/ -class BOTAN_DLL Blinder - { - public: - BigInt blind(const BigInt& x) const; - BigInt unblind(const BigInt& x) const; - - bool initialized() const { return reducer.initialized(); } - - Blinder() {} - - /** - * Construct a blinder - * @param mask the forward (blinding) mask - * @param inverse_mask the inverse of mask (depends on algo) - * @param modulus of the group operations are performed in - */ - Blinder(const BigInt& mask, - const BigInt& inverse_mask, - const BigInt& modulus); - - private: - Modular_Reducer reducer; - mutable BigInt e, d; - }; - -} - - -namespace Botan { - -/** -* This class represents Diffie-Hellman public keys. -*/ -class BOTAN_DLL DH_PublicKey : public virtual DL_Scheme_PublicKey - { - public: - std::string algo_name() const { return "DH"; } - - MemoryVector<byte> public_value() const; - size_t max_input_bits() const { return group_p().bits(); } - - DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; } - - DH_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_42) {} - - /** - * Construct a public key with the specified parameters. - * @param grp the DL group to use in the key - * @param y the public value y - */ - DH_PublicKey(const DL_Group& grp, const BigInt& y); - protected: - DH_PublicKey() {} - }; - -/** -* This class represents Diffie-Hellman private keys. -*/ -class BOTAN_DLL DH_PrivateKey : public DH_PublicKey, - public PK_Key_Agreement_Key, - public virtual DL_Scheme_PrivateKey - { - public: - MemoryVector<byte> public_value() const; - - /** - * Load a DH private key - * @param alg_id the algorithm id - * @param key_bits the subject public key - * @param rng a random number generator - */ - DH_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits, - RandomNumberGenerator& rng); - - /** - * Construct a private key with predetermined value. - * @param rng random number generator to use - * @param grp the group to be used in the key - * @param x the key's secret value (or if zero, generate a new key) - */ - DH_PrivateKey(RandomNumberGenerator& rng, const DL_Group& grp, - const BigInt& x = 0); - }; - -/** -* DH operation -*/ -class BOTAN_DLL DH_KA_Operation : public PK_Ops::Key_Agreement - { - public: - DH_KA_Operation(const DH_PrivateKey& key); - - SecureVector<byte> agree(const byte w[], size_t w_len); - private: - const BigInt& p; - - Fixed_Exponent_Power_Mod powermod_x_p; - Blinder blinder; - }; - -} - - -namespace Botan { - -/** -* CAST-256 -*/ -class BOTAN_DLL CAST_256 : public Block_Cipher_Fixed_Params<16, 4, 32, 4> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(MK); zeroise(RK); } - std::string name() const { return "CAST-256"; } - BlockCipher* clone() const { return new CAST_256; } - - CAST_256() : MK(48), RK(48) {} - private: - void key_schedule(const byte[], size_t); - - static const u32bit KEY_MASK[192]; - static const byte KEY_ROT[32]; - - SecureVector<u32bit> MK; - SecureVector<byte> RK; - }; - -extern const u32bit CAST_SBOX1[256]; -extern const u32bit CAST_SBOX2[256]; -extern const u32bit CAST_SBOX3[256]; -extern const u32bit CAST_SBOX4[256]; - -} - - -namespace Botan { - -/** -* MD2 -*/ -class BOTAN_DLL MD2 : public HashFunction - { - public: - std::string name() const { return "MD2"; } - size_t output_length() const { return 16; } - size_t hash_block_size() const { return 16; } - HashFunction* clone() const { return new MD2; } - - void clear(); - - MD2() : X(48), checksum(16), buffer(16) - { clear(); } - private: - void add_data(const byte[], size_t); - void hash(const byte[]); - void final_result(byte[]); - - SecureVector<byte> X, checksum, buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* RC6, Ron Rivest's AES candidate -*/ -class BOTAN_DLL RC6 : public Block_Cipher_Fixed_Params<16, 1, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(S); } - std::string name() const { return "RC6"; } - BlockCipher* clone() const { return new RC6; } - - RC6() : S(44) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector<u32bit> S; - }; - -} - - -namespace Botan { - -/** -* WiderWake4+1-BE -* -* Note: quite old and possibly not safe; use XSalsa20 or a block -* cipher in counter mode. -*/ -class BOTAN_DLL WiderWake_41_BE : public StreamCipher - { - public: - void cipher(const byte[], byte[], size_t); - void set_iv(const byte[], size_t); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == 8); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(16); - } - - void clear(); - std::string name() const { return "WiderWake4+1-BE"; } - StreamCipher* clone() const { return new WiderWake_41_BE; } - - WiderWake_41_BE() : T(256), state(5), t_key(4), - buffer(DEFAULT_BUFFERSIZE), position(0) - {} - - private: - void key_schedule(const byte[], size_t); - - void generate(size_t); - - SecureVector<u32bit> T; - SecureVector<u32bit> state; - SecureVector<u32bit> t_key; - SecureVector<byte> buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* ElGamal Public Key -*/ -class BOTAN_DLL ElGamal_PublicKey : public virtual DL_Scheme_PublicKey - { - public: - std::string algo_name() const { return "ElGamal"; } - DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; } - - size_t max_input_bits() const { return (group_p().bits() - 1); } - - ElGamal_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_42) - {} - - ElGamal_PublicKey(const DL_Group& group, const BigInt& y); - protected: - ElGamal_PublicKey() {} - }; - -/** -* ElGamal Private Key -*/ -class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey, - public virtual DL_Scheme_PrivateKey - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits, - RandomNumberGenerator& rng); - - ElGamal_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& group, - const BigInt& priv_key = 0); - }; - -/** -* ElGamal encryption operation -*/ -class BOTAN_DLL ElGamal_Encryption_Operation : public PK_Ops::Encryption - { - public: - size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; } - - ElGamal_Encryption_Operation(const ElGamal_PublicKey& key); - - SecureVector<byte> encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - private: - Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; - Modular_Reducer mod_p; - }; - -/** -* ElGamal decryption operation -*/ -class BOTAN_DLL ElGamal_Decryption_Operation : public PK_Ops::Decryption - { - public: - size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; } - - ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key); - - SecureVector<byte> decrypt(const byte msg[], size_t msg_len); - private: - Fixed_Exponent_Power_Mod powermod_x_p; - Modular_Reducer mod_p; - Blinder blinder; - }; - -} - - -namespace Botan { - -/** -HMAC_RNG - based on the design described in "On Extract-then-Expand -Key Derivation Functions and an HMAC-based KDF" by Hugo Krawczyk -(henceforce, 'E-t-E') - -However it actually can be parameterized with any two MAC functions, -not restricted to HMAC (this variation is also described in Krawczyk's -paper), for instance one could use HMAC(SHA-512) as the extractor -and CMAC(AES-256) as the PRF. -*/ -class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator - { - public: - void randomize(byte buf[], size_t len); - bool is_seeded() const { return seeded; } - void clear(); - std::string name() const; - - void reseed(size_t poll_bits); - void add_entropy_source(EntropySource* es); - void add_entropy(const byte[], size_t); - - /** - * @param extractor a MAC used for extracting the entropy - * @param prf a MAC used as a PRF using HKDF construction - */ - HMAC_RNG(MessageAuthenticationCode* extractor, - MessageAuthenticationCode* prf); - - ~HMAC_RNG(); - private: - MessageAuthenticationCode* extractor; - MessageAuthenticationCode* prf; - - std::vector<EntropySource*> entropy_sources; - bool seeded; - - SecureVector<byte> K, io_buffer; - size_t user_input_len; - u32bit counter; - }; - -} - - -namespace Botan { - -/** -* A MAC only used in SSLv3. Do not use elsewhere! Use HMAC instead. -*/ -class BOTAN_DLL SSL3_MAC : public MessageAuthenticationCode - { - public: - std::string name() const; - size_t output_length() const { return hash->output_length(); } - MessageAuthenticationCode* clone() const; - - void clear(); - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(hash->output_length()); - } - - /** - * @param hash the underlying hash to use - */ - SSL3_MAC(HashFunction* hash); - ~SSL3_MAC() { delete hash; } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - HashFunction* hash; - SecureVector<byte> i_key, o_key; - }; - -} - - -namespace Botan { - -/** -EMSA1_BSI is a variant of EMSA1 specified by the BSI. It accepts only -hash values which are less or equal than the maximum key length. The -implementation comes from InSiTo -*/ -class BOTAN_DLL EMSA1_BSI : public EMSA1 - { - public: - /** - * @param hash the hash object to use - */ - EMSA1_BSI(HashFunction* hash) : EMSA1(hash) {} - private: - SecureVector<byte> encoding_of(const MemoryRegion<byte>&, size_t, - RandomNumberGenerator& rng); - }; - -} - - -namespace Botan { - -/** -* Serpent, an AES finalist -*/ -class BOTAN_DLL Serpent : public Block_Cipher_Fixed_Params<16, 16, 32, 8> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(round_key); } - std::string name() const { return "Serpent"; } - BlockCipher* clone() const { return new Serpent; } - - Serpent() : round_key(132) {} - protected: - /** - * For use by subclasses using SIMD, asm, etc - * @return const reference to the key schedule - */ - const SecureVector<u32bit>& get_round_keys() const - { return round_key; } - - /** - * For use by subclasses that implement the key schedule - * @param ks is the new key schedule value to set - */ - void set_round_keys(const u32bit ks[132]) - { - copy_mem(&round_key[0], ks, 132); - } - - private: - void key_schedule(const byte key[], size_t length); - SecureVector<u32bit> round_key; - }; - -} - - -namespace Botan { - -/** -* NIST's SHA-160 -*/ -class BOTAN_DLL SHA_160 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-160"; } - size_t output_length() const { return 20; } - HashFunction* clone() const { return new SHA_160; } - - void clear(); - - SHA_160() : MDx_HashFunction(64, true, true), digest(5), W(80) - { - clear(); - } - protected: - /** - * Set a custom size for the W array. Normally 80, but some - * subclasses need slightly more for best performance/internal - * constraints - * @param W_size how big to make W - */ - SHA_160(size_t W_size) : - MDx_HashFunction(64, true, true), digest(5), W(W_size) - { - clear(); - } - - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - /** - * The digest value, exposed for use by subclasses (asm, SSE2) - */ - SecureVector<u32bit> digest; - - /** - * The message buffer, exposed for use by subclasses (asm, SSE2) - */ - SecureVector<u32bit> W; - }; - -} - - -namespace Botan { - -/** -* ANSI X9.31 RNG -*/ -class BOTAN_DLL ANSI_X931_RNG : public RandomNumberGenerator - { - public: - void randomize(byte[], size_t); - bool is_seeded() const; - void clear(); - std::string name() const; - - void reseed(size_t poll_bits); - void add_entropy_source(EntropySource*); - void add_entropy(const byte[], size_t); - - /** - * @param cipher the block cipher to use in this PRNG - * @param rng the underlying PRNG for generating inputs - * (eg, an HMAC_RNG) - */ - ANSI_X931_RNG(BlockCipher* cipher, - RandomNumberGenerator* rng); - ~ANSI_X931_RNG(); - private: - void rekey(); - void update_buffer(); - - BlockCipher* cipher; - RandomNumberGenerator* prng; - SecureVector<byte> V, R; - size_t position; - }; - -} - - -namespace Botan { - -/** -* This class represents ECDSA Public Keys. -*/ -class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey - { - public: - - /** - * Construct a public key from a given public point. - * @param dom_par the domain parameters associated with this key - * @param public_point the public point defining this key - */ - ECDSA_PublicKey(const EC_Group& dom_par, - const PointGFp& public_point) : - EC_PublicKey(dom_par, public_point) {} - - ECDSA_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - EC_PublicKey(alg_id, key_bits) {} - - /** - * Get this keys algorithm name. - * @result this keys algorithm name ("ECDSA") - */ - std::string algo_name() const { return "ECDSA"; } - - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - * @result the maximum number of input bits - */ - size_t max_input_bits() const { return domain().get_order().bits(); } - - size_t message_parts() const { return 2; } - - size_t message_part_size() const - { return domain().get_order().bytes(); } - - protected: - ECDSA_PublicKey() {} - }; - -/** -* This class represents ECDSA Private Keys -*/ -class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, - public EC_PrivateKey - { - public: - - /** - * Load a private key - * @param alg_id the X.509 algorithm identifier - * @param key_bits PKCS #8 structure - */ - ECDSA_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - EC_PrivateKey(alg_id, key_bits) {} - - /** - * Generate a new private key - * @param rng a random number generator - * @param domain parameters to used for this key - * @param x the private key (if zero, generate a ney random key) - */ - ECDSA_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& x = 0) : - EC_PrivateKey(rng, domain, x) {} - - bool check_key(RandomNumberGenerator& rng, bool) const; - }; - -/** -* ECDSA signature operation -*/ -class BOTAN_DLL ECDSA_Signature_Operation : public PK_Ops::Signature - { - public: - ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa); - - SecureVector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - private: - const PointGFp& base_point; - const BigInt& order; - const BigInt& x; - Modular_Reducer mod_order; - }; - -/** -* ECDSA verification operation -*/ -class BOTAN_DLL ECDSA_Verification_Operation : public PK_Ops::Verification - { - public: - ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - bool with_recovery() const { return false; } - - bool verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len); - private: - const PointGFp& base_point; - const PointGFp& public_point; - const BigInt& order; - }; - -} - - -namespace Botan { - -/** -* BigInt Division -* @param x an integer -* @param y a non-zero integer -* @param q will be set to x / y -* @param r will be set to x % y -*/ -void BOTAN_DLL divide(const BigInt& x, - const BigInt& y, - BigInt& q, - BigInt& r); - -} - - -namespace Botan { - -/** -* Square -*/ -class BOTAN_DLL Square : public Block_Cipher_Fixed_Params<16, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - std::string name() const { return "Square"; } - BlockCipher* clone() const { return new Square; } - - Square() : EK(28), DK(28), ME(32), MD(32) {} - private: - void key_schedule(const byte[], size_t); - - static void transform(u32bit[4]); - - static const byte SE[256]; - static const byte SD[256]; - static const byte Log[256]; - static const byte ALog[255]; - - static const u32bit TE0[256]; - static const u32bit TE1[256]; - static const u32bit TE2[256]; - static const u32bit TE3[256]; - static const u32bit TD0[256]; - static const u32bit TD1[256]; - static const u32bit TD2[256]; - static const u32bit TD3[256]; - - SecureVector<u32bit> EK, DK; - SecureVector<byte> ME, MD; - }; - -} - - -namespace Botan { - -/** -* Perform hex encoding -* @param output an array of at least input_length*2 bytes -* @param input is some binary data -* @param input_length length of input in bytes -* @param uppercase should output be upper or lower case? -*/ -void BOTAN_DLL hex_encode(char output[], - const byte input[], - size_t input_length, - bool uppercase = true); - -/** -* Perform hex encoding -* @param input some input -* @param input_length length of input in bytes -* @param uppercase should output be upper or lower case? -* @return hexadecimal representation of input -*/ -std::string BOTAN_DLL hex_encode(const byte input[], - size_t input_length, - bool uppercase = true); - -/** -* Perform hex encoding -* @param input some input -* @param uppercase should output be upper or lower case? -* @return hexadecimal representation of input -*/ -std::string BOTAN_DLL hex_encode(const MemoryRegion<byte>& input, - bool uppercase = true); - -/** -* Perform hex decoding -* @param output an array of at least input_length/2 bytes -* @param input some hex input -* @param input_length length of input in bytes -* @param input_consumed is an output parameter which says how many -* bytes of input were actually consumed. If less than -* input_length, then the range input[consumed:length] -* should be passed in later along with more input. -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL hex_decode(byte output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool ignore_ws = true); - -/** -* Perform hex decoding -* @param output an array of at least input_length/2 bytes -* @param input some hex input -* @param input_length length of input in bytes -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL hex_decode(byte output[], - const char input[], - size_t input_length, - bool ignore_ws = true); - -/** -* Perform hex decoding -* @param output an array of at least input_length/2 bytes -* @param input some hex input -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL hex_decode(byte output[], - const std::string& input, - bool ignore_ws = true); - -/** -* Perform hex decoding -* @param input some hex input -* @param input_length the length of input in bytes -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return decoded hex output -*/ -SecureVector<byte> BOTAN_DLL hex_decode(const char input[], - size_t input_length, - bool ignore_ws = true); - -/** -* Perform hex decoding -* @param input some hex input -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return decoded hex output -*/ -SecureVector<byte> BOTAN_DLL hex_decode(const std::string& input, - bool ignore_ws = true); - -} - - -namespace Botan { - -/** -* Block Cipher Cascade -*/ -class BOTAN_DLL Cascade_Cipher : public BlockCipher - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - size_t block_size() const { return block; } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(cipher1->maximum_keylength() + - cipher2->maximum_keylength()); - } - - void clear(); - std::string name() const; - BlockCipher* clone() const; - - /** - * Create a cascade of two block ciphers - * @param cipher1 the first cipher - * @param cipher2 the second cipher - */ - Cascade_Cipher(BlockCipher* cipher1, BlockCipher* cipher2); - - ~Cascade_Cipher(); - private: - void key_schedule(const byte[], size_t); - - size_t block; - BlockCipher* cipher1; - BlockCipher* cipher2; - }; - - -} - - -namespace Botan { - -/** -* EME from PKCS #1 v1.5 -*/ -class BOTAN_DLL EME_PKCS1v15 : public EME - { - public: - size_t maximum_input_size(size_t) const; - private: - SecureVector<byte> pad(const byte[], size_t, size_t, - RandomNumberGenerator&) const; - SecureVector<byte> unpad(const byte[], size_t, size_t) const; - }; - -} - - -namespace Botan { - -/** -* Bit rotation left -* @param input the input word -* @param rot the number of bits to rotate -* @return input rotated left by rot bits -*/ -template<typename T> inline T rotate_left(T input, size_t rot) - { - return static_cast<T>((input << rot) | (input >> (8*sizeof(T)-rot)));; - } - -/** -* Bit rotation right -* @param input the input word -* @param rot the number of bits to rotate -* @return input rotated right by rot bits -*/ -template<typename T> inline T rotate_right(T input, size_t rot) - { - return static_cast<T>((input >> rot) | (input << (8*sizeof(T)-rot))); - } - -} - - -#if defined(BOTAN_TARGET_CPU_HAS_SSE2) && !defined(BOTAN_NO_SSE_INTRINSICS) - #include <emmintrin.h> -#endif - -namespace Botan { - -/** -* Swap a 16 bit integer -*/ -inline u16bit reverse_bytes(u16bit val) - { - return rotate_left(val, 8); - } - -/** -* Swap a 32 bit integer -*/ -inline u32bit reverse_bytes(u32bit val) - { -#if BOTAN_GCC_VERSION >= 430 && !defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - /* - GCC intrinsic added in 4.3, works for a number of CPUs - - However avoid under ARM, as it branches to a function in libgcc - instead of generating inline asm, so slower even than the generic - rotate version below. - */ - return __builtin_bswap32(val); - -#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - - // GCC-style inline assembly for x86 or x86-64 - asm("bswapl %0" : "=r" (val) : "0" (val)); - return val; - -#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - - asm ("eor r3, %1, %1, ror #16\n\t" - "bic r3, r3, #0x00FF0000\n\t" - "mov %0, %1, ror #8\n\t" - "eor %0, %0, r3, lsr #8" - : "=r" (val) - : "0" (val) - : "r3", "cc"); - - return val; - -#else - - // Generic implementation - return (rotate_right(val, 8) & 0xFF00FF00) | - (rotate_left (val, 8) & 0x00FF00FF); - -#endif - } - -/** -* Swap a 64 bit integer -*/ -inline u64bit reverse_bytes(u64bit val) - { -#if BOTAN_GCC_VERSION >= 430 - - // GCC intrinsic added in 4.3, works for a number of CPUs - return __builtin_bswap64(val); - -#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_ARCH_IS_X86_64) - // GCC-style inline assembly for x86-64 - asm("bswapq %0" : "=r" (val) : "0" (val)); - return val; - -#else - /* Generic implementation. Defined in terms of 32-bit bswap so any - * optimizations in that version can help here (particularly - * useful for 32-bit x86). - */ - - u32bit hi = static_cast<u32bit>(val >> 32); - u32bit lo = static_cast<u32bit>(val); - - hi = reverse_bytes(hi); - lo = reverse_bytes(lo); - - return (static_cast<u64bit>(lo) << 32) | hi; -#endif - } - -/** -* Swap 4 Ts in an array -*/ -template<typename T> -inline void bswap_4(T x[4]) - { - x[0] = reverse_bytes(x[0]); - x[1] = reverse_bytes(x[1]); - x[2] = reverse_bytes(x[2]); - x[3] = reverse_bytes(x[3]); - } - -#if defined(BOTAN_TARGET_CPU_HAS_SSE2) && !defined(BOTAN_NO_SSE_INTRINSICS) - -/** -* Swap 4 u32bits in an array using SSE2 shuffle instructions -*/ -template<> -inline void bswap_4(u32bit x[4]) - { - __m128i T = _mm_loadu_si128(reinterpret_cast<const __m128i*>(x)); - - T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); - T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); - - T = _mm_or_si128(_mm_srli_epi16(T, 8), _mm_slli_epi16(T, 8)); - - _mm_storeu_si128(reinterpret_cast<__m128i*>(x), T); - } - -#endif - -} - - -namespace Botan { - -/** -* MD5 -*/ -class BOTAN_DLL MD5 : public MDx_HashFunction - { - public: - std::string name() const { return "MD5"; } - size_t output_length() const { return 16; } - HashFunction* clone() const { return new MD5; } - - void clear(); - - MD5() : MDx_HashFunction(64, false, true), M(16), digest(4) - { clear(); } - protected: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - /** - * The message buffer, exposed for use by subclasses (x86 asm) - */ - SecureVector<u32bit> M; - - /** - * The digest value, exposed for use by subclasses (x86 asm) - */ - SecureVector<u32bit> digest; - }; - -} - - -namespace Botan { - -/** -* Filter mixin that breaks input into blocks, useful for -* cipher modes -*/ -class BOTAN_DLL Buffered_Filter - { - public: - /** - * Write bytes into the buffered filter, which will them emit them - * in calls to buffered_block in the subclass - * @param in the input bytes - * @param length of in in bytes - */ - void write(const byte in[], size_t length); - - /** - * Finish a message, emitting to buffered_block and buffered_final - * Will throw an exception if less than final_minimum bytes were - * written into the filter. - */ - void end_msg(); - - /** - * Initialize a Buffered_Filter - * @param block_size the function buffered_block will be called - * with inputs which are a multiple of this size - * @param final_minimum the function buffered_final will be called - * with at least this many bytes. - */ - Buffered_Filter(size_t block_size, size_t final_minimum); - - virtual ~Buffered_Filter() {} - protected: - /** - * The block processor, implemented by subclasses - * @param input some input bytes - * @param length the size of input, guaranteed to be a multiple - * of block_size - */ - virtual void buffered_block(const byte input[], size_t length) = 0; - - /** - * The final block, implemented by subclasses - * @param input some input bytes - * @param length the size of input, guaranteed to be at least - * final_minimum bytes - */ - virtual void buffered_final(const byte input[], size_t length) = 0; - - /** - * @return block size of inputs - */ - size_t buffered_block_size() const { return main_block_mod; } - - /** - * @return current position in the buffer - */ - size_t current_position() const { return buffer_pos; } - - /** - * Reset the buffer position - */ - void buffer_reset() { buffer_pos = 0; } - private: - size_t main_block_mod, final_minimum; - - SecureVector<byte> buffer; - size_t buffer_pos; - }; - -} - - -namespace Botan { - -/** -* ECB Encryption -*/ -class BOTAN_DLL ECB_Encryption : public Keyed_Filter, - private Buffered_Filter - { - public: - std::string name() const; - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - ECB_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad); - - ECB_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad, - const SymmetricKey& key); - - ~ECB_Encryption(); - private: - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - void write(const byte input[], size_t input_length); - void end_msg(); - - BlockCipher* cipher; - BlockCipherModePaddingMethod* padder; - SecureVector<byte> temp; - }; - -/** -* ECB Decryption -*/ -class BOTAN_DLL ECB_Decryption : public Keyed_Filter, - public Buffered_Filter - { - public: - std::string name() const; - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - ECB_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad); - - ECB_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad, - const SymmetricKey& key); - - ~ECB_Decryption(); - private: - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - void write(const byte input[], size_t input_length); - void end_msg(); - - BlockCipher* cipher; - BlockCipherModePaddingMethod* padder; - SecureVector<byte> temp; - }; - -} - - -namespace Botan { - -/** -* The different charsets (nominally) supported by Botan. -*/ -enum Character_Set { - LOCAL_CHARSET, - UCS2_CHARSET, - UTF8_CHARSET, - LATIN1_CHARSET -}; - -namespace Charset { - -/* -* Character Set Handling -*/ -std::string BOTAN_DLL transcode(const std::string& str, - Character_Set to, - Character_Set from); - -bool BOTAN_DLL is_digit(char c); -bool BOTAN_DLL is_space(char c); -bool BOTAN_DLL caseless_cmp(char x, char y); - -byte BOTAN_DLL char2digit(char c); -char BOTAN_DLL digit2char(byte b); - -} - -} - - -namespace Botan { - -/** -* This class represents public keys -* of integer factorization based (IF) public key schemes. -*/ -class BOTAN_DLL IF_Scheme_PublicKey : public virtual Public_Key - { - public: - IF_Scheme_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits); - - IF_Scheme_PublicKey(const BigInt& n, const BigInt& e) : - n(n), e(e) {} - - bool check_key(RandomNumberGenerator& rng, bool) const; - - AlgorithmIdentifier algorithm_identifier() const; - - MemoryVector<byte> x509_subject_public_key() const; - - /** - * @return public modulus - */ - const BigInt& get_n() const { return n; } - - /** - * @return public exponent - */ - const BigInt& get_e() const { return e; } - - size_t max_input_bits() const { return (n.bits() - 1); } - - protected: - IF_Scheme_PublicKey() {} - - BigInt n, e; - }; - -/** -* This class represents public keys -* of integer factorization based (IF) public key schemes. -*/ -class BOTAN_DLL IF_Scheme_PrivateKey : public virtual IF_Scheme_PublicKey, - public virtual Private_Key - { - public: - - IF_Scheme_PrivateKey(RandomNumberGenerator& rng, - const BigInt& prime1, const BigInt& prime2, - const BigInt& exp, const BigInt& d_exp, - const BigInt& mod); - - IF_Scheme_PrivateKey(RandomNumberGenerator& rng, - const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits); - - bool check_key(RandomNumberGenerator& rng, bool) const; - - /** - * Get the first prime p. - * @return prime p - */ - const BigInt& get_p() const { return p; } - - /** - * Get the second prime q. - * @return prime q - */ - const BigInt& get_q() const { return q; } - - /** - * Get d with exp * d = 1 mod (p - 1, q - 1). - * @return d - */ - const BigInt& get_d() const { return d; } - - const BigInt& get_c() const { return c; } - const BigInt& get_d1() const { return d1; } - const BigInt& get_d2() const { return d2; } - - MemoryVector<byte> pkcs8_private_key() const; - - protected: - IF_Scheme_PrivateKey() {} - - BigInt d, p, q, d1, d2, c; - }; - -} - - -namespace Botan { - -/** -* RSA Public Key -*/ -class BOTAN_DLL RSA_PublicKey : public virtual IF_Scheme_PublicKey - { - public: - std::string algo_name() const { return "RSA"; } - - RSA_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - IF_Scheme_PublicKey(alg_id, key_bits) - {} - - /** - * Create a RSA_PublicKey - * @arg n the modulus - * @arg e the exponent - */ - RSA_PublicKey(const BigInt& n, const BigInt& e) : - IF_Scheme_PublicKey(n, e) - {} - - protected: - RSA_PublicKey() {} - }; - -/** -* RSA Private Key -*/ -class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey, - public IF_Scheme_PrivateKey - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - RSA_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits, - RandomNumberGenerator& rng) : - IF_Scheme_PrivateKey(rng, alg_id, key_bits) {} - - /** - * Construct a private key from the specified parameters. - * @param rng a random number generator - * @param p the first prime - * @param q the second prime - * @param e the exponent - * @param d if specified, this has to be d with - * exp * d = 1 mod (p - 1, q - 1). Leave it as 0 if you wish to - * the constructor to calculate it. - * @param n if specified, this must be n = p * q. Leave it as 0 - * if you wish to the constructor to calculate it. - */ - RSA_PrivateKey(RandomNumberGenerator& rng, - const BigInt& p, const BigInt& q, - const BigInt& e, const BigInt& d = 0, - const BigInt& n = 0) : - IF_Scheme_PrivateKey(rng, p, q, e, d, n) {} - - /** - * Create a new private key with the specified bit length - * @param rng the random number generator to use - * @param bits the desired bit length of the private key - * @param exp the public exponent to be used - */ - RSA_PrivateKey(RandomNumberGenerator& rng, - size_t bits, size_t exp = 65537); - }; - -/** -* RSA private (decrypt/sign) operation -*/ -class BOTAN_DLL RSA_Private_Operation : public PK_Ops::Signature, - public PK_Ops::Decryption - { - public: - RSA_Private_Operation(const RSA_PrivateKey& rsa); - - size_t max_input_bits() const { return (n.bits() - 1); } - - SecureVector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - SecureVector<byte> decrypt(const byte msg[], size_t msg_len); - - private: - BigInt private_op(const BigInt& m) const; - - const BigInt& n; - const BigInt& q; - const BigInt& c; - Fixed_Exponent_Power_Mod powermod_e_n, powermod_d1_p, powermod_d2_q; - Modular_Reducer mod_p; - Blinder blinder; - }; - -/** -* RSA public (encrypt/verify) operation -*/ -class BOTAN_DLL RSA_Public_Operation : public PK_Ops::Verification, - public PK_Ops::Encryption - { - public: - RSA_Public_Operation(const RSA_PublicKey& rsa) : - n(rsa.get_n()), powermod_e_n(rsa.get_e(), rsa.get_n()) - {} - - size_t max_input_bits() const { return (n.bits() - 1); } - bool with_recovery() const { return true; } - - SecureVector<byte> encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator&) - { - BigInt m(msg, msg_len); - return BigInt::encode_1363(public_op(m), n.bytes()); - } - - SecureVector<byte> verify_mr(const byte msg[], size_t msg_len) - { - BigInt m(msg, msg_len); - return BigInt::encode(public_op(m)); - } - - private: - BigInt public_op(const BigInt& m) const - { - if(m >= n) - throw Invalid_Argument("RSA public op - input is too large"); - return powermod_e_n(m); - } - - const BigInt& n; - Fixed_Exponent_Power_Mod powermod_e_n; - }; - -} - - -namespace Botan { - -/** -* RIPEMD-160 -*/ -class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction - { - public: - std::string name() const { return "RIPEMD-160"; } - size_t output_length() const { return 20; } - HashFunction* clone() const { return new RIPEMD_160; } - - void clear(); - - RIPEMD_160() : MDx_HashFunction(64, false, true), M(16), digest(5) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector<u32bit> M, digest; - }; - -} - - -namespace Botan { - -/** -* Whirlpool -*/ -class BOTAN_DLL Whirlpool : public MDx_HashFunction - { - public: - std::string name() const { return "Whirlpool"; } - size_t output_length() const { return 64; } - HashFunction* clone() const { return new Whirlpool; } - - void clear(); - - Whirlpool() : MDx_HashFunction(64, true, true, 32), M(8), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - static const u64bit C0[256]; - static const u64bit C1[256]; - static const u64bit C2[256]; - static const u64bit C3[256]; - static const u64bit C4[256]; - static const u64bit C5[256]; - static const u64bit C6[256]; - static const u64bit C7[256]; - - SecureVector<u64bit> M, digest; - }; - -} - - -namespace Botan { - -/** -* Tiger -*/ -class BOTAN_DLL Tiger : public MDx_HashFunction - { - public: - std::string name() const; - size_t output_length() const { return hash_len; } - - HashFunction* clone() const - { - return new Tiger(output_length(), passes); - } - - void clear(); - - /** - * @param out_size specifies the output length; can be 16, 20, or 24 - * @param passes to make in the algorithm - */ - Tiger(size_t out_size = 24, size_t passes = 3); - private: - void compress_n(const byte[], size_t block); - void copy_out(byte[]); - - static void pass(u64bit& A, u64bit& B, u64bit& C, - const MemoryRegion<u64bit>& M, - byte mul); - - static const u64bit SBOX1[256]; - static const u64bit SBOX2[256]; - static const u64bit SBOX3[256]; - static const u64bit SBOX4[256]; - - SecureVector<u64bit> X, digest; - const size_t hash_len, passes; - }; - -} - - -namespace Botan { - -/** -* SEED, a Korean block cipher -*/ -class BOTAN_DLL SEED : public Block_Cipher_Fixed_Params<16, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(K); } - std::string name() const { return "SEED"; } - BlockCipher* clone() const { return new SEED; } - - SEED() : K(32) {} - private: - void key_schedule(const byte[], size_t); - - class G_FUNC - { - public: - u32bit operator()(u32bit) const; - private: - static const u32bit S0[256], S1[256], S2[256], S3[256]; - }; - - SecureVector<u32bit> K; - }; - -} - - -namespace Botan { - -/** -* EMSA3 from IEEE 1363 -* aka PKCS #1 v1.5 signature padding -* aka PKCS #1 block type 1 -*/ -class BOTAN_DLL EMSA3 : public EMSA - { - public: - /** - * @param hash the hash object to use - */ - EMSA3(HashFunction* hash); - ~EMSA3(); - - void update(const byte[], size_t); - - SecureVector<byte> raw_data(); - - SecureVector<byte> encoding_of(const MemoryRegion<byte>&, size_t, - RandomNumberGenerator& rng); - - bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - size_t); - private: - HashFunction* hash; - SecureVector<byte> hash_id; - }; - -/** -* EMSA3_Raw which is EMSA3 without a hash or digest id (which -* according to QCA docs is "identical to PKCS#11's CKM_RSA_PKCS -* mechanism", something I have not confirmed) -*/ -class BOTAN_DLL EMSA3_Raw : public EMSA - { - public: - void update(const byte[], size_t); - - SecureVector<byte> raw_data(); - - SecureVector<byte> encoding_of(const MemoryRegion<byte>&, size_t, - RandomNumberGenerator& rng); - - bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - size_t); - - private: - SecureVector<byte> message; - }; - -} - - -namespace Botan { - -/** -* Twofish, an AES finalist -*/ -class BOTAN_DLL Twofish : public Block_Cipher_Fixed_Params<16, 16, 32, 8> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - std::string name() const { return "Twofish"; } - BlockCipher* clone() const { return new Twofish; } - - Twofish() : SB(1024), RK(40) {} - private: - void key_schedule(const byte[], size_t); - - static void rs_mul(byte[4], byte, size_t); - - static const u32bit MDS0[256]; - static const u32bit MDS1[256]; - static const u32bit MDS2[256]; - static const u32bit MDS3[256]; - static const byte Q0[256]; - static const byte Q1[256]; - static const byte RS[32]; - static const byte EXP_TO_POLY[255]; - static const byte POLY_TO_EXP[255]; - - SecureVector<u32bit> SB, RK; - }; - -} - - -namespace Botan { - -/** -* Create a password hash using PBKDF2 -* @param password the password -* @param rng a random number generator -* @param work_factor how much work to do to slow down guessing attacks -* @param alg_id specifies which PRF to use with PBKDF2 -* 0 is HMAC(SHA-1) -* 1 is HMAC(SHA-256) -* 2 is CMAC(Blowfish) -* all other values are currently undefined -*/ -std::string BOTAN_DLL generate_passhash9(const std::string& password, - RandomNumberGenerator& rng, - u16bit work_factor = 10, - byte alg_id = 0); - -/** -* Check a previously created password hash -* @param password the password to check against -* @param hash the stored hash to check against -*/ -bool BOTAN_DLL check_passhash9(const std::string& password, - const std::string& hash); - -} - - -namespace Botan { - -/** -* SHA-224 -*/ -class BOTAN_DLL SHA_224 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-224"; } - size_t output_length() const { return 28; } - HashFunction* clone() const { return new SHA_224; } - - void clear(); - - SHA_224() : MDx_HashFunction(64, true, true), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector<u32bit> digest; - }; - -/** -* SHA-256 -*/ -class BOTAN_DLL SHA_256 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-256"; } - size_t output_length() const { return 32; } - HashFunction* clone() const { return new SHA_256; } - - void clear(); - - SHA_256() : MDx_HashFunction(64, true, true), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector<u32bit> digest; - }; - -} - - -namespace Botan { - -/** -* Blue Midnight Wish 512 (Round 2 tweaked version) -*/ -class BOTAN_DLL BMW_512 : public MDx_HashFunction - { - public: - std::string name() const { return "BMW512"; } - size_t output_length() const { return 64; } - HashFunction* clone() const { return new BMW_512; } - - void clear(); - - BMW_512() : MDx_HashFunction(128, false, true), H(16), M(16), Q(32) - { clear(); } - private: - void compress_n(const byte input[], size_t blocks); - void copy_out(byte output[]); - - SecureVector<u64bit> H, M, Q; - }; - -} - - -namespace Botan { - -/** -* @param input the input data -* @param length length of input in bytes -* @param label the human-readable label -* @param headers a set of key/value pairs included in the header -*/ -BOTAN_DLL std::string PGP_encode( - const byte input[], - size_t length, - const std::string& label, - const std::map<std::string, std::string>& headers); - -/** -* @param input the input data -* @param length length of input in bytes -* @param label the human-readable label -*/ -BOTAN_DLL std::string PGP_encode( - const byte input[], - size_t length, - const std::string& label); - -/** -* @param source the input source -* @param label is set to the human-readable label -* @param headers is set to any headers -* @return decoded output as raw binary -*/ -BOTAN_DLL SecureVector<byte> PGP_decode( - DataSource& source, - std::string& label, - std::map<std::string, std::string>& headers); - -/** -* @param source the input source -* @param label is set to the human-readable label -* @return decoded output as raw binary -*/ -BOTAN_DLL SecureVector<byte> PGP_decode( - DataSource& source, - std::string& label); - -} - - -namespace Botan { - -/** -* Certificate Store Interface -*/ -class BOTAN_DLL Certificate_Store - { - public: - virtual ~Certificate_Store() {} - - virtual Certificate_Store* clone() const = 0; - - /** - * Add a certificate; this may fail if the store is write-only - */ - virtual void add_certificate(const X509_Certificate& cert) = 0; - - /** - * Add a CRL; this may fail if the store is write-only - */ - virtual void add_crl(const X509_CRL& crl) = 0; - - /** - * Subject DN and (optionally) key identifier - */ - virtual std::vector<X509_Certificate> - find_cert_by_subject_and_key_id( - const X509_DN& subject_dn, - const MemoryRegion<byte>& key_id) const = 0; - - /** - * Find CRLs by the DN and key id of the issuer - */ - virtual std::vector<X509_CRL> - find_crl_by_subject_and_key_id( - const X509_DN& issuer_dn, - const MemoryRegion<byte>& key_id) const = 0; - }; - -/** -* In Memory Certificate Store -*/ -class BOTAN_DLL Certificate_Store_Memory : public Certificate_Store - { - public: - Certificate_Store* clone() const; - - void add_certificate(const X509_Certificate& cert); - - void add_crl(const X509_CRL& crl); - - std::vector<X509_Certificate> find_cert_by_subject_and_key_id( - const X509_DN& subject_dn, - const MemoryRegion<byte>& key_id) const; - - std::vector<X509_CRL> find_crl_by_subject_and_key_id( - const X509_DN& issuer_dn, - const MemoryRegion<byte>& key_id) const; - - Certificate_Store_Memory() {} - private: - // TODO: Add indexing on the DN and key id to avoid linear search? - std::vector<X509_Certificate> certs; - std::vector<X509_CRL> crls; - }; - -// TODO: file-backed store - -} - - -namespace Botan { - -/** -* KDF2, from IEEE 1363 -*/ -class BOTAN_DLL KDF2 : public KDF - { - public: - SecureVector<byte> derive(size_t, const byte[], size_t, - const byte[], size_t) const; - - std::string name() const { return "KDF2(" + hash->name() + ")"; } - KDF* clone() const { return new KDF2(hash->clone()); } - - KDF2(HashFunction* h) : hash(h) {} - KDF2(const KDF2& other) : KDF(), hash(other.hash->clone()) {} - ~KDF2() { delete hash; } - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -namespace KeyPair { - -/** -* Tests whether the key is consistent for encryption; whether -* encrypting and then decrypting gives to the original plaintext. -* @param rng the rng to use -* @param key the key to test -* @param padding the encryption padding method to use -* @return true if consistent otherwise false -*/ -BOTAN_DLL bool -encryption_consistency_check(RandomNumberGenerator& rng, - const Private_Key& key, - const std::string& padding); - -/** -* Tests whether the key is consistent for signatures; whether a -* signature can be created and then verified -* @param rng the rng to use -* @param key the key to test -* @param padding the signature padding method to use -* @return true if consistent otherwise false -*/ -BOTAN_DLL bool -signature_consistency_check(RandomNumberGenerator& rng, - const Private_Key& key, - const std::string& padding); - -} - -} - - -namespace Botan { - -/** -* This namespace holds various high-level crypto functions -*/ -namespace CryptoBox { - -/** -* Encrypt a message using a passphrase -* @param input the input data -* @param input_len the length of input in bytes -* @param passphrase the passphrase used to encrypt the message -* @param rng a ref to a random number generator, such as AutoSeeded_RNG -*/ -BOTAN_DLL std::string encrypt(const byte input[], size_t input_len, - const std::string& passphrase, - RandomNumberGenerator& rng); - -/** -* Decrypt a message encrypted with CryptoBox::encrypt -* @param input the input data -* @param input_len the length of input in bytes -* @param passphrase the passphrase used to encrypt the message -*/ -BOTAN_DLL std::string decrypt(const byte input[], size_t input_len, - const std::string& passphrase); - -/** -* Decrypt a message encrypted with CryptoBox::encrypt -* @param input the input data -* @param passphrase the passphrase used to encrypt the message -*/ -BOTAN_DLL std::string decrypt(const std::string& input, - const std::string& passphrase); - -} - -} - - -namespace Botan { - -/** -* X.509 Certificate Validation Result -*/ -enum X509_Code { - VERIFIED, - UNKNOWN_X509_ERROR, - CANNOT_ESTABLISH_TRUST, - CERT_CHAIN_TOO_LONG, - SIGNATURE_ERROR, - POLICY_ERROR, - INVALID_USAGE, - - CERT_FORMAT_ERROR, - CERT_ISSUER_NOT_FOUND, - CERT_NOT_YET_VALID, - CERT_HAS_EXPIRED, - CERT_IS_REVOKED, - - CRL_FORMAT_ERROR, - CRL_ISSUER_NOT_FOUND, - CRL_NOT_YET_VALID, - CRL_HAS_EXPIRED, - - CA_CERT_CANNOT_SIGN, - CA_CERT_NOT_FOR_CERT_ISSUER, - CA_CERT_NOT_FOR_CRL_ISSUER -}; - -/** -* X.509 Certificate Store -*/ -class BOTAN_DLL X509_Store - { - public: - enum Cert_Usage { - ANY = 0x00, - TLS_SERVER = 0x01, - TLS_CLIENT = 0x02, - CODE_SIGNING = 0x04, - EMAIL_PROTECTION = 0x08, - TIME_STAMPING = 0x10, - CRL_SIGNING = 0x20 - }; - - X509_Code validate_cert(const X509_Certificate&, Cert_Usage = ANY); - - std::vector<X509_Certificate> get_cert_chain(const X509_Certificate&); - std::string PEM_encode() const; - - X509_Code add_crl(const X509_CRL&); - void add_cert(const X509_Certificate&, bool = false); - void add_certs(DataSource&); - void add_trusted_certs(DataSource&); - - void add_new_certstore(Certificate_Store*); - - X509_Store(u32bit time_slack = 24*60*60, - u32bit cache_results = 30*60); - - X509_Store(const X509_Store&); - ~X509_Store(); - private: - X509_Store& operator=(const X509_Store&) { return (*this); } - - class BOTAN_DLL CRL_Data - { - public: - X509_DN issuer; - MemoryVector<byte> serial, auth_key_id; - bool operator==(const CRL_Data&) const; - bool operator!=(const CRL_Data&) const; - bool operator<(const CRL_Data&) const; - }; - - class BOTAN_DLL Cert_Info - { - public: - bool is_verified(u32bit timeout) const; - bool is_trusted() const; - X509_Code verify_result() const; - void set_result(X509_Code) const; - Cert_Info(const X509_Certificate&, bool = false); - - X509_Certificate cert; - bool trusted; - private: - mutable bool checked; - mutable X509_Code result; - mutable u64bit last_checked; - }; - - static X509_Code check_sig(const X509_Object&, Public_Key*); - - size_t find_cert(const X509_DN&, const MemoryRegion<byte>&) const; - X509_Code check_sig(const Cert_Info&, const Cert_Info&) const; - void recompute_revoked_info() const; - - void do_add_certs(DataSource&, bool); - X509_Code construct_cert_chain(const X509_Certificate&, - std::vector<size_t>&, bool = false); - - size_t find_parent_of(const X509_Certificate&); - bool is_revoked(const X509_Certificate&) const; - - static const size_t NO_CERT_FOUND = 0xFFFFFFFF; - std::vector<Cert_Info> certs; - std::vector<CRL_Data> revoked; - std::vector<Certificate_Store*> stores; - u32bit time_slack, validation_cache_timeout; - mutable bool revoked_info_valid; - }; - -} - - -namespace Botan { - -/** -* Noekeon -*/ -class BOTAN_DLL Noekeon : public Block_Cipher_Fixed_Params<16, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - std::string name() const { return "Noekeon"; } - BlockCipher* clone() const { return new Noekeon; } - - Noekeon() : EK(4), DK(4) {} - protected: - /** - * The Noekeon round constants - */ - static const byte RC[17]; - - /** - * @return const reference to encryption subkeys - */ - const SecureVector<u32bit>& get_EK() const { return EK; } - - /** - * @return const reference to decryption subkeys - */ - const SecureVector<u32bit>& get_DK() const { return DK; } - - private: - void key_schedule(const byte[], size_t); - SecureVector<u32bit> EK, DK; - }; - -} - - -namespace Botan { - -/** -* Create a password hash using Bcrypt -* @param password the password -* @param rng a random number generator -* @param work_factor how much work to do to slow down guessing attacks -* -* @see http://www.usenix.org/events/usenix99/provos/provos_html/ -*/ -std::string BOTAN_DLL generate_bcrypt(const std::string& password, - RandomNumberGenerator& rng, - u16bit work_factor = 10); - -/** -* Check a previously created password hash -* @param password the password to check against -* @param hash the stored hash to check against -*/ -bool BOTAN_DLL check_bcrypt(const std::string& password, - const std::string& hash); - -} - - -namespace Botan { - -/** -* CFB Encryption -*/ -class BOTAN_DLL CFB_Encryption : public Keyed_Filter - { - public: - std::string name() const { return cipher->name() + "/CFB"; } - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CFB_Encryption(BlockCipher* cipher, size_t feedback = 0); - - CFB_Encryption(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv, - size_t feedback = 0); - - ~CFB_Encryption() { delete cipher; } - private: - void write(const byte[], size_t); - - BlockCipher* cipher; - SecureVector<byte> buffer, state; - size_t position, feedback; - }; - -/** -* CFB Decryption -*/ -class BOTAN_DLL CFB_Decryption : public Keyed_Filter - { - public: - std::string name() const { return cipher->name() + "/CFB"; } - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CFB_Decryption(BlockCipher* cipher, size_t feedback = 0); - - CFB_Decryption(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv, - size_t feedback = 0); - - ~CFB_Decryption() { delete cipher; } - private: - void write(const byte[], size_t); - - BlockCipher* cipher; - SecureVector<byte> buffer, state; - size_t position, feedback; - }; - -} - - -namespace Botan { - -/** -* X.509 Certificate Extension -*/ -class BOTAN_DLL Certificate_Extension - { - public: - /** - * @return OID representing this extension - */ - OID oid_of() const; - - /** - * Make a copy of this extension - * @return copy of this - */ - virtual Certificate_Extension* copy() const = 0; - - /* - * Add the contents of this extension into the information - * for the subject and/or issuer, as necessary. - * @param subject the subject info - * @param issuer the issuer info - */ - virtual void contents_to(Data_Store& subject, - Data_Store& issuer) const = 0; - - /* - * @return short readable name - */ - virtual std::string config_id() const = 0; - - /* - * @return specific OID name - */ - virtual std::string oid_name() const = 0; - - virtual ~Certificate_Extension() {} - protected: - friend class Extensions; - virtual bool should_encode() const { return true; } - virtual MemoryVector<byte> encode_inner() const = 0; - virtual void decode_inner(const MemoryRegion<byte>&) = 0; - }; - -/** -* X.509 Certificate Extension List -*/ -class BOTAN_DLL Extensions : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - void contents_to(Data_Store&, Data_Store&) const; - - void add(Certificate_Extension* extn, bool critical = false); - - Extensions& operator=(const Extensions&); - - Extensions(const Extensions&); - Extensions(bool st = true) : should_throw(st) {} - ~Extensions(); - private: - static Certificate_Extension* get_extension(const OID&); - - std::vector<std::pair<Certificate_Extension*, bool> > extensions; - bool should_throw; - }; - -namespace Cert_Extension { - -static const size_t NO_CERT_PATH_LIMIT = 0xFFFFFFF0; - -/** -* Basic Constraints Extension -*/ -class BOTAN_DLL Basic_Constraints : public Certificate_Extension - { - public: - Basic_Constraints* copy() const - { return new Basic_Constraints(is_ca, path_limit); } - - Basic_Constraints(bool ca = false, size_t limit = 0) : - is_ca(ca), path_limit(limit) {} - - bool get_is_ca() const { return is_ca; } - size_t get_path_limit() const; - private: - std::string config_id() const { return "basic_constraints"; } - std::string oid_name() const { return "X509v3.BasicConstraints"; } - - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); - void contents_to(Data_Store&, Data_Store&) const; - - bool is_ca; - size_t path_limit; - }; - -/** -* Key Usage Constraints Extension -*/ -class BOTAN_DLL Key_Usage : public Certificate_Extension - { - public: - Key_Usage* copy() const { return new Key_Usage(constraints); } - - Key_Usage(Key_Constraints c = NO_CONSTRAINTS) : constraints(c) {} - - Key_Constraints get_constraints() const { return constraints; } - private: - std::string config_id() const { return "key_usage"; } - std::string oid_name() const { return "X509v3.KeyUsage"; } - - bool should_encode() const { return (constraints != NO_CONSTRAINTS); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); - void contents_to(Data_Store&, Data_Store&) const; - - Key_Constraints constraints; - }; - -/** -* Subject Key Identifier Extension -*/ -class BOTAN_DLL Subject_Key_ID : public Certificate_Extension - { - public: - Subject_Key_ID* copy() const { return new Subject_Key_ID(key_id); } - - Subject_Key_ID() {} - Subject_Key_ID(const MemoryRegion<byte>&); - - MemoryVector<byte> get_key_id() const { return key_id; } - private: - std::string config_id() const { return "subject_key_id"; } - std::string oid_name() const { return "X509v3.SubjectKeyIdentifier"; } - - bool should_encode() const { return (key_id.size() > 0); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); - void contents_to(Data_Store&, Data_Store&) const; - - MemoryVector<byte> key_id; - }; - -/** -* Authority Key Identifier Extension -*/ -class BOTAN_DLL Authority_Key_ID : public Certificate_Extension - { - public: - Authority_Key_ID* copy() const { return new Authority_Key_ID(key_id); } - - Authority_Key_ID() {} - Authority_Key_ID(const MemoryRegion<byte>& k) : key_id(k) {} - - MemoryVector<byte> get_key_id() const { return key_id; } - private: - std::string config_id() const { return "authority_key_id"; } - std::string oid_name() const { return "X509v3.AuthorityKeyIdentifier"; } - - bool should_encode() const { return (key_id.size() > 0); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); - void contents_to(Data_Store&, Data_Store&) const; - - MemoryVector<byte> key_id; - }; - -/** -* Alternative Name Extension Base Class -*/ -class BOTAN_DLL Alternative_Name : public Certificate_Extension - { - public: - AlternativeName get_alt_name() const { return alt_name; } - - protected: - Alternative_Name(const AlternativeName&, - const std::string&, const std::string&); - - Alternative_Name(const std::string&, const std::string&); - private: - std::string config_id() const { return config_name_str; } - std::string oid_name() const { return oid_name_str; } - - bool should_encode() const { return alt_name.has_items(); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); - void contents_to(Data_Store&, Data_Store&) const; - - std::string config_name_str, oid_name_str; - AlternativeName alt_name; - }; - -/** -* Subject Alternative Name Extension -*/ -class BOTAN_DLL Subject_Alternative_Name : public Alternative_Name - { - public: - Subject_Alternative_Name* copy() const - { return new Subject_Alternative_Name(get_alt_name()); } - - Subject_Alternative_Name(const AlternativeName& = AlternativeName()); - }; - -/** -* Issuer Alternative Name Extension -*/ -class BOTAN_DLL Issuer_Alternative_Name : public Alternative_Name - { - public: - Issuer_Alternative_Name* copy() const - { return new Issuer_Alternative_Name(get_alt_name()); } - - Issuer_Alternative_Name(const AlternativeName& = AlternativeName()); - }; - -/** -* Extended Key Usage Extension -*/ -class BOTAN_DLL Extended_Key_Usage : public Certificate_Extension - { - public: - Extended_Key_Usage* copy() const { return new Extended_Key_Usage(oids); } - - Extended_Key_Usage() {} - Extended_Key_Usage(const std::vector<OID>& o) : oids(o) {} - - std::vector<OID> get_oids() const { return oids; } - private: - std::string config_id() const { return "extended_key_usage"; } - std::string oid_name() const { return "X509v3.ExtendedKeyUsage"; } - - bool should_encode() const { return (oids.size() > 0); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); - void contents_to(Data_Store&, Data_Store&) const; - - std::vector<OID> oids; - }; - -/** -* Certificate Policies Extension -*/ -class BOTAN_DLL Certificate_Policies : public Certificate_Extension - { - public: - Certificate_Policies* copy() const - { return new Certificate_Policies(oids); } - - Certificate_Policies() {} - Certificate_Policies(const std::vector<OID>& o) : oids(o) {} - - std::vector<OID> get_oids() const { return oids; } - private: - std::string config_id() const { return "policy_info"; } - std::string oid_name() const { return "X509v3.CertificatePolicies"; } - - bool should_encode() const { return (oids.size() > 0); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); - void contents_to(Data_Store&, Data_Store&) const; - - std::vector<OID> oids; - }; - -/** -* CRL Number Extension -*/ -class BOTAN_DLL CRL_Number : public Certificate_Extension - { - public: - CRL_Number* copy() const; - - CRL_Number() : has_value(false), crl_number(0) {} - CRL_Number(size_t n) : has_value(true), crl_number(n) {} - - size_t get_crl_number() const; - private: - std::string config_id() const { return "crl_number"; } - std::string oid_name() const { return "X509v3.CRLNumber"; } - - bool should_encode() const { return has_value; } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); - void contents_to(Data_Store&, Data_Store&) const; - - bool has_value; - size_t crl_number; - }; - -/** -* CRL Entry Reason Code Extension -*/ -class BOTAN_DLL CRL_ReasonCode : public Certificate_Extension - { - public: - CRL_ReasonCode* copy() const { return new CRL_ReasonCode(reason); } - - CRL_ReasonCode(CRL_Code r = UNSPECIFIED) : reason(r) {} - - CRL_Code get_reason() const { return reason; } - private: - std::string config_id() const { return "crl_reason"; } - std::string oid_name() const { return "X509v3.ReasonCode"; } - - bool should_encode() const { return (reason != UNSPECIFIED); } - MemoryVector<byte> encode_inner() const; - void decode_inner(const MemoryRegion<byte>&); - void contents_to(Data_Store&, Data_Store&) const; - - CRL_Code reason; - }; - -} - -} - - -namespace Botan { - -/** -* DSA Public Key -*/ -class BOTAN_DLL DSA_PublicKey : public virtual DL_Scheme_PublicKey - { - public: - std::string algo_name() const { return "DSA"; } - - DL_Group::Format group_format() const { return DL_Group::ANSI_X9_57; } - size_t message_parts() const { return 2; } - size_t message_part_size() const { return group_q().bytes(); } - size_t max_input_bits() const { return group_q().bits(); } - - DSA_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_57) - { - } - - DSA_PublicKey(const DL_Group& group, const BigInt& y); - protected: - DSA_PublicKey() {} - }; - -/** -* DSA Private Key -*/ -class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey, - public virtual DL_Scheme_PrivateKey - { - public: - DSA_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits, - RandomNumberGenerator& rng); - - DSA_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& group, - const BigInt& private_key = 0); - - bool check_key(RandomNumberGenerator& rng, bool strong) const; - }; - -/** -* Object that can create a DSA signature -*/ -class BOTAN_DLL DSA_Signature_Operation : public PK_Ops::Signature - { - public: - DSA_Signature_Operation(const DSA_PrivateKey& dsa); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return q.bits(); } - - SecureVector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - private: - const BigInt& q; - const BigInt& x; - Fixed_Base_Power_Mod powermod_g_p; - Modular_Reducer mod_q; - }; - -/** -* Object that can verify a DSA signature -*/ -class BOTAN_DLL DSA_Verification_Operation : public PK_Ops::Verification - { - public: - DSA_Verification_Operation(const DSA_PublicKey& dsa); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return q.bits(); } - - bool with_recovery() const { return false; } - - bool verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len); - private: - const BigInt& q; - const BigInt& y; - - Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; - Modular_Reducer mod_p, mod_q; - }; - -} - - -namespace Botan { - -/** -* PRF from ANSI X9.42 -*/ -class BOTAN_DLL X942_PRF : public KDF - { - public: - SecureVector<byte> derive(size_t, const byte[], size_t, - const byte[], size_t) const; - - std::string name() const { return "X942_PRF(" + key_wrap_oid + ")"; } - KDF* clone() const { return new X942_PRF(key_wrap_oid); } - - X942_PRF(const std::string& oid); - private: - std::string key_wrap_oid; - }; - -} - - -namespace Botan { - -/** -* TEA -*/ -class BOTAN_DLL TEA : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(K); } - std::string name() const { return "TEA"; } - BlockCipher* clone() const { return new TEA; } - - TEA() : K(4) {} - private: - void key_schedule(const byte[], size_t); - SecureVector<u32bit> K; - }; - -} - - -namespace Botan { - -/** -* Nyberg-Rueppel Public Key -*/ -class BOTAN_DLL NR_PublicKey : public virtual DL_Scheme_PublicKey - { - public: - std::string algo_name() const { return "NR"; } - - DL_Group::Format group_format() const { return DL_Group::ANSI_X9_57; } - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return group_q().bytes(); } - size_t max_input_bits() const { return (group_q().bits() - 1); } - - NR_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits); - - NR_PublicKey(const DL_Group& group, const BigInt& pub_key); - protected: - NR_PublicKey() {} - }; - -/** -* Nyberg-Rueppel Private Key -*/ -class BOTAN_DLL NR_PrivateKey : public NR_PublicKey, - public virtual DL_Scheme_PrivateKey - { - public: - bool check_key(RandomNumberGenerator& rng, bool strong) const; - - NR_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits, - RandomNumberGenerator& rng); - - NR_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& group, - const BigInt& x = 0); - }; - -/** -* Nyberg-Rueppel signature operation -*/ -class BOTAN_DLL NR_Signature_Operation : public PK_Ops::Signature - { - public: - NR_Signature_Operation(const NR_PrivateKey& nr); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return (q.bits() - 1); } - - SecureVector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - private: - const BigInt& q; - const BigInt& x; - Fixed_Base_Power_Mod powermod_g_p; - Modular_Reducer mod_q; - }; - -/** -* Nyberg-Rueppel verification operation -*/ -class BOTAN_DLL NR_Verification_Operation : public PK_Ops::Verification - { - public: - NR_Verification_Operation(const NR_PublicKey& nr); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return (q.bits() - 1); } - - bool with_recovery() const { return true; } - - SecureVector<byte> verify_mr(const byte msg[], size_t msg_len); - private: - const BigInt& q; - const BigInt& y; - - Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; - Modular_Reducer mod_p, mod_q; - }; - -} - - -namespace Botan { - -/** -* Alleged RC4 -*/ -class BOTAN_DLL ARC4 : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - - void clear(); - std::string name() const; - - StreamCipher* clone() const { return new ARC4(SKIP); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(1, 256); - } - - /** - * @param skip skip this many initial bytes in the keystream - */ - ARC4(size_t skip = 0); - - ~ARC4() { clear(); } - private: - void key_schedule(const byte[], size_t); - void generate(); - - const size_t SKIP; - - byte X, Y; - SecureVector<byte> state; - - SecureVector<byte> buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Rabin-Williams Public Key -*/ -class BOTAN_DLL RW_PublicKey : public virtual IF_Scheme_PublicKey - { - public: - std::string algo_name() const { return "RW"; } - - RW_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - IF_Scheme_PublicKey(alg_id, key_bits) - {} - - RW_PublicKey(const BigInt& mod, const BigInt& exponent) : - IF_Scheme_PublicKey(mod, exponent) - {} - - protected: - RW_PublicKey() {} - }; - -/** -* Rabin-Williams Private Key -*/ -class BOTAN_DLL RW_PrivateKey : public RW_PublicKey, - public IF_Scheme_PrivateKey - { - public: - RW_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits, - RandomNumberGenerator& rng) : - IF_Scheme_PrivateKey(rng, alg_id, key_bits) {} - - RW_PrivateKey(RandomNumberGenerator& rng, - const BigInt& p, const BigInt& q, - const BigInt& e, const BigInt& d = 0, - const BigInt& n = 0) : - IF_Scheme_PrivateKey(rng, p, q, e, d, n) {} - - RW_PrivateKey(RandomNumberGenerator& rng, size_t bits, size_t = 2); - - bool check_key(RandomNumberGenerator& rng, bool) const; - }; - -/** -* Rabin-Williams Signature Operation -*/ -class BOTAN_DLL RW_Signature_Operation : public PK_Ops::Signature - { - public: - RW_Signature_Operation(const RW_PrivateKey& rw); - - size_t max_input_bits() const { return (n.bits() - 1); } - - SecureVector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - private: - const BigInt& n; - const BigInt& e; - const BigInt& q; - const BigInt& c; - - Fixed_Exponent_Power_Mod powermod_d1_p, powermod_d2_q; - Modular_Reducer mod_p; - Blinder blinder; - }; - -/** -* Rabin-Williams Verification Operation -*/ -class BOTAN_DLL RW_Verification_Operation : public PK_Ops::Verification - { - public: - RW_Verification_Operation(const RW_PublicKey& rw) : - n(rw.get_n()), powermod_e_n(rw.get_e(), rw.get_n()) - {} - - size_t max_input_bits() const { return (n.bits() - 1); } - bool with_recovery() const { return true; } - - SecureVector<byte> verify_mr(const byte msg[], size_t msg_len); - - private: - const BigInt& n; - Fixed_Exponent_Power_Mod powermod_e_n; - }; - -} - - -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - -#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - -#define BOTAN_ENDIAN_N2B(x) (x) -#define BOTAN_ENDIAN_B2N(x) (x) - -#define BOTAN_ENDIAN_N2L(x) reverse_bytes(x) -#define BOTAN_ENDIAN_L2N(x) reverse_bytes(x) - -#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - -#define BOTAN_ENDIAN_N2L(x) (x) -#define BOTAN_ENDIAN_L2N(x) (x) - -#define BOTAN_ENDIAN_N2B(x) reverse_bytes(x) -#define BOTAN_ENDIAN_B2N(x) reverse_bytes(x) - -#endif - -#endif - -namespace Botan { - -/** -* Make a u16bit from two bytes -* @param i0 the first byte -* @param i1 the second byte -* @return i0 || i1 -*/ -inline u16bit make_u16bit(byte i0, byte i1) - { - return ((static_cast<u16bit>(i0) << 8) | i1); - } - -/** -* Make a u32bit from four bytes -* @param i0 the first byte -* @param i1 the second byte -* @param i2 the third byte -* @param i3 the fourth byte -* @return i0 || i1 || i2 || i3 -*/ -inline u32bit make_u32bit(byte i0, byte i1, byte i2, byte i3) - { - return ((static_cast<u32bit>(i0) << 24) | - (static_cast<u32bit>(i1) << 16) | - (static_cast<u32bit>(i2) << 8) | - (static_cast<u32bit>(i3))); - } - -/** -* Make a u32bit from eight bytes -* @param i0 the first byte -* @param i1 the second byte -* @param i2 the third byte -* @param i3 the fourth byte -* @param i4 the fifth byte -* @param i5 the sixth byte -* @param i6 the seventh byte -* @param i7 the eighth byte -* @return i0 || i1 || i2 || i3 || i4 || i5 || i6 || i7 -*/ -inline u64bit make_u64bit(byte i0, byte i1, byte i2, byte i3, - byte i4, byte i5, byte i6, byte i7) - { - return ((static_cast<u64bit>(i0) << 56) | - (static_cast<u64bit>(i1) << 48) | - (static_cast<u64bit>(i2) << 40) | - (static_cast<u64bit>(i3) << 32) | - (static_cast<u64bit>(i4) << 24) | - (static_cast<u64bit>(i5) << 16) | - (static_cast<u64bit>(i6) << 8) | - (static_cast<u64bit>(i7))); - } - -/** -* Load a big-endian word -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th T of in, as a big-endian value -*/ -template<typename T> -inline T load_be(const byte in[], size_t off) - { - in += off * sizeof(T); - T out = 0; - for(size_t i = 0; i != sizeof(T); ++i) - out = (out << 8) | in[i]; - return out; - } - -/** -* Load a little-endian word -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th T of in, as a litte-endian value -*/ -template<typename T> -inline T load_le(const byte in[], size_t off) - { - in += off * sizeof(T); - T out = 0; - for(size_t i = 0; i != sizeof(T); ++i) - out = (out << 8) | in[sizeof(T)-1-i]; - return out; - } - -/** -* Load a big-endian u16bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u16bit of in, as a big-endian value -*/ -template<> -inline u16bit load_be<u16bit>(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2B(*(reinterpret_cast<const u16bit*>(in) + off)); -#else - in += off * sizeof(u16bit); - return make_u16bit(in[0], in[1]); -#endif - } - -/** -* Load a little-endian u16bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u16bit of in, as a little-endian value -*/ -template<> -inline u16bit load_le<u16bit>(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2L(*(reinterpret_cast<const u16bit*>(in) + off)); -#else - in += off * sizeof(u16bit); - return make_u16bit(in[1], in[0]); -#endif - } - -/** -* Load a big-endian u32bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u32bit of in, as a big-endian value -*/ -template<> -inline u32bit load_be<u32bit>(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2B(*(reinterpret_cast<const u32bit*>(in) + off)); -#else - in += off * sizeof(u32bit); - return make_u32bit(in[0], in[1], in[2], in[3]); -#endif - } - -/** -* Load a little-endian u32bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u32bit of in, as a little-endian value -*/ -template<> -inline u32bit load_le<u32bit>(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2L(*(reinterpret_cast<const u32bit*>(in) + off)); -#else - in += off * sizeof(u32bit); - return make_u32bit(in[3], in[2], in[1], in[0]); -#endif - } - -/** -* Load a big-endian u64bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u64bit of in, as a big-endian value -*/ -template<> -inline u64bit load_be<u64bit>(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2B(*(reinterpret_cast<const u64bit*>(in) + off)); -#else - in += off * sizeof(u64bit); - return make_u64bit(in[0], in[1], in[2], in[3], - in[4], in[5], in[6], in[7]); -#endif - } - -/** -* Load a little-endian u64bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u64bit of in, as a little-endian value -*/ -template<> -inline u64bit load_le<u64bit>(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2L(*(reinterpret_cast<const u64bit*>(in) + off)); -#else - in += off * sizeof(u64bit); - return make_u64bit(in[7], in[6], in[5], in[4], - in[3], in[2], in[1], in[0]); -#endif - } - -/** -* Load two little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -*/ -template<typename T> -inline void load_le(const byte in[], T& x0, T& x1) - { - x0 = load_le<T>(in, 0); - x1 = load_le<T>(in, 1); - } - -/** -* Load four little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -*/ -template<typename T> -inline void load_le(const byte in[], - T& x0, T& x1, T& x2, T& x3) - { - x0 = load_le<T>(in, 0); - x1 = load_le<T>(in, 1); - x2 = load_le<T>(in, 2); - x3 = load_le<T>(in, 3); - } - -/** -* Load eight little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -* @param x4 where the fifth word will be written -* @param x5 where the sixth word will be written -* @param x6 where the seventh word will be written -* @param x7 where the eighth word will be written -*/ -template<typename T> -inline void load_le(const byte in[], - T& x0, T& x1, T& x2, T& x3, - T& x4, T& x5, T& x6, T& x7) - { - x0 = load_le<T>(in, 0); - x1 = load_le<T>(in, 1); - x2 = load_le<T>(in, 2); - x3 = load_le<T>(in, 3); - x4 = load_le<T>(in, 4); - x5 = load_le<T>(in, 5); - x6 = load_le<T>(in, 6); - x7 = load_le<T>(in, 7); - } - -/** -* Load a variable number of little-endian words -* @param out the output array of words -* @param in the input array of bytes -* @param count how many words are in in -*/ -template<typename T> -inline void load_le(T out[], - const byte in[], - size_t count) - { -#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS) - std::memcpy(out, in, sizeof(T)*count); - -#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - const size_t blocks = count - (count % 4); - const size_t left = count - blocks; - - for(size_t i = 0; i != blocks; i += 4) - bswap_4(out + i); - - for(size_t i = 0; i != left; ++i) - out[blocks+i] = reverse_bytes(out[blocks+i]); -#endif - -#else - for(size_t i = 0; i != count; ++i) - out[i] = load_le<T>(in, i); -#endif - } - -/** -* Load two big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -*/ -template<typename T> -inline void load_be(const byte in[], T& x0, T& x1) - { - x0 = load_be<T>(in, 0); - x1 = load_be<T>(in, 1); - } - -/** -* Load four big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -*/ -template<typename T> -inline void load_be(const byte in[], - T& x0, T& x1, T& x2, T& x3) - { - x0 = load_be<T>(in, 0); - x1 = load_be<T>(in, 1); - x2 = load_be<T>(in, 2); - x3 = load_be<T>(in, 3); - } - -/** -* Load eight big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -* @param x4 where the fifth word will be written -* @param x5 where the sixth word will be written -* @param x6 where the seventh word will be written -* @param x7 where the eighth word will be written -*/ -template<typename T> -inline void load_be(const byte in[], - T& x0, T& x1, T& x2, T& x3, - T& x4, T& x5, T& x6, T& x7) - { - x0 = load_be<T>(in, 0); - x1 = load_be<T>(in, 1); - x2 = load_be<T>(in, 2); - x3 = load_be<T>(in, 3); - x4 = load_be<T>(in, 4); - x5 = load_be<T>(in, 5); - x6 = load_be<T>(in, 6); - x7 = load_be<T>(in, 7); - } - -/** -* Load a variable number of big-endian words -* @param out the output array of words -* @param in the input array of bytes -* @param count how many words are in in -*/ -template<typename T> -inline void load_be(T out[], - const byte in[], - size_t count) - { -#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS) - std::memcpy(out, in, sizeof(T)*count); - -#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - const size_t blocks = count - (count % 4); - const size_t left = count - blocks; - - for(size_t i = 0; i != blocks; i += 4) - bswap_4(out + i); - - for(size_t i = 0; i != left; ++i) - out[blocks+i] = reverse_bytes(out[blocks+i]); -#endif - -#else - for(size_t i = 0; i != count; ++i) - out[i] = load_be<T>(in, i); -#endif - } - -/** -* Store a big-endian u16bit -* @param in the input u16bit -* @param out the byte array to write to -*/ -inline void store_be(u16bit in, byte out[2]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast<u16bit*>(out) = BOTAN_ENDIAN_B2N(in); -#else - out[0] = get_byte(0, in); - out[1] = get_byte(1, in); -#endif - } - -/** -* Store a little-endian u16bit -* @param in the input u16bit -* @param out the byte array to write to -*/ -inline void store_le(u16bit in, byte out[2]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast<u16bit*>(out) = BOTAN_ENDIAN_L2N(in); -#else - out[0] = get_byte(1, in); - out[1] = get_byte(0, in); -#endif - } - -/** -* Store a big-endian u32bit -* @param in the input u32bit -* @param out the byte array to write to -*/ -inline void store_be(u32bit in, byte out[4]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast<u32bit*>(out) = BOTAN_ENDIAN_B2N(in); -#else - out[0] = get_byte(0, in); - out[1] = get_byte(1, in); - out[2] = get_byte(2, in); - out[3] = get_byte(3, in); -#endif - } - -/** -* Store a little-endian u32bit -* @param in the input u32bit -* @param out the byte array to write to -*/ -inline void store_le(u32bit in, byte out[4]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast<u32bit*>(out) = BOTAN_ENDIAN_L2N(in); -#else - out[0] = get_byte(3, in); - out[1] = get_byte(2, in); - out[2] = get_byte(1, in); - out[3] = get_byte(0, in); -#endif - } - -/** -* Store a big-endian u64bit -* @param in the input u64bit -* @param out the byte array to write to -*/ -inline void store_be(u64bit in, byte out[8]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast<u64bit*>(out) = BOTAN_ENDIAN_B2N(in); -#else - out[0] = get_byte(0, in); - out[1] = get_byte(1, in); - out[2] = get_byte(2, in); - out[3] = get_byte(3, in); - out[4] = get_byte(4, in); - out[5] = get_byte(5, in); - out[6] = get_byte(6, in); - out[7] = get_byte(7, in); -#endif - } - -/** -* Store a little-endian u64bit -* @param in the input u64bit -* @param out the byte array to write to -*/ -inline void store_le(u64bit in, byte out[8]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast<u64bit*>(out) = BOTAN_ENDIAN_L2N(in); -#else - out[0] = get_byte(7, in); - out[1] = get_byte(6, in); - out[2] = get_byte(5, in); - out[3] = get_byte(4, in); - out[4] = get_byte(3, in); - out[5] = get_byte(2, in); - out[6] = get_byte(1, in); - out[7] = get_byte(0, in); -#endif - } - -/** -* Store two little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -*/ -template<typename T> -inline void store_le(byte out[], T x0, T x1) - { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - } - -/** -* Store two big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -*/ -template<typename T> -inline void store_be(byte out[], T x0, T x1) - { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - } - -/** -* Store four little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -*/ -template<typename T> -inline void store_le(byte out[], T x0, T x1, T x2, T x3) - { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - store_le(x2, out + (2 * sizeof(T))); - store_le(x3, out + (3 * sizeof(T))); - } - -/** -* Store four big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -*/ -template<typename T> -inline void store_be(byte out[], T x0, T x1, T x2, T x3) - { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - store_be(x2, out + (2 * sizeof(T))); - store_be(x3, out + (3 * sizeof(T))); - } - -/** -* Store eight little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -* @param x4 the fifth word -* @param x5 the sixth word -* @param x6 the seventh word -* @param x7 the eighth word -*/ -template<typename T> -inline void store_le(byte out[], T x0, T x1, T x2, T x3, - T x4, T x5, T x6, T x7) - { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - store_le(x2, out + (2 * sizeof(T))); - store_le(x3, out + (3 * sizeof(T))); - store_le(x4, out + (4 * sizeof(T))); - store_le(x5, out + (5 * sizeof(T))); - store_le(x6, out + (6 * sizeof(T))); - store_le(x7, out + (7 * sizeof(T))); - } - -/** -* Store eight big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -* @param x4 the fifth word -* @param x5 the sixth word -* @param x6 the seventh word -* @param x7 the eighth word -*/ -template<typename T> -inline void store_be(byte out[], T x0, T x1, T x2, T x3, - T x4, T x5, T x6, T x7) - { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - store_be(x2, out + (2 * sizeof(T))); - store_be(x3, out + (3 * sizeof(T))); - store_be(x4, out + (4 * sizeof(T))); - store_be(x5, out + (5 * sizeof(T))); - store_be(x6, out + (6 * sizeof(T))); - store_be(x7, out + (7 * sizeof(T))); - } - -} - - -namespace Botan { - -/** -* CBC Encryption -*/ -class BOTAN_DLL CBC_Encryption : public Keyed_Filter, - private Buffered_Filter - { - public: - std::string name() const; - - void set_iv(const InitializationVector& iv); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CBC_Encryption(BlockCipher* cipher, - BlockCipherModePaddingMethod* padding); - - CBC_Encryption(BlockCipher* cipher, - BlockCipherModePaddingMethod* padding, - const SymmetricKey& key, - const InitializationVector& iv); - - ~CBC_Encryption() { delete cipher; delete padder; } - private: - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - void write(const byte input[], size_t input_length); - void end_msg(); - - BlockCipher* cipher; - const BlockCipherModePaddingMethod* padder; - SecureVector<byte> state; - }; - -/** -* CBC Decryption -*/ -class BOTAN_DLL CBC_Decryption : public Keyed_Filter, - private Buffered_Filter - { - public: - std::string name() const; - - void set_iv(const InitializationVector& iv); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CBC_Decryption(BlockCipher* cipher, - BlockCipherModePaddingMethod* padding); - - CBC_Decryption(BlockCipher* cipher, - BlockCipherModePaddingMethod* padding, - const SymmetricKey& key, - const InitializationVector& iv); - - ~CBC_Decryption() { delete cipher; delete padder; } - private: - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - void write(const byte[], size_t); - void end_msg(); - - BlockCipher* cipher; - const BlockCipherModePaddingMethod* padder; - SecureVector<byte> state, temp; - }; - -} - - -namespace Botan { - -/** -* A class handling runtime CPU feature detection -*/ -class BOTAN_DLL CPUID - { - public: - /** - * Probe the CPU and see what extensions are supported - */ - static void initialize(); - - /** - * Return a best guess of the cache line size - */ - static size_t cache_line_size() { return cache_line; } - - /** - * Check if the processor supports RDTSC - */ - static bool has_rdtsc() - { return x86_processor_flags_has(CPUID_RDTSC_BIT); } - - /** - * Check if the processor supports SSE2 - */ - static bool has_sse2() - { return x86_processor_flags_has(CPUID_SSE2_BIT); } - - /** - * Check if the processor supports SSSE3 - */ - static bool has_ssse3() - { return x86_processor_flags_has(CPUID_SSSE3_BIT); } - - /** - * Check if the processor supports SSE4.1 - */ - static bool has_sse41() - { return x86_processor_flags_has(CPUID_SSE41_BIT); } - - /** - * Check if the processor supports SSE4.2 - */ - static bool has_sse42() - { return x86_processor_flags_has(CPUID_SSE42_BIT); } - - /** - * Check if the processor supports extended AVX vector instructions - */ - static bool has_avx() - { return x86_processor_flags_has(CPUID_AVX_BIT); } - - /** - * Check if the processor supports AES-NI - */ - static bool has_aes_ni() - { return x86_processor_flags_has(CPUID_AESNI_BIT); } - - /** - * Check if the processor supports PCMULUDQ - */ - static bool has_pcmuludq() - { return x86_processor_flags_has(CPUID_PCMUL_BIT); } - - /** - * Check if the processor supports MOVBE - */ - static bool has_movbe() - { return x86_processor_flags_has(CPUID_MOVBE_BIT); } - - /** - * Check if the processor supports RDRAND - */ - static bool has_rdrand() - { return x86_processor_flags_has(CPUID_RDRAND_BIT); } - - /** - * Check if the processor supports AltiVec/VMX - */ - static bool has_altivec() { return altivec_capable; } - private: - enum CPUID_bits { - CPUID_RDTSC_BIT = 4, - CPUID_SSE2_BIT = 26, - CPUID_PCMUL_BIT = 33, - CPUID_SSSE3_BIT = 41, - CPUID_SSE41_BIT = 51, - CPUID_SSE42_BIT = 52, - CPUID_MOVBE_BIT = 54, - CPUID_AESNI_BIT = 57, - CPUID_AVX_BIT = 60, - CPUID_RDRAND_BIT = 62 - }; - - static bool x86_processor_flags_has(u64bit bit) - { - return ((x86_processor_flags >> bit) & 1); - } - - static u64bit x86_processor_flags; - static size_t cache_line; - static bool altivec_capable; - }; - -} - - -namespace Botan { - -/** -* Serpent implementation using SIMD -*/ -class BOTAN_DLL Serpent_SIMD : public Serpent - { - public: - size_t parallelism() const { return 4; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - BlockCipher* clone() const { return new Serpent_SIMD; } - }; - -} - - -namespace Botan { - -/** -* PK_Encryptor Filter -*/ -class BOTAN_DLL PK_Encryptor_Filter : public Filter - { - public: - void write(const byte[], size_t); - void end_msg(); - PK_Encryptor_Filter(PK_Encryptor* c, - RandomNumberGenerator& rng_ref) : - cipher(c), rng(rng_ref) {} - ~PK_Encryptor_Filter() { delete cipher; } - private: - PK_Encryptor* cipher; - RandomNumberGenerator& rng; - SecureVector<byte> buffer; - }; - -/** -* PK_Decryptor Filter -*/ -class BOTAN_DLL PK_Decryptor_Filter : public Filter - { - public: - void write(const byte[], size_t); - void end_msg(); - PK_Decryptor_Filter(PK_Decryptor* c) : cipher(c) {} - ~PK_Decryptor_Filter() { delete cipher; } - private: - PK_Decryptor* cipher; - SecureVector<byte> buffer; - }; - -/** -* PK_Signer Filter -*/ -class BOTAN_DLL PK_Signer_Filter : public Filter - { - public: - void write(const byte[], size_t); - void end_msg(); - - PK_Signer_Filter(PK_Signer* s, - RandomNumberGenerator& rng_ref) : - signer(s), rng(rng_ref) {} - - ~PK_Signer_Filter() { delete signer; } - private: - PK_Signer* signer; - RandomNumberGenerator& rng; - }; - -/** -* PK_Verifier Filter -*/ -class BOTAN_DLL PK_Verifier_Filter : public Filter - { - public: - void write(const byte[], size_t); - void end_msg(); - - void set_signature(const byte[], size_t); - void set_signature(const MemoryRegion<byte>&); - - PK_Verifier_Filter(PK_Verifier* v) : verifier(v) {} - PK_Verifier_Filter(PK_Verifier*, const byte[], size_t); - PK_Verifier_Filter(PK_Verifier*, const MemoryRegion<byte>&); - ~PK_Verifier_Filter() { delete verifier; } - private: - PK_Verifier* verifier; - SecureVector<byte> signature; - }; - -} - - -namespace Botan { - -/** -* XTEA implemented using SIMD operations -*/ -class BOTAN_DLL XTEA_SIMD : public XTEA - { - public: - size_t parallelism() const { return 8; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - BlockCipher* clone() const { return new XTEA_SIMD; } - }; - -} - - -namespace Botan { - -/** -* A queue that knows how to zeroize itself -*/ -class BOTAN_DLL SecureQueue : public Fanout_Filter, public DataSource - { - public: - std::string name() const { return "Queue"; } - - void write(const byte[], size_t); - - size_t read(byte[], size_t); - size_t peek(byte[], size_t, size_t = 0) const; - - bool end_of_data() const; - - /** - * @return number of bytes available in the queue - */ - size_t size() const; - - bool attachable() { return false; } - - /** - * SecureQueue assignment - * @param other the queue to copy - */ - SecureQueue& operator=(const SecureQueue& other); - - /** - * SecureQueue default constructor (creates empty queue) - */ - SecureQueue(); - - /** - * SecureQueue copy constructor - * @param other the queue to copy - */ - SecureQueue(const SecureQueue& other); - - ~SecureQueue() { destroy(); } - private: - void destroy(); - class SecureQueueNode* head; - class SecureQueueNode* tail; - }; - -} - - -namespace Botan { - -/** -* HMAC -*/ -class BOTAN_DLL HMAC : public MessageAuthenticationCode - { - public: - void clear(); - std::string name() const; - MessageAuthenticationCode* clone() const; - - size_t output_length() const { return hash->output_length(); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(0, 2*hash->hash_block_size()); - } - - /** - * @param hash the hash to use for HMACing - */ - HMAC(HashFunction* hash); - ~HMAC() { delete hash; } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - HashFunction* hash; - SecureVector<byte> i_key, o_key; - }; - -} - - -namespace Botan { - -/** -* OpenPGP's S2K -*/ -class BOTAN_DLL OpenPGP_S2K : public PBKDF - { - public: - /** - * @param hash_in the hash function to use - */ - OpenPGP_S2K(HashFunction* hash_in) : hash(hash_in) {} - - ~OpenPGP_S2K() { delete hash; } - - std::string name() const - { - return "OpenPGP-S2K(" + hash->name() + ")"; - } - - PBKDF* clone() const - { - return new OpenPGP_S2K(hash->clone()); - } - - OctetString derive_key(size_t output_len, - const std::string& passphrase, - const byte salt[], size_t salt_len, - size_t iterations) const; - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* Lion is a block cipher construction designed by Ross Anderson and -* Eli Biham, described in "Two Practical and Provably Secure Block -* Ciphers: BEAR and LION". It has a variable block size and is -* designed to encrypt very large blocks (up to a megabyte) - -* http://www.cl.cam.ac.uk/~rja14/Papers/bear-lion.pdf -*/ -class BOTAN_DLL Lion : public BlockCipher - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - size_t block_size() const { return BLOCK_SIZE; } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(2, 2*hash->output_length(), 2); - } - - void clear(); - std::string name() const; - BlockCipher* clone() const; - - /** - * @param hash the hash to use internally - * @param cipher the stream cipher to use internally - * @param block_size the size of the block to use - */ - Lion(HashFunction* hash, - StreamCipher* cipher, - size_t block_size); - - ~Lion() { delete hash; delete cipher; } - private: - void key_schedule(const byte[], size_t); - - const size_t BLOCK_SIZE, LEFT_SIZE, RIGHT_SIZE; - - HashFunction* hash; - StreamCipher* cipher; - SecureVector<byte> key1, key2; - }; - -} - - -namespace Botan { - -/** -* Skipjack, a NSA designed cipher used in Fortezza -*/ -class BOTAN_DLL Skipjack : public Block_Cipher_Fixed_Params<8, 10> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - std::string name() const { return "Skipjack"; } - BlockCipher* clone() const { return new Skipjack; } - - Skipjack() : FTAB(2560) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector<byte> FTAB; - }; - -} - - -namespace Botan { - -namespace FPE { - -/** -* Encrypt X from and onto the group Z_n using key and tweak -* @param n the modulus -* @param X the plaintext as a BigInt -* @param key a random key -* @param tweak will modify the ciphertext (think of as an IV) -*/ -BigInt BOTAN_DLL fe1_encrypt(const BigInt& n, const BigInt& X, - const SymmetricKey& key, - const MemoryRegion<byte>& tweak); - -/** -* Decrypt X from and onto the group Z_n using key and tweak -* @param n the modulus -* @param X the ciphertext as a BigInt -* @param key is the key used for encryption -* @param tweak the same tweak used for encryption -*/ -BigInt BOTAN_DLL fe1_decrypt(const BigInt& n, const BigInt& X, - const SymmetricKey& key, - const MemoryRegion<byte>& tweak); - -} - -} - - -namespace Botan { - -/** -* This class represents ECDH Public Keys. -*/ -class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey - { - public: - - ECDH_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - EC_PublicKey(alg_id, key_bits) {} - - /** - * Construct a public key from a given public point. - * @param dom_par the domain parameters associated with this key - * @param public_point the public point defining this key - */ - ECDH_PublicKey(const EC_Group& dom_par, - const PointGFp& public_point) : - EC_PublicKey(dom_par, public_point) {} - - /** - * Get this keys algorithm name. - * @return this keys algorithm name - */ - std::string algo_name() const { return "ECDH"; } - - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - - * @return maximum number of input bits - */ - size_t max_input_bits() const { return domain().get_order().bits(); } - - /** - * @return public point value - */ - MemoryVector<byte> public_value() const - { return EC2OSP(public_point(), PointGFp::UNCOMPRESSED); } - - protected: - ECDH_PublicKey() {} - }; - -/** -* This class represents ECDH Private Keys. -*/ -class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey, - public EC_PrivateKey, - public PK_Key_Agreement_Key - { - public: - - ECDH_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion<byte>& key_bits) : - EC_PrivateKey(alg_id, key_bits) {} - - /** - * Generate a new private key - * @param rng a random number generator - * @param domain parameters to used for this key - * @param x the private key; if zero, a new random key is generated - */ - ECDH_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& x = 0) : - EC_PrivateKey(rng, domain, x) {} - - MemoryVector<byte> public_value() const - { return ECDH_PublicKey::public_value(); } - }; - -/** -* ECDH operation -*/ -class BOTAN_DLL ECDH_KA_Operation : public PK_Ops::Key_Agreement - { - public: - ECDH_KA_Operation(const ECDH_PrivateKey& key); - - SecureVector<byte> agree(const byte w[], size_t w_len); - private: - const CurveGFp& curve; - const BigInt& cofactor; - BigInt l_times_priv; - }; - -} - - -namespace Botan { - -/** -* AES-128 -*/ -class BOTAN_DLL AES_128 : public Block_Cipher_Fixed_Params<16, 16> - { - public: - AES_128() : EK(40), DK(40), ME(16), MD(16) {} - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - - std::string name() const { return "AES-128"; } - BlockCipher* clone() const { return new AES_128; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector<u32bit> EK, DK; - SecureVector<byte> ME, MD; - }; - -/** -* AES-192 -*/ -class BOTAN_DLL AES_192 : public Block_Cipher_Fixed_Params<16, 24> - { - public: - AES_192() : EK(48), DK(48), ME(16), MD(16) {} - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - - std::string name() const { return "AES-192"; } - BlockCipher* clone() const { return new AES_192; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector<u32bit> EK, DK; - SecureVector<byte> ME, MD; - }; - -/** -* AES-256 -*/ -class BOTAN_DLL AES_256 : public Block_Cipher_Fixed_Params<16, 32> - { - public: - AES_256() : EK(56), DK(56), ME(16), MD(16) {} - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - - std::string name() const { return "AES-256"; } - BlockCipher* clone() const { return new AES_256; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector<u32bit> EK, DK; - SecureVector<byte> ME, MD; - }; - -} - - -namespace Botan { - -/** -* Rivest's Package Tranform -* @param rng the random number generator to use -* @param cipher the block cipher to use -* @param input the input data buffer -* @param input_len the length of the input data in bytes -* @param output the output data buffer (must be at least -* input_len + cipher->BLOCK_SIZE bytes long) -*/ -void BOTAN_DLL aont_package(RandomNumberGenerator& rng, - BlockCipher* cipher, - const byte input[], size_t input_len, - byte output[]); - -/** -* Rivest's Package Tranform (Inversion) -* @param cipher the block cipher to use -* @param input the input data buffer -* @param input_len the length of the input data in bytes -* @param output the output data buffer (must be at least -* input_len - cipher->BLOCK_SIZE bytes long) -*/ -void BOTAN_DLL aont_unpackage(BlockCipher* cipher, - const byte input[], size_t input_len, - byte output[]); - -} - - -namespace Botan { - -/** -* Combines two hash functions using a Feistel scheme. Described in -* "On the Security of Hash Function Combiners", Anja Lehmann -*/ -class BOTAN_DLL Comb4P : public HashFunction - { - public: - /** - * @param h1 the first hash - * @param h2 the second hash - */ - Comb4P(HashFunction* h1, HashFunction* h2); - - ~Comb4P() { delete hash1; delete hash2; } - - size_t hash_block_size() const; - - size_t output_length() const - { - return hash1->output_length() + hash2->output_length(); - } - - HashFunction* clone() const - { - return new Comb4P(hash1->clone(), hash2->clone()); - } - - std::string name() const - { - return "Comb4P(" + hash1->name() + "," + hash2->name() + ")"; - } - - void clear(); - private: - void add_data(const byte input[], size_t length); - void final_result(byte out[]); - - HashFunction* hash1; - HashFunction* hash2; - }; - -} - - -namespace Botan { - -/** -* A split secret, using the format from draft-mcgrew-tss-03 -*/ -class BOTAN_DLL RTSS_Share - { - public: - /** - * @param M the number of shares needed to reconstruct - * @param N the number of shares generated - * @param secret the secret to split - * @param secret_len the length of the secret - * @param identifier the 16 byte share identifier - * @param rng the random number generator to use - */ - static std::vector<RTSS_Share> - split(byte M, byte N, - const byte secret[], u16bit secret_len, - const byte identifier[16], - RandomNumberGenerator& rng); - - /** - * @param shares the list of shares - */ - static SecureVector<byte> - reconstruct(const std::vector<RTSS_Share>& shares); - - RTSS_Share() {} - - /** - * @param hex_input the share encoded in hexadecimal - */ - RTSS_Share(const std::string& hex_input); - - /** - * @return hex representation - */ - std::string to_string() const; - - /** - * @return share identifier - */ - byte share_id() const; - - /** - * @return size of this share in bytes - */ - size_t size() const { return contents.size(); } - - /** - * @return if this TSS share was initialized or not - */ - bool initialized() const { return (contents.size() > 0); } - private: - SecureVector<byte> contents; - }; - -} - - -namespace Botan { - -/** -* RC2 -*/ -class BOTAN_DLL RC2 : public Block_Cipher_Fixed_Params<8, 1, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - /** - * Return the code of the effective key bits - * @param bits key length - * @return EKB code - */ - static byte EKB_code(size_t bits); - - void clear() { zeroise(K); } - std::string name() const { return "RC2"; } - BlockCipher* clone() const { return new RC2; } - - RC2() : K(64) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector<u16bit> K; - }; - -} - - -namespace Botan { - -/** -* DJB's Salsa20 (and XSalsa20) -*/ -class BOTAN_DLL Salsa20 : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - - void set_iv(const byte iv[], size_t iv_len); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == 8 || iv_len == 24); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(16, 32, 16); - } - - void clear(); - std::string name() const; - StreamCipher* clone() const { return new Salsa20; } - - Salsa20() : state(16), buffer(64), position(0) {} - private: - void key_schedule(const byte key[], size_t key_len); - - SecureVector<u32bit> state; - SecureVector<byte> buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* RIPEMD-128 -*/ -class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction - { - public: - std::string name() const { return "RIPEMD-128"; } - size_t output_length() const { return 16; } - HashFunction* clone() const { return new RIPEMD_128; } - - void clear(); - - RIPEMD_128() : MDx_HashFunction(64, false, true), M(16), digest(4) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector<u32bit> M, digest; - }; - -} - - -namespace Botan { - -/** -* 24-bit cyclic redundancy check -*/ -class BOTAN_DLL CRC24 : public HashFunction - { - public: - std::string name() const { return "CRC24"; } - size_t output_length() const { return 3; } - HashFunction* clone() const { return new CRC24; } - - void clear() { crc = 0xB704CE; } - - CRC24() { clear(); } - ~CRC24() { clear(); } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - u32bit crc; - }; - -} - - -namespace Botan { - -/** -* PKCS #5 v1 PBKDF, aka PBKDF1 -* Can only generate a key up to the size of the hash output. -* Unless needed for backwards compatability, use PKCS5_PBKDF2 -*/ -class BOTAN_DLL PKCS5_PBKDF1 : public PBKDF - { - public: - /** - * Create a PKCS #5 instance using the specified hash function. - * @param hash_in pointer to a hash function object to use - */ - PKCS5_PBKDF1(HashFunction* hash_in) : hash(hash_in) {} - - /** - * Copy constructor - * @param other the object to copy - */ - PKCS5_PBKDF1(const PKCS5_PBKDF1& other) : - PBKDF(), hash(other.hash->clone()) {} - - ~PKCS5_PBKDF1() { delete hash; } - - std::string name() const - { - return "PBKDF1(" + hash->name() + ")"; - } - - PBKDF* clone() const - { - return new PKCS5_PBKDF1(hash->clone()); - } - - OctetString derive_key(size_t output_len, - const std::string& passphrase, - const byte salt[], size_t salt_len, - size_t iterations) const; - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* This class represents X.509 Certificate Authorities (CAs). -*/ -class BOTAN_DLL X509_CA - { - public: - - /** - * Sign a PKCS#10 Request. - * @param req the request to sign - * @param rng the rng to use - * @param not_before the starting time for the certificate - * @param not_after the expiration time for the certificate - * @return resulting certificate - */ - X509_Certificate sign_request(const PKCS10_Request& req, - RandomNumberGenerator& rng, - const X509_Time& not_before, - const X509_Time& not_after); - - /** - * Get the certificate of this CA. - * @return CA certificate - */ - X509_Certificate ca_certificate() const; - - /** - * Create a new and empty CRL for this CA. - * @param rng the random number generator to use - * @param next_update the time to set in next update in seconds - * as the offset from the current time - * @return new CRL - */ - X509_CRL new_crl(RandomNumberGenerator& rng, - u32bit next_update = 0) const; - - /** - * Create a new CRL by with additional entries. - * @param last_crl the last CRL of this CA to add the new entries to - * @param new_entries contains the new CRL entries to be added to the CRL - * @param rng the random number generator to use - * @param next_update the time to set in next update in seconds - * as the offset from the current time - */ - X509_CRL update_crl(const X509_CRL& last_crl, - const std::vector<CRL_Entry>& new_entries, - RandomNumberGenerator& rng, - u32bit next_update = 0) const; - - /** - * Interface for creating new certificates - * @param signer a signing object - * @param rng a random number generator - * @param sig_algo the signature algorithm identifier - * @param pub_key the serialized public key - * @param not_before the start time of the certificate - * @param not_after the end time of the certificate - * @param issuer_dn the DN of the issuer - * @param subject_dn the DN of the subject - * @param extensions an optional list of certificate extensions - * @returns newly minted certificate - */ - static X509_Certificate make_cert(PK_Signer* signer, - RandomNumberGenerator& rng, - const AlgorithmIdentifier& sig_algo, - const MemoryRegion<byte>& pub_key, - const X509_Time& not_before, - const X509_Time& not_after, - const X509_DN& issuer_dn, - const X509_DN& subject_dn, - const Extensions& extensions); - - /** - * Create a new CA object. - * @param ca_certificate the certificate of the CA - * @param key the private key of the CA - * @param hash_fn name of a hash function to use for signing - */ - X509_CA(const X509_Certificate& ca_certificate, - const Private_Key& key, - const std::string& hash_fn); - - ~X509_CA(); - private: - X509_CA(const X509_CA&) {} - X509_CA& operator=(const X509_CA&) { return (*this); } - - X509_CRL make_crl(const std::vector<CRL_Entry>& entries, - u32bit crl_number, u32bit next_update, - RandomNumberGenerator& rng) const; - - AlgorithmIdentifier ca_sig_algo; - X509_Certificate cert; - PK_Signer* signer; - }; - -/** -* Choose the default signature format for a certain public key signature -* scheme. -* @param key will be the key to choose a padding scheme for -* @param hash_fn is the desired hash function -* @param alg_id will be set to the chosen scheme -* @return A PK_Signer object for generating signatures -*/ -BOTAN_DLL PK_Signer* choose_sig_format(const Private_Key& key, - const std::string& hash_fn, - AlgorithmIdentifier& alg_id); - -} - - -namespace Botan { - -namespace OIDS { - -/** -* Register an OID to string mapping. -* @param oid the oid to register -* @param name the name to be associated with the oid -*/ -BOTAN_DLL void add_oid(const OID& oid, const std::string& name); - -/** -* See if an OID exists in the internal table. -* @param oid the oid to check for -* @return true if the oid is registered -*/ -BOTAN_DLL bool have_oid(const std::string& oid); - -/** -* Resolve an OID -* @param oid the OID to look up -* @return name associated with this OID -*/ -BOTAN_DLL std::string lookup(const OID& oid); - -/** -* Find the OID to a name. The lookup will be performed in the -* general OID section of the configuration. -* @param name the name to resolve -* @return OID associated with the specified name -*/ -BOTAN_DLL OID lookup(const std::string& name); - -/** -* Tests whether the specified OID stands for the specified name. -* @param oid the OID to check -* @param name the name to check -* @return true if the specified OID stands for the specified name -*/ -BOTAN_DLL bool name_of(const OID& oid, const std::string& name); - -} - -} - - -namespace Botan { - -/** -* EAX Base Class -*/ -class BOTAN_DLL EAX_Base : public Keyed_Filter - { - public: - void set_key(const SymmetricKey& key); - void set_iv(const InitializationVector& iv); - - /** - * Set some additional data that is not included in the - * ciphertext but that will be authenticated. - * @param header the header contents - * @param header_len length of header in bytes - */ - void set_header(const byte header[], size_t header_len); - - /** - * @return name of this mode - */ - std::string name() const; - - bool valid_keylength(size_t key_len) const; - - /** - * EAX supports arbitrary IV lengths - */ - bool valid_iv_length(size_t) const { return true; } - - ~EAX_Base() { delete ctr; delete cmac; } - protected: - /** - * @param cipher the cipher to use - * @param tag_size is how big the auth tag will be - */ - EAX_Base(BlockCipher* cipher, size_t tag_size); - void start_msg(); - - /** - * The block size of the underlying cipher - */ - const size_t BLOCK_SIZE; - - /** - * The requested tag name - */ - const size_t TAG_SIZE; - - /** - * The name of the cipher - */ - std::string cipher_name; - - /** - * The stream cipher (CTR mode) - */ - StreamCipher* ctr; - - /** - * The MAC (CMAC) - */ - MessageAuthenticationCode* cmac; - - /** - * The MAC of the nonce - */ - SecureVector<byte> nonce_mac; - - /** - * The MAC of the header - */ - SecureVector<byte> header_mac; - - /** - * A buffer for CTR mode encryption - */ - SecureVector<byte> ctr_buf; - }; - -/** -* EAX Encryption -*/ -class BOTAN_DLL EAX_Encryption : public EAX_Base - { - public: - /** - * @param ciph the cipher to use - * @param tag_size is how big the auth tag will be - */ - EAX_Encryption(BlockCipher* ciph, size_t tag_size = 0) : - EAX_Base(ciph, tag_size) {} - - /** - * @param ciph the cipher to use - * @param key the key to use - * @param iv the initially set IV - * @param tag_size is how big the auth tag will be - */ - EAX_Encryption(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv, - size_t tag_size) : EAX_Base(ciph, tag_size) - { - set_key(key); - set_iv(iv); - } - private: - void write(const byte[], size_t); - void end_msg(); - }; - -/** -* EAX Decryption -*/ -class BOTAN_DLL EAX_Decryption : public EAX_Base - { - public: - /** - * @param ciph the cipher to use - * @param tag_size is how big the auth tag will be - */ - EAX_Decryption(BlockCipher* ciph, size_t tag_size = 0); - - /** - * @param ciph the cipher to use - * @param key the key to use - * @param iv the initially set IV - * @param tag_size is how big the auth tag will be - */ - EAX_Decryption(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv, - size_t tag_size = 0); - private: - void write(const byte[], size_t); - void do_write(const byte[], size_t); - void end_msg(); - - SecureVector<byte> queue; - size_t queue_start, queue_end; - }; - -} - - -namespace Botan { - -/** -* CMAC, also known as OMAC1 -*/ -class BOTAN_DLL CMAC : public MessageAuthenticationCode - { - public: - std::string name() const; - size_t output_length() const { return e->block_size(); } - MessageAuthenticationCode* clone() const; - - void clear(); - - Key_Length_Specification key_spec() const - { - return e->key_spec(); - } - - /** - * CMAC's polynomial doubling operation - * @param in the input - * @param polynomial the byte value of the polynomial - */ - static SecureVector<byte> poly_double(const MemoryRegion<byte>& in, - byte polynomial); - - /** - * @param cipher the underlying block cipher to use - */ - CMAC(BlockCipher* cipher); - ~CMAC(); - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - BlockCipher* e; - SecureVector<byte> buffer, state, B, P; - size_t position; - byte polynomial; - }; - -} - - -namespace Botan { - -/** -* Skein-512, a SHA-3 candidate -*/ -class BOTAN_DLL Skein_512 : public HashFunction - { - public: - /** - * @param output_bits the output size of Skein in bits - * @param personalization is a string that will paramaterize the - * hash output - */ - Skein_512(size_t output_bits = 512, - const std::string& personalization = ""); - - size_t hash_block_size() const { return 64; } - size_t output_length() const { return output_bits / 8; } - - HashFunction* clone() const; - std::string name() const; - void clear(); - private: - void add_data(const byte input[], size_t length); - void final_result(byte out[]); - - std::string personalization; - size_t output_bits; - - SecureVector<u64bit> H; - SecureVector<u64bit> T; - SecureVector<byte> buffer; - size_t buf_pos; - }; - -} - - -namespace Botan { - -/** -* CBC encryption with ciphertext stealing -*/ -class BOTAN_DLL CTS_Encryption : public Keyed_Filter - { - public: - std::string name() const { return cipher->name() + "/CTS"; } - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CTS_Encryption(BlockCipher* cipher); - - CTS_Encryption(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv); - - ~CTS_Encryption() { delete cipher; } - private: - void write(const byte[], size_t); - void end_msg(); - void encrypt(const byte[]); - - BlockCipher* cipher; - SecureVector<byte> buffer, state; - size_t position; - }; - -/** -* CBC decryption with ciphertext stealing -*/ -class BOTAN_DLL CTS_Decryption : public Keyed_Filter - { - public: - std::string name() const { return cipher->name() + "/CTS"; } - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CTS_Decryption(BlockCipher* cipher); - - CTS_Decryption(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv); - - ~CTS_Decryption() { delete cipher; } - private: - void write(const byte[], size_t); - void end_msg(); - void decrypt(const byte[]); - - BlockCipher* cipher; - SecureVector<byte> buffer, state, temp; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Factory function for PBEs. -* @param algo_spec the name of the PBE algorithm to retrieve -* @return pointer to a PBE with randomly created parameters -*/ -BOTAN_DLL PBE* get_pbe(const std::string& algo_spec); - -/** -* Factory function for PBEs. -* @param pbe_oid the oid of the desired PBE -* @param params a DataSource providing the DER encoded parameters to use -* @return pointer to the PBE with the specified parameters -*/ -BOTAN_DLL PBE* get_pbe(const OID& pbe_oid, - DataSource& params); - -} - - -namespace Botan { - -/** -* Public key encryptor factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the encryptor -* @param eme determines the algorithm and encoding -* @return public key encryptor object -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Encryptor* get_pk_encryptor(const Public_Key& key, - const std::string& eme) - { - return new PK_Encryptor_EME(key, eme); - } - -/** -* Public key decryptor factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the decryptor -* @param eme determines the algorithm and encoding -* @return public key decryptor object -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Decryptor* get_pk_decryptor(const Private_Key& key, - const std::string& eme) - { - return new PK_Decryptor_EME(key, eme); - } - -/** -* Public key signer factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the signer -* @param emsa determines the algorithm, encoding and hash algorithm -* @param sig_format the signature format to be used -* @return public key signer object -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Signer* get_pk_signer(const Private_Key& key, - const std::string& emsa, - Signature_Format sig_format = IEEE_1363) - { - return new PK_Signer(key, emsa, sig_format); - } - -/** -* Public key verifier factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the verifier -* @param emsa determines the algorithm, encoding and hash algorithm -* @param sig_format the signature format to be used -* @return public key verifier object -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Verifier* get_pk_verifier(const Public_Key& key, - const std::string& emsa, - Signature_Format sig_format = IEEE_1363) - { - return new PK_Verifier(key, emsa, sig_format); - } - -/** -* Public key key agreement factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the key agreement -* @param kdf the kdf algorithm to use -* @return key agreement algorithm -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Key_Agreement* get_pk_kas(const PK_Key_Agreement_Key& key, - const std::string& kdf) - { - return new PK_Key_Agreement(key, kdf); - } - -} - - -namespace Botan { - -/** -* IDEA -*/ -class BOTAN_DLL IDEA : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); zeroise(DK); } - std::string name() const { return "IDEA"; } - BlockCipher* clone() const { return new IDEA; } - - IDEA() : EK(52), DK(52) {} - protected: - /** - * @return const reference to encryption subkeys - */ - const SecureVector<u16bit>& get_EK() const { return EK; } - - /** - * @return const reference to decryption subkeys - */ - const SecureVector<u16bit>& get_DK() const { return DK; } - - private: - void key_schedule(const byte[], size_t); - SecureVector<u16bit> EK, DK; - }; - -} - - -namespace Botan { - -/** -* Return the PKCS #1 hash identifier -* @see RFC 3447 section 9.2 -* @param hash_name the name of the hash function -* @return byte sequence identifying the hash -* @throw Invalid_Argument if the hash has no known PKCS #1 hash id -*/ -BOTAN_DLL MemoryVector<byte> pkcs_hash_id(const std::string& hash_name); - -/** -* Return the IEEE 1363 hash identifier -* @param hash_name the name of the hash function -* @return byte code identifying the hash, or 0 if not known -*/ -BOTAN_DLL byte ieee1363_hash_id(const std::string& hash_name); - -} - - -namespace Botan { - -/** -* MGF1 from PKCS #1 v2.0 -*/ -class BOTAN_DLL MGF1 : public MGF - { - public: - void mask(const byte[], size_t, byte[], size_t) const; - - /** - MGF1 constructor: takes ownership of hash - */ - MGF1(HashFunction* hash); - - ~MGF1(); - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* IEEE P1619 XTS Encryption -*/ -class BOTAN_DLL XTS_Encryption : public Keyed_Filter, - private Buffered_Filter - { - public: - void set_key(const SymmetricKey& key); - void set_iv(const InitializationVector& iv); - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - std::string name() const; - - XTS_Encryption(BlockCipher* ciph); - - XTS_Encryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv); - - ~XTS_Encryption() { delete cipher; delete cipher2; } - private: - void write(const byte[], size_t); - void end_msg(); - - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - BlockCipher* cipher; - BlockCipher* cipher2; - SecureVector<byte> tweak; - }; - -/** -* IEEE P1619 XTS Encryption -*/ -class BOTAN_DLL XTS_Decryption : public Keyed_Filter, - private Buffered_Filter - { - public: - void set_key(const SymmetricKey& key); - void set_iv(const InitializationVector& iv); - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - std::string name() const; - - XTS_Decryption(BlockCipher* ciph); - - XTS_Decryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv); - - ~XTS_Decryption() { delete cipher; delete cipher2; } - private: - void write(const byte[], size_t); - void end_msg(); - - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - BlockCipher* cipher; - BlockCipher* cipher2; - SecureVector<byte> tweak; - }; - -} - - -namespace Botan { - -/** -* Struct representing a particular date and time -*/ -struct BOTAN_DLL calendar_point - { - /** The year */ - u32bit year; - - /** The month, 1 through 12 for Jan to Dec */ - byte month; - - /** The day of the month, 1 through 31 (or 28 or 30 based on month */ - byte day; - - /** Hour in 24-hour form, 0 to 23 */ - byte hour; - - /** Minutes in the hour, 0 to 60 */ - byte minutes; - - /** Seconds in the minute, 0 to 60, but might be slightly - larger to deal with leap seconds on some systems - */ - byte seconds; - - /** - * Initialize a calendar_point - * @param y the year - * @param mon the month - * @param d the day - * @param h the hour - * @param min the minute - * @param sec the second - */ - calendar_point(u32bit y, byte mon, byte d, byte h, byte min, byte sec) : - year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {} - }; - -/** -* @param time_point a time point from the system clock -* @return calendar_point object representing this time point -*/ -BOTAN_DLL calendar_point calendar_value(u64bit time_point); - -/** -* @return seconds resolution timestamp, unknown epoch -*/ -BOTAN_DLL u64bit system_time(); - -/** -* @return nanoseconds resolution timestamp, unknown epoch -*/ -BOTAN_DLL u64bit get_nanoseconds_clock(); - -} - - -namespace Botan { - -/** -* EMSA-Raw - sign inputs directly -* Don't use this unless you know what you are doing. -*/ -class BOTAN_DLL EMSA_Raw : public EMSA - { - private: - void update(const byte[], size_t); - SecureVector<byte> raw_data(); - - SecureVector<byte> encoding_of(const MemoryRegion<byte>&, size_t, - RandomNumberGenerator&); - bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - size_t); - - SecureVector<byte> message; - }; - -} - - -namespace Botan { - -/** -* Perform base64 encoding -* @param output an array of at least input_length*4/3 bytes -* @param input is some binary data -* @param input_length length of input in bytes -* @param input_consumed is an output parameter which says how many -* bytes of input were actually consumed. If less than -* input_length, then the range input[consumed:length] -* should be passed in later along with more input. -* @param final_inputs true iff this is the last input, in which case - padding chars will be applied if needed -* @return number of bytes written to output -*/ -size_t BOTAN_DLL base64_encode(char output[], - const byte input[], - size_t input_length, - size_t& input_consumed, - bool final_inputs); - -/** -* Perform base64 encoding -* @param input some input -* @param input_length length of input in bytes -* @return base64adecimal representation of input -*/ -std::string BOTAN_DLL base64_encode(const byte input[], - size_t input_length); - -/** -* Perform base64 encoding -* @param input some input -* @return base64adecimal representation of input -*/ -std::string BOTAN_DLL base64_encode(const MemoryRegion<byte>& input); - -/** -* Perform base64 decoding -* @param output an array of at least input_length*3/4 bytes -* @param input some base64 input -* @param input_length length of input in bytes -* @param input_consumed is an output parameter which says how many -* bytes of input were actually consumed. If less than -* input_length, then the range input[consumed:length] -* should be passed in later along with more input. -* @param final_inputs true iff this is the last input, in which case - padding is allowed -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL base64_decode(byte output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool final_inputs, - bool ignore_ws = true); - -/** -* Perform base64 decoding -* @param output an array of at least input_length*3/4 bytes -* @param input some base64 input -* @param input_length length of input in bytes -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL base64_decode(byte output[], - const char input[], - size_t input_length, - bool ignore_ws = true); - -/** -* Perform base64 decoding -* @param output an array of at least input_length/3*4 bytes -* @param input some base64 input -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL base64_decode(byte output[], - const std::string& input, - bool ignore_ws = true); - -/** -* Perform base64 decoding -* @param input some base64 input -* @param input_length the length of input in bytes -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return decoded base64 output -*/ -SecureVector<byte> BOTAN_DLL base64_decode(const char input[], - size_t input_length, - bool ignore_ws = true); - -/** -* Perform base64 decoding -* @param input some base64 input -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return decoded base64 output -*/ -SecureVector<byte> BOTAN_DLL base64_decode(const std::string& input, - bool ignore_ws = true); - -} - - -namespace Botan { - -/** -* PRF used in TLS 1.0/1.1 -*/ -class BOTAN_DLL TLS_PRF : public KDF - { - public: - SecureVector<byte> derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte seed[], size_t seed_len) const; - - std::string name() const { return "TLS-PRF"; } - KDF* clone() const { return new TLS_PRF; } - - TLS_PRF(); - ~TLS_PRF(); - private: - MessageAuthenticationCode* hmac_md5; - MessageAuthenticationCode* hmac_sha1; - }; - -/** -* PRF used in TLS 1.2 -*/ -class BOTAN_DLL TLS_12_PRF : public KDF - { - public: - SecureVector<byte> derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte seed[], size_t seed_len) const; - - std::string name() const { return "TLSv12-PRF(" + hmac->name() + ")"; } - KDF* clone() const { return new TLS_12_PRF(hmac->clone()); } - - TLS_12_PRF(MessageAuthenticationCode* hmac); - ~TLS_12_PRF(); - private: - MessageAuthenticationCode* hmac; - }; - -} - - -namespace Botan { - -/** -* EMSA4 aka PSS-R -*/ -class BOTAN_DLL EMSA4 : public EMSA - { - public: - /** - * @param hash the hash object to use - */ - EMSA4(HashFunction* hash); - - /** - * @param hash the hash object to use - * @param salt_size the size of the salt to use in bytes - */ - EMSA4(HashFunction* hash, size_t salt_size); - - ~EMSA4() { delete hash; delete mgf; } - private: - void update(const byte[], size_t); - SecureVector<byte> raw_data(); - - SecureVector<byte> encoding_of(const MemoryRegion<byte>&, size_t, - RandomNumberGenerator& rng); - bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - size_t); - - size_t SALT_SIZE; - HashFunction* hash; - const MGF* mgf; - }; - -} - - -namespace Botan { - -/** -* Camellia-128 -*/ -class BOTAN_DLL Camellia_128 : public Block_Cipher_Fixed_Params<16, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { SK.clear(); } - std::string name() const { return "Camellia-128"; } - BlockCipher* clone() const { return new Camellia_128; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector<u64bit> SK; - }; - -/** -* Camellia-192 -*/ -class BOTAN_DLL Camellia_192 : public Block_Cipher_Fixed_Params<16, 24> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { SK.clear(); } - std::string name() const { return "Camellia-192"; } - BlockCipher* clone() const { return new Camellia_192; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector<u64bit> SK; - }; - -/** -* Camellia-256 -*/ -class BOTAN_DLL Camellia_256 : public Block_Cipher_Fixed_Params<16, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { SK.clear(); } - std::string name() const { return "Camellia-256"; } - BlockCipher* clone() const { return new Camellia_256; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector<u64bit> SK; - }; - -} - - -namespace Botan { - -/** -* MD4 -*/ -class BOTAN_DLL MD4 : public MDx_HashFunction - { - public: - std::string name() const { return "MD4"; } - size_t output_length() const { return 16; } - HashFunction* clone() const { return new MD4; } - - void clear(); - - MD4() : MDx_HashFunction(64, false, true), M(16), digest(4) - { clear(); } - protected: - void compress_n(const byte input[], size_t blocks); - void copy_out(byte[]); - - /** - * The message buffer, exposed for use by subclasses (x86 asm) - */ - SecureVector<u32bit> M; - - /** - * The digest value, exposed for use by subclasses (x86 asm) - */ - SecureVector<u32bit> digest; - }; - -} - - -namespace Botan { - -/** -* Turing -*/ -class BOTAN_DLL Turing : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - void set_iv(const byte iv[], size_t iv_length); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len % 4 == 0 && iv_len <= 16); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(4, 32, 4); - } - - void clear(); - std::string name() const { return "Turing"; } - StreamCipher* clone() const { return new Turing; } - - Turing() : S0(256), S1(256), S2(256), S3(256), - R(17), buffer(340), position(0) {} - - private: - void key_schedule(const byte[], size_t); - void generate(); - - static u32bit fixedS(u32bit); - - static const u32bit Q_BOX[256]; - static const byte SBOX[256]; - - SecureVector<u32bit> S0, S1, S2, S3; - SecureVector<u32bit> R; - SecureVector<u32bit> K; - SecureVector<byte> buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* SRP6a Client side -* @param username the username we are attempting login for -* @param password the password we are attempting to use -* @param group_id specifies the shared SRP group -* @param hash_id specifies a secure hash function -* @param salt is the salt value sent by the server -* @param B is the server's public value -* @param rng is a random number generator -* -* @return (A,K) the client public key and the shared secret key -*/ -std::pair<BigInt,SymmetricKey> -BOTAN_DLL srp6_client_agree(const std::string& username, - const std::string& password, - const std::string& group_id, - const std::string& hash_id, - const MemoryRegion<byte>& salt, - const BigInt& B, - RandomNumberGenerator& rng); - -/** -* Generate a new SRP-6 verifier -* @param identifier a username or other client identifier -* @param password the secret used to authenticate user -* @param salt a randomly chosen value, at least 128 bits long -*/ -BigInt BOTAN_DLL generate_srp6_verifier(const std::string& identifier, - const std::string& password, - const MemoryRegion<byte>& salt, - const std::string& group_id, - const std::string& hash_id); - -/** -* Return the group id for this SRP param set, or else thrown an -* exception -*/ -std::string BOTAN_DLL srp6_group_identifier(const BigInt& N, const BigInt& g); - -/** -* Represents a SRP-6a server session -*/ -class BOTAN_DLL SRP6_Server_Session - { - public: - /** - * Server side step 1 - * @param v the verification value saved from client registration - */ - BigInt step1(const BigInt& v, - const std::string& group_id, - const std::string& hash_id, - RandomNumberGenerator& rng); - - SymmetricKey step2(const BigInt& A); - - private: - std::string hash_id; - BigInt B, b, v, S, p; - size_t p_bytes; - }; - -} - - -namespace Botan { - -/** -* SAFER-SK -*/ -class BOTAN_DLL SAFER_SK : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - std::string name() const; - BlockCipher* clone() const; - - /** - * @param rounds the number of rounds to use - must be between 1 - * and 13 - */ - SAFER_SK(size_t rounds); - private: - size_t get_rounds() const { return (EK.size() - 8) / 16; } - void key_schedule(const byte[], size_t); - - SecureVector<byte> EK; - }; - -} - - -namespace Botan { - -/** -* CAST-128 -*/ -class BOTAN_DLL CAST_128 : public Block_Cipher_Fixed_Params<8, 11, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(MK); zeroise(RK); } - std::string name() const { return "CAST-128"; } - BlockCipher* clone() const { return new CAST_128; } - - CAST_128() : MK(16), RK(16) {} - private: - void key_schedule(const byte[], size_t); - - static void cast_ks(MemoryRegion<u32bit>& ks, - MemoryRegion<u32bit>& user_key); - - static const u32bit S5[256]; - static const u32bit S6[256]; - static const u32bit S7[256]; - static const u32bit S8[256]; - - SecureVector<u32bit> MK, RK; - }; - -extern const u32bit CAST_SBOX1[256]; -extern const u32bit CAST_SBOX2[256]; -extern const u32bit CAST_SBOX3[256]; -extern const u32bit CAST_SBOX4[256]; - -} - - -namespace Botan { - -/** -* PKCS #5 v2.0 PBE -*/ -class BOTAN_DLL PBE_PKCS5v20 : public PBE - { - public: - /** - * @param cipher names a block cipher - * @return true iff PKCS #5 knows how to use this cipher - */ - static bool known_cipher(const std::string& cipher); - - std::string name() const; - - void write(const byte[], size_t); - void start_msg(); - void end_msg(); - - /** - * Load a PKCS #5 v2.0 encrypted stream - * @param input is the input source - */ - PBE_PKCS5v20(DataSource& input); - - /** - * @param cipher the block cipher to use - * @param hash the hash function to use - */ - PBE_PKCS5v20(BlockCipher* cipher, HashFunction* hash); - - ~PBE_PKCS5v20(); - private: - void set_key(const std::string&); - void new_params(RandomNumberGenerator& rng); - MemoryVector<byte> encode_params() const; - void decode_params(DataSource&); - OID get_oid() const; - - void flush_pipe(bool); - - Cipher_Dir direction; - BlockCipher* block_cipher; - HashFunction* hash_function; - SecureVector<byte> salt, key, iv; - size_t iterations, key_length; - Pipe pipe; - }; - -} - - -namespace Botan { - -/** -* Algorithm benchmark -* @param name the name of the algorithm to test (cipher, hash, or MAC) -* @param af the algorithm factory used to create objects -* @param rng the rng to use to generate random inputs -* @param milliseconds total time for the benchmark to run -* @param buf_size size of buffer to benchmark against, in KiB -* @return results a map from provider to speed in mebibytes per second -*/ -std::map<std::string, double> -BOTAN_DLL algorithm_benchmark(const std::string& name, - Algorithm_Factory& af, - RandomNumberGenerator& rng, - u32bit milliseconds, - size_t buf_size); - -} - - -namespace Botan { - -/** -* CBC-MAC -*/ -class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode - { - public: - std::string name() const; - MessageAuthenticationCode* clone() const; - size_t output_length() const { return e->block_size(); } - void clear(); - - Key_Length_Specification key_spec() const - { - return e->key_spec(); - } - - /** - * @param cipher the underlying block cipher to use - */ - CBC_MAC(BlockCipher* cipher); - ~CBC_MAC(); - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - BlockCipher* e; - SecureVector<byte> state; - size_t position; - }; - -} - - -namespace Botan { - -/** -* MARS, IBM's candidate for AES -*/ -class BOTAN_DLL MARS : public Block_Cipher_Fixed_Params<16, 16, 32, 4> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - std::string name() const { return "MARS"; } - BlockCipher* clone() const { return new MARS; } - - MARS() : EK(40) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector<u32bit> EK; - }; - -} - - -namespace Botan { - -/** -* PKCS #5 PBKDF2 -*/ -class BOTAN_DLL PKCS5_PBKDF2 : public PBKDF - { - public: - std::string name() const - { - return "PBKDF2(" + mac->name() + ")"; - } - - PBKDF* clone() const - { - return new PKCS5_PBKDF2(mac->clone()); - } - - OctetString derive_key(size_t output_len, - const std::string& passphrase, - const byte salt[], size_t salt_len, - size_t iterations) const; - - /** - * Create a PKCS #5 instance using the specified message auth code - * @param mac_fn the MAC to use - */ - PKCS5_PBKDF2(MessageAuthenticationCode* mac_fn) : mac(mac_fn) {} - - /** - * Destructor - */ - ~PKCS5_PBKDF2() { delete mac; } - private: - MessageAuthenticationCode* mac; - }; - -} - - -namespace Botan { - -class Algorithm_Factory; - -/** -* Encrypt a key under a key encryption key using the algorithm -* described in RFC 3394 -* -* @param key the plaintext key to encrypt -* @param kek the key encryption key -* @param af an algorithm factory -* @return key encrypted under kek -*/ -SecureVector<byte> BOTAN_DLL rfc3394_keywrap(const MemoryRegion<byte>& key, - const SymmetricKey& kek, - Algorithm_Factory& af); - -/** -* Decrypt a key under a key encryption key using the algorithm -* described in RFC 3394 -* -* @param key the encrypted key to decrypt -* @param kek the key encryption key -* @param af an algorithm factory -* @return key decrypted under kek -*/ -SecureVector<byte> BOTAN_DLL rfc3394_keyunwrap(const MemoryRegion<byte>& key, - const SymmetricKey& kek, - Algorithm_Factory& af); - -} - - -namespace Botan { - -/** -* DLIES Encryption -*/ -class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor - { - public: - DLIES_Encryptor(const PK_Key_Agreement_Key&, - KDF* kdf, - MessageAuthenticationCode* mac, - size_t mac_key_len = 20); - - ~DLIES_Encryptor(); - - void set_other_key(const MemoryRegion<byte>&); - private: - SecureVector<byte> enc(const byte[], size_t, - RandomNumberGenerator&) const; - size_t maximum_input_size() const; - - SecureVector<byte> other_key, my_key; - - PK_Key_Agreement ka; - KDF* kdf; - MessageAuthenticationCode* mac; - size_t mac_keylen; - }; - -/** -* DLIES Decryption -*/ -class BOTAN_DLL DLIES_Decryptor : public PK_Decryptor - { - public: - DLIES_Decryptor(const PK_Key_Agreement_Key&, - KDF* kdf, - MessageAuthenticationCode* mac, - size_t mac_key_len = 20); - - ~DLIES_Decryptor(); - - private: - SecureVector<byte> dec(const byte[], size_t) const; - - SecureVector<byte> my_key; - - PK_Key_Agreement ka; - KDF* kdf; - MessageAuthenticationCode* mac; - size_t mac_keylen; - }; - -} - - -namespace Botan { - -/** -* Output Feedback Mode -*/ -class BOTAN_DLL OFB : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - - void set_iv(const byte iv[], size_t iv_len); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len <= permutation->block_size()); } - - Key_Length_Specification key_spec() const - { - return permutation->key_spec(); - } - - std::string name() const; - - OFB* clone() const - { return new OFB(permutation->clone()); } - - void clear(); - - /** - * @param cipher the underlying block cipher to use - */ - OFB(BlockCipher* cipher); - ~OFB(); - private: - void key_schedule(const byte key[], size_t key_len); - - BlockCipher* permutation; - SecureVector<byte> buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Blowfish -*/ -class BOTAN_DLL Blowfish : public Block_Cipher_Fixed_Params<8, 1, 56> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - /** - * Modified EKSBlowfish key schedule, used for bcrypt password hashing - */ - void eks_key_schedule(const byte key[], size_t key_length, - const byte salt[16], size_t workfactor); - - void clear(); - std::string name() const { return "Blowfish"; } - BlockCipher* clone() const { return new Blowfish; } - - Blowfish() : S(1024), P(18) {} - private: - void key_schedule(const byte key[], size_t length); - - void key_expansion(const byte key[], - size_t key_length, - const byte salt[16]); - - void generate_sbox(MemoryRegion<u32bit>& box, - u32bit& L, u32bit& R, - const byte salt[16], - size_t salt_off) const; - - static const u32bit P_INIT[18]; - static const u32bit S_INIT[1024]; - - SecureVector<u32bit> S; - SecureVector<u32bit> P; - }; - -} - - -namespace Botan { - -/** -* The Adler32 checksum, used in zlib -*/ -class BOTAN_DLL Adler32 : public HashFunction - { - public: - std::string name() const { return "Adler32"; } - size_t output_length() const { return 4; } - HashFunction* clone() const { return new Adler32; } - - void clear() { S1 = 1; S2 = 0; } - - Adler32() { clear(); } - ~Adler32() { clear(); } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - u16bit S1, S2; - }; - -} - - -namespace Botan { - -/** -* Parallel Hashes -*/ -class BOTAN_DLL Parallel : public HashFunction - { - public: - void clear(); - std::string name() const; - HashFunction* clone() const; - - size_t output_length() const; - - /** - * @param hashes a set of hashes to compute in parallel - */ - Parallel(const std::vector<HashFunction*>& hashes); - ~Parallel(); - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - std::vector<HashFunction*> hashes; - }; - -} - - -namespace Botan { - -/** -* RC5 -*/ -class BOTAN_DLL RC5 : public Block_Cipher_Fixed_Params<8, 1, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(S); } - std::string name() const; - BlockCipher* clone() const { return new RC5(get_rounds()); } - - /** - * @param rounds the number of RC5 rounds to run. Must be between - * 8 and 32 and a multiple of 4. - */ - RC5(size_t rounds); - private: - size_t get_rounds() const { return (S.size() - 2) / 2; } - - void key_schedule(const byte[], size_t); - - SecureVector<u32bit> S; - }; - -} - - -namespace Botan { - -/** -* Run a set of self tests on some basic algorithms like AES and SHA-1 -* @param af an algorithm factory -* @throws Self_Test_Error if a failure occured -*/ -BOTAN_DLL void confirm_startup_self_tests(Algorithm_Factory& af); - -/** -* Run a set of self tests on some basic algorithms like AES and SHA-1 -* @param af an algorithm factory -* @returns false if a failure occured, otherwise true -*/ -BOTAN_DLL bool passes_self_tests(Algorithm_Factory& af); - -/** -* Run a set of algorithm KATs (known answer tests) -* @param algo_name the algorithm we are testing -* @param vars a set of input variables for this test, all - hex encoded. Keys used: "input", "output", "key", and "iv" -* @param af an algorithm factory -* @returns map from provider name to test result for that provider -*/ -BOTAN_DLL std::map<std::string, bool> -algorithm_kat(const SCAN_Name& algo_name, - const std::map<std::string, std::string>& vars, - Algorithm_Factory& af); - -} - - -namespace Botan { - -/** -* Noekeon implementation using SIMD operations -*/ -class BOTAN_DLL Noekeon_SIMD : public Noekeon - { - public: - size_t parallelism() const { return 4; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - BlockCipher* clone() const { return new Noekeon_SIMD; } - }; - -} - - -namespace Botan { - -/** -* PKCS #5 v1.5 PBE -*/ -class BOTAN_DLL PBE_PKCS5v15 : public PBE - { - public: - std::string name() const; - - void write(const byte[], size_t); - void start_msg(); - void end_msg(); - - /** - * @param cipher the block cipher to use (DES or RC2) - * @param hash the hash function to use - * @param direction are we encrypting or decrypting - */ - PBE_PKCS5v15(BlockCipher* cipher, - HashFunction* hash, - Cipher_Dir direction); - - ~PBE_PKCS5v15(); - private: - void set_key(const std::string&); - void new_params(RandomNumberGenerator& rng); - MemoryVector<byte> encode_params() const; - void decode_params(DataSource&); - OID get_oid() const; - - void flush_pipe(bool); - - Cipher_Dir direction; - BlockCipher* block_cipher; - HashFunction* hash_function; - - SecureVector<byte> salt, key, iv; - size_t iterations; - Pipe pipe; - }; - -} - - -namespace Botan { - -/** -* CTR-BE (Counter mode, big-endian) -*/ -class BOTAN_DLL CTR_BE : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - - void set_iv(const byte iv[], size_t iv_len); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len <= permutation->block_size()); } - - Key_Length_Specification key_spec() const - { - return permutation->key_spec(); - } - - std::string name() const; - - CTR_BE* clone() const - { return new CTR_BE(permutation->clone()); } - - void clear(); - - /** - * @param cipher the underlying block cipher to use - */ - CTR_BE(BlockCipher* cipher); - ~CTR_BE(); - private: - void key_schedule(const byte key[], size_t key_len); - void increment_counter(); - - BlockCipher* permutation; - SecureVector<byte> counter, buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Randpool -*/ -class BOTAN_DLL Randpool : public RandomNumberGenerator - { - public: - void randomize(byte[], size_t); - bool is_seeded() const { return seeded; } - void clear(); - std::string name() const; - - void reseed(size_t bits_to_collect); - void add_entropy_source(EntropySource* es); - void add_entropy(const byte input[], size_t length); - - /** - * @param cipher a block cipher to use - * @param mac a message authentication code to use - * @param pool_blocks how many cipher blocks to use for the pool - * @param iterations_before_reseed how many times we'll use the - * internal state to generate output before reseeding - */ - Randpool(BlockCipher* cipher, - MessageAuthenticationCode* mac, - size_t pool_blocks = 32, - size_t iterations_before_reseed = 128); - - ~Randpool(); - private: - void update_buffer(); - void mix_pool(); - - size_t ITERATIONS_BEFORE_RESEED, POOL_BLOCKS; - BlockCipher* cipher; - MessageAuthenticationCode* mac; - - std::vector<EntropySource*> entropy_sources; - SecureVector<byte> pool, buffer, counter; - bool seeded; - }; - -} - - -namespace Botan { - -/** -* PRF used in SSLv3 -*/ -class BOTAN_DLL SSL3_PRF : public KDF - { - public: - SecureVector<byte> derive(size_t, const byte[], size_t, - const byte[], size_t) const; - - std::string name() const { return "SSL3-PRF"; } - KDF* clone() const { return new SSL3_PRF; } - }; - -} - - -namespace Botan { - -/** -* DES/3DES-based MAC from ANSI X9.19 -*/ -class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode - { - public: - void clear(); - std::string name() const; - size_t output_length() const { return e->block_size(); } - MessageAuthenticationCode* clone() const; - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(8, 16, 8); - } - - /** - * @param cipher the underlying block cipher to use - */ - ANSI_X919_MAC(BlockCipher* cipher); - ~ANSI_X919_MAC(); - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - BlockCipher* e; - BlockCipher* d; - SecureVector<byte> state; - size_t position; - }; - -} - -#endif // USE_SYSTEM_BOTAN -#endif // BOTAN_AMALGAMATION_H__ |