diff options
author | Mouse <[email protected]> | 2015-10-20 11:25:13 -0400 |
---|---|---|
committer | Mouse <[email protected]> | 2015-10-20 11:25:13 -0400 |
commit | b81c246c9c741ef669a79749bc31795175a2a555 (patch) | |
tree | b1291dc5ad4fff2193551e597aa01203327ffb5a /src/lib | |
parent | 44e90e8cf98c7f132c88510b51492c8630fb092c (diff) | |
parent | 194d7d3682bddbd534e211357dd5f817d01ab7ed (diff) |
Merge pull request #2 from randombit/master
Update to match current Botan-1.11.22
Diffstat (limited to 'src/lib')
285 files changed, 5177 insertions, 3516 deletions
diff --git a/src/lib/alloc/info.txt b/src/lib/alloc/info.txt deleted file mode 100644 index 0ab7fa768..000000000 --- a/src/lib/alloc/info.txt +++ /dev/null @@ -1,3 +0,0 @@ -<header:public> -secmem.h -</header:public> diff --git a/src/lib/asn1/asn1_oid.cpp b/src/lib/asn1/asn1_oid.cpp index 21c2daafb..2fbc4b27c 100644 --- a/src/lib/asn1/asn1_oid.cpp +++ b/src/lib/asn1/asn1_oid.cpp @@ -54,7 +54,7 @@ std::string OID::as_string() const { oid_str += std::to_string(id[i]); if(i != id.size() - 1) - oid_str += '.'; + oid_str += "."; } return oid_str; } diff --git a/src/lib/asn1/asn1_time.cpp b/src/lib/asn1/asn1_time.cpp index b7cf589a2..a9dffa95c 100644 --- a/src/lib/asn1/asn1_time.cpp +++ b/src/lib/asn1/asn1_time.cpp @@ -234,13 +234,17 @@ bool X509_Time::passes_sanity_check() const if (m_tag == UTC_TIME) { - // UTCTime limits the value of components such that leap seconds are not covered. - // See "UNIVERSAL 23" in "Information technology – Abstract Syntax Notation One (ASN.1): Specification of basic notation" - // http://www.itu.int/ITU-T/studygroups/com17/languages/ + /* + UTCTime limits the value of components such that leap seconds + are not covered. See "UNIVERSAL 23" in "Information technology + Abstract Syntax Notation One (ASN.1): Specification of basic notation" + + http://www.itu.int/ITU-T/studygroups/com17/languages/ + */ if (m_hour > 23 || m_minute > 59 || m_second > 59) { return false; - } + } } return true; diff --git a/src/lib/asn1/ber_dec.cpp b/src/lib/asn1/ber_dec.cpp index 4267d79dc..80dfba3bb 100644 --- a/src/lib/asn1/ber_dec.cpp +++ b/src/lib/asn1/ber_dec.cpp @@ -8,7 +8,7 @@ #include <botan/ber_dec.h> #include <botan/bigint.h> -#include <botan/get_byte.h> +#include <botan/loadstor.h> namespace Botan { diff --git a/src/lib/asn1/der_enc.cpp b/src/lib/asn1/der_enc.cpp index f886e8ed3..f1bcf634e 100644 --- a/src/lib/asn1/der_enc.cpp +++ b/src/lib/asn1/der_enc.cpp @@ -8,7 +8,7 @@ #include <botan/der_enc.h> #include <botan/asn1_obj.h> #include <botan/bigint.h> -#include <botan/get_byte.h> +#include <botan/loadstor.h> #include <botan/parsing.h> #include <botan/internal/bit_ops.h> #include <algorithm> diff --git a/src/lib/asn1/info.txt b/src/lib/asn1/info.txt index c6c3db537..a067168e4 100644 --- a/src/lib/asn1/info.txt +++ b/src/lib/asn1/info.txt @@ -3,7 +3,6 @@ define ASN1 20131128 load_on auto <requires> -filters bigint oid_lookup </requires> diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h index 918206577..e16522d94 100644 --- a/src/lib/base/algo_registry.h +++ b/src/lib/base/algo_registry.h @@ -7,7 +7,7 @@ #ifndef BOTAN_ALGO_REGISTRY_H__ #define BOTAN_ALGO_REGISTRY_H__ -#include <botan/lookup.h> +#include <botan/types.h> #include <functional> #include <stdexcept> #include <mutex> @@ -35,7 +35,8 @@ class Algo_Registry void add(const std::string& name, const std::string& provider, maker_fn fn, byte pref) { std::unique_lock<std::mutex> lock(m_mutex); - m_algo_info[name].add_provider(provider, fn, pref); + if(!m_algo_info[name].add_provider(provider, fn, pref)) + throw std::runtime_error("Duplicated registration of " + name + "/" + provider); } std::vector<std::string> providers_of(const Spec& spec) @@ -102,13 +103,14 @@ class Algo_Registry struct Algo_Info { public: - void add_provider(const std::string& provider, maker_fn fn, byte pref) + bool add_provider(const std::string& provider, maker_fn fn, byte pref) { if(m_maker_fns.count(provider) > 0) - throw std::runtime_error("Duplicated registration of '" + provider + "'"); + return false; m_maker_fns[provider] = fn; m_prefs.insert(std::make_pair(pref, provider)); + return true; } std::vector<std::string> providers() const @@ -152,7 +154,7 @@ class Algo_Registry return r; } private: - std::multimap<byte, std::string> m_prefs; + std::multimap<byte, std::string, std::greater<byte>> m_prefs; std::unordered_map<std::string, maker_fn> m_maker_fns; }; @@ -224,24 +226,27 @@ make_new_T_1X(const typename Algo_Registry<T>::Spec& spec) namespace { Algo_Registry<T>::Add g_ ## type ## _reg(cond, name, maker, provider, pref); } \ BOTAN_FORCE_SEMICOLON +#define BOTAN_DEFAULT_ALGORITHM_PRIO 100 +#define BOTAN_SIMD_ALGORITHM_PRIO 110 + #define BOTAN_REGISTER_NAMED_T(T, name, type, maker) \ - BOTAN_REGISTER_TYPE(T, type, name, maker, "base", 128) + BOTAN_REGISTER_TYPE(T, type, name, maker, "base", BOTAN_DEFAULT_ALGORITHM_PRIO) #define BOTAN_REGISTER_T(T, type, maker) \ - BOTAN_REGISTER_TYPE(T, type, #type, maker, "base", 128) + BOTAN_REGISTER_TYPE(T, type, #type, maker, "base", BOTAN_DEFAULT_ALGORITHM_PRIO) #define BOTAN_REGISTER_T_NOARGS(T, type) \ - BOTAN_REGISTER_TYPE(T, type, #type, make_new_T<type>, "base", 128) + BOTAN_REGISTER_TYPE(T, type, #type, make_new_T<type>, "base", BOTAN_DEFAULT_ALGORITHM_PRIO) #define BOTAN_REGISTER_T_1LEN(T, type, def) \ - BOTAN_REGISTER_TYPE(T, type, #type, (make_new_T_1len<type,def>), "base", 128) + BOTAN_REGISTER_TYPE(T, type, #type, (make_new_T_1len<type,def>), "base", BOTAN_DEFAULT_ALGORITHM_PRIO) #define BOTAN_REGISTER_NAMED_T_NOARGS(T, type, name, provider) \ - BOTAN_REGISTER_TYPE(T, type, name, make_new_T<type>, provider, 128) + BOTAN_REGISTER_TYPE(T, type, name, make_new_T<type>, provider, BOTAN_DEFAULT_ALGORITHM_PRIO) #define BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, T, type, name, provider, pref) \ BOTAN_REGISTER_TYPE_COND(cond, T, type, name, make_new_T<type>, provider, pref) #define BOTAN_REGISTER_NAMED_T_2LEN(T, type, name, provider, len1, len2) \ - BOTAN_REGISTER_TYPE(T, type, name, (make_new_T_2len<type,len1,len2>), provider, 128) + BOTAN_REGISTER_TYPE(T, type, name, (make_new_T_2len<type,len1,len2>), provider, BOTAN_DEFAULT_ALGORITHM_PRIO) // TODO move elsewhere: #define BOTAN_REGISTER_TRANSFORM(name, maker) BOTAN_REGISTER_T(Transform, name, maker) diff --git a/src/lib/base/buf_comp.h b/src/lib/base/buf_comp.h index 30e30c71c..d0793b84b 100644 --- a/src/lib/base/buf_comp.h +++ b/src/lib/base/buf_comp.h @@ -9,7 +9,7 @@ #define BOTAN_BUFFERED_COMPUTATION_H__ #include <botan/secmem.h> -#include <botan/get_byte.h> +#include <botan/loadstor.h> #include <string> namespace Botan { diff --git a/src/lib/base/info.txt b/src/lib/base/info.txt index e09351596..33d22a279 100644 --- a/src/lib/base/info.txt +++ b/src/lib/base/info.txt @@ -4,6 +4,7 @@ buf_comp.h init.h key_spec.h lookup.h +secmem.h scan_name.h sym_algo.h symkey.h @@ -17,13 +18,11 @@ algo_registry.h define TRANSFORM 20131209 <requires> -alloc block hash hex mac modes -pbkdf rng stream utils diff --git a/src/lib/base/lookup.cpp b/src/lib/base/lookup.cpp deleted file mode 100644 index 6655a4fb4..000000000 --- a/src/lib/base/lookup.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* -* Algorithm Retrieval -* (C) 1999-2007,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include <botan/lookup.h> -#include <botan/internal/algo_registry.h> -#include <botan/cipher_mode.h> -#include <botan/block_cipher.h> -#include <botan/stream_cipher.h> -#include <botan/hash.h> -#include <botan/mac.h> -#include <botan/pbkdf.h> - -namespace Botan { - -Transform* get_transform(const std::string& specstr, - const std::string& provider, - const std::string& dirstr) - { - Algo_Registry<Transform>::Spec spec(specstr, dirstr); - return Algo_Registry<Transform>::global_registry().make(spec, provider); - } - -BlockCipher* get_block_cipher(const std::string& algo_spec, const std::string& provider) - { - return make_a<BlockCipher>(algo_spec, provider); - } - -StreamCipher* get_stream_cipher(const std::string& algo_spec, const std::string& provider) - { - return make_a<StreamCipher>(algo_spec, provider); - } - -HashFunction* get_hash_function(const std::string& algo_spec, const std::string& provider) - { - return make_a<HashFunction>(algo_spec, provider); - } - -MessageAuthenticationCode* get_mac(const std::string& algo_spec, const std::string& provider) - { - return make_a<MessageAuthenticationCode>(algo_spec, provider); - } - -std::unique_ptr<BlockCipher> make_block_cipher(const std::string& algo_spec, - const std::string& provider) - { - if(auto x = get_block_cipher(algo_spec, provider)) - return std::unique_ptr<BlockCipher>(x); - throw Algorithm_Not_Found(algo_spec); - } - -std::unique_ptr<StreamCipher> make_stream_cipher(const std::string& algo_spec, - const std::string& provider) - { - if(auto x = get_stream_cipher(algo_spec, provider)) - return std::unique_ptr<StreamCipher>(x); - throw Algorithm_Not_Found(algo_spec); - } - -std::unique_ptr<HashFunction> make_hash_function(const std::string& algo_spec, - const std::string& provider) - { - if(auto x = get_hash_function(algo_spec, provider)) - return std::unique_ptr<HashFunction>(x); - throw Algorithm_Not_Found(algo_spec); - } - -std::unique_ptr<MessageAuthenticationCode> make_message_auth(const std::string& algo_spec, - const std::string& provider) - { - if(auto x = get_mac(algo_spec, provider)) - return std::unique_ptr<MessageAuthenticationCode>(x); - throw Algorithm_Not_Found(algo_spec); - } - -std::vector<std::string> get_block_cipher_providers(const std::string& algo_spec) - { - return providers_of<BlockCipher>(BlockCipher::Spec(algo_spec)); - } - -std::vector<std::string> get_stream_cipher_providers(const std::string& algo_spec) - { - return providers_of<StreamCipher>(StreamCipher::Spec(algo_spec)); - } - -std::vector<std::string> get_hash_function_providers(const std::string& algo_spec) - { - return providers_of<HashFunction>(HashFunction::Spec(algo_spec)); - } - -std::vector<std::string> get_mac_providers(const std::string& algo_spec) - { - return providers_of<MessageAuthenticationCode>(MessageAuthenticationCode::Spec(algo_spec)); - } - -/* -* Get a PBKDF algorithm by name -*/ -PBKDF* get_pbkdf(const std::string& algo_spec, const std::string& provider) - { - if(PBKDF* pbkdf = make_a<PBKDF>(algo_spec, provider)) - return pbkdf; - throw Algorithm_Not_Found(algo_spec); - } - -} diff --git a/src/lib/base/lookup.h b/src/lib/base/lookup.h index d5b17237e..9595d1f06 100644 --- a/src/lib/base/lookup.h +++ b/src/lib/base/lookup.h @@ -8,19 +8,17 @@ #ifndef BOTAN_LOOKUP_H__ #define BOTAN_LOOKUP_H__ -#include <botan/types.h> +#include <botan/block_cipher.h> +#include <botan/stream_cipher.h> +#include <botan/hash.h> +#include <botan/mac.h> +#include <botan/exceptn.h> #include <string> #include <vector> #include <memory> namespace Botan { -class BlockCipher; -class StreamCipher; -class HashFunction; -class MessageAuthenticationCode; -class PBKDF; - /* * Get an algorithm object * NOTE: these functions create and return new objects, letting the @@ -33,13 +31,25 @@ class PBKDF; * @param algo_spec the name of the desired block cipher * @return pointer to the block cipher object */ -BOTAN_DLL BlockCipher* get_block_cipher(const std::string& algo_spec, - const std::string& provider = ""); +inline BlockCipher* get_block_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + return BlockCipher::create(algo_spec, provider).release(); + } -BOTAN_DLL std::unique_ptr<BlockCipher> make_block_cipher(const std::string& algo_spec, - const std::string& provider = ""); +inline std::unique_ptr<BlockCipher> make_block_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + std::unique_ptr<BlockCipher> p(BlockCipher::create(algo_spec, provider)); + if(p) + return p; + throw Algorithm_Not_Found(algo_spec); + } -BOTAN_DLL std::vector<std::string> get_block_cipher_providers(const std::string& algo_spec); +inline std::vector<std::string> get_block_cipher_providers(const std::string& algo_spec) + { + return BlockCipher::providers(algo_spec); + } /** * Stream cipher factory method. @@ -47,13 +57,25 @@ BOTAN_DLL std::vector<std::string> get_block_cipher_providers(const std::string& * @param algo_spec the name of the desired stream cipher * @return pointer to the stream cipher object */ -BOTAN_DLL StreamCipher* get_stream_cipher(const std::string& algo_spec, - const std::string& provider = ""); +inline StreamCipher* get_stream_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + return StreamCipher::create(algo_spec, provider).release(); + } -BOTAN_DLL std::unique_ptr<StreamCipher> make_stream_cipher(const std::string& algo_spec, - const std::string& provider = ""); +inline std::unique_ptr<StreamCipher> make_stream_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + std::unique_ptr<StreamCipher> p(StreamCipher::create(algo_spec, provider)); + if(p) + return p; + throw Algorithm_Not_Found(algo_spec); + } -BOTAN_DLL std::vector<std::string> get_stream_cipher_providers(const std::string& algo_spec); +inline std::vector<std::string> get_stream_cipher_providers(const std::string& algo_spec) + { + return StreamCipher::providers(algo_spec); + } /** * Hash function factory method. @@ -61,11 +83,20 @@ BOTAN_DLL std::vector<std::string> get_stream_cipher_providers(const std::string * @param algo_spec the name of the desired hash function * @return pointer to the hash function object */ -BOTAN_DLL HashFunction* get_hash_function(const std::string& algo_spec, - const std::string& provider = ""); +inline HashFunction* get_hash_function(const std::string& algo_spec, + const std::string& provider = "") + { + return HashFunction::create(algo_spec, provider).release(); + } -BOTAN_DLL std::unique_ptr<HashFunction> make_hash_function(const std::string& algo_spec, - const std::string& provider = ""); +inline std::unique_ptr<HashFunction> make_hash_function(const std::string& algo_spec, + const std::string& provider = "") + { + std::unique_ptr<HashFunction> p(HashFunction::create(algo_spec, provider)); + if(p) + return p; + throw Algorithm_Not_Found(algo_spec); + } inline HashFunction* get_hash(const std::string& algo_spec, const std::string& provider = "") @@ -73,7 +104,10 @@ inline HashFunction* get_hash(const std::string& algo_spec, return get_hash_function(algo_spec, provider); } -BOTAN_DLL std::vector<std::string> get_hash_function_providers(const std::string& algo_spec); +inline std::vector<std::string> get_hash_function_providers(const std::string& algo_spec) + { + return HashFunction::providers(algo_spec); + } /** * MAC factory method. @@ -81,21 +115,25 @@ BOTAN_DLL std::vector<std::string> get_hash_function_providers(const std::string * @param algo_spec the name of the desired MAC * @return pointer to the MAC object */ -BOTAN_DLL MessageAuthenticationCode* get_mac(const std::string& algo_spec, - const std::string& provider = ""); - -BOTAN_DLL std::unique_ptr<MessageAuthenticationCode> make_message_auth(const std::string& algo_spec, - const std::string& provider = ""); +inline MessageAuthenticationCode* get_mac(const std::string& algo_spec, + const std::string& provider = "") + { + return MessageAuthenticationCode::create(algo_spec, provider).release(); + } -BOTAN_DLL std::vector<std::string> get_mac_providers(const std::string& algo_spec); +inline std::unique_ptr<MessageAuthenticationCode> make_message_auth(const std::string& algo_spec, + const std::string& provider = "") + { + std::unique_ptr<MessageAuthenticationCode> p(MessageAuthenticationCode::create(algo_spec, provider)); + if(p) + return p; + throw Algorithm_Not_Found(algo_spec); + } -/** -* Password based key derivation function factory method -* @param algo_spec the name of the desired PBKDF algorithm -* @return pointer to newly allocated object of that type -*/ -BOTAN_DLL PBKDF* get_pbkdf(const std::string& algo_spec, - const std::string& provider = ""); +inline std::vector<std::string> get_mac_providers(const std::string& algo_spec) + { + return MessageAuthenticationCode::providers(algo_spec); + } } diff --git a/src/lib/base/scan_name.cpp b/src/lib/base/scan_name.cpp index 4b0c95004..5c8c55b27 100644 --- a/src/lib/base/scan_name.cpp +++ b/src/lib/base/scan_name.cpp @@ -29,7 +29,7 @@ std::string make_arg( if(name[i].first > level) { - output += '(' + name[i].second; + output += "(" + name[i].second; ++paren_depth; } else if(name[i].first < level) @@ -48,7 +48,7 @@ std::string make_arg( } for(size_t i = 0; i != paren_depth; ++i) - output += ')'; + output += ")"; return output; } @@ -141,14 +141,14 @@ std::string SCAN_Name::all_arguments() const std::string out; if(arg_count()) { - out += '('; + out += "("; for(size_t i = 0; i != arg_count(); ++i) { out += arg(i); if(i != arg_count() - 1) - out += ','; + out += ","; } - out += ')'; + out += ")"; } return out; } diff --git a/src/lib/alloc/secmem.h b/src/lib/base/secmem.h index 98707ad4e..63d4e5296 100644 --- a/src/lib/alloc/secmem.h +++ b/src/lib/base/secmem.h @@ -36,6 +36,9 @@ class secure_allocator secure_allocator() BOTAN_NOEXCEPT {} + template<typename U> + secure_allocator(const secure_allocator<U>&) BOTAN_NOEXCEPT {} + ~secure_allocator() BOTAN_NOEXCEPT {} pointer address(reference x) const BOTAN_NOEXCEPT @@ -82,12 +85,12 @@ class secure_allocator template<typename U> void destroy(U* p) { p->~U(); } }; -template<typename T> inline bool -operator==(const secure_allocator<T>&, const secure_allocator<T>&) +template<typename T, typename U> inline bool +operator==(const secure_allocator<T>&, const secure_allocator<U>&) { return true; } -template<typename T> inline bool -operator!=(const secure_allocator<T>&, const secure_allocator<T>&) +template<typename T, typename U> inline bool +operator!=(const secure_allocator<T>&, const secure_allocator<U>&) { return false; } template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>; diff --git a/src/lib/base/symkey.cpp b/src/lib/base/symkey.cpp index 88642747b..2c98da051 100644 --- a/src/lib/base/symkey.cpp +++ b/src/lib/base/symkey.cpp @@ -6,7 +6,6 @@ */ #include <botan/symkey.h> -#include <botan/internal/xor_buf.h> #include <botan/rng.h> #include <botan/hex.h> #include <algorithm> diff --git a/src/lib/base/transform.cpp b/src/lib/base/transform.cpp new file mode 100644 index 000000000..8f05a33ad --- /dev/null +++ b/src/lib/base/transform.cpp @@ -0,0 +1,20 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/internal/algo_registry.h> +#include <botan/transform.h> + +namespace Botan { + +Transform* get_transform(const std::string& specstr, + const std::string& provider, + const std::string& dirstr) + { + Algo_Registry<Transform>::Spec spec(specstr, dirstr); + return Algo_Registry<Transform>::global_registry().make(spec, provider); + } + +} diff --git a/src/lib/block/aes/aes.cpp b/src/lib/block/aes/aes.cpp index b9e00fe6c..61cc9d777 100644 --- a/src/lib/block/aes/aes.cpp +++ b/src/lib/block/aes/aes.cpp @@ -7,15 +7,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/aes.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_128, "AES-128"); -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_192, "AES-192"); -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_256, "AES-256"); - namespace { const byte SE[256] = { diff --git a/src/lib/block/aes_ni/aes_ni.cpp b/src/lib/block/aes_ni/aes_ni.cpp index 20aa63c54..d359ec772 100644 --- a/src/lib/block/aes_ni/aes_ni.cpp +++ b/src/lib/block/aes_ni/aes_ni.cpp @@ -5,17 +5,13 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/aes_ni.h> +#include <botan/loadstor.h> #include <botan/cpuid.h> #include <wmmintrin.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_128_NI, "AES-128", "aes_ni", 16); -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_192_NI, "AES-192", "aes_ni", 16); -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_256_NI, "AES-256", "aes_ni", 16); - namespace { __m128i aes_128_key_expansion(__m128i key, __m128i key_with_rcon) diff --git a/src/lib/block/aes_ssse3/aes_ssse3.cpp b/src/lib/block/aes_ssse3/aes_ssse3.cpp index f0d506b6e..bfc76ecee 100644 --- a/src/lib/block/aes_ssse3/aes_ssse3.cpp +++ b/src/lib/block/aes_ssse3/aes_ssse3.cpp @@ -10,17 +10,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/aes_ssse3.h> #include <botan/cpuid.h> #include <tmmintrin.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_128_SSSE3, "AES-128", "ssse3", 64); -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_192_SSSE3, "AES-192", "ssse3", 64); -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_256_SSSE3, "AES-256", "ssse3", 64); - namespace { const __m128i low_nibs = _mm_set1_epi8(0x0F); diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp new file mode 100644 index 000000000..7b52f8716 --- /dev/null +++ b/src/lib/block/block_cipher.cpp @@ -0,0 +1,315 @@ +/* +* Block Ciphers +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/block_cipher.h> +#include <botan/cpuid.h> +#include <botan/internal/algo_registry.h> + +#if defined(BOTAN_HAS_AES) + #include <botan/aes.h> +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + #include <botan/aes_ssse3.h> +#endif + +#if defined(BOTAN_HAS_AES_NI) + #include <botan/aes_ni.h> +#endif + +#if defined(BOTAN_HAS_BLOWFISH) + #include <botan/blowfish.h> +#endif + +#if defined(BOTAN_HAS_CAMELLIA) + #include <botan/camellia.h> +#endif + +#if defined(BOTAN_HAS_CAST) + #include <botan/cast128.h> + #include <botan/cast256.h> +#endif + +#if defined(BOTAN_HAS_CASCADE) + #include <botan/cascade.h> +#endif + +#if defined(BOTAN_HAS_DES) + #include <botan/des.h> + #include <botan/desx.h> +#endif + +#if defined(BOTAN_HAS_GOST_28147_89) + #include <botan/gost_28147.h> +#endif + +#if defined(BOTAN_HAS_IDEA) + #include <botan/idea.h> +#endif + +#if defined(BOTAN_HAS_IDEA_SSE2) + #include <botan/idea_sse2.h> +#endif + +#if defined(BOTAN_HAS_KASUMI) + #include <botan/kasumi.h> +#endif + +#if defined(BOTAN_HAS_LION) + #include <botan/lion.h> +#endif + +#if defined(BOTAN_HAS_LUBY_RACKOFF) + #include <botan/lubyrack.h> +#endif + +#if defined(BOTAN_HAS_MARS) + #include <botan/mars.h> +#endif + +#if defined(BOTAN_HAS_MISTY1) + #include <botan/misty1.h> +#endif + +#if defined(BOTAN_HAS_NOEKEON) + #include <botan/noekeon.h> +#endif + +#if defined(BOTAN_HAS_NOEKEON_SIMD) + #include <botan/noekeon_simd.h> +#endif + +#if defined(BOTAN_HAS_RC2) + #include <botan/rc2.h> +#endif + +#if defined(BOTAN_HAS_RC5) + #include <botan/rc5.h> +#endif + +#if defined(BOTAN_HAS_RC6) + #include <botan/rc6.h> +#endif + +#if defined(BOTAN_HAS_SAFER) + #include <botan/safer_sk.h> +#endif + +#if defined(BOTAN_HAS_SEED) + #include <botan/seed.h> +#endif + +#if defined(BOTAN_HAS_SERPENT) + #include <botan/serpent.h> +#endif + +#if defined(BOTAN_HAS_SERPENT_SIMD) + #include <botan/serp_simd.h> +#endif + +#if defined(BOTAN_HAS_SKIPJACK) + #include <botan/skipjack.h> +#endif + +#if defined(BOTAN_HAS_SQUARE) + #include <botan/square.h> +#endif + +#if defined(BOTAN_HAS_TEA) + #include <botan/tea.h> +#endif + +#if defined(BOTAN_HAS_TWOFISH) + #include <botan/twofish.h> +#endif + +#if defined(BOTAN_HAS_THREEFISH_512) + #include <botan/threefish.h> +#endif + +#if defined(BOTAN_HAS_THREEFISH_512_AVX2) + #include <botan/threefish_avx2.h> +#endif + +#if defined(BOTAN_HAS_XTEA) + #include <botan/xtea.h> +#endif + +#if defined(BOTAN_HAS_XTEA_SIMD) + #include <botan/xtea_simd.h> +#endif + +namespace Botan { + +BlockCipher::~BlockCipher() {} + +std::unique_ptr<BlockCipher> BlockCipher::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr<BlockCipher>(make_a<BlockCipher>(algo_spec, provider)); + } + +std::vector<std::string> BlockCipher::providers(const std::string& algo_spec) + { + return providers_of<BlockCipher>(BlockCipher::Spec(algo_spec)); + } + +#define BOTAN_REGISTER_BLOCK_CIPHER(name, maker) BOTAN_REGISTER_T(BlockCipher, name, maker) +#define BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(name) BOTAN_REGISTER_T_NOARGS(BlockCipher, name) + +#define BOTAN_REGISTER_BLOCK_CIPHER_1LEN(name, def) BOTAN_REGISTER_T_1LEN(BlockCipher, name, def) + +#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(type, name) \ + BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, make_new_T<type>) +#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1LEN(type, name, def) \ + BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, (make_new_T_1len<type,def>)) +#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(type, name, def) \ + BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, std::bind(make_new_T_1str<type>, std::placeholders::_1, def)) + +#define BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(cond, type, name, provider, pref) \ + BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, BlockCipher, type, name, provider, pref) + +#if defined(BOTAN_HAS_AES) +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_128, "AES-128"); +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_192, "AES-192"); +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_256, "AES-256"); +#endif + +#if defined(BOTAN_HAS_AES_NI) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_128_NI, "AES-128", "aes_ni", 200); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_192_NI, "AES-192", "aes_ni", 200); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_256_NI, "AES-256", "aes_ni", 200); +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_128_SSSE3, "AES-128", + "ssse3", BOTAN_SIMD_ALGORITHM_PRIO); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_192_SSSE3, "AES-192", + "ssse3", BOTAN_SIMD_ALGORITHM_PRIO); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_256_SSSE3, "AES-256", + "ssse3", BOTAN_SIMD_ALGORITHM_PRIO); +#endif + +#if defined(BOTAN_HAS_BLOWFISH) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Blowfish); +#endif + +#if defined(BOTAN_HAS_CAMELLIA) +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_128, "Camellia-128"); +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_192, "Camellia-192"); +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_256, "Camellia-256"); +#endif + +#if defined(BOTAN_HAS_CAST) +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(CAST_128, "CAST-128"); +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(CAST_256, "CAST-256"); +#endif + +#if defined(BOTAN_HAS_DES) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(DES); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(TripleDES); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(DESX); +#endif + +#if defined(BOTAN_HAS_GOST_28147_89) +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(GOST_28147_89, "GOST-28147-89", "R3411_94_TestParam"); +#endif + +#if defined(BOTAN_HAS_IDEA) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(IDEA); +#endif + +#if defined(BOTAN_HAS_IDEA_SSE2) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_sse2(), IDEA_SSE2, "IDEA", + "sse2", BOTAN_SIMD_ALGORITHM_PRIO); +#endif + +#if defined(BOTAN_HAS_KASUMI) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(KASUMI); +#endif + +#if defined(BOTAN_HAS_MARS) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(MARS); +#endif + +#if defined(BOTAN_HAS_MISTY1) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(MISTY1); +#endif + +#if defined(BOTAN_HAS_NOEKEON) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Noekeon); +#endif + +#if defined(BOTAN_HAS_NOEKEON_SIMD) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_simd_32(), Noekeon_SIMD, "Noekeon", + "simd32", BOTAN_SIMD_ALGORITHM_PRIO); +#endif + +#if defined(BOTAN_HAS_RC2) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(RC2); +#endif + +#if defined(BOTAN_HAS_RC5) +BOTAN_REGISTER_BLOCK_CIPHER_1LEN(RC5, 12); +#endif + +#if defined(BOTAN_HAS_RC6) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(RC6); +#endif + +#if defined(BOTAN_HAS_SAFER) +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1LEN(SAFER_SK, "SAFER-SK", 10); +#endif + +#if defined(BOTAN_HAS_SEED) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(SEED); +#endif + +#if defined(BOTAN_HAS_SERPENT) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Serpent); +#endif + +#if defined(BOTAN_HAS_SERPENT_SIMD) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_simd_32(), Serpent_SIMD, "Serpent", + "simd32", BOTAN_SIMD_ALGORITHM_PRIO); +#endif + +#if defined(BOTAN_HAS_TEA) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(TEA); +#endif + +#if defined(BOTAN_HAS_TWOFISH) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Twofish); +#endif + +#if defined(BOTAN_HAS_THREEFISH_512) +BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Threefish_512, "Threefish-512"); +#endif + +#if defined(BOTAN_HAS_THREEFISH_512_AVX2) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_avx2(), Threefish_512_AVX2, "Threefish-512", + "avx2", BOTAN_SIMD_ALGORITHM_PRIO); +#endif + +#if defined(BOTAN_HAS_XTEA) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(XTEA); +#endif + +#if defined(BOTAN_HAS_XTEA_SIMD) +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_simd_32(), XTEA_SIMD, "XTEA", + "simd32", BOTAN_SIMD_ALGORITHM_PRIO); +#endif + +#if defined(BOTAN_HAS_CASCADE) +BOTAN_REGISTER_NAMED_T(BlockCipher, "Cascade", Cascade_Cipher, Cascade_Cipher::make); +#endif + +#if defined(BOTAN_HAS_LION) +BOTAN_REGISTER_NAMED_T(BlockCipher, "Lion", Lion, Lion::make); +#endif + +} diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h index 08bf18fd3..0f4c2c1c5 100644 --- a/src/lib/block/block_cipher.h +++ b/src/lib/block/block_cipher.h @@ -22,6 +22,19 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm typedef SCAN_Name Spec; /** + * Create an instance based on a name + * Will return a null pointer if the algo/provider combination cannot + * be found. If provider is empty then best available is chosen. + */ + static std::unique_ptr<BlockCipher> create(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * Returns the list of available providers for this algorithm, empty if not available + */ + static std::vector<std::string> providers(const std::string& algo_spec); + + /** * @return block size of this algorithm */ virtual size_t block_size() const = 0; @@ -141,6 +154,8 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm * @return new object representing the same algorithm as *this */ virtual BlockCipher* clone() const = 0; + + virtual ~BlockCipher(); }; /** diff --git a/src/lib/block/block_utils.h b/src/lib/block/block_utils.h deleted file mode 100644 index 89f8a3dd3..000000000 --- a/src/lib/block/block_utils.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* Block Cipher Utility Header -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_BLOCK_CIPHER_UTILS_H__ -#define BOTAN_BLOCK_CIPHER_UTILS_H__ - -#include <botan/block_cipher.h> -#include <botan/internal/algo_registry.h> -#include <botan/loadstor.h> -#include <botan/rotate.h> -#include <botan/internal/xor_buf.h> -#include <algorithm> -#include <functional> - -namespace Botan { - -#define BOTAN_REGISTER_BLOCK_CIPHER(name, maker) BOTAN_REGISTER_T(BlockCipher, name, maker) -#define BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(name) BOTAN_REGISTER_T_NOARGS(BlockCipher, name) - -#define BOTAN_REGISTER_BLOCK_CIPHER_1LEN(name, def) BOTAN_REGISTER_T_1LEN(BlockCipher, name, def) - -#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(type, name) \ - BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, make_new_T<type>) -#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, (make_new_T_1len<type,def>)) -#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(type, name, def) \ - BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, std::bind(make_new_T_1str<type>, std::placeholders::_1, def)) - -#define BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(cond, type, name, provider, pref) \ - BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, BlockCipher, type, name, provider, pref) - -} - -#endif diff --git a/src/lib/block/blowfish/blowfish.cpp b/src/lib/block/blowfish/blowfish.cpp index 63838929d..2488838c3 100644 --- a/src/lib/block/blowfish/blowfish.cpp +++ b/src/lib/block/blowfish/blowfish.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/blowfish.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Blowfish); - /* * Blowfish Encryption */ diff --git a/src/lib/block/camellia/camellia.cpp b/src/lib/block/camellia/camellia.cpp index 887878910..e9b10c528 100644 --- a/src/lib/block/camellia/camellia.cpp +++ b/src/lib/block/camellia/camellia.cpp @@ -5,19 +5,542 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/camellia.h> -#include <botan/internal/camellia_sbox.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_128, "Camellia-128"); -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_192, "Camellia-192"); -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_256, "Camellia-256"); +namespace { -namespace Camellia_F { +const u64bit Camellia_SBOX1[256] = { +0x7070700070000070, 0x8282820082000082, 0x2C2C2C002C00002C, 0xECECEC00EC0000EC, +0xB3B3B300B30000B3, 0x2727270027000027, 0xC0C0C000C00000C0, 0xE5E5E500E50000E5, +0xE4E4E400E40000E4, 0x8585850085000085, 0x5757570057000057, 0x3535350035000035, +0xEAEAEA00EA0000EA, 0x0C0C0C000C00000C, 0xAEAEAE00AE0000AE, 0x4141410041000041, +0x2323230023000023, 0xEFEFEF00EF0000EF, 0x6B6B6B006B00006B, 0x9393930093000093, +0x4545450045000045, 0x1919190019000019, 0xA5A5A500A50000A5, 0x2121210021000021, +0xEDEDED00ED0000ED, 0x0E0E0E000E00000E, 0x4F4F4F004F00004F, 0x4E4E4E004E00004E, +0x1D1D1D001D00001D, 0x6565650065000065, 0x9292920092000092, 0xBDBDBD00BD0000BD, +0x8686860086000086, 0xB8B8B800B80000B8, 0xAFAFAF00AF0000AF, 0x8F8F8F008F00008F, +0x7C7C7C007C00007C, 0xEBEBEB00EB0000EB, 0x1F1F1F001F00001F, 0xCECECE00CE0000CE, +0x3E3E3E003E00003E, 0x3030300030000030, 0xDCDCDC00DC0000DC, 0x5F5F5F005F00005F, +0x5E5E5E005E00005E, 0xC5C5C500C50000C5, 0x0B0B0B000B00000B, 0x1A1A1A001A00001A, +0xA6A6A600A60000A6, 0xE1E1E100E10000E1, 0x3939390039000039, 0xCACACA00CA0000CA, +0xD5D5D500D50000D5, 0x4747470047000047, 0x5D5D5D005D00005D, 0x3D3D3D003D00003D, +0xD9D9D900D90000D9, 0x0101010001000001, 0x5A5A5A005A00005A, 0xD6D6D600D60000D6, +0x5151510051000051, 0x5656560056000056, 0x6C6C6C006C00006C, 0x4D4D4D004D00004D, +0x8B8B8B008B00008B, 0x0D0D0D000D00000D, 0x9A9A9A009A00009A, 0x6666660066000066, +0xFBFBFB00FB0000FB, 0xCCCCCC00CC0000CC, 0xB0B0B000B00000B0, 0x2D2D2D002D00002D, +0x7474740074000074, 0x1212120012000012, 0x2B2B2B002B00002B, 0x2020200020000020, +0xF0F0F000F00000F0, 0xB1B1B100B10000B1, 0x8484840084000084, 0x9999990099000099, +0xDFDFDF00DF0000DF, 0x4C4C4C004C00004C, 0xCBCBCB00CB0000CB, 0xC2C2C200C20000C2, +0x3434340034000034, 0x7E7E7E007E00007E, 0x7676760076000076, 0x0505050005000005, +0x6D6D6D006D00006D, 0xB7B7B700B70000B7, 0xA9A9A900A90000A9, 0x3131310031000031, +0xD1D1D100D10000D1, 0x1717170017000017, 0x0404040004000004, 0xD7D7D700D70000D7, +0x1414140014000014, 0x5858580058000058, 0x3A3A3A003A00003A, 0x6161610061000061, +0xDEDEDE00DE0000DE, 0x1B1B1B001B00001B, 0x1111110011000011, 0x1C1C1C001C00001C, +0x3232320032000032, 0x0F0F0F000F00000F, 0x9C9C9C009C00009C, 0x1616160016000016, +0x5353530053000053, 0x1818180018000018, 0xF2F2F200F20000F2, 0x2222220022000022, +0xFEFEFE00FE0000FE, 0x4444440044000044, 0xCFCFCF00CF0000CF, 0xB2B2B200B20000B2, +0xC3C3C300C30000C3, 0xB5B5B500B50000B5, 0x7A7A7A007A00007A, 0x9191910091000091, +0x2424240024000024, 0x0808080008000008, 0xE8E8E800E80000E8, 0xA8A8A800A80000A8, +0x6060600060000060, 0xFCFCFC00FC0000FC, 0x6969690069000069, 0x5050500050000050, +0xAAAAAA00AA0000AA, 0xD0D0D000D00000D0, 0xA0A0A000A00000A0, 0x7D7D7D007D00007D, +0xA1A1A100A10000A1, 0x8989890089000089, 0x6262620062000062, 0x9797970097000097, +0x5454540054000054, 0x5B5B5B005B00005B, 0x1E1E1E001E00001E, 0x9595950095000095, +0xE0E0E000E00000E0, 0xFFFFFF00FF0000FF, 0x6464640064000064, 0xD2D2D200D20000D2, +0x1010100010000010, 0xC4C4C400C40000C4, 0x0000000000000000, 0x4848480048000048, +0xA3A3A300A30000A3, 0xF7F7F700F70000F7, 0x7575750075000075, 0xDBDBDB00DB0000DB, +0x8A8A8A008A00008A, 0x0303030003000003, 0xE6E6E600E60000E6, 0xDADADA00DA0000DA, +0x0909090009000009, 0x3F3F3F003F00003F, 0xDDDDDD00DD0000DD, 0x9494940094000094, +0x8787870087000087, 0x5C5C5C005C00005C, 0x8383830083000083, 0x0202020002000002, +0xCDCDCD00CD0000CD, 0x4A4A4A004A00004A, 0x9090900090000090, 0x3333330033000033, +0x7373730073000073, 0x6767670067000067, 0xF6F6F600F60000F6, 0xF3F3F300F30000F3, +0x9D9D9D009D00009D, 0x7F7F7F007F00007F, 0xBFBFBF00BF0000BF, 0xE2E2E200E20000E2, +0x5252520052000052, 0x9B9B9B009B00009B, 0xD8D8D800D80000D8, 0x2626260026000026, +0xC8C8C800C80000C8, 0x3737370037000037, 0xC6C6C600C60000C6, 0x3B3B3B003B00003B, +0x8181810081000081, 0x9696960096000096, 0x6F6F6F006F00006F, 0x4B4B4B004B00004B, +0x1313130013000013, 0xBEBEBE00BE0000BE, 0x6363630063000063, 0x2E2E2E002E00002E, +0xE9E9E900E90000E9, 0x7979790079000079, 0xA7A7A700A70000A7, 0x8C8C8C008C00008C, +0x9F9F9F009F00009F, 0x6E6E6E006E00006E, 0xBCBCBC00BC0000BC, 0x8E8E8E008E00008E, +0x2929290029000029, 0xF5F5F500F50000F5, 0xF9F9F900F90000F9, 0xB6B6B600B60000B6, +0x2F2F2F002F00002F, 0xFDFDFD00FD0000FD, 0xB4B4B400B40000B4, 0x5959590059000059, +0x7878780078000078, 0x9898980098000098, 0x0606060006000006, 0x6A6A6A006A00006A, +0xE7E7E700E70000E7, 0x4646460046000046, 0x7171710071000071, 0xBABABA00BA0000BA, +0xD4D4D400D40000D4, 0x2525250025000025, 0xABABAB00AB0000AB, 0x4242420042000042, +0x8888880088000088, 0xA2A2A200A20000A2, 0x8D8D8D008D00008D, 0xFAFAFA00FA0000FA, +0x7272720072000072, 0x0707070007000007, 0xB9B9B900B90000B9, 0x5555550055000055, +0xF8F8F800F80000F8, 0xEEEEEE00EE0000EE, 0xACACAC00AC0000AC, 0x0A0A0A000A00000A, +0x3636360036000036, 0x4949490049000049, 0x2A2A2A002A00002A, 0x6868680068000068, +0x3C3C3C003C00003C, 0x3838380038000038, 0xF1F1F100F10000F1, 0xA4A4A400A40000A4, +0x4040400040000040, 0x2828280028000028, 0xD3D3D300D30000D3, 0x7B7B7B007B00007B, +0xBBBBBB00BB0000BB, 0xC9C9C900C90000C9, 0x4343430043000043, 0xC1C1C100C10000C1, +0x1515150015000015, 0xE3E3E300E30000E3, 0xADADAD00AD0000AD, 0xF4F4F400F40000F4, +0x7777770077000077, 0xC7C7C700C70000C7, 0x8080800080000080, 0x9E9E9E009E00009E }; + +const u64bit Camellia_SBOX2[256] = { +0x00E0E0E0E0E00000, 0x0005050505050000, 0x0058585858580000, 0x00D9D9D9D9D90000, +0x0067676767670000, 0x004E4E4E4E4E0000, 0x0081818181810000, 0x00CBCBCBCBCB0000, +0x00C9C9C9C9C90000, 0x000B0B0B0B0B0000, 0x00AEAEAEAEAE0000, 0x006A6A6A6A6A0000, +0x00D5D5D5D5D50000, 0x0018181818180000, 0x005D5D5D5D5D0000, 0x0082828282820000, +0x0046464646460000, 0x00DFDFDFDFDF0000, 0x00D6D6D6D6D60000, 0x0027272727270000, +0x008A8A8A8A8A0000, 0x0032323232320000, 0x004B4B4B4B4B0000, 0x0042424242420000, +0x00DBDBDBDBDB0000, 0x001C1C1C1C1C0000, 0x009E9E9E9E9E0000, 0x009C9C9C9C9C0000, +0x003A3A3A3A3A0000, 0x00CACACACACA0000, 0x0025252525250000, 0x007B7B7B7B7B0000, +0x000D0D0D0D0D0000, 0x0071717171710000, 0x005F5F5F5F5F0000, 0x001F1F1F1F1F0000, +0x00F8F8F8F8F80000, 0x00D7D7D7D7D70000, 0x003E3E3E3E3E0000, 0x009D9D9D9D9D0000, +0x007C7C7C7C7C0000, 0x0060606060600000, 0x00B9B9B9B9B90000, 0x00BEBEBEBEBE0000, +0x00BCBCBCBCBC0000, 0x008B8B8B8B8B0000, 0x0016161616160000, 0x0034343434340000, +0x004D4D4D4D4D0000, 0x00C3C3C3C3C30000, 0x0072727272720000, 0x0095959595950000, +0x00ABABABABAB0000, 0x008E8E8E8E8E0000, 0x00BABABABABA0000, 0x007A7A7A7A7A0000, +0x00B3B3B3B3B30000, 0x0002020202020000, 0x00B4B4B4B4B40000, 0x00ADADADADAD0000, +0x00A2A2A2A2A20000, 0x00ACACACACAC0000, 0x00D8D8D8D8D80000, 0x009A9A9A9A9A0000, +0x0017171717170000, 0x001A1A1A1A1A0000, 0x0035353535350000, 0x00CCCCCCCCCC0000, +0x00F7F7F7F7F70000, 0x0099999999990000, 0x0061616161610000, 0x005A5A5A5A5A0000, +0x00E8E8E8E8E80000, 0x0024242424240000, 0x0056565656560000, 0x0040404040400000, +0x00E1E1E1E1E10000, 0x0063636363630000, 0x0009090909090000, 0x0033333333330000, +0x00BFBFBFBFBF0000, 0x0098989898980000, 0x0097979797970000, 0x0085858585850000, +0x0068686868680000, 0x00FCFCFCFCFC0000, 0x00ECECECECEC0000, 0x000A0A0A0A0A0000, +0x00DADADADADA0000, 0x006F6F6F6F6F0000, 0x0053535353530000, 0x0062626262620000, +0x00A3A3A3A3A30000, 0x002E2E2E2E2E0000, 0x0008080808080000, 0x00AFAFAFAFAF0000, +0x0028282828280000, 0x00B0B0B0B0B00000, 0x0074747474740000, 0x00C2C2C2C2C20000, +0x00BDBDBDBDBD0000, 0x0036363636360000, 0x0022222222220000, 0x0038383838380000, +0x0064646464640000, 0x001E1E1E1E1E0000, 0x0039393939390000, 0x002C2C2C2C2C0000, +0x00A6A6A6A6A60000, 0x0030303030300000, 0x00E5E5E5E5E50000, 0x0044444444440000, +0x00FDFDFDFDFD0000, 0x0088888888880000, 0x009F9F9F9F9F0000, 0x0065656565650000, +0x0087878787870000, 0x006B6B6B6B6B0000, 0x00F4F4F4F4F40000, 0x0023232323230000, +0x0048484848480000, 0x0010101010100000, 0x00D1D1D1D1D10000, 0x0051515151510000, +0x00C0C0C0C0C00000, 0x00F9F9F9F9F90000, 0x00D2D2D2D2D20000, 0x00A0A0A0A0A00000, +0x0055555555550000, 0x00A1A1A1A1A10000, 0x0041414141410000, 0x00FAFAFAFAFA0000, +0x0043434343430000, 0x0013131313130000, 0x00C4C4C4C4C40000, 0x002F2F2F2F2F0000, +0x00A8A8A8A8A80000, 0x00B6B6B6B6B60000, 0x003C3C3C3C3C0000, 0x002B2B2B2B2B0000, +0x00C1C1C1C1C10000, 0x00FFFFFFFFFF0000, 0x00C8C8C8C8C80000, 0x00A5A5A5A5A50000, +0x0020202020200000, 0x0089898989890000, 0x0000000000000000, 0x0090909090900000, +0x0047474747470000, 0x00EFEFEFEFEF0000, 0x00EAEAEAEAEA0000, 0x00B7B7B7B7B70000, +0x0015151515150000, 0x0006060606060000, 0x00CDCDCDCDCD0000, 0x00B5B5B5B5B50000, +0x0012121212120000, 0x007E7E7E7E7E0000, 0x00BBBBBBBBBB0000, 0x0029292929290000, +0x000F0F0F0F0F0000, 0x00B8B8B8B8B80000, 0x0007070707070000, 0x0004040404040000, +0x009B9B9B9B9B0000, 0x0094949494940000, 0x0021212121210000, 0x0066666666660000, +0x00E6E6E6E6E60000, 0x00CECECECECE0000, 0x00EDEDEDEDED0000, 0x00E7E7E7E7E70000, +0x003B3B3B3B3B0000, 0x00FEFEFEFEFE0000, 0x007F7F7F7F7F0000, 0x00C5C5C5C5C50000, +0x00A4A4A4A4A40000, 0x0037373737370000, 0x00B1B1B1B1B10000, 0x004C4C4C4C4C0000, +0x0091919191910000, 0x006E6E6E6E6E0000, 0x008D8D8D8D8D0000, 0x0076767676760000, +0x0003030303030000, 0x002D2D2D2D2D0000, 0x00DEDEDEDEDE0000, 0x0096969696960000, +0x0026262626260000, 0x007D7D7D7D7D0000, 0x00C6C6C6C6C60000, 0x005C5C5C5C5C0000, +0x00D3D3D3D3D30000, 0x00F2F2F2F2F20000, 0x004F4F4F4F4F0000, 0x0019191919190000, +0x003F3F3F3F3F0000, 0x00DCDCDCDCDC0000, 0x0079797979790000, 0x001D1D1D1D1D0000, +0x0052525252520000, 0x00EBEBEBEBEB0000, 0x00F3F3F3F3F30000, 0x006D6D6D6D6D0000, +0x005E5E5E5E5E0000, 0x00FBFBFBFBFB0000, 0x0069696969690000, 0x00B2B2B2B2B20000, +0x00F0F0F0F0F00000, 0x0031313131310000, 0x000C0C0C0C0C0000, 0x00D4D4D4D4D40000, +0x00CFCFCFCFCF0000, 0x008C8C8C8C8C0000, 0x00E2E2E2E2E20000, 0x0075757575750000, +0x00A9A9A9A9A90000, 0x004A4A4A4A4A0000, 0x0057575757570000, 0x0084848484840000, +0x0011111111110000, 0x0045454545450000, 0x001B1B1B1B1B0000, 0x00F5F5F5F5F50000, +0x00E4E4E4E4E40000, 0x000E0E0E0E0E0000, 0x0073737373730000, 0x00AAAAAAAAAA0000, +0x00F1F1F1F1F10000, 0x00DDDDDDDDDD0000, 0x0059595959590000, 0x0014141414140000, +0x006C6C6C6C6C0000, 0x0092929292920000, 0x0054545454540000, 0x00D0D0D0D0D00000, +0x0078787878780000, 0x0070707070700000, 0x00E3E3E3E3E30000, 0x0049494949490000, +0x0080808080800000, 0x0050505050500000, 0x00A7A7A7A7A70000, 0x00F6F6F6F6F60000, +0x0077777777770000, 0x0093939393930000, 0x0086868686860000, 0x0083838383830000, +0x002A2A2A2A2A0000, 0x00C7C7C7C7C70000, 0x005B5B5B5B5B0000, 0x00E9E9E9E9E90000, +0x00EEEEEEEEEE0000, 0x008F8F8F8F8F0000, 0x0001010101010000, 0x003D3D3D3D3D0000 }; + +const u64bit Camellia_SBOX3[256] = { +0x3800383800383800, 0x4100414100414100, 0x1600161600161600, 0x7600767600767600, +0xD900D9D900D9D900, 0x9300939300939300, 0x6000606000606000, 0xF200F2F200F2F200, +0x7200727200727200, 0xC200C2C200C2C200, 0xAB00ABAB00ABAB00, 0x9A009A9A009A9A00, +0x7500757500757500, 0x0600060600060600, 0x5700575700575700, 0xA000A0A000A0A000, +0x9100919100919100, 0xF700F7F700F7F700, 0xB500B5B500B5B500, 0xC900C9C900C9C900, +0xA200A2A200A2A200, 0x8C008C8C008C8C00, 0xD200D2D200D2D200, 0x9000909000909000, +0xF600F6F600F6F600, 0x0700070700070700, 0xA700A7A700A7A700, 0x2700272700272700, +0x8E008E8E008E8E00, 0xB200B2B200B2B200, 0x4900494900494900, 0xDE00DEDE00DEDE00, +0x4300434300434300, 0x5C005C5C005C5C00, 0xD700D7D700D7D700, 0xC700C7C700C7C700, +0x3E003E3E003E3E00, 0xF500F5F500F5F500, 0x8F008F8F008F8F00, 0x6700676700676700, +0x1F001F1F001F1F00, 0x1800181800181800, 0x6E006E6E006E6E00, 0xAF00AFAF00AFAF00, +0x2F002F2F002F2F00, 0xE200E2E200E2E200, 0x8500858500858500, 0x0D000D0D000D0D00, +0x5300535300535300, 0xF000F0F000F0F000, 0x9C009C9C009C9C00, 0x6500656500656500, +0xEA00EAEA00EAEA00, 0xA300A3A300A3A300, 0xAE00AEAE00AEAE00, 0x9E009E9E009E9E00, +0xEC00ECEC00ECEC00, 0x8000808000808000, 0x2D002D2D002D2D00, 0x6B006B6B006B6B00, +0xA800A8A800A8A800, 0x2B002B2B002B2B00, 0x3600363600363600, 0xA600A6A600A6A600, +0xC500C5C500C5C500, 0x8600868600868600, 0x4D004D4D004D4D00, 0x3300333300333300, +0xFD00FDFD00FDFD00, 0x6600666600666600, 0x5800585800585800, 0x9600969600969600, +0x3A003A3A003A3A00, 0x0900090900090900, 0x9500959500959500, 0x1000101000101000, +0x7800787800787800, 0xD800D8D800D8D800, 0x4200424200424200, 0xCC00CCCC00CCCC00, +0xEF00EFEF00EFEF00, 0x2600262600262600, 0xE500E5E500E5E500, 0x6100616100616100, +0x1A001A1A001A1A00, 0x3F003F3F003F3F00, 0x3B003B3B003B3B00, 0x8200828200828200, +0xB600B6B600B6B600, 0xDB00DBDB00DBDB00, 0xD400D4D400D4D400, 0x9800989800989800, +0xE800E8E800E8E800, 0x8B008B8B008B8B00, 0x0200020200020200, 0xEB00EBEB00EBEB00, +0x0A000A0A000A0A00, 0x2C002C2C002C2C00, 0x1D001D1D001D1D00, 0xB000B0B000B0B000, +0x6F006F6F006F6F00, 0x8D008D8D008D8D00, 0x8800888800888800, 0x0E000E0E000E0E00, +0x1900191900191900, 0x8700878700878700, 0x4E004E4E004E4E00, 0x0B000B0B000B0B00, +0xA900A9A900A9A900, 0x0C000C0C000C0C00, 0x7900797900797900, 0x1100111100111100, +0x7F007F7F007F7F00, 0x2200222200222200, 0xE700E7E700E7E700, 0x5900595900595900, +0xE100E1E100E1E100, 0xDA00DADA00DADA00, 0x3D003D3D003D3D00, 0xC800C8C800C8C800, +0x1200121200121200, 0x0400040400040400, 0x7400747400747400, 0x5400545400545400, +0x3000303000303000, 0x7E007E7E007E7E00, 0xB400B4B400B4B400, 0x2800282800282800, +0x5500555500555500, 0x6800686800686800, 0x5000505000505000, 0xBE00BEBE00BEBE00, +0xD000D0D000D0D000, 0xC400C4C400C4C400, 0x3100313100313100, 0xCB00CBCB00CBCB00, +0x2A002A2A002A2A00, 0xAD00ADAD00ADAD00, 0x0F000F0F000F0F00, 0xCA00CACA00CACA00, +0x7000707000707000, 0xFF00FFFF00FFFF00, 0x3200323200323200, 0x6900696900696900, +0x0800080800080800, 0x6200626200626200, 0x0000000000000000, 0x2400242400242400, +0xD100D1D100D1D100, 0xFB00FBFB00FBFB00, 0xBA00BABA00BABA00, 0xED00EDED00EDED00, +0x4500454500454500, 0x8100818100818100, 0x7300737300737300, 0x6D006D6D006D6D00, +0x8400848400848400, 0x9F009F9F009F9F00, 0xEE00EEEE00EEEE00, 0x4A004A4A004A4A00, +0xC300C3C300C3C300, 0x2E002E2E002E2E00, 0xC100C1C100C1C100, 0x0100010100010100, +0xE600E6E600E6E600, 0x2500252500252500, 0x4800484800484800, 0x9900999900999900, +0xB900B9B900B9B900, 0xB300B3B300B3B300, 0x7B007B7B007B7B00, 0xF900F9F900F9F900, +0xCE00CECE00CECE00, 0xBF00BFBF00BFBF00, 0xDF00DFDF00DFDF00, 0x7100717100717100, +0x2900292900292900, 0xCD00CDCD00CDCD00, 0x6C006C6C006C6C00, 0x1300131300131300, +0x6400646400646400, 0x9B009B9B009B9B00, 0x6300636300636300, 0x9D009D9D009D9D00, +0xC000C0C000C0C000, 0x4B004B4B004B4B00, 0xB700B7B700B7B700, 0xA500A5A500A5A500, +0x8900898900898900, 0x5F005F5F005F5F00, 0xB100B1B100B1B100, 0x1700171700171700, +0xF400F4F400F4F400, 0xBC00BCBC00BCBC00, 0xD300D3D300D3D300, 0x4600464600464600, +0xCF00CFCF00CFCF00, 0x3700373700373700, 0x5E005E5E005E5E00, 0x4700474700474700, +0x9400949400949400, 0xFA00FAFA00FAFA00, 0xFC00FCFC00FCFC00, 0x5B005B5B005B5B00, +0x9700979700979700, 0xFE00FEFE00FEFE00, 0x5A005A5A005A5A00, 0xAC00ACAC00ACAC00, +0x3C003C3C003C3C00, 0x4C004C4C004C4C00, 0x0300030300030300, 0x3500353500353500, +0xF300F3F300F3F300, 0x2300232300232300, 0xB800B8B800B8B800, 0x5D005D5D005D5D00, +0x6A006A6A006A6A00, 0x9200929200929200, 0xD500D5D500D5D500, 0x2100212100212100, +0x4400444400444400, 0x5100515100515100, 0xC600C6C600C6C600, 0x7D007D7D007D7D00, +0x3900393900393900, 0x8300838300838300, 0xDC00DCDC00DCDC00, 0xAA00AAAA00AAAA00, +0x7C007C7C007C7C00, 0x7700777700777700, 0x5600565600565600, 0x0500050500050500, +0x1B001B1B001B1B00, 0xA400A4A400A4A400, 0x1500151500151500, 0x3400343400343400, +0x1E001E1E001E1E00, 0x1C001C1C001C1C00, 0xF800F8F800F8F800, 0x5200525200525200, +0x2000202000202000, 0x1400141400141400, 0xE900E9E900E9E900, 0xBD00BDBD00BDBD00, +0xDD00DDDD00DDDD00, 0xE400E4E400E4E400, 0xA100A1A100A1A100, 0xE000E0E000E0E000, +0x8A008A8A008A8A00, 0xF100F1F100F1F100, 0xD600D6D600D6D600, 0x7A007A7A007A7A00, +0xBB00BBBB00BBBB00, 0xE300E3E300E3E300, 0x4000404000404000, 0x4F004F4F004F4F00 }; + +const u64bit Camellia_SBOX4[256] = { +0x7070007000007070, 0x2C2C002C00002C2C, 0xB3B300B30000B3B3, 0xC0C000C00000C0C0, +0xE4E400E40000E4E4, 0x5757005700005757, 0xEAEA00EA0000EAEA, 0xAEAE00AE0000AEAE, +0x2323002300002323, 0x6B6B006B00006B6B, 0x4545004500004545, 0xA5A500A50000A5A5, +0xEDED00ED0000EDED, 0x4F4F004F00004F4F, 0x1D1D001D00001D1D, 0x9292009200009292, +0x8686008600008686, 0xAFAF00AF0000AFAF, 0x7C7C007C00007C7C, 0x1F1F001F00001F1F, +0x3E3E003E00003E3E, 0xDCDC00DC0000DCDC, 0x5E5E005E00005E5E, 0x0B0B000B00000B0B, +0xA6A600A60000A6A6, 0x3939003900003939, 0xD5D500D50000D5D5, 0x5D5D005D00005D5D, +0xD9D900D90000D9D9, 0x5A5A005A00005A5A, 0x5151005100005151, 0x6C6C006C00006C6C, +0x8B8B008B00008B8B, 0x9A9A009A00009A9A, 0xFBFB00FB0000FBFB, 0xB0B000B00000B0B0, +0x7474007400007474, 0x2B2B002B00002B2B, 0xF0F000F00000F0F0, 0x8484008400008484, +0xDFDF00DF0000DFDF, 0xCBCB00CB0000CBCB, 0x3434003400003434, 0x7676007600007676, +0x6D6D006D00006D6D, 0xA9A900A90000A9A9, 0xD1D100D10000D1D1, 0x0404000400000404, +0x1414001400001414, 0x3A3A003A00003A3A, 0xDEDE00DE0000DEDE, 0x1111001100001111, +0x3232003200003232, 0x9C9C009C00009C9C, 0x5353005300005353, 0xF2F200F20000F2F2, +0xFEFE00FE0000FEFE, 0xCFCF00CF0000CFCF, 0xC3C300C30000C3C3, 0x7A7A007A00007A7A, +0x2424002400002424, 0xE8E800E80000E8E8, 0x6060006000006060, 0x6969006900006969, +0xAAAA00AA0000AAAA, 0xA0A000A00000A0A0, 0xA1A100A10000A1A1, 0x6262006200006262, +0x5454005400005454, 0x1E1E001E00001E1E, 0xE0E000E00000E0E0, 0x6464006400006464, +0x1010001000001010, 0x0000000000000000, 0xA3A300A30000A3A3, 0x7575007500007575, +0x8A8A008A00008A8A, 0xE6E600E60000E6E6, 0x0909000900000909, 0xDDDD00DD0000DDDD, +0x8787008700008787, 0x8383008300008383, 0xCDCD00CD0000CDCD, 0x9090009000009090, +0x7373007300007373, 0xF6F600F60000F6F6, 0x9D9D009D00009D9D, 0xBFBF00BF0000BFBF, +0x5252005200005252, 0xD8D800D80000D8D8, 0xC8C800C80000C8C8, 0xC6C600C60000C6C6, +0x8181008100008181, 0x6F6F006F00006F6F, 0x1313001300001313, 0x6363006300006363, +0xE9E900E90000E9E9, 0xA7A700A70000A7A7, 0x9F9F009F00009F9F, 0xBCBC00BC0000BCBC, +0x2929002900002929, 0xF9F900F90000F9F9, 0x2F2F002F00002F2F, 0xB4B400B40000B4B4, +0x7878007800007878, 0x0606000600000606, 0xE7E700E70000E7E7, 0x7171007100007171, +0xD4D400D40000D4D4, 0xABAB00AB0000ABAB, 0x8888008800008888, 0x8D8D008D00008D8D, +0x7272007200007272, 0xB9B900B90000B9B9, 0xF8F800F80000F8F8, 0xACAC00AC0000ACAC, +0x3636003600003636, 0x2A2A002A00002A2A, 0x3C3C003C00003C3C, 0xF1F100F10000F1F1, +0x4040004000004040, 0xD3D300D30000D3D3, 0xBBBB00BB0000BBBB, 0x4343004300004343, +0x1515001500001515, 0xADAD00AD0000ADAD, 0x7777007700007777, 0x8080008000008080, +0x8282008200008282, 0xECEC00EC0000ECEC, 0x2727002700002727, 0xE5E500E50000E5E5, +0x8585008500008585, 0x3535003500003535, 0x0C0C000C00000C0C, 0x4141004100004141, +0xEFEF00EF0000EFEF, 0x9393009300009393, 0x1919001900001919, 0x2121002100002121, +0x0E0E000E00000E0E, 0x4E4E004E00004E4E, 0x6565006500006565, 0xBDBD00BD0000BDBD, +0xB8B800B80000B8B8, 0x8F8F008F00008F8F, 0xEBEB00EB0000EBEB, 0xCECE00CE0000CECE, +0x3030003000003030, 0x5F5F005F00005F5F, 0xC5C500C50000C5C5, 0x1A1A001A00001A1A, +0xE1E100E10000E1E1, 0xCACA00CA0000CACA, 0x4747004700004747, 0x3D3D003D00003D3D, +0x0101000100000101, 0xD6D600D60000D6D6, 0x5656005600005656, 0x4D4D004D00004D4D, +0x0D0D000D00000D0D, 0x6666006600006666, 0xCCCC00CC0000CCCC, 0x2D2D002D00002D2D, +0x1212001200001212, 0x2020002000002020, 0xB1B100B10000B1B1, 0x9999009900009999, +0x4C4C004C00004C4C, 0xC2C200C20000C2C2, 0x7E7E007E00007E7E, 0x0505000500000505, +0xB7B700B70000B7B7, 0x3131003100003131, 0x1717001700001717, 0xD7D700D70000D7D7, +0x5858005800005858, 0x6161006100006161, 0x1B1B001B00001B1B, 0x1C1C001C00001C1C, +0x0F0F000F00000F0F, 0x1616001600001616, 0x1818001800001818, 0x2222002200002222, +0x4444004400004444, 0xB2B200B20000B2B2, 0xB5B500B50000B5B5, 0x9191009100009191, +0x0808000800000808, 0xA8A800A80000A8A8, 0xFCFC00FC0000FCFC, 0x5050005000005050, +0xD0D000D00000D0D0, 0x7D7D007D00007D7D, 0x8989008900008989, 0x9797009700009797, +0x5B5B005B00005B5B, 0x9595009500009595, 0xFFFF00FF0000FFFF, 0xD2D200D20000D2D2, +0xC4C400C40000C4C4, 0x4848004800004848, 0xF7F700F70000F7F7, 0xDBDB00DB0000DBDB, +0x0303000300000303, 0xDADA00DA0000DADA, 0x3F3F003F00003F3F, 0x9494009400009494, +0x5C5C005C00005C5C, 0x0202000200000202, 0x4A4A004A00004A4A, 0x3333003300003333, +0x6767006700006767, 0xF3F300F30000F3F3, 0x7F7F007F00007F7F, 0xE2E200E20000E2E2, +0x9B9B009B00009B9B, 0x2626002600002626, 0x3737003700003737, 0x3B3B003B00003B3B, +0x9696009600009696, 0x4B4B004B00004B4B, 0xBEBE00BE0000BEBE, 0x2E2E002E00002E2E, +0x7979007900007979, 0x8C8C008C00008C8C, 0x6E6E006E00006E6E, 0x8E8E008E00008E8E, +0xF5F500F50000F5F5, 0xB6B600B60000B6B6, 0xFDFD00FD0000FDFD, 0x5959005900005959, +0x9898009800009898, 0x6A6A006A00006A6A, 0x4646004600004646, 0xBABA00BA0000BABA, +0x2525002500002525, 0x4242004200004242, 0xA2A200A20000A2A2, 0xFAFA00FA0000FAFA, +0x0707000700000707, 0x5555005500005555, 0xEEEE00EE0000EEEE, 0x0A0A000A00000A0A, +0x4949004900004949, 0x6868006800006868, 0x3838003800003838, 0xA4A400A40000A4A4, +0x2828002800002828, 0x7B7B007B00007B7B, 0xC9C900C90000C9C9, 0xC1C100C10000C1C1, +0xE3E300E30000E3E3, 0xF4F400F40000F4F4, 0xC7C700C70000C7C7, 0x9E9E009E00009E9E }; + +const u64bit Camellia_SBOX5[256] = { +0x00E0E0E000E0E0E0, 0x0005050500050505, 0x0058585800585858, 0x00D9D9D900D9D9D9, +0x0067676700676767, 0x004E4E4E004E4E4E, 0x0081818100818181, 0x00CBCBCB00CBCBCB, +0x00C9C9C900C9C9C9, 0x000B0B0B000B0B0B, 0x00AEAEAE00AEAEAE, 0x006A6A6A006A6A6A, +0x00D5D5D500D5D5D5, 0x0018181800181818, 0x005D5D5D005D5D5D, 0x0082828200828282, +0x0046464600464646, 0x00DFDFDF00DFDFDF, 0x00D6D6D600D6D6D6, 0x0027272700272727, +0x008A8A8A008A8A8A, 0x0032323200323232, 0x004B4B4B004B4B4B, 0x0042424200424242, +0x00DBDBDB00DBDBDB, 0x001C1C1C001C1C1C, 0x009E9E9E009E9E9E, 0x009C9C9C009C9C9C, +0x003A3A3A003A3A3A, 0x00CACACA00CACACA, 0x0025252500252525, 0x007B7B7B007B7B7B, +0x000D0D0D000D0D0D, 0x0071717100717171, 0x005F5F5F005F5F5F, 0x001F1F1F001F1F1F, +0x00F8F8F800F8F8F8, 0x00D7D7D700D7D7D7, 0x003E3E3E003E3E3E, 0x009D9D9D009D9D9D, +0x007C7C7C007C7C7C, 0x0060606000606060, 0x00B9B9B900B9B9B9, 0x00BEBEBE00BEBEBE, +0x00BCBCBC00BCBCBC, 0x008B8B8B008B8B8B, 0x0016161600161616, 0x0034343400343434, +0x004D4D4D004D4D4D, 0x00C3C3C300C3C3C3, 0x0072727200727272, 0x0095959500959595, +0x00ABABAB00ABABAB, 0x008E8E8E008E8E8E, 0x00BABABA00BABABA, 0x007A7A7A007A7A7A, +0x00B3B3B300B3B3B3, 0x0002020200020202, 0x00B4B4B400B4B4B4, 0x00ADADAD00ADADAD, +0x00A2A2A200A2A2A2, 0x00ACACAC00ACACAC, 0x00D8D8D800D8D8D8, 0x009A9A9A009A9A9A, +0x0017171700171717, 0x001A1A1A001A1A1A, 0x0035353500353535, 0x00CCCCCC00CCCCCC, +0x00F7F7F700F7F7F7, 0x0099999900999999, 0x0061616100616161, 0x005A5A5A005A5A5A, +0x00E8E8E800E8E8E8, 0x0024242400242424, 0x0056565600565656, 0x0040404000404040, +0x00E1E1E100E1E1E1, 0x0063636300636363, 0x0009090900090909, 0x0033333300333333, +0x00BFBFBF00BFBFBF, 0x0098989800989898, 0x0097979700979797, 0x0085858500858585, +0x0068686800686868, 0x00FCFCFC00FCFCFC, 0x00ECECEC00ECECEC, 0x000A0A0A000A0A0A, +0x00DADADA00DADADA, 0x006F6F6F006F6F6F, 0x0053535300535353, 0x0062626200626262, +0x00A3A3A300A3A3A3, 0x002E2E2E002E2E2E, 0x0008080800080808, 0x00AFAFAF00AFAFAF, +0x0028282800282828, 0x00B0B0B000B0B0B0, 0x0074747400747474, 0x00C2C2C200C2C2C2, +0x00BDBDBD00BDBDBD, 0x0036363600363636, 0x0022222200222222, 0x0038383800383838, +0x0064646400646464, 0x001E1E1E001E1E1E, 0x0039393900393939, 0x002C2C2C002C2C2C, +0x00A6A6A600A6A6A6, 0x0030303000303030, 0x00E5E5E500E5E5E5, 0x0044444400444444, +0x00FDFDFD00FDFDFD, 0x0088888800888888, 0x009F9F9F009F9F9F, 0x0065656500656565, +0x0087878700878787, 0x006B6B6B006B6B6B, 0x00F4F4F400F4F4F4, 0x0023232300232323, +0x0048484800484848, 0x0010101000101010, 0x00D1D1D100D1D1D1, 0x0051515100515151, +0x00C0C0C000C0C0C0, 0x00F9F9F900F9F9F9, 0x00D2D2D200D2D2D2, 0x00A0A0A000A0A0A0, +0x0055555500555555, 0x00A1A1A100A1A1A1, 0x0041414100414141, 0x00FAFAFA00FAFAFA, +0x0043434300434343, 0x0013131300131313, 0x00C4C4C400C4C4C4, 0x002F2F2F002F2F2F, +0x00A8A8A800A8A8A8, 0x00B6B6B600B6B6B6, 0x003C3C3C003C3C3C, 0x002B2B2B002B2B2B, +0x00C1C1C100C1C1C1, 0x00FFFFFF00FFFFFF, 0x00C8C8C800C8C8C8, 0x00A5A5A500A5A5A5, +0x0020202000202020, 0x0089898900898989, 0x0000000000000000, 0x0090909000909090, +0x0047474700474747, 0x00EFEFEF00EFEFEF, 0x00EAEAEA00EAEAEA, 0x00B7B7B700B7B7B7, +0x0015151500151515, 0x0006060600060606, 0x00CDCDCD00CDCDCD, 0x00B5B5B500B5B5B5, +0x0012121200121212, 0x007E7E7E007E7E7E, 0x00BBBBBB00BBBBBB, 0x0029292900292929, +0x000F0F0F000F0F0F, 0x00B8B8B800B8B8B8, 0x0007070700070707, 0x0004040400040404, +0x009B9B9B009B9B9B, 0x0094949400949494, 0x0021212100212121, 0x0066666600666666, +0x00E6E6E600E6E6E6, 0x00CECECE00CECECE, 0x00EDEDED00EDEDED, 0x00E7E7E700E7E7E7, +0x003B3B3B003B3B3B, 0x00FEFEFE00FEFEFE, 0x007F7F7F007F7F7F, 0x00C5C5C500C5C5C5, +0x00A4A4A400A4A4A4, 0x0037373700373737, 0x00B1B1B100B1B1B1, 0x004C4C4C004C4C4C, +0x0091919100919191, 0x006E6E6E006E6E6E, 0x008D8D8D008D8D8D, 0x0076767600767676, +0x0003030300030303, 0x002D2D2D002D2D2D, 0x00DEDEDE00DEDEDE, 0x0096969600969696, +0x0026262600262626, 0x007D7D7D007D7D7D, 0x00C6C6C600C6C6C6, 0x005C5C5C005C5C5C, +0x00D3D3D300D3D3D3, 0x00F2F2F200F2F2F2, 0x004F4F4F004F4F4F, 0x0019191900191919, +0x003F3F3F003F3F3F, 0x00DCDCDC00DCDCDC, 0x0079797900797979, 0x001D1D1D001D1D1D, +0x0052525200525252, 0x00EBEBEB00EBEBEB, 0x00F3F3F300F3F3F3, 0x006D6D6D006D6D6D, +0x005E5E5E005E5E5E, 0x00FBFBFB00FBFBFB, 0x0069696900696969, 0x00B2B2B200B2B2B2, +0x00F0F0F000F0F0F0, 0x0031313100313131, 0x000C0C0C000C0C0C, 0x00D4D4D400D4D4D4, +0x00CFCFCF00CFCFCF, 0x008C8C8C008C8C8C, 0x00E2E2E200E2E2E2, 0x0075757500757575, +0x00A9A9A900A9A9A9, 0x004A4A4A004A4A4A, 0x0057575700575757, 0x0084848400848484, +0x0011111100111111, 0x0045454500454545, 0x001B1B1B001B1B1B, 0x00F5F5F500F5F5F5, +0x00E4E4E400E4E4E4, 0x000E0E0E000E0E0E, 0x0073737300737373, 0x00AAAAAA00AAAAAA, +0x00F1F1F100F1F1F1, 0x00DDDDDD00DDDDDD, 0x0059595900595959, 0x0014141400141414, +0x006C6C6C006C6C6C, 0x0092929200929292, 0x0054545400545454, 0x00D0D0D000D0D0D0, +0x0078787800787878, 0x0070707000707070, 0x00E3E3E300E3E3E3, 0x0049494900494949, +0x0080808000808080, 0x0050505000505050, 0x00A7A7A700A7A7A7, 0x00F6F6F600F6F6F6, +0x0077777700777777, 0x0093939300939393, 0x0086868600868686, 0x0083838300838383, +0x002A2A2A002A2A2A, 0x00C7C7C700C7C7C7, 0x005B5B5B005B5B5B, 0x00E9E9E900E9E9E9, +0x00EEEEEE00EEEEEE, 0x008F8F8F008F8F8F, 0x0001010100010101, 0x003D3D3D003D3D3D }; + +const u64bit Camellia_SBOX6[256] = { +0x3800383838003838, 0x4100414141004141, 0x1600161616001616, 0x7600767676007676, +0xD900D9D9D900D9D9, 0x9300939393009393, 0x6000606060006060, 0xF200F2F2F200F2F2, +0x7200727272007272, 0xC200C2C2C200C2C2, 0xAB00ABABAB00ABAB, 0x9A009A9A9A009A9A, +0x7500757575007575, 0x0600060606000606, 0x5700575757005757, 0xA000A0A0A000A0A0, +0x9100919191009191, 0xF700F7F7F700F7F7, 0xB500B5B5B500B5B5, 0xC900C9C9C900C9C9, +0xA200A2A2A200A2A2, 0x8C008C8C8C008C8C, 0xD200D2D2D200D2D2, 0x9000909090009090, +0xF600F6F6F600F6F6, 0x0700070707000707, 0xA700A7A7A700A7A7, 0x2700272727002727, +0x8E008E8E8E008E8E, 0xB200B2B2B200B2B2, 0x4900494949004949, 0xDE00DEDEDE00DEDE, +0x4300434343004343, 0x5C005C5C5C005C5C, 0xD700D7D7D700D7D7, 0xC700C7C7C700C7C7, +0x3E003E3E3E003E3E, 0xF500F5F5F500F5F5, 0x8F008F8F8F008F8F, 0x6700676767006767, +0x1F001F1F1F001F1F, 0x1800181818001818, 0x6E006E6E6E006E6E, 0xAF00AFAFAF00AFAF, +0x2F002F2F2F002F2F, 0xE200E2E2E200E2E2, 0x8500858585008585, 0x0D000D0D0D000D0D, +0x5300535353005353, 0xF000F0F0F000F0F0, 0x9C009C9C9C009C9C, 0x6500656565006565, +0xEA00EAEAEA00EAEA, 0xA300A3A3A300A3A3, 0xAE00AEAEAE00AEAE, 0x9E009E9E9E009E9E, +0xEC00ECECEC00ECEC, 0x8000808080008080, 0x2D002D2D2D002D2D, 0x6B006B6B6B006B6B, +0xA800A8A8A800A8A8, 0x2B002B2B2B002B2B, 0x3600363636003636, 0xA600A6A6A600A6A6, +0xC500C5C5C500C5C5, 0x8600868686008686, 0x4D004D4D4D004D4D, 0x3300333333003333, +0xFD00FDFDFD00FDFD, 0x6600666666006666, 0x5800585858005858, 0x9600969696009696, +0x3A003A3A3A003A3A, 0x0900090909000909, 0x9500959595009595, 0x1000101010001010, +0x7800787878007878, 0xD800D8D8D800D8D8, 0x4200424242004242, 0xCC00CCCCCC00CCCC, +0xEF00EFEFEF00EFEF, 0x2600262626002626, 0xE500E5E5E500E5E5, 0x6100616161006161, +0x1A001A1A1A001A1A, 0x3F003F3F3F003F3F, 0x3B003B3B3B003B3B, 0x8200828282008282, +0xB600B6B6B600B6B6, 0xDB00DBDBDB00DBDB, 0xD400D4D4D400D4D4, 0x9800989898009898, +0xE800E8E8E800E8E8, 0x8B008B8B8B008B8B, 0x0200020202000202, 0xEB00EBEBEB00EBEB, +0x0A000A0A0A000A0A, 0x2C002C2C2C002C2C, 0x1D001D1D1D001D1D, 0xB000B0B0B000B0B0, +0x6F006F6F6F006F6F, 0x8D008D8D8D008D8D, 0x8800888888008888, 0x0E000E0E0E000E0E, +0x1900191919001919, 0x8700878787008787, 0x4E004E4E4E004E4E, 0x0B000B0B0B000B0B, +0xA900A9A9A900A9A9, 0x0C000C0C0C000C0C, 0x7900797979007979, 0x1100111111001111, +0x7F007F7F7F007F7F, 0x2200222222002222, 0xE700E7E7E700E7E7, 0x5900595959005959, +0xE100E1E1E100E1E1, 0xDA00DADADA00DADA, 0x3D003D3D3D003D3D, 0xC800C8C8C800C8C8, +0x1200121212001212, 0x0400040404000404, 0x7400747474007474, 0x5400545454005454, +0x3000303030003030, 0x7E007E7E7E007E7E, 0xB400B4B4B400B4B4, 0x2800282828002828, +0x5500555555005555, 0x6800686868006868, 0x5000505050005050, 0xBE00BEBEBE00BEBE, +0xD000D0D0D000D0D0, 0xC400C4C4C400C4C4, 0x3100313131003131, 0xCB00CBCBCB00CBCB, +0x2A002A2A2A002A2A, 0xAD00ADADAD00ADAD, 0x0F000F0F0F000F0F, 0xCA00CACACA00CACA, +0x7000707070007070, 0xFF00FFFFFF00FFFF, 0x3200323232003232, 0x6900696969006969, +0x0800080808000808, 0x6200626262006262, 0x0000000000000000, 0x2400242424002424, +0xD100D1D1D100D1D1, 0xFB00FBFBFB00FBFB, 0xBA00BABABA00BABA, 0xED00EDEDED00EDED, +0x4500454545004545, 0x8100818181008181, 0x7300737373007373, 0x6D006D6D6D006D6D, +0x8400848484008484, 0x9F009F9F9F009F9F, 0xEE00EEEEEE00EEEE, 0x4A004A4A4A004A4A, +0xC300C3C3C300C3C3, 0x2E002E2E2E002E2E, 0xC100C1C1C100C1C1, 0x0100010101000101, +0xE600E6E6E600E6E6, 0x2500252525002525, 0x4800484848004848, 0x9900999999009999, +0xB900B9B9B900B9B9, 0xB300B3B3B300B3B3, 0x7B007B7B7B007B7B, 0xF900F9F9F900F9F9, +0xCE00CECECE00CECE, 0xBF00BFBFBF00BFBF, 0xDF00DFDFDF00DFDF, 0x7100717171007171, +0x2900292929002929, 0xCD00CDCDCD00CDCD, 0x6C006C6C6C006C6C, 0x1300131313001313, +0x6400646464006464, 0x9B009B9B9B009B9B, 0x6300636363006363, 0x9D009D9D9D009D9D, +0xC000C0C0C000C0C0, 0x4B004B4B4B004B4B, 0xB700B7B7B700B7B7, 0xA500A5A5A500A5A5, +0x8900898989008989, 0x5F005F5F5F005F5F, 0xB100B1B1B100B1B1, 0x1700171717001717, +0xF400F4F4F400F4F4, 0xBC00BCBCBC00BCBC, 0xD300D3D3D300D3D3, 0x4600464646004646, +0xCF00CFCFCF00CFCF, 0x3700373737003737, 0x5E005E5E5E005E5E, 0x4700474747004747, +0x9400949494009494, 0xFA00FAFAFA00FAFA, 0xFC00FCFCFC00FCFC, 0x5B005B5B5B005B5B, +0x9700979797009797, 0xFE00FEFEFE00FEFE, 0x5A005A5A5A005A5A, 0xAC00ACACAC00ACAC, +0x3C003C3C3C003C3C, 0x4C004C4C4C004C4C, 0x0300030303000303, 0x3500353535003535, +0xF300F3F3F300F3F3, 0x2300232323002323, 0xB800B8B8B800B8B8, 0x5D005D5D5D005D5D, +0x6A006A6A6A006A6A, 0x9200929292009292, 0xD500D5D5D500D5D5, 0x2100212121002121, +0x4400444444004444, 0x5100515151005151, 0xC600C6C6C600C6C6, 0x7D007D7D7D007D7D, +0x3900393939003939, 0x8300838383008383, 0xDC00DCDCDC00DCDC, 0xAA00AAAAAA00AAAA, +0x7C007C7C7C007C7C, 0x7700777777007777, 0x5600565656005656, 0x0500050505000505, +0x1B001B1B1B001B1B, 0xA400A4A4A400A4A4, 0x1500151515001515, 0x3400343434003434, +0x1E001E1E1E001E1E, 0x1C001C1C1C001C1C, 0xF800F8F8F800F8F8, 0x5200525252005252, +0x2000202020002020, 0x1400141414001414, 0xE900E9E9E900E9E9, 0xBD00BDBDBD00BDBD, +0xDD00DDDDDD00DDDD, 0xE400E4E4E400E4E4, 0xA100A1A1A100A1A1, 0xE000E0E0E000E0E0, +0x8A008A8A8A008A8A, 0xF100F1F1F100F1F1, 0xD600D6D6D600D6D6, 0x7A007A7A7A007A7A, +0xBB00BBBBBB00BBBB, 0xE300E3E3E300E3E3, 0x4000404040004040, 0x4F004F4F4F004F4F }; + +const u64bit Camellia_SBOX7[256] = { +0x7070007070700070, 0x2C2C002C2C2C002C, 0xB3B300B3B3B300B3, 0xC0C000C0C0C000C0, +0xE4E400E4E4E400E4, 0x5757005757570057, 0xEAEA00EAEAEA00EA, 0xAEAE00AEAEAE00AE, +0x2323002323230023, 0x6B6B006B6B6B006B, 0x4545004545450045, 0xA5A500A5A5A500A5, +0xEDED00EDEDED00ED, 0x4F4F004F4F4F004F, 0x1D1D001D1D1D001D, 0x9292009292920092, +0x8686008686860086, 0xAFAF00AFAFAF00AF, 0x7C7C007C7C7C007C, 0x1F1F001F1F1F001F, +0x3E3E003E3E3E003E, 0xDCDC00DCDCDC00DC, 0x5E5E005E5E5E005E, 0x0B0B000B0B0B000B, +0xA6A600A6A6A600A6, 0x3939003939390039, 0xD5D500D5D5D500D5, 0x5D5D005D5D5D005D, +0xD9D900D9D9D900D9, 0x5A5A005A5A5A005A, 0x5151005151510051, 0x6C6C006C6C6C006C, +0x8B8B008B8B8B008B, 0x9A9A009A9A9A009A, 0xFBFB00FBFBFB00FB, 0xB0B000B0B0B000B0, +0x7474007474740074, 0x2B2B002B2B2B002B, 0xF0F000F0F0F000F0, 0x8484008484840084, +0xDFDF00DFDFDF00DF, 0xCBCB00CBCBCB00CB, 0x3434003434340034, 0x7676007676760076, +0x6D6D006D6D6D006D, 0xA9A900A9A9A900A9, 0xD1D100D1D1D100D1, 0x0404000404040004, +0x1414001414140014, 0x3A3A003A3A3A003A, 0xDEDE00DEDEDE00DE, 0x1111001111110011, +0x3232003232320032, 0x9C9C009C9C9C009C, 0x5353005353530053, 0xF2F200F2F2F200F2, +0xFEFE00FEFEFE00FE, 0xCFCF00CFCFCF00CF, 0xC3C300C3C3C300C3, 0x7A7A007A7A7A007A, +0x2424002424240024, 0xE8E800E8E8E800E8, 0x6060006060600060, 0x6969006969690069, +0xAAAA00AAAAAA00AA, 0xA0A000A0A0A000A0, 0xA1A100A1A1A100A1, 0x6262006262620062, +0x5454005454540054, 0x1E1E001E1E1E001E, 0xE0E000E0E0E000E0, 0x6464006464640064, +0x1010001010100010, 0x0000000000000000, 0xA3A300A3A3A300A3, 0x7575007575750075, +0x8A8A008A8A8A008A, 0xE6E600E6E6E600E6, 0x0909000909090009, 0xDDDD00DDDDDD00DD, +0x8787008787870087, 0x8383008383830083, 0xCDCD00CDCDCD00CD, 0x9090009090900090, +0x7373007373730073, 0xF6F600F6F6F600F6, 0x9D9D009D9D9D009D, 0xBFBF00BFBFBF00BF, +0x5252005252520052, 0xD8D800D8D8D800D8, 0xC8C800C8C8C800C8, 0xC6C600C6C6C600C6, +0x8181008181810081, 0x6F6F006F6F6F006F, 0x1313001313130013, 0x6363006363630063, +0xE9E900E9E9E900E9, 0xA7A700A7A7A700A7, 0x9F9F009F9F9F009F, 0xBCBC00BCBCBC00BC, +0x2929002929290029, 0xF9F900F9F9F900F9, 0x2F2F002F2F2F002F, 0xB4B400B4B4B400B4, +0x7878007878780078, 0x0606000606060006, 0xE7E700E7E7E700E7, 0x7171007171710071, +0xD4D400D4D4D400D4, 0xABAB00ABABAB00AB, 0x8888008888880088, 0x8D8D008D8D8D008D, +0x7272007272720072, 0xB9B900B9B9B900B9, 0xF8F800F8F8F800F8, 0xACAC00ACACAC00AC, +0x3636003636360036, 0x2A2A002A2A2A002A, 0x3C3C003C3C3C003C, 0xF1F100F1F1F100F1, +0x4040004040400040, 0xD3D300D3D3D300D3, 0xBBBB00BBBBBB00BB, 0x4343004343430043, +0x1515001515150015, 0xADAD00ADADAD00AD, 0x7777007777770077, 0x8080008080800080, +0x8282008282820082, 0xECEC00ECECEC00EC, 0x2727002727270027, 0xE5E500E5E5E500E5, +0x8585008585850085, 0x3535003535350035, 0x0C0C000C0C0C000C, 0x4141004141410041, +0xEFEF00EFEFEF00EF, 0x9393009393930093, 0x1919001919190019, 0x2121002121210021, +0x0E0E000E0E0E000E, 0x4E4E004E4E4E004E, 0x6565006565650065, 0xBDBD00BDBDBD00BD, +0xB8B800B8B8B800B8, 0x8F8F008F8F8F008F, 0xEBEB00EBEBEB00EB, 0xCECE00CECECE00CE, +0x3030003030300030, 0x5F5F005F5F5F005F, 0xC5C500C5C5C500C5, 0x1A1A001A1A1A001A, +0xE1E100E1E1E100E1, 0xCACA00CACACA00CA, 0x4747004747470047, 0x3D3D003D3D3D003D, +0x0101000101010001, 0xD6D600D6D6D600D6, 0x5656005656560056, 0x4D4D004D4D4D004D, +0x0D0D000D0D0D000D, 0x6666006666660066, 0xCCCC00CCCCCC00CC, 0x2D2D002D2D2D002D, +0x1212001212120012, 0x2020002020200020, 0xB1B100B1B1B100B1, 0x9999009999990099, +0x4C4C004C4C4C004C, 0xC2C200C2C2C200C2, 0x7E7E007E7E7E007E, 0x0505000505050005, +0xB7B700B7B7B700B7, 0x3131003131310031, 0x1717001717170017, 0xD7D700D7D7D700D7, +0x5858005858580058, 0x6161006161610061, 0x1B1B001B1B1B001B, 0x1C1C001C1C1C001C, +0x0F0F000F0F0F000F, 0x1616001616160016, 0x1818001818180018, 0x2222002222220022, +0x4444004444440044, 0xB2B200B2B2B200B2, 0xB5B500B5B5B500B5, 0x9191009191910091, +0x0808000808080008, 0xA8A800A8A8A800A8, 0xFCFC00FCFCFC00FC, 0x5050005050500050, +0xD0D000D0D0D000D0, 0x7D7D007D7D7D007D, 0x8989008989890089, 0x9797009797970097, +0x5B5B005B5B5B005B, 0x9595009595950095, 0xFFFF00FFFFFF00FF, 0xD2D200D2D2D200D2, +0xC4C400C4C4C400C4, 0x4848004848480048, 0xF7F700F7F7F700F7, 0xDBDB00DBDBDB00DB, +0x0303000303030003, 0xDADA00DADADA00DA, 0x3F3F003F3F3F003F, 0x9494009494940094, +0x5C5C005C5C5C005C, 0x0202000202020002, 0x4A4A004A4A4A004A, 0x3333003333330033, +0x6767006767670067, 0xF3F300F3F3F300F3, 0x7F7F007F7F7F007F, 0xE2E200E2E2E200E2, +0x9B9B009B9B9B009B, 0x2626002626260026, 0x3737003737370037, 0x3B3B003B3B3B003B, +0x9696009696960096, 0x4B4B004B4B4B004B, 0xBEBE00BEBEBE00BE, 0x2E2E002E2E2E002E, +0x7979007979790079, 0x8C8C008C8C8C008C, 0x6E6E006E6E6E006E, 0x8E8E008E8E8E008E, +0xF5F500F5F5F500F5, 0xB6B600B6B6B600B6, 0xFDFD00FDFDFD00FD, 0x5959005959590059, +0x9898009898980098, 0x6A6A006A6A6A006A, 0x4646004646460046, 0xBABA00BABABA00BA, +0x2525002525250025, 0x4242004242420042, 0xA2A200A2A2A200A2, 0xFAFA00FAFAFA00FA, +0x0707000707070007, 0x5555005555550055, 0xEEEE00EEEEEE00EE, 0x0A0A000A0A0A000A, +0x4949004949490049, 0x6868006868680068, 0x3838003838380038, 0xA4A400A4A4A400A4, +0x2828002828280028, 0x7B7B007B7B7B007B, 0xC9C900C9C9C900C9, 0xC1C100C1C1C100C1, +0xE3E300E3E3E300E3, 0xF4F400F4F4F400F4, 0xC7C700C7C7C700C7, 0x9E9E009E9E9E009E }; + +const u64bit Camellia_SBOX8[256] = { +0x7070700070707000, 0x8282820082828200, 0x2C2C2C002C2C2C00, 0xECECEC00ECECEC00, +0xB3B3B300B3B3B300, 0x2727270027272700, 0xC0C0C000C0C0C000, 0xE5E5E500E5E5E500, +0xE4E4E400E4E4E400, 0x8585850085858500, 0x5757570057575700, 0x3535350035353500, +0xEAEAEA00EAEAEA00, 0x0C0C0C000C0C0C00, 0xAEAEAE00AEAEAE00, 0x4141410041414100, +0x2323230023232300, 0xEFEFEF00EFEFEF00, 0x6B6B6B006B6B6B00, 0x9393930093939300, +0x4545450045454500, 0x1919190019191900, 0xA5A5A500A5A5A500, 0x2121210021212100, +0xEDEDED00EDEDED00, 0x0E0E0E000E0E0E00, 0x4F4F4F004F4F4F00, 0x4E4E4E004E4E4E00, +0x1D1D1D001D1D1D00, 0x6565650065656500, 0x9292920092929200, 0xBDBDBD00BDBDBD00, +0x8686860086868600, 0xB8B8B800B8B8B800, 0xAFAFAF00AFAFAF00, 0x8F8F8F008F8F8F00, +0x7C7C7C007C7C7C00, 0xEBEBEB00EBEBEB00, 0x1F1F1F001F1F1F00, 0xCECECE00CECECE00, +0x3E3E3E003E3E3E00, 0x3030300030303000, 0xDCDCDC00DCDCDC00, 0x5F5F5F005F5F5F00, +0x5E5E5E005E5E5E00, 0xC5C5C500C5C5C500, 0x0B0B0B000B0B0B00, 0x1A1A1A001A1A1A00, +0xA6A6A600A6A6A600, 0xE1E1E100E1E1E100, 0x3939390039393900, 0xCACACA00CACACA00, +0xD5D5D500D5D5D500, 0x4747470047474700, 0x5D5D5D005D5D5D00, 0x3D3D3D003D3D3D00, +0xD9D9D900D9D9D900, 0x0101010001010100, 0x5A5A5A005A5A5A00, 0xD6D6D600D6D6D600, +0x5151510051515100, 0x5656560056565600, 0x6C6C6C006C6C6C00, 0x4D4D4D004D4D4D00, +0x8B8B8B008B8B8B00, 0x0D0D0D000D0D0D00, 0x9A9A9A009A9A9A00, 0x6666660066666600, +0xFBFBFB00FBFBFB00, 0xCCCCCC00CCCCCC00, 0xB0B0B000B0B0B000, 0x2D2D2D002D2D2D00, +0x7474740074747400, 0x1212120012121200, 0x2B2B2B002B2B2B00, 0x2020200020202000, +0xF0F0F000F0F0F000, 0xB1B1B100B1B1B100, 0x8484840084848400, 0x9999990099999900, +0xDFDFDF00DFDFDF00, 0x4C4C4C004C4C4C00, 0xCBCBCB00CBCBCB00, 0xC2C2C200C2C2C200, +0x3434340034343400, 0x7E7E7E007E7E7E00, 0x7676760076767600, 0x0505050005050500, +0x6D6D6D006D6D6D00, 0xB7B7B700B7B7B700, 0xA9A9A900A9A9A900, 0x3131310031313100, +0xD1D1D100D1D1D100, 0x1717170017171700, 0x0404040004040400, 0xD7D7D700D7D7D700, +0x1414140014141400, 0x5858580058585800, 0x3A3A3A003A3A3A00, 0x6161610061616100, +0xDEDEDE00DEDEDE00, 0x1B1B1B001B1B1B00, 0x1111110011111100, 0x1C1C1C001C1C1C00, +0x3232320032323200, 0x0F0F0F000F0F0F00, 0x9C9C9C009C9C9C00, 0x1616160016161600, +0x5353530053535300, 0x1818180018181800, 0xF2F2F200F2F2F200, 0x2222220022222200, +0xFEFEFE00FEFEFE00, 0x4444440044444400, 0xCFCFCF00CFCFCF00, 0xB2B2B200B2B2B200, +0xC3C3C300C3C3C300, 0xB5B5B500B5B5B500, 0x7A7A7A007A7A7A00, 0x9191910091919100, +0x2424240024242400, 0x0808080008080800, 0xE8E8E800E8E8E800, 0xA8A8A800A8A8A800, +0x6060600060606000, 0xFCFCFC00FCFCFC00, 0x6969690069696900, 0x5050500050505000, +0xAAAAAA00AAAAAA00, 0xD0D0D000D0D0D000, 0xA0A0A000A0A0A000, 0x7D7D7D007D7D7D00, +0xA1A1A100A1A1A100, 0x8989890089898900, 0x6262620062626200, 0x9797970097979700, +0x5454540054545400, 0x5B5B5B005B5B5B00, 0x1E1E1E001E1E1E00, 0x9595950095959500, +0xE0E0E000E0E0E000, 0xFFFFFF00FFFFFF00, 0x6464640064646400, 0xD2D2D200D2D2D200, +0x1010100010101000, 0xC4C4C400C4C4C400, 0x0000000000000000, 0x4848480048484800, +0xA3A3A300A3A3A300, 0xF7F7F700F7F7F700, 0x7575750075757500, 0xDBDBDB00DBDBDB00, +0x8A8A8A008A8A8A00, 0x0303030003030300, 0xE6E6E600E6E6E600, 0xDADADA00DADADA00, +0x0909090009090900, 0x3F3F3F003F3F3F00, 0xDDDDDD00DDDDDD00, 0x9494940094949400, +0x8787870087878700, 0x5C5C5C005C5C5C00, 0x8383830083838300, 0x0202020002020200, +0xCDCDCD00CDCDCD00, 0x4A4A4A004A4A4A00, 0x9090900090909000, 0x3333330033333300, +0x7373730073737300, 0x6767670067676700, 0xF6F6F600F6F6F600, 0xF3F3F300F3F3F300, +0x9D9D9D009D9D9D00, 0x7F7F7F007F7F7F00, 0xBFBFBF00BFBFBF00, 0xE2E2E200E2E2E200, +0x5252520052525200, 0x9B9B9B009B9B9B00, 0xD8D8D800D8D8D800, 0x2626260026262600, +0xC8C8C800C8C8C800, 0x3737370037373700, 0xC6C6C600C6C6C600, 0x3B3B3B003B3B3B00, +0x8181810081818100, 0x9696960096969600, 0x6F6F6F006F6F6F00, 0x4B4B4B004B4B4B00, +0x1313130013131300, 0xBEBEBE00BEBEBE00, 0x6363630063636300, 0x2E2E2E002E2E2E00, +0xE9E9E900E9E9E900, 0x7979790079797900, 0xA7A7A700A7A7A700, 0x8C8C8C008C8C8C00, +0x9F9F9F009F9F9F00, 0x6E6E6E006E6E6E00, 0xBCBCBC00BCBCBC00, 0x8E8E8E008E8E8E00, +0x2929290029292900, 0xF5F5F500F5F5F500, 0xF9F9F900F9F9F900, 0xB6B6B600B6B6B600, +0x2F2F2F002F2F2F00, 0xFDFDFD00FDFDFD00, 0xB4B4B400B4B4B400, 0x5959590059595900, +0x7878780078787800, 0x9898980098989800, 0x0606060006060600, 0x6A6A6A006A6A6A00, +0xE7E7E700E7E7E700, 0x4646460046464600, 0x7171710071717100, 0xBABABA00BABABA00, +0xD4D4D400D4D4D400, 0x2525250025252500, 0xABABAB00ABABAB00, 0x4242420042424200, +0x8888880088888800, 0xA2A2A200A2A2A200, 0x8D8D8D008D8D8D00, 0xFAFAFA00FAFAFA00, +0x7272720072727200, 0x0707070007070700, 0xB9B9B900B9B9B900, 0x5555550055555500, +0xF8F8F800F8F8F800, 0xEEEEEE00EEEEEE00, 0xACACAC00ACACAC00, 0x0A0A0A000A0A0A00, +0x3636360036363600, 0x4949490049494900, 0x2A2A2A002A2A2A00, 0x6868680068686800, +0x3C3C3C003C3C3C00, 0x3838380038383800, 0xF1F1F100F1F1F100, 0xA4A4A400A4A4A400, +0x4040400040404000, 0x2828280028282800, 0xD3D3D300D3D3D300, 0x7B7B7B007B7B7B00, +0xBBBBBB00BBBBBB00, 0xC9C9C900C9C9C900, 0x4343430043434300, 0xC1C1C100C1C1C100, +0x1515150015151500, 0xE3E3E300E3E3E300, 0xADADAD00ADADAD00, 0xF4F4F400F4F4F400, +0x7777770077777700, 0xC7C7C700C7C7C700, 0x8080800080808000, 0x9E9E9E009E9E9E00 }; -namespace { +namespace Camellia_F { /* * We use the slow byte-wise version of F in the first and last rounds diff --git a/src/lib/block/camellia/camellia_sbox.h b/src/lib/block/camellia/camellia_sbox.h deleted file mode 100644 index 874beb4ce..000000000 --- a/src/lib/block/camellia/camellia_sbox.h +++ /dev/null @@ -1,545 +0,0 @@ -/* -* Camellia SBox Tables -* (C) 2012 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_CAMELLIA_SBOX_H__ -#define BOTAN_CAMELLIA_SBOX_H__ - -#include <botan/types.h> - -namespace Botan { - -const u64bit Camellia_SBOX1[256] = { -0x7070700070000070, 0x8282820082000082, 0x2C2C2C002C00002C, 0xECECEC00EC0000EC, -0xB3B3B300B30000B3, 0x2727270027000027, 0xC0C0C000C00000C0, 0xE5E5E500E50000E5, -0xE4E4E400E40000E4, 0x8585850085000085, 0x5757570057000057, 0x3535350035000035, -0xEAEAEA00EA0000EA, 0x0C0C0C000C00000C, 0xAEAEAE00AE0000AE, 0x4141410041000041, -0x2323230023000023, 0xEFEFEF00EF0000EF, 0x6B6B6B006B00006B, 0x9393930093000093, -0x4545450045000045, 0x1919190019000019, 0xA5A5A500A50000A5, 0x2121210021000021, -0xEDEDED00ED0000ED, 0x0E0E0E000E00000E, 0x4F4F4F004F00004F, 0x4E4E4E004E00004E, -0x1D1D1D001D00001D, 0x6565650065000065, 0x9292920092000092, 0xBDBDBD00BD0000BD, -0x8686860086000086, 0xB8B8B800B80000B8, 0xAFAFAF00AF0000AF, 0x8F8F8F008F00008F, -0x7C7C7C007C00007C, 0xEBEBEB00EB0000EB, 0x1F1F1F001F00001F, 0xCECECE00CE0000CE, -0x3E3E3E003E00003E, 0x3030300030000030, 0xDCDCDC00DC0000DC, 0x5F5F5F005F00005F, -0x5E5E5E005E00005E, 0xC5C5C500C50000C5, 0x0B0B0B000B00000B, 0x1A1A1A001A00001A, -0xA6A6A600A60000A6, 0xE1E1E100E10000E1, 0x3939390039000039, 0xCACACA00CA0000CA, -0xD5D5D500D50000D5, 0x4747470047000047, 0x5D5D5D005D00005D, 0x3D3D3D003D00003D, -0xD9D9D900D90000D9, 0x0101010001000001, 0x5A5A5A005A00005A, 0xD6D6D600D60000D6, -0x5151510051000051, 0x5656560056000056, 0x6C6C6C006C00006C, 0x4D4D4D004D00004D, -0x8B8B8B008B00008B, 0x0D0D0D000D00000D, 0x9A9A9A009A00009A, 0x6666660066000066, -0xFBFBFB00FB0000FB, 0xCCCCCC00CC0000CC, 0xB0B0B000B00000B0, 0x2D2D2D002D00002D, -0x7474740074000074, 0x1212120012000012, 0x2B2B2B002B00002B, 0x2020200020000020, -0xF0F0F000F00000F0, 0xB1B1B100B10000B1, 0x8484840084000084, 0x9999990099000099, -0xDFDFDF00DF0000DF, 0x4C4C4C004C00004C, 0xCBCBCB00CB0000CB, 0xC2C2C200C20000C2, -0x3434340034000034, 0x7E7E7E007E00007E, 0x7676760076000076, 0x0505050005000005, -0x6D6D6D006D00006D, 0xB7B7B700B70000B7, 0xA9A9A900A90000A9, 0x3131310031000031, -0xD1D1D100D10000D1, 0x1717170017000017, 0x0404040004000004, 0xD7D7D700D70000D7, -0x1414140014000014, 0x5858580058000058, 0x3A3A3A003A00003A, 0x6161610061000061, -0xDEDEDE00DE0000DE, 0x1B1B1B001B00001B, 0x1111110011000011, 0x1C1C1C001C00001C, -0x3232320032000032, 0x0F0F0F000F00000F, 0x9C9C9C009C00009C, 0x1616160016000016, -0x5353530053000053, 0x1818180018000018, 0xF2F2F200F20000F2, 0x2222220022000022, -0xFEFEFE00FE0000FE, 0x4444440044000044, 0xCFCFCF00CF0000CF, 0xB2B2B200B20000B2, -0xC3C3C300C30000C3, 0xB5B5B500B50000B5, 0x7A7A7A007A00007A, 0x9191910091000091, -0x2424240024000024, 0x0808080008000008, 0xE8E8E800E80000E8, 0xA8A8A800A80000A8, -0x6060600060000060, 0xFCFCFC00FC0000FC, 0x6969690069000069, 0x5050500050000050, -0xAAAAAA00AA0000AA, 0xD0D0D000D00000D0, 0xA0A0A000A00000A0, 0x7D7D7D007D00007D, -0xA1A1A100A10000A1, 0x8989890089000089, 0x6262620062000062, 0x9797970097000097, -0x5454540054000054, 0x5B5B5B005B00005B, 0x1E1E1E001E00001E, 0x9595950095000095, -0xE0E0E000E00000E0, 0xFFFFFF00FF0000FF, 0x6464640064000064, 0xD2D2D200D20000D2, -0x1010100010000010, 0xC4C4C400C40000C4, 0x0000000000000000, 0x4848480048000048, -0xA3A3A300A30000A3, 0xF7F7F700F70000F7, 0x7575750075000075, 0xDBDBDB00DB0000DB, -0x8A8A8A008A00008A, 0x0303030003000003, 0xE6E6E600E60000E6, 0xDADADA00DA0000DA, -0x0909090009000009, 0x3F3F3F003F00003F, 0xDDDDDD00DD0000DD, 0x9494940094000094, -0x8787870087000087, 0x5C5C5C005C00005C, 0x8383830083000083, 0x0202020002000002, -0xCDCDCD00CD0000CD, 0x4A4A4A004A00004A, 0x9090900090000090, 0x3333330033000033, -0x7373730073000073, 0x6767670067000067, 0xF6F6F600F60000F6, 0xF3F3F300F30000F3, -0x9D9D9D009D00009D, 0x7F7F7F007F00007F, 0xBFBFBF00BF0000BF, 0xE2E2E200E20000E2, -0x5252520052000052, 0x9B9B9B009B00009B, 0xD8D8D800D80000D8, 0x2626260026000026, -0xC8C8C800C80000C8, 0x3737370037000037, 0xC6C6C600C60000C6, 0x3B3B3B003B00003B, -0x8181810081000081, 0x9696960096000096, 0x6F6F6F006F00006F, 0x4B4B4B004B00004B, -0x1313130013000013, 0xBEBEBE00BE0000BE, 0x6363630063000063, 0x2E2E2E002E00002E, -0xE9E9E900E90000E9, 0x7979790079000079, 0xA7A7A700A70000A7, 0x8C8C8C008C00008C, -0x9F9F9F009F00009F, 0x6E6E6E006E00006E, 0xBCBCBC00BC0000BC, 0x8E8E8E008E00008E, -0x2929290029000029, 0xF5F5F500F50000F5, 0xF9F9F900F90000F9, 0xB6B6B600B60000B6, -0x2F2F2F002F00002F, 0xFDFDFD00FD0000FD, 0xB4B4B400B40000B4, 0x5959590059000059, -0x7878780078000078, 0x9898980098000098, 0x0606060006000006, 0x6A6A6A006A00006A, -0xE7E7E700E70000E7, 0x4646460046000046, 0x7171710071000071, 0xBABABA00BA0000BA, -0xD4D4D400D40000D4, 0x2525250025000025, 0xABABAB00AB0000AB, 0x4242420042000042, -0x8888880088000088, 0xA2A2A200A20000A2, 0x8D8D8D008D00008D, 0xFAFAFA00FA0000FA, -0x7272720072000072, 0x0707070007000007, 0xB9B9B900B90000B9, 0x5555550055000055, -0xF8F8F800F80000F8, 0xEEEEEE00EE0000EE, 0xACACAC00AC0000AC, 0x0A0A0A000A00000A, -0x3636360036000036, 0x4949490049000049, 0x2A2A2A002A00002A, 0x6868680068000068, -0x3C3C3C003C00003C, 0x3838380038000038, 0xF1F1F100F10000F1, 0xA4A4A400A40000A4, -0x4040400040000040, 0x2828280028000028, 0xD3D3D300D30000D3, 0x7B7B7B007B00007B, -0xBBBBBB00BB0000BB, 0xC9C9C900C90000C9, 0x4343430043000043, 0xC1C1C100C10000C1, -0x1515150015000015, 0xE3E3E300E30000E3, 0xADADAD00AD0000AD, 0xF4F4F400F40000F4, -0x7777770077000077, 0xC7C7C700C70000C7, 0x8080800080000080, 0x9E9E9E009E00009E }; - -const u64bit Camellia_SBOX2[256] = { -0x00E0E0E0E0E00000, 0x0005050505050000, 0x0058585858580000, 0x00D9D9D9D9D90000, -0x0067676767670000, 0x004E4E4E4E4E0000, 0x0081818181810000, 0x00CBCBCBCBCB0000, -0x00C9C9C9C9C90000, 0x000B0B0B0B0B0000, 0x00AEAEAEAEAE0000, 0x006A6A6A6A6A0000, -0x00D5D5D5D5D50000, 0x0018181818180000, 0x005D5D5D5D5D0000, 0x0082828282820000, -0x0046464646460000, 0x00DFDFDFDFDF0000, 0x00D6D6D6D6D60000, 0x0027272727270000, -0x008A8A8A8A8A0000, 0x0032323232320000, 0x004B4B4B4B4B0000, 0x0042424242420000, -0x00DBDBDBDBDB0000, 0x001C1C1C1C1C0000, 0x009E9E9E9E9E0000, 0x009C9C9C9C9C0000, -0x003A3A3A3A3A0000, 0x00CACACACACA0000, 0x0025252525250000, 0x007B7B7B7B7B0000, -0x000D0D0D0D0D0000, 0x0071717171710000, 0x005F5F5F5F5F0000, 0x001F1F1F1F1F0000, -0x00F8F8F8F8F80000, 0x00D7D7D7D7D70000, 0x003E3E3E3E3E0000, 0x009D9D9D9D9D0000, -0x007C7C7C7C7C0000, 0x0060606060600000, 0x00B9B9B9B9B90000, 0x00BEBEBEBEBE0000, -0x00BCBCBCBCBC0000, 0x008B8B8B8B8B0000, 0x0016161616160000, 0x0034343434340000, -0x004D4D4D4D4D0000, 0x00C3C3C3C3C30000, 0x0072727272720000, 0x0095959595950000, -0x00ABABABABAB0000, 0x008E8E8E8E8E0000, 0x00BABABABABA0000, 0x007A7A7A7A7A0000, -0x00B3B3B3B3B30000, 0x0002020202020000, 0x00B4B4B4B4B40000, 0x00ADADADADAD0000, -0x00A2A2A2A2A20000, 0x00ACACACACAC0000, 0x00D8D8D8D8D80000, 0x009A9A9A9A9A0000, -0x0017171717170000, 0x001A1A1A1A1A0000, 0x0035353535350000, 0x00CCCCCCCCCC0000, -0x00F7F7F7F7F70000, 0x0099999999990000, 0x0061616161610000, 0x005A5A5A5A5A0000, -0x00E8E8E8E8E80000, 0x0024242424240000, 0x0056565656560000, 0x0040404040400000, -0x00E1E1E1E1E10000, 0x0063636363630000, 0x0009090909090000, 0x0033333333330000, -0x00BFBFBFBFBF0000, 0x0098989898980000, 0x0097979797970000, 0x0085858585850000, -0x0068686868680000, 0x00FCFCFCFCFC0000, 0x00ECECECECEC0000, 0x000A0A0A0A0A0000, -0x00DADADADADA0000, 0x006F6F6F6F6F0000, 0x0053535353530000, 0x0062626262620000, -0x00A3A3A3A3A30000, 0x002E2E2E2E2E0000, 0x0008080808080000, 0x00AFAFAFAFAF0000, -0x0028282828280000, 0x00B0B0B0B0B00000, 0x0074747474740000, 0x00C2C2C2C2C20000, -0x00BDBDBDBDBD0000, 0x0036363636360000, 0x0022222222220000, 0x0038383838380000, -0x0064646464640000, 0x001E1E1E1E1E0000, 0x0039393939390000, 0x002C2C2C2C2C0000, -0x00A6A6A6A6A60000, 0x0030303030300000, 0x00E5E5E5E5E50000, 0x0044444444440000, -0x00FDFDFDFDFD0000, 0x0088888888880000, 0x009F9F9F9F9F0000, 0x0065656565650000, -0x0087878787870000, 0x006B6B6B6B6B0000, 0x00F4F4F4F4F40000, 0x0023232323230000, -0x0048484848480000, 0x0010101010100000, 0x00D1D1D1D1D10000, 0x0051515151510000, -0x00C0C0C0C0C00000, 0x00F9F9F9F9F90000, 0x00D2D2D2D2D20000, 0x00A0A0A0A0A00000, -0x0055555555550000, 0x00A1A1A1A1A10000, 0x0041414141410000, 0x00FAFAFAFAFA0000, -0x0043434343430000, 0x0013131313130000, 0x00C4C4C4C4C40000, 0x002F2F2F2F2F0000, -0x00A8A8A8A8A80000, 0x00B6B6B6B6B60000, 0x003C3C3C3C3C0000, 0x002B2B2B2B2B0000, -0x00C1C1C1C1C10000, 0x00FFFFFFFFFF0000, 0x00C8C8C8C8C80000, 0x00A5A5A5A5A50000, -0x0020202020200000, 0x0089898989890000, 0x0000000000000000, 0x0090909090900000, -0x0047474747470000, 0x00EFEFEFEFEF0000, 0x00EAEAEAEAEA0000, 0x00B7B7B7B7B70000, -0x0015151515150000, 0x0006060606060000, 0x00CDCDCDCDCD0000, 0x00B5B5B5B5B50000, -0x0012121212120000, 0x007E7E7E7E7E0000, 0x00BBBBBBBBBB0000, 0x0029292929290000, -0x000F0F0F0F0F0000, 0x00B8B8B8B8B80000, 0x0007070707070000, 0x0004040404040000, -0x009B9B9B9B9B0000, 0x0094949494940000, 0x0021212121210000, 0x0066666666660000, -0x00E6E6E6E6E60000, 0x00CECECECECE0000, 0x00EDEDEDEDED0000, 0x00E7E7E7E7E70000, -0x003B3B3B3B3B0000, 0x00FEFEFEFEFE0000, 0x007F7F7F7F7F0000, 0x00C5C5C5C5C50000, -0x00A4A4A4A4A40000, 0x0037373737370000, 0x00B1B1B1B1B10000, 0x004C4C4C4C4C0000, -0x0091919191910000, 0x006E6E6E6E6E0000, 0x008D8D8D8D8D0000, 0x0076767676760000, -0x0003030303030000, 0x002D2D2D2D2D0000, 0x00DEDEDEDEDE0000, 0x0096969696960000, -0x0026262626260000, 0x007D7D7D7D7D0000, 0x00C6C6C6C6C60000, 0x005C5C5C5C5C0000, -0x00D3D3D3D3D30000, 0x00F2F2F2F2F20000, 0x004F4F4F4F4F0000, 0x0019191919190000, -0x003F3F3F3F3F0000, 0x00DCDCDCDCDC0000, 0x0079797979790000, 0x001D1D1D1D1D0000, -0x0052525252520000, 0x00EBEBEBEBEB0000, 0x00F3F3F3F3F30000, 0x006D6D6D6D6D0000, -0x005E5E5E5E5E0000, 0x00FBFBFBFBFB0000, 0x0069696969690000, 0x00B2B2B2B2B20000, -0x00F0F0F0F0F00000, 0x0031313131310000, 0x000C0C0C0C0C0000, 0x00D4D4D4D4D40000, -0x00CFCFCFCFCF0000, 0x008C8C8C8C8C0000, 0x00E2E2E2E2E20000, 0x0075757575750000, -0x00A9A9A9A9A90000, 0x004A4A4A4A4A0000, 0x0057575757570000, 0x0084848484840000, -0x0011111111110000, 0x0045454545450000, 0x001B1B1B1B1B0000, 0x00F5F5F5F5F50000, -0x00E4E4E4E4E40000, 0x000E0E0E0E0E0000, 0x0073737373730000, 0x00AAAAAAAAAA0000, -0x00F1F1F1F1F10000, 0x00DDDDDDDDDD0000, 0x0059595959590000, 0x0014141414140000, -0x006C6C6C6C6C0000, 0x0092929292920000, 0x0054545454540000, 0x00D0D0D0D0D00000, -0x0078787878780000, 0x0070707070700000, 0x00E3E3E3E3E30000, 0x0049494949490000, -0x0080808080800000, 0x0050505050500000, 0x00A7A7A7A7A70000, 0x00F6F6F6F6F60000, -0x0077777777770000, 0x0093939393930000, 0x0086868686860000, 0x0083838383830000, -0x002A2A2A2A2A0000, 0x00C7C7C7C7C70000, 0x005B5B5B5B5B0000, 0x00E9E9E9E9E90000, -0x00EEEEEEEEEE0000, 0x008F8F8F8F8F0000, 0x0001010101010000, 0x003D3D3D3D3D0000 }; - -const u64bit Camellia_SBOX3[256] = { -0x3800383800383800, 0x4100414100414100, 0x1600161600161600, 0x7600767600767600, -0xD900D9D900D9D900, 0x9300939300939300, 0x6000606000606000, 0xF200F2F200F2F200, -0x7200727200727200, 0xC200C2C200C2C200, 0xAB00ABAB00ABAB00, 0x9A009A9A009A9A00, -0x7500757500757500, 0x0600060600060600, 0x5700575700575700, 0xA000A0A000A0A000, -0x9100919100919100, 0xF700F7F700F7F700, 0xB500B5B500B5B500, 0xC900C9C900C9C900, -0xA200A2A200A2A200, 0x8C008C8C008C8C00, 0xD200D2D200D2D200, 0x9000909000909000, -0xF600F6F600F6F600, 0x0700070700070700, 0xA700A7A700A7A700, 0x2700272700272700, -0x8E008E8E008E8E00, 0xB200B2B200B2B200, 0x4900494900494900, 0xDE00DEDE00DEDE00, -0x4300434300434300, 0x5C005C5C005C5C00, 0xD700D7D700D7D700, 0xC700C7C700C7C700, -0x3E003E3E003E3E00, 0xF500F5F500F5F500, 0x8F008F8F008F8F00, 0x6700676700676700, -0x1F001F1F001F1F00, 0x1800181800181800, 0x6E006E6E006E6E00, 0xAF00AFAF00AFAF00, -0x2F002F2F002F2F00, 0xE200E2E200E2E200, 0x8500858500858500, 0x0D000D0D000D0D00, -0x5300535300535300, 0xF000F0F000F0F000, 0x9C009C9C009C9C00, 0x6500656500656500, -0xEA00EAEA00EAEA00, 0xA300A3A300A3A300, 0xAE00AEAE00AEAE00, 0x9E009E9E009E9E00, -0xEC00ECEC00ECEC00, 0x8000808000808000, 0x2D002D2D002D2D00, 0x6B006B6B006B6B00, -0xA800A8A800A8A800, 0x2B002B2B002B2B00, 0x3600363600363600, 0xA600A6A600A6A600, -0xC500C5C500C5C500, 0x8600868600868600, 0x4D004D4D004D4D00, 0x3300333300333300, -0xFD00FDFD00FDFD00, 0x6600666600666600, 0x5800585800585800, 0x9600969600969600, -0x3A003A3A003A3A00, 0x0900090900090900, 0x9500959500959500, 0x1000101000101000, -0x7800787800787800, 0xD800D8D800D8D800, 0x4200424200424200, 0xCC00CCCC00CCCC00, -0xEF00EFEF00EFEF00, 0x2600262600262600, 0xE500E5E500E5E500, 0x6100616100616100, -0x1A001A1A001A1A00, 0x3F003F3F003F3F00, 0x3B003B3B003B3B00, 0x8200828200828200, -0xB600B6B600B6B600, 0xDB00DBDB00DBDB00, 0xD400D4D400D4D400, 0x9800989800989800, -0xE800E8E800E8E800, 0x8B008B8B008B8B00, 0x0200020200020200, 0xEB00EBEB00EBEB00, -0x0A000A0A000A0A00, 0x2C002C2C002C2C00, 0x1D001D1D001D1D00, 0xB000B0B000B0B000, -0x6F006F6F006F6F00, 0x8D008D8D008D8D00, 0x8800888800888800, 0x0E000E0E000E0E00, -0x1900191900191900, 0x8700878700878700, 0x4E004E4E004E4E00, 0x0B000B0B000B0B00, -0xA900A9A900A9A900, 0x0C000C0C000C0C00, 0x7900797900797900, 0x1100111100111100, -0x7F007F7F007F7F00, 0x2200222200222200, 0xE700E7E700E7E700, 0x5900595900595900, -0xE100E1E100E1E100, 0xDA00DADA00DADA00, 0x3D003D3D003D3D00, 0xC800C8C800C8C800, -0x1200121200121200, 0x0400040400040400, 0x7400747400747400, 0x5400545400545400, -0x3000303000303000, 0x7E007E7E007E7E00, 0xB400B4B400B4B400, 0x2800282800282800, -0x5500555500555500, 0x6800686800686800, 0x5000505000505000, 0xBE00BEBE00BEBE00, -0xD000D0D000D0D000, 0xC400C4C400C4C400, 0x3100313100313100, 0xCB00CBCB00CBCB00, -0x2A002A2A002A2A00, 0xAD00ADAD00ADAD00, 0x0F000F0F000F0F00, 0xCA00CACA00CACA00, -0x7000707000707000, 0xFF00FFFF00FFFF00, 0x3200323200323200, 0x6900696900696900, -0x0800080800080800, 0x6200626200626200, 0x0000000000000000, 0x2400242400242400, -0xD100D1D100D1D100, 0xFB00FBFB00FBFB00, 0xBA00BABA00BABA00, 0xED00EDED00EDED00, -0x4500454500454500, 0x8100818100818100, 0x7300737300737300, 0x6D006D6D006D6D00, -0x8400848400848400, 0x9F009F9F009F9F00, 0xEE00EEEE00EEEE00, 0x4A004A4A004A4A00, -0xC300C3C300C3C300, 0x2E002E2E002E2E00, 0xC100C1C100C1C100, 0x0100010100010100, -0xE600E6E600E6E600, 0x2500252500252500, 0x4800484800484800, 0x9900999900999900, -0xB900B9B900B9B900, 0xB300B3B300B3B300, 0x7B007B7B007B7B00, 0xF900F9F900F9F900, -0xCE00CECE00CECE00, 0xBF00BFBF00BFBF00, 0xDF00DFDF00DFDF00, 0x7100717100717100, -0x2900292900292900, 0xCD00CDCD00CDCD00, 0x6C006C6C006C6C00, 0x1300131300131300, -0x6400646400646400, 0x9B009B9B009B9B00, 0x6300636300636300, 0x9D009D9D009D9D00, -0xC000C0C000C0C000, 0x4B004B4B004B4B00, 0xB700B7B700B7B700, 0xA500A5A500A5A500, -0x8900898900898900, 0x5F005F5F005F5F00, 0xB100B1B100B1B100, 0x1700171700171700, -0xF400F4F400F4F400, 0xBC00BCBC00BCBC00, 0xD300D3D300D3D300, 0x4600464600464600, -0xCF00CFCF00CFCF00, 0x3700373700373700, 0x5E005E5E005E5E00, 0x4700474700474700, -0x9400949400949400, 0xFA00FAFA00FAFA00, 0xFC00FCFC00FCFC00, 0x5B005B5B005B5B00, -0x9700979700979700, 0xFE00FEFE00FEFE00, 0x5A005A5A005A5A00, 0xAC00ACAC00ACAC00, -0x3C003C3C003C3C00, 0x4C004C4C004C4C00, 0x0300030300030300, 0x3500353500353500, -0xF300F3F300F3F300, 0x2300232300232300, 0xB800B8B800B8B800, 0x5D005D5D005D5D00, -0x6A006A6A006A6A00, 0x9200929200929200, 0xD500D5D500D5D500, 0x2100212100212100, -0x4400444400444400, 0x5100515100515100, 0xC600C6C600C6C600, 0x7D007D7D007D7D00, -0x3900393900393900, 0x8300838300838300, 0xDC00DCDC00DCDC00, 0xAA00AAAA00AAAA00, -0x7C007C7C007C7C00, 0x7700777700777700, 0x5600565600565600, 0x0500050500050500, -0x1B001B1B001B1B00, 0xA400A4A400A4A400, 0x1500151500151500, 0x3400343400343400, -0x1E001E1E001E1E00, 0x1C001C1C001C1C00, 0xF800F8F800F8F800, 0x5200525200525200, -0x2000202000202000, 0x1400141400141400, 0xE900E9E900E9E900, 0xBD00BDBD00BDBD00, -0xDD00DDDD00DDDD00, 0xE400E4E400E4E400, 0xA100A1A100A1A100, 0xE000E0E000E0E000, -0x8A008A8A008A8A00, 0xF100F1F100F1F100, 0xD600D6D600D6D600, 0x7A007A7A007A7A00, -0xBB00BBBB00BBBB00, 0xE300E3E300E3E300, 0x4000404000404000, 0x4F004F4F004F4F00 }; - -const u64bit Camellia_SBOX4[256] = { -0x7070007000007070, 0x2C2C002C00002C2C, 0xB3B300B30000B3B3, 0xC0C000C00000C0C0, -0xE4E400E40000E4E4, 0x5757005700005757, 0xEAEA00EA0000EAEA, 0xAEAE00AE0000AEAE, -0x2323002300002323, 0x6B6B006B00006B6B, 0x4545004500004545, 0xA5A500A50000A5A5, -0xEDED00ED0000EDED, 0x4F4F004F00004F4F, 0x1D1D001D00001D1D, 0x9292009200009292, -0x8686008600008686, 0xAFAF00AF0000AFAF, 0x7C7C007C00007C7C, 0x1F1F001F00001F1F, -0x3E3E003E00003E3E, 0xDCDC00DC0000DCDC, 0x5E5E005E00005E5E, 0x0B0B000B00000B0B, -0xA6A600A60000A6A6, 0x3939003900003939, 0xD5D500D50000D5D5, 0x5D5D005D00005D5D, -0xD9D900D90000D9D9, 0x5A5A005A00005A5A, 0x5151005100005151, 0x6C6C006C00006C6C, -0x8B8B008B00008B8B, 0x9A9A009A00009A9A, 0xFBFB00FB0000FBFB, 0xB0B000B00000B0B0, -0x7474007400007474, 0x2B2B002B00002B2B, 0xF0F000F00000F0F0, 0x8484008400008484, -0xDFDF00DF0000DFDF, 0xCBCB00CB0000CBCB, 0x3434003400003434, 0x7676007600007676, -0x6D6D006D00006D6D, 0xA9A900A90000A9A9, 0xD1D100D10000D1D1, 0x0404000400000404, -0x1414001400001414, 0x3A3A003A00003A3A, 0xDEDE00DE0000DEDE, 0x1111001100001111, -0x3232003200003232, 0x9C9C009C00009C9C, 0x5353005300005353, 0xF2F200F20000F2F2, -0xFEFE00FE0000FEFE, 0xCFCF00CF0000CFCF, 0xC3C300C30000C3C3, 0x7A7A007A00007A7A, -0x2424002400002424, 0xE8E800E80000E8E8, 0x6060006000006060, 0x6969006900006969, -0xAAAA00AA0000AAAA, 0xA0A000A00000A0A0, 0xA1A100A10000A1A1, 0x6262006200006262, -0x5454005400005454, 0x1E1E001E00001E1E, 0xE0E000E00000E0E0, 0x6464006400006464, -0x1010001000001010, 0x0000000000000000, 0xA3A300A30000A3A3, 0x7575007500007575, -0x8A8A008A00008A8A, 0xE6E600E60000E6E6, 0x0909000900000909, 0xDDDD00DD0000DDDD, -0x8787008700008787, 0x8383008300008383, 0xCDCD00CD0000CDCD, 0x9090009000009090, -0x7373007300007373, 0xF6F600F60000F6F6, 0x9D9D009D00009D9D, 0xBFBF00BF0000BFBF, -0x5252005200005252, 0xD8D800D80000D8D8, 0xC8C800C80000C8C8, 0xC6C600C60000C6C6, -0x8181008100008181, 0x6F6F006F00006F6F, 0x1313001300001313, 0x6363006300006363, -0xE9E900E90000E9E9, 0xA7A700A70000A7A7, 0x9F9F009F00009F9F, 0xBCBC00BC0000BCBC, -0x2929002900002929, 0xF9F900F90000F9F9, 0x2F2F002F00002F2F, 0xB4B400B40000B4B4, -0x7878007800007878, 0x0606000600000606, 0xE7E700E70000E7E7, 0x7171007100007171, -0xD4D400D40000D4D4, 0xABAB00AB0000ABAB, 0x8888008800008888, 0x8D8D008D00008D8D, -0x7272007200007272, 0xB9B900B90000B9B9, 0xF8F800F80000F8F8, 0xACAC00AC0000ACAC, -0x3636003600003636, 0x2A2A002A00002A2A, 0x3C3C003C00003C3C, 0xF1F100F10000F1F1, -0x4040004000004040, 0xD3D300D30000D3D3, 0xBBBB00BB0000BBBB, 0x4343004300004343, -0x1515001500001515, 0xADAD00AD0000ADAD, 0x7777007700007777, 0x8080008000008080, -0x8282008200008282, 0xECEC00EC0000ECEC, 0x2727002700002727, 0xE5E500E50000E5E5, -0x8585008500008585, 0x3535003500003535, 0x0C0C000C00000C0C, 0x4141004100004141, -0xEFEF00EF0000EFEF, 0x9393009300009393, 0x1919001900001919, 0x2121002100002121, -0x0E0E000E00000E0E, 0x4E4E004E00004E4E, 0x6565006500006565, 0xBDBD00BD0000BDBD, -0xB8B800B80000B8B8, 0x8F8F008F00008F8F, 0xEBEB00EB0000EBEB, 0xCECE00CE0000CECE, -0x3030003000003030, 0x5F5F005F00005F5F, 0xC5C500C50000C5C5, 0x1A1A001A00001A1A, -0xE1E100E10000E1E1, 0xCACA00CA0000CACA, 0x4747004700004747, 0x3D3D003D00003D3D, -0x0101000100000101, 0xD6D600D60000D6D6, 0x5656005600005656, 0x4D4D004D00004D4D, -0x0D0D000D00000D0D, 0x6666006600006666, 0xCCCC00CC0000CCCC, 0x2D2D002D00002D2D, -0x1212001200001212, 0x2020002000002020, 0xB1B100B10000B1B1, 0x9999009900009999, -0x4C4C004C00004C4C, 0xC2C200C20000C2C2, 0x7E7E007E00007E7E, 0x0505000500000505, -0xB7B700B70000B7B7, 0x3131003100003131, 0x1717001700001717, 0xD7D700D70000D7D7, -0x5858005800005858, 0x6161006100006161, 0x1B1B001B00001B1B, 0x1C1C001C00001C1C, -0x0F0F000F00000F0F, 0x1616001600001616, 0x1818001800001818, 0x2222002200002222, -0x4444004400004444, 0xB2B200B20000B2B2, 0xB5B500B50000B5B5, 0x9191009100009191, -0x0808000800000808, 0xA8A800A80000A8A8, 0xFCFC00FC0000FCFC, 0x5050005000005050, -0xD0D000D00000D0D0, 0x7D7D007D00007D7D, 0x8989008900008989, 0x9797009700009797, -0x5B5B005B00005B5B, 0x9595009500009595, 0xFFFF00FF0000FFFF, 0xD2D200D20000D2D2, -0xC4C400C40000C4C4, 0x4848004800004848, 0xF7F700F70000F7F7, 0xDBDB00DB0000DBDB, -0x0303000300000303, 0xDADA00DA0000DADA, 0x3F3F003F00003F3F, 0x9494009400009494, -0x5C5C005C00005C5C, 0x0202000200000202, 0x4A4A004A00004A4A, 0x3333003300003333, -0x6767006700006767, 0xF3F300F30000F3F3, 0x7F7F007F00007F7F, 0xE2E200E20000E2E2, -0x9B9B009B00009B9B, 0x2626002600002626, 0x3737003700003737, 0x3B3B003B00003B3B, -0x9696009600009696, 0x4B4B004B00004B4B, 0xBEBE00BE0000BEBE, 0x2E2E002E00002E2E, -0x7979007900007979, 0x8C8C008C00008C8C, 0x6E6E006E00006E6E, 0x8E8E008E00008E8E, -0xF5F500F50000F5F5, 0xB6B600B60000B6B6, 0xFDFD00FD0000FDFD, 0x5959005900005959, -0x9898009800009898, 0x6A6A006A00006A6A, 0x4646004600004646, 0xBABA00BA0000BABA, -0x2525002500002525, 0x4242004200004242, 0xA2A200A20000A2A2, 0xFAFA00FA0000FAFA, -0x0707000700000707, 0x5555005500005555, 0xEEEE00EE0000EEEE, 0x0A0A000A00000A0A, -0x4949004900004949, 0x6868006800006868, 0x3838003800003838, 0xA4A400A40000A4A4, -0x2828002800002828, 0x7B7B007B00007B7B, 0xC9C900C90000C9C9, 0xC1C100C10000C1C1, -0xE3E300E30000E3E3, 0xF4F400F40000F4F4, 0xC7C700C70000C7C7, 0x9E9E009E00009E9E }; - -const u64bit Camellia_SBOX5[256] = { -0x00E0E0E000E0E0E0, 0x0005050500050505, 0x0058585800585858, 0x00D9D9D900D9D9D9, -0x0067676700676767, 0x004E4E4E004E4E4E, 0x0081818100818181, 0x00CBCBCB00CBCBCB, -0x00C9C9C900C9C9C9, 0x000B0B0B000B0B0B, 0x00AEAEAE00AEAEAE, 0x006A6A6A006A6A6A, -0x00D5D5D500D5D5D5, 0x0018181800181818, 0x005D5D5D005D5D5D, 0x0082828200828282, -0x0046464600464646, 0x00DFDFDF00DFDFDF, 0x00D6D6D600D6D6D6, 0x0027272700272727, -0x008A8A8A008A8A8A, 0x0032323200323232, 0x004B4B4B004B4B4B, 0x0042424200424242, -0x00DBDBDB00DBDBDB, 0x001C1C1C001C1C1C, 0x009E9E9E009E9E9E, 0x009C9C9C009C9C9C, -0x003A3A3A003A3A3A, 0x00CACACA00CACACA, 0x0025252500252525, 0x007B7B7B007B7B7B, -0x000D0D0D000D0D0D, 0x0071717100717171, 0x005F5F5F005F5F5F, 0x001F1F1F001F1F1F, -0x00F8F8F800F8F8F8, 0x00D7D7D700D7D7D7, 0x003E3E3E003E3E3E, 0x009D9D9D009D9D9D, -0x007C7C7C007C7C7C, 0x0060606000606060, 0x00B9B9B900B9B9B9, 0x00BEBEBE00BEBEBE, -0x00BCBCBC00BCBCBC, 0x008B8B8B008B8B8B, 0x0016161600161616, 0x0034343400343434, -0x004D4D4D004D4D4D, 0x00C3C3C300C3C3C3, 0x0072727200727272, 0x0095959500959595, -0x00ABABAB00ABABAB, 0x008E8E8E008E8E8E, 0x00BABABA00BABABA, 0x007A7A7A007A7A7A, -0x00B3B3B300B3B3B3, 0x0002020200020202, 0x00B4B4B400B4B4B4, 0x00ADADAD00ADADAD, -0x00A2A2A200A2A2A2, 0x00ACACAC00ACACAC, 0x00D8D8D800D8D8D8, 0x009A9A9A009A9A9A, -0x0017171700171717, 0x001A1A1A001A1A1A, 0x0035353500353535, 0x00CCCCCC00CCCCCC, -0x00F7F7F700F7F7F7, 0x0099999900999999, 0x0061616100616161, 0x005A5A5A005A5A5A, -0x00E8E8E800E8E8E8, 0x0024242400242424, 0x0056565600565656, 0x0040404000404040, -0x00E1E1E100E1E1E1, 0x0063636300636363, 0x0009090900090909, 0x0033333300333333, -0x00BFBFBF00BFBFBF, 0x0098989800989898, 0x0097979700979797, 0x0085858500858585, -0x0068686800686868, 0x00FCFCFC00FCFCFC, 0x00ECECEC00ECECEC, 0x000A0A0A000A0A0A, -0x00DADADA00DADADA, 0x006F6F6F006F6F6F, 0x0053535300535353, 0x0062626200626262, -0x00A3A3A300A3A3A3, 0x002E2E2E002E2E2E, 0x0008080800080808, 0x00AFAFAF00AFAFAF, -0x0028282800282828, 0x00B0B0B000B0B0B0, 0x0074747400747474, 0x00C2C2C200C2C2C2, -0x00BDBDBD00BDBDBD, 0x0036363600363636, 0x0022222200222222, 0x0038383800383838, -0x0064646400646464, 0x001E1E1E001E1E1E, 0x0039393900393939, 0x002C2C2C002C2C2C, -0x00A6A6A600A6A6A6, 0x0030303000303030, 0x00E5E5E500E5E5E5, 0x0044444400444444, -0x00FDFDFD00FDFDFD, 0x0088888800888888, 0x009F9F9F009F9F9F, 0x0065656500656565, -0x0087878700878787, 0x006B6B6B006B6B6B, 0x00F4F4F400F4F4F4, 0x0023232300232323, -0x0048484800484848, 0x0010101000101010, 0x00D1D1D100D1D1D1, 0x0051515100515151, -0x00C0C0C000C0C0C0, 0x00F9F9F900F9F9F9, 0x00D2D2D200D2D2D2, 0x00A0A0A000A0A0A0, -0x0055555500555555, 0x00A1A1A100A1A1A1, 0x0041414100414141, 0x00FAFAFA00FAFAFA, -0x0043434300434343, 0x0013131300131313, 0x00C4C4C400C4C4C4, 0x002F2F2F002F2F2F, -0x00A8A8A800A8A8A8, 0x00B6B6B600B6B6B6, 0x003C3C3C003C3C3C, 0x002B2B2B002B2B2B, -0x00C1C1C100C1C1C1, 0x00FFFFFF00FFFFFF, 0x00C8C8C800C8C8C8, 0x00A5A5A500A5A5A5, -0x0020202000202020, 0x0089898900898989, 0x0000000000000000, 0x0090909000909090, -0x0047474700474747, 0x00EFEFEF00EFEFEF, 0x00EAEAEA00EAEAEA, 0x00B7B7B700B7B7B7, -0x0015151500151515, 0x0006060600060606, 0x00CDCDCD00CDCDCD, 0x00B5B5B500B5B5B5, -0x0012121200121212, 0x007E7E7E007E7E7E, 0x00BBBBBB00BBBBBB, 0x0029292900292929, -0x000F0F0F000F0F0F, 0x00B8B8B800B8B8B8, 0x0007070700070707, 0x0004040400040404, -0x009B9B9B009B9B9B, 0x0094949400949494, 0x0021212100212121, 0x0066666600666666, -0x00E6E6E600E6E6E6, 0x00CECECE00CECECE, 0x00EDEDED00EDEDED, 0x00E7E7E700E7E7E7, -0x003B3B3B003B3B3B, 0x00FEFEFE00FEFEFE, 0x007F7F7F007F7F7F, 0x00C5C5C500C5C5C5, -0x00A4A4A400A4A4A4, 0x0037373700373737, 0x00B1B1B100B1B1B1, 0x004C4C4C004C4C4C, -0x0091919100919191, 0x006E6E6E006E6E6E, 0x008D8D8D008D8D8D, 0x0076767600767676, -0x0003030300030303, 0x002D2D2D002D2D2D, 0x00DEDEDE00DEDEDE, 0x0096969600969696, -0x0026262600262626, 0x007D7D7D007D7D7D, 0x00C6C6C600C6C6C6, 0x005C5C5C005C5C5C, -0x00D3D3D300D3D3D3, 0x00F2F2F200F2F2F2, 0x004F4F4F004F4F4F, 0x0019191900191919, -0x003F3F3F003F3F3F, 0x00DCDCDC00DCDCDC, 0x0079797900797979, 0x001D1D1D001D1D1D, -0x0052525200525252, 0x00EBEBEB00EBEBEB, 0x00F3F3F300F3F3F3, 0x006D6D6D006D6D6D, -0x005E5E5E005E5E5E, 0x00FBFBFB00FBFBFB, 0x0069696900696969, 0x00B2B2B200B2B2B2, -0x00F0F0F000F0F0F0, 0x0031313100313131, 0x000C0C0C000C0C0C, 0x00D4D4D400D4D4D4, -0x00CFCFCF00CFCFCF, 0x008C8C8C008C8C8C, 0x00E2E2E200E2E2E2, 0x0075757500757575, -0x00A9A9A900A9A9A9, 0x004A4A4A004A4A4A, 0x0057575700575757, 0x0084848400848484, -0x0011111100111111, 0x0045454500454545, 0x001B1B1B001B1B1B, 0x00F5F5F500F5F5F5, -0x00E4E4E400E4E4E4, 0x000E0E0E000E0E0E, 0x0073737300737373, 0x00AAAAAA00AAAAAA, -0x00F1F1F100F1F1F1, 0x00DDDDDD00DDDDDD, 0x0059595900595959, 0x0014141400141414, -0x006C6C6C006C6C6C, 0x0092929200929292, 0x0054545400545454, 0x00D0D0D000D0D0D0, -0x0078787800787878, 0x0070707000707070, 0x00E3E3E300E3E3E3, 0x0049494900494949, -0x0080808000808080, 0x0050505000505050, 0x00A7A7A700A7A7A7, 0x00F6F6F600F6F6F6, -0x0077777700777777, 0x0093939300939393, 0x0086868600868686, 0x0083838300838383, -0x002A2A2A002A2A2A, 0x00C7C7C700C7C7C7, 0x005B5B5B005B5B5B, 0x00E9E9E900E9E9E9, -0x00EEEEEE00EEEEEE, 0x008F8F8F008F8F8F, 0x0001010100010101, 0x003D3D3D003D3D3D }; - -const u64bit Camellia_SBOX6[256] = { -0x3800383838003838, 0x4100414141004141, 0x1600161616001616, 0x7600767676007676, -0xD900D9D9D900D9D9, 0x9300939393009393, 0x6000606060006060, 0xF200F2F2F200F2F2, -0x7200727272007272, 0xC200C2C2C200C2C2, 0xAB00ABABAB00ABAB, 0x9A009A9A9A009A9A, -0x7500757575007575, 0x0600060606000606, 0x5700575757005757, 0xA000A0A0A000A0A0, -0x9100919191009191, 0xF700F7F7F700F7F7, 0xB500B5B5B500B5B5, 0xC900C9C9C900C9C9, -0xA200A2A2A200A2A2, 0x8C008C8C8C008C8C, 0xD200D2D2D200D2D2, 0x9000909090009090, -0xF600F6F6F600F6F6, 0x0700070707000707, 0xA700A7A7A700A7A7, 0x2700272727002727, -0x8E008E8E8E008E8E, 0xB200B2B2B200B2B2, 0x4900494949004949, 0xDE00DEDEDE00DEDE, -0x4300434343004343, 0x5C005C5C5C005C5C, 0xD700D7D7D700D7D7, 0xC700C7C7C700C7C7, -0x3E003E3E3E003E3E, 0xF500F5F5F500F5F5, 0x8F008F8F8F008F8F, 0x6700676767006767, -0x1F001F1F1F001F1F, 0x1800181818001818, 0x6E006E6E6E006E6E, 0xAF00AFAFAF00AFAF, -0x2F002F2F2F002F2F, 0xE200E2E2E200E2E2, 0x8500858585008585, 0x0D000D0D0D000D0D, -0x5300535353005353, 0xF000F0F0F000F0F0, 0x9C009C9C9C009C9C, 0x6500656565006565, -0xEA00EAEAEA00EAEA, 0xA300A3A3A300A3A3, 0xAE00AEAEAE00AEAE, 0x9E009E9E9E009E9E, -0xEC00ECECEC00ECEC, 0x8000808080008080, 0x2D002D2D2D002D2D, 0x6B006B6B6B006B6B, -0xA800A8A8A800A8A8, 0x2B002B2B2B002B2B, 0x3600363636003636, 0xA600A6A6A600A6A6, -0xC500C5C5C500C5C5, 0x8600868686008686, 0x4D004D4D4D004D4D, 0x3300333333003333, -0xFD00FDFDFD00FDFD, 0x6600666666006666, 0x5800585858005858, 0x9600969696009696, -0x3A003A3A3A003A3A, 0x0900090909000909, 0x9500959595009595, 0x1000101010001010, -0x7800787878007878, 0xD800D8D8D800D8D8, 0x4200424242004242, 0xCC00CCCCCC00CCCC, -0xEF00EFEFEF00EFEF, 0x2600262626002626, 0xE500E5E5E500E5E5, 0x6100616161006161, -0x1A001A1A1A001A1A, 0x3F003F3F3F003F3F, 0x3B003B3B3B003B3B, 0x8200828282008282, -0xB600B6B6B600B6B6, 0xDB00DBDBDB00DBDB, 0xD400D4D4D400D4D4, 0x9800989898009898, -0xE800E8E8E800E8E8, 0x8B008B8B8B008B8B, 0x0200020202000202, 0xEB00EBEBEB00EBEB, -0x0A000A0A0A000A0A, 0x2C002C2C2C002C2C, 0x1D001D1D1D001D1D, 0xB000B0B0B000B0B0, -0x6F006F6F6F006F6F, 0x8D008D8D8D008D8D, 0x8800888888008888, 0x0E000E0E0E000E0E, -0x1900191919001919, 0x8700878787008787, 0x4E004E4E4E004E4E, 0x0B000B0B0B000B0B, -0xA900A9A9A900A9A9, 0x0C000C0C0C000C0C, 0x7900797979007979, 0x1100111111001111, -0x7F007F7F7F007F7F, 0x2200222222002222, 0xE700E7E7E700E7E7, 0x5900595959005959, -0xE100E1E1E100E1E1, 0xDA00DADADA00DADA, 0x3D003D3D3D003D3D, 0xC800C8C8C800C8C8, -0x1200121212001212, 0x0400040404000404, 0x7400747474007474, 0x5400545454005454, -0x3000303030003030, 0x7E007E7E7E007E7E, 0xB400B4B4B400B4B4, 0x2800282828002828, -0x5500555555005555, 0x6800686868006868, 0x5000505050005050, 0xBE00BEBEBE00BEBE, -0xD000D0D0D000D0D0, 0xC400C4C4C400C4C4, 0x3100313131003131, 0xCB00CBCBCB00CBCB, -0x2A002A2A2A002A2A, 0xAD00ADADAD00ADAD, 0x0F000F0F0F000F0F, 0xCA00CACACA00CACA, -0x7000707070007070, 0xFF00FFFFFF00FFFF, 0x3200323232003232, 0x6900696969006969, -0x0800080808000808, 0x6200626262006262, 0x0000000000000000, 0x2400242424002424, -0xD100D1D1D100D1D1, 0xFB00FBFBFB00FBFB, 0xBA00BABABA00BABA, 0xED00EDEDED00EDED, -0x4500454545004545, 0x8100818181008181, 0x7300737373007373, 0x6D006D6D6D006D6D, -0x8400848484008484, 0x9F009F9F9F009F9F, 0xEE00EEEEEE00EEEE, 0x4A004A4A4A004A4A, -0xC300C3C3C300C3C3, 0x2E002E2E2E002E2E, 0xC100C1C1C100C1C1, 0x0100010101000101, -0xE600E6E6E600E6E6, 0x2500252525002525, 0x4800484848004848, 0x9900999999009999, -0xB900B9B9B900B9B9, 0xB300B3B3B300B3B3, 0x7B007B7B7B007B7B, 0xF900F9F9F900F9F9, -0xCE00CECECE00CECE, 0xBF00BFBFBF00BFBF, 0xDF00DFDFDF00DFDF, 0x7100717171007171, -0x2900292929002929, 0xCD00CDCDCD00CDCD, 0x6C006C6C6C006C6C, 0x1300131313001313, -0x6400646464006464, 0x9B009B9B9B009B9B, 0x6300636363006363, 0x9D009D9D9D009D9D, -0xC000C0C0C000C0C0, 0x4B004B4B4B004B4B, 0xB700B7B7B700B7B7, 0xA500A5A5A500A5A5, -0x8900898989008989, 0x5F005F5F5F005F5F, 0xB100B1B1B100B1B1, 0x1700171717001717, -0xF400F4F4F400F4F4, 0xBC00BCBCBC00BCBC, 0xD300D3D3D300D3D3, 0x4600464646004646, -0xCF00CFCFCF00CFCF, 0x3700373737003737, 0x5E005E5E5E005E5E, 0x4700474747004747, -0x9400949494009494, 0xFA00FAFAFA00FAFA, 0xFC00FCFCFC00FCFC, 0x5B005B5B5B005B5B, -0x9700979797009797, 0xFE00FEFEFE00FEFE, 0x5A005A5A5A005A5A, 0xAC00ACACAC00ACAC, -0x3C003C3C3C003C3C, 0x4C004C4C4C004C4C, 0x0300030303000303, 0x3500353535003535, -0xF300F3F3F300F3F3, 0x2300232323002323, 0xB800B8B8B800B8B8, 0x5D005D5D5D005D5D, -0x6A006A6A6A006A6A, 0x9200929292009292, 0xD500D5D5D500D5D5, 0x2100212121002121, -0x4400444444004444, 0x5100515151005151, 0xC600C6C6C600C6C6, 0x7D007D7D7D007D7D, -0x3900393939003939, 0x8300838383008383, 0xDC00DCDCDC00DCDC, 0xAA00AAAAAA00AAAA, -0x7C007C7C7C007C7C, 0x7700777777007777, 0x5600565656005656, 0x0500050505000505, -0x1B001B1B1B001B1B, 0xA400A4A4A400A4A4, 0x1500151515001515, 0x3400343434003434, -0x1E001E1E1E001E1E, 0x1C001C1C1C001C1C, 0xF800F8F8F800F8F8, 0x5200525252005252, -0x2000202020002020, 0x1400141414001414, 0xE900E9E9E900E9E9, 0xBD00BDBDBD00BDBD, -0xDD00DDDDDD00DDDD, 0xE400E4E4E400E4E4, 0xA100A1A1A100A1A1, 0xE000E0E0E000E0E0, -0x8A008A8A8A008A8A, 0xF100F1F1F100F1F1, 0xD600D6D6D600D6D6, 0x7A007A7A7A007A7A, -0xBB00BBBBBB00BBBB, 0xE300E3E3E300E3E3, 0x4000404040004040, 0x4F004F4F4F004F4F }; - -const u64bit Camellia_SBOX7[256] = { -0x7070007070700070, 0x2C2C002C2C2C002C, 0xB3B300B3B3B300B3, 0xC0C000C0C0C000C0, -0xE4E400E4E4E400E4, 0x5757005757570057, 0xEAEA00EAEAEA00EA, 0xAEAE00AEAEAE00AE, -0x2323002323230023, 0x6B6B006B6B6B006B, 0x4545004545450045, 0xA5A500A5A5A500A5, -0xEDED00EDEDED00ED, 0x4F4F004F4F4F004F, 0x1D1D001D1D1D001D, 0x9292009292920092, -0x8686008686860086, 0xAFAF00AFAFAF00AF, 0x7C7C007C7C7C007C, 0x1F1F001F1F1F001F, -0x3E3E003E3E3E003E, 0xDCDC00DCDCDC00DC, 0x5E5E005E5E5E005E, 0x0B0B000B0B0B000B, -0xA6A600A6A6A600A6, 0x3939003939390039, 0xD5D500D5D5D500D5, 0x5D5D005D5D5D005D, -0xD9D900D9D9D900D9, 0x5A5A005A5A5A005A, 0x5151005151510051, 0x6C6C006C6C6C006C, -0x8B8B008B8B8B008B, 0x9A9A009A9A9A009A, 0xFBFB00FBFBFB00FB, 0xB0B000B0B0B000B0, -0x7474007474740074, 0x2B2B002B2B2B002B, 0xF0F000F0F0F000F0, 0x8484008484840084, -0xDFDF00DFDFDF00DF, 0xCBCB00CBCBCB00CB, 0x3434003434340034, 0x7676007676760076, -0x6D6D006D6D6D006D, 0xA9A900A9A9A900A9, 0xD1D100D1D1D100D1, 0x0404000404040004, -0x1414001414140014, 0x3A3A003A3A3A003A, 0xDEDE00DEDEDE00DE, 0x1111001111110011, -0x3232003232320032, 0x9C9C009C9C9C009C, 0x5353005353530053, 0xF2F200F2F2F200F2, -0xFEFE00FEFEFE00FE, 0xCFCF00CFCFCF00CF, 0xC3C300C3C3C300C3, 0x7A7A007A7A7A007A, -0x2424002424240024, 0xE8E800E8E8E800E8, 0x6060006060600060, 0x6969006969690069, -0xAAAA00AAAAAA00AA, 0xA0A000A0A0A000A0, 0xA1A100A1A1A100A1, 0x6262006262620062, -0x5454005454540054, 0x1E1E001E1E1E001E, 0xE0E000E0E0E000E0, 0x6464006464640064, -0x1010001010100010, 0x0000000000000000, 0xA3A300A3A3A300A3, 0x7575007575750075, -0x8A8A008A8A8A008A, 0xE6E600E6E6E600E6, 0x0909000909090009, 0xDDDD00DDDDDD00DD, -0x8787008787870087, 0x8383008383830083, 0xCDCD00CDCDCD00CD, 0x9090009090900090, -0x7373007373730073, 0xF6F600F6F6F600F6, 0x9D9D009D9D9D009D, 0xBFBF00BFBFBF00BF, -0x5252005252520052, 0xD8D800D8D8D800D8, 0xC8C800C8C8C800C8, 0xC6C600C6C6C600C6, -0x8181008181810081, 0x6F6F006F6F6F006F, 0x1313001313130013, 0x6363006363630063, -0xE9E900E9E9E900E9, 0xA7A700A7A7A700A7, 0x9F9F009F9F9F009F, 0xBCBC00BCBCBC00BC, -0x2929002929290029, 0xF9F900F9F9F900F9, 0x2F2F002F2F2F002F, 0xB4B400B4B4B400B4, -0x7878007878780078, 0x0606000606060006, 0xE7E700E7E7E700E7, 0x7171007171710071, -0xD4D400D4D4D400D4, 0xABAB00ABABAB00AB, 0x8888008888880088, 0x8D8D008D8D8D008D, -0x7272007272720072, 0xB9B900B9B9B900B9, 0xF8F800F8F8F800F8, 0xACAC00ACACAC00AC, -0x3636003636360036, 0x2A2A002A2A2A002A, 0x3C3C003C3C3C003C, 0xF1F100F1F1F100F1, -0x4040004040400040, 0xD3D300D3D3D300D3, 0xBBBB00BBBBBB00BB, 0x4343004343430043, -0x1515001515150015, 0xADAD00ADADAD00AD, 0x7777007777770077, 0x8080008080800080, -0x8282008282820082, 0xECEC00ECECEC00EC, 0x2727002727270027, 0xE5E500E5E5E500E5, -0x8585008585850085, 0x3535003535350035, 0x0C0C000C0C0C000C, 0x4141004141410041, -0xEFEF00EFEFEF00EF, 0x9393009393930093, 0x1919001919190019, 0x2121002121210021, -0x0E0E000E0E0E000E, 0x4E4E004E4E4E004E, 0x6565006565650065, 0xBDBD00BDBDBD00BD, -0xB8B800B8B8B800B8, 0x8F8F008F8F8F008F, 0xEBEB00EBEBEB00EB, 0xCECE00CECECE00CE, -0x3030003030300030, 0x5F5F005F5F5F005F, 0xC5C500C5C5C500C5, 0x1A1A001A1A1A001A, -0xE1E100E1E1E100E1, 0xCACA00CACACA00CA, 0x4747004747470047, 0x3D3D003D3D3D003D, -0x0101000101010001, 0xD6D600D6D6D600D6, 0x5656005656560056, 0x4D4D004D4D4D004D, -0x0D0D000D0D0D000D, 0x6666006666660066, 0xCCCC00CCCCCC00CC, 0x2D2D002D2D2D002D, -0x1212001212120012, 0x2020002020200020, 0xB1B100B1B1B100B1, 0x9999009999990099, -0x4C4C004C4C4C004C, 0xC2C200C2C2C200C2, 0x7E7E007E7E7E007E, 0x0505000505050005, -0xB7B700B7B7B700B7, 0x3131003131310031, 0x1717001717170017, 0xD7D700D7D7D700D7, -0x5858005858580058, 0x6161006161610061, 0x1B1B001B1B1B001B, 0x1C1C001C1C1C001C, -0x0F0F000F0F0F000F, 0x1616001616160016, 0x1818001818180018, 0x2222002222220022, -0x4444004444440044, 0xB2B200B2B2B200B2, 0xB5B500B5B5B500B5, 0x9191009191910091, -0x0808000808080008, 0xA8A800A8A8A800A8, 0xFCFC00FCFCFC00FC, 0x5050005050500050, -0xD0D000D0D0D000D0, 0x7D7D007D7D7D007D, 0x8989008989890089, 0x9797009797970097, -0x5B5B005B5B5B005B, 0x9595009595950095, 0xFFFF00FFFFFF00FF, 0xD2D200D2D2D200D2, -0xC4C400C4C4C400C4, 0x4848004848480048, 0xF7F700F7F7F700F7, 0xDBDB00DBDBDB00DB, -0x0303000303030003, 0xDADA00DADADA00DA, 0x3F3F003F3F3F003F, 0x9494009494940094, -0x5C5C005C5C5C005C, 0x0202000202020002, 0x4A4A004A4A4A004A, 0x3333003333330033, -0x6767006767670067, 0xF3F300F3F3F300F3, 0x7F7F007F7F7F007F, 0xE2E200E2E2E200E2, -0x9B9B009B9B9B009B, 0x2626002626260026, 0x3737003737370037, 0x3B3B003B3B3B003B, -0x9696009696960096, 0x4B4B004B4B4B004B, 0xBEBE00BEBEBE00BE, 0x2E2E002E2E2E002E, -0x7979007979790079, 0x8C8C008C8C8C008C, 0x6E6E006E6E6E006E, 0x8E8E008E8E8E008E, -0xF5F500F5F5F500F5, 0xB6B600B6B6B600B6, 0xFDFD00FDFDFD00FD, 0x5959005959590059, -0x9898009898980098, 0x6A6A006A6A6A006A, 0x4646004646460046, 0xBABA00BABABA00BA, -0x2525002525250025, 0x4242004242420042, 0xA2A200A2A2A200A2, 0xFAFA00FAFAFA00FA, -0x0707000707070007, 0x5555005555550055, 0xEEEE00EEEEEE00EE, 0x0A0A000A0A0A000A, -0x4949004949490049, 0x6868006868680068, 0x3838003838380038, 0xA4A400A4A4A400A4, -0x2828002828280028, 0x7B7B007B7B7B007B, 0xC9C900C9C9C900C9, 0xC1C100C1C1C100C1, -0xE3E300E3E3E300E3, 0xF4F400F4F4F400F4, 0xC7C700C7C7C700C7, 0x9E9E009E9E9E009E }; - -const u64bit Camellia_SBOX8[256] = { -0x7070700070707000, 0x8282820082828200, 0x2C2C2C002C2C2C00, 0xECECEC00ECECEC00, -0xB3B3B300B3B3B300, 0x2727270027272700, 0xC0C0C000C0C0C000, 0xE5E5E500E5E5E500, -0xE4E4E400E4E4E400, 0x8585850085858500, 0x5757570057575700, 0x3535350035353500, -0xEAEAEA00EAEAEA00, 0x0C0C0C000C0C0C00, 0xAEAEAE00AEAEAE00, 0x4141410041414100, -0x2323230023232300, 0xEFEFEF00EFEFEF00, 0x6B6B6B006B6B6B00, 0x9393930093939300, -0x4545450045454500, 0x1919190019191900, 0xA5A5A500A5A5A500, 0x2121210021212100, -0xEDEDED00EDEDED00, 0x0E0E0E000E0E0E00, 0x4F4F4F004F4F4F00, 0x4E4E4E004E4E4E00, -0x1D1D1D001D1D1D00, 0x6565650065656500, 0x9292920092929200, 0xBDBDBD00BDBDBD00, -0x8686860086868600, 0xB8B8B800B8B8B800, 0xAFAFAF00AFAFAF00, 0x8F8F8F008F8F8F00, -0x7C7C7C007C7C7C00, 0xEBEBEB00EBEBEB00, 0x1F1F1F001F1F1F00, 0xCECECE00CECECE00, -0x3E3E3E003E3E3E00, 0x3030300030303000, 0xDCDCDC00DCDCDC00, 0x5F5F5F005F5F5F00, -0x5E5E5E005E5E5E00, 0xC5C5C500C5C5C500, 0x0B0B0B000B0B0B00, 0x1A1A1A001A1A1A00, -0xA6A6A600A6A6A600, 0xE1E1E100E1E1E100, 0x3939390039393900, 0xCACACA00CACACA00, -0xD5D5D500D5D5D500, 0x4747470047474700, 0x5D5D5D005D5D5D00, 0x3D3D3D003D3D3D00, -0xD9D9D900D9D9D900, 0x0101010001010100, 0x5A5A5A005A5A5A00, 0xD6D6D600D6D6D600, -0x5151510051515100, 0x5656560056565600, 0x6C6C6C006C6C6C00, 0x4D4D4D004D4D4D00, -0x8B8B8B008B8B8B00, 0x0D0D0D000D0D0D00, 0x9A9A9A009A9A9A00, 0x6666660066666600, -0xFBFBFB00FBFBFB00, 0xCCCCCC00CCCCCC00, 0xB0B0B000B0B0B000, 0x2D2D2D002D2D2D00, -0x7474740074747400, 0x1212120012121200, 0x2B2B2B002B2B2B00, 0x2020200020202000, -0xF0F0F000F0F0F000, 0xB1B1B100B1B1B100, 0x8484840084848400, 0x9999990099999900, -0xDFDFDF00DFDFDF00, 0x4C4C4C004C4C4C00, 0xCBCBCB00CBCBCB00, 0xC2C2C200C2C2C200, -0x3434340034343400, 0x7E7E7E007E7E7E00, 0x7676760076767600, 0x0505050005050500, -0x6D6D6D006D6D6D00, 0xB7B7B700B7B7B700, 0xA9A9A900A9A9A900, 0x3131310031313100, -0xD1D1D100D1D1D100, 0x1717170017171700, 0x0404040004040400, 0xD7D7D700D7D7D700, -0x1414140014141400, 0x5858580058585800, 0x3A3A3A003A3A3A00, 0x6161610061616100, -0xDEDEDE00DEDEDE00, 0x1B1B1B001B1B1B00, 0x1111110011111100, 0x1C1C1C001C1C1C00, -0x3232320032323200, 0x0F0F0F000F0F0F00, 0x9C9C9C009C9C9C00, 0x1616160016161600, -0x5353530053535300, 0x1818180018181800, 0xF2F2F200F2F2F200, 0x2222220022222200, -0xFEFEFE00FEFEFE00, 0x4444440044444400, 0xCFCFCF00CFCFCF00, 0xB2B2B200B2B2B200, -0xC3C3C300C3C3C300, 0xB5B5B500B5B5B500, 0x7A7A7A007A7A7A00, 0x9191910091919100, -0x2424240024242400, 0x0808080008080800, 0xE8E8E800E8E8E800, 0xA8A8A800A8A8A800, -0x6060600060606000, 0xFCFCFC00FCFCFC00, 0x6969690069696900, 0x5050500050505000, -0xAAAAAA00AAAAAA00, 0xD0D0D000D0D0D000, 0xA0A0A000A0A0A000, 0x7D7D7D007D7D7D00, -0xA1A1A100A1A1A100, 0x8989890089898900, 0x6262620062626200, 0x9797970097979700, -0x5454540054545400, 0x5B5B5B005B5B5B00, 0x1E1E1E001E1E1E00, 0x9595950095959500, -0xE0E0E000E0E0E000, 0xFFFFFF00FFFFFF00, 0x6464640064646400, 0xD2D2D200D2D2D200, -0x1010100010101000, 0xC4C4C400C4C4C400, 0x0000000000000000, 0x4848480048484800, -0xA3A3A300A3A3A300, 0xF7F7F700F7F7F700, 0x7575750075757500, 0xDBDBDB00DBDBDB00, -0x8A8A8A008A8A8A00, 0x0303030003030300, 0xE6E6E600E6E6E600, 0xDADADA00DADADA00, -0x0909090009090900, 0x3F3F3F003F3F3F00, 0xDDDDDD00DDDDDD00, 0x9494940094949400, -0x8787870087878700, 0x5C5C5C005C5C5C00, 0x8383830083838300, 0x0202020002020200, -0xCDCDCD00CDCDCD00, 0x4A4A4A004A4A4A00, 0x9090900090909000, 0x3333330033333300, -0x7373730073737300, 0x6767670067676700, 0xF6F6F600F6F6F600, 0xF3F3F300F3F3F300, -0x9D9D9D009D9D9D00, 0x7F7F7F007F7F7F00, 0xBFBFBF00BFBFBF00, 0xE2E2E200E2E2E200, -0x5252520052525200, 0x9B9B9B009B9B9B00, 0xD8D8D800D8D8D800, 0x2626260026262600, -0xC8C8C800C8C8C800, 0x3737370037373700, 0xC6C6C600C6C6C600, 0x3B3B3B003B3B3B00, -0x8181810081818100, 0x9696960096969600, 0x6F6F6F006F6F6F00, 0x4B4B4B004B4B4B00, -0x1313130013131300, 0xBEBEBE00BEBEBE00, 0x6363630063636300, 0x2E2E2E002E2E2E00, -0xE9E9E900E9E9E900, 0x7979790079797900, 0xA7A7A700A7A7A700, 0x8C8C8C008C8C8C00, -0x9F9F9F009F9F9F00, 0x6E6E6E006E6E6E00, 0xBCBCBC00BCBCBC00, 0x8E8E8E008E8E8E00, -0x2929290029292900, 0xF5F5F500F5F5F500, 0xF9F9F900F9F9F900, 0xB6B6B600B6B6B600, -0x2F2F2F002F2F2F00, 0xFDFDFD00FDFDFD00, 0xB4B4B400B4B4B400, 0x5959590059595900, -0x7878780078787800, 0x9898980098989800, 0x0606060006060600, 0x6A6A6A006A6A6A00, -0xE7E7E700E7E7E700, 0x4646460046464600, 0x7171710071717100, 0xBABABA00BABABA00, -0xD4D4D400D4D4D400, 0x2525250025252500, 0xABABAB00ABABAB00, 0x4242420042424200, -0x8888880088888800, 0xA2A2A200A2A2A200, 0x8D8D8D008D8D8D00, 0xFAFAFA00FAFAFA00, -0x7272720072727200, 0x0707070007070700, 0xB9B9B900B9B9B900, 0x5555550055555500, -0xF8F8F800F8F8F800, 0xEEEEEE00EEEEEE00, 0xACACAC00ACACAC00, 0x0A0A0A000A0A0A00, -0x3636360036363600, 0x4949490049494900, 0x2A2A2A002A2A2A00, 0x6868680068686800, -0x3C3C3C003C3C3C00, 0x3838380038383800, 0xF1F1F100F1F1F100, 0xA4A4A400A4A4A400, -0x4040400040404000, 0x2828280028282800, 0xD3D3D300D3D3D300, 0x7B7B7B007B7B7B00, -0xBBBBBB00BBBBBB00, 0xC9C9C900C9C9C900, 0x4343430043434300, 0xC1C1C100C1C1C100, -0x1515150015151500, 0xE3E3E300E3E3E300, 0xADADAD00ADADAD00, 0xF4F4F400F4F4F400, -0x7777770077777700, 0xC7C7C700C7C7C700, 0x8080800080808000, 0x9E9E9E009E9E9E00 }; - -} - -#endif diff --git a/src/lib/block/camellia/info.txt b/src/lib/block/camellia/info.txt index 2bcfe80d0..041ba75a2 100644 --- a/src/lib/block/camellia/info.txt +++ b/src/lib/block/camellia/info.txt @@ -1,8 +1,4 @@ -define CAMELLIA 20131128 - -<header:internal> -camellia_sbox.h -</header:internal> +define CAMELLIA 20150922 <header:public> camellia.h diff --git a/src/lib/block/cascade/cascade.cpp b/src/lib/block/cascade/cascade.cpp index 3b59a4362..100fb33ab 100644 --- a/src/lib/block/cascade/cascade.cpp +++ b/src/lib/block/cascade/cascade.cpp @@ -5,17 +5,14 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/cascade.h> namespace Botan { -BOTAN_REGISTER_NAMED_T(BlockCipher, "Cascade", Cascade_Cipher, Cascade_Cipher::make); - Cascade_Cipher* Cascade_Cipher::make(const BlockCipher::Spec& spec) { - std::unique_ptr<BlockCipher> c1(get_block_cipher(spec.arg(0))); - std::unique_ptr<BlockCipher> c2(get_block_cipher(spec.arg(1))); + std::unique_ptr<BlockCipher> c1(BlockCipher::create(spec.arg(0))); + std::unique_ptr<BlockCipher> c2(BlockCipher::create(spec.arg(1))); if(c1 && c2) return new Cascade_Cipher(c1.release(), c2.release()); diff --git a/src/lib/block/cast/cast128.cpp b/src/lib/block/cast/cast128.cpp index e19c6dcb1..3973418a3 100644 --- a/src/lib/block/cast/cast128.cpp +++ b/src/lib/block/cast/cast128.cpp @@ -5,14 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/cast128.h> #include <botan/internal/cast_sboxes.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(CAST_128, "CAST-128"); - namespace { /* diff --git a/src/lib/block/cast/cast256.cpp b/src/lib/block/cast/cast256.cpp index bbb9894e7..7178dc5c1 100644 --- a/src/lib/block/cast/cast256.cpp +++ b/src/lib/block/cast/cast256.cpp @@ -5,14 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/cast256.h> #include <botan/internal/cast_sboxes.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(CAST_256, "CAST-256"); - namespace { /* diff --git a/src/lib/block/des/des.cpp b/src/lib/block/des/des.cpp index c1013b9af..6d2bcfe1e 100644 --- a/src/lib/block/des/des.cpp +++ b/src/lib/block/des/des.cpp @@ -8,14 +8,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/des.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(DES); -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(TripleDES); - namespace { /* diff --git a/src/lib/block/des/desx.cpp b/src/lib/block/des/desx.cpp index 0e19460fc..f6538748c 100644 --- a/src/lib/block/des/desx.cpp +++ b/src/lib/block/des/desx.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/desx.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(DESX); - /* * DESX Encryption */ diff --git a/src/lib/block/gost_28147/gost_28147.cpp b/src/lib/block/gost_28147/gost_28147.cpp index 90bf9328d..b8c3b7280 100644 --- a/src/lib/block/gost_28147/gost_28147.cpp +++ b/src/lib/block/gost_28147/gost_28147.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/gost_28147.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(GOST_28147_89, "GOST-28147-89", "R3411_94_TestParam"); - byte GOST_28147_89_Params::sbox_entry(size_t row, size_t col) const { byte x = sboxes[4 * col + (row / 2)]; diff --git a/src/lib/block/idea/idea.cpp b/src/lib/block/idea/idea.cpp index 764115013..c7706b372 100644 --- a/src/lib/block/idea/idea.cpp +++ b/src/lib/block/idea/idea.cpp @@ -1,17 +1,16 @@ /* * IDEA -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/idea.h> +#include <botan/loadstor.h> +#include <botan/internal/ct_utils.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(IDEA); - namespace { /* @@ -21,8 +20,7 @@ inline u16bit mul(u16bit x, u16bit y) { const u32bit P = static_cast<u32bit>(x) * y; - // P ? 0xFFFF : 0 - const u16bit P_mask = !P - 1; + const u16bit Z_mask = static_cast<u16bit>(ct_expand_mask_32(P) & 0xFFFF); const u32bit P_hi = P >> 16; const u32bit P_lo = P & 0xFFFF; @@ -30,7 +28,7 @@ inline u16bit mul(u16bit x, u16bit y) const u16bit r_1 = (P_lo - P_hi) + (P_lo < P_hi); const u16bit r_2 = 1 - x - y; - return (r_1 & P_mask) | (r_2 & ~P_mask); + return ct_select_mask_16(Z_mask, r_1, r_2); } /* @@ -64,12 +62,16 @@ void idea_op(const byte in[], byte out[], size_t blocks, const u16bit K[52]) { const size_t BLOCK_SIZE = 8; + BOTAN_CONST_TIME_POISON(in, blocks * 8); + BOTAN_CONST_TIME_POISON(out, blocks * 8); + BOTAN_CONST_TIME_POISON(K, 52 * 2); + for(size_t i = 0; i != blocks; ++i) { - u16bit X1 = load_be<u16bit>(in, 0); - u16bit X2 = load_be<u16bit>(in, 1); - u16bit X3 = load_be<u16bit>(in, 2); - u16bit X4 = load_be<u16bit>(in, 3); + u16bit X1 = load_be<u16bit>(in + BLOCK_SIZE*i, 0); + u16bit X2 = load_be<u16bit>(in + BLOCK_SIZE*i, 1); + u16bit X3 = load_be<u16bit>(in + BLOCK_SIZE*i, 2); + u16bit X4 = load_be<u16bit>(in + BLOCK_SIZE*i, 3); for(size_t j = 0; j != 8; ++j) { @@ -96,11 +98,12 @@ void idea_op(const byte in[], byte out[], size_t blocks, const u16bit K[52]) X3 += K[49]; X4 = mul(X4, K[51]); - store_be(out, X1, X3, X2, X4); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; + store_be(out + BLOCK_SIZE*i, X1, X3, X2, X4); } + + BOTAN_CONST_TIME_UNPOISON(in, blocks * 8); + BOTAN_CONST_TIME_UNPOISON(out, blocks * 8); + BOTAN_CONST_TIME_UNPOISON(K, 52 * 2); } } @@ -129,6 +132,10 @@ void IDEA::key_schedule(const byte key[], size_t) EK.resize(52); DK.resize(52); + BOTAN_CONST_TIME_POISON(key, 16); + BOTAN_CONST_TIME_POISON(EK.data(), 52 * 2); + BOTAN_CONST_TIME_POISON(DK.data(), 52 * 2); + for(size_t i = 0; i != 8; ++i) EK[i] = load_be<u16bit>(key, i); @@ -160,6 +167,10 @@ void IDEA::key_schedule(const byte key[], size_t) DK[2] = -EK[50]; DK[1] = -EK[49]; DK[0] = mul_inv(EK[48]); + + BOTAN_CONST_TIME_UNPOISON(key, 16); + BOTAN_CONST_TIME_UNPOISON(EK.data(), 52 * 2); + BOTAN_CONST_TIME_UNPOISON(DK.data(), 52 * 2); } void IDEA::clear() diff --git a/src/lib/block/idea_sse2/idea_sse2.cpp b/src/lib/block/idea_sse2/idea_sse2.cpp index af7e2182d..51b5e909b 100644 --- a/src/lib/block/idea_sse2/idea_sse2.cpp +++ b/src/lib/block/idea_sse2/idea_sse2.cpp @@ -5,15 +5,13 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/idea_sse2.h> #include <botan/cpuid.h> +#include <botan/internal/ct_utils.h> #include <emmintrin.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_sse2(), IDEA_SSE2, "IDEA", "sse2", 64); - namespace { inline __m128i mul(__m128i X, u16bit K_16) @@ -133,6 +131,10 @@ void transpose_out(__m128i& B0, __m128i& B1, __m128i& B2, __m128i& B3) */ void idea_op_8(const byte in[64], byte out[64], const u16bit EK[52]) { + BOTAN_CONST_TIME_POISON(in, 64); + BOTAN_CONST_TIME_POISON(out, 64); + BOTAN_CONST_TIME_POISON(EK, 52*2); + const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i B0 = _mm_loadu_si128(in_mm + 0); @@ -156,7 +158,6 @@ void idea_op_8(const byte in[64], byte out[64], const u16bit EK[52]) B3 = mul(B3, EK[6*i+3]); __m128i T0 = B2; - B2 = _mm_xor_si128(B2, B0); B2 = mul(B2, EK[6*i+4]); @@ -193,6 +194,10 @@ void idea_op_8(const byte in[64], byte out[64], const u16bit EK[52]) _mm_storeu_si128(out_mm + 1, B2); _mm_storeu_si128(out_mm + 2, B1); _mm_storeu_si128(out_mm + 3, B3); + + BOTAN_CONST_TIME_UNPOISON(in, 64); + BOTAN_CONST_TIME_UNPOISON(out, 64); + BOTAN_CONST_TIME_UNPOISON(EK, 52*2); } } diff --git a/src/lib/block/info.txt b/src/lib/block/info.txt index e1aa52d85..30f7392ef 100644 --- a/src/lib/block/info.txt +++ b/src/lib/block/info.txt @@ -3,7 +3,3 @@ define BLOCK_CIPHER 20131128 <header:public> block_cipher.h </header:public> - -<header:internal> -block_utils.h -</header:internal> diff --git a/src/lib/block/kasumi/kasumi.cpp b/src/lib/block/kasumi/kasumi.cpp index d0233cf5c..604d2d21a 100644 --- a/src/lib/block/kasumi/kasumi.cpp +++ b/src/lib/block/kasumi/kasumi.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/kasumi.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(KASUMI); - namespace { /* diff --git a/src/lib/block/lion/lion.cpp b/src/lib/block/lion/lion.cpp index a487e3eb0..559816aea 100644 --- a/src/lib/block/lion/lion.cpp +++ b/src/lib/block/lion/lion.cpp @@ -5,20 +5,17 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/lion.h> #include <botan/parsing.h> namespace Botan { -namespace { - -Lion* make_lion(const BlockCipher::Spec& spec) +Lion* Lion::make(const BlockCipher::Spec& spec) { if(spec.arg_count_between(2, 3)) { - std::unique_ptr<HashFunction> hash(get_hash_function(spec.arg(0))); - std::unique_ptr<StreamCipher> stream(get_stream_cipher(spec.arg(1))); + std::unique_ptr<HashFunction> hash(HashFunction::create(spec.arg(0))); + std::unique_ptr<StreamCipher> stream(StreamCipher::create(spec.arg(1))); if(hash && stream) { @@ -29,10 +26,6 @@ Lion* make_lion(const BlockCipher::Spec& spec) return nullptr; } -} - -BOTAN_REGISTER_NAMED_T(BlockCipher, "Lion", Lion, make_lion); - /* * Lion Encryption */ diff --git a/src/lib/block/lion/lion.h b/src/lib/block/lion/lion.h index d03d1d1a0..116fa911b 100644 --- a/src/lib/block/lion/lion.h +++ b/src/lib/block/lion/lion.h @@ -39,6 +39,8 @@ class BOTAN_DLL Lion : public BlockCipher std::string name() const override; BlockCipher* clone() const override; + static Lion* make(const Spec&); + /** * @param hash the hash to use internally * @param cipher the stream cipher to use internally diff --git a/src/lib/block/mars/mars.cpp b/src/lib/block/mars/mars.cpp index 50f264861..becbbf2db 100644 --- a/src/lib/block/mars/mars.cpp +++ b/src/lib/block/mars/mars.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/mars.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(MARS); - namespace { /** diff --git a/src/lib/block/misty1/misty1.cpp b/src/lib/block/misty1/misty1.cpp index 23233e02f..490eec826 100644 --- a/src/lib/block/misty1/misty1.cpp +++ b/src/lib/block/misty1/misty1.cpp @@ -5,14 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/misty1.h> +#include <botan/loadstor.h> #include <botan/parsing.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(MISTY1); - namespace { static const byte MISTY1_SBOX_S7[128] = { diff --git a/src/lib/block/noekeon/noekeon.cpp b/src/lib/block/noekeon/noekeon.cpp index fb1a215fe..d63ec3129 100644 --- a/src/lib/block/noekeon/noekeon.cpp +++ b/src/lib/block/noekeon/noekeon.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/noekeon.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Noekeon); - namespace { /* diff --git a/src/lib/block/noekeon_simd/noekeon_simd.cpp b/src/lib/block/noekeon_simd/noekeon_simd.cpp index a5d757d3c..07fcf19ff 100644 --- a/src/lib/block/noekeon_simd/noekeon_simd.cpp +++ b/src/lib/block/noekeon_simd/noekeon_simd.cpp @@ -5,14 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/noekeon_simd.h> #include <botan/internal/simd_32.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Noekeon_SIMD, "Noekeon", "simd32", 64); - /* * Noekeon's Theta Operation */ diff --git a/src/lib/block/openssl_block/info.txt b/src/lib/block/openssl_block/info.txt new file mode 100644 index 000000000..62feaac95 --- /dev/null +++ b/src/lib/block/openssl_block/info.txt @@ -0,0 +1,5 @@ +define OPENSSL_BLOCK_CIPHER 20151019 + +<requires> +openssl +</requires> diff --git a/src/lib/vendor/openssl/openssl_block.cpp b/src/lib/block/openssl_block/openssl_block.cpp index 4fd41112b..a35919e3a 100644 --- a/src/lib/vendor/openssl/openssl_block.cpp +++ b/src/lib/block/openssl_block/openssl_block.cpp @@ -1,11 +1,13 @@ /* -* OpenSSL Block Cipher +* Block Ciphers via OpenSSL * (C) 1999-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> +#include <botan/block_cipher.h> +#include <botan/internal/algo_registry.h> +#include <botan/internal/openssl.h> #include <openssl/evp.h> namespace Botan { @@ -167,12 +169,12 @@ make_evp_block_maker_keylen(const EVP_CIPHER* cipher, const char* algo, #define BOTAN_REGISTER_OPENSSL_EVP_BLOCK(NAME, EVP) \ BOTAN_REGISTER_TYPE(BlockCipher, EVP_BlockCipher ## EVP, NAME, \ - make_evp_block_maker(EVP(), NAME), "openssl", 96); + make_evp_block_maker(EVP(), NAME), "openssl", BOTAN_OPENSSL_BLOCK_PRIO); #define BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN(NAME, EVP, KMIN, KMAX, KMOD) \ BOTAN_REGISTER_TYPE(BlockCipher, OpenSSL_BlockCipher ## EVP, NAME, \ make_evp_block_maker_keylen(EVP(), NAME, KMIN, KMAX, KMOD), \ - "openssl", 96); + "openssl", BOTAN_OPENSSL_BLOCK_PRIO); #if !defined(OPENSSL_NO_AES) BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-128", EVP_aes_128_ecb); diff --git a/src/lib/block/rc2/rc2.cpp b/src/lib/block/rc2/rc2.cpp index d1fc8a2e6..bcd8475e3 100644 --- a/src/lib/block/rc2/rc2.cpp +++ b/src/lib/block/rc2/rc2.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/rc2.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(RC2); - /* * RC2 Encryption */ diff --git a/src/lib/block/rc5/rc5.cpp b/src/lib/block/rc5/rc5.cpp index 27fa0e14d..a32efd775 100644 --- a/src/lib/block/rc5/rc5.cpp +++ b/src/lib/block/rc5/rc5.cpp @@ -5,14 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/rc5.h> +#include <botan/loadstor.h> #include <botan/parsing.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_1LEN(RC5, 12); - /* * RC5 Encryption */ diff --git a/src/lib/block/rc6/rc6.cpp b/src/lib/block/rc6/rc6.cpp index e9aa5fe8b..48fb1c32e 100644 --- a/src/lib/block/rc6/rc6.cpp +++ b/src/lib/block/rc6/rc6.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/rc6.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(RC6); - /* * RC6 Encryption */ diff --git a/src/lib/block/safer/safer_sk.cpp b/src/lib/block/safer/safer_sk.cpp index f5996a986..a8781697d 100644 --- a/src/lib/block/safer/safer_sk.cpp +++ b/src/lib/block/safer/safer_sk.cpp @@ -5,16 +5,14 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/safer_sk.h> +#include <botan/rotate.h> #include <botan/parsing.h> namespace Botan { namespace { -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1LEN(SAFER_SK, "SAFER-SK", 10); - const byte EXP[256] = { 0x01, 0x2D, 0xE2, 0x93, 0xBE, 0x45, 0x15, 0xAE, 0x78, 0x03, 0x87, 0xA4, 0xB8, 0x38, 0xCF, 0x3F, 0x08, 0x67, 0x09, 0x94, 0xEB, 0x26, 0xA8, 0x6B, diff --git a/src/lib/block/seed/seed.cpp b/src/lib/block/seed/seed.cpp index 316ef1e04..833f9943f 100644 --- a/src/lib/block/seed/seed.cpp +++ b/src/lib/block/seed/seed.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/seed.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(SEED); - /* * SEED G Function */ diff --git a/src/lib/block/serpent/serpent.cpp b/src/lib/block/serpent/serpent.cpp index b809e602c..c0a65ed33 100644 --- a/src/lib/block/serpent/serpent.cpp +++ b/src/lib/block/serpent/serpent.cpp @@ -5,14 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/serpent.h> +#include <botan/loadstor.h> #include <botan/internal/serpent_sbox.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Serpent); - namespace { /* diff --git a/src/lib/block/serpent_simd/serp_simd.cpp b/src/lib/block/serpent_simd/serp_simd.cpp index 7b957598f..02fe7d6d9 100644 --- a/src/lib/block/serpent_simd/serp_simd.cpp +++ b/src/lib/block/serpent_simd/serp_simd.cpp @@ -5,15 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/serp_simd.h> #include <botan/internal/serpent_sbox.h> #include <botan/internal/simd_32.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Serpent_SIMD, "Serpent", "simd32", 64); - namespace { #define key_xor(round, B0, B1, B2, B3) \ diff --git a/src/lib/block/tea/tea.cpp b/src/lib/block/tea/tea.cpp index ef630f715..01f342607 100644 --- a/src/lib/block/tea/tea.cpp +++ b/src/lib/block/tea/tea.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/tea.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(TEA); - /* * TEA Encryption */ diff --git a/src/lib/block/threefish/threefish.cpp b/src/lib/block/threefish/threefish.cpp index 322f54881..93fd122c2 100644 --- a/src/lib/block/threefish/threefish.cpp +++ b/src/lib/block/threefish/threefish.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/threefish.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Threefish_512, "Threefish-512"); - #define THREEFISH_ROUND(X0,X1,X2,X3,X4,X5,X6,X7,ROT1,ROT2,ROT3,ROT4) \ do { \ X0 += X4; \ diff --git a/src/lib/block/threefish_avx2/threefish_avx2.cpp b/src/lib/block/threefish_avx2/threefish_avx2.cpp index e17146162..bed98fafa 100644 --- a/src/lib/block/threefish_avx2/threefish_avx2.cpp +++ b/src/lib/block/threefish_avx2/threefish_avx2.cpp @@ -5,15 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/threefish_avx2.h> #include <botan/cpuid.h> #include <immintrin.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_avx2(), Threefish_512_AVX2, "Threefish-512", "avx2", 64); - namespace { inline void interleave_epi64(__m256i& X0, __m256i& X1) diff --git a/src/lib/block/twofish/twofish.cpp b/src/lib/block/twofish/twofish.cpp index 43ea41bfd..ffdf4b198 100644 --- a/src/lib/block/twofish/twofish.cpp +++ b/src/lib/block/twofish/twofish.cpp @@ -8,13 +8,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/twofish.h> +#include <botan/loadstor.h> +#include <botan/rotate.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Twofish); - /* * Twofish Encryption */ diff --git a/src/lib/block/xtea/xtea.cpp b/src/lib/block/xtea/xtea.cpp index 9fe265457..59060dff7 100644 --- a/src/lib/block/xtea/xtea.cpp +++ b/src/lib/block/xtea/xtea.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/xtea.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(XTEA); - namespace { void xtea_encrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) diff --git a/src/lib/block/xtea_simd/xtea_simd.cpp b/src/lib/block/xtea_simd/xtea_simd.cpp index ffd2eb560..6e50f4ff7 100644 --- a/src/lib/block/xtea_simd/xtea_simd.cpp +++ b/src/lib/block/xtea_simd/xtea_simd.cpp @@ -5,14 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/block_utils.h> #include <botan/xtea_simd.h> #include <botan/internal/simd_32.h> namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), XTEA_SIMD, "XTEA", "simd32", 64); - namespace { void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) diff --git a/src/lib/cert/x509/key_constraint.h b/src/lib/cert/x509/key_constraint.h index 22ae7a32e..3509b6868 100644 --- a/src/lib/cert/x509/key_constraint.h +++ b/src/lib/cert/x509/key_constraint.h @@ -14,6 +14,7 @@ namespace Botan { /** * X.509v3 Key Constraints. +* If updating update copy in ffi.h */ enum Key_Constraints { NO_CONSTRAINTS = 0, diff --git a/src/lib/cert/x509/ocsp_types.cpp b/src/lib/cert/x509/ocsp_types.cpp index 0877f848d..04ab1ea03 100644 --- a/src/lib/cert/x509/ocsp_types.cpp +++ b/src/lib/cert/x509/ocsp_types.cpp @@ -9,7 +9,6 @@ #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/x509_ext.h> -#include <botan/lookup.h> #include <botan/hash.h> #include <botan/oids.h> @@ -24,7 +23,7 @@ CertID::CertID(const X509_Certificate& issuer, In practice it seems some responders, including, notably, ocsp.verisign.com, will reject anything but SHA-1 here */ - std::unique_ptr<HashFunction> hash(get_hash("SHA-160")); + std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-160")); m_hash_id = AlgorithmIdentifier(hash->name(), AlgorithmIdentifier::USE_NULL_PARAM); m_issuer_key_hash = unlock(hash->process(extract_key_bitstr(issuer))); @@ -54,7 +53,7 @@ bool CertID::is_id_for(const X509_Certificate& issuer, if(BigInt::decode(subject.serial_number()) != m_subject_serial) return false; - std::unique_ptr<HashFunction> hash(get_hash(OIDS::lookup(m_hash_id.oid))); + std::unique_ptr<HashFunction> hash(HashFunction::create(OIDS::lookup(m_hash_id.oid))); if(m_issuer_dn_hash != unlock(hash->process(subject.raw_issuer_dn()))) return false; diff --git a/src/lib/cert/x509/x509_ca.cpp b/src/lib/cert/x509/x509_ca.cpp index e6f689016..d329bfdd8 100644 --- a/src/lib/cert/x509/x509_ca.cpp +++ b/src/lib/cert/x509/x509_ca.cpp @@ -11,7 +11,6 @@ #include <botan/ber_dec.h> #include <botan/bigint.h> #include <botan/parsing.h> -#include <botan/lookup.h> #include <botan/oids.h> #include <botan/hash.h> #include <botan/key_constraint.h> @@ -102,6 +101,7 @@ X509_Certificate X509_CA::make_cert(PK_Signer* signer, BigInt serial_no(rng, SERIAL_BITS); + // clang-format off return X509_Certificate(X509_Object::make_signed( signer, rng, sig_algo, DER_Encoder().start_cons(SEQUENCE) @@ -130,6 +130,7 @@ X509_Certificate X509_CA::make_cert(PK_Signer* signer, .end_cons() .get_contents() ));; + // clang-format on } /* @@ -179,6 +180,7 @@ X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked, new Cert_Extension::Authority_Key_ID(cert.subject_key_id())); extensions.add(new Cert_Extension::CRL_Number(crl_number)); + // clang-format off const std::vector<byte> crl = X509_Object::make_signed( signer, rng, ca_sig_algo, DER_Encoder().start_cons(SEQUENCE) @@ -200,6 +202,7 @@ X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked, .end_explicit() .end_cons() .get_contents()); + // clang-format on return X509_CRL(crl); } @@ -221,7 +224,7 @@ PK_Signer* choose_sig_format(const Private_Key& key, { const std::string algo_name = key.algo_name(); - std::unique_ptr<HashFunction> hash(get_hash(hash_fn)); + std::unique_ptr<HashFunction> hash(HashFunction::create(hash_fn)); if(!hash) throw Algorithm_Not_Found(hash_fn); @@ -240,7 +243,7 @@ PK_Signer* choose_sig_format(const Private_Key& key, const Signature_Format format = (key.message_parts() > 1) ? DER_SEQUENCE : IEEE_1363; - padding = padding + '(' + hash->name() + ')'; + padding = padding + "(" + hash->name() + ")"; sig_algo.oid = OIDS::lookup(algo_name + "/" + padding); sig_algo.parameters = key.algorithm_identifier().parameters; diff --git a/src/lib/cert/x509/x509cert.cpp b/src/lib/cert/x509/x509cert.cpp index f6f87bbf4..48e437352 100644 --- a/src/lib/cert/x509/x509cert.cpp +++ b/src/lib/cert/x509/x509cert.cpp @@ -12,7 +12,6 @@ #include <botan/internal/stl_util.h> #include <botan/parsing.h> #include <botan/bigint.h> -#include <botan/lookup.h> #include <botan/oids.h> #include <botan/pem.h> #include <botan/hash.h> @@ -369,7 +368,7 @@ bool cert_subject_dns_match(const std::string& name, std::string X509_Certificate::fingerprint(const std::string& hash_name) const { - std::unique_ptr<HashFunction> hash(get_hash(hash_name)); + std::unique_ptr<HashFunction> hash(HashFunction::create(hash_name)); hash->update(this->BER_encode()); const auto hex_print = hex_encode(hash->final()); diff --git a/src/lib/compression/bzip2/bzip2.h b/src/lib/compression/bzip2/bzip2.h index d958cbfe7..001080fd4 100644 --- a/src/lib/compression/bzip2/bzip2.h +++ b/src/lib/compression/bzip2/bzip2.h @@ -31,7 +31,7 @@ class BOTAN_DLL Bzip2_Compression : public Stream_Compression std::string name() const override { return "Bzip2_Compression"; } private: - Compression_Stream* make_stream() const; + Compression_Stream* make_stream() const override; const size_t m_block_size; }; diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp index 6057f9408..ddbcd7cec 100644 --- a/src/lib/compression/compression.cpp +++ b/src/lib/compression/compression.cpp @@ -104,8 +104,16 @@ void Stream_Compression::process(secure_vector<byte>& buf, size_t offset, u32bit if(m_buffer.size() < buf.size() + offset) m_buffer.resize(buf.size() + offset); - m_stream->next_in(&buf[offset], buf.size() - offset); - m_stream->next_out(&m_buffer[offset], m_buffer.size() - offset); + // If the output buffer has zero length, .data() might return nullptr. This would + // make some compression algorithms (notably those provided by zlib) fail. + // Any small positive value works fine, but we choose 32 as it is the smallest power + // of two that is large enough to hold all the headers and trailers of the common + // formats, preventing further resizings to make room for output data. + if(m_buffer.size() == 0) + m_buffer.resize(32); + + m_stream->next_in(buf.data() + offset, buf.size() - offset); + m_stream->next_out(m_buffer.data() + offset, m_buffer.size() - offset); while(true) { @@ -115,7 +123,7 @@ void Stream_Compression::process(secure_vector<byte>& buf, size_t offset, u32bit { const size_t added = 8 + m_buffer.size(); m_buffer.resize(m_buffer.size() + added); - m_stream->next_out(&m_buffer[m_buffer.size() - added], added); + m_stream->next_out(m_buffer.data() + m_buffer.size() - added, added); } else if(m_stream->avail_in() == 0) { @@ -170,8 +178,8 @@ void Stream_Decompression::process(secure_vector<byte>& buf, size_t offset, u32b if(m_buffer.size() < buf.size() + offset) m_buffer.resize(buf.size() + offset); - m_stream->next_in(&buf[offset], buf.size() - offset); - m_stream->next_out(&m_buffer[offset], m_buffer.size() - offset); + m_stream->next_in(buf.data() + offset, buf.size() - offset); + m_stream->next_out(m_buffer.data() + offset, m_buffer.size() - offset); while(true) { @@ -189,14 +197,14 @@ void Stream_Decompression::process(secure_vector<byte>& buf, size_t offset, u32b // More data follows: try to process as a following stream const size_t read = (buf.size() - offset) - m_stream->avail_in(); start(); - m_stream->next_in(&buf[offset + read], buf.size() - offset - read); + m_stream->next_in(buf.data() + offset + read, buf.size() - offset - read); } if(m_stream->avail_out() == 0) { const size_t added = 8 + m_buffer.size(); m_buffer.resize(m_buffer.size() + added); - m_stream->next_out(&m_buffer[m_buffer.size() - added], added); + m_stream->next_out(m_buffer.data() + m_buffer.size() - added, added); } else if(m_stream->avail_in() == 0) { diff --git a/src/lib/compression/compression.h b/src/lib/compression/compression.h index 62525dcc9..2c74550d6 100644 --- a/src/lib/compression/compression.h +++ b/src/lib/compression/compression.h @@ -65,6 +65,7 @@ class BOTAN_DLL Stream_Compression : public Compressor_Transform void finish(secure_vector<byte>& buf, size_t offset = 0) override; void clear() override; + private: secure_vector<byte> start_raw(const byte[], size_t) override; diff --git a/src/lib/compression/lzma/lzma.h b/src/lib/compression/lzma/lzma.h index 8a142c192..ff6b45ef0 100644 --- a/src/lib/compression/lzma/lzma.h +++ b/src/lib/compression/lzma/lzma.h @@ -30,7 +30,7 @@ class BOTAN_DLL LZMA_Compression : public Stream_Compression std::string name() const override { return "LZMA_Compression"; } private: - Compression_Stream* make_stream() const; + Compression_Stream* make_stream() const override; const size_t m_level; }; diff --git a/src/lib/compression/zlib/zlib.h b/src/lib/compression/zlib/zlib.h index 19bae3480..2437e6133 100644 --- a/src/lib/compression/zlib/zlib.h +++ b/src/lib/compression/zlib/zlib.h @@ -30,7 +30,7 @@ class BOTAN_DLL Zlib_Compression : public Stream_Compression std::string name() const override { return "Zlib_Compression"; } private: - Compression_Stream* make_stream() const; + Compression_Stream* make_stream() const override; const size_t m_level; }; @@ -44,7 +44,7 @@ class BOTAN_DLL Zlib_Decompression : public Stream_Decompression std::string name() const override { return "Zlib_Decompression"; } private: - Compression_Stream* make_stream() const; + Compression_Stream* make_stream() const override; }; /** @@ -63,7 +63,7 @@ class BOTAN_DLL Deflate_Compression : public Stream_Compression std::string name() const override { return "Deflate_Compression"; } private: - Compression_Stream* make_stream() const; + Compression_Stream* make_stream() const override; const size_t m_level; }; @@ -77,7 +77,7 @@ class BOTAN_DLL Deflate_Decompression : public Stream_Decompression std::string name() const override { return "Deflate_Decompression"; } private: - Compression_Stream* make_stream() const; + Compression_Stream* make_stream() const override; }; /** @@ -97,7 +97,7 @@ class BOTAN_DLL Gzip_Compression : public Stream_Compression std::string name() const override { return "Gzip_Compression"; } private: - Compression_Stream* make_stream() const; + Compression_Stream* make_stream() const override; const size_t m_level; const byte m_os_code; @@ -106,13 +106,13 @@ class BOTAN_DLL Gzip_Compression : public Stream_Compression /** * Gzip Decompression */ -class BOTAN_DLL Gzip_Decompression : public Stream_Compression +class BOTAN_DLL Gzip_Decompression : public Stream_Decompression { public: std::string name() const override { return "Gzip_Decompression"; } private: - Compression_Stream* make_stream() const; + Compression_Stream* make_stream() const override; }; } diff --git a/src/lib/credentials/info.txt b/src/lib/credentials/info.txt deleted file mode 100644 index 303139c4c..000000000 --- a/src/lib/credentials/info.txt +++ /dev/null @@ -1,5 +0,0 @@ -define CREDENTIALS_MANAGER 20131128 - -<requires> -x509 -</requires> diff --git a/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp b/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp new file mode 100644 index 000000000..f04b75a12 --- /dev/null +++ b/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp @@ -0,0 +1,28 @@ +/* +* Darwin SecRandomCopyBytes EntropySource +* (C) 2015 Daniel Seither (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/internal/darwin_secrandom.h> +#include <Security/Security.h> + +namespace Botan { + +/** +* Gather entropy from SecRandomCopyBytes +*/ +void Darwin_SecRandom::poll(Entropy_Accumulator& accum) + { + const size_t ENTROPY_BITS_PER_BYTE = 8; + const size_t BUF_SIZE = 256; + + m_buf.resize(BUF_SIZE); + if (0 == SecRandomCopyBytes(kSecRandomDefault, m_buf.size(), m_buf.data())) + { + accum.add(m_buf.data(), m_buf.size(), ENTROPY_BITS_PER_BYTE); + } + } + +} diff --git a/src/lib/entropy/darwin_secrandom/darwin_secrandom.h b/src/lib/entropy/darwin_secrandom/darwin_secrandom.h new file mode 100644 index 000000000..504d5cc64 --- /dev/null +++ b/src/lib/entropy/darwin_secrandom/darwin_secrandom.h @@ -0,0 +1,31 @@ +/* +* Darwin SecRandomCopyBytes EntropySource +* (C) 2015 Daniel Seither (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENTROPY_SRC_DARWIN_SECRANDOM_H__ +#define BOTAN_ENTROPY_SRC_DARWIN_SECRANDOM_H__ + +#include <botan/entropy_src.h> + +namespace Botan { + +/** +* Entropy source using SecRandomCopyBytes from Darwin's Security.framework +*/ +class Darwin_SecRandom : public EntropySource + { + public: + std::string name() const override { return "Darwin SecRandomCopyBytes"; } + + void poll(Entropy_Accumulator& accum) override; + + private: + secure_vector<byte> m_buf; + }; + +} + +#endif diff --git a/src/lib/entropy/darwin_secrandom/info.txt b/src/lib/entropy/darwin_secrandom/info.txt new file mode 100644 index 000000000..e12c341fd --- /dev/null +++ b/src/lib/entropy/darwin_secrandom/info.txt @@ -0,0 +1,17 @@ +define ENTROPY_SRC_DARWIN_SECRANDOM 20150925 + +<source> +darwin_secrandom.cpp +</source> + +<header:internal> +darwin_secrandom.h +</header:internal> + +<os> +darwin +</os> + +<frameworks> +darwin -> Security +</frameworks>
\ No newline at end of file diff --git a/src/lib/entropy/entropy_srcs.cpp b/src/lib/entropy/entropy_srcs.cpp index d44ab8c92..d57160c88 100644 --- a/src/lib/entropy/entropy_srcs.cpp +++ b/src/lib/entropy/entropy_srcs.cpp @@ -43,6 +43,10 @@ #include <botan/internal/proc_walk.h> #endif +#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) + #include <botan/internal/darwin_secrandom.h> +#endif + namespace Botan { namespace { @@ -97,6 +101,10 @@ std::vector<std::unique_ptr<EntropySource>> get_default_entropy_sources() )); #endif +#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) + sources.push_back(std::unique_ptr<EntropySource>(new Darwin_SecRandom)); +#endif + return sources; } diff --git a/src/lib/entropy/proc_walk/info.txt b/src/lib/entropy/proc_walk/info.txt index c713d3b8e..8c3947dc6 100644 --- a/src/lib/entropy/proc_walk/info.txt +++ b/src/lib/entropy/proc_walk/info.txt @@ -24,7 +24,3 @@ openbsd qnx solaris </os> - -<requires> -alloc -</requires> diff --git a/src/lib/entropy/proc_walk/proc_walk.cpp b/src/lib/entropy/proc_walk/proc_walk.cpp index 7fbea678e..3d63e5d5a 100644 --- a/src/lib/entropy/proc_walk/proc_walk.cpp +++ b/src/lib/entropy/proc_walk/proc_walk.cpp @@ -86,7 +86,7 @@ int Directory_Walker::next_fd() if(filename == "." || filename == "..") continue; - const std::string full_path = entry.second + '/' + filename; + const std::string full_path = entry.second + "/" + filename; struct stat stat_buf; if(::lstat(full_path.c_str(), &stat_buf) == -1) diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 8d96a0fc7..eb30b4831 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -7,13 +7,14 @@ #include <botan/ffi.h> #include <botan/system_rng.h> #include <botan/auto_rng.h> -#include <botan/lookup.h> #include <botan/aead.h> #include <botan/hash.h> #include <botan/mac.h> #include <botan/pbkdf.h> #include <botan/version.h> #include <botan/pkcs8.h> +#include <botan/x509cert.h> +#include <botan/data_src.h> #include <botan/pubkey.h> #include <botan/data_src.h> #include <botan/hex.h> @@ -38,10 +39,23 @@ #include <botan/curve25519.h> #endif +#if defined(BOTAN_HAS_MCELIECE) + #include <botan/mceliece.h> +#endif + +#if defined(BOTAN_HAS_MCEIES) + #include <botan/mceies.h> +#endif + #if defined(BOTAN_HAS_BCRYPT) #include <botan/bcrypt.h> #endif +#if defined(BOTAN_HAS_TLS) + #include <botan/tls_client.h> + #include <botan/tls_server.h> +#endif + namespace { #define BOTAN_ASSERT_ARG_NON_NULL(p) \ @@ -71,6 +85,12 @@ void log_exception(const char* func_name, const char* what) fprintf(stderr, "%s: %s\n", func_name, what); } +int ffi_error_exception_thrown(const char* exn) + { + printf("exception %s\n", exn); + return BOTAN_FFI_ERROR_EXCEPTION_THROWN; + } + template<typename T, uint32_t M> T& safe_get(botan_struct<T,M>* p) { @@ -107,15 +127,19 @@ int apply_fn(botan_struct<T, M>* o, const char* func_name, F func) inline int write_output(uint8_t out[], size_t* out_len, const uint8_t buf[], size_t buf_len) { - Botan::clear_mem(out, *out_len); const size_t avail = *out_len; *out_len = buf_len; + if(avail >= buf_len) { Botan::copy_mem(out, buf, buf_len); return 0; } - return -1; + else + { + Botan::clear_mem(out, avail); + return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE; + } } template<typename Alloc> @@ -162,12 +186,18 @@ BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_sign_struct, Botan::PK_Signer, 0x1AF0C39F); BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_verify_struct, Botan::PK_Verifier, 0x2B91F936); BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_ka_struct, Botan::PK_Key_Agreement, 0x2939CAB1); +BOTAN_FFI_DECLARE_STRUCT(botan_x509_cert_struct, Botan::X509_Certificate, 0x8F628937); + +#if defined(BOTAN_HAS_TLS) +BOTAN_FFI_DECLARE_STRUCT(botan_tls_channel_struct, Botan::TLS::Channel, 0x0212FE99); +#endif + /* * Versioning */ uint32_t botan_ffi_api_version() { - return 20150210; // should match value in info.txt + return BOTAN_HAS_FFI; } const char* botan_version_string() @@ -182,7 +212,7 @@ uint32_t botan_version_datestamp() { return Botan::version_datestamp(); } int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len) { - return Botan::same_mem(x, y, len) ? 0 : 1; + return Botan::same_mem(x, y, len) ? 0 : -1; } int botan_hex_encode(const uint8_t* in, size_t len, char* out, uint32_t flags) @@ -203,21 +233,6 @@ int botan_hex_encode(const uint8_t* in, size_t len, char* out, uint32_t flags) int botan_rng_init(botan_rng_t* rng_out, const char* rng_type) { - // Just gives unique_ptr something to delete, really - class RNG_Wrapper : public Botan::RandomNumberGenerator - { - public: - RNG_Wrapper(Botan::RandomNumberGenerator& rng) : m_rng(rng) {} - void randomize(Botan::byte out[], size_t len) override { m_rng.randomize(out, len); } - bool is_seeded() const override { return m_rng.is_seeded(); } - void clear() override { m_rng.clear(); } - std::string name() const override { return m_rng.name(); } - void reseed(size_t poll_bits = 256) override { m_rng.reseed(poll_bits); } - void add_entropy(const Botan::byte in[], size_t len) override { m_rng.add_entropy(in, len); } - private: - Botan::RandomNumberGenerator& m_rng; - }; - try { BOTAN_ASSERT_ARG_NON_NULL(rng_out); @@ -230,7 +245,7 @@ int botan_rng_init(botan_rng_t* rng_out, const char* rng_type) std::unique_ptr<Botan::RandomNumberGenerator> rng; if(rng_type_s == "system") - rng.reset(new RNG_Wrapper(Botan::system_rng())); + rng.reset(new Botan::System_RNG); else if(rng_type_s == "user") rng.reset(new Botan::AutoSeeded_RNG); @@ -277,9 +292,10 @@ int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_t flags) if(flags != 0) return BOTAN_FFI_ERROR_BAD_FLAG; - if(auto h = Botan::get_hash_function(hash_name)) + auto h = Botan::HashFunction::create(hash_name); + if(h) { - *hash = new botan_hash_struct(h); + *hash = new botan_hash_struct(h.release()); return 0; } } @@ -328,9 +344,10 @@ int botan_mac_init(botan_mac_t* mac, const char* mac_name, uint32_t flags) if(!mac || !mac_name || flags != 0) return -1; - if(auto m = Botan::get_mac(mac_name)) + auto m = Botan::MessageAuthenticationCode::create(mac_name); + if(m) { - *mac = new botan_mac_struct(m); + *mac = new botan_mac_struct(m.release()); return 0; } } @@ -635,7 +652,6 @@ int botan_kdf(const char* kdf_algo, return -1; } -#if defined(BOTAN_HAS_BCRYPT) int botan_bcrypt_generate(uint8_t* out, size_t* out_len, const char* pass, botan_rng_t rng_obj, size_t wf, @@ -653,9 +669,13 @@ int botan_bcrypt_generate(uint8_t* out, size_t* out_len, if(wf < 2 || wf > 30) throw std::runtime_error("Bad bcrypt work factor " + std::to_string(wf)); +#if defined(BOTAN_HAS_BCRYPT) Botan::RandomNumberGenerator& rng = safe_get(rng_obj); const std::string bcrypt = Botan::generate_bcrypt(pass, rng, wf); return write_str_output(out, out_len, bcrypt); +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif } catch(std::exception& e) { @@ -673,9 +693,12 @@ int botan_bcrypt_is_valid(const char* pass, const char* hash) { try { +#if defined(BOTAN_HAS_BCRYPT) if(Botan::check_bcrypt(pass, hash)) return 0; // success - return 1; +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif } catch(std::exception& e) { @@ -689,8 +712,6 @@ int botan_bcrypt_is_valid(const char* pass, const char* hash) return BOTAN_FFI_ERROR_EXCEPTION_THROWN; } -#endif - int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits) { try @@ -707,6 +728,8 @@ int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size std::unique_ptr<Botan::Private_Key> key(new Botan::RSA_PrivateKey(rng, n_bits)); *key_obj = new botan_privkey_struct(key.release()); return 0; +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; #endif } catch(std::exception& e) @@ -733,6 +756,8 @@ int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, co std::unique_ptr<Botan::Private_Key> key(new Botan::ECDSA_PrivateKey(rng, grp)); *key_obj = new botan_privkey_struct(key.release()); return 0; +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; #endif } catch(std::exception& e) @@ -743,6 +768,31 @@ int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, co return BOTAN_FFI_ERROR_EXCEPTION_THROWN; } +int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t) + { + try + { + if(key_obj == nullptr || rng_obj == nullptr || n == 0 || t == 0) + return -1; + + *key_obj = nullptr; + +#if defined(BOTAN_HAS_MCELIECE) + Botan::RandomNumberGenerator& rng = safe_get(rng_obj); + std::unique_ptr<Botan::Private_Key> key(new Botan::McEliece_PrivateKey(rng, n, t)); + *key_obj = new botan_privkey_struct(key.release()); + return 0; +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + return BOTAN_FFI_ERROR_EXCEPTION_THROWN; + } + } + int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) { try @@ -898,7 +948,7 @@ int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash_fn, uint8_t out[], size_t* out_len) { return BOTAN_FFI_DO(Botan::Public_Key, key, { - std::unique_ptr<Botan::HashFunction> h(Botan::get_hash(hash_fn)); + std::unique_ptr<Botan::HashFunction> h(Botan::HashFunction::create(hash_fn)); return write_vec_output(out, out_len, h->process(key.x509_subject_public_key())); }); } @@ -912,6 +962,8 @@ int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op, { BOTAN_ASSERT_NONNULL(op); + *op = nullptr; + if(flags != 0) return BOTAN_FFI_ERROR_BAD_FLAG; @@ -955,6 +1007,8 @@ int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op, { BOTAN_ASSERT_NONNULL(op); + *op = nullptr; + if(flags != 0) return BOTAN_FFI_ERROR_BAD_FLAG; @@ -997,6 +1051,8 @@ int botan_pk_op_sign_create(botan_pk_op_sign_t* op, { BOTAN_ASSERT_NONNULL(op); + *op = nullptr; + if(flags != 0) return BOTAN_FFI_ERROR_BAD_FLAG; @@ -1086,6 +1142,8 @@ int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op, { BOTAN_ASSERT_NONNULL(op); + *op = nullptr; + if(flags != 0) return BOTAN_FFI_ERROR_BAD_FLAG; @@ -1128,5 +1186,213 @@ int botan_pk_op_key_agreement(botan_pk_op_ka_t op, }); } +int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* cert_path) + { + try + { + if(!cert_obj || !cert_path) + return -1; + + std::unique_ptr<Botan::X509_Certificate> c(new Botan::X509_Certificate(cert_path)); + + if(c) + { + *cert_obj = new botan_x509_cert_struct(c.release()); + return 0; + } + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + catch(...) + { + log_exception(BOTAN_CURRENT_FUNCTION, "unknown"); + } + + return -2; + } + +int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert_bits[], size_t cert_bits_len) + { + try + { + if(!cert_obj || !cert_bits) + return -1; + + Botan::DataSource_Memory bits(cert_bits, cert_bits_len); + + std::unique_ptr<Botan::X509_Certificate> c(new Botan::X509_Certificate(bits)); + + if(c) + { + *cert_obj = new botan_x509_cert_struct(c.release()); + return 0; + } + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + catch(...) + { + log_exception(BOTAN_CURRENT_FUNCTION, "unknown"); + } + + return -2; + + } + +int botan_x509_cert_destroy(botan_x509_cert_t cert) + { + delete cert; + return 0; + } + +int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_str_output(out, out_len, cert.start_time()); }); + } + +int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_str_output(out, out_len, cert.end_time()); }); + } + +int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_vec_output(out, out_len, cert.serial_number()); }); + } + +int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_str_output(out, out_len, cert.fingerprint(hash)); }); + } + +int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_vec_output(out, out_len, cert.authority_key_id()); }); + } + +int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_vec_output(out, out_len, cert.subject_key_id()); }); + } + +int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_vec_output(out, out_len, cert.subject_public_key_bits()); }); + } + + +/* +int botan_x509_cert_path_verify(botan_x509_cert_t cert, const char* dir) +{ +} +*/ + +int botan_x509_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t* key) + { + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; + //return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_vec_output(out, out_len, cert.subject_public_key_bits()); }); + } + +int botan_x509_cert_get_issuer_dn(botan_x509_cert_t cert, + const char* key, size_t index, + uint8_t out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_str_output(out, out_len, cert.issuer_info(key).at(index)); }); + } + +int botan_x509_cert_get_subject_dn(botan_x509_cert_t cert, + const char* key, size_t index, + uint8_t out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_str_output(out, out_len, cert.subject_info(key).at(index)); }); + } + +int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { return write_str_output(out, out_len, cert.to_string()); }); + } + +int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage) + { + return BOTAN_FFI_DO(Botan::X509_Certificate, cert, { + const Botan::Key_Constraints k = static_cast<Botan::Key_Constraints>(key_usage); + if(cert.allowed_usage(k)) + return 0; + return 1; + }); + } + +int botan_mceies_decrypt(botan_privkey_t mce_key_obj, + const char* aead, + const uint8_t ct[], size_t ct_len, + const uint8_t ad[], size_t ad_len, + uint8_t out[], size_t* out_len) + { + try + { + Botan::Private_Key& key = safe_get(mce_key_obj); + +#if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES) + Botan::McEliece_PrivateKey* mce = dynamic_cast<Botan::McEliece_PrivateKey*>(&key); + if(!mce) + return -2; + + const Botan::secure_vector<uint8_t> pt = mceies_decrypt(*mce, ct, ct_len, ad, ad_len, aead); + return write_vec_output(out, out_len, pt); +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + catch(std::exception& e) + { + return ffi_error_exception_thrown(e.what()); + } + } + +int botan_mceies_encrypt(botan_pubkey_t mce_key_obj, + botan_rng_t rng_obj, + const char* aead, + const uint8_t pt[], size_t pt_len, + const uint8_t ad[], size_t ad_len, + uint8_t out[], size_t* out_len) + { + try + { + Botan::Public_Key& key = safe_get(mce_key_obj); + Botan::RandomNumberGenerator& rng = safe_get(rng_obj); + +#if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES) + Botan::McEliece_PublicKey* mce = dynamic_cast<Botan::McEliece_PublicKey*>(&key); + if(!mce) + return -2; + + Botan::secure_vector<uint8_t> ct = mceies_encrypt(*mce, pt, pt_len, ad, ad_len, rng, aead); + return write_vec_output(out, out_len, ct); +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + catch(std::exception& e) + { + return ffi_error_exception_thrown(e.what()); + } + } + +/* +int botan_tls_channel_init_client(botan_tls_channel_t* channel, + botan_tls_channel_output_fn output_fn, + botan_tls_channel_data_cb data_cb, + botan_tls_channel_alert_cb alert_cb, + botan_tls_channel_session_established session_cb, + const char* server_name) + { + + } +*/ + } diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h index a516529b4..ce2253725 100644 --- a/src/lib/ffi/ffi.h +++ b/src/lib/ffi/ffi.h @@ -1,4 +1,5 @@ /* +* FFI (C89 API) * (C) 2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) @@ -11,19 +12,55 @@ extern "C" { #endif -#include <botan/build.h> -#include <stdint.h> -#include <stddef.h> - /* +This header exports some of botan's functionality via a C89 +interface. This API is uesd by the Python and OCaml bindings via those +languages respective ctypes libraries. + +The API is intended to be as easy as possible to call from other +languages, which often have easy ways to call C, because C. But some C +code is easier to deal with than others, so to make things easy this +API follows a few simple rules: + +- All interactions are via pointers to opaque structs. No need to worry about + structure padding issues and the like. + +- All functions return an int error code (except the version calls, which are + assumed to always have something to say). + +- Use simple types: size_t for lengths, const char* NULL terminated strings, + uint8_t for binary. + +- No ownership of memory transfers across the API boundary. The API will + consume data from const pointers, and will produce output by writing to + variables provided by the caller. + +- If exporting a value (a string or a blob) the function takes a pointer to the + output array and a read/write pointer to the length. If the length is insufficient, an + error is returned. So passing nullptr/0 allows querying the final value. + + Note this does not apply to all functions, like `botan_hash_final` + which is not idempotent and are documented specially. But it's a + general theory of operation. + +The API is not currently documented, nor should it be considered +stable. It is buggy as heck, most likely, and error handling is a +mess. However the goal is to provide a long term API usable for +language bindings, or for use by systems written in C. Suggestions on +how to provide the cleanest API for such users would be most welcome. + * TODO: * - Better error reporting -* - User callback for exception logging +* - User callback for exception logging? * - Doxygen comments for all functions/params * - X.509 certs and PKIX path validation goo * - TLS */ +#include <botan/build.h> +#include <stdint.h> +#include <stddef.h> + /* * Versioning */ @@ -37,22 +74,57 @@ BOTAN_DLL uint32_t botan_version_datestamp(); /* * Error handling +* +* Some way of exporting these values to other languages would be useful + + + THIS FUNCTION ASSUMES BOTH ARGUMENTS ARE LITERAL STRINGS + so it retains only the pointers and does not make a copy. + +int botan_make_error(const char* msg, const char* func, int line); +* This value is returned to callers ^^ + + normally called like + return botan_make_error(BOTAN_ERROR_STRING_NOT_IMPLEMENTED, BOTAN_FUNCTION, __LINE__); + +// This would seem to require both saving the message permanently +catch(std::exception& e) { +return botan_make_error_from_transient_string(e.what(), BOTAN_FUNCTION, __LINE__); +} + +#define botan_make_error_inf(s) return botan_make_error(s, BOTAN_FUNCTION, __LINE__); + +Easier to return a const char* from each function directly? However, + +catch(std::exception& e) { return e.what(); } + +doesn't exactly work well either! + +* +* Later call: +* const char* botan_get_error_str(int); +* To recover the msg, func, and line + */ +#define BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE (-10) #define BOTAN_FFI_ERROR_EXCEPTION_THROWN (-20) #define BOTAN_FFI_ERROR_BAD_FLAG (-30) #define BOTAN_FFI_ERROR_NULL_POINTER (-31) -#define BOTAN_FFI_ERROR_NULL_POINTER (-31) +#define BOTAN_FFI_ERROR_NOT_IMPLEMENTED (-40) //const char* botan_error_description(int err); /* -* Utility +* Returns 0 if x[0..len] == y[0..len], or otherwise -1 */ BOTAN_DLL int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len); #define BOTAN_FFI_HEX_LOWER_CASE 1 BOTAN_DLL int botan_hex_encode(const uint8_t* x, size_t len, char* out, uint32_t flags); +// TODO: botan_hex_decode +// TODO: botan_base64_encode +// TODO: botan_base64_decode /* * RNG @@ -197,11 +269,11 @@ BOTAN_DLL int botan_kdf(const char* kdf_algo, /* * Bcrypt +* *out_len should be 64 bytes +* Output is formatted bcrypt $2a$... */ -#if defined(BOTAN_HAS_BCRYPT) - BOTAN_DLL int botan_bcrypt_generate(uint8_t* out, size_t* out_len, - const char* pass, + const char* password, botan_rng_t rng, size_t work_factor, uint32_t flags); @@ -213,8 +285,6 @@ BOTAN_DLL int botan_bcrypt_generate(uint8_t* out, size_t* out_len, */ BOTAN_DLL int botan_bcrypt_is_valid(const char* pass, const char* hash); -#endif - /* * Public/private key creation, import, ... */ @@ -225,7 +295,8 @@ BOTAN_DLL int botan_privkey_create_rsa(botan_privkey_t* key, botan_rng_t rng, si //BOTAN_DLL int botan_privkey_create_dh(botan_privkey_t* key, botan_rng_t rng, size_t p_bits); BOTAN_DLL int botan_privkey_create_ecdsa(botan_privkey_t* key, botan_rng_t rng, const char* params); BOTAN_DLL int botan_privkey_create_ecdh(botan_privkey_t* key, botan_rng_t rng, const char* params); -//BOTAN_DLL int botan_privkey_create_mceliece(botan_privkey_t* key, botan_rng_t rng, size_t n, size_t t); +BOTAN_DLL int botan_privkey_create_mceliece(botan_privkey_t* key, botan_rng_t rng, size_t n, size_t t); + /* * Input currently assumed to be PKCS #8 structure; @@ -359,6 +430,82 @@ BOTAN_DLL int botan_pk_op_key_agreement(botan_pk_op_ka_t op, const uint8_t other_key[], size_t other_key_len, const uint8_t salt[], size_t salt_len); + +/* +* +* @param mce_key must be a McEliece key +* ct_len should be pt_len + n/8 + a few? +*/ +BOTAN_DLL int botan_mceies_encrypt(botan_pubkey_t mce_key, + botan_rng_t rng, + const char* aead, + const uint8_t pt[], size_t pt_len, + const uint8_t ad[], size_t ad_len, + uint8_t ct[], size_t* ct_len); + +BOTAN_DLL int botan_mceies_decrypt(botan_privkey_t mce_key, + const char* aead, + const uint8_t ct[], size_t ct_len, + const uint8_t ad[], size_t ad_len, + uint8_t pt[], size_t* pt_len); + + + +typedef struct botan_x509_cert_struct* botan_x509_cert_t; +BOTAN_DLL int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert[], size_t cert_len); +BOTAN_DLL int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* filename); +BOTAN_DLL int botan_x509_cert_destroy(botan_x509_cert_t cert); + +BOTAN_DLL int botan_x509_cert_gen_selfsigned(botan_x509_cert_t* cert, + botan_privkey_t key, + botan_rng_t rng, + const char* common_name, + const char* org_name); + +// TODO: return botan_time_struct instead +BOTAN_DLL int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len); +BOTAN_DLL int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t* out_len); + +BOTAN_DLL int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len); + +BOTAN_DLL int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len); +BOTAN_DLL int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len); +BOTAN_DLL int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len); + +BOTAN_DLL int botan_x509_cert_path_verify(botan_x509_cert_t cert, + const char* ca_dir); + +BOTAN_DLL int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert, + uint8_t out[], size_t* out_len); + +BOTAN_DLL int botan_x509_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t* key); + +BOTAN_DLL int botan_x509_cert_get_issuer_dn(botan_x509_cert_t cert, + const char* key, size_t index, + uint8_t out[], size_t* out_len); + +BOTAN_DLL int botan_x509_cert_get_subject_dn(botan_x509_cert_t cert, + const char* key, size_t index, + uint8_t out[], size_t* out_len); + +BOTAN_DLL int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len); + +// Must match values of Key_Constraints in key_constraints.h +enum botan_x509_cert_key_constraints { + NO_CONSTRAINTS = 0, + DIGITAL_SIGNATURE = 32768, + NON_REPUDIATION = 16384, + KEY_ENCIPHERMENT = 8192, + DATA_ENCIPHERMENT = 4096, + KEY_AGREEMENT = 2048, + KEY_CERT_SIGN = 1024, + CRL_SIGN = 512, + ENCIPHER_ONLY = 256, + DECIPHER_ONLY = 128 +}; + +BOTAN_DLL int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage); + /* * TLS (WIP) */ @@ -366,16 +513,29 @@ BOTAN_DLL int botan_pk_op_key_agreement(botan_pk_op_ka_t op, typedef struct botan_tls_session_struct* botan_tls_session_t; -BOTAN_DLL int botan_tls_session_get_version(botan_tls_session_t* session, uint16_t* tls_version); -BOTAN_DLL int botan_tls_session_get_ciphersuite(botan_tls_session_t* session, uint16_t* ciphersuite); +BOTAN_DLL int botan_tls_session_decrypt(botan_tls_session_t* session, + const byte key[], size_t key_len, + const byte blob[], size_t blob_len); + +BOTAN_DLL int botan_tls_session_get_version(botan_tls_session_t session, uint16_t* tls_version); +BOTAN_DLL int botan_tls_session_get_ciphersuite(botan_tls_session_t session, uint16_t* ciphersuite); +BOTAN_DLL int botan_tls_session_encrypt(botan_tls_session_t session, botan_rng_t rng, byte key[], size_t* key_len); + +BOTAN_DLL int botan_tls_session_get_peer_certs(botan_tls_session_t session, botan_x509_cert_t certs[], size_t* cert_len); + // TODO: peer certs, validation, ... typedef struct botan_tls_channel_struct* botan_tls_channel_t; -typedef void (*botan_tls_channel_output_fn)(void*, const uint8_t*, size_t); -typedef void (*botan_tls_channel_data_cb)(void*, const uint8_t*, size_t); -typedef void (*botan_tls_channel_alert_cb)(void*, uint16_t, const char*); -typedef void (*botan_tls_channel_session_established)(void*, botan_tls_session_t); +typedef void (*botan_tls_channel_output_fn)(void* application_data, const uint8_t* data, size_t data_len); + +typedef void (*botan_tls_channel_data_cb)(void* application_data, const uint8_t* data, size_t data_len); + +typedef void (*botan_tls_channel_alert_cb)(void* application_data, uint16_t alert_code); + +typedef void (*botan_tls_channel_session_established)(void* application_data, + botan_tls_channel_t channel, + botan_tls_session_t session); BOTAN_DLL int botan_tls_channel_init_client(botan_tls_channel_t* channel, botan_tls_channel_output_fn output_fn, @@ -393,6 +553,11 @@ BOTAN_DLL int botan_tls_channel_init_server(botan_tls_channel_t* channel, BOTAN_DLL int botan_tls_channel_received_data(botan_tls_channel_t chan, const uint8_t input[], size_t len); +/** +* Returns 0 for client, 1 for server, negative for error +*/ +BOTAN_DLL int botan_tls_channel_type(botan_tls_channel_t chan); + BOTAN_DLL int botan_tls_channel_send(botan_tls_channel_t chan, const uint8_t input[], size_t len); @@ -401,7 +566,6 @@ BOTAN_DLL int botan_tls_channel_close(botan_tls_channel_t chan); BOTAN_DLL int botan_tls_channel_destroy(botan_tls_channel_t chan); #endif - #ifdef __cplusplus } #endif diff --git a/src/lib/ffi/info.txt b/src/lib/ffi/info.txt index 94a804ba0..4018e4064 100644 --- a/src/lib/ffi/info.txt +++ b/src/lib/ffi/info.txt @@ -1,11 +1,12 @@ -define FFI 20150210 +define FFI 20151001 <requires> aead -filters kdf pbkdf pubkey +x509 +#tls auto_rng system_rng </requires> diff --git a/src/lib/filters/algo_filt.cpp b/src/lib/filters/algo_filt.cpp index 6ec8cdd1d..bfadef924 100644 --- a/src/lib/filters/algo_filt.cpp +++ b/src/lib/filters/algo_filt.cpp @@ -6,7 +6,6 @@ */ #include <botan/filters.h> -#include <botan/lookup.h> #include <algorithm> namespace Botan { @@ -26,14 +25,18 @@ StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher, const SymmetricKe StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : m_buffer(DEFAULT_BUFFERSIZE), - m_cipher(make_stream_cipher(sc_name)) + m_cipher(StreamCipher::create(sc_name)) { + if(!m_cipher) + throw Algorithm_Not_Found(sc_name); } StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, const SymmetricKey& key) : m_buffer(DEFAULT_BUFFERSIZE), - m_cipher(make_stream_cipher(sc_name)) + m_cipher(StreamCipher::create(sc_name)) { + if(!m_cipher) + throw Algorithm_Not_Found(sc_name); m_cipher->set_key(key); } @@ -50,13 +53,13 @@ void StreamCipher_Filter::write(const byte input[], size_t length) } Hash_Filter::Hash_Filter(const std::string& hash_name, size_t len) : - m_hash(make_hash_function(hash_name)), + m_hash(HashFunction::create(hash_name)), m_out_len(len) { + if(!m_hash) + throw Algorithm_Not_Found(hash_name); } - -void Hash_Filter::end_msg() - { +void Hash_Filter::end_msg() { secure_vector<byte> output = m_hash->final(); if(m_out_len) send(output, std::min<size_t>(m_out_len, output.size())); @@ -65,15 +68,19 @@ void Hash_Filter::end_msg() } MAC_Filter::MAC_Filter(const std::string& mac_name, size_t len) : - m_mac(make_message_auth(mac_name)), + m_mac(MessageAuthenticationCode::create(mac_name)), m_out_len(len) { + if(!m_mac) + throw Algorithm_Not_Found(mac_name); } MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, size_t len) : - m_mac(make_message_auth(mac_name)), + m_mac(MessageAuthenticationCode::create(mac_name)), m_out_len(len) { + if(!m_mac) + throw Algorithm_Not_Found(mac_name); m_mac->set_key(key); } diff --git a/src/lib/filters/comp_filter.h b/src/lib/filters/comp_filter.h index 59d6f7185..bb928b640 100644 --- a/src/lib/filters/comp_filter.h +++ b/src/lib/filters/comp_filter.h @@ -47,7 +47,7 @@ class BOTAN_DLL Compression_Filter : public Compression_Decompression_Filter using Compression_Decompression_Filter::flush; }; -class Decompression_Filter : public Compression_Decompression_Filter +class BOTAN_DLL Decompression_Filter : public Compression_Decompression_Filter { public: Decompression_Filter(const std::string& type, diff --git a/src/lib/filters/info.txt b/src/lib/filters/info.txt index da6827833..fbecd9c87 100644 --- a/src/lib/filters/info.txt +++ b/src/lib/filters/info.txt @@ -6,7 +6,6 @@ basefilt.cpp buf_filt.cpp comp_filter.cpp data_snk.cpp -data_src.cpp filter.cpp key_filt.cpp out_buf.cpp @@ -23,7 +22,6 @@ basefilt.h buf_filt.h data_snk.h comp_filter.h -data_src.h filter.h filters.h key_filt.h diff --git a/src/lib/hash/checksum/adler32/adler32.cpp b/src/lib/hash/checksum/adler32/adler32.cpp index f2385c5b8..f368b627c 100644 --- a/src/lib/hash/checksum/adler32/adler32.cpp +++ b/src/lib/hash/checksum/adler32/adler32.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/adler32.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_HASH_NOARGS(Adler32); - namespace { void adler32_update(const byte input[], size_t length, diff --git a/src/lib/hash/checksum/crc24/crc24.cpp b/src/lib/hash/checksum/crc24/crc24.cpp index 4f747c232..1484f643d 100644 --- a/src/lib/hash/checksum/crc24/crc24.cpp +++ b/src/lib/hash/checksum/crc24/crc24.cpp @@ -5,14 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/crc24.h> -#include <botan/get_byte.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_HASH_NOARGS(CRC24); - /* * Update a CRC24 Checksum */ diff --git a/src/lib/hash/checksum/crc32/crc32.cpp b/src/lib/hash/checksum/crc32/crc32.cpp index cb4ff7b5f..10d989cc6 100644 --- a/src/lib/hash/checksum/crc32/crc32.cpp +++ b/src/lib/hash/checksum/crc32/crc32.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/crc32.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_HASH_NOARGS(CRC32); - /* * Update a CRC32 Checksum */ diff --git a/src/lib/hash/comb4p/comb4p.cpp b/src/lib/hash/comb4p/comb4p.cpp index 843c530ef..4222eaf54 100644 --- a/src/lib/hash/comb4p/comb4p.cpp +++ b/src/lib/hash/comb4p/comb4p.cpp @@ -5,15 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/comb4p.h> -#include <botan/internal/xor_buf.h> #include <stdexcept> namespace Botan { -BOTAN_REGISTER_NAMED_T(HashFunction, "Comb4P", Comb4P, Comb4P::make); - namespace { void comb4p_round(secure_vector<byte>& out, @@ -41,8 +37,8 @@ Comb4P* Comb4P::make(const Spec& spec) { if(spec.arg_count() == 2) { - std::unique_ptr<HashFunction> h1(make_hash_function(spec.arg(0))); - std::unique_ptr<HashFunction> h2(make_hash_function(spec.arg(1))); + std::unique_ptr<HashFunction> h1(HashFunction::create(spec.arg(0))); + std::unique_ptr<HashFunction> h2(HashFunction::create(spec.arg(1))); if(h1 && h2) return new Comb4P(h1.release(), h2.release()); diff --git a/src/lib/hash/gost_3411/gost_3411.cpp b/src/lib/hash/gost_3411/gost_3411.cpp index 918556ca0..f8c9c0069 100644 --- a/src/lib/hash/gost_3411/gost_3411.cpp +++ b/src/lib/hash/gost_3411/gost_3411.cpp @@ -5,14 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/gost_3411.h> -#include <botan/internal/xor_buf.h> namespace Botan { -BOTAN_REGISTER_HASH_NAMED_NOARGS(GOST_34_11, "GOST-R-34.11-94"); - /** * GOST 34.11 Constructor */ diff --git a/src/lib/hash/has160/has160.cpp b/src/lib/hash/has160/has160.cpp index 2f2a5f9de..6b12e10ad 100644 --- a/src/lib/hash/has160/has160.cpp +++ b/src/lib/hash/has160/has160.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/has160.h> namespace Botan { -BOTAN_REGISTER_HASH_NAMED_NOARGS(HAS_160, "HAS-160"); - namespace HAS_160_F { /* diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp new file mode 100644 index 000000000..fe210705e --- /dev/null +++ b/src/lib/hash/hash.cpp @@ -0,0 +1,206 @@ +/* +* Hash Functions +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/hash.h> +#include <botan/cpuid.h> +#include <botan/internal/algo_registry.h> + +#if defined(BOTAN_HAS_ADLER32) + #include <botan/adler32.h> +#endif + +#if defined(BOTAN_HAS_CRC24) + #include <botan/crc24.h> +#endif + +#if defined(BOTAN_HAS_CRC32) + #include <botan/crc32.h> +#endif + +#if defined(BOTAN_HAS_GOST_34_11) + #include <botan/gost_3411.h> +#endif + +#if defined(BOTAN_HAS_HAS_160) + #include <botan/has160.h> +#endif + +#if defined(BOTAN_HAS_KECCAK) + #include <botan/keccak.h> +#endif + +#if defined(BOTAN_HAS_MD2) + #include <botan/md2.h> +#endif + +#if defined(BOTAN_HAS_MD4) + #include <botan/md4.h> +#endif + +#if defined(BOTAN_HAS_MD5) + #include <botan/md5.h> +#endif + +#if defined(BOTAN_HAS_RIPEMD_128) + #include <botan/rmd128.h> +#endif + +#if defined(BOTAN_HAS_RIPEMD_160) + #include <botan/rmd160.h> +#endif + +#if defined(BOTAN_HAS_SHA1) + #include <botan/sha160.h> +#endif + +#if defined(BOTAN_HAS_SHA1_SSE2) + #include <botan/sha1_sse2.h> +#endif + +#if defined(BOTAN_HAS_SHA2_32) + #include <botan/sha2_32.h> +#endif + +#if defined(BOTAN_HAS_SHA2_64) + #include <botan/sha2_64.h> +#endif + +#if defined(BOTAN_HAS_SKEIN_512) + #include <botan/skein_512.h> +#endif + +#if defined(BOTAN_HAS_TIGER) + #include <botan/tiger.h> +#endif + +#if defined(BOTAN_HAS_WHIRLPOOL) + #include <botan/whrlpool.h> +#endif + +#if defined(BOTAN_HAS_PARALLEL_HASH) + #include <botan/par_hash.h> +#endif + +#if defined(BOTAN_HAS_COMB4P) + #include <botan/comb4p.h> +#endif + +namespace Botan { + +std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr<HashFunction>(make_a<HashFunction>(algo_spec, provider)); + } + +std::vector<std::string> HashFunction::providers(const std::string& algo_spec) + { + return providers_of<HashFunction>(HashFunction::Spec(algo_spec)); + } + +HashFunction::HashFunction() {} + +HashFunction::~HashFunction() {} + +#define BOTAN_REGISTER_HASH(name, maker) BOTAN_REGISTER_T(HashFunction, name, maker) +#define BOTAN_REGISTER_HASH_NOARGS(name) BOTAN_REGISTER_T_NOARGS(HashFunction, name) + +#define BOTAN_REGISTER_HASH_1LEN(name, def) BOTAN_REGISTER_T_1LEN(HashFunction, name, def) + +#define BOTAN_REGISTER_HASH_NAMED_NOARGS(type, name) \ + BOTAN_REGISTER_NAMED_T(HashFunction, name, type, make_new_T<type>) +#define BOTAN_REGISTER_HASH_NAMED_1LEN(type, name, def) \ + BOTAN_REGISTER_NAMED_T(HashFunction, name, type, (make_new_T_1len<type,def>)) + +#define BOTAN_REGISTER_HASH_NOARGS_IF(cond, type, name, provider, pref) \ + BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, HashFunction, type, name, provider, pref) + +#if defined(BOTAN_HAS_ADLER32) +BOTAN_REGISTER_HASH_NOARGS(Adler32); +#endif + +#if defined(BOTAN_HAS_CRC24) +BOTAN_REGISTER_HASH_NOARGS(CRC24); +#endif + +#if defined(BOTAN_HAS_CRC32) +BOTAN_REGISTER_HASH_NOARGS(CRC32); +#endif + +#if defined(BOTAN_HAS_COMB4P) +BOTAN_REGISTER_NAMED_T(HashFunction, "Comb4P", Comb4P, Comb4P::make); +#endif + +#if defined(BOTAN_HAS_PARALLEL_HASH) +BOTAN_REGISTER_NAMED_T(HashFunction, "Parallel", Parallel, Parallel::make); +#endif + +#if defined(BOTAN_HAS_GOST_34_11) +BOTAN_REGISTER_HASH_NAMED_NOARGS(GOST_34_11, "GOST-R-34.11-94"); +#endif + +#if defined(BOTAN_HAS_HAS_160) +BOTAN_REGISTER_HASH_NAMED_NOARGS(HAS_160, "HAS-160"); +#endif + +#if defined(BOTAN_HAS_KECCAK) +BOTAN_REGISTER_HASH_NAMED_1LEN(Keccak_1600, "Keccak-1600", 512); +#endif + +#if defined(BOTAN_HAS_MD2) +BOTAN_REGISTER_HASH_NOARGS(MD2); +#endif + +#if defined(BOTAN_HAS_MD4) +BOTAN_REGISTER_HASH_NOARGS(MD4); +#endif + +#if defined(BOTAN_HAS_MD5) +BOTAN_REGISTER_HASH_NOARGS(MD5); +#endif + +#if defined(BOTAN_HAS_RIPEMD_128) +BOTAN_REGISTER_HASH_NAMED_NOARGS(RIPEMD_128, "RIPEMD-128"); +#endif + +#if defined(BOTAN_HAS_RIPEMD_160) +BOTAN_REGISTER_HASH_NAMED_NOARGS(RIPEMD_160, "RIPEMD-160"); +#endif + +#if defined(BOTAN_HAS_SHA1) +BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_160, "SHA-160"); +#endif + +#if defined(BOTAN_HAS_SHA1_SSE2) +BOTAN_REGISTER_HASH_NOARGS_IF(CPUID::has_sse2(), SHA_160_SSE2, "SHA-160", + "sse2", BOTAN_SIMD_ALGORITHM_PRIO); +#endif + +#if defined(BOTAN_HAS_SHA2_32) +BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_224, "SHA-224"); +BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_256, "SHA-256"); +#endif + +#if defined(BOTAN_HAS_SHA2_64) +BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_384, "SHA-384"); +BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_512, "SHA-512"); +BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_512_256, "SHA-512-256"); +#endif + +#if defined(BOTAN_HAS_TIGER) +BOTAN_REGISTER_NAMED_T_2LEN(HashFunction, Tiger, "Tiger", "base", 24, 3); +#endif + +#if defined(BOTAN_HAS_SKEIN_512) +BOTAN_REGISTER_NAMED_T(HashFunction, "Skein-512", Skein_512, Skein_512::make); +#endif + +#if defined(BOTAN_HAS_WHIRLPOOL) +BOTAN_REGISTER_HASH_NOARGS(Whirlpool); +#endif + +} diff --git a/src/lib/hash/hash.h b/src/lib/hash/hash.h index 9b2ca0d3b..ac1c22a65 100644 --- a/src/lib/hash/hash.h +++ b/src/lib/hash/hash.h @@ -20,11 +20,30 @@ namespace Botan { class BOTAN_DLL HashFunction : public Buffered_Computation { public: + typedef SCAN_Name Spec; + + /** + * Create an instance based on a name + * Will return a null pointer if the algo/provider combination cannot + * be found. If provider is empty then best available is chosen. + */ + static std::unique_ptr<HashFunction> create(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * Returns the list of available providers for this algorithm, empty if not available + */ + static std::vector<std::string> providers(const std::string& algo_spec); + /** * @return new object representing the same algorithm as *this */ virtual HashFunction* clone() const = 0; + HashFunction(); + + virtual ~HashFunction(); + virtual void clear() = 0; virtual std::string name() const = 0; @@ -33,8 +52,6 @@ class BOTAN_DLL HashFunction : public Buffered_Computation * @return hash block size as defined for this algorithm */ virtual size_t hash_block_size() const { return 0; } - - typedef SCAN_Name Spec; }; } diff --git a/src/lib/hash/hash_utils.h b/src/lib/hash/hash_utils.h deleted file mode 100644 index 3286b0087..000000000 --- a/src/lib/hash/hash_utils.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Hash Utility Header -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_HASH_UTILS_H__ -#define BOTAN_HASH_UTILS_H__ - -#include <botan/hash.h> -#include <botan/internal/algo_registry.h> -#include <botan/loadstor.h> -#include <botan/rotate.h> - -namespace Botan { - -#define BOTAN_REGISTER_HASH(name, maker) BOTAN_REGISTER_T(HashFunction, name, maker) -#define BOTAN_REGISTER_HASH_NOARGS(name) BOTAN_REGISTER_T_NOARGS(HashFunction, name) - -#define BOTAN_REGISTER_HASH_1LEN(name, def) BOTAN_REGISTER_T_1LEN(HashFunction, name, def) - -#define BOTAN_REGISTER_HASH_NAMED_NOARGS(type, name) \ - BOTAN_REGISTER_NAMED_T(HashFunction, name, type, make_new_T<type>) -#define BOTAN_REGISTER_HASH_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(HashFunction, name, type, (make_new_T_1len<type,def>)) - -#define BOTAN_REGISTER_HASH_NOARGS_IF(cond, type, name, provider, pref) \ - BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, HashFunction, type, name, provider, pref) - -} - -#endif diff --git a/src/lib/hash/info.txt b/src/lib/hash/info.txt index 481b39b67..e71318b73 100644 --- a/src/lib/hash/info.txt +++ b/src/lib/hash/info.txt @@ -1,7 +1,3 @@ -<header:internal> -hash_utils.h -</header:internal> - <header:public> hash.h </header:public> diff --git a/src/lib/hash/keccak/info.txt b/src/lib/hash/keccak/info.txt index ecdfba19c..6fcd286a3 100644 --- a/src/lib/hash/keccak/info.txt +++ b/src/lib/hash/keccak/info.txt @@ -1,5 +1 @@ define KECCAK 20131128 - -<requires> -alloc -</requires> diff --git a/src/lib/hash/keccak/keccak.cpp b/src/lib/hash/keccak/keccak.cpp index 8ee2357b6..39d0c822b 100644 --- a/src/lib/hash/keccak/keccak.cpp +++ b/src/lib/hash/keccak/keccak.cpp @@ -5,16 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/keccak.h> #include <botan/parsing.h> #include <botan/exceptn.h> -#include <botan/internal/xor_buf.h> namespace Botan { -BOTAN_REGISTER_HASH_NAMED_1LEN(Keccak_1600, "Keccak-1600", 512); - namespace { void keccak_f_1600(u64bit A[25]) diff --git a/src/lib/hash/md2/md2.cpp b/src/lib/hash/md2/md2.cpp index 6543cf1a0..8fe016962 100644 --- a/src/lib/hash/md2/md2.cpp +++ b/src/lib/hash/md2/md2.cpp @@ -5,14 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/md2.h> -#include <botan/internal/xor_buf.h> namespace Botan { -BOTAN_REGISTER_HASH_NOARGS(MD2); - /** * MD2 Compression Function */ diff --git a/src/lib/hash/md4/md4.cpp b/src/lib/hash/md4/md4.cpp index cc11baafa..6f4503ac0 100644 --- a/src/lib/hash/md4/md4.cpp +++ b/src/lib/hash/md4/md4.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/md4.h> namespace Botan { -BOTAN_REGISTER_HASH_NOARGS(MD4); - namespace { /* diff --git a/src/lib/hash/md5/md5.cpp b/src/lib/hash/md5/md5.cpp index 2ce8df48a..89ca52419 100644 --- a/src/lib/hash/md5/md5.cpp +++ b/src/lib/hash/md5/md5.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/md5.h> namespace Botan { -BOTAN_REGISTER_HASH_NOARGS(MD5); - namespace { /* diff --git a/src/lib/hash/openssl_hash/info.txt b/src/lib/hash/openssl_hash/info.txt new file mode 100644 index 000000000..c375d272e --- /dev/null +++ b/src/lib/hash/openssl_hash/info.txt @@ -0,0 +1,5 @@ +define OPENSSL_HASH_FUNCTION 20151019 + +<requires> +openssl +</requires> diff --git a/src/lib/vendor/openssl/openssl_hash.cpp b/src/lib/hash/openssl_hash/openssl_hash.cpp index 6133e36a4..c89dd777d 100644 --- a/src/lib/vendor/openssl/openssl_hash.cpp +++ b/src/lib/hash/openssl_hash/openssl_hash.cpp @@ -5,7 +5,9 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> +#include <botan/hash.h> +#include <botan/internal/openssl.h> +#include <botan/internal/algo_registry.h> #include <openssl/evp.h> namespace Botan { @@ -78,7 +80,7 @@ make_evp_hash_maker(const EVP_MD* md, const char* algo) #define BOTAN_REGISTER_OPENSSL_EVP_HASH(NAME, EVP) \ BOTAN_REGISTER_TYPE(HashFunction, OpenSSL_HashFunction ## EVP, NAME, \ - make_evp_hash_maker(EVP(), NAME), "openssl", 32); + make_evp_hash_maker(EVP(), NAME), "openssl", BOTAN_OPENSSL_HASH_PRIO); #if !defined(OPENSSL_NO_SHA) BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-160", EVP_sha1); diff --git a/src/lib/hash/par_hash/par_hash.cpp b/src/lib/hash/par_hash/par_hash.cpp index b6133929c..5e970ab13 100644 --- a/src/lib/hash/par_hash/par_hash.cpp +++ b/src/lib/hash/par_hash/par_hash.cpp @@ -5,21 +5,18 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/par_hash.h> #include <botan/parsing.h> namespace Botan { -BOTAN_REGISTER_NAMED_T(HashFunction, "Parallel", Parallel, Parallel::make); - Parallel* Parallel::make(const Spec& spec) { std::vector<std::unique_ptr<HashFunction>> hashes; for(size_t i = 0; i != spec.arg_count(); ++i) { - std::unique_ptr<HashFunction> h(get_hash_function(spec.arg(i))); + auto h = HashFunction::create(spec.arg(i)); if(!h) return nullptr; hashes.push_back(std::move(h)); diff --git a/src/lib/hash/rmd128/rmd128.cpp b/src/lib/hash/rmd128/rmd128.cpp index 7138d54d7..394bf2acf 100644 --- a/src/lib/hash/rmd128/rmd128.cpp +++ b/src/lib/hash/rmd128/rmd128.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/rmd128.h> namespace Botan { -BOTAN_REGISTER_HASH_NAMED_NOARGS(RIPEMD_128, "RIPEMD-128"); - namespace RIPEMD_128_F { /* diff --git a/src/lib/hash/rmd160/rmd160.cpp b/src/lib/hash/rmd160/rmd160.cpp index dad1d367a..56d063338 100644 --- a/src/lib/hash/rmd160/rmd160.cpp +++ b/src/lib/hash/rmd160/rmd160.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/rmd160.h> namespace Botan { -BOTAN_REGISTER_HASH_NAMED_NOARGS(RIPEMD_160, "RIPEMD-160"); - namespace { /* diff --git a/src/lib/hash/sha1/sha160.cpp b/src/lib/hash/sha1/sha160.cpp index 96bc2c682..39d14f486 100644 --- a/src/lib/hash/sha1/sha160.cpp +++ b/src/lib/hash/sha1/sha160.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/sha160.h> namespace Botan { -BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_160, "SHA-160"); - namespace SHA1_F { namespace { diff --git a/src/lib/hash/sha1_sse2/sha1_sse2.cpp b/src/lib/hash/sha1_sse2/sha1_sse2.cpp index 1fc62d957..2e0688185 100644 --- a/src/lib/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/lib/hash/sha1_sse2/sha1_sse2.cpp @@ -7,15 +7,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/sha1_sse2.h> #include <botan/cpuid.h> #include <emmintrin.h> namespace Botan { -BOTAN_REGISTER_HASH_NOARGS_IF(CPUID::has_sse2(), SHA_160_SSE2, "SHA-160", "sse2", 64); - namespace SHA1_SSE2_F { namespace { diff --git a/src/lib/hash/sha2_32/sha2_32.cpp b/src/lib/hash/sha2_32/sha2_32.cpp index b06d485aa..5215164cf 100644 --- a/src/lib/hash/sha2_32/sha2_32.cpp +++ b/src/lib/hash/sha2_32/sha2_32.cpp @@ -6,14 +6,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/sha2_32.h> namespace Botan { -BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_224, "SHA-224"); -BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_256, "SHA-256"); - namespace { namespace SHA2_32 { diff --git a/src/lib/hash/sha2_64/sha2_64.cpp b/src/lib/hash/sha2_64/sha2_64.cpp index 733cf0f19..d7c3f1325 100644 --- a/src/lib/hash/sha2_64/sha2_64.cpp +++ b/src/lib/hash/sha2_64/sha2_64.cpp @@ -5,15 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/sha2_64.h> namespace Botan { -BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_384, "SHA-384"); -BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_512, "SHA-512"); -BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_512_256, "SHA-512-256"); - namespace { namespace SHA2_64 { diff --git a/src/lib/hash/skein/skein_512.cpp b/src/lib/hash/skein/skein_512.cpp index 5e186b996..fe95dd7a5 100644 --- a/src/lib/hash/skein/skein_512.cpp +++ b/src/lib/hash/skein/skein_512.cpp @@ -5,17 +5,13 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/skein_512.h> #include <botan/parsing.h> #include <botan/exceptn.h> -#include <botan/internal/xor_buf.h> #include <algorithm> namespace Botan { -BOTAN_REGISTER_NAMED_T(HashFunction, "Skein-512", Skein_512, Skein_512::make); - Skein_512* Skein_512::make(const Spec& spec) { return new Skein_512(spec.arg_as_integer(0, 512), spec.arg(1, "")); diff --git a/src/lib/hash/tiger/tiger.cpp b/src/lib/hash/tiger/tiger.cpp index c6dec2f33..79708a902 100644 --- a/src/lib/hash/tiger/tiger.cpp +++ b/src/lib/hash/tiger/tiger.cpp @@ -5,15 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/tiger.h> #include <botan/exceptn.h> #include <botan/parsing.h> namespace Botan { -BOTAN_REGISTER_NAMED_T_2LEN(HashFunction, Tiger, "Tiger", "base", 24, 3); - namespace { /* diff --git a/src/lib/hash/whirlpool/whirlpool.cpp b/src/lib/hash/whirlpool/whirlpool.cpp index 573c49f91..9bebdfa7c 100644 --- a/src/lib/hash/whirlpool/whirlpool.cpp +++ b/src/lib/hash/whirlpool/whirlpool.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/hash_utils.h> #include <botan/whrlpool.h> namespace Botan { -BOTAN_REGISTER_HASH_NOARGS(Whirlpool); - /* * Whirlpool Compression Function */ diff --git a/src/lib/kdf/hkdf/hkdf.cpp b/src/lib/kdf/hkdf/hkdf.cpp index b643db6d9..6f83853f9 100644 --- a/src/lib/kdf/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -5,20 +5,17 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/kdf_utils.h> #include <botan/hkdf.h> namespace Botan { -BOTAN_REGISTER_NAMED_T(KDF, "HKDF", HKDF, HKDF::make); - HKDF* HKDF::make(const Spec& spec) { - if(auto mac = get_mac(spec.arg(0))) - return new HKDF(mac); + if(auto mac = MessageAuthenticationCode::create(spec.arg(0))) + return new HKDF(mac.release()); - if(auto mac = get_mac("HMAC(" + spec.arg(0) + ")")) - return new HKDF(mac); + if(auto mac = MessageAuthenticationCode::create("HMAC(" + spec.arg(0) + ")")) + return new HKDF(mac.release()); return nullptr; } diff --git a/src/lib/kdf/info.txt b/src/lib/kdf/info.txt index 35032e159..68aa46895 100644 --- a/src/lib/kdf/info.txt +++ b/src/lib/kdf/info.txt @@ -7,7 +7,3 @@ base <header:public> kdf.h </header:public> - -<header:internal> -kdf_utils.h -</header:internal> diff --git a/src/lib/kdf/kdf.cpp b/src/lib/kdf/kdf.cpp index 793cd3d62..3eba8a5cd 100644 --- a/src/lib/kdf/kdf.cpp +++ b/src/lib/kdf/kdf.cpp @@ -7,10 +7,54 @@ #include <botan/kdf.h> #include <botan/internal/algo_registry.h> -#include <botan/exceptn.h> + +#if defined(BOTAN_HAS_HKDF) +#include <botan/hkdf.h> +#endif + +#if defined(BOTAN_HAS_KDF1) +#include <botan/kdf1.h> +#endif + +#if defined(BOTAN_HAS_KDF2) +#include <botan/kdf2.h> +#endif + +#if defined(BOTAN_HAS_TLS_V10_PRF) +#include <botan/prf_tls.h> +#endif + +#if defined(BOTAN_HAS_TLS_V12_PRF) +#include <botan/prf_tls.h> +#endif + +#if defined(BOTAN_HAS_X942_PRF) +#include <botan/prf_x942.h> +#endif + +#define BOTAN_REGISTER_KDF_NOARGS(type, name) \ + BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T<type>)) +#define BOTAN_REGISTER_KDF_1HASH(type, name) \ + BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T_1X<type, HashFunction>)) + +#define BOTAN_REGISTER_KDF_NAMED_1STR(type, name) \ + BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T_1str_req<type>)) namespace Botan { +KDF::~KDF() {} + +std::unique_ptr<KDF> KDF::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr<KDF>(make_a<KDF>(algo_spec, provider)); + } + +std::vector<std::string> KDF::providers(const std::string& algo_spec) + { + return providers_of<KDF>(KDF::Spec(algo_spec)); + } + KDF* get_kdf(const std::string& algo_spec) { SCAN_Name request(algo_spec); @@ -18,9 +62,34 @@ KDF* get_kdf(const std::string& algo_spec) if(request.algo_name() == "Raw") return nullptr; // No KDF - if(KDF* kdf = make_a<KDF>(algo_spec)) - return kdf; - throw Algorithm_Not_Found(algo_spec); + auto kdf = KDF::create(algo_spec); + if(!kdf) + throw Algorithm_Not_Found(algo_spec); + return kdf.release(); } +#if defined(BOTAN_HAS_HKDF) +BOTAN_REGISTER_NAMED_T(KDF, "HKDF", HKDF, HKDF::make); +#endif + +#if defined(BOTAN_HAS_KDF1) +BOTAN_REGISTER_KDF_1HASH(KDF1, "KDF1"); +#endif + +#if defined(BOTAN_HAS_KDF2) +BOTAN_REGISTER_KDF_1HASH(KDF2, "KDF2"); +#endif + +#if defined(BOTAN_HAS_TLS_V10_PRF) +BOTAN_REGISTER_KDF_NOARGS(TLS_PRF, "TLS-PRF"); +#endif + +#if defined(BOTAN_HAS_TLS_V12_PRF) +BOTAN_REGISTER_NAMED_T(KDF, "TLS-12-PRF", TLS_12_PRF, TLS_12_PRF::make); +#endif + +#if defined(BOTAN_HAS_X942_PRF) +BOTAN_REGISTER_KDF_NAMED_1STR(X942_PRF, "X9.42-PRF"); +#endif + } diff --git a/src/lib/kdf/kdf.h b/src/lib/kdf/kdf.h index d69c1ece5..88b50c8b8 100644 --- a/src/lib/kdf/kdf.h +++ b/src/lib/kdf/kdf.h @@ -21,7 +21,20 @@ namespace Botan { class BOTAN_DLL KDF { public: - virtual ~KDF() {} + virtual ~KDF(); + + /** + * Create an instance based on a name + * Will return a null pointer if the algo/provider combination cannot + * be found. If provider is empty then best available is chosen. + */ + static std::unique_ptr<KDF> create(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * Returns the list of available providers for this algorithm, empty if not available + */ + static std::vector<std::string> providers(const std::string& algo_spec); virtual std::string name() const = 0; diff --git a/src/lib/kdf/kdf1/kdf1.cpp b/src/lib/kdf/kdf1/kdf1.cpp index fa3432467..c7ea3c37e 100644 --- a/src/lib/kdf/kdf1/kdf1.cpp +++ b/src/lib/kdf/kdf1/kdf1.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/kdf_utils.h> #include <botan/kdf1.h> namespace Botan { -BOTAN_REGISTER_KDF_1HASH(KDF1, "KDF1"); - size_t KDF1::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len) const diff --git a/src/lib/kdf/kdf2/kdf2.cpp b/src/lib/kdf/kdf2/kdf2.cpp index 9deb1a22f..df2b7a91c 100644 --- a/src/lib/kdf/kdf2/kdf2.cpp +++ b/src/lib/kdf/kdf2/kdf2.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/kdf_utils.h> #include <botan/kdf2.h> namespace Botan { -BOTAN_REGISTER_KDF_1HASH(KDF2, "KDF2"); - size_t KDF2::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len) const diff --git a/src/lib/kdf/kdf_utils.h b/src/lib/kdf/kdf_utils.h deleted file mode 100644 index f67892437..000000000 --- a/src/lib/kdf/kdf_utils.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* KDF Utility Header -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_KDF_UTILS_H__ -#define BOTAN_KDF_UTILS_H__ - -#include <botan/kdf.h> -#include <botan/internal/algo_registry.h> -#include <botan/exceptn.h> -#include <botan/internal/xor_buf.h> - -namespace Botan { - -#define BOTAN_REGISTER_KDF_NOARGS(type, name) \ - BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T<type>)) -#define BOTAN_REGISTER_KDF_1HASH(type, name) \ - BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T_1X<type, HashFunction>)) - -#define BOTAN_REGISTER_KDF_NAMED_1STR(type, name) \ - BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T_1str_req<type>)) - -} - -#endif diff --git a/src/lib/kdf/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp index 4fdec8fef..547b0c9c8 100644 --- a/src/lib/kdf/prf_tls/prf_tls.cpp +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/kdf_utils.h> #include <botan/prf_tls.h> #include <botan/hmac.h> @@ -13,20 +12,21 @@ namespace Botan { TLS_12_PRF* TLS_12_PRF::make(const Spec& spec) { - if(auto mac = get_mac(spec.arg(0))) - return new TLS_12_PRF(mac); - if(auto hash = get_hash_function(spec.arg(0))) - return new TLS_12_PRF(new HMAC(hash)); + if(auto mac = MessageAuthenticationCode::create(spec.arg(0))) + return new TLS_12_PRF(mac.release()); + + if(auto mac = MessageAuthenticationCode::create("HMAC(" + spec.arg(0) + ")")) + return new TLS_12_PRF(mac.release()); + return nullptr; } -BOTAN_REGISTER_NAMED_T(KDF, "TLS-12-PRF", TLS_12_PRF, TLS_12_PRF::make); -BOTAN_REGISTER_KDF_NOARGS(TLS_PRF, "TLS-PRF"); - TLS_PRF::TLS_PRF() : - m_hmac_md5(make_message_auth("HMAC(MD5)")), - m_hmac_sha1(make_message_auth("HMAC(SHA-1)")) + m_hmac_md5(MessageAuthenticationCode::create("HMAC(MD5)")), + m_hmac_sha1(MessageAuthenticationCode::create("HMAC(SHA-1)")) { + if(!m_hmac_md5 || !m_hmac_sha1) + throw Algorithm_Not_Found("TLS_PRF HMACs not available"); } namespace { diff --git a/src/lib/kdf/prf_x942/prf_x942.cpp b/src/lib/kdf/prf_x942/prf_x942.cpp index 622d68c1a..fb8de1e85 100644 --- a/src/lib/kdf/prf_x942/prf_x942.cpp +++ b/src/lib/kdf/prf_x942/prf_x942.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/kdf_utils.h> #include <botan/prf_x942.h> #include <botan/der_enc.h> #include <botan/oids.h> @@ -15,8 +14,6 @@ namespace Botan { -BOTAN_REGISTER_KDF_NAMED_1STR(X942_PRF, "X9.42-PRF"); - namespace { /* @@ -35,7 +32,7 @@ size_t X942_PRF::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len) const { - std::unique_ptr<HashFunction> hash(make_hash_function("SHA-160")); + std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-160")); const OID kek_algo(m_key_wrap_oid); secure_vector<byte> h; diff --git a/src/lib/mac/cbc_mac/cbc_mac.cpp b/src/lib/mac/cbc_mac/cbc_mac.cpp index b58372c78..449865255 100644 --- a/src/lib/mac/cbc_mac/cbc_mac.cpp +++ b/src/lib/mac/cbc_mac/cbc_mac.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/mac_utils.h> #include <botan/cbc_mac.h> namespace Botan { @@ -14,14 +13,12 @@ CBC_MAC* CBC_MAC::make(const Spec& spec) { if(spec.arg_count() == 1) { - if(auto bc = make_block_cipher(spec.arg(0))) + if(auto bc = BlockCipher::create(spec.arg(0))) return new CBC_MAC(bc.release()); } return nullptr; } -BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "CBC-MAC", CBC_MAC, CBC_MAC::make); - /* * Update an CBC-MAC Calculation */ diff --git a/src/lib/mac/cmac/cmac.cpp b/src/lib/mac/cmac/cmac.cpp index 1621079dc..27edda233 100644 --- a/src/lib/mac/cmac/cmac.cpp +++ b/src/lib/mac/cmac/cmac.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/mac_utils.h> #include <botan/cmac.h> namespace Botan { @@ -14,14 +13,12 @@ CMAC* CMAC::make(const Spec& spec) { if(spec.arg_count() == 1) { - if(BlockCipher* bc = get_block_cipher(spec.arg(0))) - return new CMAC(bc); + if(auto bc = BlockCipher::create(spec.arg(0))) + return new CMAC(bc.release()); } return nullptr; } -BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "CMAC", CMAC, CMAC::make); - /* * Perform CMAC's multiplication in GF(2^n) */ diff --git a/src/lib/mac/hmac/hmac.cpp b/src/lib/mac/hmac/hmac.cpp index 1c6821a54..f445ab0cf 100644 --- a/src/lib/mac/hmac/hmac.cpp +++ b/src/lib/mac/hmac/hmac.cpp @@ -6,7 +6,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/mac_utils.h> #include <botan/hmac.h> namespace Botan { @@ -15,14 +14,12 @@ HMAC* HMAC::make(const Spec& spec) { if(spec.arg_count() == 1) { - if(HashFunction* h = get_hash_function(spec.arg(0))) - return new HMAC(h); + if(auto h = HashFunction::create(spec.arg(0))) + return new HMAC(h.release()); } return nullptr; } -BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "HMAC", HMAC, HMAC::make); - /* * Update a HMAC Calculation */ diff --git a/src/lib/mac/info.txt b/src/lib/mac/info.txt index 3faa16c11..ab7833857 100644 --- a/src/lib/mac/info.txt +++ b/src/lib/mac/info.txt @@ -3,7 +3,3 @@ define MAC 20150626 <header:public> mac.h </header:public> - -<header:internal> -mac_utils.h -</header:internal> diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp index 0bb1939c7..8c1185c55 100644 --- a/src/lib/mac/mac.cpp +++ b/src/lib/mac/mac.cpp @@ -6,10 +6,48 @@ */ #include <botan/mac.h> +#include <botan/internal/algo_registry.h> #include <botan/mem_ops.h> +#if defined(BOTAN_HAS_CBC_MAC) + #include <botan/cbc_mac.h> +#endif + +#if defined(BOTAN_HAS_CMAC) + #include <botan/cmac.h> +#endif + +#if defined(BOTAN_HAS_HMAC) + #include <botan/hmac.h> +#endif + +#if defined(BOTAN_HAS_POLY1305) + #include <botan/poly1305.h> +#endif + +#if defined(BOTAN_HAS_SIPHASH) + #include <botan/siphash.h> +#endif + +#if defined(BOTAN_HAS_ANSI_X919_MAC) + #include <botan/x919_mac.h> +#endif + namespace Botan { +std::unique_ptr<MessageAuthenticationCode> MessageAuthenticationCode::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr<MessageAuthenticationCode>(make_a<MessageAuthenticationCode>(algo_spec, provider)); + } + +std::vector<std::string> MessageAuthenticationCode::providers(const std::string& algo_spec) + { + return providers_of<MessageAuthenticationCode>(MessageAuthenticationCode::Spec(algo_spec)); + } + +MessageAuthenticationCode::~MessageAuthenticationCode() {} + /* * Default (deterministic) MAC verification operation */ @@ -23,4 +61,28 @@ bool MessageAuthenticationCode::verify_mac(const byte mac[], size_t length) return same_mem(our_mac.data(), mac, length); } +#if defined(BOTAN_HAS_CBC_MAC) +BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "CBC-MAC", CBC_MAC, CBC_MAC::make); +#endif + +#if defined(BOTAN_HAS_CMAC) +BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "CMAC", CMAC, CMAC::make); +#endif + +#if defined(BOTAN_HAS_HMAC) +BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "HMAC", HMAC, HMAC::make); +#endif + +#if defined(BOTAN_HAS_POLY1305) +BOTAN_REGISTER_T_NOARGS(MessageAuthenticationCode, Poly1305); +#endif + +#if defined(BOTAN_HAS_SIPHASH) +BOTAN_REGISTER_NAMED_T_2LEN(MessageAuthenticationCode, SipHash, "SipHash", "base", 2, 4); +#endif + +#if defined(BOTAN_HAS_ANSI_X919_MAC) +BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "X9.19-MAC", ANSI_X919_MAC, make_new_T<ANSI_X919_MAC>); +#endif + } diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h index 8ad2d1e99..90ef4db15 100644 --- a/src/lib/mac/mac.h +++ b/src/lib/mac/mac.h @@ -22,6 +22,23 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, public SymmetricAlgorithm { public: + typedef SCAN_Name Spec; + + /** + * Create an instance based on a name + * Will return a null pointer if the algo/provider combination cannot + * be found. If provider is empty then best available is chosen. + */ + static std::unique_ptr<MessageAuthenticationCode> create(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * Returns the list of available providers for this algorithm, empty if not available + */ + static std::vector<std::string> providers(const std::string& algo_spec); + + virtual ~MessageAuthenticationCode(); + /** * Verify a MAC. * @param in the MAC to verify as a byte array @@ -34,8 +51,6 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, * Get a new object representing the same algorithm as *this */ virtual MessageAuthenticationCode* clone() const = 0; - - typedef SCAN_Name Spec; }; } diff --git a/src/lib/mac/mac_utils.h b/src/lib/mac/mac_utils.h deleted file mode 100644 index 5b22da4a3..000000000 --- a/src/lib/mac/mac_utils.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* Authentication Code Utility Header -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_MAC_UTILS_H__ -#define BOTAN_MAC_UTILS_H__ - -#include <botan/internal/algo_registry.h> -#include <botan/internal/xor_buf.h> -#include <botan/loadstor.h> -#include <botan/rotate.h> -#include <algorithm> - -namespace Botan { - -#define BOTAN_REGISTER_MAC(name, maker) BOTAN_REGISTER_T(MessageAuthenticationCode, name, maker) -#define BOTAN_REGISTER_MAC_NOARGS(name) BOTAN_REGISTER_T_NOARGS(MessageAuthenticationCode, name) - -#define BOTAN_REGISTER_MAC_1LEN(name, def) BOTAN_REGISTER_T_1LEN(MessageAuthenticationCode, name, def) - -#define BOTAN_REGISTER_MAC_NAMED_NOARGS(type, name) \ - BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, name, type, make_new_T<type>) - -#define BOTAN_REGISTER_MAC_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, name, type, (make_new_T_1len<type,def>)) -#define BOTAN_REGISTER_MAC_NAMED_1STR(type, name, def) \ - BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, name, type, \ - std::bind(make_new_T_1str<type>, std::placeholders::_1, def)); - -} - -#endif diff --git a/src/lib/mac/poly1305/poly1305.cpp b/src/lib/mac/poly1305/poly1305.cpp index 659667baf..0a62808f6 100644 --- a/src/lib/mac/poly1305/poly1305.cpp +++ b/src/lib/mac/poly1305/poly1305.cpp @@ -8,7 +8,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/mac_utils.h> #include <botan/poly1305.h> #include <botan/loadstor.h> #include <botan/mul128.h> @@ -16,8 +15,6 @@ namespace Botan { -BOTAN_REGISTER_MAC_NOARGS(Poly1305); - namespace { void poly1305_init(secure_vector<u64bit>& X, const byte key[32]) diff --git a/src/lib/mac/siphash/siphash.cpp b/src/lib/mac/siphash/siphash.cpp index f8ed28a84..4a9ffe8ea 100644 --- a/src/lib/mac/siphash/siphash.cpp +++ b/src/lib/mac/siphash/siphash.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/mac_utils.h> #include <botan/siphash.h> namespace Botan { -BOTAN_REGISTER_NAMED_T_2LEN(MessageAuthenticationCode, SipHash, "SipHash", "base", 2, 4); - namespace { void SipRounds(u64bit M, secure_vector<u64bit>& V, size_t r) diff --git a/src/lib/mac/x919_mac/x919_mac.cpp b/src/lib/mac/x919_mac/x919_mac.cpp index 542f9040a..205d812c2 100644 --- a/src/lib/mac/x919_mac/x919_mac.cpp +++ b/src/lib/mac/x919_mac/x919_mac.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/mac_utils.h> #include <botan/x919_mac.h> namespace Botan { -BOTAN_REGISTER_MAC_NAMED_NOARGS(ANSI_X919_MAC, "X9.19-MAC"); - /* * Update an ANSI X9.19 MAC Calculation */ @@ -88,10 +85,11 @@ MessageAuthenticationCode* ANSI_X919_MAC::clone() const /* * ANSI X9.19 MAC Constructor */ -ANSI_X919_MAC::ANSI_X919_MAC() : m_state(8), m_position(0) +ANSI_X919_MAC::ANSI_X919_MAC() : + m_des1(BlockCipher::create("DES")), + m_des2(BlockCipher::create("DES")), + m_state(8), m_position(0) { - m_des1.reset(get_block_cipher("DES")); - m_des2.reset(m_des1->clone()); } } diff --git a/src/lib/math/bigint/bigint.cpp b/src/lib/math/bigint/bigint.cpp index 0a068c53e..2acfabb99 100644 --- a/src/lib/math/bigint/bigint.cpp +++ b/src/lib/math/bigint/bigint.cpp @@ -7,7 +7,7 @@ #include <botan/bigint.h> #include <botan/internal/mp_core.h> -#include <botan/get_byte.h> +#include <botan/loadstor.h> #include <botan/parsing.h> #include <botan/internal/rounding.h> #include <botan/internal/bit_ops.h> diff --git a/src/lib/math/bigint/bigint.h b/src/lib/math/bigint/bigint.h index e3200ca9d..2963ba35d 100644 --- a/src/lib/math/bigint/bigint.h +++ b/src/lib/math/bigint/bigint.h @@ -12,7 +12,7 @@ #include <botan/rng.h> #include <botan/secmem.h> #include <botan/mp_types.h> -#include <botan/get_byte.h> +#include <botan/loadstor.h> #include <iosfwd> namespace Botan { diff --git a/src/lib/math/bigint/info.txt b/src/lib/math/bigint/info.txt index b5dabb7bc..53edcb1f1 100644 --- a/src/lib/math/bigint/info.txt +++ b/src/lib/math/bigint/info.txt @@ -18,7 +18,6 @@ divide.cpp </source> <requires> -alloc mp hex rng diff --git a/src/lib/math/ec_gfp/point_gfp.cpp b/src/lib/math/ec_gfp/point_gfp.cpp index 2505e4d54..705b14c52 100644 --- a/src/lib/math/ec_gfp/point_gfp.cpp +++ b/src/lib/math/ec_gfp/point_gfp.cpp @@ -2,36 +2,57 @@ * Point arithmetic on elliptic curves over GF(p) * * (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke -* 2008-2011,2012,2014 Jack Lloyd +* 2008-2011,2012,2014,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include <botan/point_gfp.h> #include <botan/numthry.h> +#include <botan/loadstor.h> +#include <botan/internal/rounding.h> namespace Botan { + PointGFp::PointGFp(const CurveGFp& curve) : - curve(curve), - coord_x(0), - coord_y(1), - coord_z(0) + m_curve(curve), + m_coord_x(0), + m_coord_y(1), + m_coord_z(0) { - curve.to_rep(coord_x, ws); - curve.to_rep(coord_y, ws); - curve.to_rep(coord_z, ws); + m_curve.to_rep(m_coord_x, m_monty_ws); + m_curve.to_rep(m_coord_y, m_monty_ws); + m_curve.to_rep(m_coord_z, m_monty_ws); } PointGFp::PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y) : - curve(curve), - coord_x(x), - coord_y(y), - coord_z(1) + m_curve(curve), + m_coord_x(x), + m_coord_y(y), + m_coord_z(1) { - curve.to_rep(coord_x, ws); - curve.to_rep(coord_y, ws); - curve.to_rep(coord_z, ws); + m_curve.to_rep(m_coord_x, m_monty_ws); + m_curve.to_rep(m_coord_y, m_monty_ws); + m_curve.to_rep(m_coord_z, m_monty_ws); + } + +void PointGFp::randomize_repr(RandomNumberGenerator& rng) + { + if(BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS > 1) + { + BigInt mask; + while(mask.is_zero()) + mask.randomize(rng, BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS, false); + + m_curve.to_rep(mask, m_monty_ws); + const BigInt mask2 = curve_mult(mask, mask); + const BigInt mask3 = curve_mult(mask2, mask); + + m_coord_x = curve_mult(m_coord_x, mask2); + m_coord_y = curve_mult(m_coord_y, mask3); + m_coord_z = curve_mult(m_coord_z, mask); + } } // Point addition @@ -39,15 +60,15 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) { if(is_zero()) { - coord_x = rhs.coord_x; - coord_y = rhs.coord_y; - coord_z = rhs.coord_z; + m_coord_x = rhs.m_coord_x; + m_coord_y = rhs.m_coord_y; + m_coord_z = rhs.m_coord_z; return; } else if(rhs.is_zero()) return; - const BigInt& p = curve.get_p(); + const BigInt& p = m_curve.get_p(); BigInt& rhs_z2 = ws_bn[0]; BigInt& U1 = ws_bn[1]; @@ -64,13 +85,13 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2 */ - curve_sqr(rhs_z2, rhs.coord_z); - curve_mult(U1, coord_x, rhs_z2); - curve_mult(S1, coord_y, curve_mult(rhs.coord_z, rhs_z2)); + curve_sqr(rhs_z2, rhs.m_coord_z); + curve_mult(U1, m_coord_x, rhs_z2); + curve_mult(S1, m_coord_y, curve_mult(rhs.m_coord_z, rhs_z2)); - curve_sqr(lhs_z2, coord_z); - curve_mult(U2, rhs.coord_x, lhs_z2); - curve_mult(S2, rhs.coord_y, curve_mult(coord_z, lhs_z2)); + curve_sqr(lhs_z2, m_coord_z); + curve_mult(U2, rhs.m_coord_x, lhs_z2); + curve_mult(S2, rhs.m_coord_y, curve_mult(m_coord_z, lhs_z2)); H = U2; H -= U1; @@ -90,7 +111,10 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) return; } - *this = PointGFp(curve); // setting myself to zero + // setting to zero: + m_coord_x = 0; + m_coord_y = 1; + m_coord_z = 0; return; } @@ -100,22 +124,22 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) U2 = curve_mult(U1, U2); - curve_sqr(coord_x, r); - coord_x -= S2; - coord_x -= (U2 << 1); - while(coord_x.is_negative()) - coord_x += p; + curve_sqr(m_coord_x, r); + m_coord_x -= S2; + m_coord_x -= (U2 << 1); + while(m_coord_x.is_negative()) + m_coord_x += p; - U2 -= coord_x; + U2 -= m_coord_x; if(U2.is_negative()) U2 += p; - curve_mult(coord_y, r, U2); - coord_y -= curve_mult(S1, S2); - if(coord_y.is_negative()) - coord_y += p; + curve_mult(m_coord_y, r, U2); + m_coord_y -= curve_mult(S1, S2); + if(m_coord_y.is_negative()) + m_coord_y += p; - curve_mult(coord_z, curve_mult(coord_z, rhs.coord_z), H); + curve_mult(m_coord_z, curve_mult(m_coord_z, rhs.m_coord_z), H); } // *this *= 2 @@ -123,9 +147,9 @@ void PointGFp::mult2(std::vector<BigInt>& ws_bn) { if(is_zero()) return; - else if(coord_y.is_zero()) + else if(m_coord_y.is_zero()) { - *this = PointGFp(curve); // setting myself to zero + *this = PointGFp(m_curve); // setting myself to zero return; } @@ -133,7 +157,7 @@ void PointGFp::mult2(std::vector<BigInt>& ws_bn) http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-1986-cc */ - const BigInt& p = curve.get_p(); + const BigInt& p = m_curve.get_p(); BigInt& y_2 = ws_bn[0]; BigInt& S = ws_bn[1]; @@ -145,17 +169,17 @@ void PointGFp::mult2(std::vector<BigInt>& ws_bn) BigInt& y = ws_bn[7]; BigInt& z = ws_bn[8]; - curve_sqr(y_2, coord_y); + curve_sqr(y_2, m_coord_y); - curve_mult(S, coord_x, y_2); + curve_mult(S, m_coord_x, y_2); S <<= 2; // * 4 while(S >= p) S -= p; - curve_sqr(z4, curve_sqr(coord_z)); - curve_mult(a_z4, curve.get_a_rep(), z4); + curve_sqr(z4, curve_sqr(m_coord_z)); + curve_mult(a_z4, m_curve.get_a_rep(), z4); - M = curve_sqr(coord_x); + M = curve_sqr(m_coord_x); M *= 3; M += a_z4; while(M >= p) @@ -180,14 +204,14 @@ void PointGFp::mult2(std::vector<BigInt>& ws_bn) if(y.is_negative()) y += p; - curve_mult(z, coord_y, coord_z); + curve_mult(z, m_coord_y, m_coord_z); z <<= 1; if(z >= p) z -= p; - coord_x = x; - coord_y = y; - coord_z = z; + m_coord_x = x; + m_coord_y = y; + m_coord_z = z; } // arithmetic operators @@ -221,7 +245,7 @@ PointGFp multi_exponentiate(const PointGFp& p1, const BigInt& z1, { const PointGFp p3 = p1 + p2; - PointGFp H(p1.curve); // create as zero + PointGFp H(p1.get_curve()); // create as zero size_t bits_left = std::max(z1.bits(), z2.bits()); std::vector<BigInt> ws(9); @@ -251,22 +275,24 @@ PointGFp multi_exponentiate(const PointGFp& p1, const BigInt& z1, PointGFp operator*(const BigInt& scalar, const PointGFp& point) { - //BOTAN_ASSERT(point.on_the_curve(), "Input is valid"); + //BOTAN_ASSERT(point.on_the_curve(), "Input is on the curve"); const CurveGFp& curve = point.get_curve(); - if(scalar.is_zero()) - return PointGFp(curve); // zero point + const size_t scalar_bits = scalar.bits(); std::vector<BigInt> ws(9); - if(scalar.abs() <= 2) // special cases for small values + if(scalar_bits <= 2) { - byte value = scalar.abs().byte_at(0); + const byte abs_val = scalar.byte_at(0); + + if(abs_val == 0) + return PointGFp::zero_of(curve); PointGFp result = point; - if(value == 2) + if(abs_val == 2) result.mult2(ws); if(scalar.is_negative()) @@ -275,94 +301,177 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point) return result; } - const size_t scalar_bits = scalar.bits(); + PointGFp R[2] = { PointGFp(curve), point }; - PointGFp x1(curve); // zero + for(size_t i = scalar_bits; i > 0; i--) + { + const size_t b = scalar.get_bit(i - 1); + R[b ^ 1].add(R[b], ws); + R[b].mult2(ws); + } - size_t bits_left = scalar_bits; + if(scalar.is_negative()) + R[0].negate(); -#if BOTAN_CURVE_GFP_USE_MONTGOMERY_LADDER + //BOTAN_ASSERT(R[0].on_the_curve(), "Output is on the curve"); - PointGFp x2 = point; - while(bits_left) + return R[0]; + } + +Blinded_Point_Multiply::Blinded_Point_Multiply(const PointGFp& base, const BigInt& order, size_t h) : + m_h(h > 0 ? h : 4), m_order(order), m_ws(9) + { + // Upper bound is a sanity check rather than hard limit + if(m_h < 1 || m_h > 8) + throw std::invalid_argument("Blinded_Point_Multiply invalid h param"); + + const CurveGFp& curve = base.get_curve(); + +#if BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER + + const PointGFp inv = -base; + + m_U.resize(6*m_h + 3); + + m_U[3*m_h+0] = inv; + m_U[3*m_h+1] = PointGFp::zero_of(curve); + m_U[3*m_h+2] = base; + + for(size_t i = 1; i <= 3 * m_h + 1; ++i) { - if(scalar.get_bit(bits_left - 1)) - { - x1.add(x2, ws); - x2.mult2(ws); - } - else - { - x2.add(x1, ws); - x1.mult2(ws); - } + m_U[3*m_h+1+i] = m_U[3*m_h+i]; + m_U[3*m_h+1+i].add(base, m_ws); - --bits_left; + m_U[3*m_h+1-i] = m_U[3*m_h+2-i]; + m_U[3*m_h+1-i].add(inv, m_ws); } - #else - const size_t window_bits = 4; - - std::vector<PointGFp> Ps(1 << window_bits); - Ps[0] = x1; - Ps[1] = point; + m_U.resize(1 << m_h); + m_U[0] = PointGFp::zero_of(curve); + m_U[1] = base; - for(size_t i = 2; i < Ps.size(); ++i) + for(size_t i = 2; i < m_U.size(); ++i) { - Ps[i] = Ps[i-1]; - Ps[i].add(point, ws); + m_U[i] = m_U[i-1]; + m_U[i].add(base, m_ws); } +#endif + } + +PointGFp Blinded_Point_Multiply::blinded_multiply(const BigInt& scalar_in, + RandomNumberGenerator& rng) + { + if(scalar_in.is_negative()) + throw std::invalid_argument("Blinded_Point_Multiply scalar must be positive"); + +#if BOTAN_POINTGFP_SCALAR_BLINDING_BITS > 0 + // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure) + const BigInt mask(rng, BOTAN_POINTGFP_SCALAR_BLINDING_BITS, false); + const BigInt scalar = scalar_in + m_order * mask; +#else + const BigInt& scalar = scalar_in; +#endif + + const size_t scalar_bits = scalar.bits(); + + // Randomize each point representation (Coron's 3rd countermeasure) + for(size_t i = 0; i != m_U.size(); ++i) + m_U[i].randomize_repr(rng); + +#if BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER + PointGFp R = m_U.at(3*m_h + 2); // base point + int32_t alpha = 0; + + R.randomize_repr(rng); - while(bits_left >= window_bits) + /* + Algorithm 7 from "Randomizing the Montgomery Powering Ladder" + Duc-Phong Le, Chik How Tan and Michael Tunstall + http://eprint.iacr.org/2015/657 + + It takes a random walk through (a subset of) the set of addition + chains that end in k. + */ + for(size_t i = scalar_bits; i > 0; i--) { - for(size_t i = 0; i != window_bits; ++i) - x1.mult2(ws); + const int32_t ki = scalar.get_bit(i); + + // choose gamma from -h,...,h + const int32_t gamma = static_cast<int32_t>((rng.next_byte() % (2*m_h))) - m_h; + const int32_t l = gamma - 2*alpha + ki - (ki ^ 1); - const u32bit nibble = scalar.get_substring(bits_left - window_bits, window_bits); - x1.add(Ps[nibble], ws); - bits_left -= window_bits; + R.mult2(m_ws); + R.add(m_U.at(3*m_h + 1 + l), m_ws); + alpha = gamma; } - while(bits_left) + const int32_t k0 = scalar.get_bit(0); + R.add(m_U[3*m_h + 1 - alpha - (k0 ^ 1)], m_ws); + +#else + + // N-bit windowing exponentiation: + + size_t windows = round_up(scalar_bits, m_h) / m_h; + + PointGFp R = m_U[0]; + + if(windows > 0) { - x1.mult2(ws); - if(scalar.get_bit(bits_left-1)) - x1.add(point, ws); - --bits_left; - } + windows--; + const u32bit nibble = scalar.get_substring(windows*m_h, m_h); + R.add(m_U[nibble], m_ws); + + /* + Randomize after adding the first nibble as before the addition R + is zero, and we cannot effectively randomize the point + representation of the zero point. + */ + R.randomize_repr(rng); + + while(windows) + { + for(size_t i = 0; i != m_h; ++i) + R.mult2(m_ws); + const u32bit nibble = scalar.get_substring((windows-1)*m_h, m_h); + R.add(m_U[nibble], m_ws); + windows--; + } + } #endif - if(scalar.is_negative()) - x1.negate(); - - //BOTAN_ASSERT(x1.on_the_curve(), "Output is on the curve"); + //BOTAN_ASSERT(R.on_the_curve(), "Output is on the curve"); - return x1; + return R; } BigInt PointGFp::get_affine_x() const { if(is_zero()) + abort(); + if(is_zero()) throw Illegal_Transformation("Cannot convert zero point to affine"); - BigInt z2 = curve_sqr(coord_z); - curve.from_rep(z2, ws); - z2 = inverse_mod(z2, curve.get_p()); + BigInt z2 = curve_sqr(m_coord_z); + m_curve.from_rep(z2, m_monty_ws); + z2 = inverse_mod(z2, m_curve.get_p()); - return curve_mult(z2, coord_x); + return curve_mult(z2, m_coord_x); } BigInt PointGFp::get_affine_y() const { if(is_zero()) + abort(); + if(is_zero()) throw Illegal_Transformation("Cannot convert zero point to affine"); - BigInt z3 = curve_mult(coord_z, curve_sqr(coord_z)); - z3 = inverse_mod(z3, curve.get_p()); - curve.to_rep(z3, ws); + BigInt z3 = curve_mult(m_coord_z, curve_sqr(m_coord_z)); + z3 = inverse_mod(z3, m_curve.get_p()); + m_curve.to_rep(z3, m_monty_ws); - return curve_mult(z3, coord_y); + return curve_mult(z3, m_coord_y); } bool PointGFp::on_the_curve() const @@ -376,22 +485,22 @@ bool PointGFp::on_the_curve() const if(is_zero()) return true; - const BigInt y2 = curve.from_rep(curve_sqr(coord_y), ws); - const BigInt x3 = curve_mult(coord_x, curve_sqr(coord_x)); - const BigInt ax = curve_mult(coord_x, curve.get_a_rep()); - const BigInt z2 = curve_sqr(coord_z); + const BigInt y2 = m_curve.from_rep(curve_sqr(m_coord_y), m_monty_ws); + const BigInt x3 = curve_mult(m_coord_x, curve_sqr(m_coord_x)); + const BigInt ax = curve_mult(m_coord_x, m_curve.get_a_rep()); + const BigInt z2 = curve_sqr(m_coord_z); - if(coord_z == z2) // Is z equal to 1 (in Montgomery form)? + if(m_coord_z == z2) // Is z equal to 1 (in Montgomery form)? { - if(y2 != curve.from_rep(x3 + ax + curve.get_b_rep(), ws)) + if(y2 != m_curve.from_rep(x3 + ax + m_curve.get_b_rep(), m_monty_ws)) return false; } - const BigInt z3 = curve_mult(coord_z, z2); + const BigInt z3 = curve_mult(m_coord_z, z2); const BigInt ax_z4 = curve_mult(ax, curve_sqr(z2)); - const BigInt b_z6 = curve_mult(curve.get_b_rep(), curve_sqr(z3)); + const BigInt b_z6 = curve_mult(m_curve.get_b_rep(), curve_sqr(z3)); - if(y2 != curve.from_rep(x3 + ax_z4 + b_z6, ws)) + if(y2 != m_curve.from_rep(x3 + ax_z4 + b_z6, m_monty_ws)) return false; return true; @@ -400,11 +509,11 @@ bool PointGFp::on_the_curve() const // swaps the states of *this and other, does not throw! void PointGFp::swap(PointGFp& other) { - curve.swap(other.curve); - coord_x.swap(other.coord_x); - coord_y.swap(other.coord_y); - coord_z.swap(other.coord_z); - ws.swap(other.ws); + m_curve.swap(other.m_curve); + m_coord_x.swap(other.m_coord_x); + m_coord_y.swap(other.m_coord_y); + m_coord_z.swap(other.m_coord_z); + m_monty_ws.swap(other.m_monty_ws); } bool PointGFp::operator==(const PointGFp& other) const diff --git a/src/lib/math/ec_gfp/point_gfp.h b/src/lib/math/ec_gfp/point_gfp.h index 813ead81e..206e43155 100644 --- a/src/lib/math/ec_gfp/point_gfp.h +++ b/src/lib/math/ec_gfp/point_gfp.h @@ -2,7 +2,7 @@ * Point arithmetic on elliptic curves over GF(p) * * (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke -* 2008-2011,2014 Jack Lloyd +* 2008-2011,2014,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -58,6 +58,11 @@ class BOTAN_DLL PointGFp */ PointGFp(const CurveGFp& curve); + static PointGFp zero_of(const CurveGFp& curve) + { + return PointGFp(curve); + } + /** * Copy constructor */ @@ -113,6 +118,7 @@ class BOTAN_DLL PointGFp * @param scalar the PointGFp to multiply with *this * @result resulting PointGFp */ + PointGFp& operator*=(const BigInt& scalar); /** @@ -142,7 +148,7 @@ class BOTAN_DLL PointGFp PointGFp& negate() { if(!is_zero()) - coord_y = curve.get_p() - coord_y; + m_coord_y = m_curve.get_p() - m_coord_y; return *this; } @@ -150,7 +156,7 @@ class BOTAN_DLL PointGFp * Return base curve of this point * @result the curve over GF(p) of this point */ - const CurveGFp& get_curve() const { return curve; } + const CurveGFp& get_curve() const { return m_curve; } /** * get affine x coordinate @@ -169,7 +175,7 @@ class BOTAN_DLL PointGFp * @result true, if this point is at infinity, false otherwise. */ bool is_zero() const - { return (coord_x.is_zero() && coord_z.is_zero()); } + { return (m_coord_x.is_zero() && m_coord_z.is_zero()); } /** * Checks whether the point is to be found on the underlying @@ -185,33 +191,40 @@ class BOTAN_DLL PointGFp void swap(PointGFp& other); /** + * Randomize the point representation + * The actual value (get_affine_x, get_affine_y) does not change + */ + void randomize_repr(RandomNumberGenerator& rng); + + /** * Equality operator */ bool operator==(const PointGFp& other) const; private: + friend class Blinded_Point_Multiply; BigInt curve_mult(const BigInt& x, const BigInt& y) const { BigInt z; - curve.mul(z, x, y, ws); + m_curve.mul(z, x, y, m_monty_ws); return z; } void curve_mult(BigInt& z, const BigInt& x, const BigInt& y) const { - curve.mul(z, x, y, ws); + m_curve.mul(z, x, y, m_monty_ws); } BigInt curve_sqr(const BigInt& x) const { BigInt z; - curve.sqr(z, x, ws); + m_curve.sqr(z, x, m_monty_ws); return z; } void curve_sqr(BigInt& z, const BigInt& x) const { - curve.sqr(z, x, ws); + m_curve.sqr(z, x, m_monty_ws); } /** @@ -226,9 +239,9 @@ class BOTAN_DLL PointGFp */ void mult2(std::vector<BigInt>& workspace); - CurveGFp curve; - BigInt coord_x, coord_y, coord_z; - mutable secure_vector<word> ws; // workspace for Montgomery + CurveGFp m_curve; + BigInt m_coord_x, m_coord_y, m_coord_z; + mutable secure_vector<word> m_monty_ws; // workspace for Montgomery }; // relational operators @@ -270,6 +283,22 @@ template<typename Alloc> PointGFp OS2ECP(const std::vector<byte, Alloc>& data, const CurveGFp& curve) { return OS2ECP(data.data(), data.size(), curve); } +/** + +*/ +class BOTAN_DLL Blinded_Point_Multiply + { + public: + Blinded_Point_Multiply(const PointGFp& base, const BigInt& order, size_t h = 0); + + PointGFp blinded_multiply(const BigInt& scalar, RandomNumberGenerator& rng); + private: + const size_t m_h; + const BigInt& m_order; + std::vector<BigInt> m_ws; + std::vector<PointGFp> m_U; + }; + } namespace std { diff --git a/src/lib/math/numbertheory/dsa_gen.cpp b/src/lib/math/numbertheory/dsa_gen.cpp index bd3c0e4a1..60151355a 100644 --- a/src/lib/math/numbertheory/dsa_gen.cpp +++ b/src/lib/math/numbertheory/dsa_gen.cpp @@ -6,7 +6,6 @@ */ #include <botan/numthry.h> -#include <botan/lookup.h> #include <botan/hash.h> #include <botan/parsing.h> #include <algorithm> @@ -52,7 +51,10 @@ bool generate_dsa_primes(RandomNumberGenerator& rng, "Generating a DSA parameter set with a " + std::to_string(qbits) + "long q requires a seed at least as many bits long"); - std::unique_ptr<HashFunction> hash(make_hash_function("SHA-" + std::to_string(qbits))); + const std::string hash_name = "SHA-" + std::to_string(qbits); + std::unique_ptr<HashFunction> hash(HashFunction::create(hash_name)); + if(!hash) + throw Algorithm_Not_Found(hash_name); const size_t HASH_SIZE = hash->output_length(); diff --git a/src/lib/math/numbertheory/make_prm.cpp b/src/lib/math/numbertheory/make_prm.cpp index 1333fdf04..3d82adf06 100644 --- a/src/lib/math/numbertheory/make_prm.cpp +++ b/src/lib/math/numbertheory/make_prm.cpp @@ -18,22 +18,37 @@ BigInt random_prime(RandomNumberGenerator& rng, size_t bits, const BigInt& coprime, size_t equiv, size_t modulo) { + if(coprime <= 0) + { + throw Invalid_Argument("random_prime: coprime must be > 0"); + } + if(modulo % 2 == 1 || modulo == 0) + { + throw Invalid_Argument("random_prime: Invalid modulo value"); + } + if(equiv >= modulo || equiv % 2 == 0) + { + throw Invalid_Argument("random_prime: equiv must be < modulo, and odd"); + } + + // Handle small values: if(bits <= 1) + { throw Invalid_Argument("random_prime: Can't make a prime of " + std::to_string(bits) + " bits"); + } else if(bits == 2) + { return ((rng.next_byte() % 2) ? 2 : 3); + } else if(bits == 3) + { return ((rng.next_byte() % 2) ? 5 : 7); + } else if(bits == 4) + { return ((rng.next_byte() % 2) ? 11 : 13); - - if(coprime <= 0) - throw Invalid_Argument("random_prime: coprime must be > 0"); - if(modulo % 2 == 1 || modulo == 0) - throw Invalid_Argument("random_prime: Invalid modulo value"); - if(equiv >= modulo || equiv % 2 == 0) - throw Invalid_Argument("random_prime: equiv must be < modulo, and odd"); + } while(true) { @@ -56,27 +71,39 @@ BigInt random_prime(RandomNumberGenerator& rng, size_t counter = 0; while(true) { - if(counter == 4096 || p.bits() > bits) - break; - - bool passes_sieve = true; ++counter; + + if(counter >= 4096) + { + break; // don't try forever, choose a new starting point + } + p += modulo; if(p.bits() > bits) break; + bool passes_sieve = true; for(size_t j = 0; j != sieve.size(); ++j) { sieve[j] = (sieve[j] + modulo) % PRIMES[j]; if(sieve[j] == 0) + { passes_sieve = false; + break; + } } - if(!passes_sieve || gcd(p - 1, coprime) != 1) + if(!passes_sieve) + continue; + + if(gcd(p - 1, coprime) != 1) continue; - if(is_prime(p, rng, 64, true)) + + if(is_prime(p, rng, 128, true)) + { return p; + } } } } @@ -93,7 +120,8 @@ BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits) BigInt p; do p = (random_prime(rng, bits - 1) << 1) + 1; - while(!is_prime(p, rng, 64, true)); + while(!is_prime(p, rng, 128, true)); + return p; } diff --git a/src/lib/math/numbertheory/pow_mod.cpp b/src/lib/math/numbertheory/pow_mod.cpp index 9a9bff2ad..49ff6cca2 100644 --- a/src/lib/math/numbertheory/pow_mod.cpp +++ b/src/lib/math/numbertheory/pow_mod.cpp @@ -15,7 +15,7 @@ namespace Botan { */ Power_Mod::Power_Mod(const BigInt& n, Usage_Hints hints) { - core = nullptr; + m_core = nullptr; set_modulus(n, hints); } @@ -24,9 +24,9 @@ Power_Mod::Power_Mod(const BigInt& n, Usage_Hints hints) */ Power_Mod::Power_Mod(const Power_Mod& other) { - core = nullptr; - if(other.core) - core = other.core->copy(); + m_core = nullptr; + if(other.m_core) + m_core = other.m_core->copy(); } /* @@ -34,10 +34,10 @@ Power_Mod::Power_Mod(const Power_Mod& other) */ Power_Mod& Power_Mod::operator=(const Power_Mod& other) { - delete core; - core = nullptr; - if(other.core) - core = other.core->copy(); + delete m_core; + m_core = nullptr; + if(other.m_core) + m_core = other.m_core->copy(); return (*this); } @@ -46,8 +46,8 @@ Power_Mod& Power_Mod::operator=(const Power_Mod& other) */ Power_Mod::~Power_Mod() { - delete core; - core = nullptr; + delete m_core; + m_core = nullptr; } /* @@ -55,12 +55,12 @@ Power_Mod::~Power_Mod() */ void Power_Mod::set_modulus(const BigInt& n, Usage_Hints hints) const { - delete core; + delete m_core; if(n.is_odd()) - core = new Montgomery_Exponentiator(n, hints); + m_core = new Montgomery_Exponentiator(n, hints); else if(n != 0) - core = new Fixed_Window_Exponentiator(n, hints); + m_core = new Fixed_Window_Exponentiator(n, hints); } /* @@ -71,9 +71,9 @@ void Power_Mod::set_base(const BigInt& b) const if(b.is_zero() || b.is_negative()) throw Invalid_Argument("Power_Mod::set_base: arg must be > 0"); - if(!core) - throw Internal_Error("Power_Mod::set_base: core was NULL"); - core->set_base(b); + if(!m_core) + throw Internal_Error("Power_Mod::set_base: m_core was NULL"); + m_core->set_base(b); } /* @@ -84,9 +84,9 @@ void Power_Mod::set_exponent(const BigInt& e) const if(e.is_negative()) throw Invalid_Argument("Power_Mod::set_exponent: arg must be > 0"); - if(!core) - throw Internal_Error("Power_Mod::set_exponent: core was NULL"); - core->set_exponent(e); + if(!m_core) + throw Internal_Error("Power_Mod::set_exponent: m_core was NULL"); + m_core->set_exponent(e); } /* @@ -94,9 +94,9 @@ void Power_Mod::set_exponent(const BigInt& e) const */ BigInt Power_Mod::execute() const { - if(!core) - throw Internal_Error("Power_Mod::execute: core was NULL"); - return core->execute(); + if(!m_core) + throw Internal_Error("Power_Mod::execute: m_core was NULL"); + return m_core->execute(); } /* diff --git a/src/lib/math/numbertheory/pow_mod.h b/src/lib/math/numbertheory/pow_mod.h index 9a827562e..4f94fd62d 100644 --- a/src/lib/math/numbertheory/pow_mod.h +++ b/src/lib/math/numbertheory/pow_mod.h @@ -63,7 +63,7 @@ class BOTAN_DLL Power_Mod Power_Mod(const Power_Mod&); virtual ~Power_Mod(); private: - mutable Modular_Exponentiator* core; + mutable Modular_Exponentiator* m_core; }; /** diff --git a/src/lib/misc/aont/package.cpp b/src/lib/misc/aont/package.cpp index 125b3842e..a3be898d8 100644 --- a/src/lib/misc/aont/package.cpp +++ b/src/lib/misc/aont/package.cpp @@ -9,8 +9,7 @@ #include <botan/package.h> #include <botan/filters.h> #include <botan/ctr.h> -#include <botan/get_byte.h> -#include <botan/internal/xor_buf.h> +#include <botan/loadstor.h> namespace Botan { diff --git a/src/lib/misc/benchmark/benchmark.cpp b/src/lib/misc/benchmark/benchmark.cpp index 90d8b1aca..d5e3694b5 100644 --- a/src/lib/misc/benchmark/benchmark.cpp +++ b/src/lib/misc/benchmark/benchmark.cpp @@ -6,7 +6,7 @@ */ #include <botan/benchmark.h> -#include <botan/lookup.h> +#include <botan/exceptn.h> #include <botan/buf_comp.h> #include <botan/cipher_mode.h> #include <botan/block_cipher.h> @@ -55,10 +55,8 @@ time_algorithm_ops(const std::string& name, const double mb_mult = buffer.size() / static_cast<double>(Mebibyte); - if(BlockCipher* p = get_block_cipher(name, provider)) + if(auto bc = BlockCipher::create(name, provider)) { - std::unique_ptr<BlockCipher> bc(p); - const SymmetricKey key(rng, bc->maximum_keylength()); return std::map<std::string, double>({ @@ -67,10 +65,8 @@ time_algorithm_ops(const std::string& name, { "decrypt", mb_mult * time_op(runtime / 2, [&]() { bc->decrypt(buffer); }) }, }); } - else if(StreamCipher* p = get_stream_cipher(name, provider)) + else if(auto sc = StreamCipher::create(name, provider)) { - std::unique_ptr<StreamCipher> sc(p); - const SymmetricKey key(rng, sc->maximum_keylength()); return std::map<std::string, double>({ @@ -78,18 +74,14 @@ time_algorithm_ops(const std::string& name, { "", mb_mult * time_op(runtime, [&]() { sc->encipher(buffer); }) }, }); } - else if(HashFunction* p = get_hash_function(name, provider)) + else if(auto h = HashFunction::create(name, provider)) { - std::unique_ptr<HashFunction> h(p); - return std::map<std::string, double>({ { "", mb_mult * time_op(runtime, [&]() { h->update(buffer); }) }, }); } - else if(MessageAuthenticationCode* p = get_mac(name, provider)) + else if(auto mac = MessageAuthenticationCode::create(name, provider)) { - std::unique_ptr<MessageAuthenticationCode> mac(p); - const SymmetricKey key(rng, mac->maximum_keylength()); return std::map<std::string, double>({ @@ -136,10 +128,10 @@ std::set<std::string> get_all_providers_of(const std::string& algo) auto add_to_set = [&provs](const std::vector<std::string>& str) { for(auto&& s : str) { provs.insert(s); } }; - add_to_set(get_block_cipher_providers(algo)); - add_to_set(get_stream_cipher_providers(algo)); - add_to_set(get_hash_function_providers(algo)); - add_to_set(get_mac_providers(algo)); + add_to_set(BlockCipher::providers(algo)); + add_to_set(StreamCipher::providers(algo)); + add_to_set(HashFunction::providers(algo)); + add_to_set(MessageAuthenticationCode::providers(algo)); return provs; } @@ -153,19 +145,18 @@ algorithm_benchmark(const std::string& name, size_t buf_size) { //Algorithm_Factory& af = global_state().algorithm_factory(); - const auto providers = get_all_providers_of(name); + const auto provider_names = get_all_providers_of(name); + if (provider_names.empty()) + throw No_Provider_Found(name); std::map<std::string, double> all_results; // provider -> ops/sec - if(!providers.empty()) - { - const std::chrono::nanoseconds ns_per_provider = milliseconds / providers.size(); + const std::chrono::nanoseconds ns_per_provider = milliseconds / provider_names.size(); - for(auto provider : providers) - { - auto results = time_algorithm_ops(name, provider, rng, ns_per_provider, buf_size); - all_results[provider] = find_first_in(results, { "", "update", "encrypt" }); - } + for(auto provider : provider_names) + { + auto results = time_algorithm_ops(name, provider, rng, ns_per_provider, buf_size); + all_results[provider] = find_first_in(results, { "", "update", "encrypt" }); } return all_results; diff --git a/src/lib/misc/cryptobox/cryptobox.cpp b/src/lib/misc/cryptobox/cryptobox.cpp index d7e7bb72b..c0fc9b777 100644 --- a/src/lib/misc/cryptobox/cryptobox.cpp +++ b/src/lib/misc/cryptobox/cryptobox.cpp @@ -8,12 +8,11 @@ #include <botan/cryptobox.h> #include <botan/filters.h> #include <botan/pipe.h> -#include <botan/lookup.h> #include <botan/sha2_64.h> #include <botan/hmac.h> #include <botan/pbkdf2.h> #include <botan/pem.h> -#include <botan/get_byte.h> +#include <botan/loadstor.h> #include <botan/mem_ops.h> namespace Botan { diff --git a/src/lib/misc/openpgp/openpgp.cpp b/src/lib/misc/openpgp/openpgp.cpp index 3a464d906..f42ce875e 100644 --- a/src/lib/misc/openpgp/openpgp.cpp +++ b/src/lib/misc/openpgp/openpgp.cpp @@ -28,16 +28,16 @@ std::string PGP_encode( std::string pgp_encoded = PGP_HEADER; if(headers.find("Version") != headers.end()) - pgp_encoded += "Version: " + headers.find("Version")->second + '\n'; + pgp_encoded += "Version: " + headers.find("Version")->second + "\n"; std::map<std::string, std::string>::const_iterator i = headers.begin(); while(i != headers.end()) { if(i->first != "Version") - pgp_encoded += i->first + ": " + i->second + '\n'; + pgp_encoded += i->first + ": " + i->second + "\n"; ++i; } - pgp_encoded += '\n'; + pgp_encoded += "\n"; Pipe pipe(new Fork( new Base64_Encoder(true, PGP_WIDTH), @@ -48,7 +48,7 @@ std::string PGP_encode( pipe.process_msg(input, length); pgp_encoded += pipe.read_all_as_string(0); - pgp_encoded += '=' + pipe.read_all_as_string(1) + '\n'; + pgp_encoded += "=" + pipe.read_all_as_string(1) + "\n"; pgp_encoded += PGP_TRAILER; return pgp_encoded; diff --git a/src/lib/misc/pbes2/pbes2.cpp b/src/lib/misc/pbes2/pbes2.cpp index 89af01e9d..c66b293e8 100644 --- a/src/lib/misc/pbes2/pbes2.cpp +++ b/src/lib/misc/pbes2/pbes2.cpp @@ -7,7 +7,6 @@ #include <botan/pbes2.h> #include <botan/cipher_mode.h> -#include <botan/lookup.h> #include <botan/pbkdf.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> @@ -82,6 +81,9 @@ pbes2_encrypt(const secure_vector<byte>& key_bits, std::unique_ptr<Cipher_Mode> enc(get_cipher_mode(cipher, ENCRYPTION)); + if(!enc) + throw Decoding_Error("PBE-PKCS5 cannot encrypt no cipher " + cipher); + std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); const size_t key_length = enc->key_spec().maximum_keylength(); @@ -155,6 +157,8 @@ pbes2_decrypt(const secure_vector<byte>& key_bits, std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); std::unique_ptr<Cipher_Mode> dec(get_cipher_mode(cipher, DECRYPTION)); + if(!dec) + throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher); if(key_length == 0) key_length = dec->key_spec().maximum_keylength(); diff --git a/src/lib/misc/pem/info.txt b/src/lib/misc/pem/info.txt index c614b5ca7..9340a7cef 100644 --- a/src/lib/misc/pem/info.txt +++ b/src/lib/misc/pem/info.txt @@ -1,5 +1,5 @@ define PEM_CODEC 20131128 <requires> -codec_filt +base64 </requires> diff --git a/src/lib/misc/pem/pem.cpp b/src/lib/misc/pem/pem.cpp index f33016c70..83b48c07b 100644 --- a/src/lib/misc/pem/pem.cpp +++ b/src/lib/misc/pem/pem.cpp @@ -6,25 +6,46 @@ */ #include <botan/pem.h> -#include <botan/filters.h> +#include <botan/base64.h> #include <botan/parsing.h> +#include <botan/exceptn.h> namespace Botan { namespace PEM_Code { +namespace { + +std::string linewrap(size_t width, const std::string& in) + { + std::string out; + for(size_t i = 0; i != in.size(); ++i) + { + if(i > 0 && i % width == 0) + { + out.push_back('\n'); + } + out.push_back(in[i]); + } + if(out.size() > 0 && out[out.size()-1] != '\n') + { + out.push_back('\n'); + } + + return out; + } + +} + /* * PEM encode BER/DER-encoded objects */ -std::string encode(const byte der[], size_t length, const std::string& label, - size_t width) +std::string encode(const byte der[], size_t length, const std::string& label, size_t width) { const std::string PEM_HEADER = "-----BEGIN " + label + "-----\n"; const std::string PEM_TRAILER = "-----END " + label + "-----\n"; - Pipe pipe(new Base64_Encoder(true, width)); - pipe.process_msg(der, length); - return (PEM_HEADER + pipe.read_all_as_string() + PEM_TRAILER); + return (PEM_HEADER + linewrap(width, base64_encode(der, length)) + PEM_TRAILER); } /* @@ -79,8 +100,7 @@ secure_vector<byte> decode(DataSource& source, std::string& label) label += static_cast<char>(b); } - Pipe base64(new Base64_Decoder); - base64.start_msg(); + std::vector<char> b64; const std::string PEM_TRAILER = "-----END " + label + "-----"; position = 0; @@ -95,10 +115,10 @@ secure_vector<byte> decode(DataSource& source, std::string& label) throw Decoding_Error("PEM: Malformed PEM trailer"); if(position == 0) - base64.write(b); + b64.push_back(b); } - base64.end_msg(); - return base64.read_all(); + + return base64_decode(b64.data(), b64.size()); } secure_vector<byte> decode_check_label(const std::string& pem, diff --git a/src/lib/misc/rfc3394/rfc3394.cpp b/src/lib/misc/rfc3394/rfc3394.cpp index a199cc599..582e8c92d 100644 --- a/src/lib/misc/rfc3394/rfc3394.cpp +++ b/src/lib/misc/rfc3394/rfc3394.cpp @@ -6,11 +6,9 @@ */ #include <botan/rfc3394.h> -#include <botan/lookup.h> #include <botan/block_cipher.h> #include <botan/loadstor.h> #include <botan/exceptn.h> -#include <botan/internal/xor_buf.h> namespace Botan { @@ -23,7 +21,10 @@ secure_vector<byte> rfc3394_keywrap(const secure_vector<byte>& key, if(kek.size() != 16 && kek.size() != 24 && kek.size() != 32) throw std::invalid_argument("Bad KEK length " + std::to_string(kek.size()) + " for NIST key wrap"); - std::unique_ptr<BlockCipher> aes(make_block_cipher("AES-" + std::to_string(8*kek.size()))); + const std::string cipher_name = "AES-" + std::to_string(8*kek.size()); + std::unique_ptr<BlockCipher> aes(BlockCipher::create(cipher_name)); + if(!aes) + throw Algorithm_Not_Found(cipher_name); aes->set_key(kek); const size_t n = key.size() / 8; @@ -67,7 +68,10 @@ secure_vector<byte> rfc3394_keyunwrap(const secure_vector<byte>& key, if(kek.size() != 16 && kek.size() != 24 && kek.size() != 32) throw std::invalid_argument("Bad KEK length " + std::to_string(kek.size()) + " for NIST key unwrap"); - std::unique_ptr<BlockCipher> aes(make_block_cipher("AES-" + std::to_string(8*kek.size()))); + const std::string cipher_name = "AES-" + std::to_string(8*kek.size()); + std::unique_ptr<BlockCipher> aes(BlockCipher::create(cipher_name)); + if(!aes) + throw Algorithm_Not_Found(cipher_name); aes->set_key(kek); const size_t n = (key.size() - 8) / 8; diff --git a/src/lib/misc/srp6/srp6.cpp b/src/lib/misc/srp6/srp6.cpp index d3f7338bd..f567db875 100644 --- a/src/lib/misc/srp6/srp6.cpp +++ b/src/lib/misc/srp6/srp6.cpp @@ -8,7 +8,6 @@ #include <botan/srp6.h> #include <botan/dl_group.h> #include <botan/numthry.h> -#include <botan/lookup.h> namespace Botan { @@ -19,7 +18,10 @@ BigInt hash_seq(const std::string& hash_id, const BigInt& in1, const BigInt& in2) { - std::unique_ptr<HashFunction> hash_fn(get_hash(hash_id)); + std::unique_ptr<HashFunction> hash_fn(HashFunction::create(hash_id)); + + if(!hash_fn) + throw Algorithm_Not_Found(hash_id); hash_fn->update(BigInt::encode_1363(in1, pad_to)); hash_fn->update(BigInt::encode_1363(in2, pad_to)); @@ -32,7 +34,10 @@ BigInt compute_x(const std::string& hash_id, const std::string& password, const std::vector<byte>& salt) { - std::unique_ptr<HashFunction> hash_fn(get_hash(hash_id)); + std::unique_ptr<HashFunction> hash_fn(HashFunction::create(hash_id)); + + if(!hash_fn) + throw Algorithm_Not_Found(hash_id); hash_fn->update(identifier); hash_fn->update(":"); diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp index 1f2099d2e..3d04887d0 100644 --- a/src/lib/modes/aead/aead.cpp +++ b/src/lib/modes/aead/aead.cpp @@ -4,11 +4,63 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/mode_utils.h> #include <botan/aead.h> +#include <botan/internal/mode_utils.h> +#include <botan/internal/algo_registry.h> + +#if defined(BOTAN_HAS_AEAD_CCM) + #include <botan/ccm.h> +#endif + +#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305) + #include <botan/chacha20poly1305.h> +#endif + +#if defined(BOTAN_HAS_AEAD_EAX) + #include <botan/eax.h> +#endif + +#if defined(BOTAN_HAS_AEAD_GCM) + #include <botan/gcm.h> +#endif + +#if defined(BOTAN_HAS_AEAD_OCB) + #include <botan/ocb.h> +#endif + +#if defined(BOTAN_HAS_AEAD_SIV) + #include <botan/siv.h> +#endif namespace Botan { +AEAD_Mode::~AEAD_Mode() {} + +#if defined(BOTAN_HAS_AEAD_CCM) +BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN2(CCM_Encryption, CCM_Decryption, 16, 3); +#endif + +#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305) +BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Encryption); +BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Decryption); +#endif + +#if defined(BOTAN_HAS_AEAD_EAX) +BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(EAX_Encryption, EAX_Decryption, 0); +#endif + +#if defined(BOTAN_HAS_AEAD_GCM) +BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(GCM_Encryption, GCM_Decryption, 16); +#endif + +#if defined(BOTAN_HAS_AEAD_OCB) +BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(OCB_Encryption, OCB_Decryption, 16); +#endif + +#if defined(BOTAN_HAS_AEAD_SIV) +BOTAN_REGISTER_BLOCK_CIPHER_MODE(SIV_Encryption, SIV_Decryption); +#endif + AEAD_Mode* get_aead(const std::string& algo_spec, Cipher_Dir direction) { std::unique_ptr<Cipher_Mode> mode(get_cipher_mode(algo_spec, direction)); diff --git a/src/lib/modes/aead/aead.h b/src/lib/modes/aead/aead.h index 1fff41f97..3214187db 100644 --- a/src/lib/modes/aead/aead.h +++ b/src/lib/modes/aead/aead.h @@ -55,6 +55,8 @@ class BOTAN_DLL AEAD_Mode : public Cipher_Mode * modes, and large enough that random collisions are unlikely). */ size_t default_nonce_length() const override { return 12; } + + virtual ~AEAD_Mode(); }; /** diff --git a/src/lib/modes/aead/ccm/ccm.cpp b/src/lib/modes/aead/ccm/ccm.cpp index b40e6e62b..bd4e0f4be 100644 --- a/src/lib/modes/aead/ccm/ccm.cpp +++ b/src/lib/modes/aead/ccm/ccm.cpp @@ -11,8 +11,6 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN2(CCM_Encryption, CCM_Decryption, 16, 3); - /* * CCM_Mode Constructor */ diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp index 3dc9d7f6d..0aef6a747 100644 --- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp +++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp @@ -10,13 +10,13 @@ namespace Botan { -BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Encryption); -BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Decryption); - ChaCha20Poly1305_Mode::ChaCha20Poly1305_Mode() : - m_chacha(make_stream_cipher("ChaCha")), - m_poly1305(make_message_auth("Poly1305")) - {} + m_chacha(StreamCipher::create("ChaCha")), + m_poly1305(MessageAuthenticationCode::create("Poly1305")) + { + if(!m_chacha || !m_poly1305) + throw Algorithm_Not_Found("ChaCha20Poly1305"); + } bool ChaCha20Poly1305_Mode::valid_nonce_length(size_t n) const { diff --git a/src/lib/modes/aead/eax/eax.cpp b/src/lib/modes/aead/eax/eax.cpp index 22e772d75..4b928cd31 100644 --- a/src/lib/modes/aead/eax/eax.cpp +++ b/src/lib/modes/aead/eax/eax.cpp @@ -13,8 +13,6 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(EAX_Encryption, EAX_Decryption, 0); - namespace { /* diff --git a/src/lib/modes/aead/gcm/gcm.cpp b/src/lib/modes/aead/gcm/gcm.cpp index 130ff6aad..7dcdd0d31 100644 --- a/src/lib/modes/aead/gcm/gcm.cpp +++ b/src/lib/modes/aead/gcm/gcm.cpp @@ -16,8 +16,6 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(GCM_Encryption, GCM_Decryption, 16); - void GHASH::gcm_multiply(secure_vector<byte>& x) const { #if defined(BOTAN_HAS_GCM_CLMUL) diff --git a/src/lib/modes/aead/ocb/ocb.cpp b/src/lib/modes/aead/ocb/ocb.cpp index ee5583bea..ff3317dd9 100644 --- a/src/lib/modes/aead/ocb/ocb.cpp +++ b/src/lib/modes/aead/ocb/ocb.cpp @@ -11,8 +11,6 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(OCB_Encryption, OCB_Decryption, 16); - // Has to be in Botan namespace so unique_ptr can reference it class L_computer { diff --git a/src/lib/modes/aead/siv/siv.cpp b/src/lib/modes/aead/siv/siv.cpp index 5b22216cf..a4cb65a94 100644 --- a/src/lib/modes/aead/siv/siv.cpp +++ b/src/lib/modes/aead/siv/siv.cpp @@ -13,8 +13,6 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_MODE(SIV_Encryption, SIV_Decryption); - SIV_Mode::SIV_Mode(BlockCipher* cipher) : m_name(cipher->name() + "/SIV"), m_ctr(new CTR_BE(cipher->clone())), diff --git a/src/lib/modes/cbc/cbc.cpp b/src/lib/modes/cbc/cbc.cpp index 85241cf53..1e3c6d6e3 100644 --- a/src/lib/modes/cbc/cbc.cpp +++ b/src/lib/modes/cbc/cbc.cpp @@ -11,27 +11,6 @@ namespace Botan { -template<typename CBC_T, typename CTS_T> -Transform* make_cbc_mode(const Transform::Spec& spec) - { - std::unique_ptr<BlockCipher> bc(get_block_cipher(spec.arg(0))); - - if(bc) - { - const std::string padding = spec.arg(1, "PKCS7"); - - if(padding == "CTS") - return new CTS_T(bc.release()); - else - return new CBC_T(bc.release(), get_bc_pad(padding)); - } - - return nullptr; - } - -BOTAN_REGISTER_TRANSFORM(CBC_Encryption, (make_cbc_mode<CBC_Encryption,CTS_Encryption>)); -BOTAN_REGISTER_TRANSFORM(CBC_Decryption, (make_cbc_mode<CBC_Decryption,CTS_Decryption>)); - CBC_Mode::CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : m_cipher(cipher), m_padding(padding), diff --git a/src/lib/modes/cfb/cfb.cpp b/src/lib/modes/cfb/cfb.cpp index e98d10cb3..7c7ed1865 100644 --- a/src/lib/modes/cfb/cfb.cpp +++ b/src/lib/modes/cfb/cfb.cpp @@ -11,8 +11,6 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(CFB_Encryption, CFB_Decryption, 0); - CFB_Mode::CFB_Mode(BlockCipher* cipher, size_t feedback_bits) : m_cipher(cipher), m_feedback_bytes(feedback_bits ? feedback_bits / 8 : cipher->block_size()) diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp index 095ef9008..acd5e23e2 100644 --- a/src/lib/modes/cipher_mode.cpp +++ b/src/lib/modes/cipher_mode.cpp @@ -7,11 +7,76 @@ #include <botan/cipher_mode.h> #include <botan/stream_mode.h> -#include <botan/lookup.h> +#include <botan/internal/mode_utils.h> +#include <botan/internal/algo_registry.h> #include <sstream> +#if defined(BOTAN_HAS_MODE_ECB) + #include <botan/ecb.h> +#endif + +#if defined(BOTAN_HAS_MODE_CBC) + #include <botan/cbc.h> +#endif + +#if defined(BOTAN_HAS_MODE_CFB) + #include <botan/cfb.h> +#endif + +#if defined(BOTAN_HAS_MODE_XTS) + #include <botan/xts.h> +#endif + namespace Botan { +#if defined(BOTAN_HAS_MODE_ECB) + +template<typename T> +Transform* make_ecb_mode(const Transform::Spec& spec) + { + std::unique_ptr<BlockCipher> bc(BlockCipher::create(spec.arg(0))); + std::unique_ptr<BlockCipherModePaddingMethod> pad(get_bc_pad(spec.arg(1, "NoPadding"))); + if(bc && pad) + return new T(bc.release(), pad.release()); + return nullptr; + } + +BOTAN_REGISTER_TRANSFORM(ECB_Encryption, make_ecb_mode<ECB_Encryption>); +BOTAN_REGISTER_TRANSFORM(ECB_Decryption, make_ecb_mode<ECB_Decryption>); +#endif + +#if defined(BOTAN_HAS_MODE_CBC) + +template<typename CBC_T, typename CTS_T> +Transform* make_cbc_mode(const Transform::Spec& spec) + { + std::unique_ptr<BlockCipher> bc(BlockCipher::create(spec.arg(0))); + + if(bc) + { + const std::string padding = spec.arg(1, "PKCS7"); + + if(padding == "CTS") + return new CTS_T(bc.release()); + else + return new CBC_T(bc.release(), get_bc_pad(padding)); + } + + return nullptr; + } + +BOTAN_REGISTER_TRANSFORM(CBC_Encryption, (make_cbc_mode<CBC_Encryption,CTS_Encryption>)); +BOTAN_REGISTER_TRANSFORM(CBC_Decryption, (make_cbc_mode<CBC_Decryption,CTS_Decryption>)); +#endif + +#if defined(BOTAN_HAS_MODE_CFB) +BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(CFB_Encryption, CFB_Decryption, 0); +#endif + +#if defined(BOTAN_HAS_MODE_XTS) +BOTAN_REGISTER_BLOCK_CIPHER_MODE(XTS_Encryption, XTS_Decryption); +#endif + Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction) { const std::string provider = ""; @@ -66,8 +131,8 @@ Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction) return cipher; } - if(StreamCipher* stream_cipher = get_stream_cipher(mode_name, provider)) - return new Stream_Cipher_Mode(stream_cipher); + if(auto sc = StreamCipher::create(mode_name, provider)) + return new Stream_Cipher_Mode(sc.release()); return nullptr; } diff --git a/src/lib/modes/ecb/ecb.cpp b/src/lib/modes/ecb/ecb.cpp index e5794d8e1..14e72e20b 100644 --- a/src/lib/modes/ecb/ecb.cpp +++ b/src/lib/modes/ecb/ecb.cpp @@ -10,19 +10,6 @@ namespace Botan { -template<typename T> -Transform* make_ecb_mode(const Transform::Spec& spec) - { - std::unique_ptr<BlockCipher> bc(get_block_cipher(spec.arg(0))); - std::unique_ptr<BlockCipherModePaddingMethod> pad(get_bc_pad(spec.arg(1, "NoPadding"))); - if(bc && pad) - return new T(bc.release(), pad.release()); - return nullptr; - } - -BOTAN_REGISTER_TRANSFORM(ECB_Encryption, make_ecb_mode<ECB_Encryption>); -BOTAN_REGISTER_TRANSFORM(ECB_Decryption, make_ecb_mode<ECB_Decryption>); - ECB_Mode::ECB_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : m_cipher(cipher), m_padding(padding) diff --git a/src/lib/modes/mode_utils.h b/src/lib/modes/mode_utils.h index 53aa41745..44524c4f6 100644 --- a/src/lib/modes/mode_utils.h +++ b/src/lib/modes/mode_utils.h @@ -9,10 +9,8 @@ #define BOTAN_MODE_UTILS_H__ #include <botan/cipher_mode.h> -#include <botan/internal/algo_registry.h> #include <botan/block_cipher.h> #include <botan/loadstor.h> -#include <botan/internal/xor_buf.h> #include <botan/internal/rounding.h> #include <botan/internal/bit_ops.h> #include <algorithm> @@ -22,18 +20,18 @@ namespace Botan { template<typename T> T* make_block_cipher_mode(const Transform::Spec& spec) { - if(BlockCipher* bc = get_block_cipher(spec.arg(0))) - return new T(bc); + if(std::unique_ptr<BlockCipher> bc = BlockCipher::create(spec.arg(0))) + return new T(bc.release()); return nullptr; } template<typename T, size_t LEN1> T* make_block_cipher_mode_len(const Transform::Spec& spec) { - if(BlockCipher* bc = get_block_cipher(spec.arg(0))) + if(std::unique_ptr<BlockCipher> bc = BlockCipher::create(spec.arg(0))) { const size_t len1 = spec.arg_as_integer(1, LEN1); - return new T(bc, len1); + return new T(bc.release(), len1); } return nullptr; @@ -42,11 +40,11 @@ T* make_block_cipher_mode_len(const Transform::Spec& spec) template<typename T, size_t LEN1, size_t LEN2> T* make_block_cipher_mode_len2(const Transform::Spec& spec) { - if(BlockCipher* bc = get_block_cipher(spec.arg(0))) + if(std::unique_ptr<BlockCipher> bc = BlockCipher::create(spec.arg(0))) { const size_t len1 = spec.arg_as_integer(1, LEN1); const size_t len2 = spec.arg_as_integer(2, LEN2); - return new T(bc, len1, len2); + return new T(bc.release(), len1, len2); } return nullptr; diff --git a/src/lib/modes/xts/xts.cpp b/src/lib/modes/xts/xts.cpp index 046de216f..c42988d10 100644 --- a/src/lib/modes/xts/xts.cpp +++ b/src/lib/modes/xts/xts.cpp @@ -10,8 +10,6 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_MODE(XTS_Encryption, XTS_Decryption); - namespace { void poly_double_128(byte out[], const byte in[]) diff --git a/src/lib/passhash/passhash9/passhash9.cpp b/src/lib/passhash/passhash9/passhash9.cpp index f30684ec6..b457fc5c7 100644 --- a/src/lib/passhash/passhash9/passhash9.cpp +++ b/src/lib/passhash/passhash9/passhash9.cpp @@ -7,7 +7,6 @@ #include <botan/passhash9.h> #include <botan/loadstor.h> -#include <botan/lookup.h> #include <botan/pbkdf2.h> #include <botan/base64.h> @@ -24,18 +23,18 @@ const size_t PASSHASH9_PBKDF_OUTPUT_LEN = 24; // 192 bits output const size_t WORK_FACTOR_SCALE = 10000; -MessageAuthenticationCode* get_pbkdf_prf(byte alg_id) +std::unique_ptr<MessageAuthenticationCode> get_pbkdf_prf(byte alg_id) { if(alg_id == 0) - return get_mac("HMAC(SHA-1)"); + return MessageAuthenticationCode::create("HMAC(SHA-1)"); else if(alg_id == 1) - return get_mac("HMAC(SHA-256)"); + return MessageAuthenticationCode::create("HMAC(SHA-256)"); else if(alg_id == 2) - return get_mac("CMAC(Blowfish)"); + return MessageAuthenticationCode::create("CMAC(Blowfish)"); else if(alg_id == 3) - return get_mac("HMAC(SHA-384)"); + return MessageAuthenticationCode::create("HMAC(SHA-384)"); else if(alg_id == 4) - return get_mac("HMAC(SHA-512)"); + return MessageAuthenticationCode::create("HMAC(SHA-512)"); return nullptr; } @@ -46,14 +45,14 @@ std::string generate_passhash9(const std::string& pass, u16bit work_factor, byte alg_id) { - MessageAuthenticationCode* prf = get_pbkdf_prf(alg_id); + std::unique_ptr<MessageAuthenticationCode> prf = get_pbkdf_prf(alg_id); if(!prf) throw Invalid_Argument("Passhash9: Algorithm id " + std::to_string(alg_id) + " is not defined"); - PKCS5_PBKDF2 kdf(prf); // takes ownership of pointer + PKCS5_PBKDF2 kdf(prf.release()); // takes ownership of pointer secure_vector<byte> salt(SALT_BYTES); rng.randomize(salt.data(), salt.size()); @@ -110,12 +109,12 @@ bool check_passhash9(const std::string& pass, const std::string& hash) const size_t kdf_iterations = WORK_FACTOR_SCALE * work_factor; - MessageAuthenticationCode* pbkdf_prf = get_pbkdf_prf(alg_id); + std::unique_ptr<MessageAuthenticationCode> pbkdf_prf = get_pbkdf_prf(alg_id); if(!pbkdf_prf) return false; // unknown algorithm, reject - PKCS5_PBKDF2 kdf(pbkdf_prf); // takes ownership of pointer + PKCS5_PBKDF2 kdf(pbkdf_prf.release()); // takes ownership of pointer secure_vector<byte> cmp = kdf.derive_key( PASSHASH9_PBKDF_OUTPUT_LEN, diff --git a/src/lib/pbkdf/info.txt b/src/lib/pbkdf/info.txt index 81f7c1260..3addbdb58 100644 --- a/src/lib/pbkdf/info.txt +++ b/src/lib/pbkdf/info.txt @@ -7,7 +7,3 @@ base <header:public> pbkdf.h </header:public> - -<header:internal> -pbkdf_utils.h -</header:internal> diff --git a/src/lib/pbkdf/pbkdf.cpp b/src/lib/pbkdf/pbkdf.cpp index 7f0a68a01..6d7a6542f 100644 --- a/src/lib/pbkdf/pbkdf.cpp +++ b/src/lib/pbkdf/pbkdf.cpp @@ -6,10 +6,43 @@ */ #include <botan/pbkdf.h> +#include <botan/internal/algo_registry.h> #include <stdexcept> +#if defined(BOTAN_HAS_PBKDF1) +#include <botan/pbkdf1.h> +#endif + +#if defined(BOTAN_HAS_PBKDF2) +#include <botan/pbkdf2.h> +#endif + namespace Botan { +#define BOTAN_REGISTER_PBKDF_1HASH(type, name) \ + BOTAN_REGISTER_NAMED_T(PBKDF, name, type, (make_new_T_1X<type, HashFunction>)) + +#if defined(BOTAN_HAS_PBKDF1) +BOTAN_REGISTER_PBKDF_1HASH(PKCS5_PBKDF1, "PBKDF1"); +#endif + +#if defined(BOTAN_HAS_PBKDF2) +BOTAN_REGISTER_NAMED_T(PBKDF, "PBKDF2", PKCS5_PBKDF2, PKCS5_PBKDF2::make); +#endif + +PBKDF::~PBKDF() {} + +std::unique_ptr<PBKDF> PBKDF::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr<PBKDF>(make_a<PBKDF>(algo_spec, provider)); + } + +std::vector<std::string> PBKDF::providers(const std::string& algo_spec) + { + return providers_of<PBKDF>(PBKDF::Spec(algo_spec)); + } + void PBKDF::pbkdf_timed(byte out[], size_t out_len, const std::string& passphrase, const byte salt[], size_t salt_len, diff --git a/src/lib/pbkdf/pbkdf.h b/src/lib/pbkdf/pbkdf.h index 5f6cd904c..495da0ac9 100644 --- a/src/lib/pbkdf/pbkdf.h +++ b/src/lib/pbkdf/pbkdf.h @@ -10,6 +10,8 @@ #include <botan/symkey.h> #include <botan/scan_name.h> +#include <botan/scan_name.h> +#include <botan/exceptn.h> #include <chrono> namespace Botan { @@ -22,8 +24,18 @@ namespace Botan { class BOTAN_DLL PBKDF { public: + /** + * Create an instance based on a name + * Will return a null pointer if the algo/provider combination cannot + * be found. If provider is empty then best available is chosen. + */ + static std::unique_ptr<PBKDF> create(const std::string& algo_spec, + const std::string& provider = ""); - virtual ~PBKDF() {} + /** + * Returns the list of available providers for this algorithm, empty if not available + */ + static std::vector<std::string> providers(const std::string& algo_spec); typedef SCAN_Name Spec; @@ -34,6 +46,8 @@ class BOTAN_DLL PBKDF virtual std::string name() const = 0; + virtual ~PBKDF(); + /** * Derive a key from a passphrase for a number of iterations * specified by either iterations or if iterations == 0 then @@ -147,6 +161,20 @@ class BOTAN_DLL PBKDF } }; +/** +* Password based key derivation function factory method +* @param algo_spec the name of the desired PBKDF algorithm +* @return pointer to newly allocated object of that type +*/ +inline PBKDF* get_pbkdf(const std::string& algo_spec, + const std::string& provider = "") + { + std::unique_ptr<PBKDF> p(PBKDF::create(algo_spec, provider)); + if(p) + return p.release(); + throw Algorithm_Not_Found(algo_spec); + } + } #endif diff --git a/src/lib/pbkdf/pbkdf1/pbkdf1.cpp b/src/lib/pbkdf/pbkdf1/pbkdf1.cpp index 28bac9572..49e1cf268 100644 --- a/src/lib/pbkdf/pbkdf1/pbkdf1.cpp +++ b/src/lib/pbkdf/pbkdf1/pbkdf1.cpp @@ -5,14 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pbkdf_utils.h> #include <botan/pbkdf1.h> #include <botan/exceptn.h> namespace Botan { -BOTAN_REGISTER_PBKDF_1HASH(PKCS5_PBKDF1, "PBKDF1"); - size_t PKCS5_PBKDF1::pbkdf(byte output_buf[], size_t output_len, const std::string& passphrase, const byte salt[], size_t salt_len, diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp index a27b9b15c..c1ac2c534 100644 --- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp +++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -5,23 +5,19 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pbkdf_utils.h> #include <botan/pbkdf2.h> -#include <botan/get_byte.h> -#include <botan/internal/xor_buf.h> +#include <botan/loadstor.h> #include <botan/internal/rounding.h> namespace Botan { -BOTAN_REGISTER_NAMED_T(PBKDF, "PBKDF2", PKCS5_PBKDF2, PKCS5_PBKDF2::make); - PKCS5_PBKDF2* PKCS5_PBKDF2::make(const Spec& spec) { - if(auto mac = get_mac(spec.arg(0))) - return new PKCS5_PBKDF2(mac); + if(auto mac = MessageAuthenticationCode::create(spec.arg(0))) + return new PKCS5_PBKDF2(mac.release()); - if(auto mac = get_mac("HMAC(" + spec.arg(0) + ")")) - return new PKCS5_PBKDF2(mac); + if(auto mac = MessageAuthenticationCode::create("HMAC(" + spec.arg(0) + ")")) + return new PKCS5_PBKDF2(mac.release()); return nullptr; } diff --git a/src/lib/pbkdf/pbkdf_utils.h b/src/lib/pbkdf/pbkdf_utils.h deleted file mode 100644 index 480fc70eb..000000000 --- a/src/lib/pbkdf/pbkdf_utils.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -* PBKDF Utility Header -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_PBKDF_UTILS_H__ -#define BOTAN_PBKDF_UTILS_H__ - -#include <botan/pbkdf.h> -#include <botan/internal/algo_registry.h> - -namespace Botan { - -#define BOTAN_REGISTER_PBKDF_1HASH(type, name) \ - BOTAN_REGISTER_NAMED_T(PBKDF, name, type, (make_new_T_1X<type, HashFunction>)) -#define BOTAN_REGISTER_PBKDF_1MAC(type, name) \ - BOTAN_REGISTER_NAMED_T(PBKDF, name, type, (make_new_T_1X<type, MessageAuthenticationCode>)) - -} - -#endif diff --git a/src/lib/pk_pad/eme.cpp b/src/lib/pk_pad/eme.cpp index 9398b4c83..4804a8a81 100644 --- a/src/lib/pk_pad/eme.cpp +++ b/src/lib/pk_pad/eme.cpp @@ -6,9 +6,53 @@ */ #include <botan/eme.h> +#include <botan/internal/algo_registry.h> + +#if defined(BOTAN_HAS_EME_OAEP) +#include <botan/oaep.h> +#endif + +#if defined(BOTAN_HAS_EME_PKCS1v15) +#include <botan/eme_pkcs.h> +#endif + +#if defined(BOTAN_HAS_EME_RAW) +#include <botan/eme_raw.h> +#endif namespace Botan { +#define BOTAN_REGISTER_EME(name, maker) BOTAN_REGISTER_T(EME, name, maker) +#define BOTAN_REGISTER_EME_NOARGS(name) BOTAN_REGISTER_T_NOARGS(EME, name) + +#define BOTAN_REGISTER_EME_NAMED_NOARGS(type, name) \ + BOTAN_REGISTER_NAMED_T(EME, name, type, make_new_T<type>) + +#if defined(BOTAN_HAS_EME_OAEP) +BOTAN_REGISTER_NAMED_T(EME, "OAEP", OAEP, OAEP::make); +#endif + +#if defined(BOTAN_HAS_EME_PKCS1v15) +BOTAN_REGISTER_EME_NAMED_NOARGS(EME_PKCS1v15, "PKCS1v15"); +#endif + +#if defined(BOTAN_HAS_EME_RAW) +BOTAN_REGISTER_EME_NAMED_NOARGS(EME_Raw, "Raw"); +#endif + +EME* get_eme(const std::string& algo_spec) + { + SCAN_Name request(algo_spec); + + if(EME* eme = make_a<EME>(algo_spec)) + return eme; + + if(request.algo_name() == "Raw") + return nullptr; // No padding + + throw Algorithm_Not_Found(algo_spec); + } + /* * Encode a message */ diff --git a/src/lib/pk_pad/eme_oaep/oaep.cpp b/src/lib/pk_pad/eme_oaep/oaep.cpp index 871f40142..b114afb8b 100644 --- a/src/lib/pk_pad/eme_oaep/oaep.cpp +++ b/src/lib/pk_pad/eme_oaep/oaep.cpp @@ -1,15 +1,13 @@ /* * OAEP -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pad_utils.h> #include <botan/oaep.h> #include <botan/mgf1.h> -#include <botan/mem_ops.h> - +#include <botan/internal/ct_utils.h> namespace Botan { @@ -20,17 +18,14 @@ OAEP* OAEP::make(const Spec& request) if(request.arg_count() == 1 || (request.arg_count() == 2 && request.arg(1) == "MGF1")) { - if(HashFunction* hash = get_hash_function(request.arg(0))) - return new OAEP(hash); + if(auto hash = HashFunction::create(request.arg(0))) + return new OAEP(hash.release()); } } return nullptr; } -BOTAN_REGISTER_NAMED_T(EME, "OAEP", OAEP, OAEP::make); - - /* * OAEP Pad Operation */ @@ -66,7 +61,7 @@ secure_vector<byte> OAEP::pad(const byte in[], size_t in_length, * OAEP Unpad Operation */ secure_vector<byte> OAEP::unpad(const byte in[], size_t in_length, - size_t key_length) const + size_t key_length) const { /* Must be careful about error messages here; if an attacker can @@ -89,41 +84,43 @@ secure_vector<byte> OAEP::unpad(const byte in[], size_t in_length, secure_vector<byte> input(key_length); buffer_insert(input, key_length - in_length, in, in_length); + BOTAN_CONST_TIME_POISON(input.data(), input.size()); + + const size_t hlen = m_Phash.size(); + mgf1_mask(*m_hash, - &input[m_Phash.size()], input.size() - m_Phash.size(), - input.data(), m_Phash.size()); + &input[hlen], input.size() - hlen, + input.data(), hlen); mgf1_mask(*m_hash, - input.data(), m_Phash.size(), - &input[m_Phash.size()], input.size() - m_Phash.size()); + input.data(), hlen, + &input[hlen], input.size() - hlen); - bool waiting_for_delim = true; - bool bad_input = false; - size_t delim_idx = 2 * m_Phash.size(); + size_t delim_idx = 2 * hlen; + byte waiting_for_delim = 0xFF; + byte bad_input = 0; - /* - * GCC 4.5 on x86-64 compiles this in a way that is still vunerable - * to timing analysis. Other compilers, or GCC on other platforms, - * may or may not. - */ for(size_t i = delim_idx; i < input.size(); ++i) { - const bool zero_p = !input[i]; - const bool one_p = input[i] == 0x01; + const byte zero_m = ct_is_zero_8(input[i]); + const byte one_m = ct_is_equal_8(input[i], 1); - const bool add_1 = waiting_for_delim && zero_p; + const byte add_m = waiting_for_delim & zero_m; - bad_input |= waiting_for_delim && !(zero_p || one_p); + bad_input |= waiting_for_delim & ~(zero_m | one_m); - delim_idx += add_1; + delim_idx += ct_select_mask_8(add_m, 1, 0); - waiting_for_delim &= zero_p; + waiting_for_delim &= zero_m; } // If we never saw any non-zero byte, then it's not valid input bad_input |= waiting_for_delim; + bad_input |= ct_expand_mask_8(!same_mem(&input[hlen], m_Phash.data(), hlen)); - bad_input |= !same_mem(&input[m_Phash.size()], m_Phash.data(), m_Phash.size()); + BOTAN_CONST_TIME_UNPOISON(input.data(), input.size()); + BOTAN_CONST_TIME_UNPOISON(&bad_input, sizeof(bad_input)); + BOTAN_CONST_TIME_UNPOISON(&delim_idx, sizeof(delim_idx)); if(bad_input) throw Decoding_Error("Invalid OAEP encoding"); diff --git a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp index 90af17565..219e93251 100644 --- a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp +++ b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp @@ -1,17 +1,15 @@ /* -* PKCS1 EME -* (C) 1999-2007 Jack Lloyd +* PKCS #1 v1.5 Type 2 (encryption) padding +* (C) 1999-2007,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pad_utils.h> #include <botan/eme_pkcs.h> +#include <botan/internal/ct_utils.h> namespace Botan { -BOTAN_REGISTER_EME_NAMED_NOARGS(EME_PKCS1v15, "PKCS1v15"); - /* * PKCS1 Pad Operation */ @@ -41,22 +39,39 @@ secure_vector<byte> EME_PKCS1v15::pad(const byte in[], size_t inlen, * PKCS1 Unpad Operation */ secure_vector<byte> EME_PKCS1v15::unpad(const byte in[], size_t inlen, - size_t key_len) const + size_t key_len) const { - if(inlen != key_len / 8 || inlen < 10 || in[0] != 0x02) + if(inlen != key_len / 8 || inlen < 10) throw Decoding_Error("PKCS1::unpad"); - size_t separator = 0; - for(size_t j = 0; j != inlen; ++j) - if(in[j] == 0) - { - separator = j; - break; - } - if(separator < 9) - throw Decoding_Error("PKCS1::unpad"); + BOTAN_CONST_TIME_POISON(in, inlen); + + byte bad_input_m = 0; + byte seen_zero_m = 0; + size_t delim_idx = 0; + + bad_input_m |= ~ct_is_equal_8(in[0], 2); + + for(size_t i = 1; i != inlen; ++i) + { + const byte is_zero_m = ct_is_zero_8(in[i]); + + delim_idx += ct_select_mask_8(~seen_zero_m, 1, 0); + + bad_input_m |= is_zero_m & ct_expand_mask_8(i < 9); + seen_zero_m |= is_zero_m; + } + + bad_input_m |= ~seen_zero_m; + + BOTAN_CONST_TIME_UNPOISON(in, inlen); + BOTAN_CONST_TIME_UNPOISON(&bad_input_m, sizeof(bad_input_m)); + BOTAN_CONST_TIME_UNPOISON(&delim_idx, sizeof(delim_idx)); + + if(bad_input_m) + throw Decoding_Error("Invalid PKCS #1 v1.5 encryption padding"); - return secure_vector<byte>(&in[separator + 1], &in[inlen]); + return secure_vector<byte>(&in[delim_idx + 1], &in[inlen]); } /* diff --git a/src/lib/pk_pad/eme_raw/eme_raw.cpp b/src/lib/pk_pad/eme_raw/eme_raw.cpp index 9ae894c70..78b670b65 100644 --- a/src/lib/pk_pad/eme_raw/eme_raw.cpp +++ b/src/lib/pk_pad/eme_raw/eme_raw.cpp @@ -4,14 +4,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pad_utils.h> #include <botan/internal/bit_ops.h> #include <botan/eme_raw.h> namespace Botan { -BOTAN_REGISTER_EME_NAMED_NOARGS(EME_Raw, "Raw"); - secure_vector<byte> EME_Raw::pad(const byte in[], size_t in_length, size_t key_bits, RandomNumberGenerator&) const diff --git a/src/lib/pk_pad/emsa.cpp b/src/lib/pk_pad/emsa.cpp new file mode 100644 index 000000000..e20286a7d --- /dev/null +++ b/src/lib/pk_pad/emsa.cpp @@ -0,0 +1,83 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/emsa.h> +#include <botan/internal/algo_registry.h> + +#if defined(BOTAN_HAS_EMSA1) + #include <botan/emsa1.h> +#endif + +#if defined(BOTAN_HAS_EMSA1_BSI) + #include <botan/emsa1_bsi.h> +#endif + +#if defined(BOTAN_HAS_EMSA_X931) + #include <botan/emsa_x931.h> +#endif + +#if defined(BOTAN_HAS_EMSA_PKCS1) + #include <botan/emsa_pkcs1.h> +#endif + +#if defined(BOTAN_HAS_EMSA_PSSR) + #include <botan/pssr.h> +#endif + +#if defined(BOTAN_HAS_EMSA_RAW) + #include <botan/emsa_raw.h> +#endif + +namespace Botan { + +EMSA::~EMSA() {} + +EMSA* get_emsa(const std::string& algo_spec) + { + SCAN_Name request(algo_spec); + + if(EMSA* emsa = make_a<EMSA>(algo_spec)) + return emsa; + + throw Algorithm_Not_Found(algo_spec); + } + +#define BOTAN_REGISTER_EMSA_NAMED_NOARGS(type, name) \ + BOTAN_REGISTER_NAMED_T(EMSA, name, type, make_new_T<type>) + +#define BOTAN_REGISTER_EMSA(name, maker) BOTAN_REGISTER_T(EMSA, name, maker) +#define BOTAN_REGISTER_EMSA_NOARGS(name) BOTAN_REGISTER_T_NOARGS(EMSA, name) + +#define BOTAN_REGISTER_EMSA_1HASH(type, name) \ + BOTAN_REGISTER_NAMED_T(EMSA, name, type, (make_new_T_1X<type, HashFunction>)) + +#if defined(BOTAN_HAS_EMSA1) +BOTAN_REGISTER_EMSA_1HASH(EMSA1, "EMSA1"); +#endif + +#if defined(BOTAN_HAS_EMSA1_BSI) +BOTAN_REGISTER_EMSA_1HASH(EMSA1_BSI, "EMSA1_BSI"); +#endif + +#if defined(BOTAN_HAS_EMSA_PKCS1) +BOTAN_REGISTER_NAMED_T(EMSA, "EMSA_PKCS1", EMSA_PCS1v15, EMSA_PKCS1v15::make); +#endif + +#if defined(BOTAN_HAS_EMSA_PSSR) +BOTAN_REGISTER_NAMED_T(EMSA, "PSSR", PSSR, PSSR::make); +#endif + +#if defined(BOTAN_HAS_EMSA_X931) +BOTAN_REGISTER_EMSA_1HASH(EMSA_X931, "EMSA_X931"); +#endif + +#if defined(BOTAN_HAS_EMSA_RAW) +BOTAN_REGISTER_EMSA_NAMED_NOARGS(EMSA_Raw, "Raw"); +#endif + +} + + diff --git a/src/lib/pk_pad/emsa.h b/src/lib/pk_pad/emsa.h index b0295636c..d4fd146da 100644 --- a/src/lib/pk_pad/emsa.h +++ b/src/lib/pk_pad/emsa.h @@ -15,7 +15,9 @@ namespace Botan { /** -* Encoding Method for Signatures, Appendix +* EMSA, from IEEE 1363s Encoding Method for Signatures, Appendix +* +* Any way of encoding/padding signatures */ class BOTAN_DLL EMSA { @@ -55,7 +57,8 @@ class BOTAN_DLL EMSA virtual bool verify(const secure_vector<byte>& coded, const secure_vector<byte>& raw, size_t key_bits) = 0; - virtual ~EMSA() {} + + virtual ~EMSA(); }; /** diff --git a/src/lib/pk_pad/emsa1/emsa1.cpp b/src/lib/pk_pad/emsa1/emsa1.cpp index 89f0d244a..0031bf263 100644 --- a/src/lib/pk_pad/emsa1/emsa1.cpp +++ b/src/lib/pk_pad/emsa1/emsa1.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pad_utils.h> #include <botan/emsa1.h> namespace Botan { -BOTAN_REGISTER_EMSA_1HASH(EMSA1, "EMSA1"); - namespace { secure_vector<byte> emsa1_encoding(const secure_vector<byte>& msg, diff --git a/src/lib/pk_pad/emsa1_bsi/emsa1_bsi.cpp b/src/lib/pk_pad/emsa1_bsi/emsa1_bsi.cpp index 81a168b7d..5fc96da8d 100644 --- a/src/lib/pk_pad/emsa1_bsi/emsa1_bsi.cpp +++ b/src/lib/pk_pad/emsa1_bsi/emsa1_bsi.cpp @@ -6,13 +6,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pad_utils.h> #include <botan/emsa1_bsi.h> namespace Botan { -BOTAN_REGISTER_EMSA_1HASH(EMSA1_BSI, "EMSA1_BSI"); - /* * EMSA1 BSI Encode Operation */ diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp index e6ce5ec2f..940f91c9a 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp @@ -5,30 +5,23 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pad_utils.h> #include <botan/emsa_pkcs1.h> #include <botan/hash_id.h> namespace Botan { -namespace { - -EMSA* make_pkcs1v15(const EMSA::Spec& spec) +EMSA* EMSA_PKCS1v15::make(const EMSA::Spec& spec) { if(spec.arg(0) == "Raw") return new EMSA_PKCS1v15_Raw; else { - if(HashFunction* h = get_hash_function(spec.arg(0))) - return new EMSA_PKCS1v15(h); + if(auto h = HashFunction::create(spec.arg(0))) + return new EMSA_PKCS1v15(h.release()); } return nullptr; } -} - -BOTAN_REGISTER_NAMED_T(EMSA, "EMSA_PKCS1", EMSA_PCS1v15, make_pkcs1v15); - namespace { secure_vector<byte> emsa3_encoding(const secure_vector<byte>& msg, diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h index 7bcae3bd1..19886f80c 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h @@ -21,6 +21,8 @@ namespace Botan { class BOTAN_DLL EMSA_PKCS1v15 : public EMSA { public: + static EMSA* make(const EMSA::Spec& spec); + /** * @param hash the hash object to use */ diff --git a/src/lib/pk_pad/emsa_pssr/pssr.cpp b/src/lib/pk_pad/emsa_pssr/pssr.cpp index a4744f8f4..36b0ab64c 100644 --- a/src/lib/pk_pad/emsa_pssr/pssr.cpp +++ b/src/lib/pk_pad/emsa_pssr/pssr.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pad_utils.h> #include <botan/pssr.h> #include <botan/mgf1.h> #include <botan/internal/bit_ops.h> @@ -17,17 +16,15 @@ PSSR* PSSR::make(const Spec& request) if(request.arg(1, "MGF1") != "MGF1") return nullptr; - if(HashFunction* hash = get_hash_function(request.arg(0))) + if(auto h = HashFunction::create(request.arg(0))) { - const size_t salt_size = request.arg_as_integer(2, hash->output_length()); - return new PSSR(hash, salt_size); + const size_t salt_size = request.arg_as_integer(2, h->output_length()); + return new PSSR(h.release(), salt_size); } return nullptr; } -BOTAN_REGISTER_NAMED_T(EMSA, "PSSR", PSSR, PSSR::make); - /* * PSSR Update Operation */ diff --git a/src/lib/pk_pad/emsa_raw/emsa_raw.cpp b/src/lib/pk_pad/emsa_raw/emsa_raw.cpp index dcce888f2..4560bd3c3 100644 --- a/src/lib/pk_pad/emsa_raw/emsa_raw.cpp +++ b/src/lib/pk_pad/emsa_raw/emsa_raw.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pad_utils.h> #include <botan/emsa_raw.h> namespace Botan { -BOTAN_REGISTER_EMSA_NAMED_NOARGS(EMSA_Raw, "Raw"); - /* * EMSA-Raw Encode Operation */ diff --git a/src/lib/pk_pad/emsa_x931/emsa_x931.cpp b/src/lib/pk_pad/emsa_x931/emsa_x931.cpp index fb1e4343a..2feedee1c 100644 --- a/src/lib/pk_pad/emsa_x931/emsa_x931.cpp +++ b/src/lib/pk_pad/emsa_x931/emsa_x931.cpp @@ -5,14 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pad_utils.h> #include <botan/emsa_x931.h> #include <botan/hash_id.h> namespace Botan { -BOTAN_REGISTER_EMSA_1HASH(EMSA_X931, "EMSA_X931"); - namespace { secure_vector<byte> emsa2_encoding(const secure_vector<byte>& msg, diff --git a/src/lib/pk_pad/get_pk_pad.cpp b/src/lib/pk_pad/get_pk_pad.cpp deleted file mode 100644 index 691de23e2..000000000 --- a/src/lib/pk_pad/get_pk_pad.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* -* EMSA/EME Retrieval -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include <botan/emsa.h> -#include <botan/eme.h> -#include <botan/scan_name.h> -#include <botan/internal/algo_registry.h> - -namespace Botan { - -EMSA* get_emsa(const std::string& algo_spec) - { - SCAN_Name request(algo_spec); - - if(EMSA* emsa = make_a<EMSA>(algo_spec)) - return emsa; - - throw Algorithm_Not_Found(algo_spec); - } - -EME* get_eme(const std::string& algo_spec) - { - SCAN_Name request(algo_spec); - - if(EME* eme = make_a<EME>(algo_spec)) - return eme; - - if(request.algo_name() == "Raw") - return nullptr; // No padding - - throw Algorithm_Not_Found(algo_spec); - } - -} diff --git a/src/lib/pk_pad/info.txt b/src/lib/pk_pad/info.txt index d77e1defd..8cb935faa 100644 --- a/src/lib/pk_pad/info.txt +++ b/src/lib/pk_pad/info.txt @@ -3,7 +3,6 @@ define PK_PADDING 20131128 load_on auto <requires> -alloc rng </requires> @@ -11,7 +10,3 @@ rng eme.h emsa.h </header:public> - -<header:internal> -pad_utils.h -</header:internal> diff --git a/src/lib/pk_pad/mgf1/mgf1.cpp b/src/lib/pk_pad/mgf1/mgf1.cpp index 950961f89..34bc4a9a9 100644 --- a/src/lib/pk_pad/mgf1/mgf1.cpp +++ b/src/lib/pk_pad/mgf1/mgf1.cpp @@ -7,7 +7,6 @@ #include <botan/mgf1.h> #include <botan/exceptn.h> -#include <botan/internal/xor_buf.h> #include <algorithm> namespace Botan { diff --git a/src/lib/pk_pad/pad_utils.h b/src/lib/pk_pad/pad_utils.h deleted file mode 100644 index 3918e133a..000000000 --- a/src/lib/pk_pad/pad_utils.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* Public Key Padding Utility Header -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_PK_PAD_UTILS_H__ -#define BOTAN_PK_PAD_UTILS_H__ - -#include <botan/internal/algo_registry.h> -#include <botan/internal/xor_buf.h> -#include <botan/loadstor.h> -#include <algorithm> - -namespace Botan { - -#define BOTAN_REGISTER_EME(name, maker) BOTAN_REGISTER_T(EME, name, maker) -#define BOTAN_REGISTER_EME_NOARGS(name) BOTAN_REGISTER_T_NOARGS(EME, name) - -#define BOTAN_REGISTER_EME_NAMED_NOARGS(type, name) \ - BOTAN_REGISTER_NAMED_T(EME, name, type, make_new_T<type>) - -#define BOTAN_REGISTER_EMSA_1HASH_1LEN(type, name) \ - BOTAN_REGISTER_NAMED_T(EMSA, name, type, (make_new_T_1X_1len<type, HashFunction>)) - -#define BOTAN_REGISTER_EME_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(EME, name, type, (make_new_T_1len<type,def>)) -#define BOTAN_REGISTER_EME_NAMED_1STR(type, name, def) \ - BOTAN_REGISTER_NAMED_T(EME, name, type, \ - std::bind(make_new_T_1str<type>, std::placeholders::_1, def)); - -#define BOTAN_REGISTER_EMSA_NAMED_NOARGS(type, name) \ - BOTAN_REGISTER_NAMED_T(EMSA, name, type, make_new_T<type>) - -#define BOTAN_REGISTER_EMSA(name, maker) BOTAN_REGISTER_T(EMSA, name, maker) -#define BOTAN_REGISTER_EMSA_NOARGS(name) BOTAN_REGISTER_T_NOARGS(EMSA, name) - -#define BOTAN_REGISTER_EMSA_1HASH(type, name) \ - BOTAN_REGISTER_NAMED_T(EMSA, name, type, (make_new_T_1X<type, HashFunction>)) - -} - -#endif diff --git a/src/lib/pubkey/blinding.cpp b/src/lib/pubkey/blinding.cpp index cd2b3d118..da9def797 100644 --- a/src/lib/pubkey/blinding.cpp +++ b/src/lib/pubkey/blinding.cpp @@ -1,6 +1,6 @@ /* * Blinding for public key operations -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -16,24 +16,28 @@ namespace Botan { -// TODO: use Montgomery - Blinder::Blinder(const BigInt& modulus, - std::function<BigInt (const BigInt&)> fwd_func, - std::function<BigInt (const BigInt&)> inv_func) + std::function<BigInt (const BigInt&)> fwd, + std::function<BigInt (const BigInt&)> inv) : + m_fwd_fn(fwd), m_inv_fn(inv) { m_reducer = Modular_Reducer(modulus); + m_modulus_bits = modulus.bits(); #if defined(BOTAN_HAS_SYSTEM_RNG) - auto& rng = system_rng(); + m_rng.reset(new System_RNG); #else - AutoSeeded_RNG rng; + m_rng.reset(new AutoSeeded_RNG); #endif - const BigInt k(rng, modulus.bits() - 1); + const BigInt k = blinding_nonce(); + m_e = m_fwd_fn(k); + m_d = m_inv_fn(k); + } - m_e = fwd_func(k); - m_d = inv_func(k); +BigInt Blinder::blinding_nonce() const + { + return BigInt(*m_rng, m_modulus_bits - 1); } BigInt Blinder::blind(const BigInt& i) const @@ -41,8 +45,20 @@ BigInt Blinder::blind(const BigInt& i) const if(!m_reducer.initialized()) throw std::runtime_error("Blinder not initialized, cannot blind"); - m_e = m_reducer.square(m_e); - m_d = m_reducer.square(m_d); + ++m_counter; + + if(BOTAN_BLINDING_REINIT_INTERVAL > 0 && (m_counter % BOTAN_BLINDING_REINIT_INTERVAL == 0)) + { + const BigInt k = blinding_nonce(); + m_e = m_fwd_fn(k); + m_d = m_inv_fn(k); + } + else + { + m_e = m_reducer.square(m_e); + m_d = m_reducer.square(m_d); + } + return m_reducer.multiply(i, m_e); } diff --git a/src/lib/pubkey/blinding.h b/src/lib/pubkey/blinding.h index e57c7888e..c1999feb7 100644 --- a/src/lib/pubkey/blinding.h +++ b/src/lib/pubkey/blinding.h @@ -1,6 +1,6 @@ /* * Blinding for public key operations -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -14,6 +14,8 @@ namespace Botan { +class RandomNumberGenerator; + /** * Blinding Function Object */ @@ -32,9 +34,21 @@ class BOTAN_DLL Blinder std::function<BigInt (const BigInt&)> fwd_func, std::function<BigInt (const BigInt&)> inv_func); + Blinder(const Blinder&) = delete; + + Blinder& operator=(const Blinder&) = delete; + private: + BigInt blinding_nonce() const; + Modular_Reducer m_reducer; + std::unique_ptr<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; }; } diff --git a/src/lib/pubkey/curve25519/donna.cpp b/src/lib/pubkey/curve25519/donna.cpp index 4fab78cb8..ab9363761 100644 --- a/src/lib/pubkey/curve25519/donna.cpp +++ b/src/lib/pubkey/curve25519/donna.cpp @@ -30,6 +30,7 @@ #include <botan/curve25519.h> #include <botan/mul128.h> #include <botan/internal/donna128.h> +#include <botan/internal/ct_utils.h> #include <botan/loadstor.h> namespace Botan { @@ -418,6 +419,10 @@ crecip(felem out, const felem z) { int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { + + BOTAN_CONST_TIME_POISON(secret, 32); + BOTAN_CONST_TIME_POISON(basepoint, 32); + limb bp[5], x[5], z[5], zmone[5]; uint8_t e[32]; int i; @@ -432,6 +437,10 @@ curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { crecip(zmone, z); fmul(z, x, zmone); fcontract(mypublic, z); + + BOTAN_CONST_TIME_UNPOISON(secret, 32); + BOTAN_CONST_TIME_UNPOISON(basepoint, 32); + BOTAN_CONST_TIME_UNPOISON(mypublic, 32); return 0; } diff --git a/src/lib/pubkey/dl_group/dl_group.cpp b/src/lib/pubkey/dl_group/dl_group.cpp index c519dcb99..fbaa67eaa 100644 --- a/src/lib/pubkey/dl_group/dl_group.cpp +++ b/src/lib/pubkey/dl_group/dl_group.cpp @@ -1,6 +1,6 @@ /* * Discrete Logarithm Parameters -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2008,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -42,7 +42,7 @@ DL_Group::DL_Group(const std::string& name) DL_Group::DL_Group(RandomNumberGenerator& rng, PrimeType type, size_t pbits, size_t qbits) { - if(pbits < 512) + if(pbits < 1024) throw Invalid_Argument("DL_Group: prime size " + std::to_string(pbits) + " is too small"); diff --git a/src/lib/pubkey/dlies/dlies.cpp b/src/lib/pubkey/dlies/dlies.cpp index 4b1a63f2c..708064d27 100644 --- a/src/lib/pubkey/dlies/dlies.cpp +++ b/src/lib/pubkey/dlies/dlies.cpp @@ -6,7 +6,6 @@ */ #include <botan/dlies.h> -#include <botan/internal/xor_buf.h> namespace Botan { diff --git a/src/lib/pubkey/ecc_key/info.txt b/src/lib/pubkey/ecc_key/info.txt index 6d6d5f0e9..fc4d4c91c 100644 --- a/src/lib/pubkey/ecc_key/info.txt +++ b/src/lib/pubkey/ecc_key/info.txt @@ -1,7 +1,6 @@ define ECC_PUBLIC_KEY_CRYPTO 20131128 <requires> -alloc asn1 bigint ec_gfp diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp index bad0f2c0b..6b589df9b 100644 --- a/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/lib/pubkey/ecdh/ecdh.cpp @@ -12,6 +12,8 @@ namespace Botan { +ECDH_PublicKey::ECDH_PublicKey() {} + namespace { /** diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h index ef3e8ef7a..2f892436c 100644 --- a/src/lib/pubkey/ecdh/ecdh.h +++ b/src/lib/pubkey/ecdh/ecdh.h @@ -56,7 +56,7 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey { return unlock(EC2OSP(public_point(), PointGFp::UNCOMPRESSED)); } protected: - ECDH_PublicKey() {} + ECDH_PublicKey(); }; /** diff --git a/src/lib/pubkey/ecdh/info.txt b/src/lib/pubkey/ecdh/info.txt index 32d944728..cfff0b304 100644 --- a/src/lib/pubkey/ecdh/info.txt +++ b/src/lib/pubkey/ecdh/info.txt @@ -1,7 +1,6 @@ define ECDH 20131128 <requires> -alloc asn1 ec_group ecc_key diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index 2518a14fe..4a4b0c037 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -2,14 +2,13 @@ * ECDSA implemenation * (C) 2007 Manuel Hartl, FlexSecure GmbH * 2007 Falko Strenzke, FlexSecure GmbH -* 2008-2010 Jack Lloyd +* 2008-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include <botan/internal/pk_utils.h> #include <botan/ecdsa.h> -#include <botan/reducer.h> #include <botan/keypair.h> #include <botan/rfc6979.h> @@ -40,10 +39,10 @@ class ECDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa, const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), - base_point(ecdsa.domain().get_base_point()), - order(ecdsa.domain().get_order()), - x(ecdsa.private_value()), - mod_order(order), + m_order(ecdsa.domain().get_order()), + m_base_point(ecdsa.domain().get_base_point(), m_order), + m_x(ecdsa.private_value()), + m_mod_order(m_order), m_hash(hash_for_deterministic_signature(emsa)) { } @@ -52,34 +51,34 @@ class ECDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA RandomNumberGenerator& rng) override; size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return order.bytes(); } - size_t max_input_bits() const override { return order.bits(); } + size_t message_part_size() const override { return m_order.bytes(); } + size_t max_input_bits() const override { return m_order.bits(); } private: - const PointGFp& base_point; - const BigInt& order; - const BigInt& x; - Modular_Reducer mod_order; + const BigInt& m_order; + Blinded_Point_Multiply m_base_point; + const BigInt& m_x; + Modular_Reducer m_mod_order; std::string m_hash; }; secure_vector<byte> ECDSA_Signature_Operation::raw_sign(const byte msg[], size_t msg_len, - RandomNumberGenerator&) + RandomNumberGenerator& rng) { const BigInt m(msg, msg_len); - const BigInt k = generate_rfc6979_nonce(x, order, m, m_hash); + const BigInt k = generate_rfc6979_nonce(m_x, m_order, m, m_hash); - const PointGFp k_times_P = base_point * k; - const BigInt r = mod_order.reduce(k_times_P.get_affine_x()); - const BigInt s = mod_order.multiply(inverse_mod(k, order), mul_add(x, r, m)); + const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng); + const BigInt r = m_mod_order.reduce(k_times_P.get_affine_x()); + const BigInt s = m_mod_order.multiply(inverse_mod(k, m_order), mul_add(m_x, r, m)); // With overwhelming probability, a bug rather than actual zero r/s BOTAN_ASSERT(s != 0, "invalid s"); BOTAN_ASSERT(r != 0, "invalid r"); - secure_vector<byte> output(2*order.bytes()); + secure_vector<byte> output(2*m_order.bytes()); r.binary_encode(&output[output.size() / 2 - r.bytes()]); s.binary_encode(&output[output.size() - s.bytes()]); return output; diff --git a/src/lib/pubkey/ecdsa/openssl_ecdsa.cpp b/src/lib/pubkey/ecdsa/openssl_ecdsa.cpp new file mode 100644 index 000000000..502702804 --- /dev/null +++ b/src/lib/pubkey/ecdsa/openssl_ecdsa.cpp @@ -0,0 +1,213 @@ +/* +* ECDSA via OpenSSL +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/build.h> + +#if defined(BOTAN_HAS_OPENSSL) + +#include <botan/internal/openssl.h> +#include <openssl/x509.h> + +#if !defined(OPENSSL_NO_ECDSA) + +#include <botan/der_enc.h> +#include <botan/ecdsa.h> +#include <botan/pkcs8.h> +#include <botan/oids.h> +#include <botan/internal/pk_utils.h> + +#include <openssl/ecdsa.h> +#include <openssl/ec.h> +#include <openssl/objects.h> + +namespace Botan { + +namespace { + +secure_vector<byte> PKCS8_for_openssl(const EC_PrivateKey& ec) + { + const PointGFp& pub_key = ec.public_point(); + const BigInt& priv_key = ec.private_value(); + + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(static_cast<size_t>(1)) + .encode(BigInt::encode_1363(priv_key, priv_key.bytes()), OCTET_STRING) + .start_cons(ASN1_Tag(0), PRIVATE) + .raw_bytes(ec.domain().DER_encode(EC_DOMPAR_ENC_OID)) + .end_cons() + .start_cons(ASN1_Tag(1), PRIVATE) + .encode(EC2OSP(pub_key, PointGFp::UNCOMPRESSED), BIT_STRING) + .end_cons() + .end_cons() + .get_contents(); + } + +int OpenSSL_EC_nid_for(const OID& oid) + { + if(oid.empty()) + return -1; + + static const std::map<std::string, int> nid_map = { + //{ "secp160r1", NID_secp160r1 }, + //{ "secp160r2", NID_secp160r2 }, + { "secp192r1", NID_X9_62_prime192v1 }, + { "secp224r1", NID_secp224r1 }, + { "secp256r1", NID_X9_62_prime256v1 }, + { "secp384r1", NID_secp384r1 }, + { "secp521r1", NID_secp521r1 } + // TODO: OpenSSL 1.0.2 added brainpool curves + }; + + const std::string name = OIDS::lookup(oid); + auto i = nid_map.find(name); + if(i != nid_map.end()) + return i->second; + + return -1; + } + +class OpenSSL_ECDSA_Verification_Operation : public PK_Ops::Verification_with_EMSA + { + public: + typedef ECDSA_PublicKey Key_Type; + + static OpenSSL_ECDSA_Verification_Operation* make(const Spec& spec) + { + if(const ECDSA_PublicKey* ecdsa = dynamic_cast<const ECDSA_PublicKey*>(&spec.key())) + { + const int nid = OpenSSL_EC_nid_for(ecdsa->domain().get_oid()); + if(nid > 0) + return new OpenSSL_ECDSA_Verification_Operation(*ecdsa, spec.padding(), nid); + } + + return nullptr; + } + + OpenSSL_ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa, const std::string& emsa, int nid) : + PK_Ops::Verification_with_EMSA(emsa), m_ossl_ec(::EC_KEY_new(), ::EC_KEY_free) + { + std::unique_ptr<::EC_GROUP, std::function<void (::EC_GROUP*)>> grp(::EC_GROUP_new_by_curve_name(nid), + ::EC_GROUP_free); + + if(!grp) + throw OpenSSL_Error("EC_GROUP_new_by_curve_name"); + + ::EC_KEY_set_group(m_ossl_ec.get(), grp.get()); + + const secure_vector<byte> enc = EC2OSP(ecdsa.public_point(), PointGFp::UNCOMPRESSED); + const byte* enc_ptr = enc.data(); + EC_KEY* key_ptr = m_ossl_ec.get(); + if(!::o2i_ECPublicKey(&key_ptr, &enc_ptr, enc.size())) + throw OpenSSL_Error("o2i_ECPublicKey"); + + const EC_GROUP* group = ::EC_KEY_get0_group(m_ossl_ec.get()); + m_order_bits = ::EC_GROUP_get_degree(group); + } + + size_t message_parts() const override { return 2; } + size_t message_part_size() const override { return (m_order_bits + 7) / 8; } + size_t max_input_bits() const override { return m_order_bits; } + + bool with_recovery() const override { return false; } + + bool verify(const byte msg[], size_t msg_len, + const byte sig_bytes[], size_t sig_len) override + { + if(sig_len != message_part_size() * message_parts()) + return false; + + std::unique_ptr<ECDSA_SIG, std::function<void (ECDSA_SIG*)>> sig(nullptr, ECDSA_SIG_free); + sig.reset(::ECDSA_SIG_new()); + + sig->r = BN_bin2bn(sig_bytes , sig_len / 2, nullptr); + sig->s = BN_bin2bn(sig_bytes + sig_len / 2, sig_len / 2, nullptr); + + const int res = ECDSA_do_verify(msg, msg_len, sig.get(), m_ossl_ec.get()); + if(res < 0) + throw OpenSSL_Error("ECDSA_do_verify"); + return (res == 1); + } + + private: + std::unique_ptr<EC_KEY, std::function<void (EC_KEY*)>> m_ossl_ec; + size_t m_order_bits = 0; + }; + +class OpenSSL_ECDSA_Signing_Operation : public PK_Ops::Signature_with_EMSA + { + public: + typedef ECDSA_PrivateKey Key_Type; + + static OpenSSL_ECDSA_Signing_Operation* make(const Spec& spec) + { + if(const ECDSA_PrivateKey* ecdsa = dynamic_cast<const ECDSA_PrivateKey*>(&spec.key())) + { + const int nid = OpenSSL_EC_nid_for(ecdsa->domain().get_oid()); + if(nid > 0) + return new OpenSSL_ECDSA_Signing_Operation(*ecdsa, spec.padding()); + } + + return nullptr; + } + + OpenSSL_ECDSA_Signing_Operation(const ECDSA_PrivateKey& ecdsa, const std::string& emsa) : + PK_Ops::Signature_with_EMSA(emsa), + m_ossl_ec(nullptr, ::EC_KEY_free) + { + const secure_vector<byte> der = PKCS8_for_openssl(ecdsa); + const byte* der_ptr = der.data(); + m_ossl_ec.reset(d2i_ECPrivateKey(nullptr, &der_ptr, der.size())); + if(!m_ossl_ec) + throw OpenSSL_Error("d2i_ECPrivateKey"); + + const EC_GROUP* group = ::EC_KEY_get0_group(m_ossl_ec.get()); + m_order_bits = ::EC_GROUP_get_degree(group); + } + + secure_vector<byte> raw_sign(const byte msg[], size_t msg_len, + RandomNumberGenerator&) override + { + std::unique_ptr<ECDSA_SIG, std::function<void (ECDSA_SIG*)>> sig(nullptr, ECDSA_SIG_free); + sig.reset(::ECDSA_do_sign(msg, msg_len, m_ossl_ec.get())); + + if(!sig) + throw OpenSSL_Error("ECDSA_do_sign"); + + const size_t order_bytes = message_part_size(); + const size_t r_bytes = BN_num_bytes(sig->r); + const size_t s_bytes = BN_num_bytes(sig->s); + secure_vector<byte> sigval(2*order_bytes); + BN_bn2bin(sig->r, &sigval[order_bytes - r_bytes]); + BN_bn2bin(sig->s, &sigval[2*order_bytes - s_bytes]); + return sigval; + } + + size_t message_parts() const override { return 2; } + size_t message_part_size() const override { return (m_order_bits + 7) / 8; } + size_t max_input_bits() const override { return m_order_bits; } + + private: + std::unique_ptr<EC_KEY, std::function<void (EC_KEY*)>> m_ossl_ec; + size_t m_order_bits = 0; + }; + +BOTAN_REGISTER_TYPE(PK_Ops::Verification, OpenSSL_ECDSA_Verification_Operation, "ECDSA", + OpenSSL_ECDSA_Verification_Operation::make, + "openssl", BOTAN_OPENSSL_ECDSA_PRIO); + +BOTAN_REGISTER_TYPE(PK_Ops::Signature, OpenSSL_ECDSA_Signing_Operation, "ECDSA", + OpenSSL_ECDSA_Signing_Operation::make, + "openssl", BOTAN_OPENSSL_ECDSA_PRIO); + +} + +} + +#endif + +#endif diff --git a/src/lib/pubkey/elgamal/elgamal.cpp b/src/lib/pubkey/elgamal/elgamal.cpp index 4d0344610..5bcdd5689 100644 --- a/src/lib/pubkey/elgamal/elgamal.cpp +++ b/src/lib/pubkey/elgamal/elgamal.cpp @@ -145,16 +145,13 @@ class ElGamal_Decryption_Operation : public PK_Ops::Decryption_with_EME ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, const std::string& eme) : - PK_Ops::Decryption_with_EME(eme) + PK_Ops::Decryption_with_EME(eme), + powermod_x_p(Fixed_Exponent_Power_Mod(key.get_x(), key.group_p())), + mod_p(Modular_Reducer(key.group_p())), + blinder(key.group_p(), + [](const BigInt& k) { return k; }, + [this](const BigInt& k) { return powermod_x_p(k); }) { - const BigInt& p = key.group_p(); - - powermod_x_p = Fixed_Exponent_Power_Mod(key.get_x(), p); - mod_p = Modular_Reducer(p); - - blinder = Blinder(p, - [](const BigInt& k) { return k; }, - [this](const BigInt& k) { return powermod_x_p(k); }); } secure_vector<byte> diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index 9c3a0ef3c..f04692d12 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -2,7 +2,7 @@ * GOST 34.10-2001 implemenation * (C) 2007 Falko Strenzke, FlexSecure GmbH * Manuel Hartl, FlexSecure GmbH -* (C) 2008-2010 Jack Lloyd +* (C) 2008-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -16,7 +16,6 @@ namespace Botan { std::vector<byte> GOST_3410_PublicKey::x509_subject_public_key() const { - // Trust CryptoPro to come up with something obnoxious const BigInt x = public_point().get_affine_x(); const BigInt y = public_point().get_affine_y(); @@ -53,7 +52,7 @@ GOST_3410_PublicKey::GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id, { OID ecc_param_id; - // Also includes hash and cipher OIDs... brilliant design guys + // The parameters also includes hash and cipher OIDs BER_Decoder(alg_id.parameters).start_cons(SEQUENCE).decode(ecc_param_id); domain_params = EC_Group(ecc_param_id); @@ -101,21 +100,23 @@ class GOST_3410_Signature_Operation : public PK_Ops::Signature_with_EMSA GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410, const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), - base_point(gost_3410.domain().get_base_point()), - order(gost_3410.domain().get_order()), - x(gost_3410.private_value()) {} + m_order(gost_3410.domain().get_order()), + m_mod_order(m_order), + m_base_point(gost_3410.domain().get_base_point(), m_order), + m_x(gost_3410.private_value()) {} size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return order.bytes(); } - size_t max_input_bits() const override { return order.bits(); } + size_t message_part_size() const override { return m_order.bytes(); } + size_t max_input_bits() const override { return m_order.bits(); } secure_vector<byte> raw_sign(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) override; private: - const PointGFp& base_point; - const BigInt& order; - const BigInt& x; + const BigInt& m_order; + Modular_Reducer m_mod_order; + Blinded_Point_Multiply m_base_point; + const BigInt& m_x; }; secure_vector<byte> @@ -124,26 +125,25 @@ GOST_3410_Signature_Operation::raw_sign(const byte msg[], size_t msg_len, { BigInt k; do - k.randomize(rng, order.bits()-1); - while(k >= order); + k.randomize(rng, m_order.bits()-1); + while(k >= m_order); BigInt e = decode_le(msg, msg_len); - e %= order; + e = m_mod_order.reduce(e); if(e == 0) e = 1; - PointGFp k_times_P = base_point * k; + const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng); BOTAN_ASSERT(k_times_P.on_the_curve(), "GOST 34.10 k*g is on the curve"); - BigInt r = k_times_P.get_affine_x() % order; - - BigInt s = (r*x + k*e) % order; + const BigInt r = m_mod_order.reduce(k_times_P.get_affine_x()); + const BigInt s = m_mod_order.reduce(r*m_x + k*e); if(r == 0 || s == 0) throw Invalid_State("GOST 34.10: r == 0 || s == 0"); - secure_vector<byte> output(2*order.bytes()); + secure_vector<byte> output(2*m_order.bytes()); s.binary_encode(&output[output.size() / 2 - s.bytes()]); r.binary_encode(&output[output.size() - r.bytes()]); return output; diff --git a/src/lib/pubkey/gost_3410/info.txt b/src/lib/pubkey/gost_3410/info.txt index 611449ebc..eb2255ad2 100644 --- a/src/lib/pubkey/gost_3410/info.txt +++ b/src/lib/pubkey/gost_3410/info.txt @@ -3,7 +3,6 @@ define GOST_34_10_2001 20131128 load_on auto <requires> -alloc asn1 ec_group ecc_key diff --git a/src/lib/pubkey/info.txt b/src/lib/pubkey/info.txt index ff28f2689..77ae820c7 100644 --- a/src/lib/pubkey/info.txt +++ b/src/lib/pubkey/info.txt @@ -28,7 +28,6 @@ pk_ops_impl.h </header:internal> <requires> -alloc asn1 bigint kdf diff --git a/src/lib/pubkey/mce/binary_matrix.cpp b/src/lib/pubkey/mce/binary_matrix.cpp deleted file mode 100644 index 12c842669..000000000 --- a/src/lib/pubkey/mce/binary_matrix.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/** - * (C) Copyright Projet SECRET, INRIA, Rocquencourt - * (C) Bhaskar Biswas and Nicolas Sendrier - * - * (C) 2014 cryptosource GmbH - * (C) 2014 Falko Strenzke [email protected] - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#include <botan/internal/binary_matrix.h> -#include <botan/internal/xor_buf.h> - -namespace Botan { - -binary_matrix::binary_matrix (u32bit rown, u32bit coln) - { - m_coln = coln; - m_rown = rown; - m_rwdcnt = (1 + (m_coln - 1) / BITS_PER_U32); - m_elem = std::vector<u32bit>(m_rown * m_rwdcnt); - } - -void binary_matrix::row_xor(u32bit a, u32bit b) - { - u32bit i; - for(i=0;i<m_rwdcnt;i++) - { - m_elem[a*m_rwdcnt+i]^=m_elem[b*m_rwdcnt+i]; - } - } - -//the matrix is reduced from LSB...(from right) -secure_vector<int> binary_matrix::row_reduced_echelon_form() - { - u32bit i, failcnt, findrow, max=m_coln - 1; - - secure_vector<int> perm(m_coln); - for(i=0;i<m_coln;i++) - { - perm[i]=i;//initialize permutation. - } - failcnt = 0; - - for(i=0;i<m_rown;i++,max--) - { - findrow=0; - for(u32bit j=i;j<m_rown;j++) - { - if(coef(j,max)) - { - if (i!=j)//not needed as ith row is 0 and jth row is 1. - row_xor(i,j);//xor to the row.(swap)? - findrow=1; - break; - }//largest value found (end if) - } - - if(!findrow)//if no row with a 1 found then swap last column and the column with no 1 down. - { - perm[m_coln - m_rown - 1 - failcnt] = max; - failcnt++; - if (!max) - { - //CSEC_FREE_MEM_CHK_SET_NULL(*p_perm); - //CSEC_THR_RETURN(); - perm.resize(0); - } - i--; - } - else - { - perm[i+m_coln - m_rown] = max; - for(u32bit j=i+1;j<m_rown;j++)//fill the column downwards with 0's - { - if(coef(j,(max))) - { - row_xor(j,i);//check the arg. order. - } - } - - for(int j=i-1;j>=0;j--)//fill the column with 0's upwards too. - { - if(coef(j,(max))) - { - row_xor(j,i); - } - } - } - }//end for(i) - return perm; - } - - -} // end namespace Botan diff --git a/src/lib/pubkey/mce/binary_matrix.h b/src/lib/pubkey/mce/binary_matrix.h deleted file mode 100644 index feb44632f..000000000 --- a/src/lib/pubkey/mce/binary_matrix.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * (C) Copyright Projet SECRET, INRIA, Rocquencourt - * (C) Bhaskar Biswas and Nicolas Sendrier - * - * (C) 2014 cryptosource GmbH - * (C) 2014 Falko Strenzke [email protected] - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#ifndef BOTAN_BINARY_MATRIX_H__ -#define BOTAN_BINARY_MATRIX_H__ - -#include <botan/secmem.h> - -namespace Botan { - -#define BITS_PER_U32 (8 * sizeof (u32bit)) - -struct binary_matrix - { - public: - binary_matrix(u32bit m_rown, u32bit m_coln); - - void row_xor(u32bit a, u32bit b); - secure_vector<int> row_reduced_echelon_form(); - - /** - * return the coefficient out of F_2 - */ - u32bit coef(u32bit i, u32bit j) - { - return (m_elem[(i) * m_rwdcnt + (j) / BITS_PER_U32] >> (j % BITS_PER_U32)) & 1; - }; - - void set_coef_to_one(u32bit i, u32bit j) - { - m_elem[(i) * m_rwdcnt + (j) / BITS_PER_U32] |= (1UL << ((j) % BITS_PER_U32)) ; - }; - - void toggle_coeff(u32bit i, u32bit j) - { - m_elem[(i) * m_rwdcnt + (j) / BITS_PER_U32] ^= (1UL << ((j) % BITS_PER_U32)) ; - } - - void set_to_zero() - { - zeroise(m_elem); - } - - u32bit m_rown; // number of rows. - u32bit m_coln; // number of columns. - u32bit m_rwdcnt; // number of words in a row - std::vector<u32bit> m_elem; - }; - -} - -#endif diff --git a/src/lib/pubkey/mce/code_based_key_gen.cpp b/src/lib/pubkey/mce/code_based_key_gen.cpp index a3749abef..44b1cb4d6 100644 --- a/src/lib/pubkey/mce/code_based_key_gen.cpp +++ b/src/lib/pubkey/mce/code_based_key_gen.cpp @@ -9,26 +9,139 @@ * */ -#include <botan/internal/code_based_key_gen.h> -#include <botan/code_based_util.h> -#include <botan/gf2m_rootfind_dcmp.h> -#include <botan/internal/binary_matrix.h> +#include <botan/mceliece.h> +#include <botan/internal/code_based_util.h> #include <botan/loadstor.h> -#include <botan/polyn_gf2m.h> namespace Botan { namespace { +struct binary_matrix + { + public: + binary_matrix(u32bit m_rown, u32bit m_coln); + + void row_xor(u32bit a, u32bit b); + secure_vector<int> row_reduced_echelon_form(); + + /** + * return the coefficient out of F_2 + */ + u32bit coef(u32bit i, u32bit j) + { + return (m_elem[(i) * m_rwdcnt + (j) / 32] >> (j % 32)) & 1; + }; + + void set_coef_to_one(u32bit i, u32bit j) + { + m_elem[(i) * m_rwdcnt + (j) / 32] |= (static_cast<u32bit>(1) << ((j) % 32)) ; + }; + + void toggle_coeff(u32bit i, u32bit j) + { + m_elem[(i) * m_rwdcnt + (j) / 32] ^= (static_cast<u32bit>(1) << ((j) % 32)) ; + } + + void set_to_zero() + { + zeroise(m_elem); + } + + //private: + u32bit m_rown; // number of rows. + u32bit m_coln; // number of columns. + u32bit m_rwdcnt; // number of words in a row + std::vector<u32bit> m_elem; + }; + +binary_matrix::binary_matrix (u32bit rown, u32bit coln) + { + m_coln = coln; + m_rown = rown; + m_rwdcnt = 1 + ((m_coln - 1) / 32); + m_elem = std::vector<u32bit>(m_rown * m_rwdcnt); + } + +void binary_matrix::row_xor(u32bit a, u32bit b) + { + u32bit i; + for(i=0;i<m_rwdcnt;i++) + { + m_elem[a*m_rwdcnt+i]^=m_elem[b*m_rwdcnt+i]; + } + } + +//the matrix is reduced from LSB...(from right) +secure_vector<int> binary_matrix::row_reduced_echelon_form() + { + u32bit i, failcnt, findrow, max=m_coln - 1; + + secure_vector<int> perm(m_coln); + for(i=0;i<m_coln;i++) + { + perm[i]=i;//initialize permutation. + } + failcnt = 0; + + for(i=0;i<m_rown;i++,max--) + { + findrow=0; + for(u32bit j=i;j<m_rown;j++) + { + if(coef(j,max)) + { + if (i!=j)//not needed as ith row is 0 and jth row is 1. + row_xor(i,j);//xor to the row.(swap)? + findrow=1; + break; + }//largest value found (end if) + } + + if(!findrow)//if no row with a 1 found then swap last column and the column with no 1 down. + { + perm[m_coln - m_rown - 1 - failcnt] = max; + failcnt++; + if (!max) + { + //CSEC_FREE_MEM_CHK_SET_NULL(*p_perm); + //CSEC_THR_RETURN(); + perm.resize(0); + } + i--; + } + else + { + perm[i+m_coln - m_rown] = max; + for(u32bit j=i+1;j<m_rown;j++)//fill the column downwards with 0's + { + if(coef(j,(max))) + { + row_xor(j,i);//check the arg. order. + } + } + + for(int j=i-1;j>=0;j--)//fill the column with 0's upwards too. + { + if(coef(j,(max))) + { + row_xor(j,i); + } + } + } + }//end for(i) + return perm; + } + void randomize_support(u32bit n, std::vector<gf2m> & L, RandomNumberGenerator & rng) { unsigned int i, j; - gf2m_small_m::gf2m tmp; + gf2m tmp; for (i = 0; i < n; ++i) { - gf2m_small_m::gf2m rnd; + gf2m rnd; rng.randomize(reinterpret_cast<byte*>(&rnd), sizeof(rnd)); j = rnd % n; // no rejection sampling, but for useful code-based parameters with n <= 13 this seem tolerable @@ -38,14 +151,14 @@ void randomize_support(u32bit n, std::vector<gf2m> & L, RandomNumberGenerator & } } -std::unique_ptr<binary_matrix> generate_R(std::vector<gf2m> &L, polyn_gf2m* g, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field, u32bit code_length, u32bit t ) +std::unique_ptr<binary_matrix> generate_R(std::vector<gf2m> &L, polyn_gf2m* g, std::shared_ptr<GF2m_Field> sp_field, u32bit code_length, u32bit t ) { //L- Support //t- Number of errors //n- Length of the Goppa code //m- The extension degree of the GF //g- The generator polynomial. - gf2m_small_m::gf2m x,y; + gf2m x,y; u32bit i,j,k,r,n; std::vector<int> Laux(code_length); n=code_length; @@ -112,7 +225,7 @@ McEliece_PrivateKey generate_mceliece_key( RandomNumberGenerator & rng, u32bit e { throw Invalid_Argument("invalid McEliece parameters"); } - std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field ( new Gf2m_Field(ext_deg )); + std::shared_ptr<GF2m_Field> sp_field ( new GF2m_Field(ext_deg )); //pick the support......... std::vector<gf2m> L(code_length); diff --git a/src/lib/pubkey/mce/code_based_key_gen.h b/src/lib/pubkey/mce/code_based_key_gen.h deleted file mode 100644 index 6764e13d6..000000000 --- a/src/lib/pubkey/mce/code_based_key_gen.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * (C) Copyright Projet SECRET, INRIA, Rocquencourt - * (C) Bhaskar Biswas and Nicolas Sendrier - * - * (C) 2014 cryptosource GmbH - * (C) 2014 Falko Strenzke [email protected] - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#ifndef BOTAN_CODE_BASED_KEY_GEN_H__ -#define BOTAN_CODE_BASED_KEY_GEN_H__ - -#include <botan/mceliece_key.h> - -namespace Botan { - -McEliece_PrivateKey generate_mceliece_key(RandomNumberGenerator &rng, - u32bit ext_deg, - u32bit code_length, - u32bit t); - -} - -#endif diff --git a/src/lib/pubkey/mce/code_based_util.h b/src/lib/pubkey/mce/code_based_util.h index 6b567dbff..a959ad0d3 100644 --- a/src/lib/pubkey/mce/code_based_util.h +++ b/src/lib/pubkey/mce/code_based_util.h @@ -13,6 +13,7 @@ #define BOTAN_CODE_BASED_UTIL_H__ #include <botan/gf2m_small_m.h> +#include <stdexcept> namespace Botan { @@ -28,18 +29,18 @@ u16bit expand_mask_16bit(T tst) return ~(result - 1); } -inline gf2m_small_m::gf2m gray_to_lex(gf2m_small_m::gf2m gray) +inline gf2m gray_to_lex(gf2m gray) { - gf2m_small_m::gf2m result = gray ^ (gray>>8); + gf2m result = gray ^ (gray >> 8); result ^= (result >> 4); result ^= (result >> 2); result ^= (result >> 1); return result; } -inline gf2m_small_m::gf2m lex_to_gray(gf2m_small_m::gf2m lex) +inline gf2m lex_to_gray(gf2m lex) { - return (lex>>1) ^ lex; + return (lex >> 1) ^ lex; } inline u32bit bit_size_to_byte_size(u32bit bit_size) diff --git a/src/lib/pubkey/mce/gf2m_rootfind_dcmp.cpp b/src/lib/pubkey/mce/gf2m_rootfind_dcmp.cpp index 2d4f06130..d23d05172 100644 --- a/src/lib/pubkey/mce/gf2m_rootfind_dcmp.cpp +++ b/src/lib/pubkey/mce/gf2m_rootfind_dcmp.cpp @@ -6,314 +6,307 @@ * */ -#include <botan/gf2m_rootfind_dcmp.h> -#include <botan/gf2m_small_m.h> +#include <botan/polyn_gf2m.h> #include <botan/internal/bit_ops.h> -#include <botan/code_based_util.h> +#include <botan/internal/code_based_util.h> -namespace Botan -{ +namespace Botan { namespace { - u32bit patch_root_array( - gf2m* res_root_arr, - u32bit res_root_arr_len, - u32bit root_pos) - { - volatile u32bit i; - volatile gf2m patch_elem = 0x01; - volatile gf2m cond_mask = (root_pos == res_root_arr_len); - cond_mask = expand_mask_16bit(cond_mask); - cond_mask = ~cond_mask; /* now cond = 1 if not enough roots */ - patch_elem &= cond_mask; - for(i = 0; i < res_root_arr_len; i++) - { +u32bit patch_root_array(gf2m* res_root_arr, + u32bit res_root_arr_len, + u32bit root_pos) + { + volatile u32bit i; + volatile gf2m patch_elem = 0x01; + volatile gf2m cond_mask = (root_pos == res_root_arr_len); + cond_mask = expand_mask_16bit(cond_mask); + cond_mask = ~cond_mask; /* now cond = 1 if not enough roots */ + patch_elem &= cond_mask; + for(i = 0; i < res_root_arr_len; i++) + { gf2m masked_patch_elem = (patch_elem++) & cond_mask; res_root_arr[i] ^= masked_patch_elem++; - } - return res_root_arr_len; - } - -struct gf2m_decomp_rootfind_state -{ - gf2m_decomp_rootfind_state(const polyn_gf2m & p_polyn, u32bit code_length); - - void calc_LiK(const polyn_gf2m & sigma); - gf2m calc_Fxj_j_neq_0( const polyn_gf2m & sigma, gf2m j_gray); - void calc_next_Aij(); - void calc_Ai_zero(const polyn_gf2m & sigma); - secure_vector<gf2m> find_roots(const polyn_gf2m & sigma); - u32bit get_code_length() const { return code_length; }; - u32bit code_length; - secure_vector<gf2m> m_Lik; // size is outer_summands * m - secure_vector<gf2m> m_Aij; // ... - u32bit m_outer_summands; - gf2m m_j; - gf2m m_j_gray; - gf2m m_sigma_3_l; - gf2m m_sigma_3_neq_0_mask; -} ; - + } + return res_root_arr_len; + } + +class gf2m_decomp_rootfind_state + { + public: + gf2m_decomp_rootfind_state(const polyn_gf2m & p_polyn, u32bit code_length); + + void calc_LiK(const polyn_gf2m & sigma); + gf2m calc_Fxj_j_neq_0( const polyn_gf2m & sigma, gf2m j_gray); + void calc_next_Aij(); + void calc_Ai_zero(const polyn_gf2m & sigma); + secure_vector<gf2m> find_roots(const polyn_gf2m & sigma); + u32bit get_code_length() const { return code_length; }; + u32bit code_length; + secure_vector<gf2m> m_Lik; // size is outer_summands * m + secure_vector<gf2m> m_Aij; // ... + u32bit m_outer_summands; + gf2m m_j; + gf2m m_j_gray; + gf2m m_sigma_3_l; + gf2m m_sigma_3_neq_0_mask; + }; /* - * !! Attention: assumes gf2m is 16bit !! - */ +* !! Attention: assumes gf2m is 16bit !! +*/ #if 0 gf2m brootf_decomp__gray_to_lex(gf2m gray) -{ - static_assert(sizeof(gf2m) == 2, "Expected size"); - gf2m result = gray ^ (gray>>8); - result ^= (result >> 4); - result ^= (result >> 2); - result ^= (result >> 1); - return result; -} + { + static_assert(sizeof(gf2m) == 2, "Expected size"); + gf2m result = gray ^ (gray>>8); + result ^= (result >> 4); + result ^= (result >> 2); + result ^= (result >> 1); + return result; + } #endif /** - * calculates ceil((t-4)/5) = outer_summands - 1 - */ +* calculates ceil((t-4)/5) = outer_summands - 1 +*/ u32bit brootf_decomp__calc_sum_limit(u32bit t) -{ - u32bit result; - if(t < 4) - { - return 0; - } - result = t - 4; - result += 4; - result /= 5; - return result; -} + { + u32bit result; + if(t < 4) + { + return 0; + } + result = t - 4; + result += 4; + result /= 5; + return result; + } + } secure_vector<gf2m> find_roots_gf2m_decomp(const polyn_gf2m & polyn, u32bit code_length) -{ - gf2m_decomp_rootfind_state state(polyn, code_length); - return state.find_roots(polyn); - -} + { + gf2m_decomp_rootfind_state state(polyn, code_length); + return state.find_roots(polyn); + } + +gf2m_decomp_rootfind_state::gf2m_decomp_rootfind_state(const polyn_gf2m & polyn, u32bit the_code_length) : + code_length(the_code_length) + { + gf2m coeff_3; + gf2m coeff_head; + std::shared_ptr<GF2m_Field> sp_field = polyn.get_sp_field(); + int deg_sigma = polyn.get_degree(); + if(deg_sigma <= 3) + { + throw std::exception(); + } + this->m_j = 0; + coeff_3 = polyn.get_coef( 3); + coeff_head = polyn.get_coef( deg_sigma); /* dummy value for SCA CM */ + if(coeff_3 != 0) + { + this->m_sigma_3_l = sp_field->gf_l_from_n(coeff_3); + this->m_sigma_3_neq_0_mask = 0xFFFF; + } + else + { + // dummy value needed for timing countermeasure + this->m_sigma_3_l = sp_field->gf_l_from_n(coeff_head); + this->m_sigma_3_neq_0_mask = 0 ; + } -gf2m_decomp_rootfind_state::gf2m_decomp_rootfind_state(const polyn_gf2m & polyn, u32bit the_code_length) - :code_length(the_code_length) -{ - - gf2m coeff_3; - gf2m coeff_head; - std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field = polyn.get_sp_field(); - int deg_sigma = polyn.get_degree(); - if(deg_sigma <= 3) - { - throw std::exception(); - } - this->m_j = 0; - coeff_3 = polyn.get_coef( 3); - coeff_head = polyn.get_coef( deg_sigma); /* dummy value for SCA CM */ - if(coeff_3 != 0) - { - this->m_sigma_3_l = sp_field->gf_l_from_n(coeff_3); - this->m_sigma_3_neq_0_mask = 0xFFFF; - } - else - { - // dummy value needed for timing countermeasure - this->m_sigma_3_l = sp_field->gf_l_from_n(coeff_head); - this->m_sigma_3_neq_0_mask = 0 ; - } - - this->m_outer_summands = 1 + brootf_decomp__calc_sum_limit(deg_sigma); - this->m_Lik.resize(this->m_outer_summands * sp_field->get_extension_degree()); - this->m_Aij.resize(this->m_outer_summands); -} + this->m_outer_summands = 1 + brootf_decomp__calc_sum_limit(deg_sigma); + this->m_Lik.resize(this->m_outer_summands * sp_field->get_extension_degree()); + this->m_Aij.resize(this->m_outer_summands); + } void gf2m_decomp_rootfind_state::calc_Ai_zero(const polyn_gf2m & sigma) -{ - u32bit i; - /* + { + u32bit i; + /* * this function assumes this the first gray code element is zero */ - for(i = 0; i < this->m_outer_summands; i++) - { - this->m_Aij[i] = sigma.get_coef(5*i); - } - this->m_j = 0; - this->m_j_gray = 0; -} + for(i = 0; i < this->m_outer_summands; i++) + { + this->m_Aij[i] = sigma.get_coef(5*i); + } + this->m_j = 0; + this->m_j_gray = 0; + } void gf2m_decomp_rootfind_state::calc_next_Aij() -{ - /* + { + /* * upon function entry, we have in the state j, Aij. * first thing, we declare Aij Aij_minusone and increase j. * Case j=0 upon function entry also included, then Aij contains A_{i,j=0}. */ - u32bit i; - gf2m diff, new_j_gray; - u32bit Lik_pos_base; - - this->m_j++; - - new_j_gray = lex_to_gray(this->m_j); - - if(this->m_j & 1) /* half of the times */ - { - Lik_pos_base = 0; - } - else if(this->m_j & 2) /* one quarter of the times */ - { - Lik_pos_base = this->m_outer_summands; - } - else if( this->m_j & 4) /* one eighth of the times */ - { - Lik_pos_base = this->m_outer_summands * 2; - } - else if( this->m_j & 8) /* one sixteenth of the times */ - { - Lik_pos_base = this->m_outer_summands * 3; - } - else if( this->m_j & 16) /* ... */ - { - Lik_pos_base = this->m_outer_summands * 4; - } - else - { - gf2m delta_offs = 5; - diff = this->m_j_gray ^ new_j_gray; - while(((static_cast<gf2m>(1) << delta_offs) & diff) == 0) - { - delta_offs++; - - } - Lik_pos_base = delta_offs * this->m_outer_summands; - } - this->m_j_gray = new_j_gray; - - i = 0; - for(; i < this->m_outer_summands; i++) - { - this->m_Aij[i] ^= this->m_Lik[Lik_pos_base + i]; - } + u32bit i; + gf2m diff, new_j_gray; + u32bit Lik_pos_base; + + this->m_j++; + + new_j_gray = lex_to_gray(this->m_j); + + if(this->m_j & 1) /* half of the times */ + { + Lik_pos_base = 0; + } + else if(this->m_j & 2) /* one quarter of the times */ + { + Lik_pos_base = this->m_outer_summands; + } + else if( this->m_j & 4) /* one eighth of the times */ + { + Lik_pos_base = this->m_outer_summands * 2; + } + else if( this->m_j & 8) /* one sixteenth of the times */ + { + Lik_pos_base = this->m_outer_summands * 3; + } + else if( this->m_j & 16) /* ... */ + { + Lik_pos_base = this->m_outer_summands * 4; + } + else + { + gf2m delta_offs = 5; + diff = this->m_j_gray ^ new_j_gray; + while(((static_cast<gf2m>(1) << delta_offs) & diff) == 0) + { + delta_offs++; + + } + Lik_pos_base = delta_offs * this->m_outer_summands; + } + this->m_j_gray = new_j_gray; + + i = 0; + for(; i < this->m_outer_summands; i++) + { + this->m_Aij[i] ^= this->m_Lik[Lik_pos_base + i]; + } + + } -} void gf2m_decomp_rootfind_state::calc_LiK(const polyn_gf2m & sigma) -{ - std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field = sigma.get_sp_field(); - u32bit i, k, d; - d = sigma.get_degree(); - for(k = 0; k < sp_field->get_extension_degree(); k++) - { - u32bit Lik_pos_base = k * this->m_outer_summands; - gf2m alpha_l_k_tt2_ttj[4]; - alpha_l_k_tt2_ttj[0] = sp_field->gf_l_from_n(static_cast<gf2m>(1) << k); - alpha_l_k_tt2_ttj[1] = sp_field->gf_mul_rrr(alpha_l_k_tt2_ttj[0], alpha_l_k_tt2_ttj[0]); - alpha_l_k_tt2_ttj[2] = sp_field->gf_mul_rrr(alpha_l_k_tt2_ttj[1],alpha_l_k_tt2_ttj[1] ); - - alpha_l_k_tt2_ttj[3] = sp_field->gf_mul_rrr(alpha_l_k_tt2_ttj[2], alpha_l_k_tt2_ttj[2]); - for(i = 0; i < this->m_outer_summands; i++) - { - u32bit j; - u32bit five_i = 5*i; - u32bit Lik_pos = Lik_pos_base + i; - this->m_Lik[Lik_pos] = 0; - for(j = 0; j <= 3; j++) + { + std::shared_ptr<GF2m_Field> sp_field = sigma.get_sp_field(); + u32bit i, k, d; + d = sigma.get_degree(); + for(k = 0; k < sp_field->get_extension_degree(); k++) { - gf2m f, x; - u32bit f_ind = five_i + (static_cast<u32bit>(1) << j); - if(f_ind > d) - { - break; - } - f = sigma.get_coef( f_ind); - - x = sp_field->gf_mul_zrz(alpha_l_k_tt2_ttj[j], f); - this->m_Lik[Lik_pos] ^= x; + u32bit Lik_pos_base = k * this->m_outer_summands; + gf2m alpha_l_k_tt2_ttj[4]; + alpha_l_k_tt2_ttj[0] = sp_field->gf_l_from_n(static_cast<gf2m>(1) << k); + alpha_l_k_tt2_ttj[1] = sp_field->gf_mul_rrr(alpha_l_k_tt2_ttj[0], alpha_l_k_tt2_ttj[0]); + alpha_l_k_tt2_ttj[2] = sp_field->gf_mul_rrr(alpha_l_k_tt2_ttj[1],alpha_l_k_tt2_ttj[1] ); + + alpha_l_k_tt2_ttj[3] = sp_field->gf_mul_rrr(alpha_l_k_tt2_ttj[2], alpha_l_k_tt2_ttj[2]); + for(i = 0; i < this->m_outer_summands; i++) + { + u32bit j; + u32bit five_i = 5*i; + u32bit Lik_pos = Lik_pos_base + i; + this->m_Lik[Lik_pos] = 0; + for(j = 0; j <= 3; j++) + { + gf2m f, x; + u32bit f_ind = five_i + (static_cast<u32bit>(1) << j); + if(f_ind > d) + { + break; + } + f = sigma.get_coef( f_ind); + + x = sp_field->gf_mul_zrz(alpha_l_k_tt2_ttj[j], f); + this->m_Lik[Lik_pos] ^= x; + } + } } - } - } -} + } gf2m gf2m_decomp_rootfind_state::calc_Fxj_j_neq_0( const polyn_gf2m & sigma, gf2m j_gray) -{ - //needs the A_{ij} to compute F(x)_j - gf2m sum = 0; - u32bit i; - std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field = sigma.get_sp_field(); - gf2m xl_j_tt_5i, xl_j_tt_5, xl_gray_tt_3; - gf2m jl_gray; - jl_gray = sp_field->gf_l_from_n(j_gray); - xl_j_tt_5 = sp_field->gf_square_rr(jl_gray); - xl_gray_tt_3 = sp_field->gf_mul_rrr(xl_j_tt_5, jl_gray); - xl_j_tt_5 = sp_field->gf_mul_rrr(xl_j_tt_5, xl_gray_tt_3); - - - sum = sp_field->gf_mul_nrr(xl_gray_tt_3, this->m_sigma_3_l); - sum &= this->m_sigma_3_neq_0_mask; - /* here, we rely on compiler to be unable to optimize + { + //needs the A_{ij} to compute F(x)_j + gf2m sum = 0; + u32bit i; + std::shared_ptr<GF2m_Field> sp_field = sigma.get_sp_field(); + gf2m xl_j_tt_5i, xl_j_tt_5, xl_gray_tt_3; + const gf2m jl_gray = sp_field->gf_l_from_n(j_gray); + xl_j_tt_5 = sp_field->gf_square_rr(jl_gray); + xl_gray_tt_3 = sp_field->gf_mul_rrr(xl_j_tt_5, jl_gray); + xl_j_tt_5 = sp_field->gf_mul_rrr(xl_j_tt_5, xl_gray_tt_3); + + + sum = sp_field->gf_mul_nrr(xl_gray_tt_3, this->m_sigma_3_l); + sum &= this->m_sigma_3_neq_0_mask; + /* here, we rely on compiler to be unable to optimize * for the state->sigma_3_neq_0_mask value */ - /* treat i = 0 special: */ - sum ^= this->m_Aij[0]; - /* treat i = 1 special also */ - if(this->m_outer_summands > 1) - { - gf2m x; - xl_j_tt_5i = xl_j_tt_5; - x = sp_field->gf_mul_zrz(xl_j_tt_5, this->m_Aij[1]); /* x_j^{5i} A_i^j */ - sum ^= x; - } - for(i = 2; i < this->m_outer_summands; i++) - { - gf2m x; - xl_j_tt_5i = sp_field->gf_mul_rrr(xl_j_tt_5i, xl_j_tt_5); - // now x_j_tt_5i lives up to its name - x = sp_field->gf_mul_zrz(xl_j_tt_5i, this->m_Aij[i]); /* x_j^{5i} A_i^(j) */ - sum ^= x; - } - return sum; -} - + /* treat i = 0 special: */ + sum ^= this->m_Aij[0]; + /* treat i = 1 special also */ + if(this->m_outer_summands > 1) + { + gf2m x; + xl_j_tt_5i = xl_j_tt_5; + x = sp_field->gf_mul_zrz(xl_j_tt_5, this->m_Aij[1]); /* x_j^{5i} A_i^j */ + sum ^= x; + } + for(i = 2; i < this->m_outer_summands; i++) + { + gf2m x; + xl_j_tt_5i = sp_field->gf_mul_rrr(xl_j_tt_5i, xl_j_tt_5); + // now x_j_tt_5i lives up to its name + x = sp_field->gf_mul_zrz(xl_j_tt_5i, this->m_Aij[i]); /* x_j^{5i} A_i^(j) */ + sum ^= x; + } + return sum; + } +secure_vector<gf2m> gf2m_decomp_rootfind_state::find_roots(const polyn_gf2m & sigma) + { + secure_vector<gf2m> result(sigma.get_degree()); + u32bit root_pos = 0; + this->calc_Ai_zero(sigma); + this->calc_LiK(sigma); + do + { + gf2m eval_result; + if(this->m_j_gray == 0) + { + eval_result = sigma.get_coef( 0); + } + else + { + eval_result = this->calc_Fxj_j_neq_0(sigma, this->m_j_gray); + } + + if(eval_result == 0) + { + + result[root_pos] = this->m_j_gray; + root_pos++; + + } + if(this->m_j + static_cast<u32bit>(1) == this->get_code_length()) + { + break; + } + this->calc_next_Aij(); + }while(1); + + // side channel / fault attack countermeasure: + root_pos = patch_root_array(result.data(), result.size(), root_pos); + result.resize(root_pos); + return result; + } -secure_vector<gf2m> gf2m_decomp_rootfind_state::find_roots(const polyn_gf2m & sigma) -{ - - secure_vector<gf2m> result(sigma.get_degree()); - u32bit root_pos = 0; - - this->calc_Ai_zero(sigma); - this->calc_LiK(sigma); - do - { - gf2m eval_result; - if(this->m_j_gray == 0) - { - eval_result = sigma.get_coef( 0); - } - else - { - eval_result = this->calc_Fxj_j_neq_0(sigma, this->m_j_gray); - } - - if(eval_result == 0) - { - - result[root_pos] = this->m_j_gray; - root_pos++; - - } - if(this->m_j + static_cast<u32bit>(1) == this->get_code_length()) - { - break; - } - this->calc_next_Aij(); - }while(1); - - // side channel / fault attack countermeasure: - root_pos = patch_root_array(result.data(), result.size(), root_pos); - result.resize(root_pos); - return result; -} } // end namespace Botan diff --git a/src/lib/pubkey/mce/gf2m_rootfind_dcmp.h b/src/lib/pubkey/mce/gf2m_rootfind_dcmp.h deleted file mode 100644 index 5914ad3ae..000000000 --- a/src/lib/pubkey/mce/gf2m_rootfind_dcmp.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * (C) 2014 cryptosource GmbH - * (C) 2014 Falko Strenzke [email protected] - * - * Botan is released under the Simplified BSD License (see license.txt) - */ - -#ifndef BOTAN_GF2M_ROOTFIND_DCMP_H__ -#define BOTAN_GF2M_ROOTFIND_DCMP_H__ - -#include <botan/polyn_gf2m.h> - -namespace Botan { - -/** -* Find the roots of a polynomial over GF(2^m) using the method by Federenko -* et al. -*/ -secure_vector<gf2m> find_roots_gf2m_decomp(const polyn_gf2m & polyn, - u32bit code_length); - -} - -#endif diff --git a/src/lib/pubkey/mce/gf2m_small_m.cpp b/src/lib/pubkey/mce/gf2m_small_m.cpp index 3de748939..11da30962 100644 --- a/src/lib/pubkey/mce/gf2m_small_m.cpp +++ b/src/lib/pubkey/mce/gf2m_small_m.cpp @@ -9,14 +9,11 @@ */ #include <botan/gf2m_small_m.h> -#include <botan/code_based_util.h> #include <string> #include <stdexcept> namespace Botan { -namespace gf2m_small_m { - #define MAX_EXT_DEG 16 namespace { @@ -41,78 +38,94 @@ unsigned int prim_poly[MAX_EXT_DEG + 1] = { 0210013 /* extension degree 16 */ }; -} - -u32bit encode_gf2m(gf2m to_enc, byte* mem) +std::vector<gf2m> gf_exp_table(size_t deg, gf2m prime_poly) { - mem[0] = to_enc >> 8; - mem[1] = to_enc & 0xFF; - return sizeof(to_enc); + // construct the table gf_exp[i]=alpha^i + + std::vector<gf2m> tab((1 << deg) + 1); + + tab[0] = 1; + for(size_t i = 1; i < tab.size(); ++i) + { + const bool overflow = tab[i - 1] >> (deg - 1); + tab[i] = (tab[i-1] << 1) ^ (overflow ? prime_poly : 0); + } + + return tab; } -gf2m decode_gf2m(const byte* mem) +const std::vector<gf2m>& exp_table(size_t deg) { - gf2m result; - result = mem[0] << 8; - result |= mem[1]; - return result; + static std::vector<gf2m> tabs[MAX_EXT_DEG + 1]; + + if(deg < 2 || deg > MAX_EXT_DEG) + throw std::runtime_error("GF2m_Field does not support degree " + std::to_string(deg)); + + if(tabs[deg].empty()) + tabs[deg] = gf_exp_table(deg, prim_poly[deg]); + + return tabs[deg]; } -// construct the table gf_exp[i]=alpha^i -void Gf2m_Field::init_exp() +std::vector<gf2m> gf_log_table(size_t deg, const std::vector<gf2m>& exp) { - m_gf_exp_table.resize(1 << get_extension_degree()); + std::vector<gf2m> tab(1 << deg); - m_gf_exp_table[0] = 1; - for(size_t i = 1; i < gf_ord(); ++i) + tab[0] = (1 << deg) - 1; // log of 0 is the order by convention + for (size_t i = 0; i < tab.size(); ++i) { - m_gf_exp_table[i] = m_gf_exp_table[i - 1] << 1; - if (m_gf_exp_table[i - 1] & (1 << (get_extension_degree()-1))) - { - m_gf_exp_table[i] ^= prim_poly[get_extension_degree()]; - } + tab[exp[i]] = i; } - - // hack for the multiplication - m_gf_exp_table[gf_ord()] = 1; + return tab; } -// construct the table gf_log[alpha^i]=i -void Gf2m_Field::init_log() +const std::vector<gf2m>& log_table(size_t deg) { - m_gf_log_table.resize(1 << get_extension_degree()); + static std::vector<gf2m> tabs[MAX_EXT_DEG + 1]; - m_gf_log_table[0] = gf_ord(); // log of 0 par convention - for (size_t i = 0; i < gf_ord() ; ++i) - { - m_gf_log_table[m_gf_exp_table[i]] = i; - } + if(deg < 2 || deg > MAX_EXT_DEG) + throw std::runtime_error("GF2m_Field does not support degree " + std::to_string(deg)); + + if(tabs[deg].empty()) + tabs[deg] = gf_log_table(deg, exp_table(deg)); + + return tabs[deg]; } +} -Gf2m_Field::Gf2m_Field(size_t extdeg) +u32bit encode_gf2m(gf2m to_enc, byte* mem) { - if(extdeg < 2 || extdeg > MAX_EXT_DEG) - throw std::runtime_error("Gf2m_Field does not support degree " + std::to_string(extdeg)); + mem[0] = to_enc >> 8; + mem[1] = to_enc & 0xFF; + return sizeof(to_enc); + } - m_gf_extension_degree = extdeg; - m_gf_cardinality = 1 << extdeg; - m_gf_multiplicative_order = m_gf_cardinality - 1; +gf2m decode_gf2m(const byte* mem) + { + gf2m result; + result = mem[0] << 8; + result |= mem[1]; + return result; + } - init_exp(); - init_log(); +GF2m_Field::GF2m_Field(size_t extdeg) : m_gf_extension_degree(extdeg), + m_gf_multiplicative_order((1 << extdeg) - 1), + m_gf_log_table(log_table(m_gf_extension_degree)), + m_gf_exp_table(exp_table(m_gf_extension_degree)) + { } -gf2m Gf2m_Field::gf_div(gf2m x, gf2m y) +gf2m GF2m_Field::gf_div(gf2m x, gf2m y) const { - s32bit sub_res = static_cast<s32bit>(m_gf_log_table[x]) - static_cast<s32bit>( m_gf_log_table[y]); - s32bit modq_res = static_cast<s32bit>(_gf_modq_1(sub_res)); - s32bit div_res = static_cast<s32bit>(x) ? static_cast<s32bit>(m_gf_exp_table[modq_res]) : 0; + const s32bit sub_res = static_cast<s32bit>(gf_log(x) - static_cast<s32bit>(gf_log(y))); + const s32bit modq_res = static_cast<s32bit>(_gf_modq_1(sub_res)); + const s32bit div_res = static_cast<s32bit>(x) ? static_cast<s32bit>(gf_exp(modq_res)) : 0; return static_cast<gf2m>(div_res); } // we suppose i >= 0. Par convention 0^0 = 1 -gf2m Gf2m_Field::gf_pow(gf2m x, int i) +gf2m GF2m_Field::gf_pow(gf2m x, int i) const { if (i == 0) return 1; @@ -123,13 +136,11 @@ gf2m Gf2m_Field::gf_pow(gf2m x, int i) // i mod (q-1) while (i >> get_extension_degree()) i = (i & (gf_ord())) + (i >> get_extension_degree()); - i *= m_gf_log_table[x]; + i *= gf_log(x); while (i >> get_extension_degree()) i = (i & (gf_ord())) + (i >> get_extension_degree()); - return m_gf_exp_table[i]; + return gf_exp(i); } } } - -} diff --git a/src/lib/pubkey/mce/gf2m_small_m.h b/src/lib/pubkey/mce/gf2m_small_m.h index 223dfd511..6a8de4424 100644 --- a/src/lib/pubkey/mce/gf2m_small_m.h +++ b/src/lib/pubkey/mce/gf2m_small_m.h @@ -17,213 +17,199 @@ namespace Botan { -namespace gf2m_small_m { - typedef u16bit gf2m; -class Gf2m_Field +/** +* GF(2^m) field for m = [2...16] +*/ +class BOTAN_DLL GF2m_Field { public: - Gf2m_Field(size_t extdeg); + GF2m_Field(size_t extdeg); - gf2m gf_mul(gf2m x, gf2m y) + gf2m gf_mul(gf2m x, gf2m y) const { return ((x) ? gf_mul_fast(x, y) : 0); } - gf2m gf_square(gf2m x) + gf2m gf_square(gf2m x) const { - return ((x) ? m_gf_exp_table[_gf_modq_1(m_gf_log_table[x] << 1)] : 0); + return ((x) ? gf_exp(_gf_modq_1(gf_log(x) << 1)) : 0); } - gf2m square_rr(gf2m x) + gf2m square_rr(gf2m x) const { return _gf_modq_1(x << 1); } - // naming convention of GF(2^m) field operations: - // l logarithmic, unreduced - // r logarithmic, reduced - // n normal, non-zero - // z normal, might be zero - // - inline gf2m gf_mul_lll(gf2m a, gf2m b); - inline gf2m gf_mul_rrr(gf2m a, gf2m b); - inline gf2m gf_mul_nrr(gf2m a, gf2m b); - inline gf2m gf_mul_rrn(gf2m a, gf2m y); - inline gf2m gf_mul_lnn(gf2m x, gf2m y); - inline gf2m gf_mul_rnn(gf2m x, gf2m y); - inline gf2m gf_mul_nrn(gf2m a, gf2m y); - inline gf2m gf_mul_rnr(gf2m y, gf2m a); - inline gf2m gf_mul_zrz(gf2m a, gf2m y); - inline gf2m gf_mul_zzr(gf2m a, gf2m y); - inline gf2m gf_mul_nnr(gf2m y, gf2m a); - inline gf2m gf_sqrt(gf2m x) ; - gf2m gf_div(gf2m x, gf2m y); - inline gf2m gf_div_rnn(gf2m x, gf2m y); - inline gf2m gf_div_rnr(gf2m x, gf2m b); - inline gf2m gf_div_nrr(gf2m a, gf2m b); - inline gf2m gf_div_zzr(gf2m x, gf2m b); - inline gf2m gf_inv(gf2m x); - inline gf2m gf_inv_rn(gf2m x); - inline gf2m gf_square_ln(gf2m x); - inline gf2m gf_square_rr(gf2m a) ; - inline gf2m gf_l_from_n(gf2m x); + gf2m gf_mul_fast(gf2m x, gf2m y) const + { + return ((y) ? gf_exp(_gf_modq_1(gf_log(x) + gf_log(y))) : 0); + } - inline gf2m gf_mul_fast(gf2m a, gf2m b); + /* + naming convention of GF(2^m) field operations: + l logarithmic, unreduced + r logarithmic, reduced + n normal, non-zero + z normal, might be zero + */ - gf2m gf_exp(gf2m i) + gf2m gf_mul_lll(gf2m a, gf2m b) const { - return m_gf_exp_table[i]; /* alpha^i */ + return (a + b); } - gf2m gf_log(gf2m i) + gf2m gf_mul_rrr(gf2m a, gf2m b) const { - return m_gf_log_table[i]; /* return i when x=alpha^i */ + return (_gf_modq_1(gf_mul_lll(a, b))); } - inline gf2m gf_ord() const + gf2m gf_mul_nrr(gf2m a, gf2m b) const { - return m_gf_multiplicative_order; + return (gf_exp(gf_mul_rrr(a, b))); } - inline gf2m get_extension_degree() const + gf2m gf_mul_rrn(gf2m a, gf2m y) const { - return m_gf_extension_degree; + return _gf_modq_1(gf_mul_lll(a, gf_log(y))); } - inline gf2m get_cardinality() const + gf2m gf_mul_rnr(gf2m y, gf2m a) const { - return m_gf_cardinality; + return gf_mul_rrn(a, y); } - gf2m gf_pow(gf2m x, int i) ; + gf2m gf_mul_lnn(gf2m x, gf2m y) const + { + return (gf_log(x) + gf_log(y)); + } - private: - gf2m m_gf_extension_degree, m_gf_cardinality, m_gf_multiplicative_order; - std::vector<gf2m> m_gf_log_table; - std::vector<gf2m> m_gf_exp_table; + gf2m gf_mul_rnn(gf2m x, gf2m y) const + { + return _gf_modq_1(gf_mul_lnn(x, y)); + } - inline gf2m _gf_modq_1(s32bit d); - void init_log(); - void init_exp(); - }; + gf2m gf_mul_nrn(gf2m a, gf2m y) const + { + return gf_exp(_gf_modq_1((a) + gf_log(y))); + } -gf2m Gf2m_Field::_gf_modq_1(s32bit d) - { - return (((d) & gf_ord()) + ((d) >> m_gf_extension_degree)); - } + /** + * zero operand allowed + */ + gf2m gf_mul_zrz(gf2m a, gf2m y) const + { + return ( (y == 0) ? 0 : gf_mul_nrn(a, y) ); + } -gf2m Gf2m_Field::gf_mul_fast(gf2m x, gf2m y) - { - return ((y) ? m_gf_exp_table[_gf_modq_1(m_gf_log_table[x] + m_gf_log_table[y])] : 0); - } + gf2m gf_mul_zzr(gf2m a, gf2m y) const + { + return gf_mul_zrz(y, a); + } -gf2m Gf2m_Field::gf_mul_lll(gf2m a, gf2m b) - { - return (a + b); - } + /** + * non-zero operand + */ + gf2m gf_mul_nnr(gf2m y, gf2m a) const + { + return gf_mul_nrn(a, y); + } -gf2m Gf2m_Field::gf_mul_rrr(gf2m a, gf2m b) - { - return (_gf_modq_1(gf_mul_lll(a, b))); - } + gf2m gf_sqrt(gf2m x) const + { + return ((x) ? gf_exp(_gf_modq_1(gf_log(x) << (get_extension_degree()-1))) : 0); + } -gf2m Gf2m_Field::gf_mul_nrr(gf2m a, gf2m b) - { - return (gf_exp(gf_mul_rrr(a, b))); - } + gf2m gf_div_rnn(gf2m x, gf2m y) const + { + return _gf_modq_1(gf_log(x) - gf_log(y)); + } -gf2m Gf2m_Field::gf_mul_rrn(gf2m a, gf2m y) - { - return _gf_modq_1(gf_mul_lll(a, gf_log(y))); - } + gf2m gf_div_rnr(gf2m x, gf2m b) const + { + return _gf_modq_1(gf_log(x) - b); + } -gf2m Gf2m_Field::gf_mul_rnr(gf2m y, gf2m a) - { - return gf_mul_rrn(a, y); - } + gf2m gf_div_nrr(gf2m a, gf2m b) const + { + return gf_exp(_gf_modq_1(a - b)); + } -gf2m Gf2m_Field::gf_mul_lnn(gf2m x, gf2m y) - { - return (m_gf_log_table[x] + m_gf_log_table[y]); - } -gf2m Gf2m_Field::gf_mul_rnn(gf2m x, gf2m y) - { - return _gf_modq_1(gf_mul_lnn(x, y)); - } + gf2m gf_div_zzr(gf2m x, gf2m b) const + { + return ((x) ? gf_exp(_gf_modq_1(gf_log(x) - b)) : 0); + } -gf2m Gf2m_Field::gf_mul_nrn(gf2m a, gf2m y) - { - return m_gf_exp_table[_gf_modq_1((a) + m_gf_log_table[y])]; - } + gf2m gf_inv(gf2m x) const + { + return gf_exp(gf_ord() - gf_log(x)); + } -/** -* zero operand allowed -*/ -gf2m Gf2m_Field::gf_mul_zrz(gf2m a, gf2m y) - { - return ( (y == 0) ? 0 : gf_mul_nrn(a, y) ); - } + gf2m gf_inv_rn(gf2m x) const + { + return (gf_ord() - gf_log(x)); + } -gf2m Gf2m_Field::gf_mul_zzr(gf2m a, gf2m y) - { - return gf_mul_zrz(y, a); - } -/** -* non-zero operand -*/ -gf2m Gf2m_Field::gf_mul_nnr(gf2m y, gf2m a) - { - return gf_mul_nrn( a, y); - } + gf2m gf_square_ln(gf2m x) const + { + return gf_log(x) << 1; + } -gf2m Gf2m_Field::gf_sqrt(gf2m x) - { - return ((x) ? m_gf_exp_table[_gf_modq_1(m_gf_log_table[x] << (m_gf_extension_degree-1))] : 0); - } + gf2m gf_square_rr(gf2m a) const + { + return a << 1; + } -gf2m Gf2m_Field::gf_div_rnn(gf2m x, gf2m y) - { - return _gf_modq_1(m_gf_log_table[x] - m_gf_log_table[y]); - } -gf2m Gf2m_Field::gf_div_rnr(gf2m x, gf2m b) - { - return _gf_modq_1(m_gf_log_table[x] - b); - } -gf2m Gf2m_Field::gf_div_nrr(gf2m a, gf2m b) - { - return m_gf_exp_table[_gf_modq_1(a - b)]; - } + gf2m gf_l_from_n(gf2m x) const + { + return gf_log(x); + } -gf2m Gf2m_Field::gf_div_zzr(gf2m x, gf2m b) - { - return ((x) ? m_gf_exp_table[_gf_modq_1(m_gf_log_table[x] - b)] : 0); - } + gf2m gf_div(gf2m x, gf2m y) const; -gf2m Gf2m_Field::gf_inv(gf2m x) - { - return m_gf_exp_table[gf_ord() - m_gf_log_table[x]]; - } -gf2m Gf2m_Field::gf_inv_rn(gf2m x) - { - return (gf_ord() - m_gf_log_table[x]); - } + gf2m gf_pow(gf2m x, int i) const; -gf2m Gf2m_Field::gf_square_ln(gf2m x) - { - return m_gf_log_table[x] << 1; - } + gf2m gf_exp(gf2m i) const + { + return m_gf_exp_table.at(i); /* alpha^i */ + } -gf2m Gf2m_Field::gf_square_rr(gf2m a) - { - return a << 1; - } + gf2m gf_log(gf2m i) const + { + return m_gf_log_table.at(i); /* return i when x=alpha^i */ + } -gf2m Gf2m_Field::gf_l_from_n(gf2m x) - { - return m_gf_log_table[x]; - } + gf2m gf_ord() const + { + return m_gf_multiplicative_order; + } + + gf2m get_extension_degree() const + { + return m_gf_extension_degree; + } + + gf2m get_cardinality() const + { + return static_cast<gf2m>(1 << get_extension_degree()); + } + + private: + gf2m _gf_modq_1(s32bit d) const + { + /* residual modulo q-1 + when -q < d < 0, we get (q-1+d) + when 0 <= d < q, we get (d) + when q <= d < 2q-1, we get (d-q+1) + */ + return (((d) & gf_ord()) + ((d) >> get_extension_degree())); + } + + gf2m m_gf_extension_degree, m_gf_multiplicative_order; + const std::vector<gf2m>& m_gf_log_table; + const std::vector<gf2m>& m_gf_exp_table; + }; u32bit encode_gf2m(gf2m to_enc, byte* mem); @@ -231,6 +217,4 @@ gf2m decode_gf2m(const byte* mem); } -} - #endif diff --git a/src/lib/pubkey/mce/goppa_code.cpp b/src/lib/pubkey/mce/goppa_code.cpp index 175508eac..637b8175a 100644 --- a/src/lib/pubkey/mce/goppa_code.cpp +++ b/src/lib/pubkey/mce/goppa_code.cpp @@ -9,10 +9,8 @@ * */ -#include <botan/goppa_code.h> - -#include <botan/gf2m_rootfind_dcmp.h> -#include <botan/code_based_util.h> +#include <botan/internal/mce_internal.h> +#include <botan/internal/code_based_util.h> namespace Botan { @@ -48,7 +46,7 @@ secure_vector<gf2m> goppa_decode(const polyn_gf2m & syndrom_polyn, u32bit code_length = Linv.size(); u32bit t = g.get_degree(); - std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field = g.get_sp_field(); + std::shared_ptr<GF2m_Field> sp_field = g.get_sp_field(); std::pair<polyn_gf2m, polyn_gf2m> h__aux = polyn_gf2m::eea_with_coefficients( syndrom_polyn, g, 1); polyn_gf2m & h = h__aux.first; @@ -125,6 +123,37 @@ secure_vector<gf2m> goppa_decode(const polyn_gf2m & syndrom_polyn, } } +void mceliece_decrypt(secure_vector<byte>& plaintext_out, + secure_vector<byte>& error_mask_out, + const secure_vector<byte>& ciphertext, + const McEliece_PrivateKey& key) + { + mceliece_decrypt(plaintext_out, error_mask_out, ciphertext.data(), ciphertext.size(), key); + } + +void mceliece_decrypt( + secure_vector<byte>& plaintext, + secure_vector<byte> & error_mask, + const byte ciphertext[], + size_t ciphertext_len, + const McEliece_PrivateKey & key) + { + secure_vector<gf2m> error_pos; + plaintext = mceliece_decrypt(error_pos, ciphertext, ciphertext_len, key); + + const size_t code_length = key.get_code_length(); + secure_vector<byte> result((code_length+7)/8); + for(auto&& pos : error_pos) + { + if(pos > code_length) + { + throw std::invalid_argument("error position larger than code size"); + } + result[pos / 8] |= (1 << (pos % 8)); + } + + error_mask = result; + } /** * @param p_err_pos_len must point to the available length of err_pos on input, the @@ -154,30 +183,27 @@ secure_vector<byte> mceliece_decrypt( throw Invalid_Argument("mce-decryption: wrong length of cleartext buffer"); } - secure_vector<u32bit> syndrome_vec(bit_size_to_32bit_size(codimension)); - matrix_arr_mul( - key.get_H_coeffs(), - key.get_code_length(), - bit_size_to_32bit_size(codimension), - ciphertext, - syndrome_vec.data(), syndrome_vec.size() ); + matrix_arr_mul(key.get_H_coeffs(), + key.get_code_length(), + bit_size_to_32bit_size(codimension), + ciphertext, + syndrome_vec.data(), syndrome_vec.size()); + secure_vector<byte> syndrome_byte_vec(bit_size_to_byte_size(codimension)); u32bit syndrome_byte_vec_size = syndrome_byte_vec.size(); for(u32bit i = 0; i < syndrome_byte_vec_size; i++) { syndrome_byte_vec[i] = syndrome_vec[i/4] >> (8* (i % 4)); } - syndrome_polyn = polyn_gf2m(t-1, syndrome_byte_vec.data(), bit_size_to_byte_size(codimension), key.get_goppa_polyn().get_sp_field()); - + syndrome_polyn = polyn_gf2m(t-1, syndrome_byte_vec.data(), bit_size_to_byte_size(codimension), key.get_goppa_polyn().get_sp_field()); syndrome_polyn.get_degree(); error_pos = goppa_decode(syndrome_polyn, key.get_goppa_polyn(), key.get_sqrtmod(), key.get_Linv()); u32bit nb_err = error_pos.size(); - secure_vector<byte> cleartext(cleartext_len); copy_mem(cleartext.data(), ciphertext, cleartext_len); @@ -192,6 +218,7 @@ secure_vector<byte> mceliece_decrypt( } cleartext[current / 8] ^= (1 << (current % 8)); } + if(unused_pt_bits) { cleartext[cleartext_len - 1] &= unused_pt_bits_mask; diff --git a/src/lib/pubkey/mce/goppa_code.h b/src/lib/pubkey/mce/goppa_code.h deleted file mode 100644 index 377cd9b3d..000000000 --- a/src/lib/pubkey/mce/goppa_code.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * (C) Copyright Projet SECRET, INRIA, Rocquencourt - * (C) Bhaskar Biswas and Nicolas Sendrier - * - * (C) 2014 cryptosource GmbH - * (C) 2014 Falko Strenzke [email protected] - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#ifndef BOTAN_MCE_GOPPA_CODE_H__ -#define BOTAN_MCE_GOPPA_CODE_H__ - -#include <botan/polyn_gf2m.h> -#include <botan/mceliece_key.h> - -namespace Botan { - -std::vector<byte> mceliece_encrypt(const secure_vector<byte>& cleartext, - const std::vector<byte>& public_matrix, - const secure_vector<gf2m> & err_pos, - u32bit code_length); - -secure_vector<byte> mceliece_decrypt(secure_vector<gf2m> & error_pos, - const byte *ciphertext, - u32bit ciphertext_len, - const McEliece_PrivateKey& key); - -} - -#endif diff --git a/src/lib/pubkey/mce/info.txt b/src/lib/pubkey/mce/info.txt index c06e23b8e..1e9b848dd 100644 --- a/src/lib/pubkey/mce/info.txt +++ b/src/lib/pubkey/mce/info.txt @@ -1,17 +1,17 @@ -define MCELIECE 20141124 +define MCELIECE 20150922 <header:public> -code_based_util.h -gf2m_rootfind_dcmp.h -gf2m_small_m.h -goppa_code.h mce_kem.h mceliece.h -mceliece_key.h polyn_gf2m.h +gf2m_small_m.h </header:public> <header:internal> -binary_matrix.h -code_based_key_gen.h +code_based_util.h +mce_internal.h </header:internal> + +<requires> +sha2_64 +</requires> diff --git a/src/lib/pubkey/mce/mce_internal.h b/src/lib/pubkey/mce/mce_internal.h new file mode 100644 index 000000000..d35479080 --- /dev/null +++ b/src/lib/pubkey/mce/mce_internal.h @@ -0,0 +1,52 @@ +/** + * (C) Copyright Projet SECRET, INRIA, Rocquencourt + * (C) Bhaskar Biswas and Nicolas Sendrier + * + * (C) 2014 cryptosource GmbH + * (C) 2014 Falko Strenzke [email protected] + * + * Botan is released under the Simplified BSD License (see license.txt) + * + */ + +#ifndef BOTAN_MCELIECE_INTERNAL_H__ +#define BOTAN_MCELIECE_INTERNAL_H__ + +#include <botan/secmem.h> +#include <botan/types.h> +#include <botan/pk_ops.h> +#include <botan/mceliece.h> + +namespace Botan { + +void mceliece_decrypt(secure_vector<byte>& plaintext_out, + secure_vector<byte>& error_mask_out, + const byte ciphertext[], + size_t ciphertext_len, + const McEliece_PrivateKey& key); + +void mceliece_decrypt(secure_vector<byte>& plaintext_out, + secure_vector<byte>& error_mask_out, + const secure_vector<byte>& ciphertext, + const McEliece_PrivateKey& key); + +secure_vector<byte> mceliece_decrypt( + secure_vector<gf2m> & error_pos, + const byte *ciphertext, u32bit ciphertext_len, + const McEliece_PrivateKey & key); + +void mceliece_encrypt(secure_vector<byte>& ciphertext_out, + secure_vector<byte>& error_mask_out, + const secure_vector<byte>& plaintext, + const McEliece_PublicKey& key, + RandomNumberGenerator& rng); + +McEliece_PrivateKey generate_mceliece_key(RandomNumberGenerator &rng, + u32bit ext_deg, + u32bit code_length, + u32bit t); + +} + + +#endif diff --git a/src/lib/pubkey/mce/mce_kem.cpp b/src/lib/pubkey/mce/mce_kem.cpp index b24c42f85..dede67731 100644 --- a/src/lib/pubkey/mce/mce_kem.cpp +++ b/src/lib/pubkey/mce/mce_kem.cpp @@ -7,56 +7,42 @@ */ #include <botan/mce_kem.h> +#include <botan/internal/mce_internal.h> #include <botan/sha2_64.h> namespace Botan { McEliece_KEM_Encryptor::McEliece_KEM_Encryptor(const McEliece_PublicKey& public_key) : - m_raw_pub_op(public_key, public_key.get_code_length()) + m_key(public_key) { } std::pair<secure_vector<byte>, secure_vector<byte>> McEliece_KEM_Encryptor::encrypt(RandomNumberGenerator& rng) { - const McEliece_PublicKey& key = m_raw_pub_op.get_key(); - secure_vector<Botan::byte> plaintext((key.get_message_word_bit_length()+7)/8); - rng.randomize(plaintext.data(), plaintext.size()); + const secure_vector<byte> plaintext = m_key.random_plaintext_element(rng); - // unset unused bits in the last plaintext byte - u32bit used = key.get_message_word_bit_length() % 8; - if(used) - { - byte mask = (1 << used) - 1; - plaintext[plaintext.size() - 1] &= mask; - } - - secure_vector<gf2m> err_pos = create_random_error_positions(key.get_code_length(), key.get_t(), rng); - - mceliece_message_parts parts(err_pos, plaintext, key.get_code_length()); - secure_vector<Botan::byte> message_and_error_input = parts.get_concat(); + secure_vector<byte> ciphertext, error_mask; + mceliece_encrypt(ciphertext, error_mask, plaintext, m_key, rng); SHA_512 hash; - hash.update(message_and_error_input); + hash.update(plaintext); + hash.update(error_mask); secure_vector<byte> sym_key = hash.final(); - secure_vector<byte> ciphertext = m_raw_pub_op.encrypt(message_and_error_input.data(), - message_and_error_input.size(), rng); return std::make_pair(ciphertext, sym_key); } - -McEliece_KEM_Decryptor::McEliece_KEM_Decryptor(const McEliece_PrivateKey& mce_key) : - m_raw_priv_op(mce_key) - { - } +McEliece_KEM_Decryptor::McEliece_KEM_Decryptor(const McEliece_PrivateKey& key) : m_key(key) { } secure_vector<Botan::byte> McEliece_KEM_Decryptor::decrypt(const byte msg[], size_t msg_len) { - secure_vector<Botan::byte> message_and_error = m_raw_priv_op.decrypt(msg, msg_len); + secure_vector<byte> plaintext, error_mask; + mceliece_decrypt(plaintext, error_mask, msg, msg_len, m_key); SHA_512 hash; - hash.update(message_and_error); + hash.update(plaintext); + hash.update(error_mask); secure_vector<byte> sym_key = hash.final(); return sym_key; diff --git a/src/lib/pubkey/mce/mce_kem.h b/src/lib/pubkey/mce/mce_kem.h index 7a8d2f7ff..cd899d568 100644 --- a/src/lib/pubkey/mce/mce_kem.h +++ b/src/lib/pubkey/mce/mce_kem.h @@ -25,7 +25,7 @@ class BOTAN_DLL McEliece_KEM_Encryptor std::pair<secure_vector<byte>, secure_vector<byte>> encrypt(RandomNumberGenerator& rng); private: - McEliece_Public_Operation m_raw_pub_op; + const McEliece_PublicKey& m_key; }; class BOTAN_DLL McEliece_KEM_Decryptor @@ -45,10 +45,10 @@ class BOTAN_DLL McEliece_KEM_Decryptor secure_vector<Botan::byte> decrypt_vec(const std::vector<byte, Alloc>& v) { return decrypt(v.data(), v.size()); - } + private: - McEliece_Private_Operation m_raw_priv_op; + const McEliece_PrivateKey& m_key; }; } diff --git a/src/lib/pubkey/mce/mceliece.cpp b/src/lib/pubkey/mce/mceliece.cpp index 6bbe93ce3..dd05b8212 100644 --- a/src/lib/pubkey/mce/mceliece.cpp +++ b/src/lib/pubkey/mce/mceliece.cpp @@ -9,165 +9,127 @@ * */ +#include <botan/internal/mce_internal.h> #include <botan/mceliece.h> -#include <botan/mceliece_key.h> -#include <botan/internal/code_based_key_gen.h> -#include <botan/polyn_gf2m.h> -#include <botan/code_based_util.h> -#include <botan/goppa_code.h> +#include <botan/internal/code_based_util.h> #include <botan/internal/bit_ops.h> -#include <botan/internal/xor_buf.h> +#include <set> namespace Botan { namespace { -void concat_vectors(byte* x, const byte* a, const byte* b, u32bit dimension, u32bit codimension) +secure_vector<byte> concat_vectors(const secure_vector<byte>& a, const secure_vector<byte>& b, + u32bit dimension, u32bit codimension) { - if(dimension % 8 == 0) + secure_vector<byte> x(bit_size_to_byte_size(dimension) + bit_size_to_byte_size(codimension)); + + const size_t final_bits = dimension % 8; + + if(final_bits == 0) { const size_t dim_bytes = bit_size_to_byte_size(dimension); - copy_mem(x, a, dim_bytes); - copy_mem(x + dim_bytes, b, bit_size_to_byte_size(codimension)); + copy_mem(&x[0], a.data(), dim_bytes); + copy_mem(&x[dim_bytes], b.data(), bit_size_to_byte_size(codimension)); } else { - u32bit i, j, k, l; - i = dimension - 8 * (dimension/ 8); - j = 8 - i; - l = dimension / 8; - copy_mem(x, a, 1 * (dimension / 8)); - x[l] = static_cast<byte>(a[l] & ((1 << i) - 1)); - - for(k = 0; k < codimension / 8; ++k) + copy_mem(&x[0], a.data(), (dimension / 8)); + u32bit l = dimension / 8; + x[l] = static_cast<byte>(a[l] & ((1 << final_bits) - 1)); + + for(u32bit k = 0; k < codimension / 8; ++k) { - x[l] ^= static_cast<byte>(b[k] << i); + x[l] ^= static_cast<byte>(b[k] << final_bits); ++l; - x[l] = static_cast<byte>(b[k] >> j); + x[l] = static_cast<byte>(b[k] >> (8 - final_bits)); } - x[l] ^= static_cast<byte>(b[k] << i); + x[l] ^= static_cast<byte>(b[codimension/8] << final_bits); } + + return x; } -std::vector<byte> mult_by_pubkey(const byte *cleartext, - std::vector<byte> const& public_matrix, - u32bit code_length, u32bit t) +secure_vector<byte> mult_by_pubkey(const secure_vector<byte>& cleartext, + std::vector<byte> const& public_matrix, + u32bit code_length, u32bit t) { - std::vector<byte> ciphertext(code_length); - u32bit i, j; - u32bit ext_deg = ceil_log2(code_length); - u32bit codimension = ext_deg * t; - u32bit dimension = code_length - codimension; - std::vector<byte> cR(bit_size_to_32bit_size(codimension)* sizeof(u32bit)); + const u32bit ext_deg = ceil_log2(code_length); + const u32bit codimension = ext_deg * t; + const u32bit dimension = code_length - codimension; + secure_vector<byte> cR(bit_size_to_32bit_size(codimension) * sizeof(u32bit)); const byte* pt = public_matrix.data(); - for(i = 0; i < dimension / 8; ++i) + for(size_t i = 0; i < dimension / 8; ++i) { - for(j = 0; j < 8; ++j) + for(size_t j = 0; j < 8; ++j) { if(cleartext[i] & (1 << j)) { xor_buf(cR.data(), pt, cR.size()); } - pt += bit_size_to_32bit_size(codimension) * sizeof(u32bit); + pt += cR.size(); } } - for(j = 0; j < dimension % 8 ; ++j) + for(size_t i = 0; i < dimension % 8 ; ++i) { - if(cleartext[i] & (1 << j)) + if(cleartext[dimension/8] & (1 << i)) { - xor_buf(cR.data(), pt, bit_size_to_byte_size(codimension)); + xor_buf(cR.data(), pt, cR.size()); } - pt += bit_size_to_32bit_size(codimension) * sizeof(u32bit); + pt += cR.size(); } - concat_vectors(ciphertext.data(), cleartext, cR.data(), dimension, codimension); + secure_vector<byte> ciphertext = concat_vectors(cleartext, cR, dimension, codimension); + ciphertext.resize((code_length+7)/8); return ciphertext; } -} - -secure_vector<gf2m> create_random_error_positions(unsigned code_length, - unsigned error_weight, - RandomNumberGenerator& rng) - { - secure_vector<gf2m> result(error_weight); - gf2m i; - for(i = 0; i < result.size(); i++) - { - unsigned j; - char try_again = 0; - do - { - try_again = 0; - gf2m new_pos = random_code_element(code_length, rng); - for(j = 0; j < i; j++) - { - if(new_pos == result[j]) - { - try_again = 1; - break; - } - } - result[i] = new_pos; - } while(try_again); - } - return result; - } - -McEliece_Private_Operation::McEliece_Private_Operation(const McEliece_PrivateKey& private_key) - :m_priv_key(private_key) +secure_vector<byte> create_random_error_vector(unsigned code_length, + unsigned error_weight, + RandomNumberGenerator& rng) { - } - -secure_vector<byte> McEliece_Private_Operation::decrypt(const byte msg[], size_t msg_len) - { - secure_vector<gf2m> err_pos; + secure_vector<byte> result((code_length+7)/8); - secure_vector<byte> plaintext = mceliece_decrypt( - err_pos, - msg, msg_len, - m_priv_key - ); + size_t bits_set = 0; - return mceliece_message_parts(err_pos, plaintext, m_priv_key.get_code_length()).get_concat(); - } + while(bits_set < error_weight) + { + gf2m x = random_code_element(code_length, rng); -McEliece_Public_Operation::McEliece_Public_Operation(const McEliece_PublicKey& public_key, u32bit the_code_length) - :m_pub_key(public_key), - m_code_length(the_code_length) - {} + const size_t byte_pos = x / 8, bit_pos = x % 8; -secure_vector<byte> McEliece_Public_Operation::encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&) - { - mceliece_message_parts parts(msg, msg_len, m_pub_key.get_code_length()); - secure_vector<gf2m> err_pos = parts.get_error_positions(); - secure_vector<byte> message_word = parts.get_message_word(); - secure_vector<byte> ciphertext((m_pub_key.get_code_length()+7)/8); + const byte mask = (1 << bit_pos); + if(result[byte_pos] & mask) + continue; // already set this bit - std::vector<byte> ciphertext_tmp = mceliece_encrypt( message_word, m_pub_key.get_public_matrix(), err_pos, m_code_length); + result[byte_pos] |= mask; + bits_set++; + } - copy_mem(ciphertext.data(), ciphertext_tmp.data(), ciphertext.size()); - return ciphertext; + return result; } -std::vector<byte> mceliece_encrypt(const secure_vector<byte> & cleartext, - std::vector<byte> const& public_matrix, - const secure_vector<gf2m> & err_pos, - u32bit code_length) +} + +void mceliece_encrypt(secure_vector<byte>& ciphertext_out, + secure_vector<byte>& error_mask_out, + const secure_vector<byte>& plaintext, + const McEliece_PublicKey& key, + RandomNumberGenerator& rng) { - std::vector<byte> ciphertext = mult_by_pubkey(cleartext.data(), public_matrix, code_length, err_pos.size()); + secure_vector<byte> error_mask = create_random_error_vector(key.get_code_length(), key.get_t(), rng); - // flip t error positions - for(size_t i = 0; i < err_pos.size(); ++i) - { - ciphertext[err_pos[i] / 8] ^= (1 << (err_pos[i] % 8)); - } + secure_vector<byte> ciphertext = mult_by_pubkey(plaintext, key.get_public_matrix(), + key.get_code_length(), key.get_t()); - return ciphertext; + ciphertext ^= error_mask; + + ciphertext_out.swap(ciphertext); + error_mask_out.swap(error_mask); } } diff --git a/src/lib/pubkey/mce/mceliece.h b/src/lib/pubkey/mce/mceliece.h index c5f02470f..ead326230 100644 --- a/src/lib/pubkey/mce/mceliece.h +++ b/src/lib/pubkey/mce/mceliece.h @@ -9,141 +9,128 @@ * */ -#ifndef BOTAN_MCELIECE_H__ -#define BOTAN_MCELIECE_H__ +#ifndef BOTAN_MCELIECE_KEY_H__ +#define BOTAN_MCELIECE_KEY_H__ -#include <botan/secmem.h> -#include <botan/types.h> -#include <botan/pk_ops.h> -#include <botan/mceliece_key.h> - -#define MASK_LOG2_BYTE ((1 << 3) - 1) -#define _BITP_TO_BYTEP(__bit_pos) (__bit_pos >> 3) -#define _BITP_TO_BYTEOFFS(__bit_pos) (__bit_pos & MASK_LOG2_BYTE) +#include <botan/pk_keys.h> +#include <botan/polyn_gf2m.h> +#include <botan/exceptn.h> namespace Botan { -secure_vector<gf2m> BOTAN_DLL create_random_error_positions(unsigned code_length, unsigned error_weight, RandomNumberGenerator& rng); - -class mceliece_message_parts +class BOTAN_DLL McEliece_PublicKey : public virtual Public_Key { public: + McEliece_PublicKey(const std::vector<byte>& key_bits); - mceliece_message_parts(const secure_vector<gf2m>& err_pos, const byte* message, u32bit message_length, u32bit code_length) : - m_error_vector(error_vector_from_error_positions(err_pos.data(), err_pos.size(), code_length)), - m_code_length(code_length) - { - m_message_word.resize(message_length); - copy_mem(m_message_word.data(), message, message_length); - } - - mceliece_message_parts(const secure_vector<gf2m>& err_pos, const secure_vector<byte>& message, unsigned code_length) : - m_error_vector(error_vector_from_error_positions(err_pos.data(), err_pos.size(), code_length)), - m_message_word(message), - m_code_length(code_length) - {} - - static secure_vector<byte> error_vector_from_error_positions(const gf2m* err_pos, size_t err_pos_len, size_t code_length) - { - secure_vector<byte> result((code_length+7)/8); - for(unsigned i = 0; i < err_pos_len; i++) - { - u16bit pos = err_pos[i]; - u32bit byte_pos = _BITP_TO_BYTEP(pos); - if(byte_pos > result.size()) - { - throw Invalid_Argument("error position larger than code size"); - } - result[byte_pos] |= (1 << _BITP_TO_BYTEOFFS(pos)); - } - return result; - } - - mceliece_message_parts(const byte* message_concat_errors, size_t message_concat_errors_len, unsigned code_length) : - m_code_length(code_length) - { - size_t err_vec_len = (code_length+7)/8; - if(message_concat_errors_len < err_vec_len ) - { - throw Invalid_Argument("cannot split McEliece message parts"); - } - size_t err_vec_start_pos = message_concat_errors_len - err_vec_len; - m_message_word = secure_vector<byte>(err_vec_start_pos); - copy_mem(m_message_word.data(), message_concat_errors, err_vec_start_pos); - m_error_vector = secure_vector<byte>(err_vec_len); - copy_mem(m_error_vector.data(), &message_concat_errors[err_vec_start_pos], err_vec_len); - } - - secure_vector<byte> get_concat() const - { - secure_vector<byte> result(m_error_vector.size() + m_message_word.size()); - copy_mem(result.data(), m_message_word.data(), m_message_word.size()); - copy_mem(&result[m_message_word.size()], m_error_vector.data(), m_error_vector.size()); - return result; - } - - secure_vector<gf2m> get_error_positions() const - { - secure_vector<gf2m> result; - for(unsigned i = 0; i < m_code_length; i++) - { - if(i >= m_code_length) - { - throw Invalid_Argument("index out of range in get_error_positions()"); - } - if((m_error_vector[_BITP_TO_BYTEP(i)] >> _BITP_TO_BYTEOFFS(i)) & 1) - { - result.push_back(i); - } - } - return result; - } - - secure_vector<byte> get_error_vector() const { return m_error_vector; } - secure_vector<byte> get_message_word() const { return m_message_word; } - private: - secure_vector<byte> m_error_vector; - secure_vector<byte> m_message_word; - unsigned m_code_length; - }; + McEliece_PublicKey(std::vector<byte> const& pub_matrix, u32bit the_t, u32bit the_code_length) : + m_public_matrix(pub_matrix), + m_t(the_t), + m_code_length(the_code_length) + {} -class BOTAN_DLL McEliece_Private_Operation : public PK_Ops::Decryption - { - public: - McEliece_Private_Operation(const McEliece_PrivateKey& mce_key); + McEliece_PublicKey(const McEliece_PublicKey& other); - size_t max_input_bits() const override { return m_priv_key.max_input_bits(); } + secure_vector<byte> random_plaintext_element(RandomNumberGenerator& rng) const; - secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override; + std::string algo_name() const override { return "McEliece"; } - McEliece_PrivateKey const& get_key() const { return m_priv_key; } + /** + * Get the maximum number of bits allowed to be fed to this key. + * @result the maximum number of input bits + */ + size_t max_input_bits() const override { return get_message_word_bit_length(); } - private: - const McEliece_PrivateKey m_priv_key; + AlgorithmIdentifier algorithm_identifier() const override; + + size_t estimated_strength() const override; + + std::vector<byte> x509_subject_public_key() const override; + + bool check_key(RandomNumberGenerator&, bool) const override + { return true; } + + u32bit get_t() const { return m_t; } + u32bit get_code_length() const { return m_code_length; } + u32bit get_message_word_bit_length() const; + const std::vector<byte>& get_public_matrix() const { return m_public_matrix; } + + bool operator==(const McEliece_PublicKey& other) const; + bool operator!=(const McEliece_PublicKey& other) const { return !(*this == other); } + + protected: + McEliece_PublicKey() {} + + std::vector<byte> m_public_matrix; + u32bit m_t; + u32bit m_code_length; }; -class BOTAN_DLL McEliece_Public_Operation : public PK_Ops::Encryption +class BOTAN_DLL McEliece_PrivateKey : public virtual McEliece_PublicKey, + public virtual Private_Key { public: - McEliece_Public_Operation(const McEliece_PublicKey& public_key, u32bit code_length); + /** + * Get the maximum number of bits allowed to be fed to this key. + * @result the maximum number of input bits + */ + size_t max_input_bits() const override { return m_Linv.size(); } + + /** + Generate a McEliece key pair + + Suggested parameters for a given security level (SL) + + SL=80 n=1632 t=33 - 59 KB pubkey 140 KB privkey + SL=107 n=2480 t=45 - 128 KB pubkey 300 KB privkey + SL=128 n=2960 t=57 - 195 KB pubkey 459 KB privkey + SL=147 n=3408 t=67 - 265 KB pubkey 622 KB privkey + SL=191 n=4624 t=95 - 516 KB pubkey 1234 KB privkey + SL=256 n=6624 t=115 - 942 KB pubkey 2184 KB privkey + */ + McEliece_PrivateKey(RandomNumberGenerator& rng, size_t code_length, size_t t); + + McEliece_PrivateKey(const secure_vector<byte>& key_bits); + + McEliece_PrivateKey(polyn_gf2m const& goppa_polyn, + std::vector<u32bit> const& parity_check_matrix_coeffs, + std::vector<polyn_gf2m> const& square_root_matrix, + std::vector<gf2m> const& inverse_support, + std::vector<byte> const& public_matrix ); + + bool check_key(RandomNumberGenerator& rng, bool strong) const override; - size_t max_input_bits() const override { return m_pub_key.max_input_bits(); } - secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&) override; + polyn_gf2m const& get_goppa_polyn() const { return m_g; } + std::vector<u32bit> const& get_H_coeffs() const { return m_coeffs; } + std::vector<gf2m> const& get_Linv() const { return m_Linv; } + std::vector<polyn_gf2m> const& get_sqrtmod() const { return m_sqrtmod; } - McEliece_PublicKey const& get_key() const { return m_pub_key; } + inline u32bit get_dimension() const { return m_dimension; } + + inline u32bit get_codimension() const { return m_codimension; } + + secure_vector<byte> pkcs8_private_key() const override; + + bool operator==(const McEliece_PrivateKey & other) const; + + bool operator!=(const McEliece_PrivateKey& other) const { return !(*this == other); } private: - McEliece_PublicKey m_pub_key; - u32bit m_code_length; + polyn_gf2m m_g; + std::vector<polyn_gf2m> m_sqrtmod; + std::vector<gf2m> m_Linv; + std::vector<u32bit> m_coeffs; + + u32bit m_codimension; + u32bit m_dimension; }; /** * Estimate work factor for McEliece * @return estimated security level for these key parameters */ -BOTAN_DLL size_t mceliece_work_factor(size_t code_size, size_t k, size_t t); +BOTAN_DLL size_t mceliece_work_factor(size_t code_size, size_t t); } - #endif diff --git a/src/lib/pubkey/mce/mceliece_key.cpp b/src/lib/pubkey/mce/mceliece_key.cpp index 8cda0af89..8edbbf88a 100644 --- a/src/lib/pubkey/mce/mceliece_key.cpp +++ b/src/lib/pubkey/mce/mceliece_key.cpp @@ -9,15 +9,12 @@ * */ -#include <botan/mceliece_key.h> -#include <botan/internal/bit_ops.h> -#include <botan/gf2m_small_m.h> #include <botan/mceliece.h> -#include <botan/internal/code_based_key_gen.h> -#include <botan/code_based_util.h> +#include <botan/internal/mce_internal.h> +#include <botan/internal/bit_ops.h> +#include <botan/internal/code_based_util.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> -#include <botan/workfactor.h> namespace Botan { @@ -42,12 +39,29 @@ McEliece_PrivateKey::McEliece_PrivateKey(RandomNumberGenerator& rng, size_t code *this = generate_mceliece_key(rng, ext_deg, code_length, t); } -unsigned McEliece_PublicKey::get_message_word_bit_length() const +u32bit McEliece_PublicKey::get_message_word_bit_length() const { u32bit codimension = ceil_log2(m_code_length) * m_t; return m_code_length - codimension; } +secure_vector<byte> McEliece_PublicKey::random_plaintext_element(RandomNumberGenerator& rng) const + { + const size_t bits = get_message_word_bit_length(); + + secure_vector<byte> plaintext((bits+7)/8); + rng.randomize(plaintext.data(), plaintext.size()); + + // unset unused bits in the last plaintext byte + if(u32bit used = bits % 8) + { + const byte mask = (1 << used) - 1; + plaintext[plaintext.size() - 1] &= mask; + } + + return plaintext; + } + AlgorithmIdentifier McEliece_PublicKey::algorithm_identifier() const { return AlgorithmIdentifier(get_oid(), std::vector<byte>()); @@ -55,16 +69,15 @@ AlgorithmIdentifier McEliece_PublicKey::algorithm_identifier() const std::vector<byte> McEliece_PublicKey::x509_subject_public_key() const { - // encode the public key - return unlock(DER_Encoder() - .start_cons(SEQUENCE) - .start_cons(SEQUENCE) - .encode(static_cast<size_t>(get_code_length())) - .encode(static_cast<size_t>(get_t())) - .end_cons() - .encode(m_public_matrix, OCTET_STRING) - .end_cons() - .get_contents()); + return DER_Encoder() + .start_cons(SEQUENCE) + .start_cons(SEQUENCE) + .encode(static_cast<size_t>(get_code_length())) + .encode(static_cast<size_t>(get_t())) + .end_cons() + .encode(m_public_matrix, OCTET_STRING) + .end_cons() + .get_contents_unlocked(); } McEliece_PublicKey::McEliece_PublicKey(const McEliece_PublicKey & other) : @@ -76,9 +89,7 @@ McEliece_PublicKey::McEliece_PublicKey(const McEliece_PublicKey & other) : size_t McEliece_PublicKey::estimated_strength() const { - const u32bit ext_deg = ceil_log2(m_code_length); - const size_t k = m_code_length - ext_deg * m_t; - return mceliece_work_factor(m_code_length, k, m_t); + return mceliece_work_factor(m_code_length, m_t); } McEliece_PublicKey::McEliece_PublicKey(const std::vector<byte>& key_bits) @@ -135,19 +146,20 @@ secure_vector<byte> McEliece_PrivateKey::pkcs8_private_key() const bool McEliece_PrivateKey::check_key(RandomNumberGenerator& rng, bool) const { - McEliece_Private_Operation priv_op(*this); - McEliece_Public_Operation pub_op(*this, get_code_length()); + const secure_vector<byte> plaintext = this->random_plaintext_element(rng); - secure_vector<byte> plaintext((this->get_message_word_bit_length()+7)/8); - rng.randomize(plaintext.data(), plaintext.size() - 1); - const secure_vector<gf2m> err_pos = create_random_error_positions(this->get_code_length(), this->get_t(), rng); + secure_vector<byte> ciphertext; + secure_vector<byte> errors; + mceliece_encrypt(ciphertext, errors, plaintext, *this, rng); - mceliece_message_parts parts(err_pos, plaintext, this->get_code_length()); - secure_vector<byte> message_and_error_input = parts.get_concat(); - secure_vector<byte> ciphertext = pub_op.encrypt(message_and_error_input.data(), message_and_error_input.size(), rng); - secure_vector<byte> message_and_error_output = priv_op.decrypt(ciphertext.data(), ciphertext.size()); + secure_vector<byte> plaintext_out; + secure_vector<byte> errors_out; + mceliece_decrypt(plaintext_out, errors_out, ciphertext, *this); - return (message_and_error_input == message_and_error_output); + if(errors != errors_out || plaintext != plaintext_out) + return false; + + return true; } McEliece_PrivateKey::McEliece_PrivateKey(const secure_vector<byte>& key_bits) @@ -172,7 +184,7 @@ McEliece_PrivateKey::McEliece_PrivateKey(const secure_vector<byte>& key_bits) m_codimension = (ext_deg * t); m_dimension = (n - m_codimension); - std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field(new gf2m_small_m::Gf2m_Field(ext_deg)); + std::shared_ptr<GF2m_Field> sp_field(new GF2m_Field(ext_deg)); m_g = polyn_gf2m(g_enc, sp_field); if(m_g.get_degree() != static_cast<int>(t)) { @@ -231,7 +243,6 @@ McEliece_PrivateKey::McEliece_PrivateKey(const secure_vector<byte>& key_bits) } - bool McEliece_PrivateKey::operator==(const McEliece_PrivateKey & other) const { if(*static_cast<const McEliece_PublicKey*>(this) != *static_cast<const McEliece_PublicKey*>(&other)) diff --git a/src/lib/pubkey/mce/mceliece_key.h b/src/lib/pubkey/mce/mceliece_key.h deleted file mode 100644 index 65ab04f16..000000000 --- a/src/lib/pubkey/mce/mceliece_key.h +++ /dev/null @@ -1,126 +0,0 @@ -/** - * (C) Copyright Projet SECRET, INRIA, Rocquencourt - * (C) Bhaskar Biswas and Nicolas Sendrier - * - * (C) 2014 cryptosource GmbH - * (C) 2014 Falko Strenzke [email protected] - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#ifndef BOTAN_MCELIECE_KEY_H__ -#define BOTAN_MCELIECE_KEY_H__ - -#include <botan/exceptn.h> -#include <botan/pk_keys.h> -#include <botan/polyn_gf2m.h> - -namespace Botan { - -class BOTAN_DLL McEliece_PublicKey : public virtual Public_Key - { - public: - - McEliece_PublicKey(const std::vector<byte>& key_bits); - - McEliece_PublicKey(std::vector<byte> const& pub_matrix, u32bit the_t, u32bit the_code_length) : - m_public_matrix(pub_matrix), - m_t(the_t), - m_code_length(the_code_length) - {} - - McEliece_PublicKey(const McEliece_PublicKey & other); - - std::string algo_name() const override { return "McEliece"; } - - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - * @result the maximum number of input bits - */ - size_t max_input_bits() const override - { - return get_message_word_bit_length(); - }; - - AlgorithmIdentifier algorithm_identifier() const override; - - size_t estimated_strength() const override; - - std::vector<byte> x509_subject_public_key() const override; - - bool check_key(RandomNumberGenerator&, bool) const override - { return true; } - - u32bit get_t() const { return m_t; } - u32bit get_code_length() const { return m_code_length; } - u32bit get_message_word_bit_length() const; - std::vector<byte> const& get_public_matrix() const { return m_public_matrix; } - - bool operator==(const McEliece_PublicKey& other) const; - bool operator!=(const McEliece_PublicKey& other) const { return !(*this == other); } - - protected: - McEliece_PublicKey() {} - - std::vector<byte> m_public_matrix; - u32bit m_t; - u32bit m_code_length; - }; - -class BOTAN_DLL McEliece_PrivateKey : public virtual McEliece_PublicKey, - public virtual Private_Key - { - public: - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - * @result the maximum number of input bits - */ - size_t max_input_bits() const override { - return m_Linv.size(); - }; - - McEliece_PrivateKey(const secure_vector<byte>& key_bits); - - McEliece_PrivateKey(polyn_gf2m const& goppa_polyn, - std::vector<u32bit> const& parity_check_matrix_coeffs, - std::vector<polyn_gf2m> const& square_root_matrix, - std::vector<gf2m> const& inverse_support, - std::vector<byte> const& public_matrix ); - - McEliece_PrivateKey(RandomNumberGenerator& rng, size_t code_length, size_t t); - bool check_key(RandomNumberGenerator& rng, bool strong) const override; - - polyn_gf2m const& get_goppa_polyn() const { return m_g; }; - std::vector<u32bit> const& get_H_coeffs() const { return m_coeffs; }; - std::vector<gf2m> const& get_Linv() const { return m_Linv; }; - std::vector<polyn_gf2m> const& get_sqrtmod() const { return m_sqrtmod; }; - - inline u32bit get_dimension() const - { return m_dimension; }; - - inline u32bit get_codimension() const - { return m_codimension; }; - - - secure_vector<byte> pkcs8_private_key() const override; - - bool operator==(const McEliece_PrivateKey & other) const; - - bool operator!=(const McEliece_PrivateKey& other) const { return !(*this == other); }; - - private: - polyn_gf2m m_g; - std::vector<polyn_gf2m> m_sqrtmod; - std::vector<gf2m> m_Linv; - std::vector<u32bit> m_coeffs; - - u32bit m_codimension; - u32bit m_dimension; - }; - -} - -#endif diff --git a/src/lib/pubkey/mce/polyn_gf2m.cpp b/src/lib/pubkey/mce/polyn_gf2m.cpp index 9b3366757..4d9bcf2e8 100644 --- a/src/lib/pubkey/mce/polyn_gf2m.cpp +++ b/src/lib/pubkey/mce/polyn_gf2m.cpp @@ -10,15 +10,13 @@ */ #include <botan/polyn_gf2m.h> -#include <botan/gf2m_rootfind_dcmp.h> -#include <botan/code_based_util.h> -#include <botan/gf2m_small_m.h> +#include <botan/internal/code_based_util.h> #include <botan/internal/bit_ops.h> +#include <botan/rng.h> +#include <botan/exceptn.h> namespace Botan { -using namespace Botan::gf2m_small_m; - namespace { gf2m generate_gf2m_mask(gf2m a) @@ -40,8 +38,6 @@ unsigned nlz_16bit(u16bit x) } } -using namespace Botan::gf2m_small_m; - int polyn_gf2m::calc_degree_secure() const { int i = this->coeff.size() - 1; @@ -86,7 +82,7 @@ polyn_gf2m::polyn_gf2m(polyn_gf2m const& other) msp_field(other.msp_field) { } -polyn_gf2m::polyn_gf2m( int d, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field) +polyn_gf2m::polyn_gf2m( int d, std::shared_ptr<GF2m_Field> sp_field) :m_deg(-1), coeff(d+1), msp_field(sp_field) @@ -115,7 +111,7 @@ void polyn_gf2m::realloc(u32bit new_size) this->coeff = secure_vector<gf2m>(new_size); } -polyn_gf2m::polyn_gf2m(const byte* mem, u32bit mem_len, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field) +polyn_gf2m::polyn_gf2m(const byte* mem, u32bit mem_len, std::shared_ptr<GF2m_Field> sp_field) :msp_field(sp_field) { if(mem_len % sizeof(gf2m)) @@ -128,7 +124,7 @@ polyn_gf2m::polyn_gf2m(const byte* mem, u32bit mem_len, std::shared_ptr<gf2m_sma this->m_deg = -1; for(u32bit i = 0; i < size; i++) { - this->coeff[i] = gf2m_small_m::decode_gf2m(mem); + this->coeff[i] = decode_gf2m(mem); mem += sizeof(this->coeff[0]); } for(u32bit i = 0; i < size; i++) @@ -142,13 +138,13 @@ polyn_gf2m::polyn_gf2m(const byte* mem, u32bit mem_len, std::shared_ptr<gf2m_sma } -polyn_gf2m::polyn_gf2m( std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field ) +polyn_gf2m::polyn_gf2m( std::shared_ptr<GF2m_Field> sp_field ) : m_deg(-1), coeff(1), msp_field(sp_field) {} -polyn_gf2m::polyn_gf2m(int degree, const unsigned char* mem, u32bit mem_byte_len, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field) +polyn_gf2m::polyn_gf2m(int degree, const unsigned char* mem, u32bit mem_byte_len, std::shared_ptr<GF2m_Field> sp_field) :msp_field(sp_field) { u32bit j, k, l; @@ -229,7 +225,7 @@ int polyn_gf2m::get_degree() const } -static gf2m eval_aux(const gf2m * /*restrict*/ coeff, gf2m a, int d, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field) +static gf2m eval_aux(const gf2m * /*restrict*/ coeff, gf2m a, int d, std::shared_ptr<GF2m_Field> sp_field) { gf2m b; b = coeff[d--]; @@ -255,7 +251,7 @@ gf2m polyn_gf2m::eval(gf2m a) void polyn_gf2m::remainder(polyn_gf2m &p, const polyn_gf2m & g) { int i, j, d; - std::shared_ptr<gf2m_small_m::Gf2m_Field> msp_field = g.msp_field; + std::shared_ptr<GF2m_Field> msp_field = g.msp_field; d = p.get_degree() - g.get_degree(); if (d >= 0) { gf2m la = msp_field->gf_inv_rn(g.get_lead_coef()); @@ -314,7 +310,7 @@ polyn_gf2m polyn_gf2m::sqmod( const std::vector<polyn_gf2m> & sq, int d) { int i, j; gf2m la; - std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field = this->msp_field; + std::shared_ptr<GF2m_Field> sp_field = this->msp_field; polyn_gf2m result(d - 1, sp_field); // terms of low degree @@ -438,7 +434,7 @@ void polyn_gf2m::patchup_deg_secure( u32bit trgt_deg, volatile gf2m patch_elem) std::pair<polyn_gf2m, polyn_gf2m> polyn_gf2m::eea_with_coefficients( const polyn_gf2m & p, const polyn_gf2m & g, int break_deg) { - std::shared_ptr<gf2m_small_m::Gf2m_Field> msp_field = g.msp_field; + std::shared_ptr<GF2m_Field> msp_field = g.msp_field; int i, j, dr, du, delta; gf2m a; polyn_gf2m aux; @@ -512,7 +508,7 @@ std::pair<polyn_gf2m, polyn_gf2m> polyn_gf2m::eea_with_coefficients( const polyn else { /* t odd */ - cond1 = r0.get_degree() <= break_deg - 1; + cond1 = r0.get_degree() < break_deg; cond2 = u0.get_degree() < break_deg - 1; cond1 &= cond2; } @@ -625,7 +621,7 @@ std::pair<polyn_gf2m, polyn_gf2m> polyn_gf2m::eea_with_coefficients( const polyn return std::make_pair(u1,r1); // coefficients u,v } -polyn_gf2m::polyn_gf2m(int t, Botan::RandomNumberGenerator& rng, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field) +polyn_gf2m::polyn_gf2m(int t, Botan::RandomNumberGenerator& rng, std::shared_ptr<GF2m_Field> sp_field) :m_deg(t), coeff(t+1), msp_field(sp_field) @@ -655,7 +651,7 @@ void polyn_gf2m::poly_shiftmod( const polyn_gf2m & g) { throw Invalid_Argument("shiftmod cannot be called on polynomials of degree 0 or less"); } - std::shared_ptr<gf2m_small_m::Gf2m_Field> msp_field = g.msp_field; + std::shared_ptr<GF2m_Field> msp_field = g.msp_field; t = g.get_degree(); a = msp_field->gf_div(this->coeff[t-1], g.coeff[t]); @@ -670,7 +666,7 @@ std::vector<polyn_gf2m> polyn_gf2m::sqrt_mod_init(const polyn_gf2m & g) { u32bit i, t; u32bit nb_polyn_sqrt_mat; - std::shared_ptr<gf2m_small_m::Gf2m_Field> msp_field = g.msp_field; + std::shared_ptr<GF2m_Field> msp_field = g.msp_field; std::vector<polyn_gf2m> result; t = g.get_degree(); nb_polyn_sqrt_mat = t/2; @@ -717,7 +713,7 @@ std::vector<polyn_gf2m> syndrome_init(polyn_gf2m const& generator, std::vector<g gf2m a; - std::shared_ptr<gf2m_small_m::Gf2m_Field> msp_field = generator.msp_field; + std::shared_ptr<GF2m_Field> msp_field = generator.msp_field; std::vector<polyn_gf2m> result; t = generator.get_degree(); @@ -744,7 +740,7 @@ std::vector<polyn_gf2m> syndrome_init(polyn_gf2m const& generator, std::vector<g return result; } -polyn_gf2m::polyn_gf2m(const secure_vector<byte>& encoded, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field ) +polyn_gf2m::polyn_gf2m(const secure_vector<byte>& encoded, std::shared_ptr<GF2m_Field> sp_field ) :msp_field(sp_field) { if(encoded.size() % 2) diff --git a/src/lib/pubkey/mce/polyn_gf2m.h b/src/lib/pubkey/mce/polyn_gf2m.h index 6ec028a25..1c8cc5211 100644 --- a/src/lib/pubkey/mce/polyn_gf2m.h +++ b/src/lib/pubkey/mce/polyn_gf2m.h @@ -12,14 +12,14 @@ #ifndef BOTAN_POLYN_GF2M_H__ #define BOTAN_POLYN_GF2M_H__ +#include <botan/secmem.h> #include <botan/gf2m_small_m.h> -#include <botan/rng.h> #include <memory> #include <utility> namespace Botan { -using namespace gf2m_small_m; +class RandomNumberGenerator; struct polyn_gf2m { @@ -27,13 +27,13 @@ struct polyn_gf2m /** * create a zero polynomial: */ - polyn_gf2m( std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field ); + polyn_gf2m( std::shared_ptr<GF2m_Field> sp_field ); polyn_gf2m() :m_deg(-1) {}; - polyn_gf2m(const secure_vector<byte>& encoded, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field ); + polyn_gf2m(const secure_vector<byte>& encoded, std::shared_ptr<GF2m_Field> sp_field ); polyn_gf2m& operator=(const polyn_gf2m&) = default; @@ -61,7 +61,7 @@ struct polyn_gf2m /** * create zero polynomial with reservation of space for a degree d polynomial */ - polyn_gf2m(int d, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field); + polyn_gf2m(int d, std::shared_ptr<GF2m_Field> sp_field); polyn_gf2m(polyn_gf2m const& other); /** @@ -71,9 +71,9 @@ struct polyn_gf2m /** * random irreducible polynomial of degree t */ - polyn_gf2m(int t, RandomNumberGenerator& rng, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field); + polyn_gf2m(int t, RandomNumberGenerator& rng, std::shared_ptr<GF2m_Field> sp_field); - std::shared_ptr<gf2m_small_m::Gf2m_Field> get_sp_field() const + std::shared_ptr<GF2m_Field> get_sp_field() const { return msp_field; }; gf2m& operator[](size_t i) { return coeff[i]; }; @@ -97,12 +97,12 @@ struct polyn_gf2m std::string to_string() const; /** decode a polynomial from memory: **/ - polyn_gf2m(const byte* mem, u32bit mem_len, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field); + polyn_gf2m(const byte* mem, u32bit mem_len, std::shared_ptr<GF2m_Field> sp_field); // remove one! ^v! /** * create a polynomial from memory area (encoded) */ - polyn_gf2m(int degree, const unsigned char* mem, u32bit mem_byte_len, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field); + polyn_gf2m(int degree, const unsigned char* mem, u32bit mem_byte_len, std::shared_ptr<GF2m_Field> sp_field); void encode(u32bit min_numo_coeffs, byte* mem, u32bit mem_len) const; @@ -149,13 +149,19 @@ struct polyn_gf2m public: int m_deg; secure_vector<gf2m> coeff; - std::shared_ptr<gf2m_small_m::Gf2m_Field> msp_field; + std::shared_ptr<GF2m_Field> msp_field; }; gf2m random_code_element(unsigned code_length, RandomNumberGenerator& rng); std::vector<polyn_gf2m> syndrome_init(polyn_gf2m const& generator, std::vector<gf2m> const& support, int n); +/** +* Find the roots of a polynomial over GF(2^m) using the method by Federenko +* et al. +*/ +secure_vector<gf2m> find_roots_gf2m_decomp(const polyn_gf2m & polyn, u32bit code_length); + } #endif diff --git a/src/lib/pubkey/mce/workfactor.cpp b/src/lib/pubkey/mce/workfactor.cpp index e7cf631d4..9594c0aab 100644 --- a/src/lib/pubkey/mce/workfactor.cpp +++ b/src/lib/pubkey/mce/workfactor.cpp @@ -8,6 +8,7 @@ */ #include <botan/mceliece.h> +#include <botan/internal/bit_ops.h> #include <cmath> namespace Botan { @@ -91,8 +92,10 @@ double best_wf(size_t n, size_t k, size_t w, size_t p) } -size_t mceliece_work_factor(size_t n, size_t k, size_t t) +size_t mceliece_work_factor(size_t n, size_t t) { + const size_t k = n - ceil_log2(n) * t; + double min = cout_total(n, k, t, 0, 0); // correspond a p=1 for(size_t p = 0; p != t / 2; ++p) { diff --git a/src/lib/pubkey/mceies/mceies.cpp b/src/lib/pubkey/mceies/mceies.cpp index 58dde2e27..d4d956a54 100644 --- a/src/lib/pubkey/mceies/mceies.cpp +++ b/src/lib/pubkey/mceies/mceies.cpp @@ -31,9 +31,10 @@ secure_vector<byte> aead_key(const secure_vector<byte>& mk, secure_vector<byte> mceies_encrypt(const McEliece_PublicKey& pubkey, - const secure_vector<byte>& pt, - byte ad[], size_t ad_len, - RandomNumberGenerator& rng) + const byte pt[], size_t pt_len, + const byte ad[], size_t ad_len, + RandomNumberGenerator& rng, + const std::string& algo) { McEliece_KEM_Encryptor kem_op(pubkey); @@ -45,7 +46,6 @@ mceies_encrypt(const McEliece_PublicKey& pubkey, BOTAN_ASSERT(mce_ciphertext.size() == mce_code_bytes, "Unexpected size"); - const std::string algo = "AES-256/OCB"; std::unique_ptr<AEAD_Mode> aead(get_aead(algo, ENCRYPTION)); if(!aead) throw std::runtime_error("mce_encrypt unable to create AEAD instance '" + algo + "'"); @@ -57,10 +57,10 @@ mceies_encrypt(const McEliece_PublicKey& pubkey, const secure_vector<byte> nonce = rng.random_vec(nonce_len); - secure_vector<byte> msg(mce_ciphertext.size() + nonce.size() + pt.size()); + secure_vector<byte> msg(mce_ciphertext.size() + nonce.size() + pt_len); copy_mem(msg.data(), mce_ciphertext.data(), mce_ciphertext.size()); copy_mem(msg.data() + mce_ciphertext.size(), nonce.data(), nonce.size()); - copy_mem(msg.data() + mce_ciphertext.size() + nonce.size(), pt.data(), pt.size()); + copy_mem(msg.data() + mce_ciphertext.size() + nonce.size(), pt, pt_len); aead->start(nonce); aead->finish(msg, mce_ciphertext.size() + nonce.size()); @@ -69,8 +69,9 @@ mceies_encrypt(const McEliece_PublicKey& pubkey, secure_vector<byte> mceies_decrypt(const McEliece_PrivateKey& privkey, - const secure_vector<byte>& ct, - byte ad[], size_t ad_len) + const byte ct[], size_t ct_len, + const byte ad[], size_t ad_len, + const std::string& algo) { try { @@ -78,23 +79,21 @@ mceies_decrypt(const McEliece_PrivateKey& privkey, const size_t mce_code_bytes = (privkey.get_code_length() + 7) / 8; - - const std::string algo = "AES-256/OCB"; std::unique_ptr<AEAD_Mode> aead(get_aead(algo, DECRYPTION)); if(!aead) throw std::runtime_error("Unable to create AEAD instance '" + algo + "'"); const size_t nonce_len = aead->default_nonce_length(); - if(ct.size() < mce_code_bytes + nonce_len + aead->tag_size()) + if(ct_len < mce_code_bytes + nonce_len + aead->tag_size()) throw std::runtime_error("Input message too small to be valid"); - const secure_vector<byte> mce_key = kem_op.decrypt(ct.data(), mce_code_bytes); + const secure_vector<byte> mce_key = kem_op.decrypt(ct, mce_code_bytes); aead->set_key(aead_key(mce_key, *aead)); aead->set_associated_data(ad, ad_len); - secure_vector<byte> pt(ct.begin() + mce_code_bytes + nonce_len, ct.end()); + secure_vector<byte> pt(ct + mce_code_bytes + nonce_len, ct + ct_len); aead->start(&ct[mce_code_bytes], nonce_len); aead->finish(pt, 0); diff --git a/src/lib/pubkey/mceies/mceies.h b/src/lib/pubkey/mceies/mceies.h index 9ead21a17..b43e2065f 100644 --- a/src/lib/pubkey/mceies/mceies.h +++ b/src/lib/pubkey/mceies/mceies.h @@ -23,9 +23,10 @@ class McEliece_PrivateKey; */ secure_vector<byte> BOTAN_DLL mceies_encrypt(const McEliece_PublicKey& pubkey, - const secure_vector<byte>& pt, - byte ad[], size_t ad_len, - RandomNumberGenerator& rng); + const byte pt[], size_t pt_len, + const byte ad[], size_t ad_len, + RandomNumberGenerator& rng, + const std::string& aead = "AES-256/OCB"); /** * McEliece Integrated Encryption System @@ -34,8 +35,9 @@ BOTAN_DLL mceies_encrypt(const McEliece_PublicKey& pubkey, */ secure_vector<byte> BOTAN_DLL mceies_decrypt(const McEliece_PrivateKey& privkey, - const secure_vector<byte>& ct, - byte ad[], size_t ad_len); + const byte ct[], size_t ct_len, + const byte ad[], size_t ad_len, + const std::string& aead = "AES-256/OCB"); } diff --git a/src/lib/pubkey/pk_algs.cpp b/src/lib/pubkey/pk_algs.cpp index 75264d56f..689237a84 100644 --- a/src/lib/pubkey/pk_algs.cpp +++ b/src/lib/pubkey/pk_algs.cpp @@ -48,6 +48,10 @@ #include <botan/curve25519.h> #endif +#if defined(BOTAN_HAS_MCELIECE) + #include <botan/mceliece.h> +#endif + namespace Botan { Public_Key* make_public_key(const AlgorithmIdentifier& alg_id, @@ -107,6 +111,11 @@ Public_Key* make_public_key(const AlgorithmIdentifier& alg_id, return new Curve25519_PublicKey(alg_id, key_bits); #endif +#if defined(BOTAN_HAS_MCELIECE) + if(alg_name == "McEliece") + return new McEliece_PublicKey(unlock(key_bits)); +#endif + throw Decoding_Error("Unhandled PK algorithm " + alg_name); } @@ -168,6 +177,11 @@ Private_Key* make_private_key(const AlgorithmIdentifier& alg_id, return new Curve25519_PrivateKey(alg_id, key_bits, rng); #endif +#if defined(BOTAN_HAS_MCELIECE) + if(alg_name == "McEliece") + return new McEliece_PrivateKey(key_bits); +#endif + throw Decoding_Error("Unhandled PK algorithm " + alg_name); } diff --git a/src/lib/pubkey/pk_utils.h b/src/lib/pubkey/pk_utils.h index 14c304ac5..326a6ea68 100644 --- a/src/lib/pubkey/pk_utils.h +++ b/src/lib/pubkey/pk_utils.h @@ -11,6 +11,7 @@ #include <botan/internal/algo_registry.h> #include <botan/internal/pk_ops_impl.h> #include <botan/numthry.h> +#include <botan/reducer.h> #include <algorithm> namespace Botan { diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp index 74b6a2053..b9923f54b 100644 --- a/src/lib/pubkey/pubkey.cpp +++ b/src/lib/pubkey/pubkey.cpp @@ -15,19 +15,26 @@ namespace Botan { namespace { template<typename T, typename Key> -T* get_pk_op(const std::string& what, const Key& key, const std::string& pad) +T* get_pk_op(const std::string& what, const Key& key, const std::string& pad, + const std::string& provider = "") { - T* p = Algo_Registry<T>::global_registry().make(typename T::Spec(key, pad)); - if(!p) - throw Lookup_Error(what + " with " + key.algo_name() + "/" + pad + " not supported"); - return p; + if(T* p = Algo_Registry<T>::global_registry().make(typename T::Spec(key, pad), provider)) + return p; + + const std::string err = what + " with " + key.algo_name() + "/" + pad + " not supported"; + if(provider != "") + throw Lookup_Error(err + " with provider " + provider); + else + throw Lookup_Error(err); } } -PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, const std::string& eme) +PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, + const std::string& padding, + const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Encryption>("Encryption", key, eme)); + m_op.reset(get_pk_op<PK_Ops::Encryption>("Encryption", key, padding, provider)); } std::vector<byte> @@ -41,9 +48,10 @@ size_t PK_Encryptor_EME::maximum_input_size() const return m_op->max_input_bits() / 8; } -PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, const std::string& eme) +PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, const std::string& padding, + const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Decryption>("Decryption", key, eme)); + m_op.reset(get_pk_op<PK_Ops::Decryption>("Decryption", key, padding, provider)); } secure_vector<byte> PK_Decryptor_EME::dec(const byte msg[], size_t length) const @@ -108,9 +116,10 @@ std::vector<byte> der_decode_signature(const byte sig[], size_t len, PK_Signer::PK_Signer(const Private_Key& key, const std::string& emsa, - Signature_Format format) + Signature_Format format, + const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Signature>("Signing", key, emsa)); + m_op.reset(get_pk_op<PK_Ops::Signature>("Signing", key, emsa, provider)); m_sig_format = format; } @@ -135,9 +144,10 @@ std::vector<byte> PK_Signer::signature(RandomNumberGenerator& rng) PK_Verifier::PK_Verifier(const Public_Key& key, const std::string& emsa_name, - Signature_Format format) + Signature_Format format, + const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Verification>("Verification", key, emsa_name)); + m_op.reset(get_pk_op<PK_Ops::Verification>("Verification", key, emsa_name, provider)); m_sig_format = format; } diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h index 687485c68..67116a9ec 100644 --- a/src/lib/pubkey/pubkey.h +++ b/src/lib/pubkey/pubkey.h @@ -120,6 +120,19 @@ class BOTAN_DLL PK_Decryptor class BOTAN_DLL PK_Signer { public: + + /** + * Construct a PK Signer. + * @param key the key to use inside this signer + * @param emsa the EMSA to use + * An example would be "EMSA1(SHA-224)". + * @param format the signature format to use + */ + PK_Signer(const Private_Key& key, + const std::string& emsa, + Signature_Format format = IEEE_1363, + const std::string& provider = ""); + /** * Sign a message. * @param in the message to sign as a byte array @@ -180,17 +193,6 @@ class BOTAN_DLL PK_Signer * @param format the signature format to use */ void set_output_format(Signature_Format format) { m_sig_format = format; } - - /** - * Construct a PK Signer. - * @param key the key to use inside this signer - * @param emsa the EMSA to use - * An example would be "EMSA1(SHA-224)". - * @param format the signature format to use - */ - PK_Signer(const Private_Key& key, - const std::string& emsa, - Signature_Format format = IEEE_1363); private: std::unique_ptr<PK_Ops::Signature> m_op; Signature_Format m_sig_format; @@ -205,6 +207,17 @@ class BOTAN_DLL PK_Verifier { public: /** + * Construct a PK Verifier. + * @param pub_key the public key to verify against + * @param emsa the EMSA to use (eg "EMSA3(SHA-1)") + * @param format the signature format to use + */ + PK_Verifier(const Public_Key& pub_key, + const std::string& emsa, + Signature_Format format = IEEE_1363, + const std::string& provider = ""); + + /** * Verify a signature. * @param msg the message that the signature belongs to, as a byte array * @param msg_length the length of the above byte array msg @@ -278,15 +291,6 @@ class BOTAN_DLL PK_Verifier */ void set_input_format(Signature_Format format); - /** - * Construct a PK Verifier. - * @param pub_key the public key to verify against - * @param emsa the EMSA to use (eg "EMSA3(SHA-1)") - * @param format the signature format to use - */ - PK_Verifier(const Public_Key& pub_key, - const std::string& emsa, - Signature_Format format = IEEE_1363); private: std::unique_ptr<PK_Ops::Verification> m_op; Signature_Format m_sig_format; @@ -299,6 +303,13 @@ class BOTAN_DLL PK_Key_Agreement { public: + /** + * Construct a PK Key Agreement. + * @param key the key to use + * @param kdf name of the KDF to use (or 'Raw' for no KDF) + */ + PK_Key_Agreement(const Private_Key& key, const std::string& kdf); + /* * Perform Key Agreement Operation * @param key_len the desired key output size @@ -361,18 +372,13 @@ class BOTAN_DLL PK_Key_Agreement params.length()); } - /** - * Construct a PK Key Agreement. - * @param key the key to use - * @param kdf name of the KDF to use (or 'Raw' for no KDF) - */ - PK_Key_Agreement(const Private_Key& key, const std::string& kdf); private: std::unique_ptr<PK_Ops::Key_Agreement> m_op; }; /** -* Encryption with an MR algorithm and an EME. +* Encryption using a standard message recovery algorithm like RSA or +* ElGamal, paired with an encoding scheme like OAEP. */ class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor { @@ -382,10 +388,11 @@ class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor /** * Construct an instance. * @param key the key to use inside the decryptor - * @param eme the EME to use + * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") */ PK_Encryptor_EME(const Public_Key& key, - const std::string& eme); + const std::string& padding, + const std::string& provider = ""); private: std::vector<byte> enc(const byte[], size_t, RandomNumberGenerator& rng) const override; @@ -405,7 +412,8 @@ class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor * @param eme the EME to use */ PK_Decryptor_EME(const Private_Key& key, - const std::string& eme); + const std::string& eme, + const std::string& provider = ""); private: secure_vector<byte> dec(const byte[], size_t) const override; diff --git a/src/lib/pubkey/rfc6979/rfc6979.cpp b/src/lib/pubkey/rfc6979/rfc6979.cpp index 5f606891d..f749b039f 100644 --- a/src/lib/pubkey/rfc6979/rfc6979.cpp +++ b/src/lib/pubkey/rfc6979/rfc6979.cpp @@ -7,8 +7,8 @@ #include <botan/rfc6979.h> #include <botan/hmac_drbg.h> +#include <botan/mac.h> #include <botan/scan_name.h> -#include <botan/lookup.h> namespace Botan { @@ -31,7 +31,7 @@ RFC6979_Nonce_Generator::RFC6979_Nonce_Generator(const std::string& hash, m_order(order), m_qlen(m_order.bits()), m_rlen(m_qlen / 8 + (m_qlen % 8 ? 1 : 0)), - m_hmac_drbg(new HMAC_DRBG(make_message_auth("HMAC(" + hash + ")").release())), + m_hmac_drbg(new HMAC_DRBG(MessageAuthenticationCode::create("HMAC(" + hash + ")").release())), m_rng_in(m_rlen * 2), m_rng_out(m_rlen) { diff --git a/src/lib/pubkey/rsa/openssl_rsa.cpp b/src/lib/pubkey/rsa/openssl_rsa.cpp new file mode 100644 index 000000000..f2825634a --- /dev/null +++ b/src/lib/pubkey/rsa/openssl_rsa.cpp @@ -0,0 +1,297 @@ +/* +* RSA operations provided by OpenSSL +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/rsa.h> + +#if defined(BOTAN_HAS_OPENSSL) + +#include <botan/internal/openssl.h> +#include <botan/internal/pk_utils.h> +#include <functional> +#include <memory> + +#include <openssl/rsa.h> +#include <openssl/x509.h> +#include <openssl/err.h> + +namespace Botan { + +namespace { + +std::pair<int, size_t> get_openssl_enc_pad(const std::string& eme) + { + ERR_load_crypto_strings(); + if(eme == "Raw") + return std::make_pair(RSA_NO_PADDING, 0); + else if(eme == "EME-PKCS1-v1_5") + return std::make_pair(RSA_PKCS1_PADDING, 11); + else if(eme == "OAEP(SHA-1)") + return std::make_pair(RSA_PKCS1_OAEP_PADDING, 41); + else + throw Lookup_Error("OpenSSL RSA does not support EME " + eme); + } + +secure_vector<byte> strip_leading_zeros(const secure_vector<byte>& input) + { + size_t leading_zeros = 0; + + for(size_t i = 0; i != input.size(); ++i) + { + if(input[i] != 0) + break; + ++leading_zeros; + } + + secure_vector<byte> output(&input[leading_zeros], + &input[input.size()]); + return output; + } + +class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption + { + public: + typedef RSA_PublicKey Key_Type; + + static OpenSSL_RSA_Encryption_Operation* make(const Spec& spec) + { + try + { + if(auto* key = dynamic_cast<const RSA_PublicKey*>(&spec.key())) + { + auto pad_info = get_openssl_enc_pad(spec.padding()); + return new OpenSSL_RSA_Encryption_Operation(*key, pad_info.first, pad_info.second); + } + } + catch(...) {} + + return nullptr; + } + + OpenSSL_RSA_Encryption_Operation(const RSA_PublicKey& rsa, int pad, size_t pad_overhead) : + m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad) + { + const std::vector<byte> der = rsa.x509_subject_public_key(); + const byte* der_ptr = der.data(); + m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size())); + if(!m_openssl_rsa) + throw OpenSSL_Error("d2i_RSAPublicKey"); + + m_bits = 8 * (n_size() - pad_overhead) - 1; + } + + size_t max_input_bits() const override { return m_bits; }; + + secure_vector<byte> encrypt(const byte msg[], size_t msg_len, + RandomNumberGenerator&) override + { + const size_t mod_sz = n_size(); + + if(msg_len > mod_sz) + throw Invalid_Argument("Input too large for RSA key"); + + secure_vector<byte> outbuf(mod_sz); + + secure_vector<byte> inbuf; + + if(m_padding == RSA_NO_PADDING) + { + inbuf.resize(mod_sz); + copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len); + } + else + { + inbuf.assign(msg, msg + msg_len); + } + + int rc = ::RSA_public_encrypt(inbuf.size(), inbuf.data(), outbuf.data(), + m_openssl_rsa.get(), m_padding); + if(rc < 0) + throw OpenSSL_Error("RSA_public_encrypt"); + + return outbuf; + } + + private: + size_t n_size() const { return ::RSA_size(m_openssl_rsa.get()); } + std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa; + size_t m_bits = 0; + int m_padding = 0; + }; + +class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption + { + public: + typedef RSA_PrivateKey Key_Type; + + static OpenSSL_RSA_Decryption_Operation* make(const Spec& spec) + { + try + { + if(auto* key = dynamic_cast<const RSA_PrivateKey*>(&spec.key())) + { + auto pad_info = get_openssl_enc_pad(spec.padding()); + return new OpenSSL_RSA_Decryption_Operation(*key, pad_info.first); + } + } + catch(...) {} + + return nullptr; + } + + OpenSSL_RSA_Decryption_Operation(const RSA_PrivateKey& rsa, int pad) : + m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad) + { + const secure_vector<byte> der = rsa.pkcs8_private_key(); + const byte* der_ptr = der.data(); + m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size())); + if(!m_openssl_rsa) + throw OpenSSL_Error("d2i_RSAPrivateKey"); + } + + size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; } + + secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override + { + secure_vector<byte> buf(::RSA_size(m_openssl_rsa.get())); + int rc = ::RSA_private_decrypt(msg_len, msg, buf.data(), m_openssl_rsa.get(), m_padding); + if(rc < 0 || static_cast<size_t>(rc) > buf.size()) + throw OpenSSL_Error("RSA_private_decrypt"); + buf.resize(rc); + + if(m_padding == RSA_NO_PADDING) + { + return strip_leading_zeros(buf); + } + return buf; + } + + private: + std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa; + int m_padding = 0; + }; + +class OpenSSL_RSA_Verification_Operation : public PK_Ops::Verification_with_EMSA + { + public: + typedef RSA_PublicKey Key_Type; + + static OpenSSL_RSA_Verification_Operation* make(const Spec& spec) + { + if(const RSA_PublicKey* rsa = dynamic_cast<const RSA_PublicKey*>(&spec.key())) + { + return new OpenSSL_RSA_Verification_Operation(*rsa, spec.padding()); + } + + return nullptr; + } + + OpenSSL_RSA_Verification_Operation(const RSA_PublicKey& rsa, const std::string& emsa) : + PK_Ops::Verification_with_EMSA(emsa), + m_openssl_rsa(nullptr, ::RSA_free) + { + const std::vector<byte> der = rsa.x509_subject_public_key(); + const byte* der_ptr = der.data(); + m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size())); + } + + size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; } + + bool with_recovery() const override { return true; } + + secure_vector<byte> verify_mr(const byte msg[], size_t msg_len) override + { + const size_t mod_sz = ::RSA_size(m_openssl_rsa.get()); + + if(msg_len > mod_sz) + throw Invalid_Argument("OpenSSL RSA verify input too large"); + + secure_vector<byte> inbuf(mod_sz); + copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len); + + secure_vector<byte> outbuf(mod_sz); + + int rc = ::RSA_public_decrypt(inbuf.size(), inbuf.data(), outbuf.data(), + m_openssl_rsa.get(), RSA_NO_PADDING); + if(rc < 0) + throw Invalid_Argument("RSA_public_decrypt"); + + return strip_leading_zeros(outbuf); + } + private: + std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa; + }; + +class OpenSSL_RSA_Signing_Operation : public PK_Ops::Signature_with_EMSA + { + public: + typedef RSA_PrivateKey Key_Type; + + static OpenSSL_RSA_Signing_Operation* make(const Spec& spec) + { + if(const RSA_PrivateKey* rsa = dynamic_cast<const RSA_PrivateKey*>(&spec.key())) + { + return new OpenSSL_RSA_Signing_Operation(*rsa, spec.padding()); + } + + return nullptr; + } + + OpenSSL_RSA_Signing_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) : + PK_Ops::Signature_with_EMSA(emsa), + m_openssl_rsa(nullptr, ::RSA_free) + { + const secure_vector<byte> der = rsa.pkcs8_private_key(); + const byte* der_ptr = der.data(); + m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size())); + if(!m_openssl_rsa) + throw OpenSSL_Error("d2i_RSAPrivateKey"); + } + + secure_vector<byte> raw_sign(const byte msg[], size_t msg_len, + RandomNumberGenerator&) override + { + const size_t mod_sz = ::RSA_size(m_openssl_rsa.get()); + + if(msg_len > mod_sz) + throw Invalid_Argument("OpenSSL RSA sign input too large"); + + secure_vector<byte> inbuf(mod_sz); + copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len); + + secure_vector<byte> outbuf(mod_sz); + + int rc = ::RSA_private_encrypt(inbuf.size(), inbuf.data(), outbuf.data(), + m_openssl_rsa.get(), RSA_NO_PADDING); + if(rc < 0) + throw OpenSSL_Error("RSA_private_encrypt"); + + return outbuf; + } + + size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; } + + private: + std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa; + }; + +BOTAN_REGISTER_TYPE(PK_Ops::Verification, OpenSSL_RSA_Verification_Operation, "RSA", + OpenSSL_RSA_Verification_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO); + +BOTAN_REGISTER_TYPE(PK_Ops::Signature, OpenSSL_RSA_Signing_Operation, "RSA", + OpenSSL_RSA_Signing_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO); + +BOTAN_REGISTER_TYPE(PK_Ops::Encryption, OpenSSL_RSA_Encryption_Operation, "RSA", + OpenSSL_RSA_Encryption_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO); + +BOTAN_REGISTER_TYPE(PK_Ops::Decryption, OpenSSL_RSA_Decryption_Operation, "RSA", + OpenSSL_RSA_Decryption_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO); + +} + +} + +#endif // BOTAN_HAS_OPENSSL diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp index 13425a46f..5804d0034 100644 --- a/src/lib/pubkey/rsa/rsa.cpp +++ b/src/lib/pubkey/rsa/rsa.cpp @@ -87,14 +87,14 @@ class RSA_Private_Operation BigInt blinded_private_op(const BigInt& m) const { + if(m >= n) + throw Invalid_Argument("RSA private op - input is too large"); + return m_blinder.unblind(private_op(m_blinder.blind(m))); } BigInt private_op(const BigInt& m) const { - if(m >= n) - throw Invalid_Argument("RSA private op - input is too large"); - auto future_j1 = std::async(std::launch::async, m_powermod_d1_p, m); BigInt j2 = m_powermod_d2_q(m); BigInt j1 = future_j1.get(); @@ -131,7 +131,8 @@ class RSA_Signature_Operation : public PK_Ops::Signature_with_EMSA, { const BigInt m(msg, msg_len); const BigInt x = blinded_private_op(m); - BOTAN_ASSERT(m == m_powermod_e_n(x), "RSA sign consistency check"); + const BigInt c = m_powermod_e_n(x); + BOTAN_ASSERT(m == c, "RSA sign consistency check"); return BigInt::encode_1363(x, n.bytes()); } }; @@ -154,7 +155,8 @@ class RSA_Decryption_Operation : public PK_Ops::Decryption_with_EME, { const BigInt m(msg, msg_len); const BigInt x = blinded_private_op(m); - BOTAN_ASSERT(m == m_powermod_e_n(x), "RSA decrypt consistency check"); + const BigInt c = m_powermod_e_n(x); + BOTAN_ASSERT(m == c, "RSA sign consistency check"); return BigInt::encode_locked(x); } }; diff --git a/src/lib/pubkey/x509_key.h b/src/lib/pubkey/x509_key.h index 1bfa248ff..cbb0412d2 100644 --- a/src/lib/pubkey/x509_key.h +++ b/src/lib/pubkey/x509_key.h @@ -10,7 +10,7 @@ #include <botan/pk_keys.h> #include <botan/alg_id.h> -#include <botan/pipe.h> +#include <botan/data_src.h> #include <string> namespace Botan { diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/lib/rng/hmac_drbg/hmac_drbg.cpp index af0565120..ad731b6b3 100644 --- a/src/lib/rng/hmac_drbg/hmac_drbg.cpp +++ b/src/lib/rng/hmac_drbg/hmac_drbg.cpp @@ -20,6 +20,18 @@ HMAC_DRBG::HMAC_DRBG(MessageAuthenticationCode* mac, m_mac->set_key(std::vector<byte>(m_mac->output_length(), 0x00)); } +HMAC_DRBG::HMAC_DRBG(const std::string& mac_name, + RandomNumberGenerator* prng) : + m_prng(prng), + m_reseed_counter(0) + { + m_mac = MessageAuthenticationCode::create(mac_name); + if(!m_mac) + throw Algorithm_Not_Found(mac_name); + m_V = secure_vector<byte>(m_mac->output_length(), 0x01), + m_mac->set_key(std::vector<byte>(m_mac->output_length(), 0x00)); + } + void HMAC_DRBG::randomize(byte out[], size_t length) { if(!is_seeded() || m_reseed_counter > BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED) diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.h b/src/lib/rng/hmac_drbg/hmac_drbg.h index 2fefdef0d..c9d0e3d20 100644 --- a/src/lib/rng/hmac_drbg/hmac_drbg.h +++ b/src/lib/rng/hmac_drbg/hmac_drbg.h @@ -35,6 +35,9 @@ class BOTAN_DLL HMAC_DRBG : public RandomNumberGenerator HMAC_DRBG(MessageAuthenticationCode* mac, RandomNumberGenerator* underlying_rng = nullptr); + HMAC_DRBG(const std::string& mac, + RandomNumberGenerator* underlying_rng = nullptr); + private: void update(const byte input[], size_t input_len); diff --git a/src/lib/rng/hmac_rng/hmac_rng.cpp b/src/lib/rng/hmac_rng/hmac_rng.cpp index 36003385a..5456b3bac 100644 --- a/src/lib/rng/hmac_rng/hmac_rng.cpp +++ b/src/lib/rng/hmac_rng/hmac_rng.cpp @@ -6,9 +6,7 @@ */ #include <botan/hmac_rng.h> -#include <botan/get_byte.h> #include <botan/entropy_src.h> -#include <botan/internal/xor_buf.h> #include <algorithm> #include <chrono> diff --git a/src/lib/rng/rng.cpp b/src/lib/rng/rng.cpp index 76e868b93..d4fd5fb10 100644 --- a/src/lib/rng/rng.cpp +++ b/src/lib/rng/rng.cpp @@ -7,14 +7,16 @@ #include <botan/rng.h> #include <botan/hmac_rng.h> -#include <botan/lookup.h> namespace Botan { RandomNumberGenerator* RandomNumberGenerator::make_rng() { - std::unique_ptr<MessageAuthenticationCode> h1(make_message_auth("HMAC(SHA-512)")); - std::unique_ptr<MessageAuthenticationCode> h2(h1->clone()); + std::unique_ptr<MessageAuthenticationCode> h1(MessageAuthenticationCode::create("HMAC(SHA-512)")); + std::unique_ptr<MessageAuthenticationCode> h2(MessageAuthenticationCode::create("HMAC(SHA-512)")); + + if(!h1 || !h2) + throw Algorithm_Not_Found("HMAC_RNG HMACs"); std::unique_ptr<RandomNumberGenerator> rng(new HMAC_RNG(h1.release(), h2.release())); rng->reseed(256); diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h index b1f78f75d..6ee67f66f 100644 --- a/src/lib/rng/rng.h +++ b/src/lib/rng/rng.h @@ -47,17 +47,35 @@ class BOTAN_DLL RandomNumberGenerator } /** - * Return a random byte - * @return random byte + * Only usable with POD types, only useful with integers + * get_random<u64bit>() */ - byte next_byte() + template<typename T> T get_random() { - byte out; - this->randomize(&out, 1); - return out; + T r; + this->randomize(reinterpret_cast<byte*>(&r), sizeof(r)); + return r; } /** + * Return a value in range [0,2^bits) + */ + u64bit gen_mask(size_t bits) + { + if(bits == 0 || bits > 64) + throw std::invalid_argument("RandomNumberGenerator::gen_mask invalid argument"); + + const u64bit mask = ((1 << bits) - 1); + return this->get_random<u64bit>() & mask; + } + + /** + * Return a random byte + * @return random byte + */ + byte next_byte() { return get_random<byte>(); } + + /** * Check whether this RNG is seeded. * @return true if this RNG was already seeded, false otherwise. */ diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp index 1ab80669b..8b949d071 100644 --- a/src/lib/rng/system_rng/system_rng.cpp +++ b/src/lib/rng/system_rng/system_rng.cpp @@ -1,6 +1,6 @@ /* * System RNG -* (C) 2014 Jack Lloyd +* (C) 2014,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -28,11 +28,11 @@ namespace Botan { namespace { -class System_RNG : public RandomNumberGenerator +class System_RNG_Impl : public RandomNumberGenerator { public: - System_RNG(); - ~System_RNG(); + System_RNG_Impl(); + ~System_RNG_Impl(); void randomize(byte buf[], size_t len) override; @@ -51,7 +51,7 @@ class System_RNG : public RandomNumberGenerator #endif }; -System_RNG::System_RNG() +System_RNG_Impl::System_RNG_Impl() { #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) @@ -66,7 +66,7 @@ System_RNG::System_RNG() #endif } -System_RNG::~System_RNG() +System_RNG_Impl::~System_RNG_Impl() { #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) ::CryptReleaseContext(m_prov, 0); @@ -76,7 +76,7 @@ System_RNG::~System_RNG() #endif } -void System_RNG::randomize(byte buf[], size_t len) +void System_RNG_Impl::randomize(byte buf[], size_t len) { #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) ::CryptGenRandom(m_prov, static_cast<DWORD>(len), buf); @@ -104,7 +104,7 @@ void System_RNG::randomize(byte buf[], size_t len) RandomNumberGenerator& system_rng() { - static System_RNG g_system_rng; + static System_RNG_Impl g_system_rng; return g_system_rng; } diff --git a/src/lib/rng/system_rng/system_rng.h b/src/lib/rng/system_rng/system_rng.h index cac861618..0f4b94725 100644 --- a/src/lib/rng/system_rng/system_rng.h +++ b/src/lib/rng/system_rng/system_rng.h @@ -1,6 +1,6 @@ /* * System RNG interface -* (C) 2014 Jack Lloyd +* (C) 2014,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -19,6 +19,29 @@ namespace Botan { */ BOTAN_DLL RandomNumberGenerator& system_rng(); +/* +* Instantiatable reference to the system RNG. +*/ +class BOTAN_DLL System_RNG : public RandomNumberGenerator + { + public: + System_RNG() : m_rng(system_rng()) {} + + void randomize(Botan::byte out[], size_t len) override { m_rng.randomize(out, len); } + + bool is_seeded() const override { return m_rng.is_seeded(); } + + void clear() override { m_rng.clear(); } + + std::string name() const override { return m_rng.name(); } + + void reseed(size_t poll_bits = 256) override { m_rng.reseed(poll_bits); } + + void add_entropy(const byte in[], size_t len) override { m_rng.add_entropy(in, len); } + private: + Botan::RandomNumberGenerator& m_rng; + }; + } #endif diff --git a/src/lib/rng/x931_rng/x931_rng.cpp b/src/lib/rng/x931_rng/x931_rng.cpp index 976e324c3..d531cf4a9 100644 --- a/src/lib/rng/x931_rng/x931_rng.cpp +++ b/src/lib/rng/x931_rng/x931_rng.cpp @@ -6,7 +6,6 @@ */ #include <botan/x931_rng.h> -#include <botan/internal/xor_buf.h> #include <algorithm> namespace Botan { diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp index 9841f99a2..0a32c720b 100644 --- a/src/lib/stream/chacha/chacha.cpp +++ b/src/lib/stream/chacha/chacha.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/stream_utils.h> #include <botan/chacha.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_STREAM_CIPHER_NOARGS(ChaCha); - void ChaCha::chacha(byte output[64], const u32bit input[16]) { u32bit x00 = input[ 0], x01 = input[ 1], x02 = input[ 2], x03 = input[ 3], diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index f1cdc7c42..e90bb43a4 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -5,19 +5,16 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/stream_utils.h> #include <botan/ctr.h> namespace Botan { -BOTAN_REGISTER_NAMED_T(StreamCipher, "CTR-BE", CTR_BE, CTR_BE::make); - CTR_BE* CTR_BE::make(const Spec& spec) { if(spec.algo_name() == "CTR-BE" && spec.arg_count() == 1) { - if(BlockCipher* c = get_block_cipher(spec.arg(0))) - return new CTR_BE(c); + if(auto c = BlockCipher::create(spec.arg(0))) + return new CTR_BE(c.release()); } return nullptr; } diff --git a/src/lib/stream/info.txt b/src/lib/stream/info.txt index 8dc30936d..59b5d577a 100644 --- a/src/lib/stream/info.txt +++ b/src/lib/stream/info.txt @@ -3,7 +3,3 @@ define STREAM_CIPHER 20131128 <header:public> stream_cipher.h </header:public> - -<header:internal> -stream_utils.h -</header:internal> diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index b98f81be3..e8cb463db 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -5,19 +5,16 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/stream_utils.h> #include <botan/ofb.h> namespace Botan { -BOTAN_REGISTER_NAMED_T(StreamCipher, "OFB", OFB, OFB::make); - OFB* OFB::make(const Spec& spec) { if(spec.algo_name() == "OFB" && spec.arg_count() == 1) { - if(BlockCipher* c = get_block_cipher(spec.arg(0))) - return new OFB(c); + if(auto c = BlockCipher::create(spec.arg(0))) + return new OFB(c.release()); } return nullptr; } diff --git a/src/lib/vendor/openssl/openssl_rc4.cpp b/src/lib/stream/rc4/openssl_rc4.cpp index 494b30974..e4f180a9b 100644 --- a/src/lib/vendor/openssl/openssl_rc4.cpp +++ b/src/lib/stream/rc4/openssl_rc4.cpp @@ -5,7 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/stream_utils.h> +#include <botan/stream_cipher.h> + +#if defined(BOTAN_HAS_OPENSSL) + +#include <botan/internal/algo_registry.h> +#include <botan/internal/openssl.h> #include <botan/parsing.h> #include <openssl/rc4.h> @@ -48,6 +53,9 @@ class OpenSSL_RC4 : public StreamCipher } -BOTAN_REGISTER_TYPE(StreamCipher, OpenSSL_RC4, "RC4", (make_new_T_1len<OpenSSL_RC4,0>), "openssl", 64); +BOTAN_REGISTER_TYPE(StreamCipher, OpenSSL_RC4, "RC4", (make_new_T_1len<OpenSSL_RC4,0>), + "openssl", BOTAN_OPENSSL_RC4_PRIO); } + +#endif diff --git a/src/lib/stream/rc4/rc4.cpp b/src/lib/stream/rc4/rc4.cpp index 3fd0d2276..6146e2818 100644 --- a/src/lib/stream/rc4/rc4.cpp +++ b/src/lib/stream/rc4/rc4.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/stream_utils.h> #include <botan/rc4.h> namespace Botan { -BOTAN_REGISTER_NAMED_T(StreamCipher, "RC4", RC4, RC4::make); - RC4* RC4::make(const Spec& spec) { if(spec.algo_name() == "RC4") diff --git a/src/lib/stream/salsa20/salsa20.cpp b/src/lib/stream/salsa20/salsa20.cpp index daf01dd0a..1d3fe3d28 100644 --- a/src/lib/stream/salsa20/salsa20.cpp +++ b/src/lib/stream/salsa20/salsa20.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/stream_utils.h> #include <botan/salsa20.h> +#include <botan/loadstor.h> namespace Botan { -BOTAN_REGISTER_STREAM_CIPHER_NOARGS(Salsa20); - namespace { #define SALSA20_QUARTER_ROUND(x1, x2, x3, x4) \ diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp new file mode 100644 index 000000000..060e65d86 --- /dev/null +++ b/src/lib/stream/stream_cipher.cpp @@ -0,0 +1,73 @@ +/* +* Stream Ciphers +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/stream_cipher.h> +#include <botan/internal/algo_registry.h> + +#if defined(BOTAN_HAS_CHACHA) + #include <botan/chacha.h> +#endif + +#if defined(BOTAN_HAS_SALSA20) + #include <botan/salsa20.h> +#endif + +#if defined(BOTAN_HAS_CTR_BE) + #include <botan/ctr.h> +#endif + +#if defined(BOTAN_HAS_OFB) + #include <botan/ofb.h> +#endif + +#if defined(BOTAN_HAS_RC4) + #include <botan/rc4.h> +#endif + +namespace Botan { + +std::unique_ptr<StreamCipher> StreamCipher::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr<StreamCipher>(make_a<StreamCipher>(algo_spec, provider)); + } + +std::vector<std::string> StreamCipher::providers(const std::string& algo_spec) + { + return providers_of<StreamCipher>(StreamCipher::Spec(algo_spec)); + } + +StreamCipher::StreamCipher() {} +StreamCipher::~StreamCipher() {} + +void StreamCipher::set_iv(const byte[], size_t iv_len) + { + if(!valid_iv_length(iv_len)) + throw Invalid_IV_Length(name(), iv_len); + } + +#if defined(BOTAN_HAS_CHACHA) +BOTAN_REGISTER_T_NOARGS(StreamCipher, ChaCha); +#endif + +#if defined(BOTAN_HAS_SALSA20) +BOTAN_REGISTER_T_NOARGS(StreamCipher, Salsa20); +#endif + +#if defined(BOTAN_HAS_CTR_BE) +BOTAN_REGISTER_NAMED_T(StreamCipher, "CTR-BE", CTR_BE, CTR_BE::make); +#endif + +#if defined(BOTAN_HAS_OFB) +BOTAN_REGISTER_NAMED_T(StreamCipher, "OFB", OFB, OFB::make); +#endif + +#if defined(BOTAN_HAS_RC4) +BOTAN_REGISTER_NAMED_T(StreamCipher, "RC4", RC4, RC4::make); +#endif + +} diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h index bfdd152a7..8c9b28147 100644 --- a/src/lib/stream/stream_cipher.h +++ b/src/lib/stream/stream_cipher.h @@ -20,6 +20,21 @@ namespace Botan { class BOTAN_DLL StreamCipher : public SymmetricAlgorithm { public: + typedef SCAN_Name Spec; + + /** + * Create an instance based on a name + * Will return a null pointer if the algo/provider combination cannot + * be found. If provider is empty then best available is chosen. + */ + static std::unique_ptr<StreamCipher> create(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * Returns the list of available providers for this algorithm, empty if not available + */ + static std::vector<std::string> providers(const std::string& algo_spec); + /** * Encrypt or decrypt a message * @param in the plaintext @@ -53,11 +68,7 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm * @param iv the initialization vector * @param iv_len the length of the IV in bytes */ - virtual void set_iv(const byte[], size_t iv_len) - { - if(iv_len) - throw Invalid_IV_Length(name(), iv_len); - } + virtual void set_iv(const byte[], size_t iv_len); /** * @param iv_len the length of the IV in bytes @@ -70,7 +81,8 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm */ virtual StreamCipher* clone() const = 0; - typedef SCAN_Name Spec; + StreamCipher(); + virtual ~StreamCipher(); }; } diff --git a/src/lib/stream/stream_utils.h b/src/lib/stream/stream_utils.h deleted file mode 100644 index 8ba8d4b01..000000000 --- a/src/lib/stream/stream_utils.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* Stream Cipher Utility Header -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_STREAM_CIPHER_UTILS_H__ -#define BOTAN_STREAM_CIPHER_UTILS_H__ - -#include <botan/stream_cipher.h> -#include <botan/internal/algo_registry.h> -#include <botan/loadstor.h> -#include <botan/rotate.h> -#include <botan/internal/xor_buf.h> -#include <algorithm> - -namespace Botan { - -#define BOTAN_REGISTER_STREAM_CIPHER(name, maker) BOTAN_REGISTER_T(StreamCipher, name, maker) -#define BOTAN_REGISTER_STREAM_CIPHER_NOARGS(name) BOTAN_REGISTER_T_NOARGS(StreamCipher, name) - -#define BOTAN_REGISTER_STREAM_CIPHER_1LEN(name, def) BOTAN_REGISTER_T_1LEN(StreamCipher, name, def) - -#define BOTAN_REGISTER_STREAM_CIPHER_NAMED_NOARGS(type, name) BOTAN_REGISTER_NAMED_T(StreamCipher, name, type, make_new_T<type>) -#define BOTAN_REGISTER_STREAM_CIPHER_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(StreamCipher, name, type, (make_new_T_1len<type,def>)) - -} - -#endif diff --git a/src/lib/credentials/credentials_manager.cpp b/src/lib/tls/credentials_manager.cpp index 6443bb246..6443bb246 100644 --- a/src/lib/credentials/credentials_manager.cpp +++ b/src/lib/tls/credentials_manager.cpp diff --git a/src/lib/credentials/credentials_manager.h b/src/lib/tls/credentials_manager.h index 96e840d13..96e840d13 100644 --- a/src/lib/credentials/credentials_manager.h +++ b/src/lib/tls/credentials_manager.h diff --git a/src/lib/tls/info.txt b/src/lib/tls/info.txt index 3f3b323f1..1b0cf1415 100644 --- a/src/lib/tls/info.txt +++ b/src/lib/tls/info.txt @@ -3,6 +3,7 @@ define TLS 20150319 load_on auto <header:public> +credentials_manager.h tls_alert.h tls_blocking.h tls_channel.h @@ -36,7 +37,6 @@ tls_session_key.h aead aes asn1 -credentials dh ecdh ecdsa diff --git a/src/lib/tls/msg_hello_verify.cpp b/src/lib/tls/msg_hello_verify.cpp index a3c439750..c1dc574d4 100644 --- a/src/lib/tls/msg_hello_verify.cpp +++ b/src/lib/tls/msg_hello_verify.cpp @@ -7,7 +7,6 @@ #include <botan/internal/tls_messages.h> #include <botan/mac.h> -#include <botan/lookup.h> namespace Botan { @@ -36,7 +35,7 @@ Hello_Verify_Request::Hello_Verify_Request(const std::vector<byte>& client_hello const std::string& client_identity, const SymmetricKey& secret_key) { - std::unique_ptr<MessageAuthenticationCode> hmac(get_mac("HMAC(SHA-256)")); + std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)")); hmac->set_key(secret_key); hmac->update_be(client_hello_bits.size()); diff --git a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp index 508f8ff2f..ed207972e 100644 --- a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp +++ b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp @@ -8,7 +8,6 @@ #include <botan/tls_session_manager_sql.h> #include <botan/database.h> #include <botan/pbkdf.h> -#include <botan/lookup.h> #include <botan/hex.h> #include <botan/loadstor.h> #include <chrono> diff --git a/src/lib/tls/tls_ciphersuite.cpp b/src/lib/tls/tls_ciphersuite.cpp index c0f9dbf76..4fdf33811 100644 --- a/src/lib/tls/tls_ciphersuite.cpp +++ b/src/lib/tls/tls_ciphersuite.cpp @@ -7,7 +7,6 @@ #include <botan/tls_ciphersuite.h> #include <botan/parsing.h> -#include <botan/lookup.h> #include <botan/block_cipher.h> #include <botan/stream_cipher.h> #include <botan/hash.h> @@ -104,16 +103,13 @@ namespace { bool have_hash(const std::string& prf) { - return (!get_hash_function_providers(prf).empty()); + return (HashFunction::providers(prf).size() > 0); } bool have_cipher(const std::string& cipher) { - if(!get_block_cipher_providers(cipher).empty()) - return true; - if(!get_stream_cipher_providers(cipher).empty()) - return true; - return false; + return (BlockCipher::providers(cipher).size() > 0) || + (StreamCipher::providers(cipher).size() > 0); } } diff --git a/src/lib/tls/tls_handshake_hash.cpp b/src/lib/tls/tls_handshake_hash.cpp index 94c2774c5..615767cc2 100644 --- a/src/lib/tls/tls_handshake_hash.cpp +++ b/src/lib/tls/tls_handshake_hash.cpp @@ -7,7 +7,6 @@ #include <botan/internal/tls_handshake_hash.h> #include <botan/tls_exceptn.h> -#include <botan/lookup.h> #include <botan/hash.h> namespace Botan { @@ -29,7 +28,7 @@ secure_vector<byte> Handshake_Hash::final(Protocol_Version version, return mac_algo.c_str(); }; - std::unique_ptr<HashFunction> hash(make_hash_function(choose_hash())); + std::unique_ptr<HashFunction> hash(HashFunction::create(choose_hash())); hash->update(data); return hash->final(); } diff --git a/src/lib/tls/tls_record.cpp b/src/lib/tls/tls_record.cpp index 3ba02f039..71542de16 100644 --- a/src/lib/tls/tls_record.cpp +++ b/src/lib/tls/tls_record.cpp @@ -12,8 +12,6 @@ #include <botan/internal/tls_seq_numbers.h> #include <botan/internal/tls_session_key.h> #include <botan/internal/rounding.h> -#include <botan/internal/xor_buf.h> -#include <botan/lookup.h> #include <botan/rng.h> namespace Botan { @@ -63,20 +61,17 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, return; } - if(BlockCipher* bc = get_block_cipher(cipher_algo)) - { - m_block_cipher.reset(bc); - m_block_cipher->set_key(cipher_key); - m_block_cipher_cbc_state = iv.bits_of(); - m_block_size = bc->block_size(); - - if(version.supports_explicit_cbc_ivs()) - m_iv_size = m_block_size; - } - else + m_block_cipher = BlockCipher::create(cipher_algo); + m_mac = MessageAuthenticationCode::create("HMAC(" + mac_algo + ")"); + if(!m_block_cipher) throw Invalid_Argument("Unknown TLS cipher " + cipher_algo); - m_mac.reset(get_mac("HMAC(" + mac_algo + ")")); + m_block_cipher->set_key(cipher_key); + m_block_cipher_cbc_state = iv.bits_of(); + m_block_size = m_block_cipher->block_size(); + + if(version.supports_explicit_cbc_ivs()) + m_iv_size = m_block_size; m_mac->set_key(mac_key); } diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp index 2f5a0e00d..330135e63 100644 --- a/src/lib/tls/tls_server.cpp +++ b/src/lib/tls/tls_server.cpp @@ -371,7 +371,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state, catch(...) {} m_next_protocol = ""; - if(state.client_hello()->supports_alpn()) + if(m_choose_next_protocol && state.client_hello()->supports_alpn()) m_next_protocol = m_choose_next_protocol(state.client_hello()->next_protocols()); if(resuming) diff --git a/src/lib/tls/tls_version.h b/src/lib/tls/tls_version.h index a025b27ba..73968bb8c 100644 --- a/src/lib/tls/tls_version.h +++ b/src/lib/tls/tls_version.h @@ -8,7 +8,7 @@ #ifndef BOTAN_TLS_PROTOCOL_VERSION_H__ #define BOTAN_TLS_PROTOCOL_VERSION_H__ -#include <botan/get_byte.h> +#include <botan/loadstor.h> #include <string> namespace Botan { diff --git a/src/lib/vendor/boost/info.txt b/src/lib/utils/boost/info.txt index 8748c0bf1..8748c0bf1 100644 --- a/src/lib/vendor/boost/info.txt +++ b/src/lib/utils/boost/info.txt diff --git a/src/lib/utils/bswap.h b/src/lib/utils/bswap.h index 6773b196d..beb3f9555 100644 --- a/src/lib/utils/bswap.h +++ b/src/lib/utils/bswap.h @@ -31,7 +31,7 @@ inline u16bit reverse_bytes(u16bit val) */ inline u32bit reverse_bytes(u32bit val) { -#if BOTAN_GCC_VERSION >= 430 && !defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) +#if BOTAN_GCC_VERSION >= 430 && !defined(BOTAN_TARGET_ARCH_IS_ARM32) /* GCC intrinsic added in 4.3, works for a number of CPUs @@ -47,7 +47,7 @@ inline u32bit reverse_bytes(u32bit val) asm("bswapl %0" : "=r" (val) : "0" (val)); return val; -#elif defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) +#elif defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_TARGET_ARCH_IS_ARM32) asm ("eor r3, %1, %1, ror #16\n\t" "bic r3, r3, #0x00FF0000\n\t" diff --git a/src/lib/utils/cpuid.cpp b/src/lib/utils/cpuid.cpp index 817bf4f52..c98829789 100644 --- a/src/lib/utils/cpuid.cpp +++ b/src/lib/utils/cpuid.cpp @@ -7,7 +7,7 @@ #include <botan/cpuid.h> #include <botan/types.h> -#include <botan/get_byte.h> +#include <botan/loadstor.h> #include <botan/mem_ops.h> #include <ostream> @@ -157,6 +157,19 @@ bool altivec_check_pvr_emul() } +bool CPUID::has_simd_32() + { +#if defined(BOTAN_HAS_SIMD_SSE2) + return CPUID::has_sse2(); +#elif defined(BOTAN_HAS_SIMD_ALTIVEC) + return CPUID::has_altivec(); +#elif defined(BOTAN_HAS_SIMD_SCALAR) + return true; +#else + return false; +#endif + } + void CPUID::print(std::ostream& o) { o << "CPUID flags: "; diff --git a/src/lib/utils/cpuid.h b/src/lib/utils/cpuid.h index 5d8093753..36c301c2f 100644 --- a/src/lib/utils/cpuid.h +++ b/src/lib/utils/cpuid.h @@ -118,6 +118,8 @@ class BOTAN_DLL CPUID static bool has_rdseed() { return x86_processor_flags_has(CPUID_RDSEED_BIT); } + static bool has_simd_32(); + static void print(std::ostream& o); private: enum CPUID_bits { diff --git a/src/lib/utils/ct_utils.h b/src/lib/utils/ct_utils.h new file mode 100644 index 000000000..4ae735330 --- /dev/null +++ b/src/lib/utils/ct_utils.h @@ -0,0 +1,132 @@ +/* +* Functions for constant time operations on data and testing of +* constant time annotations using ctgrind. +* +* For more information about constant time programming see +* Wagner, Molnar, et al "The Program Counter Security Model" +* +* (C) 2010 Falko Strenzke +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_TIMING_ATTACK_CM_H__ +#define BOTAN_TIMING_ATTACK_CM_H__ + +#include <botan/types.h> +#include <vector> + +#if defined(BOTAN_USE_CTGRIND) + +// These are external symbols from libctgrind.so +extern "C" void ct_poison(const void* address, size_t length); +extern "C" void ct_unpoison(const void* address, size_t length); + +#endif + +namespace Botan { + +#if defined(BOTAN_USE_CTGRIND) + +#define BOTAN_CONST_TIME_POISON(p, l) ct_poison(p, l) +#define BOTAN_CONST_TIME_UNPOISON(p, l) ct_unpoison(p, l) + +#else + +#define BOTAN_CONST_TIME_POISON(p, l) +#define BOTAN_CONST_TIME_UNPOISON(p, l) + +#endif + +/* +* Expand to a mask used for other operations +* @param in an integer +* @return 0 if in == 0 else 0xFFFFFFFF +*/ +inline uint32_t ct_expand_mask_32(uint32_t x) + { + // First fold x down to a single bit: + uint32_t r = x; + r |= r >> 16; + r |= r >> 8; + r |= r >> 4; + r |= r >> 2; + r |= r >> 1; + r &= 1; + // assumes 2s complement signed representation + r = ~(r - 1); + return r; + } + +inline uint32_t ct_select_mask_32(uint32_t mask, uint32_t a, uint32_t b) + { + return (a & mask) | (b & ~mask); + } + +inline uint32_t ct_is_zero_32(uint32_t x) + { + return ~ct_expand_mask_32(x); + } + +inline uint32_t ct_is_equal_32(uint32_t x, uint32_t y) + { + return ct_is_zero_32(x ^ y); + } + +inline uint16_t ct_expand_mask_16(uint16_t x) + { + uint16_t r = x; + r |= r >> 8; + r |= r >> 4; + r |= r >> 2; + r |= r >> 1; + r &= 1; + r = ~(r - 1); + return r; + } + +inline uint16_t ct_select_mask_16(uint16_t mask, uint16_t a, uint16_t b) + { + return (a & mask) | (b & ~mask); + } + +inline uint16_t ct_is_zero_16(uint16_t x) + { + return ~ct_expand_mask_16(x); + } + +inline uint16_t ct_is_equal_16(uint16_t x, uint16_t y) + { + return ct_is_zero_16(x ^ y); + } + +inline uint8_t ct_expand_mask_8(uint8_t x) + { + uint8_t r = x; + r |= r >> 4; + r |= r >> 2; + r |= r >> 1; + r &= 1; + r = ~(r - 1); + return r; + } + +inline uint8_t ct_select_mask_8(uint8_t mask, uint8_t a, uint8_t b) + { + return (a & mask) | (b & ~mask); + } + +inline uint8_t ct_is_zero_8(uint8_t x) + { + return ~ct_expand_mask_8(x); + } + +inline uint8_t ct_is_equal_8(uint8_t x, uint8_t y) + { + return ct_is_zero_8(x ^ y); + } + +} + +#endif diff --git a/src/lib/filters/data_src.cpp b/src/lib/utils/data_src.cpp index 4e0725943..4e0725943 100644 --- a/src/lib/filters/data_src.cpp +++ b/src/lib/utils/data_src.cpp diff --git a/src/lib/filters/data_src.h b/src/lib/utils/data_src.h index 2b6998448..2b6998448 100644 --- a/src/lib/filters/data_src.h +++ b/src/lib/utils/data_src.h diff --git a/src/lib/utils/datastor/info.txt b/src/lib/utils/datastor/info.txt index b91fe5082..e69de29bb 100644 --- a/src/lib/utils/datastor/info.txt +++ b/src/lib/utils/datastor/info.txt @@ -1,3 +0,0 @@ -<requires> -alloc -</requires> diff --git a/src/lib/utils/exceptn.h b/src/lib/utils/exceptn.h index 7e16a5dec..eef1b4d43 100644 --- a/src/lib/utils/exceptn.h +++ b/src/lib/utils/exceptn.h @@ -113,6 +113,16 @@ struct BOTAN_DLL Algorithm_Not_Found : public Lookup_Error }; /** +* No_Provider_Found Exception +*/ +struct BOTAN_DLL No_Provider_Found : public Exception + { + No_Provider_Found(const std::string& name) : + Exception("Could not find any provider for algorithm named \"" + name + "\"") + {} + }; + +/** * Invalid_Algorithm_Name Exception */ struct BOTAN_DLL Invalid_Algorithm_Name : public Invalid_Argument diff --git a/src/lib/utils/filesystem.cpp b/src/lib/utils/filesystem.cpp index 950d4d4e2..8d51e64bd 100644 --- a/src/lib/utils/filesystem.cpp +++ b/src/lib/utils/filesystem.cpp @@ -86,7 +86,7 @@ std::vector<std::string> impl_readdir(const std::string& dir_path) const std::string filename = dirent->d_name; if(filename == "." || filename == "..") continue; - const std::string full_path = cur_path + '/' + filename; + const std::string full_path = cur_path + "/" + filename; struct stat stat_buf; diff --git a/src/lib/utils/get_byte.h b/src/lib/utils/get_byte.h index 0846befbd..14f55b97b 100644 --- a/src/lib/utils/get_byte.h +++ b/src/lib/utils/get_byte.h @@ -12,18 +12,6 @@ namespace Botan { -/** -* Byte extraction -* @param byte_num which byte to extract, 0 == highest byte -* @param input the value to extract from -* @return byte byte_num of input -*/ -template<typename T> inline byte get_byte(size_t byte_num, T input) - { - return static_cast<byte>( - input >> ((sizeof(T)-1-(byte_num&(sizeof(T)-1))) << 3) - ); - } } diff --git a/src/lib/utils/info.txt b/src/lib/utils/info.txt index b8c7b85d2..228fccd82 100644 --- a/src/lib/utils/info.txt +++ b/src/lib/utils/info.txt @@ -1,4 +1,4 @@ -define UTIL_FUNCTIONS 20140123 +define UTIL_FUNCTIONS 20150919 load_on always @@ -8,9 +8,9 @@ bswap.h calendar.h charset.h cpuid.h +data_src.h database.h exceptn.h -get_byte.h loadstor.h mem_ops.h mul128.h @@ -22,12 +22,11 @@ version.h <header:internal> bit_ops.h +ct_utils.h donna128.h filesystem.h prefetch.h rounding.h semaphore.h stl_util.h -ta_utils.h -xor_buf.h </header:internal> diff --git a/src/lib/utils/loadstor.h b/src/lib/utils/loadstor.h index d3871480c..53700fc86 100644 --- a/src/lib/utils/loadstor.h +++ b/src/lib/utils/loadstor.h @@ -11,7 +11,6 @@ #include <botan/types.h> #include <botan/bswap.h> -#include <botan/get_byte.h> #include <botan/mem_ops.h> #include <vector> @@ -40,6 +39,19 @@ namespace Botan { /** +* Byte extraction +* @param byte_num which byte to extract, 0 == highest byte +* @param input the value to extract from +* @return byte byte_num of input +*/ +template<typename T> inline byte get_byte(size_t byte_num, T input) + { + return static_cast<byte>( + input >> ((sizeof(T)-1-(byte_num&(sizeof(T)-1))) << 3) + ); + } + +/** * Make a u16bit from two bytes * @param i0 the first byte * @param i1 the second byte diff --git a/src/lib/alloc/locking_allocator/info.txt b/src/lib/utils/locking_allocator/info.txt index d3b5e86f8..d3b5e86f8 100644 --- a/src/lib/alloc/locking_allocator/info.txt +++ b/src/lib/utils/locking_allocator/info.txt diff --git a/src/lib/alloc/locking_allocator/locking_allocator.cpp b/src/lib/utils/locking_allocator/locking_allocator.cpp index 6a9cc2579..c145cfd7f 100644 --- a/src/lib/alloc/locking_allocator/locking_allocator.cpp +++ b/src/lib/utils/locking_allocator/locking_allocator.cpp @@ -18,15 +18,11 @@ namespace Botan { namespace { -/** -* Requests for objects of sizeof(T) will be aligned at -* sizeof(T)*ALIGNMENT_MULTIPLE bytes. -*/ -const size_t ALIGNMENT_MULTIPLE = 2; - size_t reset_mlock_limit(size_t max_req) { +#if defined(RLIMIT_MEMLOCK) struct rlimit limits; + ::getrlimit(RLIMIT_MEMLOCK, &limits); if(limits.rlim_cur < limits.rlim_max) @@ -37,6 +33,9 @@ size_t reset_mlock_limit(size_t max_req) } return std::min<size_t>(limits.rlim_cur, max_req); +#endif + + return 0; } size_t mlock_limit() @@ -99,7 +98,7 @@ void* mlock_allocator::allocate(size_t num_elems, size_t elem_size) return nullptr; const size_t n = num_elems * elem_size; - const size_t alignment = ALIGNMENT_MULTIPLE * elem_size; + const size_t alignment = 16; if(n / elem_size != num_elems) return nullptr; // overflow! diff --git a/src/lib/alloc/locking_allocator/locking_allocator.h b/src/lib/utils/locking_allocator/locking_allocator.h index 2aca2dfa9..2aca2dfa9 100644 --- a/src/lib/alloc/locking_allocator/locking_allocator.h +++ b/src/lib/utils/locking_allocator/locking_allocator.h diff --git a/src/lib/utils/mem_ops.h b/src/lib/utils/mem_ops.h index f9e39fa31..6ea7bdafe 100644 --- a/src/lib/utils/mem_ops.h +++ b/src/lib/utils/mem_ops.h @@ -10,6 +10,7 @@ #include <botan/types.h> #include <cstring> +#include <vector> namespace Botan { @@ -70,6 +71,132 @@ template<typename T> inline bool same_mem(const T* p1, const T* p2, size_t n) return difference == 0; } +/** +* XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length +* @param out the input/output buffer +* @param in the read-only input buffer +* @param length the length of the buffers +*/ +template<typename T> +void xor_buf(T out[], const T in[], size_t length) + { + while(length >= 8) + { + out[0] ^= in[0]; out[1] ^= in[1]; + out[2] ^= in[2]; out[3] ^= in[3]; + out[4] ^= in[4]; out[5] ^= in[5]; + out[6] ^= in[6]; out[7] ^= in[7]; + + out += 8; in += 8; length -= 8; + } + + for(size_t i = 0; i != length; ++i) + out[i] ^= in[i]; + } + +/** +* XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length +* @param out the output buffer +* @param in the first input buffer +* @param in2 the second output buffer +* @param length the length of the three buffers +*/ +template<typename T> void xor_buf(T out[], + const T in[], + const T in2[], + size_t length) + { + while(length >= 8) + { + out[0] = in[0] ^ in2[0]; + out[1] = in[1] ^ in2[1]; + out[2] = in[2] ^ in2[2]; + out[3] = in[3] ^ in2[3]; + out[4] = in[4] ^ in2[4]; + out[5] = in[5] ^ in2[5]; + out[6] = in[6] ^ in2[6]; + out[7] = in[7] ^ in2[7]; + + in += 8; in2 += 8; out += 8; length -= 8; + } + + for(size_t i = 0; i != length; ++i) + out[i] = in[i] ^ in2[i]; + } + +#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK + +template<> +inline void xor_buf<byte>(byte out[], const byte in[], size_t length) + { + while(length >= 8) + { + *reinterpret_cast<u64bit*>(out) ^= *reinterpret_cast<const u64bit*>(in); + out += 8; in += 8; length -= 8; + } + + for(size_t i = 0; i != length; ++i) + out[i] ^= in[i]; + } + +template<> +inline void xor_buf<byte>(byte out[], + const byte in[], + const byte in2[], + size_t length) + { + while(length >= 8) + { + *reinterpret_cast<u64bit*>(out) = + *reinterpret_cast<const u64bit*>(in) ^ + *reinterpret_cast<const u64bit*>(in2); + + in += 8; in2 += 8; out += 8; length -= 8; + } + + for(size_t i = 0; i != length; ++i) + out[i] = in[i] ^ in2[i]; + } + +#endif + +template<typename Alloc, typename Alloc2> +void xor_buf(std::vector<byte, Alloc>& out, + const std::vector<byte, Alloc2>& in, + size_t n) + { + xor_buf(out.data(), in.data(), n); + } + +template<typename Alloc> +void xor_buf(std::vector<byte, Alloc>& out, + const byte* in, + size_t n) + { + xor_buf(out.data(), in, n); + } + +template<typename Alloc, typename Alloc2> +void xor_buf(std::vector<byte, Alloc>& out, + const byte* in, + const std::vector<byte, Alloc2>& in2, + size_t n) + { + xor_buf(out.data(), in, in2.data(), n); + } + +template<typename T, typename Alloc, typename Alloc2> +std::vector<T, Alloc>& +operator^=(std::vector<T, Alloc>& out, + const std::vector<T, Alloc2>& in) + { + if(out.size() < in.size()) + out.resize(in.size()); + + xor_buf(out.data(), in.data(), in.size()); + return out; + } + } #endif diff --git a/src/lib/utils/openssl/info.txt b/src/lib/utils/openssl/info.txt new file mode 100644 index 000000000..13ea92cbf --- /dev/null +++ b/src/lib/utils/openssl/info.txt @@ -0,0 +1,16 @@ +define OPENSSL 20150829 + +# This base module doesn't have any code, but other code using openssl +# rely on it either macro check for BOTAN_HAS_OPENSSL or a module +# dependency on openssl to test for the existence of and desire to use +# OpenSSL for certain operations. + +load_on vendor + +<header:internal> +openssl.h +</header:internal> + +<libs> +all -> crypto +</libs> diff --git a/src/lib/utils/openssl/openssl.h b/src/lib/utils/openssl/openssl.h new file mode 100644 index 000000000..05d3e953f --- /dev/null +++ b/src/lib/utils/openssl/openssl.h @@ -0,0 +1,35 @@ +/* +* Utils for calling OpenSSL +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_OPENSSL_H__ +#define BOTAN_OPENSSL_H__ + +#include <botan/secmem.h> +#include <botan/exceptn.h> +#include <memory> + +#include <openssl/err.h> + +namespace Botan { + +class OpenSSL_Error : public Exception + { + public: + OpenSSL_Error(const std::string& what) : + Exception(what + " failed: " + ERR_error_string(ERR_get_error(), nullptr)) {} + }; + +#define BOTAN_OPENSSL_BLOCK_PRIO 150 +#define BOTAN_OPENSSL_HASH_PRIO 150 +#define BOTAN_OPENSSL_RC4_PRIO 150 + +#define BOTAN_OPENSSL_RSA_PRIO 90 +#define BOTAN_OPENSSL_ECDSA_PRIO 90 + +} + +#endif diff --git a/src/lib/utils/parsing.cpp b/src/lib/utils/parsing.cpp index 4feea8d60..ea89c8e5f 100644 --- a/src/lib/utils/parsing.cpp +++ b/src/lib/utils/parsing.cpp @@ -9,7 +9,7 @@ #include <botan/parsing.h> #include <botan/exceptn.h> #include <botan/charset.h> -#include <botan/get_byte.h> +#include <botan/loadstor.h> #include <limits> #include <set> #include <stdexcept> diff --git a/src/lib/utils/simd/simd_altivec/simd_altivec.h b/src/lib/utils/simd/simd_altivec/simd_altivec.h index 32533aafb..0a77d60fa 100644 --- a/src/lib/utils/simd/simd_altivec/simd_altivec.h +++ b/src/lib/utils/simd/simd_altivec/simd_altivec.h @@ -22,8 +22,6 @@ namespace Botan { class SIMD_Altivec { public: - static bool enabled() { return CPUID::has_altivec(); } - SIMD_Altivec(const u32bit B[4]) { m_reg = (__vector unsigned int){B[0], B[1], B[2], B[3]}; diff --git a/src/lib/utils/simd/simd_scalar/simd_scalar.h b/src/lib/utils/simd/simd_scalar/simd_scalar.h index 379e2d6a8..28d72c615 100644 --- a/src/lib/utils/simd/simd_scalar/simd_scalar.h +++ b/src/lib/utils/simd/simd_scalar/simd_scalar.h @@ -21,8 +21,6 @@ template<typename T, size_t N> class SIMD_Scalar { public: - static bool enabled() { return true; } - static size_t size() { return N; } SIMD_Scalar() { /* uninitialized */ } diff --git a/src/lib/utils/simd/simd_sse2/simd_sse2.h b/src/lib/utils/simd/simd_sse2/simd_sse2.h index 61989eb8e..9e85bd45b 100644 --- a/src/lib/utils/simd/simd_sse2/simd_sse2.h +++ b/src/lib/utils/simd/simd_sse2/simd_sse2.h @@ -18,8 +18,6 @@ namespace Botan { class SIMD_SSE2 { public: - static bool enabled() { return CPUID::has_sse2(); } - SIMD_SSE2(const u32bit B[4]) { reg = _mm_loadu_si128(reinterpret_cast<const __m128i*>(B)); diff --git a/src/lib/vendor/sqlite3/info.txt b/src/lib/utils/sqlite3/info.txt index 98ce5f796..98ce5f796 100644 --- a/src/lib/vendor/sqlite3/info.txt +++ b/src/lib/utils/sqlite3/info.txt diff --git a/src/lib/vendor/sqlite3/sqlite3.cpp b/src/lib/utils/sqlite3/sqlite3.cpp index be3c2b227..be3c2b227 100644 --- a/src/lib/vendor/sqlite3/sqlite3.cpp +++ b/src/lib/utils/sqlite3/sqlite3.cpp diff --git a/src/lib/vendor/sqlite3/sqlite3.h b/src/lib/utils/sqlite3/sqlite3.h index 8495a1d1b..8495a1d1b 100644 --- a/src/lib/vendor/sqlite3/sqlite3.h +++ b/src/lib/utils/sqlite3/sqlite3.h diff --git a/src/lib/utils/ta_utils.cpp b/src/lib/utils/ta_utils.cpp deleted file mode 100644 index 8aee726ec..000000000 --- a/src/lib/utils/ta_utils.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* Timing Attack Countermeasure Functions -* (C) 2010 Falko Strenzke, Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include <botan/internal/ta_utils.h> - -namespace Botan { - -namespace TA_CM { - -/* -* We use volatile in these functions in an attempt to ensure that the -* compiler doesn't optimize in a way that would create branching -* operations. -* -* Note: this needs further testing; on at least x86-64 with GCC, -* volatile is not required to get branch-free operations, it just -* makes the functions much longer/slower. It may not be required -* anywhere. -*/ - -namespace { - -template<typename T> -T expand_mask(T x) - { - volatile T r = x; - for(size_t i = 1; i != sizeof(T) * 8; i *= 2) - r |= r >> i; - r &= 1; - r = ~(r - 1); - return r; - } - -} - -u32bit expand_mask_u32bit(u32bit in) - { - return expand_mask<u32bit>(in); - } - -u16bit expand_mask_u16bit(u16bit in) - { - return expand_mask<u16bit>(in); - } - -u32bit max_32(u32bit a, u32bit b) - { - const u32bit a_larger = b - a; /* negative if a larger */ - const u32bit mask = expand_mask<u32bit>(a_larger >> 31); - return (a & mask) | (b & ~mask); - } - -u32bit min_32(u32bit a, u32bit b) - { - const u32bit a_larger = b - a; /* negative if a larger */ - const u32bit mask = expand_mask<u32bit>(a_larger >> 31); - return (a & ~mask) | (b & mask); - } - -} - -} diff --git a/src/lib/utils/ta_utils.h b/src/lib/utils/ta_utils.h deleted file mode 100644 index 9353214b2..000000000 --- a/src/lib/utils/ta_utils.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -* Timing Attack Countermeasure Functions -* (C) 2010 Falko Strenzke, Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_TIMING_ATTACK_CM_H__ -#define BOTAN_TIMING_ATTACK_CM_H__ - -#include <botan/types.h> - -namespace Botan { - -namespace TA_CM { - -/** -* Function used in timing attack countermeasures -* See Wagner, Molnar, et al "The Program Counter Security Model" -* -* @param in an integer -* @return 0 if in == 0 else 0xFFFFFFFF -*/ -u32bit expand_mask_u32bit(u32bit in); - - -/** - * Expand an input to a bit mask depending on it being being zero or - * non-zero - * @ param in the input - * @return the mask 0xFFFF if tst is non-zero and 0 otherwise - */ -u16bit expand_mask_u16bit(u16bit in); - -/** -* Branch-free maximum -* Note: assumes twos-complement signed representation -* @param a an integer -* @param b an integer -* @return max(a,b) -*/ -u32bit max_32(u32bit a, u32bit b); - -/** -* Branch-free minimum -* Note: assumes twos-complement signed representation -* @param a an integer -* @param b an integer -* @return min(a,b) -*/ -u32bit min_32(u32bit a, u32bit b); - -} - -} - -#endif diff --git a/src/lib/vendor/openssl/info.txt b/src/lib/vendor/openssl/info.txt deleted file mode 100644 index a1faac3e3..000000000 --- a/src/lib/vendor/openssl/info.txt +++ /dev/null @@ -1,5 +0,0 @@ -load_on vendor - -<libs> -all -> crypto -</libs> diff --git a/src/lib/vendor/openssl/openssl_rsa.cpp b/src/lib/vendor/openssl/openssl_rsa.cpp deleted file mode 100644 index ef86bf91a..000000000 --- a/src/lib/vendor/openssl/openssl_rsa.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* -* OpenSSL RSA interface -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include <botan/build.h> - -#if defined(BOTAN_HAS_RSA) - -#include <botan/rsa.h> -#include <botan/internal/pk_utils.h> -#include <functional> -#include <memory> - -#include <openssl/rsa.h> -#include <openssl/x509.h> -#include <openssl/err.h> - -namespace Botan { - -namespace { - -std::pair<int, size_t> get_openssl_enc_pad(const std::string& eme) - { - if(eme == "Raw") - return std::make_pair(RSA_NO_PADDING, 0); - else if(eme == "EME-PKCS1-v1_5") - return std::make_pair(RSA_PKCS1_PADDING, 11); - else if(eme == "EME1(SHA-1)") - return std::make_pair(RSA_PKCS1_OAEP_PADDING, 41); - else - throw Lookup_Error("OpenSSL RSA does not support EME " + eme); - } - -class OpenSSL_Error : public Exception - { - public: - OpenSSL_Error(const std::string& what) : - Exception(what + " failed: " + ERR_error_string(ERR_get_error(), nullptr)) {} - }; - -class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption - { - public: - typedef RSA_PublicKey Key_Type; - - static OpenSSL_RSA_Encryption_Operation* make(const Spec& spec) - { - try - { - if(auto* key = dynamic_cast<const RSA_PublicKey*>(&spec.key())) - { - auto pad_info = get_openssl_enc_pad(spec.padding()); - return new OpenSSL_RSA_Encryption_Operation(*key, pad_info.first, pad_info.second); - } - } - catch(...) {} - - return nullptr; - } - - OpenSSL_RSA_Encryption_Operation(const RSA_PublicKey& rsa, int pad, size_t pad_overhead) : - m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad) - { - const std::vector<byte> der = rsa.x509_subject_public_key(); - const byte* der_ptr = der.data(); - m_openssl_rsa.reset(d2i_RSAPublicKey(nullptr, &der_ptr, der.size())); - if(!m_openssl_rsa) - throw OpenSSL_Error("d2i_RSAPublicKey"); - - m_bits = 8 * (RSA_size(m_openssl_rsa.get()) - pad_overhead); - } - - size_t max_input_bits() const override { return m_bits; }; - - secure_vector<byte> encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator&) override - { - - secure_vector<byte> buf(::RSA_size(m_openssl_rsa.get())); - int rc = ::RSA_public_encrypt(msg_len, msg, buf.data(), m_openssl_rsa.get(), m_padding); - if(rc < 0) - throw OpenSSL_Error("RSA_public_encrypt"); - return buf; - } - - private: - std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa; - size_t m_bits = 0; - int m_padding = 0; - }; - -class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption - { - public: - typedef RSA_PrivateKey Key_Type; - - static OpenSSL_RSA_Decryption_Operation* make(const Spec& spec) - { - try - { - if(auto* key = dynamic_cast<const RSA_PrivateKey*>(&spec.key())) - { - auto pad_info = get_openssl_enc_pad(spec.padding()); - return new OpenSSL_RSA_Decryption_Operation(*key, pad_info.first); - } - } - catch(...) {} - - return nullptr; - } - - OpenSSL_RSA_Decryption_Operation(const RSA_PrivateKey& rsa, int pad) : - m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad) - { - const secure_vector<byte> der = rsa.pkcs8_private_key(); - const byte* der_ptr = der.data(); - m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size())); - if(!m_openssl_rsa) - throw OpenSSL_Error("d2i_RSAPrivateKey"); - - m_bits = 8 * RSA_size(m_openssl_rsa.get()); - } - - size_t max_input_bits() const override { return m_bits; }; - - secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override - { - secure_vector<byte> buf(::RSA_size(m_openssl_rsa.get())); - int rc = ::RSA_private_decrypt(msg_len, msg, buf.data(), m_openssl_rsa.get(), m_padding); - if(rc < 0 || static_cast<size_t>(rc) > buf.size()) - throw OpenSSL_Error("RSA_private_decrypt"); - buf.resize(rc); - return buf; - } - - private: - std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa; - size_t m_bits = 0; - int m_padding = 0; - }; - -BOTAN_REGISTER_TYPE(PK_Ops::Encryption, OpenSSL_RSA_Encryption_Operation, "RSA", - OpenSSL_RSA_Encryption_Operation::make, "openssl", 255); -BOTAN_REGISTER_TYPE(PK_Ops::Decryption, OpenSSL_RSA_Decryption_Operation, "RSA", - OpenSSL_RSA_Decryption_Operation::make, "openssl", 255); - -} - -} - -#endif // BOTAN_HAS_RSA |