Botan for MacOS added

This commit is contained in:
pokamest 2021-08-03 07:32:04 -07:00
parent dec04ccd06
commit bd586a1921
310 changed files with 49997 additions and 0 deletions

View file

@ -20,6 +20,12 @@ win32 {
}
}
macx {
message("macOS build")
INCLUDEPATH += $$PWD/include/macos/botan-2
LIBS += -L$$PWD/lib/macos -lbotan-2
}
linux-g++ {
message("Linux build")
INCLUDEPATH += $$PWD/include/linux/botan-2

View file

@ -0,0 +1,40 @@
/*
* Adler32
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ADLER32_H_
#define BOTAN_ADLER32_H_
#include <botan/hash.h>
BOTAN_FUTURE_INTERNAL_HEADER(adler32.h)
namespace Botan {
/**
* The Adler32 checksum, used in zlib
*/
class BOTAN_PUBLIC_API(2,0) Adler32 final : public HashFunction
{
public:
std::string name() const override { return "Adler32"; }
size_t output_length() const override { return 4; }
HashFunction* clone() const override { return new Adler32; }
std::unique_ptr<HashFunction> copy_state() const override;
void clear() override { m_S1 = 1; m_S2 = 0; }
Adler32() { clear(); }
~Adler32() { clear(); }
private:
void add_data(const uint8_t[], size_t) override;
void final_result(uint8_t[]) override;
uint16_t m_S1, m_S2;
};
}
#endif

View file

@ -0,0 +1,147 @@
/*
* Interface for AEAD modes
* (C) 2013 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_AEAD_MODE_H_
#define BOTAN_AEAD_MODE_H_
#include <botan/cipher_mode.h>
namespace Botan {
/**
* Interface for AEAD (Authenticated Encryption with Associated Data)
* modes. These modes provide both encryption and message
* authentication, and can authenticate additional per-message data
* which is not included in the ciphertext (for instance a sequence
* number).
*/
class BOTAN_PUBLIC_API(2,0) AEAD_Mode : public Cipher_Mode
{
public:
/**
* Create an AEAD mode
* @param algo the algorithm to create
* @param direction specify if this should be an encryption or decryption AEAD
* @param provider optional specification for provider to use
* @return an AEAD mode or a null pointer if not available
*/
static std::unique_ptr<AEAD_Mode> create(const std::string& algo,
Cipher_Dir direction,
const std::string& provider = "");
/**
* Create an AEAD mode, or throw
* @param algo the algorithm to create
* @param direction specify if this should be an encryption or decryption AEAD
* @param provider optional specification for provider to use
* @return an AEAD mode, or throw an exception
*/
static std::unique_ptr<AEAD_Mode> create_or_throw(const std::string& algo,
Cipher_Dir direction,
const std::string& provider = "");
bool authenticated() const override { return true; }
/**
* Set associated data that is not included in the ciphertext but
* that should be authenticated. Must be called after set_key and
* before start.
*
* Unless reset by another call, the associated data is kept
* between messages. Thus, if the AD does not change, calling
* once (after set_key) is the optimum.
*
* @param ad the associated data
* @param ad_len length of add in bytes
*/
virtual void set_associated_data(const uint8_t ad[], size_t ad_len) = 0;
/**
* Set associated data that is not included in the ciphertext but
* that should be authenticated. Must be called after set_key and
* before start.
*
* Unless reset by another call, the associated data is kept
* between messages. Thus, if the AD does not change, calling
* once (after set_key) is the optimum.
*
* Some AEADs (namely SIV) support multiple AD inputs. For
* all other modes only nominal AD input 0 is supported; all
* other values of i will cause an exception.
*
* @param ad the associated data
* @param ad_len length of add in bytes
*/
virtual void set_associated_data_n(size_t i, const uint8_t ad[], size_t ad_len);
/**
* Returns the maximum supported number of associated data inputs which
* can be provided to set_associated_data_n
*
* If returns 0, then no associated data is supported.
*/
virtual size_t maximum_associated_data_inputs() const { return 1; }
/**
* Most AEADs require the key to be set prior to setting the AD
* A few allow the AD to be set even before the cipher is keyed.
* Such ciphers would return false from this function.
*/
virtual bool associated_data_requires_key() const { return true; }
/**
* Set associated data that is not included in the ciphertext but
* that should be authenticated. Must be called after set_key and
* before start.
*
* See @ref set_associated_data().
*
* @param ad the associated data
*/
template<typename Alloc>
void set_associated_data_vec(const std::vector<uint8_t, Alloc>& ad)
{
set_associated_data(ad.data(), ad.size());
}
/**
* Set associated data that is not included in the ciphertext but
* that should be authenticated. Must be called after set_key and
* before start.
*
* See @ref set_associated_data().
*
* @param ad the associated data
*/
template<typename Alloc>
void set_ad(const std::vector<uint8_t, Alloc>& ad)
{
set_associated_data(ad.data(), ad.size());
}
/**
* @return default AEAD nonce size (a commonly supported value among AEAD
* modes, and large enough that random collisions are unlikely)
*/
size_t default_nonce_length() const override { return 12; }
virtual ~AEAD_Mode() = default;
};
/**
* Get an AEAD mode by name (eg "AES-128/GCM" or "Serpent/EAX")
* @param name AEAD name
* @param direction ENCRYPTION or DECRYPTION
*/
inline AEAD_Mode* get_aead(const std::string& name, Cipher_Dir direction)
{
return AEAD_Mode::create(name, direction, "").release();
}
}
#endif

View file

@ -0,0 +1,131 @@
/*
* AES
* (C) 1999-2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_AES_H_
#define BOTAN_AES_H_
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(aes.h)
namespace Botan {
/**
* AES-128
*/
class BOTAN_PUBLIC_API(2,0) AES_128 final : public Block_Cipher_Fixed_Params<16, 16>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string provider() const override;
std::string name() const override { return "AES-128"; }
BlockCipher* clone() const override { return new AES_128; }
size_t parallelism() const override;
private:
void key_schedule(const uint8_t key[], size_t length) override;
#if defined(BOTAN_HAS_AES_VPERM)
void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
void vperm_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
void vperm_key_schedule(const uint8_t key[], size_t length);
#endif
#if defined(BOTAN_HAS_AES_NI)
void aesni_key_schedule(const uint8_t key[], size_t length);
#endif
#if defined(BOTAN_HAS_AES_POWER8) || defined(BOTAN_HAS_AES_ARMV8) || defined(BOTAN_HAS_AES_NI)
void hw_aes_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
void hw_aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
#endif
secure_vector<uint32_t> m_EK, m_DK;
};
/**
* AES-192
*/
class BOTAN_PUBLIC_API(2,0) AES_192 final : public Block_Cipher_Fixed_Params<16, 24>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string provider() const override;
std::string name() const override { return "AES-192"; }
BlockCipher* clone() const override { return new AES_192; }
size_t parallelism() const override;
private:
#if defined(BOTAN_HAS_AES_VPERM)
void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
void vperm_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
void vperm_key_schedule(const uint8_t key[], size_t length);
#endif
#if defined(BOTAN_HAS_AES_NI)
void aesni_key_schedule(const uint8_t key[], size_t length);
#endif
#if defined(BOTAN_HAS_AES_POWER8) || defined(BOTAN_HAS_AES_ARMV8) || defined(BOTAN_HAS_AES_NI)
void hw_aes_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
void hw_aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
#endif
void key_schedule(const uint8_t key[], size_t length) override;
secure_vector<uint32_t> m_EK, m_DK;
};
/**
* AES-256
*/
class BOTAN_PUBLIC_API(2,0) AES_256 final : public Block_Cipher_Fixed_Params<16, 32>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string provider() const override;
std::string name() const override { return "AES-256"; }
BlockCipher* clone() const override { return new AES_256; }
size_t parallelism() const override;
private:
#if defined(BOTAN_HAS_AES_VPERM)
void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
void vperm_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
void vperm_key_schedule(const uint8_t key[], size_t length);
#endif
#if defined(BOTAN_HAS_AES_NI)
void aesni_key_schedule(const uint8_t key[], size_t length);
#endif
#if defined(BOTAN_HAS_AES_POWER8) || defined(BOTAN_HAS_AES_ARMV8) || defined(BOTAN_HAS_AES_NI)
void hw_aes_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
void hw_aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
#endif
void key_schedule(const uint8_t key[], size_t length) override;
secure_vector<uint32_t> m_EK, m_DK;
};
}
#endif

View file

@ -0,0 +1,14 @@
/*
* Algorithm Identifier
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ALGORITHM_IDENTIFIER_H_
#define BOTAN_ALGORITHM_IDENTIFIER_H_
#include <botan/asn1_obj.h>
BOTAN_DEPRECATED_HEADER(alg_id.h)
#endif

View file

@ -0,0 +1,118 @@
/**
* (C) 2018,2019 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ARGON2_H_
#define BOTAN_ARGON2_H_
#include <botan/pwdhash.h>
//BOTAN_FUTURE_INTERNAL_HEADER(argon2.h)
namespace Botan {
class RandomNumberGenerator;
/**
* Argon2 key derivation function
*/
class BOTAN_PUBLIC_API(2,11) Argon2 final : public PasswordHash
{
public:
Argon2(uint8_t family, size_t M, size_t t, size_t p);
Argon2(const Argon2& other) = default;
Argon2& operator=(const Argon2&) = default;
/**
* Derive a new key under the current Argon2 parameter set
*/
void derive_key(uint8_t out[], size_t out_len,
const char* password, size_t password_len,
const uint8_t salt[], size_t salt_len) const override;
std::string to_string() const override;
size_t M() const { return m_M; }
size_t t() const { return m_t; }
size_t p() const { return m_p; }
size_t iterations() const override { return t(); }
size_t parallelism() const override { return p(); }
size_t memory_param() const override { return M(); }
size_t total_memory_usage() const override { return M() * 1024; }
private:
uint8_t m_family;
size_t m_M, m_t, m_p;
};
class BOTAN_PUBLIC_API(2,11) Argon2_Family final : public PasswordHashFamily
{
public:
Argon2_Family(uint8_t family);
std::string name() const override;
std::unique_ptr<PasswordHash> tune(size_t output_length,
std::chrono::milliseconds msec,
size_t max_memory) const override;
std::unique_ptr<PasswordHash> default_params() const override;
std::unique_ptr<PasswordHash> from_iterations(size_t iter) const override;
std::unique_ptr<PasswordHash> from_params(
size_t M, size_t t, size_t p) const override;
private:
const uint8_t m_family;
};
/**
* Argon2 key derivation function
*
* @param output the output will be placed here
* @param output_len length of output
* @param password the user password
* @param password_len the length of password
* @param salt the salt
* @param salt_len length of salt
* @param key an optional secret key
* @param key_len the length of key
* @param ad an optional additional input
* @param ad_len the length of ad
* @param y the Argon2 variant (0 = Argon2d, 1 = Argon2i, 2 = Argon2id)
* @param p the parallelization parameter
* @param M the amount of memory to use in Kb
* @param t the number of iterations to use
*/
void BOTAN_PUBLIC_API(2,11) argon2(uint8_t output[], size_t output_len,
const char* password, size_t password_len,
const uint8_t salt[], size_t salt_len,
const uint8_t key[], size_t key_len,
const uint8_t ad[], size_t ad_len,
uint8_t y, size_t p, size_t M, size_t t);
std::string BOTAN_PUBLIC_API(2,11)
argon2_generate_pwhash(const char* password, size_t password_len,
RandomNumberGenerator& rng,
size_t p, size_t M, size_t t,
uint8_t y = 2, size_t salt_len = 16, size_t output_len = 32);
/**
* Check a previously created password hash
* @param password the password to check against
* @param password_len the length of password
* @param hash the stored hash to check against
*/
bool BOTAN_PUBLIC_API(2,11) argon2_check_pwhash(const char* password, size_t password_len,
const std::string& hash);
}
#endif

View file

@ -0,0 +1,84 @@
/*
* ARIA
* (C) 2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*
* This ARIA implementation is based on the 32-bit implementation by Aaram Yun from the
* National Security Research Institute, KOREA. Aaram Yun's implementation is based on
* the 8-bit implementation by Jin Hong. The source files are available in ARIA.zip from
* the Korea Internet & Security Agency website.
* <A HREF="https://tools.ietf.org/html/rfc5794">RFC 5794, A Description of the ARIA Encryption Algorithm</A>,
* <A HREF="http://seed.kisa.or.kr/iwt/ko/bbs/EgovReferenceList.do?bbsId=BBSMSTR_000000000002">Korea
* Internet & Security Agency homepage</A>
*/
#ifndef BOTAN_ARIA_H_
#define BOTAN_ARIA_H_
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(aria.h)
namespace Botan {
/**
* ARIA-128
*/
class BOTAN_PUBLIC_API(2,3) ARIA_128 final : public Block_Cipher_Fixed_Params<16, 16>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "ARIA-128"; }
BlockCipher* clone() const override { return new ARIA_128; }
private:
void key_schedule(const uint8_t key[], size_t length) override;
// Encryption and Decryption round keys.
secure_vector<uint32_t> m_ERK, m_DRK;
};
/**
* ARIA-192
*/
class BOTAN_PUBLIC_API(2,3) ARIA_192 final : public Block_Cipher_Fixed_Params<16, 24>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "ARIA-192"; }
BlockCipher* clone() const override { return new ARIA_192; }
private:
void key_schedule(const uint8_t key[], size_t length) override;
// Encryption and Decryption round keys.
secure_vector<uint32_t> m_ERK, m_DRK;
};
/**
* ARIA-256
*/
class BOTAN_PUBLIC_API(2,3) ARIA_256 final : public Block_Cipher_Fixed_Params<16, 32>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "ARIA-256"; }
BlockCipher* clone() const override { return new ARIA_256; }
private:
void key_schedule(const uint8_t key[], size_t length) override;
// Encryption and Decryption round keys.
secure_vector<uint32_t> m_ERK, m_DRK;
};
}
#endif

View file

@ -0,0 +1,11 @@
/*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_X509_ALT_NAME_H_
#define BOTAN_X509_ALT_NAME_H_
#include <botan/pkix_types.h>
BOTAN_DEPRECATED_HEADER(asn1_alt_name.h)
#endif

View file

@ -0,0 +1,11 @@
/*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ASN1_ATTRIBUTE_H_
#define BOTAN_ASN1_ATTRIBUTE_H_
#include <botan/pkix_types.h>
BOTAN_DEPRECATED_HEADER(asn1_attribute.h)
#endif

View file

@ -0,0 +1,475 @@
/*
* (C) 1999-2007,2018,2020 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ASN1_OBJECT_TYPES_H_
#define BOTAN_ASN1_OBJECT_TYPES_H_
#include <botan/secmem.h>
#include <botan/exceptn.h>
#include <vector>
#include <string>
#include <chrono>
namespace Botan {
class BER_Decoder;
class DER_Encoder;
/**
* ASN.1 Type and Class Tags
* This will become an enum class in a future major release
*/
enum ASN1_Tag : uint32_t {
UNIVERSAL = 0x00,
APPLICATION = 0x40,
CONTEXT_SPECIFIC = 0x80,
CONSTRUCTED = 0x20,
PRIVATE = CONSTRUCTED | CONTEXT_SPECIFIC,
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,
UNIVERSAL_STRING = 0x1C,
BMP_STRING = 0x1E,
UTC_TIME = 0x17,
GENERALIZED_TIME = 0x18,
UTC_OR_GENERALIZED_TIME = 0x19,
NO_OBJECT = 0xFF00,
DIRECTORY_STRING = 0xFF01
};
std::string BOTAN_UNSTABLE_API asn1_tag_to_string(ASN1_Tag type);
std::string BOTAN_UNSTABLE_API asn1_class_to_string(ASN1_Tag type);
/**
* Basic ASN.1 Object Interface
*/
class BOTAN_PUBLIC_API(2,0) ASN1_Object
{
public:
/**
* Encode whatever this object is into to
* @param to the DER_Encoder that will be written to
*/
virtual void encode_into(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(BER_Decoder& from) = 0;
/**
* Return the encoding of this object. This is a convenience
* method when just one object needs to be serialized. Use
* DER_Encoder for complicated encodings.
*/
std::vector<uint8_t> BER_encode() const;
ASN1_Object() = default;
ASN1_Object(const ASN1_Object&) = default;
ASN1_Object & operator=(const ASN1_Object&) = default;
virtual ~ASN1_Object() = default;
};
/**
* BER Encoded Object
*/
class BOTAN_PUBLIC_API(2,0) BER_Object final
{
public:
BER_Object() : type_tag(NO_OBJECT), class_tag(UNIVERSAL) {}
BER_Object(const BER_Object& other) = default;
BER_Object& operator=(const BER_Object& other) = default;
BER_Object(BER_Object&& other) = default;
BER_Object& operator=(BER_Object&& other) = default;
bool is_set() const { return type_tag != NO_OBJECT; }
ASN1_Tag tagging() const { return ASN1_Tag(type() | get_class()); }
ASN1_Tag type() const { return type_tag; }
ASN1_Tag get_class() const { return class_tag; }
const uint8_t* bits() const { return value.data(); }
size_t length() const { return value.size(); }
void assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag,
const std::string& descr = "object") const;
bool is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) const;
bool is_a(int type_tag, ASN1_Tag class_tag) const;
BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:
/*
* The following member variables are public for historical reasons, but
* will be made private in a future major release. Use the accessor
* functions above.
*/
ASN1_Tag type_tag, class_tag;
secure_vector<uint8_t> value;
private:
friend class BER_Decoder;
void set_tagging(ASN1_Tag type_tag, ASN1_Tag class_tag);
uint8_t* mutable_bits(size_t length)
{
value.resize(length);
return value.data();
}
};
/*
* ASN.1 Utility Functions
*/
class DataSource;
namespace ASN1 {
std::vector<uint8_t> put_in_sequence(const std::vector<uint8_t>& val);
std::vector<uint8_t> put_in_sequence(const uint8_t bits[], size_t len);
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
*/
class BOTAN_PUBLIC_API(2,0) BER_Decoding_Error : public Decoding_Error
{
public:
explicit BER_Decoding_Error(const std::string&);
};
/**
* Exception For Incorrect BER Taggings
*/
class BOTAN_PUBLIC_API(2,0) BER_Bad_Tag final : public BER_Decoding_Error
{
public:
BER_Bad_Tag(const std::string& msg, ASN1_Tag tag);
BER_Bad_Tag(const std::string& msg, ASN1_Tag tag1, ASN1_Tag tag2);
};
/**
* This class represents ASN.1 object identifiers.
*/
class BOTAN_PUBLIC_API(2,0) OID final : public ASN1_Object
{
public:
/**
* Create an uninitialied OID object
*/
explicit OID() {}
/**
* Construct an OID from a string.
* @param str a string in the form "a.b.c" etc., where a,b,c are numbers
*/
explicit OID(const std::string& str);
/**
* Initialize an OID from a sequence of integer values
*/
explicit OID(std::initializer_list<uint32_t> init) : m_id(init) {}
/**
* Initialize an OID from a vector of integer values
*/
explicit OID(std::vector<uint32_t>&& init) : m_id(init) {}
/**
* Construct an OID from a string.
* @param str a string in the form "a.b.c" etc., where a,b,c are numbers
* or any known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier")
*/
static OID from_string(const std::string& str);
void encode_into(class DER_Encoder&) const override;
void decode_from(class BER_Decoder&) override;
/**
* Find out whether this OID is empty
* @return true is no OID value is set
*/
bool empty() const { return m_id.empty(); }
/**
* Find out whether this OID has a value
* @return true is this OID has a value
*/
bool has_value() const { return (m_id.empty() == false); }
/**
* Get this OID as list (vector) of its components.
* @return vector representing this OID
*/
const std::vector<uint32_t>& get_components() const { return m_id; }
const std::vector<uint32_t>& get_id() const { return get_components(); }
/**
* Get this OID as a string
* @return string representing this OID
*/
std::string BOTAN_DEPRECATED("Use OID::to_string") as_string() const
{
return this->to_string();
}
/**
* Get this OID as a dotted-decimal string
* @return string representing this OID
*/
std::string to_string() const;
/**
* If there is a known name associated with this OID, return that.
* Otherwise return the result of to_string
*/
std::string to_formatted_string() const;
/**
* Compare two OIDs.
* @return true if they are equal, false otherwise
*/
bool operator==(const OID& other) const
{
return m_id == other.m_id;
}
/**
* Reset this instance to an empty OID.
*/
void BOTAN_DEPRECATED("Avoid mutation of OIDs") clear() { m_id.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
*/
BOTAN_DEPRECATED("Avoid mutation of OIDs") OID& operator+=(uint32_t new_comp)
{
m_id.push_back(new_comp);
return (*this);
}
private:
std::vector<uint32_t> m_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 BOTAN_PUBLIC_API(2,0) operator+(const OID& oid, uint32_t new_comp);
/**
* Compare two OIDs.
* @param a the first OID
* @param b the second OID
* @return true if a is not equal to b
*/
inline bool operator!=(const OID& a, const OID& b)
{
return !(a == b);
}
/**
* Compare two OIDs.
* @param a the first OID
* @param b the second OID
* @return true if a is lexicographically smaller than b
*/
bool BOTAN_PUBLIC_API(2,0) operator<(const OID& a, const OID& b);
/**
* Time (GeneralizedTime/UniversalTime)
*/
class BOTAN_PUBLIC_API(2,0) ASN1_Time final : public ASN1_Object
{
public:
/// DER encode a ASN1_Time
void encode_into(DER_Encoder&) const override;
// Decode a BER encoded ASN1_Time
void decode_from(BER_Decoder&) override;
/// Return an internal string representation of the time
std::string to_string() const;
/// Returns a human friendly string replesentation of no particular formatting
std::string readable_string() const;
/// Return if the time has been set somehow
bool time_is_set() const;
/// Compare this time against another
int32_t cmp(const ASN1_Time& other) const;
/// Create an invalid ASN1_Time
ASN1_Time() = default;
/// Create a ASN1_Time from a time point
explicit ASN1_Time(const std::chrono::system_clock::time_point& time);
/// Create an ASN1_Time from string
ASN1_Time(const std::string& t_spec, ASN1_Tag tag);
/// Returns a STL timepoint object
std::chrono::system_clock::time_point to_std_timepoint() const;
/// Return time since epoch
uint64_t time_since_epoch() const;
private:
void set_to(const std::string& t_spec, ASN1_Tag);
bool passes_sanity_check() const;
uint32_t m_year = 0;
uint32_t m_month = 0;
uint32_t m_day = 0;
uint32_t m_hour = 0;
uint32_t m_minute = 0;
uint32_t m_second = 0;
ASN1_Tag m_tag = NO_OBJECT;
};
/*
* Comparison Operations
*/
bool BOTAN_PUBLIC_API(2,0) operator==(const ASN1_Time&, const ASN1_Time&);
bool BOTAN_PUBLIC_API(2,0) operator!=(const ASN1_Time&, const ASN1_Time&);
bool BOTAN_PUBLIC_API(2,0) operator<=(const ASN1_Time&, const ASN1_Time&);
bool BOTAN_PUBLIC_API(2,0) operator>=(const ASN1_Time&, const ASN1_Time&);
bool BOTAN_PUBLIC_API(2,0) operator<(const ASN1_Time&, const ASN1_Time&);
bool BOTAN_PUBLIC_API(2,0) operator>(const ASN1_Time&, const ASN1_Time&);
typedef ASN1_Time X509_Time;
/**
* ASN.1 string type
* This class normalizes all inputs to a UTF-8 std::string
*/
class BOTAN_PUBLIC_API(2,0) ASN1_String final : public ASN1_Object
{
public:
void encode_into(class DER_Encoder&) const override;
void decode_from(class BER_Decoder&) override;
ASN1_Tag tagging() const { return m_tag; }
const std::string& value() const { return m_utf8_str; }
size_t size() const { return value().size(); }
bool empty() const { return m_utf8_str.empty(); }
std::string BOTAN_DEPRECATED("Use value() to get UTF-8 string instead")
iso_8859() const;
/**
* Return true iff this is a tag for a known string type we can handle.
* This ignores string types that are not supported, eg teletexString
*/
static bool is_string_type(ASN1_Tag tag);
bool operator==(const ASN1_String& other) const
{ return value() == other.value(); }
explicit ASN1_String(const std::string& utf8 = "");
ASN1_String(const std::string& utf8, ASN1_Tag tag);
private:
std::vector<uint8_t> m_data;
std::string m_utf8_str;
ASN1_Tag m_tag;
};
/**
* Algorithm Identifier
*/
class BOTAN_PUBLIC_API(2,0) AlgorithmIdentifier final : public ASN1_Object
{
public:
enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM };
void encode_into(class DER_Encoder&) const override;
void decode_from(class BER_Decoder&) override;
AlgorithmIdentifier() = default;
AlgorithmIdentifier(const OID& oid, Encoding_Option enc);
AlgorithmIdentifier(const std::string& oid_name, Encoding_Option enc);
AlgorithmIdentifier(const OID& oid, const std::vector<uint8_t>& params);
AlgorithmIdentifier(const std::string& oid_name, const std::vector<uint8_t>& params);
const OID& get_oid() const { return oid; }
const std::vector<uint8_t>& get_parameters() const { return parameters; }
bool parameters_are_null() const;
bool parameters_are_empty() const { return parameters.empty(); }
bool parameters_are_null_or_empty() const
{
return parameters_are_empty() || parameters_are_null();
}
BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:
/*
* These values are public for historical reasons, but in a future release
* they will be made private. Do not access them.
*/
OID oid;
std::vector<uint8_t> parameters;
};
/*
* Comparison Operations
*/
bool BOTAN_PUBLIC_API(2,0) operator==(const AlgorithmIdentifier&,
const AlgorithmIdentifier&);
bool BOTAN_PUBLIC_API(2,0) operator!=(const AlgorithmIdentifier&,
const AlgorithmIdentifier&);
}
#endif

View file

@ -0,0 +1,14 @@
/*
* ASN.1 OID
* (C) 1999-2007,2019 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ASN1_OID_H_
#define BOTAN_ASN1_OID_H_
#include <botan/asn1_obj.h>
BOTAN_DEPRECATED_HEADER(asn1_oid.h)
#endif

View file

@ -0,0 +1,125 @@
/*
* (C) 2014,2015,2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ASN1_PRINT_H_
#define BOTAN_ASN1_PRINT_H_
#include <botan/asn1_obj.h>
#include <string>
#include <vector>
#include <iosfwd>
namespace Botan {
class BER_Decoder;
/**
* Format ASN.1 data and call a virtual to format
*/
class BOTAN_PUBLIC_API(2,4) ASN1_Formatter
{
public:
virtual ~ASN1_Formatter() = default;
/**
* @param print_context_specific if true, try to parse nested context specific data.
* @param max_depth do not recurse more than this many times. If zero, recursion
* is unbounded.
*/
ASN1_Formatter(bool print_context_specific, size_t max_depth) :
m_print_context_specific(print_context_specific),
m_max_depth(max_depth)
{}
void print_to_stream(std::ostream& out,
const uint8_t in[],
size_t len) const;
std::string print(const uint8_t in[], size_t len) const;
template<typename Alloc>
std::string print(const std::vector<uint8_t, Alloc>& vec) const
{
return print(vec.data(), vec.size());
}
protected:
/**
* This is called for each element
*/
virtual std::string format(ASN1_Tag type_tag,
ASN1_Tag class_tag,
size_t level,
size_t length,
const std::string& value) const = 0;
/**
* This is called to format binary elements that we don't know how to
* convert to a string The result will be passed as value to format; the
* tags are included as a hint to aid decoding.
*/
virtual std::string format_bin(ASN1_Tag type_tag,
ASN1_Tag class_tag,
const std::vector<uint8_t>& vec) const = 0;
private:
void decode(std::ostream& output,
BER_Decoder& decoder,
size_t level) const;
const bool m_print_context_specific;
const size_t m_max_depth;
};
/**
* Format ASN.1 data into human readable output. The exact form of the output for
* any particular input is not guaranteed and may change from release to release.
*/
class BOTAN_PUBLIC_API(2,4) ASN1_Pretty_Printer final : public ASN1_Formatter
{
public:
/**
* @param print_limit strings larger than this are not printed
* @param print_binary_limit binary strings larger than this are not printed
* @param print_context_specific if true, try to parse nested context specific data.
* @param initial_level the initial depth (0 or 1 are the only reasonable values)
* @param value_column ASN.1 values are lined up at this column in output
* @param max_depth do not recurse more than this many times. If zero, recursion
* is unbounded.
*/
ASN1_Pretty_Printer(size_t print_limit = 4096,
size_t print_binary_limit = 2048,
bool print_context_specific = true,
size_t initial_level = 0,
size_t value_column = 60,
size_t max_depth = 64) :
ASN1_Formatter(print_context_specific, max_depth),
m_print_limit(print_limit),
m_print_binary_limit(print_binary_limit),
m_initial_level(initial_level),
m_value_column(value_column)
{}
private:
std::string format(ASN1_Tag type_tag,
ASN1_Tag class_tag,
size_t level,
size_t length,
const std::string& value) const override;
std::string format_bin(ASN1_Tag type_tag,
ASN1_Tag class_tag,
const std::vector<uint8_t>& vec) const override;
const size_t m_print_limit;
const size_t m_print_binary_limit;
const size_t m_initial_level;
const size_t m_value_column;
};
}
#endif

View file

@ -0,0 +1,14 @@
/*
* ASN.1 string type
* (C) 1999-2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ASN1_STRING_H_
#define BOTAN_ASN1_STRING_H_
#include <botan/asn1_obj.h>
BOTAN_DEPRECATED_HEADER(asn1_str.h)
#endif

View file

@ -0,0 +1,14 @@
/*
* ASN.1 Time Representation
* (C) 1999-2007,2012 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ASN1_TIME_H_
#define BOTAN_ASN1_TIME_H_
#include <botan/asn1_obj.h>
BOTAN_DEPRECATED_HEADER(asn1_time.h)
#endif

View file

@ -0,0 +1,157 @@
/*
* Runtime assertion checking
* (C) 2010,2018 Jack Lloyd
* 2017 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ASSERTION_CHECKING_H_
#define BOTAN_ASSERTION_CHECKING_H_
#include <botan/build.h>
#include <botan/compiler.h>
namespace Botan {
/**
* Called when an assertion fails
* Throws an Exception object
*/
BOTAN_NORETURN void BOTAN_PUBLIC_API(2,0)
assertion_failure(const char* expr_str,
const char* assertion_made,
const char* func,
const char* file,
int line);
/**
* Called when an invalid argument is used
* Throws Invalid_Argument
*/
BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_argument(const char* message,
const char* func,
const char* file);
#define BOTAN_ARG_CHECK(expr, msg) \
do { if(!(expr)) Botan::throw_invalid_argument(msg, __func__, __FILE__); } while(0)
/**
* Called when an invalid state is encountered
* Throws Invalid_State
*/
BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_state(const char* message,
const char* func,
const char* file);
#define BOTAN_STATE_CHECK(expr) \
do { if(!(expr)) Botan::throw_invalid_state(#expr, __func__, __FILE__); } while(0)
/**
* Make an assertion
*/
#define BOTAN_ASSERT(expr, assertion_made) \
do { \
if(!(expr)) \
Botan::assertion_failure(#expr, \
assertion_made, \
__func__, \
__FILE__, \
__LINE__); \
} while(0)
/**
* Make an assertion
*/
#define BOTAN_ASSERT_NOMSG(expr) \
do { \
if(!(expr)) \
Botan::assertion_failure(#expr, \
"", \
__func__, \
__FILE__, \
__LINE__); \
} while(0)
/**
* Assert that value1 == value2
*/
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made) \
do { \
if((expr1) != (expr2)) \
Botan::assertion_failure(#expr1 " == " #expr2, \
assertion_made, \
__func__, \
__FILE__, \
__LINE__); \
} while(0)
/**
* Assert that expr1 (if true) implies expr2 is also true
*/
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg) \
do { \
if((expr1) && !(expr2)) \
Botan::assertion_failure(#expr1 " implies " #expr2, \
msg, \
__func__, \
__FILE__, \
__LINE__); \
} while(0)
/**
* Assert that a pointer is not null
*/
#define BOTAN_ASSERT_NONNULL(ptr) \
do { \
if((ptr) == nullptr) \
Botan::assertion_failure(#ptr " is not null", \
"", \
__func__, \
__FILE__, \
__LINE__); \
} while(0)
#if defined(BOTAN_ENABLE_DEBUG_ASSERTS)
#define BOTAN_DEBUG_ASSERT(expr) BOTAN_ASSERT_NOMSG(expr)
#else
#define BOTAN_DEBUG_ASSERT(expr) do {} while(0)
#endif
/**
* Mark variable as unused. Takes between 1 and 9 arguments and marks all as unused,
* e.g. BOTAN_UNUSED(a); or BOTAN_UNUSED(x, y, z);
*/
#define _BOTAN_UNUSED_IMPL1(a) static_cast<void>(a)
#define _BOTAN_UNUSED_IMPL2(a, b) static_cast<void>(a); _BOTAN_UNUSED_IMPL1(b)
#define _BOTAN_UNUSED_IMPL3(a, b, c) static_cast<void>(a); _BOTAN_UNUSED_IMPL2(b, c)
#define _BOTAN_UNUSED_IMPL4(a, b, c, d) static_cast<void>(a); _BOTAN_UNUSED_IMPL3(b, c, d)
#define _BOTAN_UNUSED_IMPL5(a, b, c, d, e) static_cast<void>(a); _BOTAN_UNUSED_IMPL4(b, c, d, e)
#define _BOTAN_UNUSED_IMPL6(a, b, c, d, e, f) static_cast<void>(a); _BOTAN_UNUSED_IMPL5(b, c, d, e, f)
#define _BOTAN_UNUSED_IMPL7(a, b, c, d, e, f, g) static_cast<void>(a); _BOTAN_UNUSED_IMPL6(b, c, d, e, f, g)
#define _BOTAN_UNUSED_IMPL8(a, b, c, d, e, f, g, h) static_cast<void>(a); _BOTAN_UNUSED_IMPL7(b, c, d, e, f, g, h)
#define _BOTAN_UNUSED_IMPL9(a, b, c, d, e, f, g, h, i) static_cast<void>(a); _BOTAN_UNUSED_IMPL8(b, c, d, e, f, g, h, i)
#define _BOTAN_UNUSED_GET_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, IMPL_NAME, ...) IMPL_NAME
#define BOTAN_UNUSED(...) _BOTAN_UNUSED_GET_IMPL(__VA_ARGS__, \
_BOTAN_UNUSED_IMPL9, \
_BOTAN_UNUSED_IMPL8, \
_BOTAN_UNUSED_IMPL7, \
_BOTAN_UNUSED_IMPL6, \
_BOTAN_UNUSED_IMPL5, \
_BOTAN_UNUSED_IMPL4, \
_BOTAN_UNUSED_IMPL3, \
_BOTAN_UNUSED_IMPL2, \
_BOTAN_UNUSED_IMPL1, \
unused dummy rest value \
) /* we got an one of _BOTAN_UNUSED_IMPL*, now call it */ (__VA_ARGS__)
}
#endif

View file

@ -0,0 +1,102 @@
/*
* Auto Seeded RNG
* (C) 2008,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_AUTO_SEEDING_RNG_H_
#define BOTAN_AUTO_SEEDING_RNG_H_
#include <botan/rng.h>
namespace Botan {
class Stateful_RNG;
/**
* A userspace PRNG
*/
class BOTAN_PUBLIC_API(2,0) AutoSeeded_RNG final : public RandomNumberGenerator
{
public:
void randomize(uint8_t out[], size_t len) override;
void randomize_with_input(uint8_t output[], size_t output_len,
const uint8_t input[], size_t input_len) override;
bool is_seeded() const override;
bool accepts_input() const override { return true; }
/**
* Mark state as requiring a reseed on next use
*/
void force_reseed();
size_t reseed(Entropy_Sources& srcs,
size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override;
void add_entropy(const uint8_t in[], size_t len) override;
std::string name() const override;
void clear() override;
/**
* Uses the system RNG (if available) or else a default group of
* entropy sources (all other systems) to gather seed material.
*
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed
*/
AutoSeeded_RNG(size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
/**
* Create an AutoSeeded_RNG which will get seed material from some other
* RNG instance. For example you could provide a reference to the system
* RNG or a hardware RNG.
*
* @param underlying_rng is a reference to some RNG which will be used
* to perform the periodic reseeding
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed
*/
AutoSeeded_RNG(RandomNumberGenerator& underlying_rng,
size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
/**
* Create an AutoSeeded_RNG which will get seed material from a set of
* entropy sources.
*
* @param entropy_sources will be polled to perform reseeding periodically
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed
*/
AutoSeeded_RNG(Entropy_Sources& entropy_sources,
size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
/**
* Create an AutoSeeded_RNG which will get seed material from both an
* underlying RNG and a set of entropy sources.
*
* @param underlying_rng is a reference to some RNG which will be used
* to perform the periodic reseeding
* @param entropy_sources will be polled to perform reseeding periodically
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed
*/
AutoSeeded_RNG(RandomNumberGenerator& underlying_rng,
Entropy_Sources& entropy_sources,
size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
~AutoSeeded_RNG();
private:
std::unique_ptr<Stateful_RNG> m_rng;
};
}
#endif

View file

@ -0,0 +1,14 @@
/*
* Base64 Encoder/Decoder
* (C) 1999-2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BASE64_FILTER_H_
#define BOTAN_BASE64_FILTER_H_
#include <botan/filters.h>
BOTAN_DEPRECATED_HEADER(b64_filt.h)
#endif

View file

@ -0,0 +1,127 @@
/*
* Base32 Encoding and Decoding
* (C) 2018 Erwan Chaussy
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BASE32_CODEC_H_
#define BOTAN_BASE32_CODEC_H_
#include <botan/secmem.h>
#include <string>
namespace Botan {
/**
* Perform base32 encoding
* @param output an array of at least base32_encode_max_output 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_PUBLIC_API(2, 7) base32_encode(char output[],
const uint8_t input[],
size_t input_length,
size_t& input_consumed,
bool final_inputs);
/**
* Perform base32 encoding
* @param input some input
* @param input_length length of input in bytes
* @return base32 representation of input
*/
std::string BOTAN_PUBLIC_API(2, 7) base32_encode(const uint8_t input[],
size_t input_length);
/**
* Perform base32 encoding
* @param input some input
* @return base32 representation of input
*/
template <typename Alloc>
std::string base32_encode(const std::vector<uint8_t, Alloc>& input)
{
return base32_encode(input.data(), input.size());
}
/**
* Perform base32 decoding
* @param output an array of at least base32_decode_max_output bytes
* @param input some base32 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_PUBLIC_API(2, 7) base32_decode(uint8_t output[],
const char input[],
size_t input_length,
size_t& input_consumed,
bool final_inputs,
bool ignore_ws = true);
/**
* Perform base32 decoding
* @param output an array of at least base32_decode_max_output bytes
* @param input some base32 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_PUBLIC_API(2, 7) base32_decode(uint8_t output[],
const char input[],
size_t input_length,
bool ignore_ws = true);
/**
* Perform base32 decoding
* @param output an array of at least base32_decode_max_output bytes
* @param input some base32 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_PUBLIC_API(2, 7) base32_decode(uint8_t output[],
const std::string& input,
bool ignore_ws = true);
/**
* Perform base32 decoding
* @param input some base32 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 base32 output
*/
secure_vector<uint8_t> BOTAN_PUBLIC_API(2, 7) base32_decode(const char input[],
size_t input_length,
bool ignore_ws = true);
/**
* Perform base32 decoding
* @param input some base32 input
* @param ignore_ws ignore whitespace on input; if false, throw an
exception if whitespace is encountered
* @return decoded base32 output
*/
secure_vector<uint8_t> BOTAN_PUBLIC_API(2, 7) base32_decode(const std::string& input,
bool ignore_ws = true);
} // namespace Botan
#endif

View file

@ -0,0 +1,76 @@
/*
* (C) 2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BASE58_CODEC_H_
#define BOTAN_BASE58_CODEC_H_
#include <botan/secmem.h>
#include <vector>
#include <string>
namespace Botan {
/**
* Perform base58 encoding
*
* This is raw base58 encoding, without the checksum
*/
std::string
BOTAN_PUBLIC_API(2,9) base58_encode(const uint8_t input[],
size_t input_length);
/**
* Perform base58 encoding with checksum
*/
std::string
BOTAN_PUBLIC_API(2,9) base58_check_encode(const uint8_t input[],
size_t input_length);
/**
* Perform base58 decoding
*
* This is raw base58 encoding, without the checksum
*/
std::vector<uint8_t>
BOTAN_PUBLIC_API(2,9) base58_decode(const char input[],
size_t input_length);
/**
* Perform base58 decoding with checksum
*/
std::vector<uint8_t>
BOTAN_PUBLIC_API(2,9) base58_check_decode(const char input[],
size_t input_length);
// Some convenience wrappers:
template<typename Alloc>
inline std::string base58_encode(const std::vector<uint8_t, Alloc>& vec)
{
return base58_encode(vec.data(), vec.size());
}
template<typename Alloc>
inline std::string base58_check_encode(const std::vector<uint8_t, Alloc>& vec)
{
return base58_check_encode(vec.data(), vec.size());
}
inline std::vector<uint8_t> base58_decode(const std::string& s)
{
return base58_decode(s.data(), s.size());
}
inline std::vector<uint8_t> base58_check_decode(const std::string& s)
{
return base58_check_decode(s.data(), s.size());
}
}
#endif

View file

@ -0,0 +1,141 @@
/*
* Base64 Encoding and Decoding
* (C) 2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BASE64_CODEC_H_
#define BOTAN_BASE64_CODEC_H_
#include <botan/secmem.h>
#include <string>
namespace Botan {
/**
* Perform base64 encoding
* @param output an array of at least base64_encode_max_output 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_PUBLIC_API(2,0) base64_encode(char output[],
const uint8_t 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_PUBLIC_API(2,0) base64_encode(const uint8_t input[],
size_t input_length);
/**
* Perform base64 encoding
* @param input some input
* @return base64adecimal representation of input
*/
template<typename Alloc>
std::string base64_encode(const std::vector<uint8_t, Alloc>& input)
{
return base64_encode(input.data(), input.size());
}
/**
* Perform base64 decoding
* @param output an array of at least base64_decode_max_output 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_PUBLIC_API(2,0) base64_decode(uint8_t 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 base64_decode_max_output 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_PUBLIC_API(2,0) base64_decode(uint8_t output[],
const char input[],
size_t input_length,
bool ignore_ws = true);
/**
* Perform base64 decoding
* @param output an array of at least base64_decode_max_output 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_PUBLIC_API(2,0) base64_decode(uint8_t 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
*/
secure_vector<uint8_t> BOTAN_PUBLIC_API(2,0) 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
*/
secure_vector<uint8_t> BOTAN_PUBLIC_API(2,0) base64_decode(const std::string& input,
bool ignore_ws = true);
/**
* Calculate the size of output buffer for base64_encode
* @param input_length the length of input in bytes
* @return the size of output buffer in bytes
*/
size_t BOTAN_PUBLIC_API(2,1) base64_encode_max_output(size_t input_length);
/**
* Calculate the size of output buffer for base64_decode
* @param input_length the length of input in bytes
* @return the size of output buffer in bytes
*/
size_t BOTAN_PUBLIC_API(2,1) base64_decode_max_output(size_t input_length);
}
#endif

View file

@ -0,0 +1,18 @@
/*
* Basic Filters
* (C) 1999-2007 Jack Lloyd
* (C) 2013 Joel Low
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BASEFILT_H_
#define BOTAN_BASEFILT_H_
// This header is deprecated and will be removed in a future major release
#include <botan/filters.h>
BOTAN_DEPRECATED_HEADER(basefilt.h)
#endif

View file

@ -0,0 +1,49 @@
/*
* Bcrypt Password Hashing
* (C) 2011 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BCRYPT_H_
#define BOTAN_BCRYPT_H_
#include <botan/types.h>
#include <string>
namespace Botan {
class RandomNumberGenerator;
/**
* Create a password hash using Bcrypt
*
* @warning The password is truncated at at most 72 characters; characters after
* that do not have any effect on the resulting hash. To support longer
* passwords, consider pre-hashing the password, for example by using
* the hex encoding of SHA-256 of the password as the input to bcrypt.
*
* @param password the password.
* @param rng a random number generator
* @param work_factor how much work to do to slow down guessing attacks
* @param version which version to emit (may be 'a', 'b', or 'y' all of which
* have identical behavior in this implementation).
*
* @see https://www.usenix.org/events/usenix99/provos/provos_html/
*/
std::string BOTAN_PUBLIC_API(2,0) generate_bcrypt(const std::string& password,
RandomNumberGenerator& rng,
uint16_t work_factor = 12,
char version = 'a');
/**
* Check a previously created password hash
* @param password the password to check against
* @param hash the stored hash to check against
*/
bool BOTAN_PUBLIC_API(2,0) check_bcrypt(const std::string& password,
const std::string& hash);
}
#endif

View file

@ -0,0 +1,77 @@
/*
* (C) 2018,2019 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_PBKDF_BCRYPT_H_
#define BOTAN_PBKDF_BCRYPT_H_
#include <botan/pwdhash.h>
BOTAN_FUTURE_INTERNAL_HEADER(bcrypt_pbkdf.h)
namespace Botan {
/**
* Bcrypt-PBKDF key derivation function
*/
class BOTAN_PUBLIC_API(2,11) Bcrypt_PBKDF final : public PasswordHash
{
public:
Bcrypt_PBKDF(size_t iterations) : m_iterations(iterations) {}
Bcrypt_PBKDF(const Bcrypt_PBKDF& other) = default;
Bcrypt_PBKDF& operator=(const Bcrypt_PBKDF&) = default;
/**
* Derive a new key under the current Bcrypt-PBKDF parameter set
*/
void derive_key(uint8_t out[], size_t out_len,
const char* password, size_t password_len,
const uint8_t salt[], size_t salt_len) const override;
std::string to_string() const override;
size_t iterations() const override { return m_iterations; }
size_t parallelism() const override { return 0; }
size_t memory_param() const override { return 0; }
size_t total_memory_usage() const override { return 4096; }
private:
size_t m_iterations;
};
class BOTAN_PUBLIC_API(2,11) Bcrypt_PBKDF_Family final : public PasswordHashFamily
{
public:
Bcrypt_PBKDF_Family() {}
std::string name() const override;
std::unique_ptr<PasswordHash> tune(size_t output_length,
std::chrono::milliseconds msec,
size_t max_memory) const override;
std::unique_ptr<PasswordHash> default_params() const override;
std::unique_ptr<PasswordHash> from_iterations(size_t iter) const override;
std::unique_ptr<PasswordHash> from_params(
size_t i, size_t, size_t) const override;
};
/**
* Bcrypt PBKDF compatible with OpenBSD bcrypt_pbkdf
*/
void BOTAN_UNSTABLE_API bcrypt_pbkdf(uint8_t output[], size_t output_len,
const char* pass, size_t pass_len,
const uint8_t salt[], size_t salt_len,
size_t rounds);
}
#endif

View file

@ -0,0 +1,418 @@
/*
* BER Decoder
* (C) 1999-2010,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BER_DECODER_H_
#define BOTAN_BER_DECODER_H_
#include <botan/asn1_obj.h>
#include <botan/data_src.h>
namespace Botan {
class BigInt;
/**
* BER Decoding Object
*/
class BOTAN_PUBLIC_API(2,0) BER_Decoder final
{
public:
/**
* Set up to BER decode the data in buf of length len
*/
BER_Decoder(const uint8_t buf[], size_t len);
/**
* Set up to BER decode the data in vec
*/
explicit BER_Decoder(const secure_vector<uint8_t>& vec);
/**
* Set up to BER decode the data in vec
*/
explicit BER_Decoder(const std::vector<uint8_t>& vec);
/**
* Set up to BER decode the data in src
*/
explicit BER_Decoder(DataSource& src);
/**
* Set up to BER decode the data in obj
*/
BER_Decoder(const BER_Object& obj) :
BER_Decoder(obj.bits(), obj.length()) {}
/**
* Set up to BER decode the data in obj
*/
BER_Decoder(BER_Object&& obj) :
BER_Decoder(std::move(obj), nullptr) {}
BER_Decoder(const BER_Decoder& other);
BER_Decoder& operator=(const BER_Decoder&) = delete;
/**
* Get the next object in the data stream.
* If EOF, returns an object with type NO_OBJECT.
*/
BER_Object get_next_object();
BER_Decoder& get_next(BER_Object& ber)
{
ber = get_next_object();
return (*this);
}
/**
* Push an object back onto the stream. Throws if another
* object was previously pushed and has not been subsequently
* read out.
*/
void push_back(const BER_Object& obj);
/**
* Push an object back onto the stream. Throws if another
* object was previously pushed and has not been subsequently
* read out.
*/
void push_back(BER_Object&& obj);
/**
* Return true if there is at least one more item remaining
*/
bool more_items() const;
/**
* Verify the stream is concluded, throws otherwise.
* Returns (*this)
*/
BER_Decoder& verify_end();
/**
* Verify the stream is concluded, throws otherwise.
* Returns (*this)
*/
BER_Decoder& verify_end(const std::string& err_msg);
/**
* Discard any data that remains unread
* Returns (*this)
*/
BER_Decoder& discard_remaining();
/**
* Start decoding a constructed data (sequence or set)
*/
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag = UNIVERSAL);
/**
* Finish decoding a constructed data, throws if any data remains.
* Returns the parent of *this (ie the object on which start_cons was called).
*/
BER_Decoder& end_cons();
/**
* Get next object and copy value to POD type
* Asserts value length is equal to POD type sizeof.
* Asserts Type tag and optional Class tag according to parameters.
* Copy value to POD type (struct, union, C-style array, std::array, etc.).
* @param out POD type reference where to copy object value
* @param type_tag ASN1_Tag enum to assert type on object read
* @param class_tag ASN1_Tag enum to assert class on object read (default: CONTEXT_SPECIFIC)
* @return this reference
*/
template <typename T>
BER_Decoder& get_next_value(T &out,
ASN1_Tag type_tag,
ASN1_Tag class_tag = CONTEXT_SPECIFIC)
{
static_assert(std::is_standard_layout<T>::value && std::is_trivial<T>::value, "Type must be POD");
BER_Object obj = get_next_object();
obj.assert_is_a(type_tag, class_tag);
if (obj.length() != sizeof(T))
throw BER_Decoding_Error(
"Size mismatch. Object value size is " +
std::to_string(obj.length()) +
"; Output type size is " +
std::to_string(sizeof(T)));
copy_mem(reinterpret_cast<uint8_t*>(&out), obj.bits(), obj.length());
return (*this);
}
/*
* Save all the bytes remaining in the source
*/
template<typename Alloc>
BER_Decoder& raw_bytes(std::vector<uint8_t, Alloc>& out)
{
out.clear();
uint8_t buf;
while(m_source->read_byte(buf))
out.push_back(buf);
return (*this);
}
BER_Decoder& decode_null();
/**
* Decode a BER encoded BOOLEAN
*/
BER_Decoder& decode(bool& out)
{
return decode(out, BOOLEAN, UNIVERSAL);
}
/*
* Decode a small BER encoded INTEGER
*/
BER_Decoder& decode(size_t& out)
{
return decode(out, INTEGER, UNIVERSAL);
}
/*
* Decode a BER encoded INTEGER
*/
BER_Decoder& decode(BigInt& out)
{
return decode(out, INTEGER, UNIVERSAL);
}
std::vector<uint8_t> get_next_octet_string()
{
std::vector<uint8_t> out_vec;
decode(out_vec, OCTET_STRING);
return out_vec;
}
/*
* BER decode a BIT STRING or OCTET STRING
*/
template<typename Alloc>
BER_Decoder& decode(std::vector<uint8_t, Alloc>& out, ASN1_Tag real_type)
{
return decode(out, real_type, real_type, UNIVERSAL);
}
BER_Decoder& decode(bool& v,
ASN1_Tag type_tag,
ASN1_Tag class_tag = CONTEXT_SPECIFIC);
BER_Decoder& decode(size_t& v,
ASN1_Tag type_tag,
ASN1_Tag class_tag = CONTEXT_SPECIFIC);
BER_Decoder& decode(BigInt& v,
ASN1_Tag type_tag,
ASN1_Tag class_tag = CONTEXT_SPECIFIC);
BER_Decoder& decode(std::vector<uint8_t>& v,
ASN1_Tag real_type,
ASN1_Tag type_tag,
ASN1_Tag class_tag = CONTEXT_SPECIFIC);
BER_Decoder& decode(secure_vector<uint8_t>& v,
ASN1_Tag real_type,
ASN1_Tag type_tag,
ASN1_Tag class_tag = CONTEXT_SPECIFIC);
BER_Decoder& decode(class ASN1_Object& obj,
ASN1_Tag type_tag = NO_OBJECT,
ASN1_Tag class_tag = NO_OBJECT);
/**
* Decode an integer value which is typed as an octet string
*/
BER_Decoder& decode_octet_string_bigint(BigInt& b);
uint64_t decode_constrained_integer(ASN1_Tag type_tag,
ASN1_Tag class_tag,
size_t T_bytes);
template<typename T> BER_Decoder& decode_integer_type(T& out)
{
return decode_integer_type<T>(out, INTEGER, UNIVERSAL);
}
template<typename T>
BER_Decoder& decode_integer_type(T& out,
ASN1_Tag type_tag,
ASN1_Tag class_tag = CONTEXT_SPECIFIC)
{
out = static_cast<T>(decode_constrained_integer(type_tag, class_tag, sizeof(out)));
return (*this);
}
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_optional_implicit(
T& out,
ASN1_Tag type_tag,
ASN1_Tag class_tag,
ASN1_Tag real_type,
ASN1_Tag real_class,
const T& default_value = T());
template<typename T>
BER_Decoder& decode_list(std::vector<T>& out,
ASN1_Tag type_tag = SEQUENCE,
ASN1_Tag class_tag = UNIVERSAL);
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);
}
/*
* Decode an OPTIONAL string type
*/
template<typename Alloc>
BER_Decoder& decode_optional_string(std::vector<uint8_t, Alloc>& out,
ASN1_Tag real_type,
uint16_t type_no,
ASN1_Tag class_tag = CONTEXT_SPECIFIC)
{
BER_Object obj = get_next_object();
ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no);
if(obj.is_a(type_tag, class_tag))
{
if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
{
BER_Decoder(std::move(obj)).decode(out, real_type).verify_end();
}
else
{
push_back(std::move(obj));
decode(out, real_type, type_tag, class_tag);
}
}
else
{
out.clear();
push_back(std::move(obj));
}
return (*this);
}
private:
BER_Decoder(BER_Object&& obj, BER_Decoder* parent);
BER_Decoder* m_parent = nullptr;
BER_Object m_pushed;
// either m_data_src.get() or an unowned pointer
DataSource* m_source;
mutable std::unique_ptr<DataSource> m_data_src;
};
/*
* 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.is_a(type_tag, class_tag))
{
if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
{
BER_Decoder(std::move(obj)).decode(out).verify_end();
}
else
{
push_back(std::move(obj));
decode(out, type_tag, class_tag);
}
}
else
{
out = default_value;
push_back(std::move(obj));
}
return (*this);
}
/*
* Decode an OPTIONAL or DEFAULT element
*/
template<typename T>
BER_Decoder& BER_Decoder::decode_optional_implicit(
T& out,
ASN1_Tag type_tag,
ASN1_Tag class_tag,
ASN1_Tag real_type,
ASN1_Tag real_class,
const T& default_value)
{
BER_Object obj = get_next_object();
if(obj.is_a(type_tag, class_tag))
{
obj.set_tagging(real_type, real_class);
push_back(std::move(obj));
decode(out, real_type, real_class);
}
else
{
// Not what we wanted, push it back on the stream
out = default_value;
push_back(std::move(obj));
}
return (*this);
}
/*
* Decode a list of homogenously typed values
*/
template<typename T>
BER_Decoder& BER_Decoder::decode_list(std::vector<T>& vec,
ASN1_Tag type_tag,
ASN1_Tag class_tag)
{
BER_Decoder list = start_cons(type_tag, class_tag);
while(list.more_items())
{
T value;
list.decode(value);
vec.push_back(std::move(value));
}
list.end_cons();
return (*this);
}
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,60 @@
/*
* BLAKE2b
* (C) 2016 cynecx
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BLAKE2B_H_
#define BOTAN_BLAKE2B_H_
#include <botan/hash.h>
#include <string>
#include <memory>
BOTAN_FUTURE_INTERNAL_HEADER(blake2b.h)
namespace Botan {
/**
* BLAKE2B
*/
class BOTAN_PUBLIC_API(2,0) BLAKE2b final : public HashFunction
{
public:
/**
* @param output_bits the output size of BLAKE2b in bits
*/
explicit BLAKE2b(size_t output_bits = 512);
size_t hash_block_size() const override { return 128; }
size_t output_length() const override { return m_output_bits / 8; }
HashFunction* clone() const override;
std::string name() const override;
void clear() override;
std::unique_ptr<HashFunction> copy_state() const override;
private:
void add_data(const uint8_t input[], size_t length) override;
void final_result(uint8_t out[]) override;
void state_init();
void compress(const uint8_t* data, size_t blocks, uint64_t increment);
const size_t m_output_bits;
secure_vector<uint8_t> m_buffer;
size_t m_bufpos;
secure_vector<uint64_t> m_H;
uint64_t m_T[2];
uint64_t m_F[2];
};
typedef BLAKE2b Blake2b;
}
#endif

View file

@ -0,0 +1,80 @@
/*
* Blinding for public key operations
* (C) 1999-2010,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BLINDER_H_
#define BOTAN_BLINDER_H_
#include <botan/bigint.h>
#include <botan/reducer.h>
#include <functional>
BOTAN_FUTURE_INTERNAL_HEADER(blinding.h)
namespace Botan {
class RandomNumberGenerator;
/**
* Blinding Function Object.
*/
class BOTAN_PUBLIC_API(2,0) Blinder final
{
public:
/**
* Blind a value.
* The blinding nonce k is freshly generated after
* BOTAN_BLINDING_REINIT_INTERVAL calls to blind().
* BOTAN_BLINDING_REINIT_INTERVAL = 0 means a fresh
* nonce is only generated once. On every other call,
* an updated nonce is used for blinding: k' = k*k mod n.
* @param x value to blind
* @return blinded value
*/
BigInt blind(const BigInt& x) const;
/**
* Unblind a value.
* @param x value to unblind
* @return unblinded value
*/
BigInt unblind(const BigInt& x) const;
/**
* @param modulus the modulus
* @param rng the RNG to use for generating the nonce
* @param fwd_func a function that calculates the modular
* exponentiation of the public exponent and the given value (the nonce)
* @param inv_func a function that calculates the modular inverse
* of the given value (the nonce)
*/
Blinder(const BigInt& modulus,
RandomNumberGenerator& rng,
std::function<BigInt (const BigInt&)> fwd_func,
std::function<BigInt (const BigInt&)> inv_func);
Blinder(const Blinder&) = delete;
Blinder& operator=(const Blinder&) = delete;
RandomNumberGenerator& rng() const { return m_rng; }
private:
BigInt blinding_nonce() const;
Modular_Reducer m_reducer;
RandomNumberGenerator& m_rng;
std::function<BigInt (const BigInt&)> m_fwd_fn;
std::function<BigInt (const BigInt&)> m_inv_fn;
size_t m_modulus_bits = 0;
mutable BigInt m_e, m_d;
mutable size_t m_counter = 0;
};
}
#endif

View file

@ -0,0 +1,254 @@
/*
* Block Cipher Base Class
* (C) 1999-2009 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BLOCK_CIPHER_H_
#define BOTAN_BLOCK_CIPHER_H_
#include <botan/sym_algo.h>
#include <string>
#include <memory>
#include <vector>
namespace Botan {
/**
* This class represents a block cipher object.
*/
class BOTAN_PUBLIC_API(2,0) BlockCipher : public SymmetricAlgorithm
{
public:
/**
* Create an instance based on a name
* If provider is empty then best available is chosen.
* @param algo_spec algorithm name
* @param provider provider implementation to choose
* @return a null pointer if the algo/provider combination cannot be found
*/
static std::unique_ptr<BlockCipher>
create(const std::string& algo_spec,
const std::string& provider = "");
/**
* Create an instance based on a name, or throw if the
* algo/provider combination cannot be found. If provider is
* empty then best available is chosen.
*/
static std::unique_ptr<BlockCipher>
create_or_throw(const std::string& algo_spec,
const std::string& provider = "");
/**
* @return list of available providers for this algorithm, empty if not available
* @param algo_spec algorithm name
*/
static std::vector<std::string> providers(const std::string& algo_spec);
/**
* @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;
}
/**
* @return provider information about this implementation. Default is "base",
* might also return "sse2", "avx2", "openssl", or some other arbitrary string.
*/
virtual std::string provider() const { return "base"; }
/**
* 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 uint8_t in[], uint8_t 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 uint8_t in[], uint8_t 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(uint8_t 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(uint8_t block[]) const { decrypt_n(block, block, 1); }
/**
* Encrypt one or more blocks
* @param block the input/output buffer (multiple of block_size())
*/
template<typename Alloc>
void encrypt(std::vector<uint8_t, Alloc>& block) const
{
return encrypt_n(block.data(), block.data(), block.size() / block_size());
}
/**
* Decrypt one or more blocks
* @param block the input/output buffer (multiple of block_size())
*/
template<typename Alloc>
void decrypt(std::vector<uint8_t, Alloc>& block) const
{
return decrypt_n(block.data(), block.data(), block.size() / block_size());
}
/**
* Encrypt one or more blocks
* @param in the input buffer (multiple of block_size())
* @param out the output buffer (same size as in)
*/
template<typename Alloc, typename Alloc2>
void encrypt(const std::vector<uint8_t, Alloc>& in,
std::vector<uint8_t, Alloc2>& out) const
{
return encrypt_n(in.data(), out.data(), in.size() / block_size());
}
/**
* Decrypt one or more blocks
* @param in the input buffer (multiple of block_size())
* @param out the output buffer (same size as in)
*/
template<typename Alloc, typename Alloc2>
void decrypt(const std::vector<uint8_t, Alloc>& in,
std::vector<uint8_t, Alloc2>& out) const
{
return decrypt_n(in.data(), out.data(), in.size() / block_size());
}
/**
* 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 uint8_t in[], uint8_t 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 uint8_t in[], uint8_t out[],
size_t blocks) const = 0;
virtual void encrypt_n_xex(uint8_t data[],
const uint8_t mask[],
size_t blocks) const
{
const size_t BS = block_size();
xor_buf(data, mask, blocks * BS);
encrypt_n(data, data, blocks);
xor_buf(data, mask, blocks * BS);
}
virtual void decrypt_n_xex(uint8_t data[],
const uint8_t mask[],
size_t blocks) const
{
const size_t BS = block_size();
xor_buf(data, mask, blocks * BS);
decrypt_n(data, data, blocks);
xor_buf(data, mask, blocks * BS);
}
/**
* @return new object representing the same algorithm as *this
*/
virtual BlockCipher* clone() const = 0;
virtual ~BlockCipher() = default;
};
/**
* Tweakable block ciphers allow setting a tweak which is a non-keyed
* value which affects the encryption/decryption operation.
*/
class BOTAN_PUBLIC_API(2,8) Tweakable_Block_Cipher : public BlockCipher
{
public:
/**
* Set the tweak value. This must be called after setting a key. The value
* persists until either set_tweak, set_key, or clear is called.
* Different algorithms support different tweak length(s). If called with
* an unsupported length, Invalid_Argument will be thrown.
*/
virtual void set_tweak(const uint8_t tweak[], size_t len) = 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, typename BaseClass = BlockCipher>
class Block_Cipher_Fixed_Params : public BaseClass
{
public:
enum { BLOCK_SIZE = BS };
size_t block_size() const final override { return BS; }
// override to take advantage of compile time constant block size
void encrypt_n_xex(uint8_t data[],
const uint8_t mask[],
size_t blocks) const final override
{
xor_buf(data, mask, blocks * BS);
this->encrypt_n(data, data, blocks);
xor_buf(data, mask, blocks * BS);
}
void decrypt_n_xex(uint8_t data[],
const uint8_t mask[],
size_t blocks) const final override
{
xor_buf(data, mask, blocks * BS);
this->decrypt_n(data, data, blocks);
xor_buf(data, mask, blocks * BS);
}
Key_Length_Specification key_spec() const final override
{
return Key_Length_Specification(KMIN, KMAX, KMOD);
}
};
}
#endif

View file

@ -0,0 +1,62 @@
/*
* Blowfish
* (C) 1999-2011 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BLOWFISH_H_
#define BOTAN_BLOWFISH_H_
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(blowfish.h)
namespace Botan {
/**
* Blowfish
*/
class BOTAN_PUBLIC_API(2,0) Blowfish final : public Block_Cipher_Fixed_Params<8, 1, 56>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
/**
* Modified EKSBlowfish key schedule, used for bcrypt password hashing
*/
void salted_set_key(const uint8_t key[], size_t key_length,
const uint8_t salt[], size_t salt_length,
const size_t workfactor, bool salt_first = false);
BOTAN_DEPRECATED("Use Blowfish::salted_set_key taking salt length")
void eks_key_schedule(const uint8_t key[], size_t key_length,
const uint8_t salt[16], size_t workfactor)
{
salted_set_key(key, key_length, salt, 16, workfactor);
}
void clear() override;
std::string name() const override { return "Blowfish"; }
BlockCipher* clone() const override { return new Blowfish; }
private:
void key_schedule(const uint8_t key[], size_t length) override;
void key_expansion(const uint8_t key[],
size_t key_length,
const uint8_t salt[],
size_t salt_length);
void generate_sbox(secure_vector<uint32_t>& box,
uint32_t& L, uint32_t& R,
const uint8_t salt[],
size_t salt_length,
size_t salt_off) const;
secure_vector<uint32_t> m_S, m_P;
};
}
#endif

View file

@ -0,0 +1,41 @@
/*
* A vague catch all include file for Botan
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BOTAN_H_
#define BOTAN_BOTAN_H_
/*
* There is no real reason for this header to exist beyond historical
* reasons. The application should instead include the specific header
* files that define the interfaces it intends to use.
*
* This header file will be removed in Botan 3.x
*/
#include <botan/lookup.h>
#include <botan/version.h>
#include <botan/parsing.h>
#include <botan/init.h>
#include <botan/rng.h>
#include <botan/secmem.h>
#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
#include <botan/auto_rng.h>
#endif
#if defined(BOTAN_HAS_FILTERS)
#include <botan/filters.h>
#endif
#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
#include <botan/x509_key.h>
#include <botan/pkcs8.h>
#endif
BOTAN_DEPRECATED_HEADER(botan.h)
#endif

View file

@ -0,0 +1,108 @@
/*
* Byte Swapping Operations
* (C) 1999-2011,2018 Jack Lloyd
* (C) 2007 Yves Jerschow
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BYTE_SWAP_H_
#define BOTAN_BYTE_SWAP_H_
#include <botan/types.h>
#if defined(BOTAN_BUILD_COMPILER_IS_MSVC)
#include <stdlib.h>
#endif
BOTAN_FUTURE_INTERNAL_HEADER(bswap.h)
namespace Botan {
/**
* Swap a 16 bit integer
*/
inline uint16_t reverse_bytes(uint16_t val)
{
#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_XLC)
return __builtin_bswap16(val);
#else
return static_cast<uint16_t>((val << 8) | (val >> 8));
#endif
}
/**
* Swap a 32 bit integer
*/
inline uint32_t reverse_bytes(uint32_t val)
{
#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_XLC)
return __builtin_bswap32(val);
#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC)
return _byteswap_ulong(val);
#elif defined(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;
#else
// Generic implementation
uint16_t hi = static_cast<uint16_t>(val >> 16);
uint16_t lo = static_cast<uint16_t>(val);
hi = reverse_bytes(hi);
lo = reverse_bytes(lo);
return (static_cast<uint32_t>(lo) << 16) | hi;
#endif
}
/**
* Swap a 64 bit integer
*/
inline uint64_t reverse_bytes(uint64_t val)
{
#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_XLC)
return __builtin_bswap64(val);
#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC)
return _byteswap_uint64(val);
#elif defined(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.
*/
uint32_t hi = static_cast<uint32_t>(val >> 32);
uint32_t lo = static_cast<uint32_t>(val);
hi = reverse_bytes(hi);
lo = reverse_bytes(lo);
return (static_cast<uint64_t>(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]);
}
}
#endif

View file

@ -0,0 +1,178 @@
/*
* Buffered Computation
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BUFFERED_COMPUTATION_H_
#define BOTAN_BUFFERED_COMPUTATION_H_
#include <botan/secmem.h>
#include <string>
namespace Botan {
/**
* This class represents any kind of computation which uses an internal
* state, such as hash functions or MACs
*/
class BOTAN_PUBLIC_API(2,0) 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 uint8_t in[], size_t length) { add_data(in, length); }
/**
* Add new input to process.
* @param in the input to process as a secure_vector
*/
void update(const secure_vector<uint8_t>& in)
{
add_data(in.data(), in.size());
}
/**
* Add new input to process.
* @param in the input to process as a std::vector
*/
void update(const std::vector<uint8_t>& in)
{
add_data(in.data(), in.size());
}
void update_be(uint16_t val);
void update_be(uint32_t val);
void update_be(uint64_t val);
void update_le(uint16_t val);
void update_le(uint32_t val);
void update_le(uint64_t val);
/**
* 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(cast_char_ptr_to_uint8(str.data()), str.size());
}
/**
* Process a single byte.
* @param in the byte to process
*/
void update(uint8_t 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(uint8_t out[]) { final_result(out); }
/**
* Complete the computation and retrieve the
* final result.
* @return secure_vector holding the result
*/
secure_vector<uint8_t> final()
{
secure_vector<uint8_t> output(output_length());
final_result(output.data());
return output;
}
std::vector<uint8_t> final_stdvec()
{
std::vector<uint8_t> output(output_length());
final_result(output.data());
return output;
}
template<typename Alloc>
void final(std::vector<uint8_t, Alloc>& out)
{
out.resize(output_length());
final_result(out.data());
}
/**
* 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()
*/
secure_vector<uint8_t> process(const uint8_t 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()
*/
secure_vector<uint8_t> process(const secure_vector<uint8_t>& in)
{
add_data(in.data(), in.size());
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()
*/
secure_vector<uint8_t> process(const std::vector<uint8_t>& in)
{
add_data(in.data(), 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()
*/
secure_vector<uint8_t> process(const std::string& in)
{
update(in);
return final();
}
virtual ~Buffered_Computation() = default;
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 uint8_t input[], size_t length) = 0;
/**
* Write the final output to out
* @param out is an output buffer of output_length()
*/
virtual void final_result(uint8_t out[]) = 0;
};
}
#endif

View file

@ -0,0 +1,14 @@
/*
* Buffered Filter
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BUFFERED_FILTER_H_
#define BOTAN_BUFFERED_FILTER_H_
#include <botan/filters.h>
BOTAN_DEPRECATED_HEADER(buf_filt.h)
#endif

View file

@ -0,0 +1,471 @@
#ifndef BOTAN_BUILD_CONFIG_H_
#define BOTAN_BUILD_CONFIG_H_
/*
* Build configuration for Botan 2.18.1
*
* Automatically generated from
* 'configure.py --prefix=../botan-release'
*
* Target
* - Compiler: clang++ -fstack-protector -m64 -pthread -stdlib=libc++ -std=c++11 -D_REENTRANT -O3
* - Arch: x86_64
* - OS: macos
*/
#define BOTAN_VERSION_MAJOR 2
#define BOTAN_VERSION_MINOR 18
#define BOTAN_VERSION_PATCH 1
#define BOTAN_VERSION_DATESTAMP 0
#define BOTAN_VERSION_RELEASE_TYPE "unreleased"
#define BOTAN_VERSION_VC_REVISION "unknown"
#define BOTAN_DISTRIBUTION_INFO "unspecified"
/* How many bits per limb in a BigInt */
#define BOTAN_MP_WORD_BITS 64
#define BOTAN_INSTALL_PREFIX R"(../botan-release)"
#define BOTAN_INSTALL_HEADER_DIR R"(include/botan-2)"
#define BOTAN_INSTALL_LIB_DIR R"(../botan-release/lib)"
#define BOTAN_LIB_LINK "-ldl -framework CoreFoundation -framework Security"
#define BOTAN_LINK_FLAGS "-fstack-protector -m64 -pthread -stdlib=libc++"
#define BOTAN_SYSTEM_CERT_BUNDLE "/etc/ssl/cert.pem"
#ifndef BOTAN_DLL
#define BOTAN_DLL __attribute__((visibility("default")))
#endif
/* Target identification and feature test macros */
#define BOTAN_TARGET_OS_IS_MACOS
#define BOTAN_TARGET_OS_HAS_APPLE_KEYCHAIN
#define BOTAN_TARGET_OS_HAS_ARC4RANDOM
#define BOTAN_TARGET_OS_HAS_ATOMICS
#define BOTAN_TARGET_OS_HAS_CLOCK_GETTIME
#define BOTAN_TARGET_OS_HAS_COMMONCRYPTO
#define BOTAN_TARGET_OS_HAS_DEV_RANDOM
#define BOTAN_TARGET_OS_HAS_FILESYSTEM
#define BOTAN_TARGET_OS_HAS_GETENTROPY
#define BOTAN_TARGET_OS_HAS_POSIX1
#define BOTAN_TARGET_OS_HAS_POSIX_MLOCK
#define BOTAN_TARGET_OS_HAS_SOCKETS
#define BOTAN_TARGET_OS_HAS_THREAD_LOCAL
#define BOTAN_TARGET_OS_HAS_THREADS
#define BOTAN_BUILD_COMPILER_IS_CLANG
#define BOTAN_TARGET_ARCH_IS_X86_64
#define BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN
#define BOTAN_TARGET_CPU_IS_X86_FAMILY
#define BOTAN_TARGET_CPU_HAS_NATIVE_64BIT
#define BOTAN_TARGET_SUPPORTS_AESNI
#define BOTAN_TARGET_SUPPORTS_AVX2
#define BOTAN_TARGET_SUPPORTS_BMI2
#define BOTAN_TARGET_SUPPORTS_RDRAND
#define BOTAN_TARGET_SUPPORTS_RDSEED
#define BOTAN_TARGET_SUPPORTS_SHA
#define BOTAN_TARGET_SUPPORTS_SSE2
#define BOTAN_TARGET_SUPPORTS_SSE41
#define BOTAN_TARGET_SUPPORTS_SSE42
#define BOTAN_TARGET_SUPPORTS_SSSE3
/*
* Module availability definitions
*/
#define BOTAN_HAS_ADLER32 20131128
#define BOTAN_HAS_AEAD_CCM 20131128
#define BOTAN_HAS_AEAD_CHACHA20_POLY1305 20180807
#define BOTAN_HAS_AEAD_EAX 20131128
#define BOTAN_HAS_AEAD_GCM 20131128
#define BOTAN_HAS_AEAD_MODES 20131128
#define BOTAN_HAS_AEAD_OCB 20131128
#define BOTAN_HAS_AEAD_SIV 20131202
#define BOTAN_HAS_AES 20131128
#define BOTAN_HAS_AES_NI 20131128
#define BOTAN_HAS_AES_VPERM 20190901
#define BOTAN_HAS_ANSI_X919_MAC 20131128
#define BOTAN_HAS_ARGON2 20190824
#define BOTAN_HAS_ARIA 20170415
#define BOTAN_HAS_ASN1 20171109
#define BOTAN_HAS_AUTO_RNG 20161126
#define BOTAN_HAS_AUTO_SEEDING_RNG 20160821
#define BOTAN_HAS_BASE32_CODEC 20180418
#define BOTAN_HAS_BASE58_CODEC 20181209
#define BOTAN_HAS_BASE64_CODEC 20131128
#define BOTAN_HAS_BCRYPT 20131128
#define BOTAN_HAS_BIGINT 20131128
#define BOTAN_HAS_BIGINT_MP 20151225
#define BOTAN_HAS_BLAKE2B 20130131
#define BOTAN_HAS_BLOCK_CIPHER 20131128
#define BOTAN_HAS_BLOWFISH 20180718
#define BOTAN_HAS_CAMELLIA 20150922
#define BOTAN_HAS_CASCADE 20131128
#define BOTAN_HAS_CAST 20131128
#define BOTAN_HAS_CAST_128 20171203
#define BOTAN_HAS_CAST_256 20171203
#define BOTAN_HAS_CBC_MAC 20131128
#define BOTAN_HAS_CECPQ1 20161116
#define BOTAN_HAS_CERTSTOR_FLATFILE 20190410
#define BOTAN_HAS_CERTSTOR_MACOS 20190207
#define BOTAN_HAS_CERTSTOR_SQL 20160818
#define BOTAN_HAS_CERTSTOR_SYSTEM 20190411
#define BOTAN_HAS_CHACHA 20180807
#define BOTAN_HAS_CHACHA_AVX2 20180418
#define BOTAN_HAS_CHACHA_RNG 20170728
#define BOTAN_HAS_CHACHA_SIMD32 20181104
#define BOTAN_HAS_CIPHER_MODES 20180124
#define BOTAN_HAS_CIPHER_MODE_PADDING 20131128
#define BOTAN_HAS_CMAC 20131128
#define BOTAN_HAS_CODEC_FILTERS 20131128
#define BOTAN_HAS_COMB4P 20131128
#define BOTAN_HAS_CPUID 20170917
#define BOTAN_HAS_CRC24 20131128
#define BOTAN_HAS_CRC32 20131128
#define BOTAN_HAS_CRYPTO_BOX 20131128
#define BOTAN_HAS_CTR_BE 20131128
#define BOTAN_HAS_CURVE_25519 20170621
#define BOTAN_HAS_DES 20131128
#define BOTAN_HAS_DIFFIE_HELLMAN 20131128
#define BOTAN_HAS_DLIES 20160713
#define BOTAN_HAS_DL_GROUP 20131128
#define BOTAN_HAS_DL_PUBLIC_KEY_FAMILY 20131128
#define BOTAN_HAS_DSA 20131128
#define BOTAN_HAS_DYNAMIC_LOADER 20160310
#define BOTAN_HAS_ECC_GROUP 20170225
#define BOTAN_HAS_ECC_KEY 20190801
#define BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO 20131128
#define BOTAN_HAS_ECDH 20131128
#define BOTAN_HAS_ECDSA 20131128
#define BOTAN_HAS_ECGDSA 20160301
#define BOTAN_HAS_ECIES 20160128
#define BOTAN_HAS_ECKCDSA 20160413
#define BOTAN_HAS_EC_CURVE_GFP 20131128
#define BOTAN_HAS_ED25519 20170607
#define BOTAN_HAS_ELGAMAL 20131128
#define BOTAN_HAS_EME_OAEP 20180305
#define BOTAN_HAS_EME_PKCS1 20190426
#define BOTAN_HAS_EME_PKCS1v15 20131128
#define BOTAN_HAS_EME_RAW 20150313
#define BOTAN_HAS_EMSA1 20131128
#define BOTAN_HAS_EMSA_PKCS1 20140118
#define BOTAN_HAS_EMSA_PSSR 20131128
#define BOTAN_HAS_EMSA_RAW 20131128
#define BOTAN_HAS_EMSA_X931 20140118
#define BOTAN_HAS_ENTROPY_SOURCE 20151120
#define BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM 20131128
#define BOTAN_HAS_ENTROPY_SRC_GETENTROPY 20170327
#define BOTAN_HAS_ENTROPY_SRC_RDSEED 20151218
#define BOTAN_HAS_FFI 20210220
#define BOTAN_HAS_FILTERS 20160415
#define BOTAN_HAS_FPE_FE1 20131128
#define BOTAN_HAS_GHASH 20201002
#define BOTAN_HAS_GHASH_CLMUL_CPU 20201002
#define BOTAN_HAS_GHASH_CLMUL_VPERM 20201002
#define BOTAN_HAS_GMAC 20160207
#define BOTAN_HAS_GOST_28147_89 20131128
#define BOTAN_HAS_GOST_34_10_2001 20131128
#define BOTAN_HAS_GOST_34_10_2012 20190801
#define BOTAN_HAS_GOST_34_11 20131128
#define BOTAN_HAS_HASH 20180112
#define BOTAN_HAS_HASH_ID 20131128
#define BOTAN_HAS_HEX_CODEC 20131128
#define BOTAN_HAS_HKDF 20170927
#define BOTAN_HAS_HMAC 20131128
#define BOTAN_HAS_HMAC_DRBG 20140319
#define BOTAN_HAS_HOTP 20180816
#define BOTAN_HAS_HTTP_UTIL 20171003
#define BOTAN_HAS_IDEA 20131128
#define BOTAN_HAS_IDEA_SSE2 20131128
#define BOTAN_HAS_ISO_9796 20161121
#define BOTAN_HAS_KASUMI 20131128
#define BOTAN_HAS_KDF1 20131128
#define BOTAN_HAS_KDF1_18033 20160128
#define BOTAN_HAS_KDF2 20131128
#define BOTAN_HAS_KDF_BASE 20131128
#define BOTAN_HAS_KECCAK 20131128
#define BOTAN_HAS_KEYPAIR_TESTING 20131128
#define BOTAN_HAS_LION 20131128
#define BOTAN_HAS_LOCKING_ALLOCATOR 20131128
#define BOTAN_HAS_MAC 20150626
#define BOTAN_HAS_MCEIES 20150706
#define BOTAN_HAS_MCELIECE 20150922
#define BOTAN_HAS_MD4 20131128
#define BOTAN_HAS_MD5 20131128
#define BOTAN_HAS_MDX_HASH_FUNCTION 20131128
#define BOTAN_HAS_MEM_POOL 20180309
#define BOTAN_HAS_MGF1 20140118
#define BOTAN_HAS_MISTY1 20131128
#define BOTAN_HAS_MODES 20150626
#define BOTAN_HAS_MODE_CBC 20131128
#define BOTAN_HAS_MODE_CFB 20131128
#define BOTAN_HAS_MODE_XTS 20131128
#define BOTAN_HAS_NEWHOPE 20161018
#define BOTAN_HAS_NIST_KEYWRAP 20171119
#define BOTAN_HAS_NOEKEON 20131128
#define BOTAN_HAS_NOEKEON_SIMD 20160903
#define BOTAN_HAS_NUMBERTHEORY 20131128
#define BOTAN_HAS_OCSP 20161118
#define BOTAN_HAS_OFB 20131128
#define BOTAN_HAS_PACKAGE_TRANSFORM 20131128
#define BOTAN_HAS_PARALLEL_HASH 20131128
#define BOTAN_HAS_PASSHASH9 20131128
#define BOTAN_HAS_PBKDF 20180902
#define BOTAN_HAS_PBKDF1 20131128
#define BOTAN_HAS_PBKDF2 20180902
#define BOTAN_HAS_PBKDF_BCRYPT 20190531
#define BOTAN_HAS_PEM_CODEC 20131128
#define BOTAN_HAS_PGP_S2K 20170527
#define BOTAN_HAS_PIPE_UNIXFD_IO 20131128
#define BOTAN_HAS_PKCS11 20160219
#define BOTAN_HAS_PKCS5_PBES2 20141119
#define BOTAN_HAS_PK_PADDING 20131128
#define BOTAN_HAS_POLY1305 20141227
#define BOTAN_HAS_POLY_DBL 20170927
#define BOTAN_HAS_PROCESSOR_RNG 20200508
#define BOTAN_HAS_PSK_DB 20171119
#define BOTAN_HAS_PUBLIC_KEY_CRYPTO 20131128
#define BOTAN_HAS_RC4 20131128
#define BOTAN_HAS_RDRAND_RNG 20160619
#define BOTAN_HAS_RFC3394_KEYWRAP 20131128
#define BOTAN_HAS_RFC6979_GENERATOR 20140321
#define BOTAN_HAS_RIPEMD_160 20131128
#define BOTAN_HAS_ROUGHTIME 20190220
#define BOTAN_HAS_RSA 20160730
#define BOTAN_HAS_SALSA20 20171114
#define BOTAN_HAS_SCRYPT 20180902
#define BOTAN_HAS_SEED 20131128
#define BOTAN_HAS_SERPENT 20131128
#define BOTAN_HAS_SERPENT_AVX2 20180824
#define BOTAN_HAS_SERPENT_SIMD 20160903
#define BOTAN_HAS_SHA1 20131128
#define BOTAN_HAS_SHA1_SSE2 20160803
#define BOTAN_HAS_SHA1_X86_SHA_NI 20170518
#define BOTAN_HAS_SHA2_32 20131128
#define BOTAN_HAS_SHA2_32_X86 20170518
#define BOTAN_HAS_SHA2_32_X86_BMI2 20180526
#define BOTAN_HAS_SHA2_64 20131128
#define BOTAN_HAS_SHA2_64_BMI2 20190117
#define BOTAN_HAS_SHA3 20161018
#define BOTAN_HAS_SHA3_BMI2 20190117
#define BOTAN_HAS_SHACAL2 20170813
#define BOTAN_HAS_SHACAL2_AVX2 20180826
#define BOTAN_HAS_SHACAL2_SIMD 20170813
#define BOTAN_HAS_SHACAL2_X86 20170814
#define BOTAN_HAS_SHAKE 20161009
#define BOTAN_HAS_SHAKE_CIPHER 20161018
#define BOTAN_HAS_SIMD_32 20131128
#define BOTAN_HAS_SIMD_AVX2 20180824
#define BOTAN_HAS_SIPHASH 20150110
#define BOTAN_HAS_SKEIN_512 20131128
#define BOTAN_HAS_SM2 20180801
#define BOTAN_HAS_SM3 20170402
#define BOTAN_HAS_SM4 20170716
#define BOTAN_HAS_SOCKETS 20171216
#define BOTAN_HAS_SODIUM_API 20190615
#define BOTAN_HAS_SP800_108 20160128
#define BOTAN_HAS_SP800_56A 20170501
#define BOTAN_HAS_SP800_56C 20160211
#define BOTAN_HAS_SRP6 20161017
#define BOTAN_HAS_STATEFUL_RNG 20160819
#define BOTAN_HAS_STREAM_CIPHER 20131128
#define BOTAN_HAS_STREEBOG 20170623
#define BOTAN_HAS_SYSTEM_RNG 20141202
#define BOTAN_HAS_THREAD_UTILS 20190922
#define BOTAN_HAS_THREEFISH_512 20131224
#define BOTAN_HAS_THREEFISH_512_AVX2 20160903
#define BOTAN_HAS_THRESHOLD_SECRET_SHARING 20131128
#define BOTAN_HAS_TIGER 20131128
#define BOTAN_HAS_TLS 20191210
#define BOTAN_HAS_TLS_CBC 20161008
#define BOTAN_HAS_TLS_SESSION_MANAGER_SQL_DB 20141219
#define BOTAN_HAS_TLS_V10 20191109
#define BOTAN_HAS_TLS_V10_PRF 20131128
#define BOTAN_HAS_TLS_V12_PRF 20131128
#define BOTAN_HAS_TOTP 20180816
#define BOTAN_HAS_TWOFISH 20131128
#define BOTAN_HAS_UTIL_FUNCTIONS 20180903
#define BOTAN_HAS_UUID 20180930
#define BOTAN_HAS_WHIRLPOOL 20131128
#define BOTAN_HAS_X25519 20180910
#define BOTAN_HAS_X509 20180911
#define BOTAN_HAS_X509_CERTIFICATES 20151023
#define BOTAN_HAS_X942_PRF 20131128
#define BOTAN_HAS_XMSS_RFC8391 20201101
#define BOTAN_HAS_XTEA 20131128
/*
* Local/misc configuration options (if any) follow
*/
/*
* Things you can edit (but probably shouldn't)
*/
#if !defined(BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES)
#if defined(BOTAN_NO_DEPRECATED)
#define BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES private
#else
#define BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES public
#endif
#endif
/* How much to allocate for a buffer of no particular size */
#define BOTAN_DEFAULT_BUFFER_SIZE 1024
/*
* Total maximum amount of RAM (in KiB) we will lock into memory, even
* if the OS would let us lock more
*/
#define BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB 512
/*
* If BOTAN_MEM_POOL_USE_MMU_PROTECTIONS is defined, the Memory_Pool
* class used for mlock'ed memory will use OS calls to set page
* permissions so as to prohibit access to pages on the free list, then
* enable read/write access when the page is set to be used. This will
* turn (some) use after free bugs into a crash.
*
* The additional syscalls have a substantial performance impact, which
* is why this option is not enabled by default.
*/
#if defined(BOTAN_HAS_VALGRIND) || defined(BOTAN_ENABLE_DEBUG_ASSERTS)
#define BOTAN_MEM_POOL_USE_MMU_PROTECTIONS
#endif
/*
* If enabled uses memset via volatile function pointer to zero memory,
* otherwise does a byte at a time write via a volatile pointer.
*/
#define BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO 1
/*
* Normally blinding is performed by choosing a random starting point (plus
* its inverse, of a form appropriate to the algorithm being blinded), and
* then choosing new blinding operands by successive squaring of both
* values. This is much faster than computing a new starting point but
* introduces some possible corelation
*
* To avoid possible leakage problems in long-running processes, the blinder
* periodically reinitializes the sequence. This value specifies how often
* a new sequence should be started.
*/
#define BOTAN_BLINDING_REINIT_INTERVAL 64
/*
* Userspace RNGs like HMAC_DRBG will reseed after a specified number
* of outputs are generated. Set to zero to disable automatic reseeding.
*/
#define BOTAN_RNG_DEFAULT_RESEED_INTERVAL 1024
#define BOTAN_RNG_RESEED_POLL_BITS 256
#define BOTAN_RNG_AUTO_RESEED_TIMEOUT std::chrono::milliseconds(10)
#define BOTAN_RNG_RESEED_DEFAULT_TIMEOUT std::chrono::milliseconds(50)
/*
* Specifies (in order) the list of entropy sources that will be used
* to seed an in-memory RNG.
*/
#define BOTAN_ENTROPY_DEFAULT_SOURCES \
{ "rdseed", "hwrng", "p9_darn", "getentropy", "dev_random", \
"system_rng", "proc_walk", "system_stats" }
/* Multiplier on a block cipher's native parallelism */
#define BOTAN_BLOCK_CIPHER_PAR_MULT 4
/*
* These control the RNG used by the system RNG interface
*/
#define BOTAN_SYSTEM_RNG_DEVICE "/dev/urandom"
#define BOTAN_SYSTEM_RNG_POLL_DEVICES { "/dev/urandom", "/dev/random" }
/*
* This directory will be monitored by ProcWalking_EntropySource and
* the contents provided as entropy inputs to the RNG. May also be
* usefully set to something like "/sys", depending on the system being
* deployed to. Set to an empty string to disable.
*/
#define BOTAN_ENTROPY_PROC_FS_PATH "/proc"
/*
* These paramaters control how many bytes to read from the system
* PRNG, and how long to block if applicable. The timeout only applies
* to reading /dev/urandom and company.
*/
#define BOTAN_SYSTEM_RNG_POLL_REQUEST 64
#define BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS 20
/*
* When a PBKDF is self-tuning parameters, it will attempt to take about this
* amount of time to self-benchmark.
*/
#define BOTAN_PBKDF_TUNING_TIME std::chrono::milliseconds(10)
/*
* If no way of dynamically determining the cache line size for the
* system exists, this value is used as the default. Used by the side
* channel countermeasures rather than for alignment purposes, so it is
* better to be on the smaller side if the exact value cannot be
* determined. Typically 32 or 64 bytes on modern CPUs.
*/
#if !defined(BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE)
#define BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE 32
#endif
/**
* Controls how AutoSeeded_RNG is instantiated
*/
#if !defined(BOTAN_AUTO_RNG_HMAC)
#if defined(BOTAN_HAS_SHA2_64)
#define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-384)"
#elif defined(BOTAN_HAS_SHA2_32)
#define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-256)"
#elif defined(BOTAN_HAS_SHA3)
#define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-3(256))"
#elif defined(BOTAN_HAS_SHA1)
#define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-1)"
#endif
/* Otherwise, no hash found: leave BOTAN_AUTO_RNG_HMAC undefined */
#endif
/* Check for a common build problem */
#if defined(BOTAN_TARGET_ARCH_IS_X86_64) && ((defined(_MSC_VER) && !defined(_WIN64)) || \
(defined(__clang__) && !defined(__x86_64__)) || \
(defined(__GNUG__) && !defined(__x86_64__)))
#error "Trying to compile Botan configured as x86_64 with non-x86_64 compiler."
#endif
#if defined(BOTAN_TARGET_ARCH_IS_X86_32) && ((defined(_MSC_VER) && defined(_WIN64)) || \
(defined(__clang__) && !defined(__i386__)) || \
(defined(__GNUG__) && !defined(__i386__)))
#error "Trying to compile Botan configured as x86_32 with non-x86_32 compiler."
#endif
#include <botan/compiler.h>
#endif

View file

@ -0,0 +1,91 @@
/*
* Calendar Functions
* (C) 1999-2009,2015 Jack Lloyd
* (C) 2015 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CALENDAR_H_
#define BOTAN_CALENDAR_H_
#include <botan/types.h>
#include <chrono>
#include <string>
namespace Botan {
/**
* Struct representing a particular date and time
*/
class BOTAN_PUBLIC_API(2,0) calendar_point
{
public:
/** The year */
uint32_t get_year() const { return year; }
/** The month, 1 through 12 for Jan to Dec */
uint32_t get_month() const { return month; }
/** The day of the month, 1 through 31 (or 28 or 30 based on month */
uint32_t get_day() const { return day; }
/** Hour in 24-hour form, 0 to 23 */
uint32_t get_hour() const { return hour; }
/** Minutes in the hour, 0 to 60 */
uint32_t get_minutes() const { return minutes; }
/** Seconds in the minute, 0 to 60, but might be slightly
larger to deal with leap seconds on some systems
*/
uint32_t get_seconds() const { return 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(uint32_t y, uint32_t mon, uint32_t d, uint32_t h, uint32_t min, uint32_t sec) :
year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {}
/**
* Returns an STL timepoint object
*/
std::chrono::system_clock::time_point to_std_timepoint() const;
/**
* Returns a human readable string of the struct's components.
* Formatting might change over time. Currently it is RFC339 'iso-date-time'.
*/
std::string to_string() const;
BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES:
/*
The member variables are public for historical reasons. Use the get_xxx() functions
defined above. These members will be made private in a future major release.
*/
uint32_t year;
uint32_t month;
uint32_t day;
uint32_t hour;
uint32_t minutes;
uint32_t seconds;
};
/**
* Convert a time_point to a calendar_point
* @param time_point a time point from the system clock
* @return calendar_point object representing this time point
*/
BOTAN_PUBLIC_API(2,0) calendar_point calendar_value(
const std::chrono::system_clock::time_point& time_point);
}
#endif

View file

@ -0,0 +1,73 @@
/*
* Camellia
* (C) 2012 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CAMELLIA_H_
#define BOTAN_CAMELLIA_H_
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(camellia.h)
namespace Botan {
/**
* Camellia-128
*/
class BOTAN_PUBLIC_API(2,0) Camellia_128 final : public Block_Cipher_Fixed_Params<16, 16>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "Camellia-128"; }
BlockCipher* clone() const override { return new Camellia_128; }
private:
void key_schedule(const uint8_t key[], size_t length) override;
secure_vector<uint64_t> m_SK;
};
/**
* Camellia-192
*/
class BOTAN_PUBLIC_API(2,0) Camellia_192 final : public Block_Cipher_Fixed_Params<16, 24>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "Camellia-192"; }
BlockCipher* clone() const override { return new Camellia_192; }
private:
void key_schedule(const uint8_t key[], size_t length) override;
secure_vector<uint64_t> m_SK;
};
/**
* Camellia-256
*/
class BOTAN_PUBLIC_API(2,0) Camellia_256 final : public Block_Cipher_Fixed_Params<16, 32>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "Camellia-256"; }
BlockCipher* clone() const override { return new Camellia_256; }
private:
void key_schedule(const uint8_t key[], size_t length) override;
secure_vector<uint64_t> m_SK;
};
}
#endif

View file

@ -0,0 +1,57 @@
/*
* Block Cipher Cascade
* (C) 2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CASCADE_H_
#define BOTAN_CASCADE_H_
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(cascade.h)
namespace Botan {
/**
* Block Cipher Cascade
*/
class BOTAN_PUBLIC_API(2,0) Cascade_Cipher final : public BlockCipher
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
size_t block_size() const override { return m_block; }
Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(m_cipher1->maximum_keylength() +
m_cipher2->maximum_keylength());
}
void clear() override;
std::string name() const override;
BlockCipher* clone() const override;
/**
* 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(const Cascade_Cipher&) = delete;
Cascade_Cipher& operator=(const Cascade_Cipher&) = delete;
private:
void key_schedule(const uint8_t[], size_t) override;
size_t m_block;
std::unique_ptr<BlockCipher> m_cipher1, m_cipher2;
};
}
#endif

View file

@ -0,0 +1,42 @@
/*
* CAST-128
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CAST128_H_
#define BOTAN_CAST128_H_
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(cast128.h)
namespace Botan {
/**
* CAST-128
*/
class BOTAN_PUBLIC_API(2,0) CAST_128 final : public Block_Cipher_Fixed_Params<8, 11, 16>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "CAST-128"; }
BlockCipher* clone() const override { return new CAST_128; }
private:
void key_schedule(const uint8_t[], size_t) override;
static void cast_ks(secure_vector<uint32_t>& ks,
secure_vector<uint32_t>& user_key);
secure_vector<uint32_t> m_MK;
secure_vector<uint8_t> m_RK;
};
}
#endif

View file

@ -0,0 +1,38 @@
/*
* CAST-256
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CAST256_H_
#define BOTAN_CAST256_H_
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(cast256.h)
namespace Botan {
/**
* CAST-256
*/
class BOTAN_PUBLIC_API(2,0) CAST_256 final : public Block_Cipher_Fixed_Params<16, 4, 32, 4>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "CAST-256"; }
BlockCipher* clone() const override { return new CAST_256; }
private:
void key_schedule(const uint8_t[], size_t) override;
secure_vector<uint32_t> m_MK;
secure_vector<uint8_t> m_RK;
};
}
#endif

View file

@ -0,0 +1,157 @@
/*
* CBC mode
* (C) 1999-2007,2013 Jack Lloyd
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_MODE_CBC_H_
#define BOTAN_MODE_CBC_H_
#include <botan/cipher_mode.h>
#include <botan/block_cipher.h>
#include <botan/mode_pad.h>
BOTAN_FUTURE_INTERNAL_HEADER(cbc.h)
namespace Botan {
/**
* CBC Mode
*/
class BOTAN_PUBLIC_API(2,0) CBC_Mode : public Cipher_Mode
{
public:
std::string name() const override;
size_t update_granularity() const override;
Key_Length_Specification key_spec() const override;
size_t default_nonce_length() const override;
bool valid_nonce_length(size_t n) const override;
void clear() override;
void reset() override;
protected:
CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding);
const BlockCipher& cipher() const { return *m_cipher; }
const BlockCipherModePaddingMethod& padding() const
{
BOTAN_ASSERT_NONNULL(m_padding);
return *m_padding;
}
size_t block_size() const { return m_block_size; }
secure_vector<uint8_t>& state() { return m_state; }
uint8_t* state_ptr() { return m_state.data(); }
private:
void start_msg(const uint8_t nonce[], size_t nonce_len) override;
void key_schedule(const uint8_t key[], size_t length) override;
std::unique_ptr<BlockCipher> m_cipher;
std::unique_ptr<BlockCipherModePaddingMethod> m_padding;
secure_vector<uint8_t> m_state;
size_t m_block_size;
};
/**
* CBC Encryption
*/
class BOTAN_PUBLIC_API(2,0) CBC_Encryption : public CBC_Mode
{
public:
/**
* @param cipher block cipher to use
* @param padding padding method to use
*/
CBC_Encryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) :
CBC_Mode(cipher, padding) {}
size_t process(uint8_t buf[], size_t size) override;
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
size_t output_length(size_t input_length) const override;
size_t minimum_final_size() const override;
};
/**
* CBC Encryption with ciphertext stealing (CBC-CS3 variant)
*/
class BOTAN_PUBLIC_API(2,0) CTS_Encryption final : public CBC_Encryption
{
public:
/**
* @param cipher block cipher to use
*/
explicit CTS_Encryption(BlockCipher* cipher) : CBC_Encryption(cipher, nullptr) {}
size_t output_length(size_t input_length) const override;
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
size_t minimum_final_size() const override;
bool valid_nonce_length(size_t n) const override;
};
/**
* CBC Decryption
*/
class BOTAN_PUBLIC_API(2,0) CBC_Decryption : public CBC_Mode
{
public:
/**
* @param cipher block cipher to use
* @param padding padding method to use
*/
CBC_Decryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) :
CBC_Mode(cipher, padding), m_tempbuf(update_granularity()) {}
size_t process(uint8_t buf[], size_t size) override;
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
size_t output_length(size_t input_length) const override;
size_t minimum_final_size() const override;
void reset() override;
private:
secure_vector<uint8_t> m_tempbuf;
};
/**
* CBC Decryption with ciphertext stealing (CBC-CS3 variant)
*/
class BOTAN_PUBLIC_API(2,0) CTS_Decryption final : public CBC_Decryption
{
public:
/**
* @param cipher block cipher to use
*/
explicit CTS_Decryption(BlockCipher* cipher) : CBC_Decryption(cipher, nullptr) {}
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
size_t minimum_final_size() const override;
bool valid_nonce_length(size_t n) const override;
};
}
#endif

View file

@ -0,0 +1,50 @@
/*
* CBC-MAC
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CBC_MAC_H_
#define BOTAN_CBC_MAC_H_
#include <botan/mac.h>
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(cbc_mac.h)
namespace Botan {
/**
* CBC-MAC
*/
class BOTAN_PUBLIC_API(2,0) CBC_MAC final : public MessageAuthenticationCode
{
public:
std::string name() const override;
MessageAuthenticationCode* clone() const override;
size_t output_length() const override { return m_cipher->block_size(); }
void clear() override;
Key_Length_Specification key_spec() const override
{
return m_cipher->key_spec();
}
/**
* @param cipher the block cipher to use
*/
explicit CBC_MAC(BlockCipher* cipher);
private:
void add_data(const uint8_t[], size_t) override;
void final_result(uint8_t[]) override;
void key_schedule(const uint8_t[], size_t) override;
std::unique_ptr<BlockCipher> m_cipher;
secure_vector<uint8_t> m_state;
size_t m_position = 0;
};
}
#endif

View file

@ -0,0 +1,130 @@
/*
* CCM Mode
* (C) 2013 Jack Lloyd
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_AEAD_CCM_H_
#define BOTAN_AEAD_CCM_H_
#include <botan/aead.h>
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(ccm.h)
namespace Botan {
/**
* Base class for CCM encryption and decryption
* @see RFC 3610
*/
class BOTAN_PUBLIC_API(2,0) CCM_Mode : public AEAD_Mode
{
public:
size_t process(uint8_t buf[], size_t sz) override;
void set_associated_data(const uint8_t ad[], size_t ad_len) override;
bool associated_data_requires_key() const override { return false; }
std::string name() const override;
size_t update_granularity() const override;
Key_Length_Specification key_spec() const override;
bool valid_nonce_length(size_t) const override;
size_t default_nonce_length() const override;
void clear() override;
void reset() override;
size_t tag_size() const override { return m_tag_size; }
protected:
CCM_Mode(BlockCipher* cipher, size_t tag_size, size_t L);
size_t L() const { return m_L; }
const BlockCipher& cipher() const { return *m_cipher; }
void encode_length(uint64_t len, uint8_t out[]);
void inc(secure_vector<uint8_t>& C);
const secure_vector<uint8_t>& ad_buf() const { return m_ad_buf; }
secure_vector<uint8_t>& msg_buf() { return m_msg_buf; }
secure_vector<uint8_t> format_b0(size_t msg_size);
secure_vector<uint8_t> format_c0();
private:
void start_msg(const uint8_t nonce[], size_t nonce_len) override;
void key_schedule(const uint8_t key[], size_t length) override;
const size_t m_tag_size;
const size_t m_L;
std::unique_ptr<BlockCipher> m_cipher;
secure_vector<uint8_t> m_nonce, m_msg_buf, m_ad_buf;
};
/**
* CCM Encryption
*/
class BOTAN_PUBLIC_API(2,0) CCM_Encryption final : public CCM_Mode
{
public:
/**
* @param cipher a 128-bit block cipher
* @param tag_size is how big the auth tag will be (even values
* between 4 and 16 are accepted)
* @param L length of L parameter. The total message length
* must be less than 2**L bytes, and the nonce is 15-L bytes.
*/
CCM_Encryption(BlockCipher* cipher, size_t tag_size = 16, size_t L = 3) :
CCM_Mode(cipher, tag_size, L) {}
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
size_t output_length(size_t input_length) const override
{ return input_length + tag_size(); }
size_t minimum_final_size() const override { return 0; }
};
/**
* CCM Decryption
*/
class BOTAN_PUBLIC_API(2,0) CCM_Decryption final : public CCM_Mode
{
public:
/**
* @param cipher a 128-bit block cipher
* @param tag_size is how big the auth tag will be (even values
* between 4 and 16 are accepted)
* @param L length of L parameter. The total message length
* must be less than 2**L bytes, and the nonce is 15-L bytes.
*/
CCM_Decryption(BlockCipher* cipher, size_t tag_size = 16, size_t L = 3) :
CCM_Mode(cipher, tag_size, L) {}
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
size_t output_length(size_t input_length) const override
{
BOTAN_ASSERT(input_length >= tag_size(), "Sufficient input");
return input_length - tag_size();
}
size_t minimum_final_size() const override { return tag_size(); }
};
}
#endif

View file

@ -0,0 +1,38 @@
/*
* CECPQ1 (x25519 + NewHope)
* (C) 2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CECPQ1_H_
#define BOTAN_CECPQ1_H_
#include <botan/secmem.h>
#include <botan/newhope.h>
namespace Botan {
class CECPQ1_key final
{
public:
secure_vector<uint8_t> m_x25519;
newhope_poly m_newhope;
};
void BOTAN_PUBLIC_API(2,0) CECPQ1_offer(uint8_t* offer_message,
CECPQ1_key* offer_key_output,
RandomNumberGenerator& rng);
void BOTAN_PUBLIC_API(2,0) CECPQ1_accept(uint8_t* shared_key,
uint8_t* accept_message,
const uint8_t* offer_message,
RandomNumberGenerator& rng);
void BOTAN_PUBLIC_API(2,0) CECPQ1_finish(uint8_t* shared_key,
const CECPQ1_key& offer_key,
const uint8_t* accept_message);
}
#endif

View file

@ -0,0 +1,11 @@
/*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_X509_PATH_RESULT_H_
#define BOTAN_X509_PATH_RESULT_H_
#include <botan/pkix_enums.h>
BOTAN_DEPRECATED_HEADER(cert_status.h)
#endif

View file

@ -0,0 +1,165 @@
/*
* Certificate Store
* (C) 1999-2010,2013 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CERT_STORE_H_
#define BOTAN_CERT_STORE_H_
#include <botan/x509cert.h>
#include <botan/x509_crl.h>
namespace Botan {
/**
* Certificate Store Interface
*/
class BOTAN_PUBLIC_API(2,0) Certificate_Store
{
public:
virtual ~Certificate_Store();
/**
* Find a certificate by Subject DN and (optionally) key identifier
* @param subject_dn the subject's distinguished name
* @param key_id an optional key id
* @return a matching certificate or nullptr otherwise
* If more than one certificate in the certificate store matches, then
* a single value is selected arbitrarily.
*/
virtual std::shared_ptr<const X509_Certificate>
find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const;
/**
* Find all certificates with a given Subject DN.
* Subject DN and even the key identifier might not be unique.
*/
virtual std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs(
const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const = 0;
/**
* Find a certificate by searching for one with a matching SHA-1 hash of
* public key. Used for OCSP.
* @param key_hash SHA-1 hash of the subject's public key
* @return a matching certificate or nullptr otherwise
*/
virtual std::shared_ptr<const X509_Certificate>
find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const = 0;
/**
* Find a certificate by searching for one with a matching SHA-256 hash of
* raw subject name. Used for OCSP.
* @param subject_hash SHA-256 hash of the subject's raw name
* @return a matching certificate or nullptr otherwise
*/
virtual std::shared_ptr<const X509_Certificate>
find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const = 0;
/**
* Finds a CRL for the given certificate
* @param subject the subject certificate
* @return the CRL for subject or nullptr otherwise
*/
virtual std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const;
/**
* @return whether the certificate is known
* @param cert certififcate to be searched
*/
bool certificate_known(const X509_Certificate& cert) const
{
return find_cert(cert.subject_dn(), cert.subject_key_id()) != nullptr;
}
// remove this (used by TLS::Server)
virtual std::vector<X509_DN> all_subjects() const = 0;
};
/**
* In Memory Certificate Store
*/
class BOTAN_PUBLIC_API(2,0) Certificate_Store_In_Memory final : public Certificate_Store
{
public:
/**
* Attempt to parse all files in dir (including subdirectories)
* as certificates. Ignores errors.
*/
explicit Certificate_Store_In_Memory(const std::string& dir);
/**
* Adds given certificate to the store.
*/
explicit Certificate_Store_In_Memory(const X509_Certificate& cert);
/**
* Create an empty store.
*/
Certificate_Store_In_Memory() = default;
/**
* Add a certificate to the store.
* @param cert certificate to be added
*/
void add_certificate(const X509_Certificate& cert);
/**
* Add a certificate already in a shared_ptr to the store.
* @param cert certificate to be added
*/
void add_certificate(std::shared_ptr<const X509_Certificate> cert);
/**
* Add a certificate revocation list (CRL) to the store.
* @param crl CRL to be added
*/
void add_crl(const X509_CRL& crl);
/**
* Add a certificate revocation list (CRL) to the store as a shared_ptr
* @param crl CRL to be added
*/
void add_crl(std::shared_ptr<const X509_CRL> crl);
/**
* @return DNs for all certificates managed by the store
*/
std::vector<X509_DN> all_subjects() const override;
/*
* Find a certificate by Subject DN and (optionally) key identifier
* @return the first certificate that matches
*/
std::shared_ptr<const X509_Certificate> find_cert(
const X509_DN& subject_dn,
const std::vector<uint8_t>& key_id) const override;
/*
* Find all certificates with a given Subject DN.
* Subject DN and even the key identifier might not be unique.
*/
std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs(
const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override;
std::shared_ptr<const X509_Certificate>
find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override;
std::shared_ptr<const X509_Certificate>
find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override;
/**
* Finds a CRL for the given certificate
*/
std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const override;
private:
// TODO: Add indexing on the DN and key id to avoid linear search
std::vector<std::shared_ptr<const X509_Certificate>> m_certs;
std::vector<std::shared_ptr<const X509_CRL>> m_crls;
};
}
#endif

View file

@ -0,0 +1,77 @@
/*
* Certificate Store
* (C) 1999-2019 Jack Lloyd
* (C) 2019 Patrick Schmidt
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CERT_STORE_FLATFILE_H_
#define BOTAN_CERT_STORE_FLATFILE_H_
#include <botan/certstor.h>
#include <vector>
#include <memory>
#include <map>
namespace Botan {
/**
* Certificate Store that is backed by a file of PEMs of trusted CAs.
*/
class BOTAN_PUBLIC_API(2, 11) Flatfile_Certificate_Store final : public Certificate_Store
{
public:
/**
* Construct a new Certificate_Store given a file path to a file including
* PEMs of trusted self-signed CAs.
*
* @param file the name of the file to read certificates from
* @param ignore_non_ca if true, certs that are not self-signed CA certs will
* be ignored. Otherwise (if false), an exception will be thrown instead.
*/
Flatfile_Certificate_Store(const std::string& file, bool ignore_non_ca = false);
Flatfile_Certificate_Store(const Flatfile_Certificate_Store&) = default;
Flatfile_Certificate_Store(Flatfile_Certificate_Store&&) = default;
Flatfile_Certificate_Store& operator=(const Flatfile_Certificate_Store&) = default;
Flatfile_Certificate_Store& operator=(Flatfile_Certificate_Store&&) = default;
/**
* @return DNs for all certificates managed by the store
*/
std::vector<X509_DN> all_subjects() const override;
/**
* Find all certificates with a given Subject DN.
* Subject DN and even the key identifier might not be unique.
*/
std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs(
const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override;
/**
* Find a certificate by searching for one with a matching SHA-1 hash of
* public key.
* @return a matching certificate or nullptr otherwise
*/
std::shared_ptr<const X509_Certificate>
find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override;
std::shared_ptr<const X509_Certificate>
find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override;
/**
* Fetching CRLs is not supported by this certificate store. This will
* always return an empty list.
*/
std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const override;
private:
std::vector<X509_DN> m_all_subjects;
std::map<X509_DN, std::vector<std::shared_ptr<const X509_Certificate>>> m_dn_to_cert;
std::map<std::vector<uint8_t>, std::shared_ptr<const X509_Certificate>> m_pubkey_sha1_to_cert;
std::map<std::vector<uint8_t>, std::shared_ptr<const X509_Certificate>> m_subject_dn_sha256_to_cert;
};
}
#endif

View file

@ -0,0 +1,81 @@
/*
* Certificate Store
* (C) 1999-2019 Jack Lloyd
* (C) 2019 René Meusel
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CERT_STORE_SYSTEM_MACOS_H_
#define BOTAN_CERT_STORE_SYSTEM_MACOS_H_
#include <memory>
#include <botan/certstor.h>
namespace Botan {
class Certificate_Store_MacOS_Impl;
/**
* Certificate Store that is backed by the system trust store on macOS. This
* opens a handle to the macOS keychain and serves certificate queries directly
* from there.
*/
class BOTAN_PUBLIC_API(2, 10) Certificate_Store_MacOS final : public Certificate_Store
{
public:
Certificate_Store_MacOS();
Certificate_Store_MacOS(const Certificate_Store_MacOS&) = default;
Certificate_Store_MacOS(Certificate_Store_MacOS&&) = default;
Certificate_Store_MacOS& operator=(const Certificate_Store_MacOS&) = default;
Certificate_Store_MacOS& operator=(Certificate_Store_MacOS&&) = default;
/**
* @return DNs for all certificates managed by the store
*/
std::vector<X509_DN> all_subjects() const override;
/**
* Find a certificate by Subject DN and (optionally) key identifier
* @return the first certificate that matches
*/
std::shared_ptr<const X509_Certificate> find_cert(
const X509_DN& subject_dn,
const std::vector<uint8_t>& key_id) const override;
/**
* Find all certificates with a given Subject DN.
* Subject DN and even the key identifier might not be unique.
*/
std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs(
const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override;
/**
* Find a certificate by searching for one with a matching SHA-1 hash of
* public key.
* @return a matching certificate or nullptr otherwise
*/
std::shared_ptr<const X509_Certificate>
find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override;
/**
* @throws Botan::Not_Implemented
*/
std::shared_ptr<const X509_Certificate>
find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override;
/**
* Fetching CRLs is not supported by the keychain on macOS. This will
* always return an empty list.
*/
std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const override;
private:
std::shared_ptr<Certificate_Store_MacOS_Impl> m_impl;
};
}
#endif

View file

@ -0,0 +1,119 @@
/*
* Certificate Store in SQL
* (C) 2016 Kai Michaelis, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CERT_STORE_SQL_H_
#define BOTAN_CERT_STORE_SQL_H_
#include <botan/certstor.h>
#include <botan/x509cert.h>
#include <botan/x509_crl.h>
#include <botan/database.h>
#include <botan/mutex.h>
namespace Botan {
class Private_Key;
class RandomNumberGenerator;
/**
* Certificate and private key store backed by an SQL database.
*/
class BOTAN_PUBLIC_API(2,0) Certificate_Store_In_SQL : public Certificate_Store
{
public:
/**
* Create/open a certificate store.
* @param db underlying database storage
* @param passwd password to encrypt private keys in the database
* @param rng used for encrypting keys
* @param table_prefix optional prefix for db table names
*/
explicit Certificate_Store_In_SQL(const std::shared_ptr<SQL_Database> db,
const std::string& passwd,
RandomNumberGenerator& rng,
const std::string& table_prefix = "");
/**
* Returns the first certificate with matching subject DN and optional key ID.
*/
std::shared_ptr<const X509_Certificate>
find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override;
/*
* Find all certificates with a given Subject DN.
* Subject DN and even the key identifier might not be unique.
*/
std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs(
const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override;
std::shared_ptr<const X509_Certificate>
find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override;
std::shared_ptr<const X509_Certificate>
find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override;
/**
* Returns all subject DNs known to the store instance.
*/
std::vector<X509_DN> all_subjects() const override;
/**
* Inserts "cert" into the store, returns false if the certificate is
* already known and true if insertion was successful.
*/
bool insert_cert(const X509_Certificate& cert);
/**
* Removes "cert" from the store. Returns false if the certificate could not
* be found and true if removal was successful.
*/
bool remove_cert(const X509_Certificate& cert);
/// Returns the private key for "cert" or an empty shared_ptr if none was found.
std::shared_ptr<const Private_Key> find_key(const X509_Certificate&) const;
/// Returns all certificates for private key "key".
std::vector<std::shared_ptr<const X509_Certificate>>
find_certs_for_key(const Private_Key& key) const;
/**
* Inserts "key" for "cert" into the store, returns false if the key is
* already known and true if insertion was successful.
*/
bool insert_key(const X509_Certificate& cert, const Private_Key& key);
/// Removes "key" from the store.
void remove_key(const Private_Key& key);
/// Marks "cert" as revoked starting from "time".
void revoke_cert(const X509_Certificate&, CRL_Code, const X509_Time& time = X509_Time());
/// Reverses the revokation for "cert".
void affirm_cert(const X509_Certificate&);
/**
* Generates Certificate Revocation Lists for all certificates marked as revoked.
* A CRL is returned for each unique issuer DN.
*/
std::vector<X509_CRL> generate_crls() const;
/**
* Generates a CRL for all certificates issued by the given issuer.
*/
std::shared_ptr<const X509_CRL>
find_crl_for(const X509_Certificate& issuer) const override;
private:
RandomNumberGenerator& m_rng;
std::shared_ptr<SQL_Database> m_database;
std::string m_prefix;
std::string m_password;
mutex_type m_mutex;
};
}
#endif

View file

@ -0,0 +1,42 @@
/*
* (C) 2019 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_SYSTEM_CERT_STORE_H_
#define BOTAN_SYSTEM_CERT_STORE_H_
#include <botan/certstor.h>
namespace Botan {
class BOTAN_PUBLIC_API(2,11) System_Certificate_Store final : public Certificate_Store
{
public:
System_Certificate_Store();
std::shared_ptr<const X509_Certificate>
find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override;
std::vector<std::shared_ptr<const X509_Certificate>>
find_all_certs(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override;
std::shared_ptr<const X509_Certificate>
find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override;
std::shared_ptr<const X509_Certificate>
find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override;
std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const override;
std::vector<X509_DN> all_subjects() const override;
private:
std::shared_ptr<Certificate_Store> m_system_store;
};
}
#endif

View file

@ -0,0 +1,106 @@
/*
* CFB mode
* (C) 1999-2007,2013 Jack Lloyd
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_MODE_CFB_H_
#define BOTAN_MODE_CFB_H_
#include <botan/cipher_mode.h>
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(cfb.h)
namespace Botan {
/**
* CFB Mode
*/
class BOTAN_PUBLIC_API(2,0) CFB_Mode : public Cipher_Mode
{
public:
std::string name() const override final;
size_t update_granularity() const override final;
size_t minimum_final_size() const override final;
Key_Length_Specification key_spec() const override final;
size_t output_length(size_t input_length) const override final;
size_t default_nonce_length() const override final;
bool valid_nonce_length(size_t n) const override final;
void clear() override final;
void reset() override final;
protected:
CFB_Mode(BlockCipher* cipher, size_t feedback_bits);
void shift_register();
size_t feedback() const { return m_feedback_bytes; }
const BlockCipher& cipher() const { return *m_cipher; }
size_t block_size() const { return m_block_size; }
secure_vector<uint8_t> m_state;
secure_vector<uint8_t> m_keystream;
size_t m_keystream_pos = 0;
private:
void start_msg(const uint8_t nonce[], size_t nonce_len) override;
void key_schedule(const uint8_t key[], size_t length) override;
std::unique_ptr<BlockCipher> m_cipher;
const size_t m_block_size;
const size_t m_feedback_bytes;
};
/**
* CFB Encryption
*/
class BOTAN_PUBLIC_API(2,0) CFB_Encryption final : public CFB_Mode
{
public:
/**
* If feedback_bits is zero, cipher->block_size() bytes will be used.
* @param cipher block cipher to use
* @param feedback_bits number of bits fed back into the shift register,
* must be a multiple of 8
*/
CFB_Encryption(BlockCipher* cipher, size_t feedback_bits) :
CFB_Mode(cipher, feedback_bits) {}
size_t process(uint8_t buf[], size_t size) override;
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
};
/**
* CFB Decryption
*/
class BOTAN_PUBLIC_API(2,0) CFB_Decryption final : public CFB_Mode
{
public:
/**
* If feedback_bits is zero, cipher->block_size() bytes will be used.
* @param cipher block cipher to use
* @param feedback_bits number of bits fed back into the shift register,
* must be a multiple of 8
*/
CFB_Decryption(BlockCipher* cipher, size_t feedback_bits) :
CFB_Mode(cipher, feedback_bits) {}
size_t process(uint8_t buf[], size_t size) override;
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
};
}
#endif

View file

@ -0,0 +1,82 @@
/*
* ChaCha20
* (C) 2014,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CHACHA_H_
#define BOTAN_CHACHA_H_
#include <botan/stream_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(chacha.h)
namespace Botan {
/**
* DJB's ChaCha (https://cr.yp.to/chacha.html)
*/
class BOTAN_PUBLIC_API(2,0) ChaCha final : public StreamCipher
{
public:
/**
* @param rounds number of rounds
* @note Currently only 8, 12 or 20 rounds are supported, all others
* will throw an exception
*/
explicit ChaCha(size_t rounds = 20);
std::string provider() const override;
void cipher(const uint8_t in[], uint8_t out[], size_t length) override;
void write_keystream(uint8_t out[], size_t len) override;
void set_iv(const uint8_t iv[], size_t iv_len) override;
/*
* ChaCha accepts 0, 8, 12 or 24 byte IVs.
* The default IV is a 8 zero bytes.
* An IV of length 0 is treated the same as the default zero IV.
* An IV of length 24 selects XChaCha mode
*/
bool valid_iv_length(size_t iv_len) const override;
size_t default_iv_length() const override;
Key_Length_Specification key_spec() const override;
void clear() override;
StreamCipher* clone() const override;
std::string name() const override;
void seek(uint64_t offset) override;
private:
void key_schedule(const uint8_t key[], size_t key_len) override;
void initialize_state();
void chacha_x8(uint8_t output[64*8], uint32_t state[16], size_t rounds);
#if defined(BOTAN_HAS_CHACHA_SIMD32)
void chacha_simd32_x4(uint8_t output[64*4], uint32_t state[16], size_t rounds);
#endif
#if defined(BOTAN_HAS_CHACHA_AVX2)
void chacha_avx2_x8(uint8_t output[64*8], uint32_t state[16], size_t rounds);
#endif
size_t m_rounds;
secure_vector<uint32_t> m_key;
secure_vector<uint32_t> m_state;
secure_vector<uint8_t> m_buffer;
size_t m_position = 0;
};
}
#endif

View file

@ -0,0 +1,104 @@
/*
* ChaCha20Poly1305 AEAD
* (C) 2014 Jack Lloyd
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_AEAD_CHACHA20_POLY1305_H_
#define BOTAN_AEAD_CHACHA20_POLY1305_H_
#include <botan/aead.h>
#include <botan/stream_cipher.h>
#include <botan/mac.h>
BOTAN_FUTURE_INTERNAL_HEADER(chacha20poly1305.h)
namespace Botan {
/**
* Base class
* See draft-irtf-cfrg-chacha20-poly1305-03 for specification
* If a nonce of 64 bits is used the older version described in
* draft-agl-tls-chacha20poly1305-04 is used instead.
* If a nonce of 192 bits is used, XChaCha20Poly1305 is selected.
*/
class BOTAN_PUBLIC_API(2,0) ChaCha20Poly1305_Mode : public AEAD_Mode
{
public:
void set_associated_data(const uint8_t ad[], size_t ad_len) override;
bool associated_data_requires_key() const override { return false; }
std::string name() const override { return "ChaCha20Poly1305"; }
size_t update_granularity() const override { return 64; }
Key_Length_Specification key_spec() const override
{ return Key_Length_Specification(32); }
bool valid_nonce_length(size_t n) const override;
size_t tag_size() const override { return 16; }
void clear() override;
void reset() override;
protected:
std::unique_ptr<StreamCipher> m_chacha;
std::unique_ptr<MessageAuthenticationCode> m_poly1305;
ChaCha20Poly1305_Mode();
secure_vector<uint8_t> m_ad;
size_t m_nonce_len = 0;
size_t m_ctext_len = 0;
bool cfrg_version() const { return m_nonce_len == 12 || m_nonce_len == 24; }
void update_len(size_t len);
private:
void start_msg(const uint8_t nonce[], size_t nonce_len) override;
void key_schedule(const uint8_t key[], size_t length) override;
};
/**
* ChaCha20Poly1305 Encryption
*/
class BOTAN_PUBLIC_API(2,0) ChaCha20Poly1305_Encryption final : public ChaCha20Poly1305_Mode
{
public:
size_t output_length(size_t input_length) const override
{ return input_length + tag_size(); }
size_t minimum_final_size() const override { return 0; }
size_t process(uint8_t buf[], size_t size) override;
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
};
/**
* ChaCha20Poly1305 Decryption
*/
class BOTAN_PUBLIC_API(2,0) ChaCha20Poly1305_Decryption final : public ChaCha20Poly1305_Mode
{
public:
size_t output_length(size_t input_length) const override
{
BOTAN_ASSERT(input_length >= tag_size(), "Sufficient input");
return input_length - tag_size();
}
size_t minimum_final_size() const override { return tag_size(); }
size_t process(uint8_t buf[], size_t size) override;
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
};
}
#endif

View file

@ -0,0 +1,125 @@
/*
* ChaCha_RNG
* (C) 2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CHACHA_RNG_H_
#define BOTAN_CHACHA_RNG_H_
#include <botan/stateful_rng.h>
#include <botan/stream_cipher.h>
#include <botan/mac.h>
namespace Botan {
class Entropy_Sources;
/**
* ChaCha_RNG is a very fast but completely ad-hoc RNG created by
* creating a 256-bit random value and using it as a key for ChaCha20.
*
* The RNG maintains two 256-bit keys, one for HMAC_SHA256 (HK) and the
* other for ChaCha20 (CK). To compute a new key in response to
* reseeding request or add_entropy calls, ChaCha_RNG computes
* CK' = HMAC_SHA256(HK, input_material)
* Then a new HK' is computed by running ChaCha20 with the new key to
* output 32 bytes:
* HK' = ChaCha20(CK')
*
* Now output can be produced by continuing to produce output with ChaCha20
* under CK'
*
* The first HK (before seeding occurs) is taken as the all zero value.
*
* @warning This RNG construction is probably fine but is non-standard.
* The primary reason to use it is in cases where the other RNGs are
* not fast enough.
*/
class BOTAN_PUBLIC_API(2,3) ChaCha_RNG final : public Stateful_RNG
{
public:
/**
* Automatic reseeding is disabled completely, as it has no access to
* any source for seed material.
*
* If a fork is detected, the RNG will be unable to reseed itself
* in response. In this case, an exception will be thrown rather
* than generating duplicated output.
*/
ChaCha_RNG();
/**
* Provide an initial seed to the RNG, without providing an
* underlying RNG or entropy source. Automatic reseeding is
* disabled completely, as it has no access to any source for
* seed material.
*
* If a fork is detected, the RNG will be unable to reseed itself
* in response. In this case, an exception will be thrown rather
* than generating duplicated output.
*
* @param seed the seed material, should be at least 256 bits
*/
ChaCha_RNG(const secure_vector<uint8_t>& seed);
/**
* Automatic reseeding from @p underlying_rng will take place after
* @p reseed_interval many requests or after a fork was detected.
*
* @param underlying_rng is a reference to some RNG which will be used
* to perform the periodic reseeding
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed
*/
ChaCha_RNG(RandomNumberGenerator& underlying_rng,
size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
/**
* Automatic reseeding from @p entropy_sources will take place after
* @p reseed_interval many requests or after a fork was detected.
*
* @param entropy_sources will be polled to perform reseeding periodically
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed.
*/
ChaCha_RNG(Entropy_Sources& entropy_sources,
size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
/**
* Automatic reseeding from @p underlying_rng and @p entropy_sources
* will take place after @p reseed_interval many requests or after
* a fork was detected.
*
* @param underlying_rng is a reference to some RNG which will be used
* to perform the periodic reseeding
* @param entropy_sources will be polled to perform reseeding periodically
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed.
*/
ChaCha_RNG(RandomNumberGenerator& underlying_rng,
Entropy_Sources& entropy_sources,
size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
std::string name() const override { return "ChaCha_RNG"; }
size_t security_level() const override;
size_t max_number_of_bytes_per_request() const override { return 0; }
private:
void update(const uint8_t input[], size_t input_len) override;
void generate_output(uint8_t output[], size_t output_len,
const uint8_t input[], size_t input_len) override;
void clear_state() override;
std::unique_ptr<MessageAuthenticationCode> m_hmac;
std::unique_ptr<StreamCipher> m_chacha;
};
}
#endif

View file

@ -0,0 +1,80 @@
/*
* Character Set Handling
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CHARSET_H_
#define BOTAN_CHARSET_H_
#include <botan/types.h>
#include <string>
BOTAN_FUTURE_INTERNAL_HEADER(charset.h)
namespace Botan {
/**
* Convert a sequence of UCS-2 (big endian) characters to a UTF-8 string
* This is used for ASN.1 BMPString type
* @param ucs2 the sequence of UCS-2 characters
* @param len length of ucs2 in bytes, must be a multiple of 2
*/
std::string BOTAN_UNSTABLE_API ucs2_to_utf8(const uint8_t ucs2[], size_t len);
/**
* Convert a sequence of UCS-4 (big endian) characters to a UTF-8 string
* This is used for ASN.1 UniversalString type
* @param ucs4 the sequence of UCS-4 characters
* @param len length of ucs4 in bytes, must be a multiple of 4
*/
std::string BOTAN_UNSTABLE_API ucs4_to_utf8(const uint8_t ucs4[], size_t len);
/**
* Convert a UTF-8 string to Latin-1
* If a character outside the Latin-1 range is encountered, an exception is thrown.
*/
std::string BOTAN_UNSTABLE_API utf8_to_latin1(const std::string& utf8);
/**
* The different charsets (nominally) supported by Botan.
*/
enum Character_Set {
LOCAL_CHARSET,
UCS2_CHARSET,
UTF8_CHARSET,
LATIN1_CHARSET
};
namespace Charset {
/*
* Character set conversion - avoid this.
* For specific conversions, use the functions above like
* ucs2_to_utf8 and utf8_to_latin1
*
* If you need something more complex than that, use a real library
* such as iconv, Boost.Locale, or ICU
*/
std::string BOTAN_PUBLIC_API(2,0)
BOTAN_DEPRECATED("Avoid. See comment in header.")
transcode(const std::string& str,
Character_Set to,
Character_Set from);
/*
* Simple character classifier functions
*/
bool BOTAN_PUBLIC_API(2,0) is_digit(char c);
bool BOTAN_PUBLIC_API(2,0) is_space(char c);
bool BOTAN_PUBLIC_API(2,0) caseless_cmp(char x, char y);
uint8_t BOTAN_PUBLIC_API(2,0) char2digit(char c);
char BOTAN_PUBLIC_API(2,0) digit2char(uint8_t b);
}
}
#endif

View file

@ -0,0 +1,14 @@
/*
* Filter interface for ciphers
* (C) 2013,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CIPHER_FILTER_H_
#define BOTAN_CIPHER_FILTER_H_
#include <botan/filters.h>
BOTAN_DEPRECATED_HEADER(cipher_filter.h)
#endif

View file

@ -0,0 +1,198 @@
/*
* Cipher Modes
* (C) 2013,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CIPHER_MODE_H_
#define BOTAN_CIPHER_MODE_H_
#include <botan/secmem.h>
#include <botan/sym_algo.h>
#include <botan/exceptn.h>
#include <string>
#include <vector>
namespace Botan {
/**
* The two possible directions for cipher filters, determining whether they
* actually perform encryption or decryption.
*/
enum Cipher_Dir : int { ENCRYPTION, DECRYPTION };
/**
* Interface for cipher modes
*/
class BOTAN_PUBLIC_API(2,0) Cipher_Mode : public SymmetricAlgorithm
{
public:
/**
* @return list of available providers for this algorithm, empty if not available
* @param algo_spec algorithm name
*/
static std::vector<std::string> providers(const std::string& algo_spec);
/**
* Create an AEAD mode
* @param algo the algorithm to create
* @param direction specify if this should be an encryption or decryption AEAD
* @param provider optional specification for provider to use
* @return an AEAD mode or a null pointer if not available
*/
static std::unique_ptr<Cipher_Mode> create(const std::string& algo,
Cipher_Dir direction,
const std::string& provider = "");
/**
* Create an AEAD mode, or throw
* @param algo the algorithm to create
* @param direction specify if this should be an encryption or decryption AEAD
* @param provider optional specification for provider to use
* @return an AEAD mode, or throw an exception
*/
static std::unique_ptr<Cipher_Mode> create_or_throw(const std::string& algo,
Cipher_Dir direction,
const std::string& provider = "");
/*
* Prepare for processing a message under the specified nonce
*/
virtual void start_msg(const uint8_t nonce[], size_t nonce_len) = 0;
/**
* Begin processing a message.
* @param nonce the per message nonce
*/
template<typename Alloc>
void start(const std::vector<uint8_t, Alloc>& nonce)
{
start_msg(nonce.data(), nonce.size());
}
/**
* Begin processing a message.
* @param nonce the per message nonce
* @param nonce_len length of nonce
*/
void start(const uint8_t nonce[], size_t nonce_len)
{
start_msg(nonce, nonce_len);
}
/**
* Begin processing a message.
*/
void start()
{
return start_msg(nullptr, 0);
}
/**
* Process message blocks
*
* Input must be a multiple of update_granularity
*
* Processes msg in place and returns bytes written. Normally
* this will be either msg_len (indicating the entire message was
* processed) or for certain AEAD modes zero (indicating that the
* mode requires the entire message be processed in one pass).
*
* @param msg the message to be processed
* @param msg_len length of the message in bytes
*/
virtual size_t process(uint8_t msg[], size_t msg_len) = 0;
/**
* Process some data. Input must be in size update_granularity() uint8_t blocks.
* @param buffer in/out parameter which will possibly be resized
* @param offset an offset into blocks to begin processing
*/
void update(secure_vector<uint8_t>& buffer, size_t offset = 0)
{
BOTAN_ASSERT(buffer.size() >= offset, "Offset ok");
uint8_t* buf = buffer.data() + offset;
const size_t buf_size = buffer.size() - offset;
const size_t written = process(buf, buf_size);
buffer.resize(offset + written);
}
/**
* Complete processing of a message.
*
* @param final_block in/out parameter which must be at least
* minimum_final_size() bytes, and will be set to any final output
* @param offset an offset into final_block to begin processing
*/
virtual void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) = 0;
/**
* Returns the size of the output if this transform is used to process a
* message with input_length bytes. In most cases the answer is precise.
* If it is not possible to precise (namely for CBC decryption) instead a
* lower bound is returned.
*/
virtual size_t output_length(size_t input_length) const = 0;
/**
* @return size of required blocks to update
*/
virtual size_t update_granularity() const = 0;
/**
* @return required minimium size to finalize() - may be any
* length larger than this.
*/
virtual size_t minimum_final_size() const = 0;
/**
* @return the default size for a nonce
*/
virtual size_t default_nonce_length() const = 0;
/**
* @return true iff nonce_len is a valid length for the nonce
*/
virtual bool valid_nonce_length(size_t nonce_len) const = 0;
/**
* Resets just the message specific state and allows encrypting again under the existing key
*/
virtual void reset() = 0;
/**
* @return true iff this mode provides authentication as well as
* confidentiality.
*/
virtual bool authenticated() const { return false; }
/**
* @return the size of the authentication tag used (in bytes)
*/
virtual size_t tag_size() const { return 0; }
/**
* @return provider information about this implementation. Default is "base",
* might also return "sse2", "avx2", "openssl", or some other arbitrary string.
*/
virtual std::string provider() const { return "base"; }
};
/**
* Get a cipher mode by name (eg "AES-128/CBC" or "Serpent/XTS")
* @param algo_spec cipher name
* @param direction ENCRYPTION or DECRYPTION
* @param provider provider implementation to choose
*/
inline Cipher_Mode* get_cipher_mode(const std::string& algo_spec,
Cipher_Dir direction,
const std::string& provider = "")
{
return Cipher_Mode::create(algo_spec, direction, provider).release();
}
}
#endif

View file

@ -0,0 +1,67 @@
/*
* CMAC
* (C) 1999-2007,2014 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CMAC_H_
#define BOTAN_CMAC_H_
#include <botan/mac.h>
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(cmac.h)
namespace Botan {
/**
* CMAC, also known as OMAC1
*/
class BOTAN_PUBLIC_API(2,0) CMAC final : public MessageAuthenticationCode
{
public:
std::string name() const override;
size_t output_length() const override { return m_block_size; }
MessageAuthenticationCode* clone() const override;
void clear() override;
Key_Length_Specification key_spec() const override
{
return m_cipher->key_spec();
}
/**
* CMAC's polynomial doubling operation
*
* This function was only exposed for use elsewhere in the library, but it is not
* longer used. This function will be removed in a future release.
*
* @param in the input
*/
static secure_vector<uint8_t>
BOTAN_DEPRECATED("This was only for internal use and is no longer used")
poly_double(const secure_vector<uint8_t>& in);
/**
* @param cipher the block cipher to use
*/
explicit CMAC(BlockCipher* cipher);
CMAC(const CMAC&) = delete;
CMAC& operator=(const CMAC&) = delete;
private:
void add_data(const uint8_t[], size_t) override;
void final_result(uint8_t[]) override;
void key_schedule(const uint8_t[], size_t) override;
std::unique_ptr<BlockCipher> m_cipher;
secure_vector<uint8_t> m_buffer, m_state, m_B, m_P;
const size_t m_block_size;
size_t m_position;
};
}
#endif

View file

@ -0,0 +1,61 @@
/*
* Comb4P hash combiner
* (C) 2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_COMB4P_H_
#define BOTAN_COMB4P_H_
#include <botan/hash.h>
BOTAN_FUTURE_INTERNAL_HEADER(comb4p.h)
namespace Botan {
/**
* Combines two hash functions using a Feistel scheme. Described in
* "On the Security of Hash Function Combiners", Anja Lehmann
*/
class BOTAN_PUBLIC_API(2,0) Comb4P final : public HashFunction
{
public:
/**
* @param h1 the first hash
* @param h2 the second hash
*/
Comb4P(HashFunction* h1, HashFunction* h2);
size_t hash_block_size() const override;
size_t output_length() const override
{
return m_hash1->output_length() + m_hash2->output_length();
}
HashFunction* clone() const override
{
return new Comb4P(m_hash1->clone(), m_hash2->clone());
}
std::unique_ptr<HashFunction> copy_state() const override;
std::string name() const override
{
return "Comb4P(" + m_hash1->name() + "," + m_hash2->name() + ")";
}
void clear() override;
private:
Comb4P() = default;
void add_data(const uint8_t input[], size_t length) override;
void final_result(uint8_t out[]) override;
std::unique_ptr<HashFunction> m_hash1, m_hash2;
};
}
#endif

View file

@ -0,0 +1,15 @@
/*
* Filter interface for compression
* (C) 2014,2015,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_COMPRESSION_FILTER_H_
#define BOTAN_COMPRESSION_FILTER_H_
BOTAN_DEPRECATED_HEADER(comp_filter.h)
#include <botan/filters.h>
#endif

View file

@ -0,0 +1,225 @@
/*
* Define useful compiler-specific macros
* (C) 2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
/* This header is included in both C++ and C (via ffi.h) and should only
contain macro definitions. Avoid C++ style // comments in this file.
*/
#ifndef BOTAN_UTIL_COMPILER_FLAGS_H_
#define BOTAN_UTIL_COMPILER_FLAGS_H_
/* Should we use GCC-style inline assembler? */
#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || \
defined(BOTAN_BUILD_COMPILER_IS_CLANG) || \
defined(BOTAN_BUILD_COMPILER_IS_XLC) || \
defined(BOTAN_BUILD_COMPILER_IS_SUN_STUDIO)
#define BOTAN_USE_GCC_INLINE_ASM
#endif
/**
* Used to annotate API exports which are public and supported.
* These APIs will not be broken/removed unless strictly required for
* functionality or security, and only in new major versions.
* @param maj The major version this public API was released in
* @param min The minor version this public API was released in
*/
#define BOTAN_PUBLIC_API(maj,min) BOTAN_DLL
/**
* Used to annotate API exports which are public, but are now deprecated
* and which will be removed in a future major release.
*/
#define BOTAN_DEPRECATED_API(msg) BOTAN_DLL BOTAN_DEPRECATED(msg)
/**
* Used to annotate API exports which are public and can be used by
* applications if needed, but which are intentionally not documented,
* and which may change incompatibly in a future major version.
*/
#define BOTAN_UNSTABLE_API BOTAN_DLL
/**
* Used to annotate API exports which are exported but only for the
* purposes of testing. They should not be used by applications and
* may be removed or changed without notice.
*/
#define BOTAN_TEST_API BOTAN_DLL
/*
* Define BOTAN_GCC_VERSION
*/
#if defined(__GNUC__) && !defined(__clang__)
#define BOTAN_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__)
#else
#define BOTAN_GCC_VERSION 0
#endif
/*
* Define BOTAN_CLANG_VERSION
*/
#if defined(__clang__)
#define BOTAN_CLANG_VERSION (__clang_major__ * 10 + __clang_minor__)
#else
#define BOTAN_CLANG_VERSION 0
#endif
/*
* Define BOTAN_FUNC_ISA
*/
#if (defined(__GNUC__) && !defined(__clang__)) || (BOTAN_CLANG_VERSION > 38)
#define BOTAN_FUNC_ISA(isa) __attribute__ ((target(isa)))
#else
#define BOTAN_FUNC_ISA(isa)
#endif
/*
* Define BOTAN_WARN_UNUSED_RESULT
*/
#if defined(__GNUC__) || defined(__clang__)
#define BOTAN_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
#else
#define BOTAN_WARN_UNUSED_RESULT
#endif
/*
* Define BOTAN_MALLOC_FN
*/
#if defined(__ibmxl__)
/* XLC pretends to be both Clang and GCC, but is neither */
#define BOTAN_MALLOC_FN __attribute__ ((malloc))
#elif defined(__GNUC__)
#define BOTAN_MALLOC_FN __attribute__ ((malloc, alloc_size(1,2)))
#elif defined(_MSC_VER)
#define BOTAN_MALLOC_FN __declspec(restrict)
#else
#define BOTAN_MALLOC_FN
#endif
/*
* Define BOTAN_DEPRECATED
*/
#if !defined(BOTAN_NO_DEPRECATED_WARNINGS) && !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_AMALGAMATION_H_)
#if defined(__clang__)
#define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg)))
#define BOTAN_DEPRECATED_HEADER(hdr) _Pragma("message \"this header is deprecated\"")
#define BOTAN_FUTURE_INTERNAL_HEADER(hdr) _Pragma("message \"this header will be made internal in the future\"")
#elif defined(_MSC_VER)
#define BOTAN_DEPRECATED(msg) __declspec(deprecated(msg))
#define BOTAN_DEPRECATED_HEADER(hdr) __pragma(message("this header is deprecated"))
#define BOTAN_FUTURE_INTERNAL_HEADER(hdr) __pragma(message("this header will be made internal in the future"))
#elif defined(__GNUC__)
/* msg supported since GCC 4.5, earliest we support is 4.8 */
#define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg)))
#define BOTAN_DEPRECATED_HEADER(hdr) _Pragma("GCC warning \"this header is deprecated\"")
#define BOTAN_FUTURE_INTERNAL_HEADER(hdr) _Pragma("GCC warning \"this header will be made internal in the future\"")
#endif
#endif
#if !defined(BOTAN_DEPRECATED)
#define BOTAN_DEPRECATED(msg)
#endif
#if !defined(BOTAN_DEPRECATED_HEADER)
#define BOTAN_DEPRECATED_HEADER(hdr)
#endif
#if !defined(BOTAN_FUTURE_INTERNAL_HEADER)
#define BOTAN_FUTURE_INTERNAL_HEADER(hdr)
#endif
/*
* Define BOTAN_NORETURN
*/
#if !defined(BOTAN_NORETURN)
#if defined (__clang__) || defined (__GNUC__)
#define BOTAN_NORETURN __attribute__ ((__noreturn__))
#elif defined (_MSC_VER)
#define BOTAN_NORETURN __declspec(noreturn)
#else
#define BOTAN_NORETURN
#endif
#endif
/*
* Define BOTAN_THREAD_LOCAL
*/
#if !defined(BOTAN_THREAD_LOCAL)
#if defined(BOTAN_TARGET_OS_HAS_THREADS) && defined(BOTAN_TARGET_OS_HAS_THREAD_LOCAL)
#define BOTAN_THREAD_LOCAL thread_local
#else
#define BOTAN_THREAD_LOCAL /**/
#endif
#endif
/*
* Define BOTAN_IF_CONSTEXPR
*/
#if !defined(BOTAN_IF_CONSTEXPR)
#if __cplusplus >= 201703
#define BOTAN_IF_CONSTEXPR if constexpr
#else
#define BOTAN_IF_CONSTEXPR if
#endif
#endif
/*
* Define BOTAN_PARALLEL_FOR
*/
#if !defined(BOTAN_PARALLEL_FOR)
#if defined(BOTAN_TARGET_HAS_OPENMP)
#define BOTAN_PARALLEL_FOR _Pragma("omp parallel for") for
#else
#define BOTAN_PARALLEL_FOR for
#endif
#endif
/*
* Define BOTAN_FORCE_INLINE
*/
#if !defined(BOTAN_FORCE_INLINE)
#if defined (__clang__) || defined (__GNUC__)
#define BOTAN_FORCE_INLINE __attribute__ ((__always_inline__)) inline
#elif defined (_MSC_VER)
#define BOTAN_FORCE_INLINE __forceinline
#else
#define BOTAN_FORCE_INLINE inline
#endif
#endif
/*
* Define BOTAN_PARALLEL_SIMD_FOR
*/
#if !defined(BOTAN_PARALLEL_SIMD_FOR)
#if defined(BOTAN_TARGET_HAS_OPENMP)
#define BOTAN_PARALLEL_SIMD_FOR _Pragma("omp simd") for
#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && (BOTAN_GCC_VERSION >= 490)
#define BOTAN_PARALLEL_SIMD_FOR _Pragma("GCC ivdep") for
#else
#define BOTAN_PARALLEL_SIMD_FOR for
#endif
#endif
#endif

View file

@ -0,0 +1,484 @@
/*
* Runtime CPU detection
* (C) 2009,2010,2013,2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CPUID_H_
#define BOTAN_CPUID_H_
#include <botan/types.h>
#include <vector>
#include <string>
#include <iosfwd>
BOTAN_FUTURE_INTERNAL_HEADER(cpuid.h)
namespace Botan {
/**
* A class handling runtime CPU feature detection. It is limited to
* just the features necessary to implement CPU specific code in Botan,
* rather than being a general purpose utility.
*
* This class supports:
*
* - x86 features using CPUID. x86 is also the only processor with
* accurate cache line detection currently.
*
* - PowerPC AltiVec detection on Linux, NetBSD, OpenBSD, and macOS
*
* - ARM NEON and crypto extensions detection. On Linux and Android
* systems which support getauxval, that is used to access CPU
* feature information. Otherwise a relatively portable but
* thread-unsafe mechanism involving executing probe functions which
* catching SIGILL signal is used.
*/
class BOTAN_PUBLIC_API(2,1) CPUID final
{
public:
/**
* Probe the CPU and see what extensions are supported
*/
static void initialize();
static bool has_simd_32();
/**
* Deprecated equivalent to
* o << "CPUID flags: " << CPUID::to_string() << "\n";
*/
BOTAN_DEPRECATED("Use CPUID::to_string")
static void print(std::ostream& o);
/**
* Return a possibly empty string containing list of known CPU
* extensions. Each name will be seperated by a space, and the ordering
* will be arbitrary. This list only contains values that are useful to
* Botan (for example FMA instructions are not checked).
*
* Example outputs "sse2 ssse3 rdtsc", "neon arm_aes", "altivec"
*/
static std::string to_string();
/**
* Return a best guess of the cache line size
*/
static size_t cache_line_size()
{
return state().cache_line_size();
}
static bool is_little_endian()
{
#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
return true;
#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
return false;
#else
return state().endian_status() == Endian_Status::Little;
#endif
}
static bool is_big_endian()
{
#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
return true;
#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
return false;
#else
return state().endian_status() == Endian_Status::Big;
#endif
}
enum CPUID_bits : uint64_t {
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
// These values have no relation to cpuid bitfields
// SIMD instruction sets
CPUID_SSE2_BIT = (1ULL << 0),
CPUID_SSSE3_BIT = (1ULL << 1),
CPUID_SSE41_BIT = (1ULL << 2),
CPUID_SSE42_BIT = (1ULL << 3),
CPUID_AVX2_BIT = (1ULL << 4),
CPUID_AVX512F_BIT = (1ULL << 5),
CPUID_AVX512DQ_BIT = (1ULL << 6),
CPUID_AVX512BW_BIT = (1ULL << 7),
// Ice Lake profile: AVX-512 F, DQ, BW, IFMA, VBMI, VBMI2, BITALG
CPUID_AVX512_ICL_BIT = (1ULL << 11),
// Crypto-specific ISAs
CPUID_AESNI_BIT = (1ULL << 16),
CPUID_CLMUL_BIT = (1ULL << 17),
CPUID_RDRAND_BIT = (1ULL << 18),
CPUID_RDSEED_BIT = (1ULL << 19),
CPUID_SHA_BIT = (1ULL << 20),
CPUID_AVX512_AES_BIT = (1ULL << 21),
CPUID_AVX512_CLMUL_BIT = (1ULL << 22),
// Misc useful instructions
CPUID_RDTSC_BIT = (1ULL << 48),
CPUID_ADX_BIT = (1ULL << 49),
CPUID_BMI1_BIT = (1ULL << 50),
CPUID_BMI2_BIT = (1ULL << 51),
#endif
#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
CPUID_ALTIVEC_BIT = (1ULL << 0),
CPUID_POWER_CRYPTO_BIT = (1ULL << 1),
CPUID_DARN_BIT = (1ULL << 2),
#endif
#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
CPUID_ARM_NEON_BIT = (1ULL << 0),
CPUID_ARM_SVE_BIT = (1ULL << 1),
CPUID_ARM_AES_BIT = (1ULL << 16),
CPUID_ARM_PMULL_BIT = (1ULL << 17),
CPUID_ARM_SHA1_BIT = (1ULL << 18),
CPUID_ARM_SHA2_BIT = (1ULL << 19),
CPUID_ARM_SHA3_BIT = (1ULL << 20),
CPUID_ARM_SHA2_512_BIT = (1ULL << 21),
CPUID_ARM_SM3_BIT = (1ULL << 22),
CPUID_ARM_SM4_BIT = (1ULL << 23),
#endif
CPUID_INITIALIZED_BIT = (1ULL << 63)
};
#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
/**
* Check if the processor supports AltiVec/VMX
*/
static bool has_altivec()
{ return has_cpuid_bit(CPUID_ALTIVEC_BIT); }
/**
* Check if the processor supports POWER8 crypto extensions
*/
static bool has_power_crypto()
{ return has_cpuid_bit(CPUID_POWER_CRYPTO_BIT); }
/**
* Check if the processor supports POWER9 DARN RNG
*/
static bool has_darn_rng()
{ return has_cpuid_bit(CPUID_DARN_BIT); }
#endif
#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
/**
* Check if the processor supports NEON SIMD
*/
static bool has_neon()
{ return has_cpuid_bit(CPUID_ARM_NEON_BIT); }
/**
* Check if the processor supports ARMv8 SVE
*/
static bool has_arm_sve()
{ return has_cpuid_bit(CPUID_ARM_SVE_BIT); }
/**
* Check if the processor supports ARMv8 SHA1
*/
static bool has_arm_sha1()
{ return has_cpuid_bit(CPUID_ARM_SHA1_BIT); }
/**
* Check if the processor supports ARMv8 SHA2
*/
static bool has_arm_sha2()
{ return has_cpuid_bit(CPUID_ARM_SHA2_BIT); }
/**
* Check if the processor supports ARMv8 AES
*/
static bool has_arm_aes()
{ return has_cpuid_bit(CPUID_ARM_AES_BIT); }
/**
* Check if the processor supports ARMv8 PMULL
*/
static bool has_arm_pmull()
{ return has_cpuid_bit(CPUID_ARM_PMULL_BIT); }
/**
* Check if the processor supports ARMv8 SHA-512
*/
static bool has_arm_sha2_512()
{ return has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); }
/**
* Check if the processor supports ARMv8 SHA-3
*/
static bool has_arm_sha3()
{ return has_cpuid_bit(CPUID_ARM_SHA3_BIT); }
/**
* Check if the processor supports ARMv8 SM3
*/
static bool has_arm_sm3()
{ return has_cpuid_bit(CPUID_ARM_SM3_BIT); }
/**
* Check if the processor supports ARMv8 SM4
*/
static bool has_arm_sm4()
{ return has_cpuid_bit(CPUID_ARM_SM4_BIT); }
#endif
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
/**
* Check if the processor supports RDTSC
*/
static bool has_rdtsc()
{ return has_cpuid_bit(CPUID_RDTSC_BIT); }
/**
* Check if the processor supports SSE2
*/
static bool has_sse2()
{ return has_cpuid_bit(CPUID_SSE2_BIT); }
/**
* Check if the processor supports SSSE3
*/
static bool has_ssse3()
{ return has_cpuid_bit(CPUID_SSSE3_BIT); }
/**
* Check if the processor supports SSE4.1
*/
static bool has_sse41()
{ return has_cpuid_bit(CPUID_SSE41_BIT); }
/**
* Check if the processor supports SSE4.2
*/
static bool has_sse42()
{ return has_cpuid_bit(CPUID_SSE42_BIT); }
/**
* Check if the processor supports AVX2
*/
static bool has_avx2()
{ return has_cpuid_bit(CPUID_AVX2_BIT); }
/**
* Check if the processor supports AVX-512F
*/
static bool has_avx512f()
{ return has_cpuid_bit(CPUID_AVX512F_BIT); }
/**
* Check if the processor supports AVX-512DQ
*/
static bool has_avx512dq()
{ return has_cpuid_bit(CPUID_AVX512DQ_BIT); }
/**
* Check if the processor supports AVX-512BW
*/
static bool has_avx512bw()
{ return has_cpuid_bit(CPUID_AVX512BW_BIT); }
/**
* Check if the processor supports AVX-512 Ice Lake profile
*/
static bool has_avx512_icelake()
{ return has_cpuid_bit(CPUID_AVX512_ICL_BIT); }
/**
* Check if the processor supports AVX-512 AES (VAES)
*/
static bool has_avx512_aes()
{ return has_cpuid_bit(CPUID_AVX512_AES_BIT); }
/**
* Check if the processor supports AVX-512 VPCLMULQDQ
*/
static bool has_avx512_clmul()
{ return has_cpuid_bit(CPUID_AVX512_CLMUL_BIT); }
/**
* Check if the processor supports BMI1
*/
static bool has_bmi1()
{ return has_cpuid_bit(CPUID_BMI1_BIT); }
/**
* Check if the processor supports BMI2
*/
static bool has_bmi2()
{ return has_cpuid_bit(CPUID_BMI2_BIT); }
/**
* Check if the processor supports AES-NI
*/
static bool has_aes_ni()
{ return has_cpuid_bit(CPUID_AESNI_BIT); }
/**
* Check if the processor supports CLMUL
*/
static bool has_clmul()
{ return has_cpuid_bit(CPUID_CLMUL_BIT); }
/**
* Check if the processor supports Intel SHA extension
*/
static bool has_intel_sha()
{ return has_cpuid_bit(CPUID_SHA_BIT); }
/**
* Check if the processor supports ADX extension
*/
static bool has_adx()
{ return has_cpuid_bit(CPUID_ADX_BIT); }
/**
* Check if the processor supports RDRAND
*/
static bool has_rdrand()
{ return has_cpuid_bit(CPUID_RDRAND_BIT); }
/**
* Check if the processor supports RDSEED
*/
static bool has_rdseed()
{ return has_cpuid_bit(CPUID_RDSEED_BIT); }
#endif
/**
* Check if the processor supports byte-level vector permutes
* (SSSE3, NEON, Altivec)
*/
static bool has_vperm()
{
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
return has_ssse3();
#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
return has_neon();
#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
return has_altivec();
#else
return false;
#endif
}
/**
* Check if the processor supports hardware AES instructions
*/
static bool has_hw_aes()
{
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
return has_aes_ni();
#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
return has_arm_aes();
#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
return has_power_crypto();
#else
return false;
#endif
}
/**
* Check if the processor supports carryless multiply
* (CLMUL, PMULL)
*/
static bool has_carryless_multiply()
{
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
return has_clmul();
#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
return has_arm_pmull();
#elif defined(BOTAN_TARGET_ARCH_IS_PPC64)
return has_power_crypto();
#else
return false;
#endif
}
/*
* Clear a CPUID bit
* Call CPUID::initialize to reset
*
* This is only exposed for testing, don't use unless you know
* what you are doing.
*/
static void clear_cpuid_bit(CPUID_bits bit)
{
state().clear_cpuid_bit(static_cast<uint64_t>(bit));
}
/*
* Don't call this function, use CPUID::has_xxx above
* It is only exposed for the tests.
*/
static bool has_cpuid_bit(CPUID_bits elem)
{
const uint64_t elem64 = static_cast<uint64_t>(elem);
return state().has_bit(elem64);
}
static std::vector<CPUID::CPUID_bits> bit_from_string(const std::string& tok);
private:
enum class Endian_Status : uint32_t {
Unknown = 0x00000000,
Big = 0x01234567,
Little = 0x67452301,
};
struct CPUID_Data
{
public:
CPUID_Data();
CPUID_Data(const CPUID_Data& other) = default;
CPUID_Data& operator=(const CPUID_Data& other) = default;
void clear_cpuid_bit(uint64_t bit)
{
m_processor_features &= ~bit;
}
bool has_bit(uint64_t bit) const
{
return (m_processor_features & bit) == bit;
}
uint64_t processor_features() const { return m_processor_features; }
Endian_Status endian_status() const { return m_endian_status; }
size_t cache_line_size() const { return m_cache_line_size; }
private:
static Endian_Status runtime_check_endian();
#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || \
defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \
defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
static uint64_t detect_cpu_features(size_t* cache_line_size);
#endif
uint64_t m_processor_features;
size_t m_cache_line_size;
Endian_Status m_endian_status;
};
static CPUID_Data& state()
{
static CPUID::CPUID_Data g_cpuid;
return g_cpuid;
}
};
}
#endif

View file

@ -0,0 +1,41 @@
/*
* CRC24
* (C) 1999-2007 Jack Lloyd
* (C) 2017 [Ribose Inc](https://www.ribose.com). Performed by Krzysztof Kwiatkowski.
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CRC24_H_
#define BOTAN_CRC24_H_
#include <botan/hash.h>
BOTAN_FUTURE_INTERNAL_HEADER(crc24.h)
namespace Botan {
/**
* 24-bit cyclic redundancy check
*/
class BOTAN_PUBLIC_API(2,0) CRC24 final : public HashFunction
{
public:
std::string name() const override { return "CRC24"; }
size_t output_length() const override { return 3; }
HashFunction* clone() const override { return new CRC24; }
std::unique_ptr<HashFunction> copy_state() const override;
void clear() override { m_crc = 0XCE04B7L; }
CRC24() { clear(); }
~CRC24() { clear(); }
private:
void add_data(const uint8_t[], size_t) override;
void final_result(uint8_t[]) override;
uint32_t m_crc;
};
}
#endif

View file

@ -0,0 +1,40 @@
/*
* CRC32
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CRC32_H_
#define BOTAN_CRC32_H_
#include <botan/hash.h>
BOTAN_FUTURE_INTERNAL_HEADER(crc32.h)
namespace Botan {
/**
* 32-bit cyclic redundancy check
*/
class BOTAN_PUBLIC_API(2,0) CRC32 final : public HashFunction
{
public:
std::string name() const override { return "CRC32"; }
size_t output_length() const override { return 4; }
HashFunction* clone() const override { return new CRC32; }
std::unique_ptr<HashFunction> copy_state() const override;
void clear() override { m_crc = 0xFFFFFFFF; }
CRC32() { clear(); }
~CRC32() { clear(); }
private:
void add_data(const uint8_t[], size_t) override;
void final_result(uint8_t[]) override;
uint32_t m_crc;
};
}
#endif

View file

@ -0,0 +1,196 @@
/*
* Credentials Manager
* (C) 2011,2012 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CREDENTIALS_MANAGER_H_
#define BOTAN_CREDENTIALS_MANAGER_H_
#include <botan/pk_keys.h>
#include <botan/x509cert.h>
#include <botan/certstor.h>
#include <botan/symkey.h>
#include <string>
namespace Botan {
class X509_DN;
class BigInt;
/**
* Interface for a credentials manager.
*
* A type is a fairly static value that represents the general nature
* of the transaction occurring. Currently used values are "tls-client"
* and "tls-server". Context represents a hostname, email address,
* username, or other identifier.
*/
class BOTAN_PUBLIC_API(2,0) Credentials_Manager
{
public:
virtual ~Credentials_Manager() = default;
/**
* Return a list of the certificates of CAs that we trust in this
* type/context.
*
* @param type specifies the type of operation occurring
*
* @param context specifies a context relative to type. For instance
* for type "tls-client", context specifies the servers name.
*/
virtual std::vector<Certificate_Store*> trusted_certificate_authorities(
const std::string& type,
const std::string& context);
/**
* Return a cert chain we can use, ordered from leaf to root,
* or else an empty vector.
*
* It is assumed that the caller can get the private key of the
* leaf with private_key_for
*
* @param cert_key_types specifies the key types desired ("RSA",
* "DSA", "ECDSA", etc), or empty if there
* is no preference by the caller.
*
* @param acceptable_CAs the CAs the requestor will accept (possibly empty)
* @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
*/
virtual std::vector<X509_Certificate> find_cert_chain(
const std::vector<std::string>& cert_key_types,
const std::vector<X509_DN>& acceptable_CAs,
const std::string& type,
const std::string& context);
/**
* Return a cert chain we can use, ordered from leaf to root,
* or else an empty vector.
*
* This virtual function is deprecated, and will be removed in a
* future release. Use (and override) find_cert_chain instead.
*
* It is assumed that the caller can get the private key of the
* leaf with private_key_for
*
* @param cert_key_types specifies the key types desired ("RSA",
* "DSA", "ECDSA", etc), or empty if there
* is no preference by the caller.
*
* @param type specifies the type of operation occurring
*
* @param context specifies a context relative to type.
*/
virtual std::vector<X509_Certificate> cert_chain(
const std::vector<std::string>& cert_key_types,
const std::string& type,
const std::string& context);
/**
* Return a cert chain we can use, ordered from leaf to root,
* or else an empty vector.
*
* It is assumed that the caller can get the private key of the
* leaf with private_key_for
*
* @param cert_key_type specifies the type of key requested
* ("RSA", "DSA", "ECDSA", etc)
*
* @param type specifies the type of operation occurring
*
* @param context specifies a context relative to type.
*/
std::vector<X509_Certificate> cert_chain_single_type(
const std::string& cert_key_type,
const std::string& type,
const std::string& context);
/**
* @return private key associated with this certificate if we should
* use it with this context. cert was returned by cert_chain
* @note this object should retain ownership of the returned key;
* it should not be deleted by the caller.
*/
virtual Private_Key* private_key_for(const X509_Certificate& cert,
const std::string& type,
const std::string& context);
/**
* @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @return true if we should attempt SRP authentication
*/
virtual bool attempt_srp(const std::string& type,
const std::string& context);
/**
* @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @return identifier for client-side SRP auth, if available
for this type/context. Should return empty string
if password auth not desired/available.
*/
virtual std::string srp_identifier(const std::string& type,
const std::string& context);
/**
* @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @param identifier specifies what identifier we want the
* password for. This will be a value previously returned
* by srp_identifier.
* @return password for client-side SRP auth, if available
for this identifier/type/context.
*/
virtual std::string srp_password(const std::string& type,
const std::string& context,
const std::string& identifier);
/**
* Retrieve SRP verifier parameters
*/
virtual bool srp_verifier(const std::string& type,
const std::string& context,
const std::string& identifier,
std::string& group_name,
BigInt& verifier,
std::vector<uint8_t>& salt,
bool generate_fake_on_unknown);
/**
* @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @return the PSK identity hint for this type/context
*/
virtual std::string psk_identity_hint(const std::string& type,
const std::string& context);
/**
* @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @param identity_hint was passed by the server (but may be empty)
* @return the PSK identity we want to use
*/
virtual std::string psk_identity(const std::string& type,
const std::string& context,
const std::string& identity_hint);
/**
* @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @param identity is a PSK identity previously returned by
psk_identity for the same type and context.
* @return the PSK used for identity, or throw an exception if no
* key exists
*/
virtual SymmetricKey psk(const std::string& type,
const std::string& context,
const std::string& identity);
};
}
#endif

View file

@ -0,0 +1,11 @@
/*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CRL_ENTRY_H_
#define BOTAN_CRL_ENTRY_H_
#include <botan/x509_crl.h>
BOTAN_DEPRECATED_HEADER(crl_ent.h)
#endif

View file

@ -0,0 +1,79 @@
/*
* Cryptobox Message Routines
* (C) 2009 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CRYPTOBOX_H_
#define BOTAN_CRYPTOBOX_H_
#include <string>
#include <botan/symkey.h>
namespace Botan {
class RandomNumberGenerator;
/**
* 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_PUBLIC_API(2,0) std::string encrypt(const uint8_t 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_PUBLIC_API(2,3)
secure_vector<uint8_t>
decrypt_bin(const uint8_t 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_PUBLIC_API(2,3)
secure_vector<uint8_t>
decrypt_bin(const std::string& input,
const std::string& passphrase);
/**
* 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_PUBLIC_API(2,0)
std::string decrypt(const uint8_t 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_PUBLIC_API(2,0)
std::string decrypt(const std::string& input,
const std::string& passphrase);
}
}
#endif

View file

@ -0,0 +1,65 @@
/*
* CTR-BE Mode
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CTR_BE_H_
#define BOTAN_CTR_BE_H_
#include <botan/block_cipher.h>
#include <botan/stream_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(ctr.h)
namespace Botan {
/**
* CTR-BE (Counter mode, big-endian)
*/
class BOTAN_PUBLIC_API(2,0) CTR_BE final : public StreamCipher
{
public:
void cipher(const uint8_t in[], uint8_t out[], size_t length) override;
void set_iv(const uint8_t iv[], size_t iv_len) override;
size_t default_iv_length() const override;
bool valid_iv_length(size_t iv_len) const override;
Key_Length_Specification key_spec() const override;
std::string name() const override;
CTR_BE* clone() const override;
void clear() override;
/**
* @param cipher the block cipher to use
*/
explicit CTR_BE(BlockCipher* cipher);
CTR_BE(BlockCipher* cipher, size_t ctr_size);
void seek(uint64_t offset) override;
private:
void key_schedule(const uint8_t key[], size_t key_len) override;
void add_counter(const uint64_t counter);
std::unique_ptr<BlockCipher> m_cipher;
const size_t m_block_size;
const size_t m_ctr_size;
const size_t m_ctr_blocks;
secure_vector<uint8_t> m_counter, m_pad;
std::vector<uint8_t> m_iv;
size_t m_pad_pos;
};
}
#endif

View file

@ -0,0 +1,123 @@
/*
* Curve25519
* (C) 2014 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_CURVE_25519_H_
#define BOTAN_CURVE_25519_H_
#include <botan/pk_keys.h>
namespace Botan {
class BOTAN_PUBLIC_API(2,0) Curve25519_PublicKey : public virtual Public_Key
{
public:
std::string algo_name() const override { return "Curve25519"; }
size_t estimated_strength() const override { return 128; }
size_t key_length() const override { return 255; }
bool check_key(RandomNumberGenerator& rng, bool strong) const override;
AlgorithmIdentifier algorithm_identifier() const override;
std::vector<uint8_t> public_key_bits() const override;
std::vector<uint8_t> public_value() const { return m_public; }
/**
* Create a Curve25519 Public Key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
*/
Curve25519_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits);
/**
* Create a Curve25519 Public Key.
* @param pub 32-byte raw public key
*/
explicit Curve25519_PublicKey(const std::vector<uint8_t>& pub) : m_public(pub) {}
/**
* Create a Curve25519 Public Key.
* @param pub 32-byte raw public key
*/
explicit Curve25519_PublicKey(const secure_vector<uint8_t>& pub) :
m_public(pub.begin(), pub.end()) {}
protected:
Curve25519_PublicKey() = default;
std::vector<uint8_t> m_public;
};
class BOTAN_PUBLIC_API(2,0) Curve25519_PrivateKey final : public Curve25519_PublicKey,
public virtual Private_Key,
public virtual PK_Key_Agreement_Key
{
public:
/**
* Construct a private key from the specified parameters.
* @param alg_id the X.509 algorithm identifier
* @param key_bits PKCS #8 structure
*/
Curve25519_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits);
/**
* Generate a private key.
* @param rng the RNG to use
*/
explicit Curve25519_PrivateKey(RandomNumberGenerator& rng);
/**
* Construct a private key from the specified parameters.
* @param secret_key the private key
*/
explicit Curve25519_PrivateKey(const secure_vector<uint8_t>& secret_key);
std::vector<uint8_t> public_value() const override { return Curve25519_PublicKey::public_value(); }
secure_vector<uint8_t> agree(const uint8_t w[], size_t w_len) const;
const secure_vector<uint8_t>& get_x() const { return m_private; }
secure_vector<uint8_t> private_key_bits() const override;
bool check_key(RandomNumberGenerator& rng, bool strong) const override;
std::unique_ptr<PK_Ops::Key_Agreement>
create_key_agreement_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
private:
secure_vector<uint8_t> m_private;
};
typedef Curve25519_PublicKey X25519_PublicKey;
typedef Curve25519_PrivateKey X25519_PrivateKey;
/*
* The types above are just wrappers for curve25519_donna, plus defining
* encodings for public and private keys.
*/
void BOTAN_PUBLIC_API(2,0) curve25519_donna(uint8_t mypublic[32],
const uint8_t secret[32],
const uint8_t basepoint[32]);
/**
* Exponentiate by the x25519 base point
* @param mypublic output value
* @param secret random scalar
*/
void BOTAN_PUBLIC_API(2,0) curve25519_basepoint(uint8_t mypublic[32],
const uint8_t secret[32]);
}
#endif

View file

@ -0,0 +1,265 @@
/*
* Elliptic curves over GF(p)
*
* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
* 2010-2011,2012,2014 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_GFP_CURVE_H_
#define BOTAN_GFP_CURVE_H_
#include <botan/bigint.h>
#include <memory>
// Currently exposed in PointGFp
//BOTAN_FUTURE_INTERNAL_HEADER(curve_gfp.h)
namespace Botan {
class BOTAN_UNSTABLE_API CurveGFp_Repr
{
public:
virtual ~CurveGFp_Repr() = default;
virtual const BigInt& get_p() const = 0;
virtual const BigInt& get_a() const = 0;
virtual const BigInt& get_b() const = 0;
virtual size_t get_p_words() const = 0;
virtual size_t get_ws_size() const = 0;
virtual bool is_one(const BigInt& x) const = 0;
virtual bool a_is_zero() const = 0;
virtual bool a_is_minus_3() const = 0;
/*
* Returns to_curve_rep(get_a())
*/
virtual const BigInt& get_a_rep() const = 0;
/*
* Returns to_curve_rep(get_b())
*/
virtual const BigInt& get_b_rep() const = 0;
/*
* Returns to_curve_rep(1)
*/
virtual const BigInt& get_1_rep() const = 0;
virtual BigInt invert_element(const BigInt& x, secure_vector<word>& ws) const = 0;
virtual void to_curve_rep(BigInt& x, secure_vector<word>& ws) const = 0;
virtual void from_curve_rep(BigInt& x, secure_vector<word>& ws) const = 0;
void curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
secure_vector<word>& ws) const
{
BOTAN_DEBUG_ASSERT(x.sig_words() <= get_p_words());
curve_mul_words(z, x.data(), x.size(), y, ws);
}
virtual void curve_mul_words(BigInt& z,
const word x_words[],
const size_t x_size,
const BigInt& y,
secure_vector<word>& ws) const = 0;
void curve_sqr(BigInt& z, const BigInt& x,
secure_vector<word>& ws) const
{
BOTAN_DEBUG_ASSERT(x.sig_words() <= get_p_words());
curve_sqr_words(z, x.data(), x.size(), ws);
}
virtual void curve_sqr_words(BigInt& z,
const word x_words[],
size_t x_size,
secure_vector<word>& ws) const = 0;
};
/**
* This class represents an elliptic curve over GF(p)
*
* There should not be any reason for applications to use this type.
* If you need EC primitives use the interfaces EC_Group and PointGFp
*
* It is likely this class will be removed entirely in a future major
* release.
*/
class BOTAN_UNSTABLE_API CurveGFp final
{
public:
/**
* Create an uninitialized CurveGFp
*/
CurveGFp() = default;
/**
* 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) :
m_repr(choose_repr(p, a, b))
{
}
CurveGFp(const CurveGFp&) = default;
CurveGFp& operator=(const CurveGFp&) = default;
/**
* @return curve coefficient a
*/
const BigInt& get_a() const { return m_repr->get_a(); }
/**
* @return curve coefficient b
*/
const BigInt& get_b() const { return m_repr->get_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 m_repr->get_p(); }
size_t get_p_words() const { return m_repr->get_p_words(); }
size_t get_ws_size() const { return m_repr->get_ws_size(); }
const BigInt& get_a_rep() const { return m_repr->get_a_rep(); }
const BigInt& get_b_rep() const { return m_repr->get_b_rep(); }
const BigInt& get_1_rep() const { return m_repr->get_1_rep(); }
bool a_is_minus_3() const { return m_repr->a_is_minus_3(); }
bool a_is_zero() const { return m_repr->a_is_zero(); }
bool is_one(const BigInt& x) const { return m_repr->is_one(x); }
BigInt invert_element(const BigInt& x, secure_vector<word>& ws) const
{
return m_repr->invert_element(x, ws);
}
void to_rep(BigInt& x, secure_vector<word>& ws) const
{
m_repr->to_curve_rep(x, ws);
}
void from_rep(BigInt& x, secure_vector<word>& ws) const
{
m_repr->from_curve_rep(x, ws);
}
BigInt from_rep_to_tmp(const BigInt& x, secure_vector<word>& ws) const
{
BigInt xt(x);
m_repr->from_curve_rep(xt, ws);
return xt;
}
// TODO: from_rep taking && ref
void mul(BigInt& z, const BigInt& x, const BigInt& y, secure_vector<word>& ws) const
{
m_repr->curve_mul(z, x, y, ws);
}
void mul(BigInt& z, const word x_w[], size_t x_size,
const BigInt& y, secure_vector<word>& ws) const
{
m_repr->curve_mul_words(z, x_w, x_size, y, ws);
}
void sqr(BigInt& z, const BigInt& x, secure_vector<word>& ws) const
{
m_repr->curve_sqr(z, x, ws);
}
void sqr(BigInt& z, const word x_w[], size_t x_size, secure_vector<word>& ws) const
{
m_repr->curve_sqr_words(z, x_w, x_size, ws);
}
BigInt mul(const BigInt& x, const BigInt& y, secure_vector<word>& ws) const
{
return mul_to_tmp(x, y, ws);
}
BigInt sqr(const BigInt& x, secure_vector<word>& ws) const
{
return sqr_to_tmp(x, ws);
}
BigInt mul_to_tmp(const BigInt& x, const BigInt& y, secure_vector<word>& ws) const
{
BigInt z;
m_repr->curve_mul(z, x, y, ws);
return z;
}
BigInt sqr_to_tmp(const BigInt& x, secure_vector<word>& ws) const
{
BigInt z;
m_repr->curve_sqr(z, x, ws);
return z;
}
void swap(CurveGFp& other)
{
std::swap(m_repr, other.m_repr);
}
/**
* Equality operator
* @param other a curve
* @return true iff *this is the same as other
*/
inline bool operator==(const CurveGFp& other) const
{
if(m_repr.get() == other.m_repr.get())
return true;
return (get_p() == other.get_p()) &&
(get_a() == other.get_a()) &&
(get_b() == other.get_b());
}
private:
static std::shared_ptr<CurveGFp_Repr>
choose_repr(const BigInt& p, const BigInt& a, const BigInt& b);
std::shared_ptr<CurveGFp_Repr> m_repr;
};
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) noexcept
{
curve1.swap(curve2);
}
} // namespace std
#endif

View file

@ -0,0 +1,49 @@
/*
* Arithmetic operations specialized for NIST ECC primes
* (C) 2014,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_NIST_PRIMES_H_
#define BOTAN_NIST_PRIMES_H_
#include <botan/bigint.h>
BOTAN_FUTURE_INTERNAL_HEADER(curve_nistp.h)
namespace Botan {
/**
* NIST Prime reduction functions.
*
* Reduces the value in place
*
* ws is a workspace function which is used as a temporary,
* and will be resized as needed.
*/
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p521();
BOTAN_PUBLIC_API(2,0) void redc_p521(BigInt& x, secure_vector<word>& ws);
/*
Previously this macro indicated if the P-{192,224,256,384} reducers
were available. Now they are always enabled and this macro has no meaning.
The define will be removed in a future major release.
*/
#define BOTAN_HAS_NIST_PRIME_REDUCERS_W32
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p384();
BOTAN_PUBLIC_API(2,0) void redc_p384(BigInt& x, secure_vector<word>& ws);
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p256();
BOTAN_PUBLIC_API(2,0) void redc_p256(BigInt& x, secure_vector<word>& ws);
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p224();
BOTAN_PUBLIC_API(2,0) void redc_p224(BigInt& x, secure_vector<word>& ws);
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p192();
BOTAN_PUBLIC_API(2,0) void redc_p192(BigInt& x, secure_vector<word>& ws);
}
#endif

View file

@ -0,0 +1,76 @@
/*
* DataSink
* (C) 1999-2007 Jack Lloyd
* 2017 Philippe Lieser
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DATA_SINK_H_
#define BOTAN_DATA_SINK_H_
#include <botan/filter.h>
#include <memory>
#include <iosfwd>
namespace Botan {
/**
* This class represents abstract data sink objects.
*/
class BOTAN_PUBLIC_API(2,0) DataSink : public Filter
{
public:
bool attachable() override { return false; }
DataSink() = default;
virtual ~DataSink() = default;
DataSink& operator=(const DataSink&) = delete;
DataSink(const DataSink&) = delete;
};
/**
* This class represents a data sink which writes its output to a stream.
*/
class BOTAN_PUBLIC_API(2,0) DataSink_Stream final : public DataSink
{
public:
/**
* 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>");
#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
/**
* Construct a DataSink_Stream from a filesystem path name.
* @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);
#endif
std::string name() const override { return m_identifier; }
void write(const uint8_t[], size_t) override;
void end_msg() override;
~DataSink_Stream();
private:
const std::string m_identifier;
// May be null, if m_sink was an external reference
std::unique_ptr<std::ostream> m_sink_memory;
std::ostream& m_sink;
};
}
#endif

View file

@ -0,0 +1,181 @@
/*
* DataSource
* (C) 1999-2007 Jack Lloyd
* 2012 Markus Wanner
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DATA_SRC_H_
#define BOTAN_DATA_SRC_H_
#include <botan/secmem.h>
#include <string>
#include <iosfwd>
namespace Botan {
/**
* This class represents an abstract data source object.
*/
class BOTAN_PUBLIC_API(2,0) 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(uint8_t out[], size_t length) BOTAN_WARN_UNUSED_RESULT = 0;
virtual bool check_available(size_t n) = 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(uint8_t out[], size_t length, size_t peek_offset) const BOTAN_WARN_UNUSED_RESULT = 0;
/**
* Test whether the source still has data that can be read.
* @return true if there is no more 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(uint8_t& 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(uint8_t& 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);
/**
* @return number of bytes read so far.
*/
virtual size_t get_bytes_read() const = 0;
DataSource() = default;
virtual ~DataSource() = default;
DataSource& operator=(const DataSource&) = delete;
DataSource(const DataSource&) = delete;
};
/**
* This class represents a Memory-Based DataSource
*/
class BOTAN_PUBLIC_API(2,0) DataSource_Memory final : public DataSource
{
public:
size_t read(uint8_t[], size_t) override;
size_t peek(uint8_t[], size_t, size_t) const override;
bool check_available(size_t n) override;
bool end_of_data() const override;
/**
* Construct a memory source that reads from a string
* @param in the string to read from
*/
explicit 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 uint8_t in[], size_t length) :
m_source(in, in + length), m_offset(0) {}
/**
* Construct a memory source that reads from a secure_vector
* @param in the MemoryRegion to read from
*/
explicit DataSource_Memory(const secure_vector<uint8_t>& in) :
m_source(in), m_offset(0) {}
/**
* Construct a memory source that reads from a std::vector
* @param in the MemoryRegion to read from
*/
explicit DataSource_Memory(const std::vector<uint8_t>& in) :
m_source(in.begin(), in.end()), m_offset(0) {}
size_t get_bytes_read() const override { return m_offset; }
private:
secure_vector<uint8_t> m_source;
size_t m_offset;
};
/**
* This class represents a Stream-Based DataSource.
*/
class BOTAN_PUBLIC_API(2,0) DataSource_Stream final : public DataSource
{
public:
size_t read(uint8_t[], size_t) override;
size_t peek(uint8_t[], size_t, size_t) const override;
bool check_available(size_t n) override;
bool end_of_data() const override;
std::string id() const override;
DataSource_Stream(std::istream&,
const std::string& id = "<std::istream>");
#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
/**
* Construct a Stream-Based DataSource from filesystem path
* @param file the path to the file
* @param use_binary whether to treat the file as binary or not
*/
DataSource_Stream(const std::string& file, bool use_binary = false);
#endif
DataSource_Stream(const DataSource_Stream&) = delete;
DataSource_Stream& operator=(const DataSource_Stream&) = delete;
~DataSource_Stream();
size_t get_bytes_read() const override { return m_total_read; }
private:
const std::string m_identifier;
std::unique_ptr<std::istream> m_source_memory;
std::istream& m_source;
size_t m_total_read;
};
}
#endif

View file

@ -0,0 +1,88 @@
/*
* SQL database interface
* (C) 2014 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_SQL_DATABASE_H_
#define BOTAN_SQL_DATABASE_H_
#include <botan/types.h>
#include <botan/exceptn.h>
#include <string>
#include <chrono>
#include <vector>
namespace Botan {
class BOTAN_PUBLIC_API(2,0) SQL_Database
{
public:
class BOTAN_PUBLIC_API(2,0) SQL_DB_Error final : public Exception
{
public:
explicit SQL_DB_Error(const std::string& what) :
Exception("SQL database", what),
m_rc(0)
{}
SQL_DB_Error(const std::string& what, int rc) :
Exception("SQL database", what),
m_rc(rc)
{}
ErrorType error_type() const noexcept override { return Botan::ErrorType::DatabaseError; }
int error_code() const noexcept override { return m_rc; }
private:
int m_rc;
};
class BOTAN_PUBLIC_API(2,0) Statement
{
public:
/* Bind statement parameters */
virtual void bind(int column, const std::string& str) = 0;
virtual void bind(int column, size_t i) = 0;
virtual void bind(int column, std::chrono::system_clock::time_point time) = 0;
virtual void bind(int column, const std::vector<uint8_t>& blob) = 0;
virtual void bind(int column, const uint8_t* data, size_t len) = 0;
/* Get output */
virtual std::pair<const uint8_t*, size_t> get_blob(int column) = 0;
virtual std::string get_str(int column) = 0;
virtual size_t get_size_t(int column) = 0;
/* Run to completion */
virtual size_t spin() = 0;
/* Maybe update */
virtual bool step() = 0;
virtual ~Statement() = default;
};
/*
* Create a new statement for execution.
* Use ?1, ?2, ?3, etc for parameters to set later with bind
*/
virtual std::shared_ptr<Statement> new_statement(const std::string& base_sql) const = 0;
virtual size_t row_count(const std::string& table_name) = 0;
virtual void create_table(const std::string& table_schema) = 0;
virtual ~SQL_Database() = default;
};
}
#endif

View file

@ -0,0 +1,85 @@
/*
* Data Store
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DATA_STORE_H_
#define BOTAN_DATA_STORE_H_
#include <botan/pkix_types.h>
#include <functional>
#include <string>
#include <vector>
#include <map>
BOTAN_FUTURE_INTERNAL_HEADER(datastor.h)
namespace Botan {
/**
* Data Store
*
* This class is used internally by the library, and exposed for ABI
* reasons. There is no reason for applications to use this type directly.
* It will be removed in a future major release.
*/
class BOTAN_UNSTABLE_API Data_Store final
{
public:
/**
* A search function
*/
bool operator==(const Data_Store&) const;
std::multimap<std::string, std::string> search_for(
std::function<bool (std::string, std::string)> predicate) const;
std::vector<std::string> get(const std::string&) const;
std::string get1(const std::string& key) const;
std::string get1(const std::string& key,
const std::string& default_value) const;
std::vector<uint8_t> get1_memvec(const std::string&) const;
uint32_t get1_uint32(const std::string&, uint32_t = 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&, uint32_t);
void add(const std::string&, const secure_vector<uint8_t>&);
void add(const std::string&, const std::vector<uint8_t>&);
private:
std::multimap<std::string, std::string> m_contents;
};
/*
* Data Store Extraction Operations
*/
/*
* Create and populate a X509_DN
* @param info data store containing DN information
* @return DN containing attributes from data store
*/
BOTAN_PUBLIC_API(2,0) X509_DN
BOTAN_DEPRECATED("Avoid roundtripping names through Data_Store")
create_dn(const Data_Store& info);
/*
* Create and populate an AlternativeName
* @param info data store containing AlternativeName information
* @return AlternativeName containing attributes from data store
*/
BOTAN_PUBLIC_API(2,0) AlternativeName
BOTAN_DEPRECATED("Avoid roundtripping names through Data_Store")
create_alt_name(const Data_Store& info);
}
#endif

View file

@ -0,0 +1,227 @@
/*
* DER Encoder
* (C) 1999-2007,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DER_ENCODER_H_
#define BOTAN_DER_ENCODER_H_
#include <botan/asn1_obj.h>
#include <vector>
#include <functional>
namespace Botan {
class BigInt;
/**
* General DER Encoding Object
*/
class BOTAN_PUBLIC_API(2,0) DER_Encoder final
{
public:
typedef std::function<void (const uint8_t[], size_t)> append_fn;
/**
* DER encode, writing to an internal buffer
* Use get_contents or get_contents_unlocked to read the results
* after all encoding is completed.
*/
DER_Encoder() = default;
/**
* DER encode, writing to @param vec
* If this constructor is used, get_contents* may not be called.
*/
DER_Encoder(secure_vector<uint8_t>& vec);
/**
* DER encode, writing to @param vec
* If this constructor is used, get_contents* may not be called.
*/
DER_Encoder(std::vector<uint8_t>& vec);
/**
* DER encode, calling append to write output
* If this constructor is used, get_contents* may not be called.
*/
DER_Encoder(append_fn append) : m_append_output(append) {}
secure_vector<uint8_t> get_contents();
/**
* Return the encoded contents as a std::vector
*
* If using this function, instead pass a std::vector to the
* contructor of DER_Encoder where the output will be placed. This
* avoids several unecessary copies.
*/
std::vector<uint8_t> BOTAN_DEPRECATED("Use DER_Encoder(vector) instead") get_contents_unlocked();
DER_Encoder& start_cons(ASN1_Tag type_tag,
ASN1_Tag class_tag = UNIVERSAL);
DER_Encoder& end_cons();
DER_Encoder& start_explicit(uint16_t type_tag);
DER_Encoder& end_explicit();
/**
* Insert raw bytes directly into the output stream
*/
DER_Encoder& raw_bytes(const uint8_t val[], size_t len);
template<typename Alloc>
DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val)
{
return raw_bytes(val.data(), val.size());
}
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 uint8_t val[], size_t len, ASN1_Tag real_type);
template<typename Alloc>
DER_Encoder& encode(const std::vector<uint8_t, Alloc>& vec, ASN1_Tag real_type)
{
return encode(vec.data(), vec.size(), 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 uint8_t v[], size_t len,
ASN1_Tag real_type,
ASN1_Tag type_tag,
ASN1_Tag class_tag = CONTEXT_SPECIFIC);
template<typename Alloc>
DER_Encoder& encode(const std::vector<uint8_t, Alloc>& bytes,
ASN1_Tag real_type,
ASN1_Tag type_tag, ASN1_Tag class_tag)
{
return encode(bytes.data(), bytes.size(),
real_type, type_tag, class_tag);
}
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);
}
/*
* Request for an object to encode itself to this stream
*/
DER_Encoder& encode(const ASN1_Object& obj);
/*
* Conditionally write some values to the stream
*/
DER_Encoder& encode_if(bool pred, DER_Encoder& enc)
{
if(pred)
return raw_bytes(enc.get_contents());
return (*this);
}
DER_Encoder& encode_if(bool pred, const ASN1_Object& obj)
{
if(pred)
encode(obj);
return (*this);
}
DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
const uint8_t rep[], size_t length);
DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
const std::vector<uint8_t>& rep)
{
return add_object(type_tag, class_tag, rep.data(), rep.size());
}
DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
const secure_vector<uint8_t>& rep)
{
return add_object(type_tag, class_tag, rep.data(), rep.size());
}
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,
uint8_t val);
private:
class DER_Sequence final
{
public:
ASN1_Tag tag_of() const;
void push_contents(DER_Encoder& der);
void add_bytes(const uint8_t val[], size_t len);
void add_bytes(const uint8_t hdr[], size_t hdr_len,
const uint8_t val[], size_t val_len);
DER_Sequence(ASN1_Tag, ASN1_Tag);
DER_Sequence(DER_Sequence&& seq)
{
std::swap(m_type_tag, seq.m_type_tag);
std::swap(m_class_tag, seq.m_class_tag);
std::swap(m_contents, seq.m_contents);
std::swap(m_set_contents, seq.m_set_contents);
}
DER_Sequence& operator=(DER_Sequence&& seq)
{
std::swap(m_type_tag, seq.m_type_tag);
std::swap(m_class_tag, seq.m_class_tag);
std::swap(m_contents, seq.m_contents);
std::swap(m_set_contents, seq.m_set_contents);
return (*this);
}
DER_Sequence(const DER_Sequence& seq) = default;
DER_Sequence& operator=(const DER_Sequence& seq) = default;
private:
ASN1_Tag m_type_tag, m_class_tag;
secure_vector<uint8_t> m_contents;
std::vector< secure_vector<uint8_t> > m_set_contents;
};
append_fn m_append_output;
secure_vector<uint8_t> m_default_outbuf;
std::vector<DER_Sequence> m_subsequences;
};
}
#endif

View file

@ -0,0 +1,67 @@
/*
* DES
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DES_H_
#define BOTAN_DES_H_
#include <botan/block_cipher.h>
BOTAN_FUTURE_INTERNAL_HEADER(des.h)
namespace Botan {
/**
* DES
*/
class BOTAN_PUBLIC_API(2,0) DES final : public Block_Cipher_Fixed_Params<8, 8>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "DES"; }
BlockCipher* clone() const override { return new DES; }
private:
void key_schedule(const uint8_t[], size_t) override;
secure_vector<uint32_t> m_round_key;
};
/**
* Triple DES
*/
class BOTAN_PUBLIC_API(2,0) TripleDES final : public Block_Cipher_Fixed_Params<8, 16, 24, 8>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "TripleDES"; }
BlockCipher* clone() const override { return new TripleDES; }
private:
void key_schedule(const uint8_t[], size_t) override;
secure_vector<uint32_t> m_round_key;
};
/*
* DES Tables
*/
extern const uint32_t DES_SPBOX1[256];
extern const uint32_t DES_SPBOX2[256];
extern const uint32_t DES_SPBOX3[256];
extern const uint32_t DES_SPBOX4[256];
extern const uint32_t DES_SPBOX5[256];
extern const uint32_t DES_SPBOX6[256];
extern const uint32_t DES_SPBOX7[256];
extern const uint32_t DES_SPBOX8[256];
}
#endif

View file

@ -0,0 +1,37 @@
/*
* DESX
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DESX_H_
#define BOTAN_DESX_H_
#include <botan/des.h>
BOTAN_FUTURE_INTERNAL_HEADER(desx.h)
namespace Botan {
/**
* DESX
*/
class BOTAN_PUBLIC_API(2,0) DESX final : public Block_Cipher_Fixed_Params<8, 24>
{
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void clear() override;
std::string name() const override { return "DESX"; }
BlockCipher* clone() const override { return new DESX; }
private:
void key_schedule(const uint8_t[], size_t) override;
secure_vector<uint8_t> m_K1, m_K2;
DES m_des;
};
}
#endif

View file

@ -0,0 +1,81 @@
/*
* Diffie-Hellman
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DIFFIE_HELLMAN_H_
#define BOTAN_DIFFIE_HELLMAN_H_
#include <botan/dl_algo.h>
namespace Botan {
/**
* This class represents Diffie-Hellman public keys.
*/
class BOTAN_PUBLIC_API(2,0) DH_PublicKey : public virtual DL_Scheme_PublicKey
{
public:
std::string algo_name() const override { return "DH"; }
std::vector<uint8_t> public_value() const;
DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_42; }
/**
* Create a public key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
*/
DH_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& 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() = default;
};
/**
* This class represents Diffie-Hellman private keys.
*/
class BOTAN_PUBLIC_API(2,0) DH_PrivateKey final : public DH_PublicKey,
public PK_Key_Agreement_Key,
public virtual DL_Scheme_PrivateKey
{
public:
std::vector<uint8_t> public_value() const override;
/**
* Load a private key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits PKCS #8 structure
*/
DH_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits);
/**
* Create a private key.
* @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);
std::unique_ptr<PK_Ops::Key_Agreement>
create_key_agreement_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
};
}
#endif

View file

@ -0,0 +1,101 @@
/*
* Division
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DIVISON_ALGORITHM_H_
#define BOTAN_DIVISON_ALGORITHM_H_
#include <botan/bigint.h>
BOTAN_FUTURE_INTERNAL_HEADER(divide.h)
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_UNSTABLE_API vartime_divide(const BigInt& x,
const BigInt& y,
BigInt& q,
BigInt& r);
/**
* BigInt division, const time variant
*
* This runs with control flow independent of the values of x/y.
* Warning: the loop bounds still leak the sizes of x and y.
*
* @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_PUBLIC_API(2,9) ct_divide(const BigInt& x,
const BigInt& y,
BigInt& q,
BigInt& r);
inline void divide(const BigInt& x,
const BigInt& y,
BigInt& q,
BigInt& r)
{
ct_divide(x, y, q, r);
}
/**
* BigInt division, const time variant
*
* This runs with control flow independent of the values of x/y.
* Warning: the loop bounds still leak the sizes of x and y.
*
* @param x an integer
* @param y a non-zero integer
* @return x/y with remainder discarded
*/
inline BigInt ct_divide(const BigInt& x, const BigInt& y)
{
BigInt q, r;
ct_divide(x, y, q, r);
return q;
}
/**
* BigInt division, const time variant
*
* This runs with control flow independent of the values of x/y.
* Warning: the loop bounds still leak the sizes of x and y.
*
* @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_PUBLIC_API(2,9) ct_divide_u8(const BigInt& x,
uint8_t y,
BigInt& q,
uint8_t& r);
/**
* BigInt modulo, const time variant
*
* Using this function is (slightly) cheaper than calling ct_divide and
* using only the remainder.
*
* @param x a non-negative integer
* @param modulo a positive integer
* @return result x % modulo
*/
BigInt BOTAN_PUBLIC_API(2,9) ct_modulo(const BigInt& x,
const BigInt& modulo);
}
#endif

View file

@ -0,0 +1,140 @@
/*
* DL Scheme
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DL_ALGO_H_
#define BOTAN_DL_ALGO_H_
#include <botan/dl_group.h>
#include <botan/pk_keys.h>
namespace Botan {
/**
* This class represents discrete logarithm (DL) public keys.
*/
class BOTAN_PUBLIC_API(2,0) DL_Scheme_PublicKey : public virtual Public_Key
{
public:
bool check_key(RandomNumberGenerator& rng, bool) const override;
AlgorithmIdentifier algorithm_identifier() const override;
std::vector<uint8_t> public_key_bits() const override;
/**
* Get the DL domain parameters of this key.
* @return DL domain parameters of this key
*/
const DL_Group& get_domain() const { return m_group; }
/**
* Get the DL domain parameters of this key.
* @return DL domain parameters of this key
*/
const DL_Group& get_group() const { return m_group; }
/**
* Get the public value y with y = g^x mod p where x is the secret key.
*/
const BigInt& get_y() const { return m_y; }
/**
* Get the prime p of the underlying DL group.
* @return prime p
*/
const BigInt& group_p() const { return m_group.get_p(); }
/**
* Get the prime q of the underlying DL group.
* @return prime q
*/
const BigInt& group_q() const { return m_group.get_q(); }
/**
* Get the generator g of the underlying DL group.
* @return generator g
*/
const BigInt& group_g() const { return m_group.get_g(); }
/**
* Get the underlying groups encoding format.
* @return encoding format
*/
virtual DL_Group::Format group_format() const = 0;
size_t key_length() const override;
size_t estimated_strength() const override;
DL_Scheme_PublicKey& operator=(const DL_Scheme_PublicKey& other) = default;
protected:
DL_Scheme_PublicKey() = default;
/**
* Create a public key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
* @param group_format the underlying groups encoding format
*/
DL_Scheme_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits,
DL_Group::Format group_format);
DL_Scheme_PublicKey(const DL_Group& group, const BigInt& y);
/**
* The DL public key
*/
BigInt m_y;
/**
* The DL group
*/
DL_Group m_group;
};
/**
* This class represents discrete logarithm (DL) private keys.
*/
class BOTAN_PUBLIC_API(2,0) DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey,
public virtual Private_Key
{
public:
bool check_key(RandomNumberGenerator& rng, bool) const override;
/**
* Get the secret key x.
* @return secret key
*/
const BigInt& get_x() const { return m_x; }
secure_vector<uint8_t> private_key_bits() const override;
DL_Scheme_PrivateKey& operator=(const DL_Scheme_PrivateKey& other) = default;
protected:
/**
* Create a private key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded private key bits
* @param group_format the underlying groups encoding format
*/
DL_Scheme_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits,
DL_Group::Format group_format);
DL_Scheme_PrivateKey() = default;
/**
* The DL private key
*/
BigInt m_x;
};
}
#endif

View file

@ -0,0 +1,357 @@
/*
* Discrete Logarithm Group
* (C) 1999-2008,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DL_PARAM_H_
#define BOTAN_DL_PARAM_H_
#include <botan/bigint.h>
namespace Botan {
class Montgomery_Params;
class DL_Group_Data;
enum class DL_Group_Source {
Builtin,
RandomlyGenerated,
ExternalSource,
};
/**
* This class represents discrete logarithm groups. It holds a prime
* modulus p, a generator g, and (optionally) a prime q which is a
* factor of (p-1). In most cases g generates the order-q subgroup.
*/
class BOTAN_PUBLIC_API(2,0) DL_Group final
{
public:
/**
* Determine the prime creation for DL groups.
*/
enum PrimeType { Strong, Prime_Subgroup, DSA_Kosherizer };
/**
* 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,
ANSI_X9_42_DH_PARAMETERS = ANSI_X9_42,
PKCS3_DH_PARAMETERS = PKCS_3
};
/**
* 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() = default;
/**
* Construct a DL group that is registered in the configuration.
* @param name the name of the group, for example "modp/ietf/3072"
*
* @warning This constructor also accepts PEM inputs. This behavior is
* deprecated and will be removed in a future major release. Instead
* use DL_Group_from_PEM function
*/
explicit DL_Group(const std::string& name);
/*
* Read a PEM representation
*/
static DL_Group DL_Group_from_PEM(const std::string& pem);
/**
* 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 std::vector<uint8_t>& seed,
size_t pbits = 1024, size_t qbits = 0);
/**
* Create a DL group.
* @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);
/**
* Decode a BER-encoded DL group param
*/
DL_Group(const uint8_t ber[], size_t ber_len, Format format);
/**
* Decode a BER-encoded DL group param
*/
template<typename Alloc>
DL_Group(const std::vector<uint8_t, Alloc>& ber, Format format) :
DL_Group(ber.data(), ber.size(), format) {}
/**
* Get the prime p.
* @return prime p
*/
const BigInt& get_p() const;
/**
* Get the prime q, returns zero if q is not used
* @return prime q
*/
const BigInt& get_q() const;
/**
* Get the base g.
* @return base g
*/
const BigInt& get_g() const;
/**
* 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 = true) const;
/**
* Verify a public element, ie check if y = g^x for some x.
*
* This is not a perfect test. It verifies that 1 < y < p and (if q is set)
* that y is in the subgroup of size q.
*/
bool verify_public_element(const BigInt& y) const;
/**
* Verify a pair of elements y = g^x
*
* This verifies that 1 < x,y < p and that y=g^x mod p
*/
bool verify_element_pair(const BigInt& y, const BigInt& x) 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
*/
std::vector<uint8_t> DER_encode(Format format) const;
/**
* Reduce an integer modulo p
* @return x % p
*/
BigInt mod_p(const BigInt& x) const;
/**
* Multiply and reduce an integer modulo p
* @return (x*y) % p
*/
BigInt multiply_mod_p(const BigInt& x, const BigInt& y) const;
/**
* Return the inverse of x mod p
*/
BigInt inverse_mod_p(const BigInt& x) const;
/**
* Reduce an integer modulo q
* Throws if q is unset on this DL_Group
* @return x % q
*/
BigInt mod_q(const BigInt& x) const;
/**
* Multiply and reduce an integer modulo q
* Throws if q is unset on this DL_Group
* @return (x*y) % q
*/
BigInt multiply_mod_q(const BigInt& x, const BigInt& y) const;
/**
* Multiply and reduce an integer modulo q
* Throws if q is unset on this DL_Group
* @return (x*y*z) % q
*/
BigInt multiply_mod_q(const BigInt& x, const BigInt& y, const BigInt& z) const;
/**
* Square and reduce an integer modulo q
* Throws if q is unset on this DL_Group
* @return (x*x) % q
*/
BigInt square_mod_q(const BigInt& x) const;
/**
* Return the inverse of x mod q
* Throws if q is unset on this DL_Group
*/
BigInt inverse_mod_q(const BigInt& x) const;
/**
* Modular exponentiation
*
* @warning this function leaks the size of x via the number of
* loop iterations. Use the version taking the maximum size to
* avoid this.
*
* @return (g^x) % p
*/
BigInt power_g_p(const BigInt& x) const;
/**
* Modular exponentiation
* @param x the exponent
* @param max_x_bits x is assumed to be at most this many bits long.
*
* @return (g^x) % p
*/
BigInt power_g_p(const BigInt& x, size_t max_x_bits) const;
/**
* Multi-exponentiate
* Return (g^x * y^z) % p
*/
BigInt multi_exponentiate(const BigInt& x, const BigInt& y, const BigInt& z) const;
/**
* Return parameters for Montgomery reduction/exponentiation mod p
*/
std::shared_ptr<const Montgomery_Params> monty_params_p() const;
/**
* Return the size of p in bits
* Same as get_p().bits()
*/
size_t p_bits() const;
/**
* Return the size of p in bytes
* Same as get_p().bytes()
*/
size_t p_bytes() const;
/**
* Return the size of q in bits
* Same as get_q().bits()
* Throws if q is unset
*/
size_t q_bits() const;
/**
* Return the size of q in bytes
* Same as get_q().bytes()
* Throws if q is unset
*/
size_t q_bytes() const;
/**
* Return size in bits of a secret exponent
*
* This attempts to balance between the attack costs of NFS
* (which depends on the size of the modulus) and Pollard's rho
* (which depends on the size of the exponent).
*
* It may vary over time for a particular group, if the attack
* costs change.
*/
size_t exponent_bits() const;
/**
* Return an estimate of the strength of this group against
* discrete logarithm attacks (eg NFS). Warning: since this only
* takes into account known attacks it is by necessity an
* overestimate of the actual strength.
*/
size_t estimated_strength() const;
/**
* Decode a DER/BER encoded group into this instance.
* @param ber a vector containing the DER/BER encoded group
* @param format the format of the encoded group
*
* @warning avoid this. Instead use the DL_Group constructor
*/
void BER_decode(const std::vector<uint8_t>& ber, Format format);
/**
* Decode a PEM encoded group into this instance.
* @param pem the PEM encoding of the group
*/
void BOTAN_DEPRECATED("Use DL_Group_from_PEM") PEM_decode(const std::string& pem);
DL_Group_Source source() const;
/**
* Return PEM representation of named DL group
*/
static std::string BOTAN_DEPRECATED("Use DL_Group(name).PEM_encode()")
PEM_for_named_group(const std::string& name);
/*
* For internal use only
*/
static std::shared_ptr<DL_Group_Data> DL_group_info(const std::string& name);
private:
static std::shared_ptr<DL_Group_Data> load_DL_group_info(const char* p_str,
const char* q_str,
const char* g_str);
static std::shared_ptr<DL_Group_Data> load_DL_group_info(const char* p_str,
const char* g_str);
static std::shared_ptr<DL_Group_Data>
BER_decode_DL_group(const uint8_t data[], size_t data_len,
DL_Group::Format format,
DL_Group_Source source);
const DL_Group_Data& data() const;
std::shared_ptr<DL_Group_Data> m_data;
};
}
#endif

View file

@ -0,0 +1,163 @@
/*
* DLIES
* (C) 1999-2007 Jack Lloyd
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DLIES_H_
#define BOTAN_DLIES_H_
#include <botan/pubkey.h>
#include <botan/mac.h>
#include <botan/kdf.h>
#include <botan/dh.h>
#include <botan/cipher_mode.h>
namespace Botan {
/**
* DLIES Encryption
*/
class BOTAN_PUBLIC_API(2,0) DLIES_Encryptor final : public PK_Encryptor
{
public:
/**
* Stream mode: use KDF to provide a stream of bytes to xor with the message
*
* @param own_priv_key own (ephemeral) DH private key
* @param rng the RNG to use
* @param kdf the KDF that should be used
* @param mac the MAC function that should be used
* @param mac_key_len key length of the MAC function. Default = 20 bytes
*
* output = (ephemeral) public key + ciphertext + tag
*/
DLIES_Encryptor(const DH_PrivateKey& own_priv_key,
RandomNumberGenerator& rng,
KDF* kdf,
MessageAuthenticationCode* mac,
size_t mac_key_len = 20);
/**
* Block cipher mode
*
* @param own_priv_key own (ephemeral) DH private key
* @param rng the RNG to use
* @param kdf the KDF that should be used
* @param cipher the block cipher that should be used
* @param cipher_key_len the key length of the block cipher
* @param mac the MAC function that should be used
* @param mac_key_len key length of the MAC function. Default = 20 bytes
*
* output = (ephemeral) public key + ciphertext + tag
*/
DLIES_Encryptor(const DH_PrivateKey& own_priv_key,
RandomNumberGenerator& rng,
KDF* kdf,
Cipher_Mode* cipher,
size_t cipher_key_len,
MessageAuthenticationCode* mac,
size_t mac_key_len = 20);
// Set the other parties public key
inline void set_other_key(const std::vector<uint8_t>& other_pub_key)
{
m_other_pub_key = other_pub_key;
}
/// Set the initialization vector for the data encryption method
inline void set_initialization_vector(const InitializationVector& iv)
{
m_iv = iv;
}
private:
std::vector<uint8_t> enc(const uint8_t[], size_t,
RandomNumberGenerator&) const override;
size_t maximum_input_size() const override;
size_t ciphertext_length(size_t ptext_len) const override;
std::vector<uint8_t> m_other_pub_key;
std::vector<uint8_t> m_own_pub_key;
PK_Key_Agreement m_ka;
std::unique_ptr<KDF> m_kdf;
std::unique_ptr<Cipher_Mode> m_cipher;
const size_t m_cipher_key_len;
std::unique_ptr<MessageAuthenticationCode> m_mac;
const size_t m_mac_keylen;
InitializationVector m_iv;
};
/**
* DLIES Decryption
*/
class BOTAN_PUBLIC_API(2,0) DLIES_Decryptor final : public PK_Decryptor
{
public:
/**
* Stream mode: use KDF to provide a stream of bytes to xor with the message
*
* @param own_priv_key own (ephemeral) DH private key
* @param rng the RNG to use
* @param kdf the KDF that should be used
* @param mac the MAC function that should be used
* @param mac_key_len key length of the MAC function. Default = 20 bytes
*
* input = (ephemeral) public key + ciphertext + tag
*/
DLIES_Decryptor(const DH_PrivateKey& own_priv_key,
RandomNumberGenerator& rng,
KDF* kdf,
MessageAuthenticationCode* mac,
size_t mac_key_len = 20);
/**
* Block cipher mode
*
* @param own_priv_key own (ephemeral) DH private key
* @param rng the RNG to use
* @param kdf the KDF that should be used
* @param cipher the block cipher that should be used
* @param cipher_key_len the key length of the block cipher
* @param mac the MAC function that should be used
* @param mac_key_len key length of the MAC function. Default = 20 bytes
*
* input = (ephemeral) public key + ciphertext + tag
*/
DLIES_Decryptor(const DH_PrivateKey& own_priv_key,
RandomNumberGenerator& rng,
KDF* kdf,
Cipher_Mode* cipher,
size_t cipher_key_len,
MessageAuthenticationCode* mac,
size_t mac_key_len = 20);
/// Set the initialization vector for the data decryption method
inline void set_initialization_vector(const InitializationVector& iv)
{
m_iv = iv;
}
private:
secure_vector<uint8_t> do_decrypt(uint8_t& valid_mask,
const uint8_t in[], size_t in_len) const override;
size_t plaintext_length(size_t ctext_len) const override;
const size_t m_pub_key_size;
PK_Key_Agreement m_ka;
std::unique_ptr<KDF> m_kdf;
std::unique_ptr<Cipher_Mode> m_cipher;
const size_t m_cipher_key_len;
std::unique_ptr<MessageAuthenticationCode> m_mac;
const size_t m_mac_keylen;
InitializationVector m_iv;
};
}
#endif

View file

@ -0,0 +1,87 @@
/*
* DSA
* (C) 1999-2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DSA_H_
#define BOTAN_DSA_H_
#include <botan/dl_algo.h>
namespace Botan {
/**
* DSA Public Key
*/
class BOTAN_PUBLIC_API(2,0) DSA_PublicKey : public virtual DL_Scheme_PublicKey
{
public:
std::string algo_name() const override { return "DSA"; }
DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_57; }
size_t message_parts() const override { return 2; }
size_t message_part_size() const override { return group_q().bytes(); }
/**
* Load a public key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
*/
DSA_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits) :
DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_57)
{
}
/**
* Create a public key.
* @param group the underlying DL group
* @param y the public value y = g^x mod p
*/
DSA_PublicKey(const DL_Group& group, const BigInt& y);
std::unique_ptr<PK_Ops::Verification>
create_verification_op(const std::string& params,
const std::string& provider) const override;
protected:
DSA_PublicKey() = default;
};
/**
* DSA Private Key
*/
class BOTAN_PUBLIC_API(2,0) DSA_PrivateKey final : public DSA_PublicKey,
public virtual DL_Scheme_PrivateKey
{
public:
/**
* Load a private key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded key bits in ANSI X9.57 format
*/
DSA_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits);
/**
* Create a private key.
* @param rng the RNG to use
* @param group the underlying DL group
* @param private_key the private key (if zero, a new random key is generated)
*/
DSA_PrivateKey(RandomNumberGenerator& rng,
const DL_Group& group,
const BigInt& private_key = 0);
bool check_key(RandomNumberGenerator& rng, bool strong) const override;
std::unique_ptr<PK_Ops::Signature>
create_signature_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
};
}
#endif

View file

@ -0,0 +1,68 @@
/*
* Dynamically Loaded Object
* (C) 2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_DYNAMIC_LOADER_H_
#define BOTAN_DYNAMIC_LOADER_H_
#include <botan/types.h>
#include <string>
namespace Botan {
/**
* Represents a DLL or shared object
*/
class BOTAN_PUBLIC_API(2,0) Dynamically_Loaded_Library final
{
public:
/**
* Load a DLL (or fail with an exception)
* @param lib_name name or path to a library
*
* If you don't use a full path, the search order will be defined
* by whatever the system linker does by default. Always using fully
* qualified pathnames can help prevent code injection attacks (eg
* via manipulation of LD_LIBRARY_PATH on Linux)
*/
Dynamically_Loaded_Library(const std::string& lib_name);
/**
* Unload the DLL
* @warning Any pointers returned by resolve()/resolve_symbol()
* should not be used after this destructor runs.
*/
~Dynamically_Loaded_Library();
/**
* Load a symbol (or fail with an exception)
* @param symbol names the symbol to load
* @return address of the loaded symbol
*/
void* resolve_symbol(const std::string& symbol);
/**
* Convenience function for casting symbol to the right type
* @param symbol names the symbol to load
* @return address of the loaded symbol
*/
template<typename T>
T resolve(const std::string& symbol)
{
return reinterpret_cast<T>(resolve_symbol(symbol));
}
private:
Dynamically_Loaded_Library(const Dynamically_Loaded_Library&);
Dynamically_Loaded_Library& operator=(const Dynamically_Loaded_Library&);
std::string m_lib_name;
void* m_lib;
};
}
#endif

View file

@ -0,0 +1,119 @@
/*
* EAX Mode
* (C) 1999-2007,2013 Jack Lloyd
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_AEAD_EAX_H_
#define BOTAN_AEAD_EAX_H_
#include <botan/aead.h>
#include <botan/block_cipher.h>
#include <botan/stream_cipher.h>
#include <botan/mac.h>
BOTAN_FUTURE_INTERNAL_HEADER(eax.h)
namespace Botan {
/**
* EAX base class
*/
class BOTAN_PUBLIC_API(2,0) EAX_Mode : public AEAD_Mode
{
public:
void set_associated_data(const uint8_t ad[], size_t ad_len) override;
std::string name() const override;
size_t update_granularity() const override;
Key_Length_Specification key_spec() const override;
// EAX supports arbitrary nonce lengths
bool valid_nonce_length(size_t) const override { return true; }
size_t tag_size() const override { return m_tag_size; }
void clear() override;
void reset() override;
protected:
/**
* @param cipher the cipher to use
* @param tag_size is how big the auth tag will be
*/
EAX_Mode(BlockCipher* cipher, size_t tag_size);
size_t block_size() const { return m_cipher->block_size(); }
size_t m_tag_size;
std::unique_ptr<BlockCipher> m_cipher;
std::unique_ptr<StreamCipher> m_ctr;
std::unique_ptr<MessageAuthenticationCode> m_cmac;
secure_vector<uint8_t> m_ad_mac;
secure_vector<uint8_t> m_nonce_mac;
private:
void start_msg(const uint8_t nonce[], size_t nonce_len) override;
void key_schedule(const uint8_t key[], size_t length) override;
};
/**
* EAX Encryption
*/
class BOTAN_PUBLIC_API(2,0) EAX_Encryption final : public EAX_Mode
{
public:
/**
* @param cipher a 128-bit block cipher
* @param tag_size is how big the auth tag will be
*/
EAX_Encryption(BlockCipher* cipher, size_t tag_size = 0) :
EAX_Mode(cipher, tag_size) {}
size_t output_length(size_t input_length) const override
{ return input_length + tag_size(); }
size_t minimum_final_size() const override { return 0; }
size_t process(uint8_t buf[], size_t size) override;
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
};
/**
* EAX Decryption
*/
class BOTAN_PUBLIC_API(2,0) EAX_Decryption final : public EAX_Mode
{
public:
/**
* @param cipher a 128-bit block cipher
* @param tag_size is how big the auth tag will be
*/
EAX_Decryption(BlockCipher* cipher, size_t tag_size = 0) :
EAX_Mode(cipher, tag_size) {}
size_t output_length(size_t input_length) const override
{
BOTAN_ASSERT(input_length >= tag_size(), "Sufficient input");
return input_length - tag_size();
}
size_t minimum_final_size() const override { return tag_size(); }
size_t process(uint8_t buf[], size_t size) override;
void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override;
};
}
#endif

View file

@ -0,0 +1,398 @@
/*
* ECC Domain Parameters
*
* (C) 2007 Falko Strenzke, FlexSecure GmbH
* 2008-2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ECC_DOMAIN_PARAMETERS_H_
#define BOTAN_ECC_DOMAIN_PARAMETERS_H_
#include <botan/point_gfp.h>
#include <botan/asn1_obj.h>
#include <memory>
#include <set>
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
};
enum class EC_Group_Source {
Builtin,
ExternalSource,
};
class CurveGFp;
class EC_Group_Data;
class EC_Group_Data_Map;
/**
* Class representing an elliptic curve
*
* The internal representation is stored in a shared_ptr, so copying an
* EC_Group is inexpensive.
*/
class BOTAN_PUBLIC_API(2,0) EC_Group final
{
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
*/
BOTAN_DEPRECATED("Use version taking all BigInts")
EC_Group(const CurveGFp& curve,
const PointGFp& base_point,
const BigInt& order,
const BigInt& cofactor) :
EC_Group(curve.get_p(),
curve.get_a(),
curve.get_b(),
base_point.get_affine_x(),
base_point.get_affine_y(),
order,
cofactor) {}
/**
* Construct Domain paramers from specified parameters
* @param p the elliptic curve p
* @param a the elliptic curve a param
* @param b the elliptic curve b param
* @param base_x the x coordinate of the base point
* @param base_y the y coordinate of the base point
* @param order the order of the base point
* @param cofactor the cofactor
* @param oid an optional OID used to identify this curve
*/
EC_Group(const BigInt& p,
const BigInt& a,
const BigInt& b,
const BigInt& base_x,
const BigInt& base_y,
const BigInt& order,
const BigInt& cofactor,
const OID& oid = OID());
/**
* Decode a BER encoded ECC domain parameter set
* @param ber the bytes of the BER encoding
* @param ber_len the length of ber
*/
explicit EC_Group(const uint8_t ber[], size_t ber_len);
template<typename Alloc>
EC_Group(const std::vector<uint8_t, Alloc>& ber) :
EC_Group(ber.data(), ber.size()) {}
/**
* Create an EC domain by OID (or throw if unknown)
* @param oid the OID of the EC domain to create
*/
explicit EC_Group(const OID& oid);
/**
* Create an EC domain from PEM encoding (as from PEM_encode), or
* from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7")
* @param pem_or_oid PEM-encoded data, or an OID
* @warning Support for PEM in this function is deprecated. Use
* EC_Group_from_PEM
*/
explicit EC_Group(const std::string& pem_or_oid);
static EC_Group EC_Group_from_PEM(const std::string& pem);
/**
* Create an uninitialized EC_Group
*/
EC_Group();
~EC_Group();
EC_Group(const EC_Group&) = default;
EC_Group(EC_Group&&) = default;
EC_Group& operator=(const EC_Group&) = default;
EC_Group& operator=(EC_Group&&) = default;
/**
* Create the DER encoding of this domain
* @param form of encoding to use
* @returns bytes encododed as DER
*/
std::vector<uint8_t> 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
*/
BOTAN_DEPRECATED("Avoid CurveGFp") const CurveGFp& get_curve() const;
/**
* Return if a == -3 mod p
*/
bool a_is_minus_3() const;
/**
* Return if a == 0 mod p
*/
bool a_is_zero() const;
/**
* Return the size of p in bits (same as get_p().bits())
*/
size_t get_p_bits() const;
/**
* Return the size of p in bits (same as get_p().bytes())
*/
size_t get_p_bytes() const;
/**
* Return the size of group order in bits (same as get_order().bits())
*/
size_t get_order_bits() const;
/**
* Return the size of p in bytes (same as get_order().bytes())
*/
size_t get_order_bytes() const;
/**
* Return the prime modulus of the field
*/
const BigInt& get_p() const;
/**
* Return the a parameter of the elliptic curve equation
*/
const BigInt& get_a() const;
/**
* Return the b parameter of the elliptic curve equation
*/
const BigInt& get_b() const;
/**
* Return group base point
* @result base point
*/
const PointGFp& get_base_point() const;
/**
* Return the x coordinate of the base point
*/
const BigInt& get_g_x() const;
/**
* Return the y coordinate of the base point
*/
const BigInt& get_g_y() const;
/**
* Return the order of the base point
* @result order of the base point
*/
const BigInt& get_order() const;
/*
* Reduce x modulo the order
*/
BigInt mod_order(const BigInt& x) const;
/*
* Return inverse of x modulo the order
*/
BigInt inverse_mod_order(const BigInt& x) const;
/*
* Reduce (x*x) modulo the order
*/
BigInt square_mod_order(const BigInt& x) const;
/*
* Reduce (x*y) modulo the order
*/
BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const;
/*
* Reduce (x*y*z) modulo the order
*/
BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const;
/**
* Return the cofactor
* @result the cofactor
*/
const BigInt& get_cofactor() const;
/**
* Check if y is a plausible point on the curve
*
* In particular, checks that it is a point on the curve, not infinity,
* and that it has order matching the group.
*/
bool verify_public_element(const PointGFp& y) const;
/**
* Return the OID of these domain parameters
* @result the OID as a string
*/
std::string BOTAN_DEPRECATED("Use get_curve_oid") get_oid() const { return get_curve_oid().to_string(); }
/**
* Return the OID of these domain parameters
* @result the OID
*/
const OID& get_curve_oid() const;
/**
* Return a point on this curve with the affine values x, y
*/
PointGFp point(const BigInt& x, const BigInt& y) const;
/**
* Multi exponentiate. Not constant time.
* @return base_point*x + pt*y
*/
PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const;
/**
* Blinded point multiplication, attempts resistance to side channels
* @param k the scalar
* @param rng a random number generator
* @param ws a temp workspace
* @return base_point*k
*/
PointGFp blinded_base_point_multiply(const BigInt& k,
RandomNumberGenerator& rng,
std::vector<BigInt>& ws) const;
/**
* Blinded point multiplication, attempts resistance to side channels
* Returns just the x coordinate of the point
*
* @param k the scalar
* @param rng a random number generator
* @param ws a temp workspace
* @return x coordinate of base_point*k
*/
BigInt blinded_base_point_multiply_x(const BigInt& k,
RandomNumberGenerator& rng,
std::vector<BigInt>& ws) const;
/**
* Blinded point multiplication, attempts resistance to side channels
* @param point input point
* @param k the scalar
* @param rng a random number generator
* @param ws a temp workspace
* @return point*k
*/
PointGFp blinded_var_point_multiply(const PointGFp& point,
const BigInt& k,
RandomNumberGenerator& rng,
std::vector<BigInt>& ws) const;
/**
* Return a random scalar ie an integer in [1,order)
*/
BigInt random_scalar(RandomNumberGenerator& rng) const;
/**
* Return the zero (or infinite) point on this curve
*/
PointGFp zero_point() const;
size_t point_size(PointGFp::Compression_Type format) const;
PointGFp OS2ECP(const uint8_t bits[], size_t len) const;
template<typename Alloc>
PointGFp OS2ECP(const std::vector<uint8_t, Alloc>& vec) const
{
return this->OS2ECP(vec.data(), vec.size());
}
bool initialized() const { return (m_data != nullptr); }
/**
* Verify EC_Group domain
* @returns true if group is valid. false otherwise
*/
bool verify_group(RandomNumberGenerator& rng,
bool strong = false) const;
bool operator==(const EC_Group& other) const;
EC_Group_Source source() const;
/**
* Return PEM representation of named EC group
* Deprecated: Use EC_Group(name).PEM_encode() if this is needed
*/
static std::string BOTAN_DEPRECATED("See header comment") PEM_for_named_group(const std::string& name);
/**
* Return a set of known named EC groups
*/
static const std::set<std::string>& known_named_groups();
/*
* For internal use only
*/
static std::shared_ptr<EC_Group_Data> EC_group_info(const OID& oid);
static size_t clear_registered_curve_data();
private:
static EC_Group_Data_Map& ec_group_data();
static std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t len,
EC_Group_Source source);
static std::shared_ptr<EC_Group_Data>
load_EC_group_info(const char* p,
const char* a,
const char* b,
const char* g_x,
const char* g_y,
const char* order,
const OID& oid);
// Member data
const EC_Group_Data& data() const;
std::shared_ptr<EC_Group_Data> m_data;
};
inline bool operator!=(const EC_Group& lhs,
const EC_Group& rhs)
{
return !(lhs == rhs);
}
// For compatibility with 1.8
typedef EC_Group EC_Domain_Params;
}
#endif

View file

@ -0,0 +1,172 @@
/*
* ECDSA
* (C) 2007 Falko Strenzke, FlexSecure GmbH
* Manuel Hartl, FlexSecure GmbH
* (C) 2008-2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ECC_PUBLIC_KEY_BASE_H_
#define BOTAN_ECC_PUBLIC_KEY_BASE_H_
#include <botan/ec_group.h>
#include <botan/pk_keys.h>
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_PUBLIC_API(2,0) EC_PublicKey : public virtual Public_Key
{
public:
/**
* Create a public key.
* @param dom_par EC domain parameters
* @param pub_point public point on the curve
*/
EC_PublicKey(const EC_Group& dom_par,
const PointGFp& pub_point);
/**
* Load a public key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
*/
EC_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits);
EC_PublicKey(const EC_PublicKey& other) = default;
EC_PublicKey& operator=(const EC_PublicKey& other) = default;
virtual ~EC_PublicKey() = default;
/**
* 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 m_public_key; }
AlgorithmIdentifier algorithm_identifier() const override;
std::vector<uint8_t> public_key_bits() const override;
bool check_key(RandomNumberGenerator& rng,
bool strong) const override;
/**
* 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 m_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);
/**
* Set the point encoding method to be used when encoding this key.
* @param enc the encoding to use
*/
void set_point_encoding(PointGFp::Compression_Type enc);
/**
* Return the DER encoding of this keys domain in whatever format
* is preset for this particular key
*/
std::vector<uint8_t> 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 m_domain_encoding; }
/**
* Get the point encoding method to be used when encoding this key.
* @result the encoding to use
*/
PointGFp::Compression_Type point_encoding() const
{ return m_point_encoding; }
size_t key_length() const override;
size_t estimated_strength() const override;
protected:
EC_PublicKey() : m_domain_params{}, m_public_key{}, m_domain_encoding(EC_DOMPAR_ENC_EXPLICIT)
{}
EC_Group m_domain_params;
PointGFp m_public_key;
EC_Group_Encoding m_domain_encoding;
PointGFp::Compression_Type m_point_encoding = PointGFp::UNCOMPRESSED;
};
/**
* This abstract class represents ECC private keys
*/
class BOTAN_PUBLIC_API(2,0) EC_PrivateKey : public virtual EC_PublicKey,
public virtual Private_Key
{
public:
/*
* If x=0, creates a new private key in the domain
* using the given rng. If with_modular_inverse is set,
* the public key will be calculated by multiplying
* the base point with the modular inverse of
* x (as in ECGDSA and ECKCDSA), otherwise by
* multiplying directly with x (as in ECDSA).
*/
EC_PrivateKey(RandomNumberGenerator& rng,
const EC_Group& domain,
const BigInt& x,
bool with_modular_inverse=false);
/*
* Creates a new private key object from the
* ECPrivateKey structure given in key_bits.
* If with_modular_inverse is set,
* the public key will be calculated by multiplying
* the base point with the modular inverse of
* x (as in ECGDSA and ECKCDSA), otherwise by
* multiplying directly with x (as in ECDSA).
*/
EC_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits,
bool with_modular_inverse=false);
secure_vector<uint8_t> private_key_bits() const override;
/**
* Get the private key value of this key object.
* @result the private key value of this key object
*/
const BigInt& private_value() const;
EC_PrivateKey(const EC_PrivateKey& other) = default;
EC_PrivateKey& operator=(const EC_PrivateKey& other) = default;
~EC_PrivateKey() = default;
protected:
EC_PrivateKey() = default;
BigInt m_private_key;
};
}
#endif

View file

@ -0,0 +1,106 @@
/*
* ECDH
* (C) 2007 Falko Strenzke, FlexSecure GmbH
* Manuel Hartl, FlexSecure GmbH
* (C) 2008-2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ECDH_KEY_H_
#define BOTAN_ECDH_KEY_H_
#include <botan/ecc_key.h>
namespace Botan {
/**
* This class represents ECDH Public Keys.
*/
class BOTAN_PUBLIC_API(2,0) ECDH_PublicKey : public virtual EC_PublicKey
{
public:
/**
* Create an ECDH public key.
* @param alg_id algorithm identifier
* @param key_bits DER encoded public key bits
*/
ECDH_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& 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 override { return "ECDH"; }
/**
* @return public point value
*/
std::vector<uint8_t> public_value() const
{ return public_point().encode(PointGFp::UNCOMPRESSED); }
/**
* @return public point value
*/
std::vector<uint8_t> public_value(PointGFp::Compression_Type format) const
{ return public_point().encode(format); }
protected:
ECDH_PublicKey() = default;
};
/**
* This class represents ECDH Private Keys.
*/
class BOTAN_PUBLIC_API(2,0) ECDH_PrivateKey final : public ECDH_PublicKey,
public EC_PrivateKey,
public PK_Key_Agreement_Key
{
public:
/**
* Load a private key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits ECPrivateKey bits
*/
ECDH_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& 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) {}
std::vector<uint8_t> public_value() const override
{ return ECDH_PublicKey::public_value(PointGFp::UNCOMPRESSED); }
std::vector<uint8_t> public_value(PointGFp::Compression_Type type) const
{ return ECDH_PublicKey::public_value(type); }
std::unique_ptr<PK_Ops::Key_Agreement>
create_key_agreement_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
};
}
#endif

View file

@ -0,0 +1,117 @@
/*
* ECDSA
* (C) 2007 Falko Strenzke, FlexSecure GmbH
* Manuel Hartl, FlexSecure GmbH
* (C) 2008-2010 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ECDSA_KEY_H_
#define BOTAN_ECDSA_KEY_H_
#include <botan/ecc_key.h>
namespace Botan {
/**
* This class represents ECDSA Public Keys.
*/
class BOTAN_PUBLIC_API(2,0) ECDSA_PublicKey : public virtual EC_PublicKey
{
public:
/**
* Create 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) {}
/**
* Load a public key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
*/
ECDSA_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits) :
EC_PublicKey(alg_id, key_bits) {}
/**
* Recover a public key from a signature/msg pair
* See SEC section 4.6.1
* @param group the elliptic curve group
* @param msg the message
* @param r the r paramter of the signature
* @param s the s paramter of the signature
* @param v the recovery ID
*/
ECDSA_PublicKey(const EC_Group& group,
const std::vector<uint8_t>& msg,
const BigInt& r,
const BigInt& s,
uint8_t v);
/**
* Get this keys algorithm name.
* @result this keys algorithm name ("ECDSA")
*/
std::string algo_name() const override { return "ECDSA"; }
size_t message_parts() const override { return 2; }
size_t message_part_size() const override
{ return domain().get_order().bytes(); }
uint8_t recovery_param(const std::vector<uint8_t>& msg,
const BigInt& r,
const BigInt& s) const;
std::unique_ptr<PK_Ops::Verification>
create_verification_op(const std::string& params,
const std::string& provider) const override;
protected:
ECDSA_PublicKey() = default;
};
/**
* This class represents ECDSA Private Keys
*/
class BOTAN_PUBLIC_API(2,0) ECDSA_PrivateKey final : public ECDSA_PublicKey,
public EC_PrivateKey
{
public:
/**
* Load a private key
* @param alg_id the X.509 algorithm identifier
* @param key_bits ECPrivateKey bits
*/
ECDSA_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits) :
EC_PrivateKey(alg_id, key_bits) {}
/**
* Create a 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 new 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 override;
std::unique_ptr<PK_Ops::Signature>
create_signature_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
};
}
#endif

View file

@ -0,0 +1,96 @@
/*
* ECGDSA (BSI-TR-03111, version 2.0)
* (C) 2016 René Korthaus
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ECGDSA_KEY_H_
#define BOTAN_ECGDSA_KEY_H_
#include <botan/ecc_key.h>
namespace Botan {
/**
* This class represents ECGDSA public keys.
*/
class BOTAN_PUBLIC_API(2,0) ECGDSA_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
*/
ECGDSA_PublicKey(const EC_Group& dom_par,
const PointGFp& public_point) :
EC_PublicKey(dom_par, public_point) {}
/**
* Load a public key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
*/
ECGDSA_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits) :
EC_PublicKey(alg_id, key_bits) {}
/**
* Get this keys algorithm name.
* @result this keys algorithm name ("ECGDSA")
*/
std::string algo_name() const override { return "ECGDSA"; }
size_t message_parts() const override { return 2; }
size_t message_part_size() const override
{ return domain().get_order().bytes(); }
std::unique_ptr<PK_Ops::Verification>
create_verification_op(const std::string& params,
const std::string& provider) const override;
protected:
ECGDSA_PublicKey() = default;
};
/**
* This class represents ECGDSA private keys.
*/
class BOTAN_PUBLIC_API(2,0) ECGDSA_PrivateKey final : public ECGDSA_PublicKey,
public EC_PrivateKey
{
public:
/**
* Load a private key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits ECPrivateKey bits
*/
ECGDSA_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits) :
EC_PrivateKey(alg_id, key_bits, true) {}
/**
* 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 new random key)
*/
ECGDSA_PrivateKey(RandomNumberGenerator& rng,
const EC_Group& domain,
const BigInt& x = 0) :
EC_PrivateKey(rng, domain, x, true) {}
bool check_key(RandomNumberGenerator& rng, bool) const override;
std::unique_ptr<PK_Ops::Signature>
create_signature_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
};
}
#endif

View file

@ -0,0 +1,314 @@
/*
* ECIES
* (C) 2016 Philipp Weber
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ECIES_H_
#define BOTAN_ECIES_H_
#include <botan/ecdh.h>
#include <botan/ec_group.h>
#include <botan/cipher_mode.h>
#include <botan/point_gfp.h>
#include <botan/pubkey.h>
#include <botan/secmem.h>
#include <botan/symkey.h>
#include <botan/mac.h>
#include <memory>
#include <string>
#include <vector>
namespace Botan {
class RandomNumberGenerator;
enum class ECIES_Flags : uint32_t
{
NONE = 0,
/// if set: prefix the input of the (ecdh) key agreement with the encoded (ephemeral) public key
SINGLE_HASH_MODE = 1,
/// (decryption only) if set: use cofactor multiplication during (ecdh) key agreement
COFACTOR_MODE = 2,
/// if set: use ecdhc instead of ecdh
OLD_COFACTOR_MODE = 4,
/// (decryption only) if set: test if the (ephemeral) public key is on the curve
CHECK_MODE = 8
};
inline ECIES_Flags operator |(ECIES_Flags a, ECIES_Flags b)
{
return static_cast<ECIES_Flags>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
}
inline ECIES_Flags operator &(ECIES_Flags a, ECIES_Flags b)
{
return static_cast<ECIES_Flags>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
}
/**
* Parameters for ECIES secret derivation
*/
class BOTAN_PUBLIC_API(2,0) ECIES_KA_Params
{
public:
/**
* @param domain ec domain parameters of the involved ec keys
* @param kdf_spec name of the key derivation function
* @param length length of the secret to be derived
* @param compression_type format of encoded keys (affects the secret derivation if single_hash_mode is used)
* @param flags options, see documentation of ECIES_Flags
*/
ECIES_KA_Params(const EC_Group& domain, const std::string& kdf_spec, size_t length,
PointGFp::Compression_Type compression_type, ECIES_Flags flags);
ECIES_KA_Params(const ECIES_KA_Params&) = default;
ECIES_KA_Params& operator=(const ECIES_KA_Params&) = delete;
virtual ~ECIES_KA_Params() = default;
inline const EC_Group& domain() const
{
return m_domain;
}
inline size_t secret_length() const
{
return m_length;
}
inline bool single_hash_mode() const
{
return (m_flags & ECIES_Flags::SINGLE_HASH_MODE) == ECIES_Flags::SINGLE_HASH_MODE;
}
inline bool cofactor_mode() const
{
return (m_flags & ECIES_Flags::COFACTOR_MODE) == ECIES_Flags::COFACTOR_MODE;
}
inline bool old_cofactor_mode() const
{
return (m_flags & ECIES_Flags::OLD_COFACTOR_MODE) == ECIES_Flags::OLD_COFACTOR_MODE;
}
inline bool check_mode() const
{
return (m_flags & ECIES_Flags::CHECK_MODE) == ECIES_Flags::CHECK_MODE;
}
inline PointGFp::Compression_Type compression_type() const
{
return m_compression_mode;
}
const std::string& kdf_spec() const
{
return m_kdf_spec;
}
private:
const EC_Group m_domain;
const std::string m_kdf_spec;
const size_t m_length;
const PointGFp::Compression_Type m_compression_mode;
const ECIES_Flags m_flags;
};
class BOTAN_PUBLIC_API(2,0) ECIES_System_Params final : public ECIES_KA_Params
{
public:
/**
* @param domain ec domain parameters of the involved ec keys
* @param kdf_spec name of the key derivation function
* @param dem_algo_spec name of the data encryption method
* @param dem_key_len length of the key used for the data encryption method
* @param mac_spec name of the message authentication code
* @param mac_key_len length of the key used for the message authentication code
*/
ECIES_System_Params(const EC_Group& domain, const std::string& kdf_spec, const std::string& dem_algo_spec,
size_t dem_key_len, const std::string& mac_spec, size_t mac_key_len);
/**
* @param domain ec domain parameters of the involved ec keys
* @param kdf_spec name of the key derivation function
* @param dem_algo_spec name of the data encryption method
* @param dem_key_len length of the key used for the data encryption method
* @param mac_spec name of the message authentication code
* @param mac_key_len length of the key used for the message authentication code
* @param compression_type format of encoded keys (affects the secret derivation if single_hash_mode is used)
* @param flags options, see documentation of ECIES_Flags
*/
ECIES_System_Params(const EC_Group& domain, const std::string& kdf_spec, const std::string& dem_algo_spec,
size_t dem_key_len, const std::string& mac_spec, size_t mac_key_len,
PointGFp::Compression_Type compression_type, ECIES_Flags flags);
ECIES_System_Params(const ECIES_System_Params&) = default;
ECIES_System_Params& operator=(const ECIES_System_Params&) = delete;
virtual ~ECIES_System_Params() = default;
/// creates an instance of the message authentication code
std::unique_ptr<MessageAuthenticationCode> create_mac() const;
/// creates an instance of the data encryption method
std::unique_ptr<Cipher_Mode> create_cipher(Botan::Cipher_Dir direction) const;
/// returns the length of the key used by the data encryption method
inline size_t dem_keylen() const
{
return m_dem_keylen;
}
/// returns the length of the key used by the message authentication code
inline size_t mac_keylen() const
{
return m_mac_keylen;
}
private:
const std::string m_dem_spec;
const size_t m_dem_keylen;
const std::string m_mac_spec;
const size_t m_mac_keylen;
};
/**
* ECIES secret derivation according to ISO 18033-2
*/
class BOTAN_PUBLIC_API(2,0) ECIES_KA_Operation
{
public:
/**
* @param private_key the (ephemeral) private key which is used to derive the secret
* @param ecies_params settings for ecies
* @param for_encryption disable cofactor mode if the secret will be used for encryption
* (according to ISO 18033 cofactor mode is only used during decryption)
* @param rng the RNG to use
*/
ECIES_KA_Operation(const PK_Key_Agreement_Key& private_key,
const ECIES_KA_Params& ecies_params,
bool for_encryption,
RandomNumberGenerator& rng);
/**
* Performs a key agreement with the provided keys and derives the secret from the result
* @param eph_public_key_bin the encoded (ephemeral) public key which belongs to the used (ephemeral) private key
* @param other_public_key_point public key point of the other party
*/
SymmetricKey derive_secret(const std::vector<uint8_t>& eph_public_key_bin,
const PointGFp& other_public_key_point) const;
private:
const PK_Key_Agreement m_ka;
const ECIES_KA_Params m_params;
};
/**
* ECIES Encryption according to ISO 18033-2
*/
class BOTAN_PUBLIC_API(2,0) ECIES_Encryptor final : public PK_Encryptor
{
public:
/**
* @param private_key the (ephemeral) private key which is used for the key agreement
* @param ecies_params settings for ecies
* @param rng random generator to use
*/
ECIES_Encryptor(const PK_Key_Agreement_Key& private_key,
const ECIES_System_Params& ecies_params,
RandomNumberGenerator& rng);
/**
* Creates an ephemeral private key which is used for the key agreement
* @param rng random generator used during private key generation
* @param ecies_params settings for ecies
*/
ECIES_Encryptor(RandomNumberGenerator& rng, const ECIES_System_Params& ecies_params);
/// Set the public key of the other party
inline void set_other_key(const Botan::PointGFp& public_point)
{
m_other_point = public_point;
}
/// Set the initialization vector for the data encryption method
inline void set_initialization_vector(const InitializationVector& iv)
{
m_iv = iv;
}
/// Set the label which is appended to the input for the message authentication code
inline void set_label(const std::string& label)
{
m_label = std::vector<uint8_t>(label.begin(), label.end());
}
private:
std::vector<uint8_t> enc(const uint8_t data[], size_t length, RandomNumberGenerator&) const override;
size_t maximum_input_size() const override;
size_t ciphertext_length(size_t ptext_len) const override;
const ECIES_KA_Operation m_ka;
const ECIES_System_Params m_params;
std::unique_ptr<MessageAuthenticationCode> m_mac;
std::unique_ptr<Cipher_Mode> m_cipher;
std::vector<uint8_t> m_eph_public_key_bin;
InitializationVector m_iv;
PointGFp m_other_point;
std::vector<uint8_t> m_label;
};
/**
* ECIES Decryption according to ISO 18033-2
*/
class BOTAN_PUBLIC_API(2,0) ECIES_Decryptor final : public PK_Decryptor
{
public:
/**
* @param private_key the private key which is used for the key agreement
* @param ecies_params settings for ecies
* @param rng the random generator to use
*/
ECIES_Decryptor(const PK_Key_Agreement_Key& private_key,
const ECIES_System_Params& ecies_params,
RandomNumberGenerator& rng);
/// Set the initialization vector for the data encryption method
inline void set_initialization_vector(const InitializationVector& iv)
{
m_iv = iv;
}
/// Set the label which is appended to the input for the message authentication code
inline void set_label(const std::string& label)
{
m_label = std::vector<uint8_t>(label.begin(), label.end());
}
private:
secure_vector<uint8_t> do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const override;
size_t plaintext_length(size_t ctext_len) const override;
const ECIES_KA_Operation m_ka;
const ECIES_System_Params m_params;
std::unique_ptr<MessageAuthenticationCode> m_mac;
std::unique_ptr<Cipher_Mode> m_cipher;
InitializationVector m_iv;
std::vector<uint8_t> m_label;
};
}
#endif

View file

@ -0,0 +1,96 @@
/*
* ECKCDSA (ISO/IEC 14888-3:2006/Cor.2:2009)
* (C) 2016 René Korthaus, Sirrix AG
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ECKCDSA_KEY_H_
#define BOTAN_ECKCDSA_KEY_H_
#include <botan/ecc_key.h>
namespace Botan {
/**
* This class represents ECKCDSA public keys.
*/
class BOTAN_PUBLIC_API(2,0) ECKCDSA_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
*/
ECKCDSA_PublicKey(const EC_Group& dom_par,
const PointGFp& public_point) :
EC_PublicKey(dom_par, public_point) {}
/**
* Load a public key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
*/
ECKCDSA_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits) :
EC_PublicKey(alg_id, key_bits) {}
/**
* Get this keys algorithm name.
* @result this keys algorithm name ("ECGDSA")
*/
std::string algo_name() const override { return "ECKCDSA"; }
size_t message_parts() const override { return 2; }
size_t message_part_size() const override
{ return domain().get_order().bytes(); }
std::unique_ptr<PK_Ops::Verification>
create_verification_op(const std::string& params,
const std::string& provider) const override;
protected:
ECKCDSA_PublicKey() = default;
};
/**
* This class represents ECKCDSA private keys.
*/
class BOTAN_PUBLIC_API(2,0) ECKCDSA_PrivateKey final : public ECKCDSA_PublicKey,
public EC_PrivateKey
{
public:
/**
* Load a private key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits ECPrivateKey bits
*/
ECKCDSA_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits) :
EC_PrivateKey(alg_id, key_bits, true) {}
/**
* Create a 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 new random key)
*/
ECKCDSA_PrivateKey(RandomNumberGenerator& rng,
const EC_Group& domain,
const BigInt& x = 0) :
EC_PrivateKey(rng, domain, x, true) {}
bool check_key(RandomNumberGenerator& rng, bool) const override;
std::unique_ptr<PK_Ops::Signature>
create_signature_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
};
}
#endif

View file

@ -0,0 +1,113 @@
/*
* Ed25519
* (C) 2017 Ribose Inc
*
* Based on the public domain code from SUPERCOP ref10 by
* Peter Schwabe, Daniel J. Bernstein, Niels Duif, Tanja Lange, Bo-Yin Yang
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ED25519_H_
#define BOTAN_ED25519_H_
#include <botan/pk_keys.h>
namespace Botan {
class BOTAN_PUBLIC_API(2,2) Ed25519_PublicKey : public virtual Public_Key
{
public:
std::string algo_name() const override { return "Ed25519"; }
size_t estimated_strength() const override { return 128; }
size_t key_length() const override { return 255; }
bool check_key(RandomNumberGenerator& rng, bool strong) const override;
AlgorithmIdentifier algorithm_identifier() const override;
std::vector<uint8_t> public_key_bits() const override;
/**
* Create a Ed25519 Public Key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
*/
Ed25519_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits);
template<typename Alloc>
Ed25519_PublicKey(const std::vector<uint8_t, Alloc>& pub) :
Ed25519_PublicKey(pub.data(), pub.size()) {}
Ed25519_PublicKey(const uint8_t pub_key[], size_t len);
std::unique_ptr<PK_Ops::Verification>
create_verification_op(const std::string& params,
const std::string& provider) const override;
const std::vector<uint8_t>& get_public_key() const { return m_public; }
protected:
Ed25519_PublicKey() = default;
std::vector<uint8_t> m_public;
};
class BOTAN_PUBLIC_API(2,2) Ed25519_PrivateKey final : public Ed25519_PublicKey,
public virtual Private_Key
{
public:
/**
* Construct a private key from the specified parameters.
* @param alg_id the X.509 algorithm identifier
* @param key_bits PKCS #8 structure
*/
Ed25519_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits);
/**
* Generate a private key.
* @param rng the RNG to use
*/
explicit Ed25519_PrivateKey(RandomNumberGenerator& rng);
/**
* Construct a private key from the specified parameters.
* @param secret_key the private key
*/
explicit Ed25519_PrivateKey(const secure_vector<uint8_t>& secret_key);
const secure_vector<uint8_t>& get_private_key() const { return m_private; }
secure_vector<uint8_t> private_key_bits() const override;
bool check_key(RandomNumberGenerator& rng, bool strong) const override;
std::unique_ptr<PK_Ops::Signature>
create_signature_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
private:
secure_vector<uint8_t> m_private;
};
void ed25519_gen_keypair(uint8_t pk[32], uint8_t sk[64], const uint8_t seed[32]);
void ed25519_sign(uint8_t sig[64],
const uint8_t msg[],
size_t msg_len,
const uint8_t sk[64],
const uint8_t domain_sep[], size_t domain_sep_len);
bool ed25519_verify(const uint8_t msg[],
size_t msg_len,
const uint8_t sig[64],
const uint8_t pk[32],
const uint8_t domain_sep[], size_t domain_sep_len);
}
#endif

View file

@ -0,0 +1,85 @@
/*
* ElGamal
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_ELGAMAL_H_
#define BOTAN_ELGAMAL_H_
#include <botan/dl_algo.h>
namespace Botan {
/**
* ElGamal Public Key
*/
class BOTAN_PUBLIC_API(2,0) ElGamal_PublicKey : public virtual DL_Scheme_PublicKey
{
public:
std::string algo_name() const override { return "ElGamal"; }
DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_42; }
/**
* Load a public key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded public key bits
*/
ElGamal_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits) :
DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_42)
{}
/**
* Create a public key.
* @param group the underlying DL group
* @param y the public value y = g^x mod p
*/
ElGamal_PublicKey(const DL_Group& group, const BigInt& y);
std::unique_ptr<PK_Ops::Encryption>
create_encryption_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
protected:
ElGamal_PublicKey() = default;
};
/**
* ElGamal Private Key
*/
class BOTAN_PUBLIC_API(2,0) ElGamal_PrivateKey final : public ElGamal_PublicKey,
public virtual DL_Scheme_PrivateKey
{
public:
bool check_key(RandomNumberGenerator& rng, bool) const override;
/**
* Load a private key.
* @param alg_id the X.509 algorithm identifier
* @param key_bits DER encoded key bits in ANSI X9.42 format
*/
ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<uint8_t>& key_bits);
/**
* Create a private key.
* @param rng random number generator to use
* @param group the group to be used in the key
* @param priv_key the key's secret value (or if zero, generate a new key)
*/
ElGamal_PrivateKey(RandomNumberGenerator& rng,
const DL_Group& group,
const BigInt& priv_key = 0);
std::unique_ptr<PK_Ops::Decryption>
create_decryption_op(RandomNumberGenerator& rng,
const std::string& params,
const std::string& provider) const override;
};
}
#endif

View file

@ -0,0 +1,94 @@
/*
* EME Classes
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_PUBKEY_EME_ENCRYPTION_PAD_H_
#define BOTAN_PUBKEY_EME_ENCRYPTION_PAD_H_
#include <botan/secmem.h>
#include <string>
BOTAN_FUTURE_INTERNAL_HEADER(eme.h)
namespace Botan {
class RandomNumberGenerator;
/**
* Encoding Method for Encryption
*/
class BOTAN_PUBLIC_API(2,0) EME
{
public:
virtual ~EME() = default;
/**
* 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
*/
secure_vector<uint8_t> encode(const uint8_t 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
*/
secure_vector<uint8_t> encode(const secure_vector<uint8_t>& in,
size_t key_length,
RandomNumberGenerator& rng) const;
/**
* Decode an input
* @param valid_mask written to specifies if output is valid
* @param in the encoded plaintext
* @param in_len length of encoded plaintext in bytes
* @return bytes of out[] written to along with
* validity mask (0xFF if valid, else 0x00)
*/
virtual secure_vector<uint8_t> unpad(uint8_t& valid_mask,
const uint8_t in[],
size_t in_len) 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
*/
virtual secure_vector<uint8_t> pad(const uint8_t in[],
size_t in_length,
size_t key_length,
RandomNumberGenerator& rng) const = 0;
};
/**
* 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_PUBLIC_API(2,0) EME* get_eme(const std::string& algo_spec);
}
#endif

View file

@ -0,0 +1,35 @@
/*
* EME PKCS#1 v1.5
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_EME_PKCS1_H_
#define BOTAN_EME_PKCS1_H_
#include <botan/eme.h>
BOTAN_FUTURE_INTERNAL_HEADER(eme_pkcs.h)
namespace Botan {
/**
* EME from PKCS #1 v1.5
*/
class BOTAN_PUBLIC_API(2,0) EME_PKCS1v15 final : public EME
{
public:
size_t maximum_input_size(size_t) const override;
secure_vector<uint8_t> pad(const uint8_t[], size_t, size_t,
RandomNumberGenerator&) const override;
secure_vector<uint8_t> unpad(uint8_t& valid_mask,
const uint8_t in[],
size_t in_len) const override;
};
}
#endif

View file

@ -0,0 +1,33 @@
/*
* (C) 2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_EME_RAW_H_
#define BOTAN_EME_RAW_H_
#include <botan/eme.h>
BOTAN_FUTURE_INTERNAL_HEADER(eme_raw.h)
namespace Botan {
class BOTAN_PUBLIC_API(2,0) EME_Raw final : public EME
{
public:
size_t maximum_input_size(size_t i) const override;
EME_Raw() = default;
private:
secure_vector<uint8_t> pad(const uint8_t[], size_t, size_t,
RandomNumberGenerator&) const override;
secure_vector<uint8_t> unpad(uint8_t& valid_mask,
const uint8_t in[],
size_t in_len) const override;
};
}
#endif

View file

@ -0,0 +1,107 @@
/*
* EMSA Classes
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_PUBKEY_EMSA_H_
#define BOTAN_PUBKEY_EMSA_H_
#include <botan/secmem.h>
#include <botan/asn1_obj.h>
#include <string>
BOTAN_FUTURE_INTERNAL_HEADER(emsa.h)
namespace Botan {
class Private_Key;
class RandomNumberGenerator;
/**
* EMSA, from IEEE 1363s Encoding Method for Signatures, Appendix
*
* Any way of encoding/padding signatures
*/
class BOTAN_PUBLIC_API(2,0) EMSA
{
public:
virtual ~EMSA() = default;
/**
* Add more data to the signature computation
* @param input some data
* @param length length of input in bytes
*/
virtual void update(const uint8_t input[], size_t length) = 0;
/**
* @return raw hash
*/
virtual secure_vector<uint8_t> 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 secure_vector<uint8_t> encoding_of(const secure_vector<uint8_t>& 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 secure_vector<uint8_t>& coded,
const secure_vector<uint8_t>& raw,
size_t key_bits) = 0;
/**
* Prepare sig_algo for use in choose_sig_format for x509 certs
*
* @param key used for checking compatibility with the encoding scheme
* @param cert_hash_name is checked to equal the hash for the encoding
* @return algorithm identifier to signatures created using this key,
* padding method and hash.
*/
virtual AlgorithmIdentifier config_for_x509(const Private_Key& key,
const std::string& cert_hash_name) const;
/**
* @return a new object representing the same encoding method as *this
*/
virtual EMSA* clone() = 0;
/**
* @return the SCAN name of the encoding/padding scheme
*/
virtual std::string name() const = 0;
};
/**
* Factory method for EMSA (message-encoding methods for signatures
* with appendix) objects
* @param algo_spec the name of the EMSA to create
* @return pointer to newly allocated object of that type
*/
BOTAN_PUBLIC_API(2,0) EMSA* get_emsa(const std::string& algo_spec);
/**
* Returns the hash function used in the given EMSA scheme
* If the hash function is not specified or not understood,
* returns "SHA-512"
* @param algo_spec the name of the EMSA
* @return hash function used in the given EMSA scheme
*/
BOTAN_PUBLIC_API(2,0) std::string hash_for_emsa(const std::string& algo_spec);
}
#endif

View file

@ -0,0 +1,55 @@
/*
* EMSA1
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_EMSA1_H_
#define BOTAN_EMSA1_H_
#include <botan/emsa.h>
#include <botan/hash.h>
BOTAN_FUTURE_INTERNAL_HEADER(emsa1.h)
namespace Botan {
/**
* EMSA1 from IEEE 1363
* Essentially, sign the hash directly
*/
class BOTAN_PUBLIC_API(2,0) EMSA1 final : public EMSA
{
public:
/**
* @param hash the hash function to use
*/
explicit EMSA1(HashFunction* hash) : m_hash(hash) {}
EMSA* clone() override;
std::string name() const override;
AlgorithmIdentifier config_for_x509(const Private_Key& key,
const std::string& cert_hash_name) const override;
private:
size_t hash_output_length() const { return m_hash->output_length(); }
void update(const uint8_t[], size_t) override;
secure_vector<uint8_t> raw_data() override;
secure_vector<uint8_t> encoding_of(const secure_vector<uint8_t>& msg,
size_t output_bits,
RandomNumberGenerator& rng) override;
bool verify(const secure_vector<uint8_t>& coded,
const secure_vector<uint8_t>& raw,
size_t key_bits) override;
std::unique_ptr<HashFunction> m_hash;
};
}
#endif

View file

@ -0,0 +1,94 @@
/*
* PKCS #1 v1.5 signature padding
* (C) 1999-2008 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_EMSA_PKCS1_H_
#define BOTAN_EMSA_PKCS1_H_
#include <botan/emsa.h>
#include <botan/hash.h>
BOTAN_FUTURE_INTERNAL_HEADER(emsa_pkcs1.h)
namespace Botan {
/**
* PKCS #1 v1.5 signature padding
* aka PKCS #1 block type 1
* aka EMSA3 from IEEE 1363
*/
class BOTAN_PUBLIC_API(2,0) EMSA_PKCS1v15 final : public EMSA
{
public:
/**
* @param hash the hash function to use
*/
explicit EMSA_PKCS1v15(HashFunction* hash);
EMSA* clone() override { return new EMSA_PKCS1v15(m_hash->clone()); }
void update(const uint8_t[], size_t) override;
secure_vector<uint8_t> raw_data() override;
secure_vector<uint8_t> encoding_of(const secure_vector<uint8_t>&, size_t,
RandomNumberGenerator& rng) override;
bool verify(const secure_vector<uint8_t>&, const secure_vector<uint8_t>&,
size_t) override;
std::string name() const override
{ return "EMSA3(" + m_hash->name() + ")"; }
AlgorithmIdentifier config_for_x509(const Private_Key& key,
const std::string& cert_hash_name) const override;
private:
std::unique_ptr<HashFunction> m_hash;
std::vector<uint8_t> m_hash_id;
};
/**
* EMSA_PKCS1v15_Raw which is EMSA_PKCS1v15 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_PUBLIC_API(2,0) EMSA_PKCS1v15_Raw final : public EMSA
{
public:
EMSA* clone() override { return new EMSA_PKCS1v15_Raw(); }
void update(const uint8_t[], size_t) override;
secure_vector<uint8_t> raw_data() override;
secure_vector<uint8_t> encoding_of(const secure_vector<uint8_t>&, size_t,
RandomNumberGenerator& rng) override;
bool verify(const secure_vector<uint8_t>&, const secure_vector<uint8_t>&,
size_t) override;
/**
* @param hash_algo if non-empty, the digest id for that hash is
* included in the signature.
*/
EMSA_PKCS1v15_Raw(const std::string& hash_algo = "");
std::string name() const override
{
if(m_hash_name.empty()) return "EMSA3(Raw)";
else return "EMSA3(Raw," + m_hash_name + ")";
}
private:
size_t m_hash_output_len = 0;
std::string m_hash_name;
std::vector<uint8_t> m_hash_id;
secure_vector<uint8_t> m_message;
};
}
#endif

Some files were not shown because too many files have changed in this diff Show more