diff options
54 files changed, 800 insertions, 261 deletions
diff --git a/checks/aead.vec b/checks/aead.vec index 4d9f39556..bc75ca489 100644 --- a/checks/aead.vec +++ b/checks/aead.vec @@ -1,3 +1,4 @@ + AEAD = AES-128/SIV Plaintext = 112233445566778899AABBCCDDEE Key = FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF @@ -10,3 +11,10 @@ Key = 7F7E7D7C7B7A79787776757473727170404142434445464748494A4B4C4D4E4F AD = 00112233445566778899AABBCCDDEEFFDEADDADADEADDADAFFEEDDCCBBAA99887766554433221100 Nonce = 09F911029D74E35BD84156C5635688C1 Ciphertext = E21A9D0FE3BD3ED189C71F29B24C39E1E40B9BAB82D428D0A9B392F13EA14C9B4433F393595A8E031F032350F50D2B21825B3EE64958103BD8445C3F48E5CF + +AEAD = AES-128/OCB +Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +AD = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +Nonce = 000102030405060708090A0B +Key = 000102030405060708090A0B0C0D0E0F +Ciphertext = BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A657149D53773463CB68C65778B058A635659C623211DEEA0DE30D2C381879F4C8 diff --git a/checks/bench.h b/checks/bench.h index b423a2215..3840bc112 100644 --- a/checks/bench.h +++ b/checks/bench.h @@ -17,4 +17,6 @@ bool bench_algo(const std::string& algo_name, void bench_pk(Botan::RandomNumberGenerator&, const std::string&, double seconds); +void time_transform(const std::string& algo); + #endif diff --git a/checks/ecdh.cpp b/checks/ecdh.cpp index 841bce55b..178282047 100644 --- a/checks/ecdh.cpp +++ b/checks/ecdh.cpp @@ -12,7 +12,7 @@ #include "validate.h" #include "common.h" -#if defined(BOTAN_HAS_ECDH) +#if defined(BOTAN_HAS_ECDH) && defined(BOTAN_HAS_X509) #include <iostream> #include <fstream> diff --git a/checks/ecdsa.cpp b/checks/ecdsa.cpp index a43de69c5..2506e1389 100644 --- a/checks/ecdsa.cpp +++ b/checks/ecdsa.cpp @@ -8,7 +8,7 @@ #include "validate.h" -#if defined(BOTAN_HAS_ECDSA) +#if defined(BOTAN_HAS_ECDSA) && defined(BOTAN_HAS_X509) #include <botan/botan.h> #include <botan/pubkey.h> diff --git a/checks/ocb.cpp b/checks/ocb.cpp index d2fbbeeb3..3cb9c4c09 100644 --- a/checks/ocb.cpp +++ b/checks/ocb.cpp @@ -126,33 +126,6 @@ void test_ocb_long(size_t taglen, const std::string &expected) void test_ocb() { - SymmetricKey key("000102030405060708090A0B0C0D0E0F"); - - std::vector<byte> nonce = hex_decode("000102030405060708090A0B"); - - std::vector<byte> pt = hex_decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627"); - std::vector<byte> ad = hex_decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627"); - - const std::string expected = "BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A657149D53773463CB68C65778B058A635659C623211DEEA0DE30D2C381879F4C8"; - - std::vector<byte> ctext = ocb_encrypt(key, nonce, pt, ad); - - const std::string ctext_hex = hex_encode(ctext); - - if(ctext_hex != expected) - std::cout << "OCB/AES-128 encrypt test failure\n" << ctext_hex << " !=\n" << expected << "\n"; - - try - { - std::vector<byte> dec = ocb_decrypt(key, nonce, ctext, ad); - - if(dec != pt) std::cout << "OCB fails to decrypt\n"; - } - catch(std::exception& e) - { - std::cout << "Correct OCB message rejected - " << e.what() << "\n"; - } - test_ocb_long(128, "B2B41CBF9B05037DA7F16C24A35C1C94"); test_ocb_long(96, "1A4F0654277709A5BDA0D380"); test_ocb_long(64, "B7ECE9D381FE437F"); diff --git a/checks/tests.cpp b/checks/tests.cpp index fdaccd805..db934735e 100644 --- a/checks/tests.cpp +++ b/checks/tests.cpp @@ -31,10 +31,16 @@ void run_tests_bb(std::istream& src, if(key == output_key) { ++test_cnt; - bool passed = cb(vars); - - if(!passed) + try + { + if(!cb(vars)) + ++test_fail; + } + catch(std::exception& e) + { + std::cout << e.what() << "\n"; ++test_fail; + } if(clear_between_cb) vars.clear(); diff --git a/checks/tls.cpp b/checks/tls.cpp index 55236515d..c0b85cc7e 100644 --- a/checks/tls.cpp +++ b/checks/tls.cpp @@ -1,3 +1,7 @@ +#include "validate.h" + +#if defined(BOTAN_HAS_TLS) + #include <botan/tls_server.h> #include <botan/tls_client.h> #include <botan/pkcs10.h> @@ -6,7 +10,6 @@ #include <botan/x509_ca.h> #include <botan/hex.h> -#include "validate.h" #include <iostream> #include <vector> #include <memory> @@ -268,3 +271,7 @@ size_t do_tls_tests(RandomNumberGenerator& rng) return errors; } + +#else +size_t do_tls_tests(RandomNumberGenerator&) { return 0; } +#endif diff --git a/checks/transform.cpp b/checks/transform.cpp new file mode 100644 index 000000000..71ecc35e7 --- /dev/null +++ b/checks/transform.cpp @@ -0,0 +1,83 @@ +#include "validate.h" +#include "bench.h" + +#include <botan/libstate.h> +#include <botan/botan.h> +#include <botan/threefish.h> +#include <botan/benchmark.h> +#include <botan/hex.h> +#include <iostream> +#include <fstream> + +using namespace Botan; + +namespace { + +Transformation* get_transform(const std::string& algo) + { + if(algo == "Threefish-512") + return new Threefish_512; + + throw std::runtime_error("Unknown transform " + algo); + } + +secure_vector<byte> transform_test(const std::string& algo, + const secure_vector<byte>& nonce, + const secure_vector<byte>& key, + const secure_vector<byte>& in) + { + std::unique_ptr<Transformation> transform(get_transform(algo)); + + transform->set_key(key); + transform->start_vec(nonce); + + secure_vector<byte> out = in; + transform->update(out, 0); + + return out; + } + +} + +void test_transform() + { + std::ifstream vec("checks/transform.vec"); + + run_tests(vec, "Transform", "Output", true, + [](std::map<std::string, std::string> m) + { + return hex_encode(transform_test(m["Transform"], + hex_decode_locked(m["Nonce"]), + hex_decode_locked(m["Key"]), + hex_decode_locked(m["Input"]))); + }); + + //time_transform("Threefish-512"); + } + +void time_transform(const std::string& algo) + { + std::unique_ptr<Transformation> tf(get_transform(algo)); + + AutoSeeded_RNG rng; + + tf->set_key(rng.random_vec(tf->maximum_keylength())); + tf->start_vec(rng.random_vec(tf->default_nonce_length())); + + for(size_t mult : { 1, 2, 4, 8, 16, 128 }) + { + const size_t buf_size = mult*tf->update_granularity(); + + secure_vector<byte> buffer(buf_size); + + double res = time_op(std::chrono::seconds(1), + [&tf,&buffer,buf_size]{ + tf->update(buffer); + buffer.resize(buf_size); + }); + + const u64bit Mbytes = (res * buf_size) / 1024 / 1024; + + std::cout << Mbytes << " MiB / second in " << buf_size << " byte blocks\n"; + } + } diff --git a/checks/transform.vec b/checks/transform.vec new file mode 100644 index 000000000..8f8a155e0 --- /dev/null +++ b/checks/transform.vec @@ -0,0 +1,12 @@ + +Transform = Threefish-512 +Input = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +Key = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +Nonce = 00000000000000000000000000000000 +Output = B1A2BBC6EF6025BC40EB3822161F36E375D1BB0AEE3186FBD19E47C5D479947B7BC2F8586E35F0CFF7E7F03084B0B7B1F1AB3961A580A3E97EB41EA14A6D7BBE + +Transform = Threefish-512 +Input = FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0 +Nonce = 000102030405060708090A0B0C0D0E0F +Key = 101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Output = E304439626D45A2CB401CAD8D636249A6338330EB06D45DD8B36B90E97254779272A0A8D99463504784420EA18C9A725AF11DFFEA10162348927673D5C1CAF3D diff --git a/checks/validate.cpp b/checks/validate.cpp index 48932f0e4..866f414eb 100644 --- a/checks/validate.cpp +++ b/checks/validate.cpp @@ -418,6 +418,7 @@ u32bit do_validation_tests(const std::string& filename, if(should_pass) { + test_transform(); test_ocb(); test_hkdf(); test_pbkdf(); diff --git a/checks/validate.h b/checks/validate.h index 48830619b..bb4114c3f 100644 --- a/checks/validate.h +++ b/checks/validate.h @@ -39,6 +39,7 @@ void test_hkdf(); void test_pbkdf(); void test_kdf(); void test_aead(); +void test_transform(); void run_tests_bb(std::istream& src, const std::string& name_key, diff --git a/configure.py b/configure.py index 211b59547..607471e27 100755 --- a/configure.py +++ b/configure.py @@ -229,8 +229,11 @@ def process_command_line(args): metavar='BINARY', help='set the name of the compiler binary') - target_group.add_option('--chost', dest='chost', - help=optparse.SUPPRESS_HELP) + target_group.add_option('--cc-abi-flags', metavar='FLAG', + help='set compiler ABI flags', + default='') + + target_group.add_option('--chost', help=optparse.SUPPRESS_HELP) target_group.add_option('--with-endian', metavar='ORDER', default=None, help='override guess of CPU byte order') @@ -811,21 +814,23 @@ class CompilerInfo(object): """ Return the machine specific ABI flags """ - def mach_abi_link_flags(self, osname, arch, submodel, debug_p): - + def mach_abi_link_flags(self, options): def all(): - if debug_p: + if options.debug_build: return 'all-debug' return 'all' abi_link = set() - for what in [all(), osname, arch, submodel]: + for what in [all(), options.os, options.arch, options.cpu]: if self.mach_abi_linking.get(what) != None: abi_link.add(self.mach_abi_linking.get(what)) + for flag in options.cc_abi_flags.split(' '): + abi_link.add(flag) + if len(abi_link) == 0: return '' - return ' ' + ' '.join(abi_link) + return ' ' + ' '.join(sorted(list(abi_link))) """ @@ -1048,6 +1053,9 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): for mod in modules: if src in mod.sources(): if mod.need_isa != None: + if mod.need_isa not in cc.isa_flags: + raise Exception('Compiler does not support %s, required by %s' % ( + mod.need_isa, src)) return cc.isa_flags[mod.need_isa] return '' @@ -1056,12 +1064,12 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): """ def build_commands(sources, obj_dir, flags): for (obj_file,src) in zip(objectfile_list(sources, obj_dir), sources): - yield '%s: %s\n\t$(CXX) %s%s $(%s_FLAGS) %s %s$? %s$@\n' % ( + yield '%s: %s\n\t$(CXX) %s $(%s_FLAGS) %s%s %s$? %s$@\n' % ( obj_file, src, + isa_specific_flags(cc, src), + flags, cc.add_include_dir_option, build_config.include_dir, - flags, - isa_specific_flags(cc, src), cc.compile_option, cc.output_to_option) @@ -1079,8 +1087,9 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): maintainer_flags, maintainer_mode): if maintainer_mode and maintainer_flags != '': - return maintainer_flags - return normal_flags + return maintainer_flags + ' ' + normal_flags + else: + return normal_flags def innosetup_arch(os, arch): if os != 'windows': @@ -1139,9 +1148,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'mp_bits': choose_mp_bits(), - 'cc': (options.compiler_binary or cc.binary_name) + - cc.mach_abi_link_flags(options.os, options.arch, - options.cpu, options.debug_build), + 'cc': (options.compiler_binary or cc.binary_name) + cc.mach_abi_link_flags(options), 'lib_opt': cc.library_opt_flags(options), 'check_opt': '' if options.no_optimizations else cc.check_opt_flags, diff --git a/doc/aead.rst b/doc/aead.rst index cb49f8a51..dbd06bbe1 100644 --- a/doc/aead.rst +++ b/doc/aead.rst @@ -81,3 +81,9 @@ AEAD modes currently available include GCM, OCB, and EAX. All three use a Returns true if *nonce_len* is a valid nonce length for this scheme. For EAX and GCM, any length nonces are allowed. OCB allows any value between 8 and 15 bytes. + + .. cpp:function:: size_t default_nonce_length() const + + Returns a reasonable length for the nonce, typically either 96 + bits, or the only supported length for modes which don't + support 96 bit nonces. diff --git a/doc/examples/cpuid.cpp b/doc/examples/cpuid.cpp index ac3f50580..9ffb810a9 100644 --- a/doc/examples/cpuid.cpp +++ b/doc/examples/cpuid.cpp @@ -35,12 +35,15 @@ int main() print_if_feature("SSSE3", CPUID::has_ssse3()); print_if_feature("SSE4.1", CPUID::has_sse41()); print_if_feature("SSE4.2", CPUID::has_sse42()); - print_if_feature("AVX", CPUID::has_avx()); + print_if_feature("AVX2", CPUID::has_avx2()); + print_if_feature("BMI2", CPUID::has_bmi2()); print_if_feature("AltiVec", CPUID::has_altivec()); print_header("Other extensions"); print_if_feature("RDTSC", CPUID::has_rdtsc()); print_if_feature("PCMUL", CPUID::has_pcmuludq()); print_if_feature("AES-NI", CPUID::has_aes_ni()); - print_if_feature("RDRND", CPUID::has_rdrand()); + print_if_feature("RDRAND", CPUID::has_rdrand()); + print_if_feature("RDSEED", CPUID::has_rdseed()); + print_if_feature("SHA", CPUID::has_intel_sha()); } diff --git a/doc/relnotes/1_11_6.rst b/doc/relnotes/1_11_6.rst index 79b2dca2e..434d8c499 100644 --- a/doc/relnotes/1_11_6.rst +++ b/doc/relnotes/1_11_6.rst @@ -8,7 +8,8 @@ Version 1.11.6, Not Yet Released * Botan now requires Boost, specifically the filesystem and asio libraries. - * The default TLS policy no longer includes RC4 in the cipher list. + * The default TLS policy no longer includes RC4 in the cipher list, and + refuses to negotation SSLv3 by default. * Add HKDF from :rfc:`5869` diff --git a/src/algo_base/info.txt b/src/algo_base/info.txt index cfdd9b691..a2c509f2c 100644 --- a/src/algo_base/info.txt +++ b/src/algo_base/info.txt @@ -1,3 +1,5 @@ +define TRANSFORM 20131209 + <requires> alloc filters diff --git a/src/algo_base/transform.h b/src/algo_base/transform.h index 3f4e80b94..2eec9d85b 100644 --- a/src/algo_base/transform.h +++ b/src/algo_base/transform.h @@ -72,7 +72,11 @@ class BOTAN_DLL Transformation : public SymmetricAlgorithm /** * Return the default size for a nonce */ - virtual size_t default_nonce_size() const = 0; + virtual size_t default_nonce_length() const = 0; + + BOTAN_DEPRECATED("Use default_nonce_length") + size_t default_nonce_size() const + { return default_nonce_length(); } /** * Return true iff nonce_len is a valid length for the nonce diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index 83fd87d1b..396670168 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -18,8 +18,6 @@ namespace Botan { -namespace { - double time_op(std::chrono::nanoseconds runtime, std::function<void ()> op) { std::chrono::nanoseconds time_used(0); @@ -41,8 +39,6 @@ double time_op(std::chrono::nanoseconds runtime, std::function<void ()> op) return reps / seconds_used; // ie, return ops per second } -} - std::map<std::string, double> time_algorithm_ops(const std::string& name, Algorithm_Factory& af, diff --git a/src/benchmark/benchmark.h b/src/benchmark/benchmark.h index 93224dd2e..40784a767 100644 --- a/src/benchmark/benchmark.h +++ b/src/benchmark/benchmark.h @@ -50,6 +50,9 @@ BOTAN_DLL algorithm_benchmark(const std::string& name, std::chrono::milliseconds milliseconds, size_t buf_size); +double BOTAN_DLL +time_op(std::chrono::nanoseconds runtime, std::function<void ()> op); + } #endif diff --git a/src/block/threefish/info.txt b/src/block/threefish/info.txt new file mode 100644 index 000000000..91fc7bfb1 --- /dev/null +++ b/src/block/threefish/info.txt @@ -0,0 +1 @@ +define THREEFISH 20131209 diff --git a/src/block/threefish/threefish.cpp b/src/block/threefish/threefish.cpp new file mode 100644 index 000000000..6fb65a37e --- /dev/null +++ b/src/block/threefish/threefish.cpp @@ -0,0 +1,164 @@ +/* +* Threefish-512 +* (C) 2013 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/threefish.h> +#include <botan/rotate.h> +#include <botan/loadstor.h> + +namespace Botan { + +secure_vector<byte> Threefish_512::start(const byte tweak[], size_t tweak_len) + { + if(!valid_nonce_length(tweak_len)) + throw Invalid_IV_Length(name(), tweak_len); + + m_T.resize(3); + + m_T[0] = load_le<u64bit>(tweak, 0); + m_T[1] = load_le<u64bit>(tweak, 1); + m_T[2] = m_T[0] ^ m_T[1]; + + return secure_vector<byte>(); + } + +void Threefish_512::update(secure_vector<byte>& blocks, size_t offset) + { + byte* buf = &blocks[offset]; + size_t sz = blocks.size() - offset; + + BOTAN_ASSERT(sz % update_granularity() == 0, "Block sized input"); + + BOTAN_ASSERT(m_T.size() == 3, "Tweak was set"); + +#define THREEFISH_ROUND(I1,I2,I3,I4,I5,I6,I7,I8,ROT1,ROT2,ROT3,ROT4) \ + do { \ + X##I1 += X##I2; X##I2 = rotate_left(X##I2, ROT1) ^ X##I1; \ + X##I3 += X##I4; X##I4 = rotate_left(X##I4, ROT2) ^ X##I3; \ + X##I5 += X##I6; X##I6 = rotate_left(X##I6, ROT3) ^ X##I5; \ + X##I7 += X##I8; X##I8 = rotate_left(X##I8, ROT4) ^ X##I7; \ + } while(0) + +#define THREEFISH_INJECT_KEY(r) \ + do { \ + X0 += m_K[(r ) % 9]; \ + X1 += m_K[(r+1) % 9]; \ + X2 += m_K[(r+2) % 9]; \ + X3 += m_K[(r+3) % 9]; \ + X4 += m_K[(r+4) % 9]; \ + X5 += m_K[(r+5) % 9] + m_T[(r ) % 3]; \ + X6 += m_K[(r+6) % 9] + m_T[(r+1) % 3]; \ + X7 += m_K[(r+7) % 9] + (r); \ + } while(0) + +#define THREEFISH_8_ROUNDS(R1,R2) \ + do { \ + THREEFISH_ROUND(0,1,2,3,4,5,6,7, 46,36,19,37); \ + THREEFISH_ROUND(2,1,4,7,6,5,0,3, 33,27,14,42); \ + THREEFISH_ROUND(4,1,6,3,0,5,2,7, 17,49,36,39); \ + THREEFISH_ROUND(6,1,0,7,2,5,4,3, 44, 9,54,56); \ + \ + THREEFISH_INJECT_KEY(R1); \ + \ + THREEFISH_ROUND(0,1,2,3,4,5,6,7, 39,30,34,24); \ + THREEFISH_ROUND(2,1,4,7,6,5,0,3, 13,50,10,17); \ + THREEFISH_ROUND(4,1,6,3,0,5,2,7, 25,29,39,43); \ + THREEFISH_ROUND(6,1,0,7,2,5,4,3, 8,35,56,22); \ + \ + THREEFISH_INJECT_KEY(R2); \ + } while(0) + + while(sz) + { + u64bit X0 = load_le<u64bit>(buf, 0); + u64bit X1 = load_le<u64bit>(buf, 1); + u64bit X2 = load_le<u64bit>(buf, 2); + u64bit X3 = load_le<u64bit>(buf, 3); + u64bit X4 = load_le<u64bit>(buf, 4); + u64bit X5 = load_le<u64bit>(buf, 5); + u64bit X6 = load_le<u64bit>(buf, 6); + u64bit X7 = load_le<u64bit>(buf, 7); + + THREEFISH_INJECT_KEY(0); + + THREEFISH_8_ROUNDS(1,2); + THREEFISH_8_ROUNDS(3,4); + THREEFISH_8_ROUNDS(5,6); + THREEFISH_8_ROUNDS(7,8); + THREEFISH_8_ROUNDS(9,10); + THREEFISH_8_ROUNDS(11,12); + THREEFISH_8_ROUNDS(13,14); + THREEFISH_8_ROUNDS(15,16); + THREEFISH_8_ROUNDS(17,18); + + store_le(buf, X0, X1, X2, X3, X4, X5, X6, X7); + + buf += 64; + sz -= 64; + } + +#undef THREEFISH_8_ROUNDS +#undef THREEFISH_INJECT_KEY +#undef THREEFISH_ROUND + } + +Key_Length_Specification Threefish_512::key_spec() const + { + return Key_Length_Specification(64); + } + +void Threefish_512::key_schedule(const byte key[], size_t) + { + // todo: define key schedule for smaller keys + m_K.resize(9); + + for(size_t i = 0; i != 8; ++i) + m_K[i] = load_le<u64bit>(key, i); + + m_K[8] = m_K[0] ^ m_K[1] ^ m_K[2] ^ m_K[3] ^ + m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22; + } + +void Threefish_512::finish(secure_vector<byte>& blocks, size_t offset) + { + update(blocks, offset); + m_T.clear(); + } + +size_t Threefish_512::output_length(size_t input_length) const + { + if(input_length % update_granularity() == 0) + throw std::invalid_argument("Threefish - invalid input length " + std::to_string(input_length)); + + return input_length; + } + +size_t Threefish_512::update_granularity() const + { + return 64; // single block + } + +size_t Threefish_512::minimum_final_size() const + { + return 0; + } + +size_t Threefish_512::default_nonce_length() const + { + return 16; + } + +bool Threefish_512::valid_nonce_length(size_t nonce_len) const + { + return default_nonce_length() == nonce_len; + } + +void Threefish_512::clear() + { + zeroise(m_K); + } + +} diff --git a/src/block/threefish/threefish.h b/src/block/threefish/threefish.h new file mode 100644 index 000000000..b7806a93d --- /dev/null +++ b/src/block/threefish/threefish.h @@ -0,0 +1,52 @@ +/* +* Threefish +* (C) 2013 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_THREEFISH_H__ +#define BOTAN_THREEFISH_H__ + +#include <botan/transform.h> + +namespace Botan { + +/** +* Threefish-512 +*/ +class BOTAN_DLL Threefish_512 : public Transformation + { + public: + secure_vector<byte> start(const byte tweak[], size_t tweak_len) override; + + void update(secure_vector<byte>& blocks, size_t offset) override; + + void finish(secure_vector<byte>& final_block, size_t offset) override; + + size_t output_length(size_t input_length) const override; + + size_t update_granularity() const override; + + size_t minimum_final_size() const override; + + size_t default_nonce_length() const override; + + bool valid_nonce_length(size_t nonce_len) const override; + + Key_Length_Specification key_spec() const override; + + std::string name() const { return "Threefish-512"; } + + void clear(); + + private: + void key_schedule(const byte key[], size_t key_len) override; + + secure_vector<u64bit> m_T; + secure_vector<u64bit> m_K; + }; + +} + +#endif diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt index 0af44768b..163e64272 100644 --- a/src/build-data/cc/clang.txt +++ b/src/build-data/cc/clang.txt @@ -30,9 +30,14 @@ darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)" </so_link_flags> <isa_flags> +"sse2" -> "-msse2" +"ssse3" -> "-mssse3" +"sse4.1" -> "-msse4.1" +"sse4.2" -> "-msse4.2" +"avx" -> "-mavx" "aes-ni" -> "-maes" -"ssse3" -> "-mssse3" -"sse2" -> "-msse2" +"avx2" -> "-mavx2" +"bmi2" -> "-mbmi2" </isa_flags> <mach_opt> @@ -43,7 +48,8 @@ ivybridge -> "-march=core-avx-i" </mach_opt> <mach_abi_linking> -all -> "-stdlib=libc++ -pthread" +#all -> "-stdlib=libc++ -pthread" +all -> "-stdlib=libstdc++ -pthread" x86_64 -> "-m64" ppc64 -> "-m64" diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index ed425ca84..52d5020e2 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -8,8 +8,9 @@ add_include_dir_option -I add_lib_dir_option -L add_lib_option -l -lang_flags "-D_REENTRANT -std=c++11" -warning_flags "-Werror -Wno-error=old-style-cast -Wno-error=zero-as-null-pointer-constant -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wold-style-cast -Wzero-as-null-pointer-constant" +lang_flags "-std=c++11 -D_REENTRANT -fstack-protector" +maintainer_warning_flags "-Werror -Wno-error=old-style-cast -Wno-error=zero-as-null-pointer-constant" +warning_flags "-Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wold-style-cast -Wzero-as-null-pointer-constant" lib_opt_flags "-O3" check_opt_flags "-O2" @@ -43,6 +44,8 @@ solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME)" "sse4.2" -> "-msse4.2" "avx" -> "-mavx" "aes-ni" -> "-maes" +"avx2" -> "-mavx2" +"bmi2" -> "-mbmi2" </isa_flags> <mach_opt> diff --git a/src/build-data/makefile/unix.in b/src/build-data/makefile/unix.in index 0b6afe0c3..fbc45a681 100644 --- a/src/build-data/makefile/unix.in +++ b/src/build-data/makefile/unix.in @@ -6,8 +6,8 @@ LANG_FLAGS = %{lang_flags} WARN_FLAGS = %{warn_flags} LINK_TO = %{link_to} -LIB_FLAGS = $(LIB_OPT) $(LANG_FLAGS) $(WARN_FLAGS) -CHECK_FLAGS = $(CHECK_OPT) $(LANG_FLAGS) $(WARN_FLAGS) +LIB_FLAGS = $(LANG_FLAGS) $(LIB_OPT) $(WARN_FLAGS) +CHECK_FLAGS = $(LANG_FLAGS) $(CHECK_OPT) $(WARN_FLAGS) # Version Numbers VERSION = %{version} diff --git a/src/build-data/makefile/unix_shr.in b/src/build-data/makefile/unix_shr.in index 806969a00..c412a94fd 100644 --- a/src/build-data/makefile/unix_shr.in +++ b/src/build-data/makefile/unix_shr.in @@ -8,8 +8,8 @@ SO_OBJ_FLAGS = %{shared_flags} SO_LINK_CMD = %{so_link} LINK_TO = %{link_to} -LIB_FLAGS = $(LIB_OPT) $(LANG_FLAGS) $(WARN_FLAGS) $(SO_OBJ_FLAGS) -CHECK_FLAGS = $(CHECK_OPT) $(LANG_FLAGS) $(WARN_FLAGS) +LIB_FLAGS = $(SO_OBJ_FLAGS) $(LANG_FLAGS) $(LIB_OPT) $(WARN_FLAGS) +CHECK_FLAGS = $(LANG_FLAGS) $(CHECK_OPT) $(WARN_FLAGS) # Version Numbers VERSION = %{version} diff --git a/src/build-data/scripts/dist.py b/src/build-data/scripts/dist.py index 316057d22..4271492f8 100755 --- a/src/build-data/scripts/dist.py +++ b/src/build-data/scripts/dist.py @@ -19,6 +19,7 @@ import subprocess import sys import tarfile import datetime +import hashlib def check_subprocess_results(subproc, name): (stdout, stderr) = subproc.communicate() @@ -90,14 +91,18 @@ def datestamp(db, rev_id): logging.info('Could not retreive date for %s' % (rev_id)) return 0 -def gpg_sign(keyid, passphrase_file, files): +def gpg_sign(keyid, passphrase_file, files, detached = True): + + options = ['--armor', '--detach-sign'] if detached else ['--clearsign'] + + gpg_cmd = ['gpg', '--batch'] + options + ['--local-user', keyid] + if passphrase_file != None: + gpg_cmd[1:1] = ['--passphrase-file', passphrase_file] + for filename in files: logging.info('Signing %s using PGP id %s' % (filename, keyid)) - cmd = ['gpg', '--batch', '--armor', '--detach-sign', '--local-user', keyid, filename] - - if passphrase_file != None: - cmd[1:1] = ['--passphrase-file', passphrase_file] + cmd = gpg_cmd + [filename] logging.debug('Running %s' % (' '.join(cmd))) @@ -137,12 +142,15 @@ def parse_args(args): parser.add_option('--pgp-key-id', metavar='KEYID', default='EFBADFBC', - help='PGP signing key (default %default)') + help='PGP signing key (default %default, "none" to disable)') parser.add_option('--pgp-passphrase-file', metavar='FILE', default=None, help='PGP signing key passphrase file') + parser.add_option('--write-hash-file', metavar='FILE', default=None, + help='Write a file with checksums') + return parser.parse_args(args) def remove_file_if_exists(fspath): @@ -238,6 +246,8 @@ def main(args = None): output_basename = output_name(args) + logging.debug('Output basename %s' % (output_basename)) + if os.access(output_basename, os.X_OK): logging.info('Removing existing output dir %s' % (output_basename)) shutil.rmtree(output_basename) @@ -285,6 +295,10 @@ def main(args = None): archives = options.archive_types.split(',') if options.archive_types != '' else [] + hash_file = None + if options.write_hash_file != None: + hash_file = open(options.write_hash_file, 'w') + for archive in archives: logging.debug('Writing archive type "%s"' % (archive)) @@ -304,19 +318,31 @@ def main(args = None): archive = tarfile.open(output_archive, write_mode()) archive.add(output_basename) archive.close() + + if hash_file != None: + sha256 = hashlib.new('sha256') + sha256.update(open(output_archive).read()) + hash_file.write("%s %s\n" % (sha256.hexdigest(), output_archive)) else: raise Exception('Unknown archive type "%s"' % (archive)) output_files.append(output_archive) + hash_file.close() + shutil.rmtree(output_basename) if options.print_output_names: for output_file in output_files: - print output_file + print(output_file) - if options.pgp_key_id != '': - output_files += gpg_sign(options.pgp_key_id, options.pgp_passphrase_file, output_files) + if options.pgp_key_id != 'none': + if options.write_hash_file != None: + output_files += gpg_sign(options.pgp_key_id, options.pgp_passphrase_file, + [options.write_hash_file], False) + else: + output_files += gpg_sign(options.pgp_key_id, options.pgp_passphrase_file, + output_files, True) if options.output_dir != '.': for output_file in output_files: diff --git a/src/cert/x509/info.txt b/src/cert/x509/info.txt index ef3043e9e..a74fd6631 100644 --- a/src/cert/x509/info.txt +++ b/src/cert/x509/info.txt @@ -5,3 +5,7 @@ define OCSP 20131128 datastor http_util </requires> + +<libs> +all -> boost_filesystem +</libs> diff --git a/src/engine/simd_engine/simd_engine.cpp b/src/engine/simd_engine/simd_engine.cpp index 70529f1fd..3f4e2b7aa 100644 --- a/src/engine/simd_engine/simd_engine.cpp +++ b/src/engine/simd_engine/simd_engine.cpp @@ -80,6 +80,8 @@ SIMD_Engine::find_hash(const SCAN_Name& request, return new SHA_160_SSE2; #endif + BOTAN_UNUSED(request); + return nullptr; } diff --git a/src/filters/transform_filter.cpp b/src/filters/transform_filter.cpp index e8033b1a8..2f25aa2c5 100644 --- a/src/filters/transform_filter.cpp +++ b/src/filters/transform_filter.cpp @@ -12,7 +12,7 @@ namespace Botan { Transformation_Filter::Transformation_Filter(Transformation* transform) : Buffered_Filter(transform->update_granularity(), transform->minimum_final_size()), - m_nonce(transform->default_nonce_size() == 0), + m_nonce(transform->default_nonce_length() == 0), m_transform(transform), m_buffer(m_transform->update_granularity()) { diff --git a/src/hash/bmw_512/bmw_512.cpp b/src/hash/bmw_512/bmw_512.cpp index 40338fdf0..9dfa62214 100644 --- a/src/hash/bmw_512/bmw_512.cpp +++ b/src/hash/bmw_512/bmw_512.cpp @@ -82,6 +82,8 @@ void BMW_512_compress(u64bit H[16], const u64bit M[16], u64bit Q[32]) Q[14] = S4(Q[30]) + H[15]; Q[15] = S0(Q[31]) + H[ 0]; + const u64bit EXPANSION_CONSTANT = 0x0555555555555555; + for(size_t i = 16; i != 16 + EXPAND_1_ROUNDS; ++i) { Q[i] = S1(Q[i-16]) + S2(Q[i-15]) + S3(Q[i-14]) + S0(Q[i-13]) + @@ -91,7 +93,7 @@ void BMW_512_compress(u64bit H[16], const u64bit M[16], u64bit Q[32]) ((rotate_left(M[(i-16) % 16], ((i-16)%16) + 1) + rotate_left(M[(i-13) % 16], ((i-13)%16) + 1) - rotate_left(M[(i- 6) % 16], ((i-6)%16) + 1) + - (0x0555555555555555 * i)) ^ H[(i-16+7)%16]); + (EXPANSION_CONSTANT * i)) ^ H[(i-16+7)%16]); } for(size_t i = 16 + EXPAND_1_ROUNDS; i != 32; ++i) @@ -107,7 +109,7 @@ void BMW_512_compress(u64bit H[16], const u64bit M[16], u64bit Q[32]) ((rotate_left(M[(i-16) % 16], ((i-16)%16 + 1)) + rotate_left(M[(i-13) % 16], ((i-13)%16 + 1)) - rotate_left(M[(i- 6) % 16], ((i-6)%16 + 1)) + - (0x0555555555555555 * i)) ^ H[(i-16+7)%16]); + (EXPANSION_CONSTANT * i)) ^ H[(i-16+7)%16]); } u64bit XL = Q[16] ^ Q[17] ^ Q[18] ^ Q[19] ^ diff --git a/src/libstate/info.txt b/src/libstate/info.txt index 7e2bac6ee..49a6d38ee 100644 --- a/src/libstate/info.txt +++ b/src/libstate/info.txt @@ -19,7 +19,3 @@ pubkey rng stream </requires> - -<libs> -all -> boost_system,boost_filesystem -</libs> diff --git a/src/modes/aead/aead.h b/src/modes/aead/aead.h index d03cb295d..8df98fcad 100644 --- a/src/modes/aead/aead.h +++ b/src/modes/aead/aead.h @@ -48,7 +48,7 @@ class BOTAN_DLL AEAD_Mode : public Cipher_Mode * Default AEAD nonce size (a commonly supported value among AEAD * modes, and large enough that random collisions are unlikely). */ - size_t default_nonce_size() const override { return 12; } + size_t default_nonce_length() const override { return 12; } /** * Return the size of the authentication tag used (in bytes) diff --git a/src/modes/aead/ccm/ccm.cpp b/src/modes/aead/ccm/ccm.cpp index fb35172cc..50fc38738 100644 --- a/src/modes/aead/ccm/ccm.cpp +++ b/src/modes/aead/ccm/ccm.cpp @@ -47,7 +47,7 @@ bool CCM_Mode::valid_nonce_length(size_t n) const return (n == (15-L())); } -size_t CCM_Mode::default_nonce_size() const +size_t CCM_Mode::default_nonce_length() const { return (15-L()); } diff --git a/src/modes/aead/ccm/ccm.h b/src/modes/aead/ccm/ccm.h index a62c84f55..b9ce0b30b 100644 --- a/src/modes/aead/ccm/ccm.h +++ b/src/modes/aead/ccm/ccm.h @@ -37,7 +37,7 @@ class BOTAN_DLL CCM_Mode : public AEAD_Mode bool valid_nonce_length(size_t) const override; - size_t default_nonce_size() const override; + size_t default_nonce_length() const override; void clear(); diff --git a/src/modes/cbc/cbc.cpp b/src/modes/cbc/cbc.cpp index 482588cf5..31834bade 100644 --- a/src/modes/cbc/cbc.cpp +++ b/src/modes/cbc/cbc.cpp @@ -47,7 +47,7 @@ Key_Length_Specification CBC_Mode::key_spec() const return cipher().key_spec(); } -size_t CBC_Mode::default_nonce_size() const +size_t CBC_Mode::default_nonce_length() const { return cipher().block_size(); } diff --git a/src/modes/cbc/cbc.h b/src/modes/cbc/cbc.h index 8638c8a05..726d5d080 100644 --- a/src/modes/cbc/cbc.h +++ b/src/modes/cbc/cbc.h @@ -29,7 +29,7 @@ class BOTAN_DLL CBC_Mode : public Cipher_Mode Key_Length_Specification key_spec() const override; - size_t default_nonce_size() const override; + size_t default_nonce_length() const override; bool valid_nonce_length(size_t n) const override; diff --git a/src/modes/cfb/cfb.cpp b/src/modes/cfb/cfb.cpp index 2edb917b4..7721e1487 100644 --- a/src/modes/cfb/cfb.cpp +++ b/src/modes/cfb/cfb.cpp @@ -54,7 +54,7 @@ Key_Length_Specification CFB_Mode::key_spec() const return cipher().key_spec(); } -size_t CFB_Mode::default_nonce_size() const +size_t CFB_Mode::default_nonce_length() const { return cipher().block_size(); } diff --git a/src/modes/cfb/cfb.h b/src/modes/cfb/cfb.h index 46b1997d2..984e5cb96 100644 --- a/src/modes/cfb/cfb.h +++ b/src/modes/cfb/cfb.h @@ -33,7 +33,7 @@ class BOTAN_DLL CFB_Mode : public Cipher_Mode size_t output_length(size_t input_length) const override; - size_t default_nonce_size() const override; + size_t default_nonce_length() const override; bool valid_nonce_length(size_t n) const override; diff --git a/src/modes/ecb/ecb.cpp b/src/modes/ecb/ecb.cpp index 1b73da64f..f026eb035 100644 --- a/src/modes/ecb/ecb.cpp +++ b/src/modes/ecb/ecb.cpp @@ -42,7 +42,7 @@ Key_Length_Specification ECB_Mode::key_spec() const return cipher().key_spec(); } -size_t ECB_Mode::default_nonce_size() const +size_t ECB_Mode::default_nonce_length() const { return 0; } diff --git a/src/modes/ecb/ecb.h b/src/modes/ecb/ecb.h index 8ab62fa45..9545a33ea 100644 --- a/src/modes/ecb/ecb.h +++ b/src/modes/ecb/ecb.h @@ -29,7 +29,7 @@ class BOTAN_DLL ECB_Mode : public Cipher_Mode Key_Length_Specification key_spec() const override; - size_t default_nonce_size() const override; + size_t default_nonce_length() const override; bool valid_nonce_length(size_t n) const override; diff --git a/src/modes/xts/xts.cpp b/src/modes/xts/xts.cpp index 80b7ed7f3..02da5fa5d 100644 --- a/src/modes/xts/xts.cpp +++ b/src/modes/xts/xts.cpp @@ -86,7 +86,7 @@ Key_Length_Specification XTS_Mode::key_spec() const return cipher().key_spec().multiple(2); } -size_t XTS_Mode::default_nonce_size() const +size_t XTS_Mode::default_nonce_length() const { return cipher().block_size(); } diff --git a/src/modes/xts/xts.h b/src/modes/xts/xts.h index a1f0f1626..49f2a3458 100644 --- a/src/modes/xts/xts.h +++ b/src/modes/xts/xts.h @@ -30,7 +30,7 @@ class BOTAN_DLL XTS_Mode : public Cipher_Mode Key_Length_Specification key_spec() const override; - size_t default_nonce_size() const override; + size_t default_nonce_length() const override; bool valid_nonce_length(size_t n) const override; diff --git a/src/simd/simd_32.h b/src/simd/simd_32.h index 4ef0cea85..17cf5b91e 100644 --- a/src/simd/simd_32.h +++ b/src/simd/simd_32.h @@ -20,7 +20,7 @@ #elif defined(BOTAN_HAS_SIMD_SCALAR) #include <botan/internal/simd_scalar.h> - namespace Botan { typedef SIMD_Scalar SIMD_32; } + namespace Botan { typedef SIMD_4_Scalar<u32bit> SIMD_32; } #else #error "No SIMD module defined" diff --git a/src/simd/simd_scalar/simd_scalar.h b/src/simd/simd_scalar/simd_scalar.h index 2c68622af..cf1145794 100644 --- a/src/simd/simd_scalar/simd_scalar.h +++ b/src/simd/simd_scalar/simd_scalar.h @@ -1,6 +1,6 @@ /* -* Scalar emulation of SIMD 32-bit operations -* (C) 2009 Jack Lloyd +* Scalar emulation of SIMD +* (C) 2009,2013 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -17,12 +17,13 @@ namespace Botan { * Fake SIMD, using plain scalar operations * Often still faster than iterative on superscalar machines */ -class SIMD_Scalar +template<typename T> +class SIMD_4_Scalar { public: static bool enabled() { return true; } - SIMD_Scalar(const u32bit B[4]) + SIMD_4_Scalar(const T B[4]) { R0 = B[0]; R1 = B[1]; @@ -30,7 +31,7 @@ class SIMD_Scalar R3 = B[3]; } - SIMD_Scalar(u32bit B0, u32bit B1, u32bit B2, u32bit B3) + SIMD_4_Scalar(T B0, T B1, T B2, T B3) { R0 = B0; R1 = B1; @@ -38,7 +39,7 @@ class SIMD_Scalar R3 = B3; } - SIMD_Scalar(u32bit B) + SIMD_4_Scalar(T B) { R0 = B; R1 = B; @@ -46,22 +47,22 @@ class SIMD_Scalar R3 = B; } - static SIMD_Scalar load_le(const void* in) + static SIMD_4_Scalar<T> load_le(const void* in) { const byte* in_b = static_cast<const byte*>(in); - return SIMD_Scalar(Botan::load_le<u32bit>(in_b, 0), - Botan::load_le<u32bit>(in_b, 1), - Botan::load_le<u32bit>(in_b, 2), - Botan::load_le<u32bit>(in_b, 3)); + return SIMD_4_Scalar<T>(Botan::load_le<T>(in_b, 0), + Botan::load_le<T>(in_b, 1), + Botan::load_le<T>(in_b, 2), + Botan::load_le<T>(in_b, 3)); } - static SIMD_Scalar load_be(const void* in) + static SIMD_4_Scalar<T> load_be(const void* in) { const byte* in_b = static_cast<const byte*>(in); - return SIMD_Scalar(Botan::load_be<u32bit>(in_b, 0), - Botan::load_be<u32bit>(in_b, 1), - Botan::load_be<u32bit>(in_b, 2), - Botan::load_be<u32bit>(in_b, 3)); + return SIMD_4_Scalar<T>(Botan::load_be<T>(in_b, 0), + Botan::load_be<T>(in_b, 1), + Botan::load_be<T>(in_b, 2), + Botan::load_be<T>(in_b, 3)); } void store_le(byte out[]) const @@ -90,7 +91,7 @@ class SIMD_Scalar R3 = Botan::rotate_right(R3, rot); } - void operator+=(const SIMD_Scalar& other) + void operator+=(const SIMD_4_Scalar<T>& other) { R0 += other.R0; R1 += other.R1; @@ -98,15 +99,15 @@ class SIMD_Scalar R3 += other.R3; } - SIMD_Scalar operator+(const SIMD_Scalar& other) const + SIMD_4_Scalar<T> operator+(const SIMD_4_Scalar<T>& other) const { - return SIMD_Scalar(R0 + other.R0, + return SIMD_4_Scalar<T>(R0 + other.R0, R1 + other.R1, R2 + other.R2, R3 + other.R3); } - void operator-=(const SIMD_Scalar& other) + void operator-=(const SIMD_4_Scalar<T>& other) { R0 -= other.R0; R1 -= other.R1; @@ -114,15 +115,15 @@ class SIMD_Scalar R3 -= other.R3; } - SIMD_Scalar operator-(const SIMD_Scalar& other) const + SIMD_4_Scalar<T> operator-(const SIMD_4_Scalar<T>& other) const { - return SIMD_Scalar(R0 - other.R0, - R1 - other.R1, - R2 - other.R2, - R3 - other.R3); + return SIMD_4_Scalar<T>(R0 - other.R0, + R1 - other.R1, + R2 - other.R2, + R3 - other.R3); } - void operator^=(const SIMD_Scalar& other) + void operator^=(const SIMD_4_Scalar<T>& other) { R0 ^= other.R0; R1 ^= other.R1; @@ -130,15 +131,15 @@ class SIMD_Scalar R3 ^= other.R3; } - SIMD_Scalar operator^(const SIMD_Scalar& other) const + SIMD_4_Scalar<T> operator^(const SIMD_4_Scalar<T>& other) const { - return SIMD_Scalar(R0 ^ other.R0, + return SIMD_4_Scalar<T>(R0 ^ other.R0, R1 ^ other.R1, R2 ^ other.R2, R3 ^ other.R3); } - void operator|=(const SIMD_Scalar& other) + void operator|=(const SIMD_4_Scalar<T>& other) { R0 |= other.R0; R1 |= other.R1; @@ -146,15 +147,15 @@ class SIMD_Scalar R3 |= other.R3; } - SIMD_Scalar operator&(const SIMD_Scalar& other) + SIMD_4_Scalar<T> operator&(const SIMD_4_Scalar<T>& other) { - return SIMD_Scalar(R0 & other.R0, - R1 & other.R1, - R2 & other.R2, - R3 & other.R3); + return SIMD_4_Scalar<T>(R0 & other.R0, + R1 & other.R1, + R2 & other.R2, + R3 & other.R3); } - void operator&=(const SIMD_Scalar& other) + void operator&=(const SIMD_4_Scalar<T>& other) { R0 &= other.R0; R1 &= other.R1; @@ -162,51 +163,51 @@ class SIMD_Scalar R3 &= other.R3; } - SIMD_Scalar operator<<(size_t shift) const + SIMD_4_Scalar<T> operator<<(size_t shift) const { - return SIMD_Scalar(R0 << shift, - R1 << shift, - R2 << shift, - R3 << shift); + return SIMD_4_Scalar<T>(R0 << shift, + R1 << shift, + R2 << shift, + R3 << shift); } - SIMD_Scalar operator>>(size_t shift) const + SIMD_4_Scalar<T> operator>>(size_t shift) const { - return SIMD_Scalar(R0 >> shift, - R1 >> shift, - R2 >> shift, - R3 >> shift); + return SIMD_4_Scalar<T>(R0 >> shift, + R1 >> shift, + R2 >> shift, + R3 >> shift); } - SIMD_Scalar operator~() const + SIMD_4_Scalar<T> operator~() const { - return SIMD_Scalar(~R0, ~R1, ~R2, ~R3); + return SIMD_4_Scalar<T>(~R0, ~R1, ~R2, ~R3); } // (~reg) & other - SIMD_Scalar andc(const SIMD_Scalar& other) + SIMD_4_Scalar<T> andc(const SIMD_4_Scalar<T>& other) { - return SIMD_Scalar(~R0 & other.R0, - ~R1 & other.R1, - ~R2 & other.R2, - ~R3 & other.R3); + return SIMD_4_Scalar<T>(~R0 & other.R0, + ~R1 & other.R1, + ~R2 & other.R2, + ~R3 & other.R3); } - SIMD_Scalar bswap() const + SIMD_4_Scalar<T> bswap() const { - return SIMD_Scalar(reverse_bytes(R0), - reverse_bytes(R1), - reverse_bytes(R2), - reverse_bytes(R3)); + return SIMD_4_Scalar<T>(reverse_bytes(R0), + reverse_bytes(R1), + reverse_bytes(R2), + reverse_bytes(R3)); } - static void transpose(SIMD_Scalar& B0, SIMD_Scalar& B1, - SIMD_Scalar& B2, SIMD_Scalar& B3) + static void transpose(SIMD_4_Scalar<T>& B0, SIMD_4_Scalar<T>& B1, + SIMD_4_Scalar<T>& B2, SIMD_4_Scalar<T>& B3) { - SIMD_Scalar T0(B0.R0, B1.R0, B2.R0, B3.R0); - SIMD_Scalar T1(B0.R1, B1.R1, B2.R1, B3.R1); - SIMD_Scalar T2(B0.R2, B1.R2, B2.R2, B3.R2); - SIMD_Scalar T3(B0.R3, B1.R3, B2.R3, B3.R3); + SIMD_4_Scalar<T> T0(B0.R0, B1.R0, B2.R0, B3.R0); + SIMD_4_Scalar<T> T1(B0.R1, B1.R1, B2.R1, B3.R1); + SIMD_4_Scalar<T> T2(B0.R2, B1.R2, B2.R2, B3.R2); + SIMD_4_Scalar<T> T3(B0.R3, B1.R3, B2.R3, B3.R3); B0 = T0; B1 = T1; @@ -215,7 +216,7 @@ class SIMD_Scalar } private: - u32bit R0, R1, R2, R3; + T R0, R1, R2, R3; }; } diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp index 3271c3abe..05251e186 100644 --- a/src/tls/tls_policy.cpp +++ b/src/tls/tls_policy.cpp @@ -20,10 +20,10 @@ std::vector<std::string> Policy::allowed_ciphers() const return std::vector<std::string>({ "AES-256/GCM", "AES-128/GCM", - "AES-256/CCM(16,3)", - "AES-128/CCM(16,3)", - "AES-256/CCM(8,3)", - "AES-128/CCM(8,3)", + "AES-256/CCM", + "AES-128/CCM", + "AES-256/CCM-8", + "AES-128/CCM-8", //"Camellia-256/GCM", //"Camellia-128/GCM", "AES-256", @@ -141,11 +141,16 @@ u32bit Policy::session_ticket_lifetime() const bool Policy::acceptable_protocol_version(Protocol_Version version) const { - if(!version.known_version()) + // By default require TLS to minimize surprise + if(version.is_datagram_protocol()) return false; - // By default require TLS to minimize surprise - return !version.is_datagram_protocol(); + return (version > Protocol_Version::SSL_V3); + } + +bool Policy::acceptable_ciphersuite(const Ciphersuite&) const + { + return true; } namespace { @@ -235,6 +240,9 @@ std::vector<u16bit> Policy::ciphersuite_list(Protocol_Version version, for(auto suite : Ciphersuite::all_known_ciphersuites()) { + if(!acceptable_ciphersuite(suite)) + continue; + if(!have_srp && suite.kex_algo() == "SRP_SHA") continue; diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h index 6a51f2bbf..5b205dfeb 100644 --- a/src/tls/tls_policy.h +++ b/src/tls/tls_policy.h @@ -9,6 +9,7 @@ #define BOTAN_TLS_POLICY_H__ #include <botan/tls_version.h> +#include <botan/tls_ciphersuite.h> #include <botan/x509cert.h> #include <botan/dl_group.h> #include <vector> @@ -127,6 +128,8 @@ class BOTAN_DLL Policy */ virtual bool acceptable_protocol_version(Protocol_Version version) const; + virtual bool acceptable_ciphersuite(const Ciphersuite& suite) const; + /** * @return true if servers should choose the ciphersuite matching * their highest preference, rather than the clients. diff --git a/src/utils/assert.h b/src/utils/assert.h index 9265be450..f62fae63e 100644 --- a/src/utils/assert.h +++ b/src/utils/assert.h @@ -73,6 +73,11 @@ void BOTAN_DLL assertion_failure(const char* expr_str, __LINE__); \ } while(0) +/** +* Mark variable as unused +*/ +#define BOTAN_UNUSED(v) static_cast<void>(v) + } #endif diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index f6581f09c..4cb6c826f 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -1,6 +1,6 @@ /* * Runtime CPU detection -* (C) 2009-2010 Jack Lloyd +* (C) 2009-2010,2013 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -28,90 +28,60 @@ #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) - #include <intrin.h> - #define CALL_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) +#include <intrin.h> + +#define X86_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) + +#define X86_CPUID_SUBLEVEL(type, level, out) do { __cpuid((int*)out, type, level); } while(0) #elif defined(BOTAN_BUILD_COMPILER_IS_INTEL) - #include <ia32intrin.h> - #define CALL_CPUID(type, out) do { __cpuid(out, type); } while(0) +#include <ia32intrin.h> -#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && (BOTAN_GCC_VERSION >= 430) +#define X86_CPUID(type, out) do { __cpuid(out, type); } while(0) - // Only available starting in GCC 4.3 - #include <cpuid.h> +#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && 0 -namespace { +#include <cpuid.h> - /* - * Prevent inlining to work around GCC bug 44174 - */ - void __attribute__((__noinline__)) call_gcc_cpuid(Botan::u32bit type, - Botan::u32bit out[4]) - { - __get_cpuid(type, out, out+1, out+2, out+3); - } +#define X86_CPUID(type, out) do { __get_cpuid(type, out, out+1, out+2, out+3); } while(0) - #define CALL_CPUID call_gcc_cpuid +namespace { + +// avoids asm clobber errors in gcc 4.7.3 +void gcc_cpuid(unsigned int type, unsigned int level, unsigned int* eax, unsigned int* ebx, + unsigned int* ecx, unsigned int* edx) + { + __cpuid_count(type, level, eax, ebx, ecx, edx); + } } -#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && \ - (defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_GCC)) +#define X86_CPUID_SUBLEVEL(type, level, out) \ + do { gcc_cpuid(type, level, out, out+1, out+2, out+3); } while(0) - /* - * We can't safely use this on x86-32 as some 32-bit ABIs use ebx as - * a PIC register, and in theory there are some x86-32s still out - * there that don't support cpuid at all; it requires strange - * contortions to detect them. - */ +#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && BOTAN_USE_GCC_INLINE_ASM - #define CALL_CPUID(type, out) \ - asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \ - : "0" (type)) +#define X86_CPUID(type, out) \ + asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \ + : "0" (type)) -#else - #warning "No method of calling CPUID for this compiler" -#endif +#define X86_CPUID_SUBLEVEL(type, level, out) \ + asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \ + : "0" (type), "2" (level)) #endif -#ifndef CALL_CPUID - // In all other cases, just zeroize the supposed cpuid output - #define CALL_CPUID(type, out) \ - do { out[0] = out[1] = out[2] = out[3] = 0; } while(0); #endif namespace Botan { -u64bit CPUID::x86_processor_flags = 0; -size_t CPUID::cache_line = 32; -bool CPUID::altivec_capable = false; +u64bit CPUID::m_x86_processor_flags[2] = { 0, 0 }; +size_t CPUID::m_cache_line_size = 0; +bool CPUID::m_altivec_capable = false; namespace { -u32bit get_x86_cache_line_size() - { - const u32bit INTEL_CPUID[3] = { 0x756E6547, 0x6C65746E, 0x49656E69 }; - const u32bit AMD_CPUID[3] = { 0x68747541, 0x444D4163, 0x69746E65 }; - - u32bit cpuid[4] = { 0 }; - CALL_CPUID(0, cpuid); - - if(same_mem(cpuid + 1, INTEL_CPUID, 3)) - { - CALL_CPUID(1, cpuid); - return 8 * get_byte(2, cpuid[1]); - } - else if(same_mem(cpuid + 1, AMD_CPUID, 3)) - { - CALL_CPUID(0x80000005, cpuid); - return get_byte(3, cpuid[2]); - } - else - return 32; // default cache line guess - } - #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) bool altivec_check_sysctl() @@ -189,27 +159,55 @@ bool altivec_check_pvr_emul() void CPUID::initialize() { +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) + if(altivec_check_sysctl() || altivec_check_pvr_emul()) + altivec_capable = true; +#endif + +#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + const u32bit INTEL_CPUID[3] = { 0x756E6547, 0x6C65746E, 0x49656E69 }; + const u32bit AMD_CPUID[3] = { 0x68747541, 0x444D4163, 0x69746E65 }; + u32bit cpuid[4] = { 0 }; - CALL_CPUID(1, cpuid); + X86_CPUID(0, cpuid); + + const u32bit max_supported_sublevel = cpuid[0]; + + if(max_supported_sublevel == 0) + return; - x86_processor_flags = (static_cast<u64bit>(cpuid[2]) << 32) | cpuid[3]; + const bool is_intel = same_mem(cpuid + 1, INTEL_CPUID, 3); + const bool is_amd = same_mem(cpuid + 1, AMD_CPUID, 3); + + X86_CPUID(1, cpuid); + + m_x86_processor_flags[0] = (static_cast<u64bit>(cpuid[2]) << 32) | cpuid[3]; + + if(is_intel) + m_cache_line_size = 8 * get_byte(2, cpuid[1]); + + if(max_supported_sublevel >= 7) + { + clear_mem(cpuid, 4); + X86_CPUID_SUBLEVEL(7, 0, cpuid); + m_x86_processor_flags[1] = (static_cast<u64bit>(cpuid[2]) << 32) | cpuid[1]; + } + + if(is_amd) + { + X86_CPUID(0x80000005, cpuid); + m_cache_line_size = get_byte(3, cpuid[2]); + } + +#endif #if defined(BOTAN_TARGET_ARCH_IS_X86_64) /* * If we don't have access to CPUID, we can still safely assume that * any x86-64 processor has SSE2. */ - if(x86_processor_flags == 0) - x86_processor_flags |= (1 << CPUID_SSE2_BIT); -#endif - - cache_line = get_x86_cache_line_size(); - - altivec_capable = false; - -#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - if(altivec_check_sysctl() || altivec_check_pvr_emul()) - altivec_capable = true; + if(m_x86_processor_flags[0] == 0) + m_x86_processor_flags[0] = (1 << CPUID_SSE2_BIT); #endif } diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h index 14ac6ad39..eaf1c1330 100644 --- a/src/utils/cpuid.h +++ b/src/utils/cpuid.h @@ -1,6 +1,6 @@ /* * Runtime CPU detection -* (C) 2009-2010 Jack Lloyd +* (C) 2009-2010,2013 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -26,7 +26,7 @@ class BOTAN_DLL CPUID /** * Return a best guess of the cache line size */ - static size_t cache_line_size() { return cache_line; } + static size_t cache_line_size() { return m_cache_line_size; } /** * Check if the processor supports RDTSC @@ -59,10 +59,16 @@ class BOTAN_DLL CPUID { return x86_processor_flags_has(CPUID_SSE42_BIT); } /** - * Check if the processor supports extended AVX vector instructions + * Check if the processor supports AVX2 */ - static bool has_avx() - { return x86_processor_flags_has(CPUID_AVX_BIT); } + static bool has_avx2() + { return x86_processor_flags_has(CPUID_AVX2_BIT); } + + /** + * Check if the processor supports BMI2 + */ + static bool has_bmi2() + { return x86_processor_flags_has(CPUID_BMI2_BIT); } /** * Check if the processor supports AES-NI @@ -77,15 +83,33 @@ class BOTAN_DLL CPUID { return x86_processor_flags_has(CPUID_PCMUL_BIT); } /** + * Check if the processor supports Intel SHA extension + */ + static bool has_intel_sha() + { return x86_processor_flags_has(CPUID_SHA_BIT); } + + /** + * Check if the processor supports ADX extension + */ + static bool has_adx() + { return x86_processor_flags_has(CPUID_ADX_BIT); } + + /** * Check if the processor supports RDRAND */ static bool has_rdrand() { return x86_processor_flags_has(CPUID_RDRAND_BIT); } /** + * Check if the processor supports RDSEED + */ + static bool has_rdseed() + { return x86_processor_flags_has(CPUID_RDSEED_BIT); } + + /** * Check if the processor supports AltiVec/VMX */ - static bool has_altivec() { return altivec_capable; } + static bool has_altivec() { return m_altivec_capable; } private: enum CPUID_bits { CPUID_RDTSC_BIT = 4, @@ -95,18 +119,23 @@ class BOTAN_DLL CPUID CPUID_SSE41_BIT = 51, CPUID_SSE42_BIT = 52, CPUID_AESNI_BIT = 57, - CPUID_AVX_BIT = 60, - CPUID_RDRAND_BIT = 62 + CPUID_RDRAND_BIT = 62, + + CPUID_AVX2_BIT = 64+5, + CPUID_BMI2_BIT = 64+8, + CPUID_RDSEED_BIT = 64+18, + CPUID_ADX_BIT = 64+19, + CPUID_SHA_BIT = 64+29, }; static bool x86_processor_flags_has(u64bit bit) { - return ((x86_processor_flags >> bit) & 1); + return ((m_x86_processor_flags[bit/64] >> (bit % 64)) & 1); } - static u64bit x86_processor_flags; - static size_t cache_line; - static bool altivec_capable; + static u64bit m_x86_processor_flags[2]; + static size_t m_cache_line_size; + static bool m_altivec_capable; }; } diff --git a/src/utils/http_util/info.txt b/src/utils/http_util/info.txt index 39b8ffba6..279e93352 100644 --- a/src/utils/http_util/info.txt +++ b/src/utils/http_util/info.txt @@ -1,3 +1,7 @@ define HTTP_UTIL 20131128 load_on auto + +<libs> +all -> boost_system +</libs> diff --git a/src/utils/info.txt b/src/utils/info.txt index 33f38386d..0e8edeb00 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -2,17 +2,6 @@ define UTIL_FUNCTIONS 20131128 load_on always -<source> -assert.cpp -calendar.cpp -charset.cpp -cpuid.cpp -parsing.cpp -semaphore.cpp -version.cpp -zero_mem.cpp -</source> - <header:internal> bit_ops.h prefetch.h diff --git a/src/utils/parsing.h b/src/utils/parsing.h index 88c5a7bc0..b37e3cb62 100644 --- a/src/utils/parsing.h +++ b/src/utils/parsing.h @@ -13,6 +13,10 @@ #include <vector> #include <set> +#include <istream> +#include <functional> +#include <map> + namespace Botan { /** @@ -112,6 +116,18 @@ BOTAN_DLL u32bit string_to_ipv4(const std::string& ip_str); */ BOTAN_DLL std::string ipv4_to_string(u32bit ip_addr); +void BOTAN_DLL lex_cfg(std::istream& is, + std::function<void (std::string)> cb); + +void BOTAN_DLL lex_cfg_w_headers(std::istream& is, + std::function<void (std::string)> cb, + std::function<void (std::string)> header_cb); + +std::map<std::string, std::map<std::string, std::string>> +BOTAN_DLL +parse_cfg(std::istream& is); + + } #endif diff --git a/src/utils/read_cfg.cpp b/src/utils/read_cfg.cpp new file mode 100644 index 000000000..ad57a8b3e --- /dev/null +++ b/src/utils/read_cfg.cpp @@ -0,0 +1,115 @@ +/* +* Simple config/test file reader +* (C) 2013 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/parsing.h> +#include <boost/algorithm/string.hpp> + +namespace Botan { + +void lex_cfg(std::istream& is, + std::function<void (std::string)> cb) + { + while(is.good()) + { + std::string s; + + std::getline(is, s); + + while(is.good() && s.back() == '\\') + { + boost::trim_if(s, boost::is_any_of("\\\n")); + std::string x; + std::getline(is, x); + boost::trim_left(x); + s += x; + } + + auto comment = s.find('#'); + if(comment) + s = s.substr(0, comment); + + if(s.empty()) + continue; + + std::vector<std::string> parts; + boost::split(parts, s, boost::is_any_of(" \t\n"), boost::token_compress_on); + + for(auto p : parts) + { + if(p.empty()) + continue; + + auto eq = p.find("="); + + if(eq == std::string::npos || p.size() < 2) + { + cb(p); + } + else if(eq == 0) + { + cb("="); + cb(p.substr(1, std::string::npos)); + } + else if(eq == p.size() - 1) + { + cb(p.substr(0, p.size() - 1)); + cb("="); + } + else if(eq != std::string::npos) + { + cb(p.substr(0, eq)); + cb("="); + cb(p.substr(eq + 1, std::string::npos)); + } + } + } + } + +void lex_cfg_w_headers(std::istream& is, + std::function<void (std::string)> cb, + std::function<void (std::string)> hdr_cb) + { + auto intercept = [cb,hdr_cb](const std::string& s) + { + if(s[0] == '[' && s[s.length()-1] == ']') + hdr_cb(s.substr(1, s.length()-2)); + else + cb(s); + }; + + lex_cfg(is, intercept); + } + +std::map<std::string, std::map<std::string, std::string>> + parse_cfg(std::istream& is) + { + std::string header = "default"; + std::map<std::string, std::map<std::string, std::string>> vals; + std::string key; + + auto header_cb = [&header](const std::string i) { header = i; }; + auto cb = [&header,&key,&vals](const std::string s) + { + if(s == "=") + { + BOTAN_ASSERT(!key.empty(), "Valid assignment in config"); + } + else if(key.empty()) + key = s; + else + { + vals[header][key] = s; + key = ""; + } + }; + + lex_cfg_w_headers(is, cb, header_cb); + + return vals; + } + +} |