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 | |
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')
388 files changed, 6667 insertions, 7007 deletions
diff --git a/src/build-data/arch/arm.txt b/src/build-data/arch/arm32.txt index 81ecc05c3..67be376d6 100644 --- a/src/build-data/arch/arm.txt +++ b/src/build-data/arch/arm32.txt @@ -1,8 +1,8 @@ - endian little family arm <aliases> +arm armel # For Debian armhf # For Debian evbarm # For NetBSD diff --git a/src/build-data/arch/arm64.txt b/src/build-data/arch/arm64.txt new file mode 100644 index 000000000..362cf88d3 --- /dev/null +++ b/src/build-data/arch/arm64.txt @@ -0,0 +1,12 @@ +endian little +wordsize 64 + +family arm + +<aliases> +aarch64 +</aliases> + +<submodels> +armv8-a +</submodels> diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index 5db2ce566..3061c9608 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -57,7 +57,34 @@ * If enabled the ECC implementation will use Montgomery ladder * instead of a fixed window implementation. */ -#define BOTAN_CURVE_GFP_USE_MONTGOMERY_LADDER 0 +#define BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER 0 + +/* +* Set number of bits used to generate mask for blinding the scalar of +* a point multiplication. Set to zero to disable this side-channel +* countermeasure. +*/ +#define BOTAN_POINTGFP_SCALAR_BLINDING_BITS 20 + +/* +* Set number of bits used to generate mask for blinding the +* representation of an ECC point. Set to zero to diable this +* side-channel countermeasure. +*/ +#define BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS 80 + +/* +* Normally blinding is performed by choosing a random starting point (plus +* its inverse, of a form appropriate to the algorithm being blinded), and +* then choosing new blinding operands by successive squaring of both +* values. This is much faster than computing a new starting point but +* introduces some possible coorelation +* +* To avoid possible leakage problems in long-running processes, the blinder +* periodically reinitializes the sequence. This value specifies how often +* a new sequence should be started. +*/ +#define BOTAN_BLINDING_REINIT_INTERVAL 32 /* PK key consistency checking toggles */ #define BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD 1 @@ -65,6 +92,12 @@ #define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_GENERATE 1 /* +* Define BOTAN_USE_CTGRIND to enable checking constant time +* annotations using ctgrind https://github.com/agl/ctgrind +*/ +//#define BOTAN_USE_CTGRIND + +/* * RNGs will automatically poll the system for additional seed material * after producing this many bytes of output. */ diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt index 8b09831d6..129218dcd 100644 --- a/src/build-data/cc/clang.txt +++ b/src/build-data/cc/clang.txt @@ -6,6 +6,7 @@ output_to_option "-o " add_include_dir_option -I add_lib_dir_option -L add_lib_option -l +add_framework_option "-framework " lang_flags "-std=c++11 -D_REENTRANT -fstack-protector" @@ -26,12 +27,12 @@ visibility_attribute '__attribute__((visibility("default")))' makefile_style gmake <so_link_commands> -darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)" -darwin-debug -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)" +darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME_ABI)" +darwin-debug -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME_ABI)" # The default works for GNU ld and several other Unix linkers -default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" -default-debug -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" +default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)" +default-debug -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)" </so_link_commands> <binary_link_commands> diff --git a/src/build-data/cc/ekopath.txt b/src/build-data/cc/ekopath.txt index 823eed7a9..a41abc7c4 100644 --- a/src/build-data/cc/ekopath.txt +++ b/src/build-data/cc/ekopath.txt @@ -22,7 +22,7 @@ shared_flags "-fPIC" makefile_style gmake <so_link_commands> -default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" +default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)" </so_link_commands> <mach_opt> diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index 225440a35..4eacacef2 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -30,13 +30,13 @@ makefile_style gmake <so_link_commands> # The default works for GNU ld and several other Unix linkers -default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" -default-debug -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" +default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)" +default-debug -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)" # Darwin, HP-UX and Solaris linkers use different syntax -darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)" -hpux -> "$(CXX) -shared -fPIC -Wl,+h,$(SONAME)" -solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME)" +darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME_ABI)" +hpux -> "$(CXX) -shared -fPIC -Wl,+h,$(SONAME_ABI)" +solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME_ABI)" # AIX and OpenBSD don't use sonames at all aix -> "$(CXX) -shared -fPIC" @@ -91,7 +91,8 @@ sh4 -> "-m4 -mieee" # *removed* from the submodel name before it's put into SUBMODEL. alpha -> "-mcpu=SUBMODEL" alpha- -arm -> "-march=SUBMODEL" +arm32 -> "-march=SUBMODEL" +arm64 -> "-march=SUBMODEL" superh -> "-mSUBMODEL" sh hppa -> "-march=SUBMODEL" hppa ia64 -> "-mtune=SUBMODEL" diff --git a/src/build-data/cc/hpcc.txt b/src/build-data/cc/hpcc.txt index 904e489c9..2e30995f6 100644 --- a/src/build-data/cc/hpcc.txt +++ b/src/build-data/cc/hpcc.txt @@ -25,5 +25,5 @@ hppa2.0 -> "+DA2.0W" </mach_abi_linking> <so_link_commands> -default -> "$(CXX) +Z -b -Wl,+h,$(SONAME)" # Documented in cc(1), but not CC(1) (?) +default -> "$(CXX) +Z -b -Wl,+h,$(SONAME_ABI)" # Documented in cc(1), but not CC(1) (?) </so_link_commands> diff --git a/src/build-data/cc/icc.txt b/src/build-data/cc/icc.txt index f15d9eb9c..f7fdf72be 100644 --- a/src/build-data/cc/icc.txt +++ b/src/build-data/cc/icc.txt @@ -30,5 +30,5 @@ westmere -> "-march=core2" </mach_opt> <so_link_commands> -default -> "$(CXX) -fPIC -shared -Wl,-soname,$(SONAME)" +default -> "$(CXX) -fPIC -shared -Wl,-soname,$(SONAME_ABI)" </so_link_commands> diff --git a/src/build-data/cc/pgi.txt b/src/build-data/cc/pgi.txt index 50042388d..ca4b49cd9 100644 --- a/src/build-data/cc/pgi.txt +++ b/src/build-data/cc/pgi.txt @@ -16,8 +16,8 @@ shared_flags "-fPIC" makefile_style gmake <so_link_commands> -linux -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" -solaris -> "$(CXX) -G -fPIC -Wl,-h,$(SONAME)" +linux -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)" +solaris -> "$(CXX) -G -fPIC -Wl,-h,$(SONAME_ABI)" </so_link_commands> <mach_opt> diff --git a/src/build-data/cc/sunstudio.txt b/src/build-data/cc/sunstudio.txt index 37998e859..964c878ff 100644 --- a/src/build-data/cc/sunstudio.txt +++ b/src/build-data/cc/sunstudio.txt @@ -21,7 +21,7 @@ ar_command "CC -xar -o" makefile_style gmake <so_link_commands> -default -> "$(CXX) -G -h$(SONAME)" +default -> "$(CXX) -G -h$(SONAME_ABI)" </so_link_commands> <mach_opt> diff --git a/src/build-data/makefile/gmake.in b/src/build-data/makefile/gmake.in index c6ef73854..4eb4b0fe6 100644 --- a/src/build-data/makefile/gmake.in +++ b/src/build-data/makefile/gmake.in @@ -47,7 +47,7 @@ $(STATIC_LIB): $(LIBOBJS) $(RANLIB) $(STATIC_LIB) # Fake targets -.PHONY = clean distclean docs install valgrind lcov +.PHONY: clean distclean docs install valgrind lcov %{gmake_coverage_in} diff --git a/src/build-data/makefile/gmake_dso.in b/src/build-data/makefile/gmake_dso.in index 0e7974791..fa167b780 100644 --- a/src/build-data/makefile/gmake_dso.in +++ b/src/build-data/makefile/gmake_dso.in @@ -1,12 +1,12 @@ -SHARED_LIB_NAME = $(LIB_BASENAME).%{so_suffix}.%{so_abi_rev}.%{version_patch} -SONAME = $(LIB_BASENAME).%{so_suffix}.%{so_abi_rev} -SYMLINK = $(LIB_BASENAME).%{so_suffix} +SONAME_PATCH = %{soname_patch} +SONAME_ABI = %{soname_abi} +SONAME_BASE = %{soname_base} -SHARED_LIB = %{out_dir}/$(SHARED_LIB_NAME) +SHARED_LIB = %{out_dir}/$(SONAME_PATCH) $(SHARED_LIB): $(LIBOBJS) $(LIB_LINK_CMD) $(LDFLAGS) $(LIBOBJS) $(LIB_LINKS_TO) -o $(SHARED_LIB) - $(LN) $(SHARED_LIB_NAME) %{out_dir}/$(SONAME) - $(LN) $(SHARED_LIB_NAME) %{out_dir}/$(SYMLINK) + $(LN) $(SONAME_PATCH) %{out_dir}/$(SONAME_ABI) + $(LN) $(SONAME_PATCH) %{out_dir}/$(SONAME_BASE) LIBRARIES += $(SHARED_LIB) diff --git a/src/build-data/os/android.txt b/src/build-data/os/android.txt index 5df133c8e..43e5fdc44 100644 --- a/src/build-data/os/android.txt +++ b/src/build-data/os/android.txt @@ -1,5 +1,9 @@ os_type unix +soname_pattern_base "libbotan-{version_major}.{version_minor}.so" +soname_pattern_abi "libbotan-{version_major}.{version_minor}.so.{abi_rev}" +soname_pattern_patch "libbotan-{version_major}.{version_minor}.so.{abi_rev}.{version_patch}" + <target_features> clock_gettime gettimeofday diff --git a/src/build-data/os/cygwin.txt b/src/build-data/os/cygwin.txt index be67e2607..7788cd3ca 100644 --- a/src/build-data/os/cygwin.txt +++ b/src/build-data/os/cygwin.txt @@ -5,7 +5,7 @@ program_suffix .exe # Cygwin supports shared libs fine, but there are problems with making a Botan # shared library when libraries it depends on are static-only (such as libz). # So until I can figure out a work-around, it's disabled. -build_shared no +building_shared_supported no install_root c:\Botan doc_dir docs diff --git a/src/build-data/os/darwin.txt b/src/build-data/os/darwin.txt index 3a13b34e4..56285ccf7 100644 --- a/src/build-data/os/darwin.txt +++ b/src/build-data/os/darwin.txt @@ -1,6 +1,8 @@ os_type unix -so_suffix dylib +soname_pattern_base "libbotan-{version_major}.{version_minor}.dylib" +soname_pattern_abi "libbotan-{version_major}.{version_minor}.{abi_rev}.dylib" +soname_pattern_patch "libbotan-{version_major}.{version_minor}.{abi_rev}.{version_patch}.dylib" # It doesn't have the 's' option; you need to use needs ranlib ar_command "ar cr" diff --git a/src/build-data/os/hpux.txt b/src/build-data/os/hpux.txt index cea405554..726b0b960 100644 --- a/src/build-data/os/hpux.txt +++ b/src/build-data/os/hpux.txt @@ -1,7 +1,5 @@ os_type unix -so_suffix sl - <target_features> gettimeofday getsid diff --git a/src/build-data/os/linux.txt b/src/build-data/os/linux.txt index 48c3bf318..c83e57afa 100644 --- a/src/build-data/os/linux.txt +++ b/src/build-data/os/linux.txt @@ -1,5 +1,9 @@ os_type unix +soname_pattern_base "libbotan-{version_major}.{version_minor}.so" +soname_pattern_abi "libbotan-{version_major}.{version_minor}.so.{abi_rev}" +soname_pattern_patch "libbotan-{version_major}.{version_minor}.so.{abi_rev}.{version_patch}" + <target_features> clock_gettime gettimeofday diff --git a/src/build-data/os/mingw.txt b/src/build-data/os/mingw.txt index cc98b11e6..5c72099e0 100644 --- a/src/build-data/os/mingw.txt +++ b/src/build-data/os/mingw.txt @@ -2,10 +2,9 @@ os_type windows program_suffix .exe obj_suffix o -so_suffix dll static_suffix a -build_shared no +building_shared_supported no ar_command "ar crs" ar_needs_ranlib yes diff --git a/src/build-data/os/windows.txt b/src/build-data/os/windows.txt index fd74fe817..32236e00b 100644 --- a/src/build-data/os/windows.txt +++ b/src/build-data/os/windows.txt @@ -2,9 +2,10 @@ os_type windows program_suffix .exe obj_suffix obj -so_suffix dll static_suffix lib +soname_pattern_base "botan.dll" + install_root c:\\Botan doc_dir docs diff --git a/src/cmd/apps.h b/src/cmd/apps.h index bcb860fb4..d56fab5ad 100644 --- a/src/cmd/apps.h +++ b/src/cmd/apps.h @@ -68,3 +68,9 @@ class AppRegistrations }; #define REGISTER_APP(nm) AppRegistrations::AppRegistration g_ ## nm ## _registration(#nm, nm) + +#if defined(BOTAN_TARGET_OS_IS_WINDOWS) || defined(BOTAN_TARGET_OS_IS_MINGW) + #undef BOTAN_TARGET_OS_HAS_SOCKETS +#else + #define BOTAN_TARGET_OS_HAS_SOCKETS +#endif diff --git a/src/cmd/credentials.h b/src/cmd/credentials.h index f7109e1a3..06349657d 100644 --- a/src/cmd/credentials.h +++ b/src/cmd/credentials.h @@ -10,11 +10,6 @@ #include <botan/pkcs8.h> #include <botan/credentials_manager.h> #include <botan/x509self.h> -#include <botan/rsa.h> -#include <botan/dsa.h> -#include <botan/srp6.h> -#include <botan/srp6_files.h> -#include <botan/ecdsa.h> #include <iostream> #include <fstream> #include <memory> diff --git a/src/cmd/dl_group.cpp b/src/cmd/dl_group.cpp new file mode 100644 index 000000000..2db65ded2 --- /dev/null +++ b/src/cmd/dl_group.cpp @@ -0,0 +1,85 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "apps.h" + +#if defined(BOTAN_HAS_DL_GROUP) + +#include <botan/dl_group.h> +#include <fstream> + +namespace { + +std::string read_file_contents(const std::string& filename) + { + std::ifstream in(filename.c_str()); + if(!in.good()) + throw std::runtime_error("Failure reading " + filename); + + std::vector<std::string> contents; + size_t total_size = 0; + while(in.good()) + { + std::string line; + std::getline(in, line); + total_size += line.size(); + contents.push_back(std::move(line)); + } + + std::string res; + contents.reserve(total_size); + for(auto&& line : contents) + res += line; + return res; + } + +int dl_group(int argc, char* argv[]) + { + if(argc < 2) + { + std::cout << "Usage: " << argv[0] << " [create bits|info file]" << std::endl; + return 1; + } + + const std::string cmd = argv[1]; + + if(cmd == "create") + { + AutoSeeded_RNG rng; + const size_t bits = to_u32bit(argv[2]); + + const DL_Group::PrimeType prime_type = DL_Group::Strong; + //const DL_Group::PrimeType prime_type = DL_Group::Prime_Subgroup; + + DL_Group grp(rng, prime_type, bits); + + std::cout << grp.PEM_encode(DL_Group::DSA_PARAMETERS); + } + else if(cmd == "info") + { + DL_Group grp; + std::string pem = read_file_contents(argv[2]); + std::cout << pem << "\n"; + + std::cout << "DL_Group " << grp.get_p().bits() << " bits\n"; + std::cout << "p=" << grp.get_p() << "\n"; + std::cout << "q=" << grp.get_q() << "\n"; + std::cout << "g=" << grp.get_g() << "\n"; + } + else + { + std::cout << "ERROR: Unknown command\n"; + return 1; + } + + return 0; + } + +REGISTER_APP(dl_group); + +} + +#endif diff --git a/src/cmd/hash.cpp b/src/cmd/hash.cpp index fdeaa465d..7755bb4a5 100644 --- a/src/cmd/hash.cpp +++ b/src/cmd/hash.cpp @@ -8,7 +8,6 @@ #if defined(BOTAN_HAS_CODEC_FILTERS) -#include <botan/lookup.h> #include <botan/filters.h> #include <iostream> #include <fstream> diff --git a/src/cmd/implementation/speed.h b/src/cmd/implementation/speed.h new file mode 100644 index 000000000..3cfd0ef61 --- /dev/null +++ b/src/cmd/implementation/speed.h @@ -0,0 +1,30 @@ +/* +* (C) 2014 Jack Lloyd +* (C) 2015 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CHECK_BENCHMARK_H__ +#define BOTAN_CHECK_BENCHMARK_H__ + +#include <botan/rng.h> +#include <string> +#include <chrono> + +void benchmark_public_key(Botan::RandomNumberGenerator& rng, + const std::string& algo, + const std::string& provider, + double seconds); + +std::map<std::string, double> benchmark_is_prime(Botan::RandomNumberGenerator &rng, + const std::chrono::milliseconds runtime); + +std::map<std::string, double> benchmark_random_prime(Botan::RandomNumberGenerator &rng, + const std::chrono::milliseconds runtime); + +bool benchmark_transform(Botan::RandomNumberGenerator& rng, const std::string& algo_name, + const std::chrono::milliseconds runtime); + + +#endif diff --git a/src/cmd/implementation/speed_prime.cpp b/src/cmd/implementation/speed_prime.cpp new file mode 100644 index 000000000..a7a344bef --- /dev/null +++ b/src/cmd/implementation/speed_prime.cpp @@ -0,0 +1,96 @@ +/* +* (C) 2015 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "speed.h" + +using namespace Botan; + +#if defined(BOTAN_HAS_NUMBERTHEORY) + +#include <botan/numthry.h> +#include <chrono> + +namespace { +const size_t RSA_EXP = 65537; +const size_t RSA_BITS = 2048; + +const auto SAMPLE_DATA = std::vector<BigInt>{ + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895363"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895377"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895381"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895389"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895399"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895401"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895431"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895441"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895461"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895471"), + }; +} + +#endif // BOTAN_HAS_NUMBERTHEORY + +std::map<std::string, double> benchmark_is_prime(RandomNumberGenerator& rng, + const std::chrono::milliseconds runtime) + { + std::map<std::string, double> speeds; + +#if defined(BOTAN_HAS_NUMBERTHEORY) + + std::chrono::nanoseconds time_used(0); + size_t reps = 0; + + auto start = std::chrono::high_resolution_clock::now(); + + while(time_used < runtime) + { + // main work + for (const BigInt &p : SAMPLE_DATA) + { + is_prime(p, rng, 64, true); + } + + ++reps; + time_used = std::chrono::high_resolution_clock::now() - start; + } + + const double seconds_used = static_cast<double>(time_used.count()) / 1000000000; + speeds["base"] = reps / seconds_used; // ie, return ops per second + +#endif // BOTAN_HAS_NUMBERTHEORY + + return speeds; + } + +std::map<std::string, double> benchmark_random_prime(RandomNumberGenerator& rng, + const std::chrono::milliseconds runtime) + { + std::map<std::string, double> speeds; + +#if defined(BOTAN_HAS_NUMBERTHEORY) + + std::chrono::nanoseconds time_used(0); + size_t reps = 0; + + auto start = std::chrono::high_resolution_clock::now(); + + while(time_used < runtime) + { + // main work + random_prime(rng, (RSA_BITS + 1) / 2, RSA_EXP); + + ++reps; + time_used = std::chrono::high_resolution_clock::now() - start; + } + + const double seconds_used = static_cast<double>(time_used.count()) / 1000000000; + speeds["base"] = reps / seconds_used; // ie, return ops per second + +#endif // BOTAN_HAS_NUMBERTHEORY + + return speeds; + } + diff --git a/src/cmd/speed_pk.cpp b/src/cmd/implementation/speed_public_key.cpp index 035b9a3af..2ff49bd15 100644 --- a/src/cmd/speed_pk.cpp +++ b/src/cmd/implementation/speed_public_key.cpp @@ -4,7 +4,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include "apps.h" +#include "../apps.h" #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) @@ -82,12 +82,15 @@ using namespace Botan; namespace { const char* ec_domains[] = { - "secp160r2", - "secp192r1", - "secp224r1", + // "secp160r2", + // "secp192r1", + // "secp224r1", "secp256r1", "secp384r1", "secp521r1", + //"brainpool256r1", + //"brainpool384r1", + //"brainpool512r1", nullptr }; @@ -159,6 +162,8 @@ void benchmark_sig_ver(PK_Verifier& ver, PK_Signer& sig, message.resize(48); rng.randomize(&message[0], message.size()); } + else + message[0]++; sig_timer.start(); signature = sig.sign_message(message, rng); @@ -197,7 +202,8 @@ void benchmark_sig_ver(PK_Verifier& ver, PK_Signer& sig, */ #if defined(BOTAN_HAS_RSA) -void benchmark_rsa(RandomNumberGenerator& rng, +void benchmark_rsa(const std::string& provider, + RandomNumberGenerator& rng, double seconds, Benchmark_Report& report) { @@ -208,8 +214,8 @@ void benchmark_rsa(RandomNumberGenerator& rng, { size_t keylen = keylens[i]; - //const std::string sig_padding = "EMSA4(SHA-1)"; - //const std::string enc_padding = "EME1(SHA-1)"; + //const std::string sig_padding = "PSSR(SHA-256)"; + //const std::string enc_padding = "OAEP(SHA-1)"; const std::string sig_padding = "EMSA-PKCS1-v1_5(SHA-1)"; const std::string enc_padding = "EME-PKCS1-v1_5"; @@ -238,14 +244,14 @@ void benchmark_rsa(RandomNumberGenerator& rng, while(verify_timer.seconds() < seconds || sig_timer.seconds() < seconds) { - PK_Encryptor_EME enc(key, enc_padding); - PK_Decryptor_EME dec(key, enc_padding); + PK_Encryptor_EME enc(key, enc_padding, provider); + PK_Decryptor_EME dec(key, enc_padding, provider); benchmark_enc_dec(enc, dec, enc_timer, dec_timer, rng, 10000, seconds); - PK_Signer sig(key, sig_padding); - PK_Verifier ver(key, sig_padding); + PK_Signer sig(key, sig_padding, IEEE_1363, provider); + PK_Verifier ver(key, sig_padding, IEEE_1363, provider); benchmark_sig_ver(ver, sig, verify_timer, sig_timer, rng, 10000, seconds); @@ -313,7 +319,8 @@ void benchmark_rw(RandomNumberGenerator& rng, #if defined(BOTAN_HAS_ECDSA) -void benchmark_ecdsa(RandomNumberGenerator& rng, +void benchmark_ecdsa(const std::string& provider, + RandomNumberGenerator& rng, double seconds, Benchmark_Report& report) { @@ -343,14 +350,14 @@ void benchmark_ecdsa(RandomNumberGenerator& rng, ECDSA_PrivateKey key(rng, params); keygen_timer.stop(); - PK_Signer sig(key, padding, IEEE_1363); - PK_Verifier ver(key, padding); + PK_Signer sig(key, padding, IEEE_1363, provider); + PK_Verifier ver(key, padding, IEEE_1363, provider); benchmark_sig_ver(ver, sig, verify_timer, sig_timer, rng, 1000, seconds); } - const std::string nm = "ECDSA-" + std::to_string(pbits); + const std::string nm = std::string("ECDSA ") + ec_domains[j]; report.report(nm, keygen_timer); report.report(nm, verify_timer); @@ -729,20 +736,21 @@ void benchmark_mce(RandomNumberGenerator& rng, Benchmark_Report& report) { const std::vector<std::pair<size_t, size_t>> params = { - { 1024, 35 }, - { 2048, 50 }, - { 2960, 56 }, + { 1632, 33 }, + { 2480, 45 }, + { 2960, 57 }, + { 3408, 67 }, + { 4264, 95 }, { 6624, 115 } }; const std::string algo_name = "McEliece"; - const std::string padding = "Raw"; for(auto& param : params) { Timer keygen_timer("keygen"); - Timer enc_timer(padding + " encrypt"); - Timer dec_timer(padding + " decrypt"); + Timer enc_timer("encrypt"); + Timer dec_timer("decrypt"); keygen_timer.start(); McEliece_PrivateKey priv_key(rng, param.first, param.second); @@ -771,9 +779,9 @@ void benchmark_mce(RandomNumberGenerator& rng, std::to_string(param.second); std::ostringstream keysize_report; - keysize_report << "(size " << pub_key.x509_subject_public_key().size() << " pub " - << priv_key.pkcs8_private_key().size() << " priv " - << pub_key.estimated_strength() << " work factor)"; + keysize_report << "(work factor " << pub_key.estimated_strength() << ", " + << "pub bytes " << pub_key.x509_subject_public_key().size() << " " + << "priv bytes " << priv_key.pkcs8_private_key().size() << ")"; report.report(nm + " " + keysize_report.str(), keygen_timer); report.report(nm, enc_timer); @@ -784,8 +792,10 @@ void benchmark_mce(RandomNumberGenerator& rng, } -void bench_pk(RandomNumberGenerator& rng, - const std::string& algo, double seconds) +void benchmark_public_key(RandomNumberGenerator& rng, + const std::string& algo, + const std::string& provider, + double seconds) { /* There is some strangeness going on here. It looks like algorithms @@ -817,7 +827,7 @@ void bench_pk(RandomNumberGenerator& rng, #if defined(BOTAN_HAS_RSA) if(algo == "All" || algo == "RSA") - benchmark_rsa(rng, seconds, report); + benchmark_rsa(provider, rng, seconds, report); #endif #if defined(BOTAN_HAS_DSA) @@ -827,7 +837,7 @@ void bench_pk(RandomNumberGenerator& rng, #if defined(BOTAN_HAS_ECDSA) if(algo == "All" || algo == "ECDSA") - benchmark_ecdsa(rng, seconds, report); + benchmark_ecdsa(provider, rng, seconds, report); #endif #if defined(BOTAN_HAS_ECDH) diff --git a/src/cmd/implementation/speed_transform.cpp b/src/cmd/implementation/speed_transform.cpp new file mode 100644 index 000000000..2db5cdd70 --- /dev/null +++ b/src/cmd/implementation/speed_transform.cpp @@ -0,0 +1,67 @@ +/* +* (C) 2009 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "speed.h" + +#include <iostream> +#include <iomanip> + +#include <botan/cipher_mode.h> +#include <botan/transform.h> + +using namespace Botan; + +namespace { +void benchmark_transform(std::unique_ptr<Transform> tf, + RandomNumberGenerator& rng, + const std::chrono::milliseconds runtime) + { + for(size_t buf_size : { 16, 64, 256, 1024, 8192 }) + { + secure_vector<byte> buffer(buf_size); + + std::chrono::nanoseconds time_used(0); + + tf->start(rng.random_vec(tf->default_nonce_length())); + + auto start = std::chrono::high_resolution_clock::now(); + + secure_vector<byte> buf(buf_size); + size_t reps = 0; + while(time_used < runtime) + { + tf->update(buf); + buf.resize(buf_size); + ++reps; + time_used = std::chrono::high_resolution_clock::now() - start; + } + + const u64bit nsec_used = std::chrono::duration_cast<std::chrono::nanoseconds>(time_used).count(); + + const double seconds_used = static_cast<double>(nsec_used) / 1000000000; + + const double Mbps = ((reps / seconds_used) * buf_size) / 1024 / 1024; + + std::cout << tf->name() << " " << std::setprecision(4) << Mbps + << " MiB / sec with " << buf_size << " byte blocks" << std::endl; + } + } +} + +bool benchmark_transform(RandomNumberGenerator& rng, const std::string& algo_name, + const std::chrono::milliseconds runtime) + { + std::unique_ptr<Transform> tf; + tf.reset(get_cipher_mode(algo_name, ENCRYPTION)); + if(!tf) + return false; + + if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(tf.get())) + keyed->set_key(rng.random_vec(keyed->key_spec().maximum_keylength())); + + benchmark_transform(std::move(tf), rng, runtime); + return true; + } diff --git a/src/cmd/timer.cpp b/src/cmd/implementation/timer.cpp index 14e55316b..14e55316b 100644 --- a/src/cmd/timer.cpp +++ b/src/cmd/implementation/timer.cpp diff --git a/src/cmd/timer.h b/src/cmd/implementation/timer.h index ac5bd5cef..ac5bd5cef 100644 --- a/src/cmd/timer.h +++ b/src/cmd/implementation/timer.h diff --git a/src/cmd/mce.cpp b/src/cmd/mce.cpp new file mode 100644 index 000000000..3b33df661 --- /dev/null +++ b/src/cmd/mce.cpp @@ -0,0 +1,117 @@ +#include "apps.h" + +#if defined(BOTAN_HAS_MCELIECE) + +#include <botan/mceliece.h> +#include <botan/mceies.h> +#include <botan/pkcs8.h> +#include <fstream> + +namespace { + +int mce(int argc, char* argv[]) + { + if(argc < 4) + { + std::cout << "Usage: " << argv[0] << " [keygen n t pass|keybits n t|encrypt file key|decrypt file key pass]\n"; + return 1; + } + + const std::string cmd = argv[1]; + + AutoSeeded_RNG rng; + + if(cmd == "keygen") + { + const size_t n = std::stol(argv[2]); + const size_t t = std::stol(argv[3]); + const std::string pass = argv[4]; + + McEliece_PrivateKey pk(rng, n, t); + + bool ok = pk.check_key(rng, true); + + if(!ok) + { + std::cout << "Keygen failed self-test\n"; + return 2; + } + + /* + secure_vector<byte> priv = PKCS8::BER_encode(pk); + std::vector<byte> pub = X509::BER_encode(pk); + std::cout << priv.size()/1024.0 << " " << pub.size()/1024.0 << "\n"; + */ + + std::ofstream pub_file("mce.pub"); + pub_file << X509::PEM_encode(pk); + pub_file.close(); + + std::ofstream priv_file("mce.priv"); + priv_file << PKCS8::PEM_encode(pk, rng, pass); + priv_file.close(); + } + else if(cmd == "keybits") + { + const size_t n = std::stol(argv[2]); + const size_t t = std::stol(argv[3]); + std::cout << "McEliece key with params (" << n << "," << t << ") has " + << mceliece_work_factor(n, t) << " bit security\n"; + } + else if(cmd == "encrypt") + { + std::unique_ptr<Public_Key> p8(X509::load_key(argv[3])); + const McEliece_PublicKey* key = dynamic_cast<McEliece_PublicKey*>(p8.get()); + + if(!key) + { + throw std::runtime_error("Loading McEliece public key failed"); + } + + const std::string input_path = argv[2]; + std::ifstream in(input_path, std::ios::binary); + std::string pt((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>()); + + secure_vector<byte> ct = mceies_encrypt(*key, + reinterpret_cast<const byte*>(pt.data()), + pt.size(), + nullptr, 0, rng, "AES-128/GCM"); + + std::cout << pt.size() << " -> " << ct.size() << "\n"; + + std::ofstream out(std::string(input_path) + ".ct", std::ios::binary); + out.write(reinterpret_cast<const char*>(ct.data()), ct.size()); + out.close(); + } + else if(cmd == "decrypt") + { + const std::string key_file = argv[3]; + const std::string pass = argv[4]; + std::unique_ptr<Private_Key> p8(PKCS8::load_key(key_file, rng, pass)); + const McEliece_PrivateKey* key = dynamic_cast<McEliece_PrivateKey*>(p8.get()); + + if(!key) + { + throw std::runtime_error("Loading McEliece private key failed"); + } + + std::ifstream in(argv[2], std::ios::binary); + std::string ct((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>()); + + secure_vector<byte> pt = mceies_decrypt(*key, + reinterpret_cast<const byte*>(ct.data()), + ct.size(), + nullptr, 0, "AES-128/GCM"); + + std::ofstream out("mce.plaintext", std::ios::binary); + out.write(reinterpret_cast<const char*>(pt.data()), pt.size()); + out.close(); + } + return 0; + } + +} + +REGISTER_APP(mce); + +#endif diff --git a/src/cmd/pkcs8.cpp b/src/cmd/pkcs8.cpp new file mode 100644 index 000000000..19af70eb1 --- /dev/null +++ b/src/cmd/pkcs8.cpp @@ -0,0 +1,77 @@ +/* +* (C) 2015 René Korthaus +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "apps.h" +#include <iostream> +#include <fstream> +#include <string> +#include <memory> +#include <chrono> + +#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) +#include <botan/pk_keys.h> +#include <botan/pkcs8.h> +#include <botan/x509_key.h> + +using namespace Botan; + +namespace { + +int pkcs8(int argc, char* argv[]) + { + BOTAN_UNUSED(argc); + OptionParser opts("in=|out=|passin=|passout=|pbe=|pubout"); + opts.parse(argv); + + const std::string passin = opts.value_or_else("passin", ""); + const std::string passout = opts.value_or_else("passout", ""); + const std::string pbe = opts.value_or_else("pbe", ""); + + if(argc < 3) + { + opts.help( std::cout, "pkcs8" ); + return 1; + } + + try + { + std::ofstream out_key(opts.value("out")); + + if (!out_key) + { + std::cout << "Couldn't write key" << std::endl; + return 1; + } + + AutoSeeded_RNG rng; + std::unique_ptr<Private_Key> key(PKCS8::load_key(opts.value("in"), rng, passin)); + + if(opts.is_set("pubout")) + { + out_key << X509::PEM_encode(*key); + } + else + { + if(passout.empty()) + out_key << PKCS8::PEM_encode(*key); + else + out_key << PKCS8::PEM_encode(*key, rng, passout, std::chrono::milliseconds(300), pbe); + } + } + catch(std::exception& e) + { + std::cout << "Exception caught: " << e.what() << std::endl; + return 2; + } + + return 0; + } + +REGISTER_APP(pkcs8); + +} + +#endif diff --git a/src/cmd/prime.cpp b/src/cmd/prime.cpp new file mode 100644 index 000000000..61f535dd7 --- /dev/null +++ b/src/cmd/prime.cpp @@ -0,0 +1,48 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "apps.h" + +#if defined(BOTAN_HAS_NUMBERTHEORY) + +#include <botan/numthry.h> + +#include <algorithm> +#include <iostream> + +namespace { + +int prime(int argc, char* argv[]) + { + if(argc < 2) + { + std::cout << "Usage: " << argv[0] << " bits count" << std::endl; + return 1; + } + + AutoSeeded_RNG rng; + const size_t bits = to_u32bit(argv[1]); + const size_t cnt = argv[2] != nullptr ? to_u32bit(argv[2]) : 1; + + for(size_t i = 0; i != cnt; ++i) + { + const BigInt p = random_prime(rng, bits); + std::cout << p << "\n"; + + if(p.bits() != bits) + { + std::cout << "Result not exactly requested bit size, got " << p.bits() << "\n"; + } + } + + return 0; + } + +} + +REGISTER_APP(prime); + +#endif diff --git a/src/cmd/speed.cpp b/src/cmd/speed.cpp index eea3a7c60..990c6a364 100644 --- a/src/cmd/speed.cpp +++ b/src/cmd/speed.cpp @@ -8,27 +8,17 @@ #if defined(BOTAN_HAS_RUNTIME_BENCHMARKING) -#include "speed.h" +#include "implementation/speed.h" + #include <iostream> #include <iomanip> #include <botan/benchmark.h> #include <botan/auto_rng.h> -#include <botan/cipher_mode.h> -#include <botan/parsing.h> -#include <botan/symkey.h> -#include <botan/transform.h> -#include <botan/hex.h> - -#include <chrono> - -typedef std::chrono::high_resolution_clock benchmark_clock; - using namespace Botan; namespace { - const std::vector<std::string> default_benchmark_list = { /* Block ciphers */ "AES-128", @@ -90,7 +80,11 @@ const std::vector<std::string> default_benchmark_list = { /* MACs */ "CMAC(AES-128)", - "HMAC(SHA-1)" + "HMAC(SHA-1)", + + /* Misc */ + "is_prime", + "random_prime" }; void report_results(const std::string& algo, @@ -123,84 +117,50 @@ void report_results(const std::string& algo, std::cout.flags(flags); } -void time_transform(std::unique_ptr<Transform> tf, - RandomNumberGenerator& rng) +void bench_algo(const std::string& algo, + const std::string& provider, + RandomNumberGenerator& rng, + double seconds, + size_t buf_size) { - const std::chrono::seconds runtime(2); - - for(size_t buf_size : { 16, 64, 256, 1024, 8192 }) - { - secure_vector<byte> buffer(buf_size); - - std::chrono::nanoseconds time_used(0); - - tf->start(rng.random_vec(tf->default_nonce_length())); - - auto start = std::chrono::high_resolution_clock::now(); - - secure_vector<byte> buf(buf_size); - size_t reps = 0; - while(time_used < runtime) - { - tf->update(buf); - buf.resize(buf_size); - ++reps; - time_used = std::chrono::high_resolution_clock::now() - start; - } - - const u64bit nsec_used = std::chrono::duration_cast<std::chrono::nanoseconds>(time_used).count(); - - const double seconds_used = static_cast<double>(nsec_used) / 1000000000; + std::chrono::milliseconds runtime( + static_cast<std::chrono::milliseconds::rep>(seconds * 1000)); - const double Mbps = ((reps / seconds_used) * buf_size) / 1024 / 1024; - - std::cout << tf->name() << " " << std::setprecision(4) << Mbps - << " MiB / sec with " << buf_size << " byte blocks" << std::endl; - } - } - -bool time_transform(const std::string& algo, RandomNumberGenerator& rng) + if (algo == "random_prime") { - std::unique_ptr<Transform> tf; - tf.reset(get_cipher_mode(algo, ENCRYPTION)); - if(!tf) - return false; - - if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(tf.get())) - keyed->set_key(rng.random_vec(keyed->key_spec().maximum_keylength())); - - time_transform(std::move(tf), rng); - return true; + auto speeds = benchmark_random_prime(rng, runtime); + report_results(algo, speeds); + return; } -void bench_algo(const std::string& algo, - RandomNumberGenerator& rng, - double seconds, - size_t buf_size) + if (algo == "is_prime") { - std::chrono::milliseconds ms( - static_cast<std::chrono::milliseconds::rep>(seconds * 1000)); + auto speeds = benchmark_is_prime(rng, runtime); + report_results(algo, speeds); + return; + } - if(time_transform(algo, rng)) + // This does report itself + if (benchmark_transform(rng, algo, runtime)) return; - std::map<std::string, double> speeds = algorithm_benchmark(algo, rng, ms, buf_size); - - if(!speeds.empty()) + try { + auto speeds = algorithm_benchmark(algo, rng, runtime, buf_size); report_results(algo, speeds); - return; } - -#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) - bench_pk(rng, algo, seconds); -#endif + catch (No_Provider_Found) + { + #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) + benchmark_public_key(rng, algo, provider, seconds); + #endif + } } int speed(int argc, char* argv[]) { BOTAN_UNUSED(argc); - OptionParser opts("seconds=|buf-size="); + OptionParser opts("seconds=|buf-size=|provider="); opts.parse(argv); double seconds = .5; @@ -226,7 +186,9 @@ int speed(int argc, char* argv[]) } } - auto args = opts.arguments(); + const std::string provider = opts.value_if_set("provider"); + + std::vector<std::string> args = opts.arguments(); if(args.empty()) args = default_benchmark_list; @@ -240,7 +202,9 @@ int speed(int argc, char* argv[]) AutoSeeded_RNG rng; for(auto alg: args) - bench_algo(alg, rng, seconds, buf_size); + { + bench_algo(alg, provider, rng, seconds, buf_size); + } return 0; } diff --git a/src/cmd/speed.h b/src/cmd/speed.h deleted file mode 100644 index 5f3918a3f..000000000 --- a/src/cmd/speed.h +++ /dev/null @@ -1,16 +0,0 @@ -/* -* (C) 2014 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_CHECK_BENCHMARK_H__ -#define BOTAN_CHECK_BENCHMARK_H__ - -#include <botan/rng.h> -#include <string> - -void bench_pk(Botan::RandomNumberGenerator& rng, - const std::string& algo, double seconds); - -#endif diff --git a/src/cmd/tls_client.cpp b/src/cmd/tls_client.cpp index a5da299c6..f9d32ea6c 100644 --- a/src/cmd/tls_client.cpp +++ b/src/cmd/tls_client.cpp @@ -6,10 +6,7 @@ #include "apps.h" -#if defined(BOTAN_HAS_TLS) \ - && defined(BOTAN_HAS_DSA) \ - && !defined(BOTAN_TARGET_OS_IS_WINDOWS) \ - && !defined(BOTAN_TARGET_OS_IS_MINGW) +#if defined(BOTAN_HAS_TLS) && defined(BOTAN_TARGET_OS_HAS_SOCKETS) #include <botan/tls_client.h> #include <botan/pkcs8.h> diff --git a/src/cmd/tls_server.cpp b/src/cmd/tls_server.cpp index 744ab5544..cd95cf0d6 100644 --- a/src/cmd/tls_server.cpp +++ b/src/cmd/tls_server.cpp @@ -7,9 +7,7 @@ #include "apps.h" -#if defined(BOTAN_HAS_TLS) && defined(BOTAN_HAS_DSA) \ - && !defined(BOTAN_TARGET_OS_IS_WINDOWS) \ - && !defined(BOTAN_TARGET_OS_IS_MINGW) +#if defined(BOTAN_HAS_TLS) && defined(BOTAN_TARGET_OS_HAS_SOCKETS) #include <botan/tls_server.h> #include <botan/hex.h> diff --git a/src/contrib/perl-xs/Botan.pm b/src/contrib/perl-xs/Botan.pm deleted file mode 100644 index ac4ad91fb..000000000 --- a/src/contrib/perl-xs/Botan.pm +++ /dev/null @@ -1,117 +0,0 @@ -package Botan; - -use strict; -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD); - -require DynaLoader; -require AutoLoader; -use Carp; - -@ISA = qw(DynaLoader); -$VERSION = '0.01'; - -@EXPORT_OK = qw( - NONE - IGNORE_WS - FULL_CHECK -); - -%EXPORT_TAGS = ( - 'all' => [ @EXPORT_OK ], - 'decoder_checking' => [ qw( - NONE - IGNORE_WS - FULL_CHECK - )], - -); - - -sub AUTOLOAD -{ - # This AUTOLOAD is used to 'autoload' constants from the constant() - # XS function. If a constant is not found then control is passed - # to the AUTOLOAD in AutoLoader. - - my $constname = $AUTOLOAD; - $constname =~ s/.*:://; - croak '& not defined' if $constname eq 'constant'; -# my $val = constant($constname, @_ ? $_[0] : 0); - my $val = constant($constname); - if ($! != 0) { - if ( $! =~ /Invalid/ ) - { - $AutoLoader::AUTOLOAD = $AUTOLOAD; - goto &AutoLoader::AUTOLOAD; - } - else - { - croak "Your vendor has not defined Botan symbol $constname"; - } - } - no strict 'refs'; - *$AUTOLOAD = sub { $val }; - goto &$AUTOLOAD; -} - - -bootstrap Botan $VERSION; - -# to setup inheritance... - -package Botan::Filter; -use vars qw(@ISA); -@ISA = qw(); - -package Botan::Chain; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Fork; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Hex_Encoder; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Hex_Decoder; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Base64_Decoder; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - -package Botan::Base64_Encoder; -use vars qw(@ISA); -@ISA = qw( Botan::Filter ); - - -package Botan; - -1; -__END__ - -=head1 NAME - -Botan - Perl extension for access to Botan ... - -=head1 SYNOPSIS - - use Botan; - blah blah blah - -=head1 DESCRIPTION - -Blah blah blah. - -=head1 AUTHOR - -Vaclav Ovsik <[email protected]> - -=head1 SEE ALSO - -Bla - -=cut diff --git a/src/contrib/perl-xs/Botan.xs b/src/contrib/perl-xs/Botan.xs deleted file mode 100644 index 375f73830..000000000 --- a/src/contrib/perl-xs/Botan.xs +++ /dev/null @@ -1,821 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" - -#ifdef __cplusplus -} -#endif - -#include <botan/alg_id.h> -#include <botan/asn1_alt_name.h> -#include <botan/asn1_oid.h> -#include <botan/filters.h> -#include <botan/oids.h> -#include <botan/x509cert.h> -#include <botan/x509_ext.h> - - -/* xsubpp converts ':' to '_' in typemap. We create our types without ':' */ - -typedef Botan::ASN1_String Botan__ASN1_String; -typedef Botan::AlgorithmIdentifier Botan__AlgorithmIdentifier; -typedef Botan::AlternativeName Botan__AlternativeName; -typedef Botan::Attribute Botan__Attribute; -typedef Botan::Base64_Decoder Botan__Base64_Decoder; -typedef Botan::Base64_Encoder Botan__Base64_Encoder; -typedef Botan::Chain Botan__Chain; -typedef Botan::Certificate_Extension Botan__Extension; -typedef Botan::Filter Botan__Filter; -typedef Botan::Fork Botan__Fork; -typedef Botan::Hex_Decoder Botan__Hex_Decoder; -typedef Botan::Hex_Encoder Botan__Hex_Encoder; -typedef Botan::OID Botan__OID; -typedef Botan::Pipe Botan__Pipe; -typedef Botan::X509_Certificate Botan__X509_Certificate; -typedef Botan::X509_DN Botan__X509_DN; -typedef Botan::X509_Time Botan__X509_Time; -typedef Botan::u32bit Botan__u32bit; - - -/* Types to keep track of destruction C++ objects passed - * into other objects... - * An Botan object is deleted by his parent object into which is passed, - * e.g. some Filter is deleted when his Pipe is destructed. We must - * track this and not to delete object again in Perls destructor. - */ - -class ObjectInfo -{ -private: - I32 d_signature; - bool d_del; -public: - static I32 const SIGNVAL = 0x696a626f; - ObjectInfo() : d_signature(SIGNVAL), - d_del(true) {}; - ~ObjectInfo() {}; - void set_delete(bool del = true) { d_del = del; }; - void set_delete_no() { set_delete(false); }; - void set_delete_yes() { set_delete(true); }; - bool should_delete() const { return d_del; }; -}; - -/* Constant object in initial state - template */ - -ObjectInfo const oi_init; - - -/*============================================================================*/ - -MODULE = Botan PACKAGE = Botan - -PROTOTYPES: ENABLE - -void -constant(char *name) - CODE: - using namespace Botan; - errno = 0; - switch (name[0]) - { - case 'F': - if ( strEQ(name, "FULL_CHECK") ) - XSRETURN_IV( FULL_CHECK ); // Decoder_Checking enum - break; - case 'I': - if ( strEQ(name, "IGNORE_WS") ) - XSRETURN_IV( IGNORE_WS ); // Decoder_Checking enum - break; - case 'N': - if ( strEQ(name, "NONE") ) - XSRETURN_IV( NONE ); // Decoder_Checking enum - break; - } - errno = EINVAL; - XSRETURN_UNDEF; - - -# =========================== Botan::Chain ========================== - -MODULE = Botan PACKAGE = Botan::Chain - -Botan__Chain * -Botan__Chain::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0) - Botan__Filter *f1; - Botan__Filter *f2; - Botan__Filter *f3; - Botan__Filter *f4; - PREINIT: - ObjectInfo *f1_oi; - ObjectInfo *f2_oi; - ObjectInfo *f3_oi; - ObjectInfo *f4_oi; - CODE: - try { - RETVAL = new Botan__Chain(f1, f2, f3, f4); - if ( f1 ) f1_oi->set_delete_no(); - if ( f2 ) f2_oi->set_delete_no(); - if ( f3 ) f3_oi->set_delete_no(); - if ( f4 ) f4_oi->set_delete_no(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Chain::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# =========================== Botan::Fork ========================== - -MODULE = Botan PACKAGE = Botan::Fork - -Botan__Fork * -Botan__Fork::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0) - Botan__Filter *f1; - Botan__Filter *f2; - Botan__Filter *f3; - Botan__Filter *f4; - PREINIT: - ObjectInfo *f1_oi; - ObjectInfo *f2_oi; - ObjectInfo *f3_oi; - ObjectInfo *f4_oi; - CODE: - try { - RETVAL = new Botan__Fork(f1, f2, f3, f4); - if ( f1 ) f1_oi->set_delete_no(); - if ( f2 ) f2_oi->set_delete_no(); - if ( f3 ) f3_oi->set_delete_no(); - if ( f4 ) f4_oi->set_delete_no(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Fork::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ============================ Botan::Base64_Decoder ============================ - -MODULE = Botan PACKAGE = Botan::Base64_Decoder - -Botan__Base64_Decoder * -Botan__Base64_Decoder::new(checking = Botan::NONE) - int checking; - CODE: - try { - using namespace Botan; - RETVAL = new Base64_Decoder((Decoder_Checking)checking); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Base64_Decoder::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# =========================== Botan::Base64_Encoder ========================== - -MODULE = Botan PACKAGE = Botan::Base64_Encoder - -Botan__Base64_Encoder * -Botan__Base64_Encoder::new(breaks = false, length = 72) - bool breaks; - Botan__u32bit length; - CODE: - try { - RETVAL = new Botan__Base64_Encoder(breaks, length); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Base64_Encoder::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ============================ Botan::Hex_Decoder ============================ - -MODULE = Botan PACKAGE = Botan::Hex_Decoder - -Botan__Hex_Decoder * -Botan__Hex_Decoder::new(checking = Botan::NONE) - int checking; - CODE: - try { - using namespace Botan; - RETVAL = new Hex_Decoder((Decoder_Checking)checking); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Hex_Decoder::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ============================ Botan::Hex_Encoder ============================ - -MODULE = Botan PACKAGE = Botan::Hex_Encoder - -Botan__Hex_Encoder * -Botan__Hex_Encoder::new(breaks = false, length = 72, lcase = false) - bool breaks; - Botan__u32bit length; - bool lcase; - CODE: - try { - using Botan::Hex_Encoder; - RETVAL = new Hex_Encoder(breaks, length, - lcase ? Hex_Encoder::Lowercase : Hex_Encoder::Uppercase); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Hex_Encoder::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - if ( THIS_oi->should_delete() ) - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ================================ Botan::OID ================================ - -MODULE = Botan PACKAGE = Botan::OID - -Botan__OID * -Botan__OID::new(s) - char *s; - CODE: - try { - RETVAL = new Botan__OID(s); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__OID::DESTROY() - CODE: - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - -char * -Botan__OID::as_string() - CODE: - try { - RETVAL = const_cast<char *>(THIS->as_string().c_str()); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - - -# ================================ Botan::OIDS ================================ - -MODULE = Botan PACKAGE = Botan::OIDS - -void -add_oid(oid, name) - Botan__OID *oid; - char *name; - CODE: - try { - Botan::OIDS::add_oid(*oid, name); - } - catch (const std::exception &e) { - croak(e.what()); - } - -char * -lookup_by_oid(oid) - Botan__OID *oid; - CODE: - try { - RETVAL = const_cast<char *>(Botan::OIDS::lookup(*oid).c_str()); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -Botan__OID * -lookup_by_name(name) - char *name; - CODE: - try { - RETVAL = new Botan__OID(Botan::OIDS::lookup(name)); - } - catch (const std::exception &e) { - croak(e.what()); - } - char const * CLASS = "Botan::OID"; - OUTPUT: - RETVAL - -int -have_oid(name) - char *name; - CODE: - try { - RETVAL = Botan::OIDS::have_oid(name); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - - -# ================================ Botan::Pipe ================================ - -MODULE = Botan PACKAGE = Botan::Pipe - -Botan__Pipe * -Botan__Pipe::new(...) - CODE: - for (I32 i = 1; i < items; i++) - { - if ( !sv_isobject(ST(i)) || (SvTYPE(SvRV(ST(i))) != SVt_PVMG) ) - croak("Botan::Pipe::new() -- arg %u is not " - "a blessed SV reference", i +1); - if ( !sv_derived_from(ST(i), "Botan::Filter") ) - croak("Botan::Pipe::new() -- arg %u is not " - "an object derived from Botan::Filter", i +1); - MAGIC *mg = mg_find(SvRV(ST(i)), '~'); - if ( mg == 0 - || mg->mg_len != sizeof(ObjectInfo) - || *(I32 *)(mg->mg_ptr) != ObjectInfo::SIGNVAL ) - croak("Botan::Pipe::new() -- arg %u has no " - "valid private magic data (ObjectInfo)", i +1); - } - try { - RETVAL = new Botan__Pipe(); - for (I32 i = 1; i < items; i++) - { - SV *osv = (SV *)SvRV(ST(i)); - ObjectInfo *oi = (ObjectInfo *)(mg_find(osv, '~')->mg_ptr); - RETVAL->append((Botan__Filter *)(SvIV(osv))); - oi->set_delete_no(); - } - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Pipe::DESTROY() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - -void -Botan__Pipe::write(s) - SV *s; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - STRLEN len; - char *ptr = SvPV(s, len); - try { - THIS->write((unsigned char *)ptr, len); - } - catch (const std::exception &e) { - croak(e.what()); - } - -void -Botan__Pipe::process_msg(s) - SV *s; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - STRLEN len; - char *ptr = SvPV(s, len); - try { - THIS->process_msg((unsigned char *)ptr, len); - } - catch (const std::exception &e) { - croak(e.what()); - } - -Botan__u32bit -Botan__Pipe::remaining(msgno = Botan::Pipe::DEFAULT_MESSAGE) - Botan__u32bit msgno; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - RETVAL = THIS->remaining(msgno); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -SV * -Botan__Pipe::read(len = 0xFFFFFFFF, msgno = Botan::Pipe::DEFAULT_MESSAGE) - Botan__u32bit len; - Botan__u32bit msgno; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - if ( len > THIS->remaining(msgno) ) - len = THIS->remaining(msgno); - RETVAL = NEWSV(0, len); - SvPOK_on(RETVAL); - if ( len > 0 ) - SvCUR_set(RETVAL, THIS->read((unsigned char *)SvPVX(RETVAL), - len, msgno)); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -SV * -Botan__Pipe::peek(len = 0xFFFFFFFF, offset = 0, \ - msgno = Botan::Pipe::DEFAULT_MESSAGE) - Botan__u32bit len; - Botan__u32bit offset; - Botan__u32bit msgno; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - if ( len > THIS->remaining(msgno) ) - len = THIS->remaining(msgno); - RETVAL = NEWSV(0, len); - SvPOK_on(RETVAL); - if ( len > 0 ) - SvCUR_set(RETVAL, THIS->peek((unsigned char *)SvPVX(RETVAL), - len, offset, msgno)); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -Botan__u32bit -Botan__Pipe::default_msg() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - RETVAL = THIS->default_msg(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Pipe::set_default_msg(msgno) - Botan__u32bit msgno; - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - THIS->set_default_msg(msgno); - } - catch (const std::exception &e) { - croak(e.what()); - } - -Botan__u32bit -Botan__Pipe::message_count() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - RETVAL = THIS->message_count(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -bool -Botan__Pipe::end_of_data() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - RETVAL = THIS->end_of_data(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__Pipe::start_msg() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - THIS->start_msg(); - } - catch (const std::exception &e) { - croak(e.what()); - } - -void -Botan__Pipe::end_msg() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - THIS->end_msg(); - } - catch (const std::exception &e) { - croak(e.what()); - } - -void -Botan__Pipe::reset() - PREINIT: - ObjectInfo *THIS_oi; - CODE: - try { - THIS->reset(); - } - catch (const std::exception &e) { - croak(e.what()); - } - - -# ========================== Botan::X509_Certificate ========================== - -MODULE = Botan PACKAGE = Botan::X509_Certificate - -Botan__X509_Certificate * -Botan__X509_Certificate::new(char *fn) - CODE: - try { - RETVAL = new Botan__X509_Certificate(fn); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__X509_Certificate::DESTROY() - CODE: - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - -unsigned int -Botan__X509_Certificate::x509_version() - CODE: - try { - RETVAL = THIS->x509_version(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -char * -Botan__X509_Certificate::start_time() - CODE: - try { - RETVAL = const_cast<char *>(THIS->start_time().c_str()); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -char * -Botan__X509_Certificate::end_time() - CODE: - try { - RETVAL = const_cast<char *>(THIS->end_time().c_str()); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -char * -Botan__X509_Certificate::subject_info(char *info) - CODE: - try { - std::vector<std::string> s = THIS->subject_info(info); - - if(s.size() > 0) - RETVAL = const_cast<char *>(s[0].c_str()); - else - RETVAL = "err"; - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -char * -Botan__X509_Certificate::issuer_info(char *info) - CODE: - try { - std::vector<std::string> s = THIS->subject_info(info); - - if(s.size() > 0) - RETVAL = const_cast<char *>(s[0].c_str()); - else - RETVAL = "err"; - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -Botan__X509_DN * -Botan__X509_Certificate::subject_dn() - CODE: - try { - RETVAL = new Botan__X509_DN(THIS->subject_dn()); - } - catch (const std::exception &e) { - croak(e.what()); - } - char const * CLASS = "Botan::X509_DN"; - OUTPUT: - RETVAL - -Botan__X509_DN * -Botan__X509_Certificate::issuer_dn() - CODE: - try { - RETVAL = new Botan__X509_DN(THIS->issuer_dn()); - } - catch (const std::exception &e) { - croak(e.what()); - } - char const * CLASS = "Botan::X509_DN"; - OUTPUT: - RETVAL - - -# ============================== Botan::X509_DN ============================== - -MODULE = Botan PACKAGE = Botan::X509_DN - -Botan__X509_DN * -Botan__X509_DN::new() - CODE: - try { - RETVAL = new Botan__X509_DN(); - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL - -void -Botan__X509_DN::DESTROY() - CODE: - try { - delete THIS; - } - catch (const std::exception &e) { - croak(e.what()); - } - -AV * -Botan__X509_DN::get_attributes() - CODE: - try { - using namespace std; - using namespace Botan; - - typedef multimap<OID, string>::const_iterator rdn_iter; - - multimap<OID, string> const &atrmmap = THIS->get_attributes(); - RETVAL = newAV(); - for(rdn_iter i = atrmmap.begin(); i != atrmmap.end(); i++) - { - string const &atr = i->first.as_string(); - string const &val = i->second; - av_push(RETVAL, newSVpvn(atr.c_str(), atr.length())); - av_push(RETVAL, newSVpvn(val.c_str(), val.length())); - } - } - catch (const std::exception &e) { - croak(e.what()); - } - OUTPUT: - RETVAL diff --git a/src/contrib/perl-xs/Changes b/src/contrib/perl-xs/Changes deleted file mode 100644 index 5f32b0c63..000000000 --- a/src/contrib/perl-xs/Changes +++ /dev/null @@ -1,4 +0,0 @@ -Revision history for Perl extension to Botan. - -0.01 Fri, 20 Feb 2004 15:10:50 +0100 - - first version diff --git a/src/contrib/perl-xs/MANIFEST b/src/contrib/perl-xs/MANIFEST deleted file mode 100644 index b9d8454d6..000000000 --- a/src/contrib/perl-xs/MANIFEST +++ /dev/null @@ -1,15 +0,0 @@ -Botan.pm -Botan.xs -Changes -MANIFEST -Makefile.PL -data/ca.cert.der -data/ca.cert.pem -t/base64.t -t/filt.t -t/hex.t -t/oid.t -t/pipe.t -t/testutl.pl -t/x509cert.t -typemap diff --git a/src/contrib/perl-xs/Makefile.PL b/src/contrib/perl-xs/Makefile.PL deleted file mode 100644 index ab28bff1f..000000000 --- a/src/contrib/perl-xs/Makefile.PL +++ /dev/null @@ -1,29 +0,0 @@ -use ExtUtils::MakeMaker; - -my ($cc, $cflags, $lids); -if ( $^O eq 'MSWin32' ) -{ -# $cflags = ''; -# $libs = ':nosearch -lgdi32 -llibeay32'; -} -else -{ - $cc = 'g++'; - $cflags = $Config::Config{ccflags} . ' -Wno-write-strings -fexceptions ' . qx( botan config --cflags ); - $libs = qx( botan config --libs ); -} - -WriteMakefile( - 'NAME' => 'Botan', - 'DISTNAME' => 'Botan-XS', - 'VERSION_FROM' => 'Botan.pm', # finds $VERSION - 'XSOPT' => '-C++', - 'CC' => $cc, - 'LD' => '$(CC)', - 'CCFLAGS' => $cflags, - 'LIBS' => [ $libs ], - 'OPTIMIZE' => '-g', -# 'clean' => { -# 'FILES' => 'neco.p12 rnd', -# }, -); diff --git a/src/contrib/perl-xs/data/ca.cert.der b/src/contrib/perl-xs/data/ca.cert.der Binary files differdeleted file mode 100644 index d6ed8aeaf..000000000 --- a/src/contrib/perl-xs/data/ca.cert.der +++ /dev/null diff --git a/src/contrib/perl-xs/data/ca.cert.pem b/src/contrib/perl-xs/data/ca.cert.pem deleted file mode 100644 index 012913b26..000000000 --- a/src/contrib/perl-xs/data/ca.cert.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICxDCCAi2gAwIBAgIBEjANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJDWjER -MA8GA1UEChMISUNaIGEucy4xGDAWBgNVBAMTD1Rlc3QgcHJpbWFyeSBDQTEWMBQG -CSqGSIb3DQEJARYHY2FAaS5jejAeFw0wMDA4MjAyMTQ4MDBaFw0wMjA4MTAyMTQ4 -MDBaME8xCzAJBgNVBAYTAkNaMREwDwYDVQQKEwhJQ1ogYS5zLjEVMBMGA1UEAxMM -VGVzdCBzaWduIENBMRYwFAYJKoZIhvcNAQkBFgdjYUBpLmN6MIGfMA0GCSqGSIb3 -DQEBAQUAA4GNADCBiQKBgQCo2GReNqwU0/8bZZua5hgYaVHvD9QAmfILNXD25jRk -C8lqe5m/GzbmftSUso5HyUy1t+qzvRDTmxK8uRn0P00Mqj9gjwF8PGQvZE/FrDF7 -rta9GCcH4n2GfQ0iexlhRZW44AfOD4HCgq38Z0bzBclsvUslBWe1AT+S5+chZ5Wb -UwIDAQABo4GsMIGpMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLXqc1b1DOfGehii -k4Z+/ih9BYZmMHoGA1UdIwRzMHGAFL7x2ToS4RDAbDJu4fHnzzGjfGmgoVakVDBS -MQswCQYDVQQGEwJDWjERMA8GA1UEChMISUNaIGEucy4xGDAWBgNVBAMTD1Rlc3Qg -cHJpbWFyeSBDQTEWMBQGCSqGSIb3DQEJARYHY2FAaS5jeoIBADANBgkqhkiG9w0B -AQUFAAOBgQAKD9ku9kKXUGhSw8KuWJXTnEsIUzDtgmREBEUOtEvGfU45vogWN7ZL -9fQZ1deywN4RJ4T5ZTTcCTPodOdG+IXLJ+uPn/m9iQ/D86c3GKS3yx4JNAn5PH1m -qLsMYVjbFD2uREZQsqbg3RT6L1D8+oK0pN379u3bD6oJx/qa7+F4Jg== ------END CERTIFICATE----- diff --git a/src/contrib/perl-xs/t/base64.t b/src/contrib/perl-xs/t/base64.t deleted file mode 100644 index f0973e13e..000000000 --- a/src/contrib/perl-xs/t/base64.t +++ /dev/null @@ -1,273 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..24\n"; } -END { print "not ok 1\n" unless $loaded; } - -require 't/testutl.pl'; -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -# Data prep - -my $botan_lic_b64_garbage = <<'EOF'; -Q29weXJpZ2h0IChDKSAxOTk5LTIwMDQgVGhlIEJvdGFuIFByb2plY3QuIEFsbCBy__� -aWdodHMgcmVzZXJ2ZWQuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJj$$*: -ZSBhbmQgYmluYXJ5IGZvcm1zLCBmb3IgYW55IHVzZSwgd2l0aCBvciB3aXRob3V0!@#$%^&*( -Cm1vZGlmaWNhdGlvbiwgaXMgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZv[\] -bGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMg'~` -b2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBu() -b3RpY2UsIHRoaXMKbGlzdCBvZiBjb25kaXRpb25zLCBhbmQgdGhlIGZvbGxvd2lu -ZyBkaXNjbGFpbWVyLgoKMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3Jt -IG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAp0aGlz -IGxpc3Qgb2YgY29uZGl0aW9ucywgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1l -ciBpbiB0aGUgZG9jdW1lbnRhdGlvbgphbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHBy_,^ -b3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KClRISVMgU09GVFdBUkUgSVMg{|}~~~~~ -UFJPVklERUQgQlkgVEhFIEFVVEhPUihTKSAiQVMgSVMiIEFORCBBTlkgRVhQUkVT~~~~~~~~ -UyBPUiBJTVBMSUVECldBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1J__:; -VEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GCk1FUkNIQU5UQUJJTElU -WSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsIEFSRSBESVND -TEFJTUVELgoKSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUihTKSBPUiBDT05U -UklCVVRPUihTKSBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsCklORElSRUNULCBJ -TkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwg -REFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVN -RU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNF -LApEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhP -V0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GCkxJQUJJTElUWSwgV0hF -VEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5D -TFVESU5HIE5FR0xJR0VOQ0UKT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBX -QVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRgpBRFZJ -U0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4K -EOF - -my $botan_lic_b64_ws = $botan_lic_b64_garbage; -$botan_lic_b64_ws =~ s/[^A-Za-z0-9+\/= \n]//g; - -my $botan_lic_b64 = $botan_lic_b64_ws; -$botan_lic_b64 =~ s/[ \n]//g; - - -my $botan_lic = <<'EOF'; -Copyright (C) 1999-2004 The Botan Project. All rights reserved. - -Redistribution and use in source and binary forms, for any use, with or without -modification, is permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this -list of conditions, and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions, and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. - -IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -EOF - - -# Decoder... - -my $f; - -eval { $f = Botan::Base64_Decoder->new(&Botan::NONE); }; -print "not " if $@ || !defined $f; -print "ok 2\n"; - -my $dec; -eval { $dec = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec; -print "ok 3\n"; - -eval { $f = Botan::Base64_Decoder->new(&Botan::IGNORE_WS); }; -print "not " if $@ || !defined $f; -print "ok 4\n"; - -my $dec_is; -eval { $dec_is = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec_is; -print "ok 5\n"; - -eval { $f = Botan::Base64_Decoder->new(&Botan::FULL_CHECK); }; -print "not " if $@ || !defined $f; -print "ok 6\n"; - -my $dec_fc; -eval { $dec_fc = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec_fc; -print "ok 7\n"; - - -# Testing clean base64 input - -my $data; - -undef $data; -eval { - $dec->process_msg($botan_lic_b64); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 8\n"; - -undef $data; -eval { - $dec_is->process_msg($botan_lic_b64); - $data = $dec_is->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 9\n"; - -undef $data; -eval { - $dec_fc->process_msg($botan_lic_b64); - $data = $dec_fc->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 10\n"; - - -# Testing base64 input with whitespaces - -undef $data; -eval { - $dec->process_msg($botan_lic_b64_ws); - $dec->set_default_msg(1); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 11\n"; - -undef $data; -eval { - $dec_is->process_msg($botan_lic_b64_ws); - $dec_is->set_default_msg(1); - $data = $dec_is->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 12\n"; - -undef $data; -eval { - $dec_fc->process_msg($botan_lic_b64_ws); - $dec_fc->set_default_msg(1); - $data = $dec_fc->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 13\n"; - - -# Testing base64 input with garbage - -undef $data; -eval { - $dec->process_msg($botan_lic_b64_garbage); - $dec->set_default_msg(2); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $botan_lic; -print "ok 14\n"; - -undef $data; -eval { - $dec_is->process_msg($botan_lic_b64_garbage); - $dec_is->set_default_msg(2); - $data = $dec_is->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 15\n"; - -undef $data; -eval { - $dec_fc->process_msg($botan_lic_b64_garbage); - $dec_fc->set_default_msg(2); - $data = $dec_fc->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 16\n"; - - -# Encoder... - -eval { $f = Botan::Base64_Encoder->new(); }; -print "not " if $@ || !defined $f; -print "ok 17\n"; - -my $enc; -eval { $enc = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $enc; -print "ok 18\n"; - -eval { $f = Botan::Base64_Encoder->new(1, 5); }; -print "not " if $@ || !defined $f; -print "ok 19\n"; - -my $enc2; -eval { $enc2 = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $enc2; -print "ok 20\n"; - -undef $data; -eval { - $enc->process_msg("Hello\n"); - $data = $enc->read(); -}; -print "not " if $@ || $data ne "SGVsbG8K"; -print "ok 21\n"; - -undef $data; -eval { - $enc2->process_msg("Hello\n"); - $data = $enc2->read(); -}; -print "not " if $@ || $data ne "SGVsb\nG8K\n"; -print "ok 22\n"; - - -# Encoder with decoder... - -my $p; -eval { - $p = Botan::Pipe->new( - Botan::Base64_Encoder->new(), - Botan::Base64_Decoder->new(), - ); -}; -print "not " if $@ || !defined $p; -print "ok 23\n"; - -print "not " unless random_message_ok($p); -print "ok 24\n"; diff --git a/src/contrib/perl-xs/t/filt.t b/src/contrib/perl-xs/t/filt.t deleted file mode 100644 index 2a7b4c8ba..000000000 --- a/src/contrib/perl-xs/t/filt.t +++ /dev/null @@ -1,56 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..5\n"; } -END { print "not ok 1\n" unless $loaded; } - -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -my $pipe = Botan::Pipe->new(Botan::Hex_Encoder->new()); - -print "not " unless $pipe; -print "ok 2\n"; - -$pipe->process_msg('FOO'); - -print "not " if $pipe->read() ne '464F4F'; -print "ok 3\n"; - -$pipe = Botan::Pipe->new(Botan::Hex_Encoder->new(0, 0, 1)); - -print "not " unless $pipe; -print "ok 4\n"; - -$pipe->process_msg('FOO'); - -print "not " if $pipe->read() ne '464f4f'; -print "ok 5\n"; - - - - - - -#my $pipe = Botan::Pipe->new(Botan::Base64_Encoder->new()); -#$pipe->process_msg('FOO'); -# -#print "not " if $pipe->read() ne 'Rk9P'; -#print "ok 4\n"; - diff --git a/src/contrib/perl-xs/t/hex.t b/src/contrib/perl-xs/t/hex.t deleted file mode 100644 index 6f447b25c..000000000 --- a/src/contrib/perl-xs/t/hex.t +++ /dev/null @@ -1,256 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..24\n"; } -END { print "not ok 1\n" unless $loaded; } - -require 't/testutl.pl'; -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -# Data prep - -my ($hex, $hex_ws, $hex_garbage); -while ( $_ = <DATA> ) -{ - $hex_garbage .= $_; - s/[^[:xdigit:][:space:]]//g; - $hex_ws .= $_; - s/[^[:xdigit:]]//g; - $hex .= $_; -} -my $data_test = pack("H*", $hex); - -# Decoder... - -my $f; - -eval { $f = Botan::Hex_Decoder->new(&Botan::NONE); }; -print "not " if $@ || !defined $f; -print "ok 2\n"; - -my $dec; -eval { $dec = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec; -print "ok 3\n"; - -eval { $f = Botan::Hex_Decoder->new(&Botan::IGNORE_WS); }; -print "not " if $@ || !defined $f; -print "ok 4\n"; - -my $dec_is; -eval { $dec_is = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec_is; -print "ok 5\n"; - -eval { $f = Botan::Hex_Decoder->new(&Botan::FULL_CHECK); }; -print "not " if $@ || !defined $f; -print "ok 6\n"; - -my $dec_fc; -eval { $dec_fc = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $dec_fc; -print "ok 7\n"; - - -# Testing clean hexadecimal input - -my $data; - -undef $data; -eval { - $dec->process_msg($hex); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 8\n"; - -undef $data; -eval { - $dec_is->process_msg($hex); - $data = $dec_is->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 9\n"; - -undef $data; -eval { - $dec_fc->process_msg($hex); - $data = $dec_fc->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 10\n"; - - -# Testing hexadecimal input with whitespaces - -undef $data; -eval { - $dec->process_msg($hex_ws); - $dec->set_default_msg(1); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 11\n"; - -undef $data; -eval { - $dec_is->process_msg($hex_ws); - $dec_is->set_default_msg(1); - $data = $dec_is->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 12\n"; - -undef $data; -eval { - $dec_fc->process_msg($hex_ws); - $dec_fc->set_default_msg(1); - $data = $dec_fc->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 13\n"; - - -# Testing hexadecimal input with garbage - -undef $data; -eval { - $dec->process_msg($hex_garbage); - $dec->set_default_msg(2); - $data = $dec->read(); -}; - -print "not " if $@ || $data ne $data_test; -print "ok 14\n"; - -undef $data; -eval { - $dec_is->process_msg($hex_garbage); - $dec_is->set_default_msg(2); - $data = $dec_is->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 15\n"; - -undef $data; -eval { - $dec_fc->process_msg($hex_garbage); - $dec_fc->set_default_msg(2); - $data = $dec_fc->read(); -}; - -print "not " unless $@ && !defined $data; -print "ok 16\n"; - - -# Encoder... - -eval { $f = Botan::Hex_Encoder->new(); }; -print "not " if $@ || !defined $f; -print "ok 17\n"; - -my $enc; -eval { $enc = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $enc; -print "ok 18\n"; - -eval { $f = Botan::Hex_Encoder->new(1, 5, 1); }; -print "not " if $@ || !defined $f; -print "ok 19\n"; - -my $enc2; -eval { $enc2 = Botan::Pipe->new($f); }; -print "not " if $@ || !defined $enc2; -print "ok 20\n"; - -undef $data; -eval { - $enc->process_msg("Hello\n"); - $data = $enc->read(); -}; -print "not " if $@ || $data ne "48656C6C6F0A"; -print "ok 21\n"; - -undef $data; -eval { - $enc2->process_msg("Hello\n"); - $data = $enc2->read(); -}; -print "not " if $@ || $data ne "48656\nc6c6f\n0a\n"; -print "ok 22\n"; - - -# Encoder with decoder... - -my $p; -eval { - $p = Botan::Pipe->new( - Botan::Hex_Encoder->new(), - Botan::Hex_Decoder->new(), - ); -}; -print "not " if $@ || !defined $p; -print "ok 23\n"; - -print "not " unless random_message_ok($p); -print "ok 24\n"; - - - -__DATA__ -cb13 4a4d 7522 1fd3 c6f6 7786 d04b 3043 ..JMu"....w..K.. -4552 4bcf 4d2b 9d71 0cfe 4d6a 1caf bcfd .RK.M+.q..Mj.... -8f91 6151 ff85 e900 7e6a bafc 15e9 ae51 ...Q....~j.....Q -b14b 7210 bb40 5958 2b82 d49e b808 68a5 .Kr..@YX+.....h. -7945 9dec f686 9b98 989e 826d 8088 6ee7 y..........m..n. -d066 1eac 8c34 c461 bb54 7726 87ab d681 .........Tw&.... -a0be 52e5 1128 0cf2 759e cb2d e690 4ed9 ..R..(..u..-..N. -7e88 bda7 2523 4a0f 185a 02b1 f898 fc41 ~...%#J..Z...... -dd48 fa87 945d 7611 b8c9 a50a 2de2 b670 .H...]v.....-..p -0056 c8be 2cbb e7d0 1e70 4a3d 79f0 dce9 .V..,....pJ=y... -b57f 154b 2b3a db73 f086 de11 9f3e 1641 ...K+:.s.....>.. -3a28 8b9b bb0f 682b 80db b791 89e0 62c0 :(....h+........ -7204 db97 5432 2eb0 a04e f38e 809f 7223 r...T....N....r# -912e e552 1452 6dd2 e09f dd06 c715 7c1a ...R.Rm.......|. -fe3d d6cc b6d0 a17a 27d7 4327 4e43 8af3 .=.....z'..'N... -6eb5 e9f8 bfe9 34c3 6636 8243 358f 966d n..............m -7d87 d17b 5c37 6acb 4972 f4ec 6806 bbde }..{\.j.Ir..h... -2689 a019 a9e2 4101 7fe2 de72 bc03 eb5e &..........r...^ -b699 2d6b f8cd a08e 6e01 edfc a81a 94b6 ..-k....n....... -9073 15fb efb2 c8d9 9f85 6633 85f1 e9d0 .s.............. -20ce 578b ab9d 2e51 b947 69bf fba5 82c6 .W....Q.Gi..... -2ed0 dd36 d679 a399 7db3 8a0d cdef 0eda .....y..}....... -e761 e7f1 5b17 3f67 0c83 215a eddf 9d2a ....[.?g..!Z...* -5e70 0a77 c92e 94e1 a82b fd7c f10a 894f ^p.w.....+.|...O -2955 f0e8 7398 f409 2040 b797 da03 a5a6 )U..s... @...... -7ba4 c3c9 2659 b9f7 6a56 e17a b481 983f {...&Y..jV.z...? -00ed 3cc8 5a22 ad5c b6e0 3566 d717 35a6 ..<.Z".\........ -1523 4104 de63 477e fd24 68e5 e816 98df .#....G~.$h..... -1747 417e db72 a76a be5b b9dc 3dfb 2d05 .G.~.r.j.[..=.-. -d27f e597 eafc 9a29 15c5 792d 9c88 9aea .......)..y-.... -485e e431 96c3 7723 da6d 28b2 477a fd12 H^....w#.m(.Gz.. -e645 5dcd 7d5a d8b4 7acc 10b2 b41a e11d ..].}Z..z....... diff --git a/src/contrib/perl-xs/t/oid.t b/src/contrib/perl-xs/t/oid.t deleted file mode 100644 index 66204541f..000000000 --- a/src/contrib/perl-xs/t/oid.t +++ /dev/null @@ -1,45 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..6\n"; } -END { print "not ok 1\n" unless $loaded; } - -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -print "not " unless Botan::OIDS::have_oid('X520.CommonName'); -print "ok 2\n"; - -my $oid_c = Botan::OID->new('2.5.4.3'); -print "not " if Botan::OIDS::lookup_by_oid($oid_c) ne 'X520.CommonName'; -print "ok 3\n"; - -my $oid_x = Botan::OIDS::lookup_by_name('X520.CommonName'); -print "not " if $oid_x->as_string() ne '2.5.4.3'; -print "ok 4\n"; - -my $oid_foo_num = '1.2.3.4.5.6.7.8.9.10.11.12.13.14.15'; -my $oid_foo = Botan::OID->new($oid_foo_num); -print "not " if Botan::OIDS::lookup_by_oid($oid_foo) ne $oid_foo_num; -print "ok 5\n"; - -Botan::OIDS::add_oid($oid_foo, 'Zito.Foo'); - -print "not " if Botan::OIDS::lookup_by_oid($oid_foo) ne 'Zito.Foo'; -print "ok 6\n"; diff --git a/src/contrib/perl-xs/t/pipe.t b/src/contrib/perl-xs/t/pipe.t deleted file mode 100644 index f850d8519..000000000 --- a/src/contrib/perl-xs/t/pipe.t +++ /dev/null @@ -1,98 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..20\n"; } -END { print "not ok 1\n" unless $loaded; } - -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -my $pipe = Botan::Pipe->new(); - -print "not " unless $pipe; -print "ok 2\n"; - -$pipe->start_msg(); -$pipe->write('Hello world'); -$pipe->end_msg(); - -print "not " if $pipe->message_count() != 1; -print "ok 3\n"; - -print "not " if $pipe->remaining() != 11; -print "ok 4\n"; - -print "not " if $pipe->end_of_data(); -print "ok 5\n"; - -print "not " if $pipe->read() ne 'Hello world'; -print "ok 6\n"; - -print "not " if $pipe->remaining() != 0; -print "ok 7\n"; - -print "not " unless $pipe->end_of_data(); -print "ok 8\n"; - -$pipe->process_msg('Hello world'); - -print "not " if $pipe->message_count() != 2; -print "ok 9\n"; - -my $msg_num = $pipe->message_count() -1; - -print "not " if $pipe->read(5, $msg_num) ne 'Hello'; -print "ok 10\n"; - -print "not " if $pipe->read(6, $msg_num) ne ' world'; -print "ok 11\n"; - -print "not " if $pipe->remaining() != 0; -print "ok 12\n"; - -print "not " unless $pipe->end_of_data(); -print "ok 13\n"; - -$pipe->process_msg("The\0string\0with\0null\0chars\0"); -$msg_num = $pipe->message_count() -1; - -print "not " if $pipe->read(80, $msg_num) ne "The\0string\0with\0null\0chars\0"; -print "ok 14\n"; - -$pipe->process_msg('FOO BAR'); -$pipe->set_default_msg($pipe->message_count() -1); - -print "not " if $pipe->peek(3) ne 'FOO'; -print "ok 15\n"; - -print "not " if $pipe->peek(3, 4) ne 'BAR'; -print "ok 16\n"; - -print "not " if $pipe->peek() ne 'FOO BAR'; -print "ok 17\n"; - -print "not " if $pipe->read() ne 'FOO BAR'; -print "ok 18\n"; - -print "not " if $pipe->remaining() != 0; -print "ok 19\n"; - -print "not " unless $pipe->end_of_data(); -print "ok 20\n"; - diff --git a/src/contrib/perl-xs/t/testutl.pl b/src/contrib/perl-xs/t/testutl.pl deleted file mode 100644 index add6f6a45..000000000 --- a/src/contrib/perl-xs/t/testutl.pl +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/perl - -sub random_message_ok -{ - my ($pipe, $iter, $chunkmax) = @_; - $iter = 100 unless defined $iter; - $chunkmax = 300 unless defined $chunkmax; - eval { - my $input = ''; - $pipe->start_msg(); - for(my $i = 0; $i < $iter; $i++) - { - my $chunk = ''; - my $chunklen = int(rand($chunkmax)); - $chunk .= pack("C", int(rand(256))) while $chunklen--; - $input .= $chunk; - $pipe->write($chunk); - } - $pipe->end_msg(); - my $msg_num = $pipe->message_count() -1; - my $output = $pipe->read(0xFFFFFFFF, $msg_num); - return $input eq $output; - }; -} - -1; diff --git a/src/contrib/perl-xs/t/x509cert.t b/src/contrib/perl-xs/t/x509cert.t deleted file mode 100644 index 2a943aeac..000000000 --- a/src/contrib/perl-xs/t/x509cert.t +++ /dev/null @@ -1,42 +0,0 @@ -# vim: set ft=perl: -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..4\n"; } -END { print "not ok 1\n" unless $loaded; } - -use Botan; - -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - -use strict; - -my $cert = Botan::X509_Certificate->new('data/ca.cert.der'); - -print "not " if $cert->x509_version() != 3; -print "ok 2\n"; - -print "not " if $cert->start_time() ne '2000/8/20 21:48:00 UTC'; -print "ok 3\n"; - -print "not " if $cert->end_time() ne '2002/8/10 21:48:00 UTC'; -print "ok 4\n"; - -#my $subject = $cert->subject_dn()->get_attributes(); -#print STDERR "subject=", join(',', @{$subject}), "\n"; -# -#my $issuer = $cert->issuer_dn()->get_attributes(); -#print STDERR "issuer=", join(',', @{$issuer}), "\n"; -# diff --git a/src/contrib/perl-xs/typemap b/src/contrib/perl-xs/typemap deleted file mode 100644 index d7403d40d..000000000 --- a/src/contrib/perl-xs/typemap +++ /dev/null @@ -1,62 +0,0 @@ -TYPEMAP - -Botan__ASN1_String * O_OBJECT -Botan__AlgorithmIdentifier * O_OBJECT -Botan__AlternativeName * O_OBJECT -Botan__Attribute * O_OBJECT -Botan__Base64_Decoder * O_EXTOBJECT -Botan__Base64_Encoder * O_EXTOBJECT -Botan__Chain * O_EXTOBJECT -Botan__Extension * O_OBJECT -Botan__Filter * O_EXTOBJECT -Botan__Fork * O_EXTOBJECT -Botan__Hex_Decoder * O_EXTOBJECT -Botan__Hex_Encoder * O_EXTOBJECT -Botan__OID * O_OBJECT -Botan__Pipe * O_OBJECT -Botan__X509_Certificate * O_OBJECT -Botan__X509_DN * O_OBJECT -Botan__X509_Time * O_OBJECT -Botan__u32bit T_UV - - -###################################################################### -OUTPUT - -# The Perl object is blessed into 'CLASS', which should be a -# char* having the name of the package for the blessing. -O_OBJECT - sv_setref_pv($arg, CLASS, (void*)$var); - -O_EXTOBJECT - sv_setref_pv($arg, CLASS, (void*)$var); - sv_magic(SvRV($arg), 0, '~', (char *)&oi_init, sizeof(oi_init)); - - -###################################################################### -INPUT - -O_OBJECT - if ( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) - $var = ($type)SvIV((SV*)SvRV( $arg )); - else - croak(\"${Package}::$func_name() -- \" - \"$var is not a blessed SV reference\"); - -# The pointer variable "ObjectInfo *${var}_oi;" must be declared -# in PREINIT section. I don't know how to emit this declaration safely here. -O_EXTOBJECT - if ( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) - $var = ($type)SvIV((SV*)SvRV($arg)); - else - croak(\"${Package}::$func_name() -- \" - \"$var is not a blessed SV reference\"); - { - MAGIC *mg = mg_find(SvRV($arg), '~'); - if ( mg == 0 - || mg->mg_len != sizeof(ObjectInfo) - || *(I32 *)(mg->mg_ptr) != ObjectInfo::SIGNVAL ) - croak(\"${Package}::$func_name() -- \" - \"private magic data for $var invalid\"); - ${var}_oi = (ObjectInfo *)(mg->mg_ptr); - } diff --git a/src/contrib/sqlite/codec.cpp b/src/contrib/sqlite/codec.cpp deleted file mode 100644 index 4a13d3dde..000000000 --- a/src/contrib/sqlite/codec.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Codec class for SQLite3 encryption codec. - * (C) 2010 Olivier de Gaalon - * - * Botan is released under the Simplified BSD License (see license.txt) - */ - -#include "codec.h" - -Codec::Codec(void *db) -{ - InitializeCodec(db); -} - -Codec::Codec(const Codec *other, void *db) -{ - //Only used to copy main db key for an attached db - InitializeCodec(db); - m_hasReadKey = other->m_hasReadKey; - m_hasWriteKey = other->m_hasWriteKey; - m_readKey = other->m_readKey; - m_ivReadKey = other->m_ivReadKey; - m_writeKey = other->m_writeKey; - m_ivWriteKey = other->m_ivWriteKey; -} - -void Codec::InitializeCodec(void *db) -{ - m_hasReadKey = false; - m_hasWriteKey = false; - m_db = db; - - try - { - m_encipherFilter = get_cipher(BLOCK_CIPHER_STR, ENCRYPTION); - m_decipherFilter = get_cipher(BLOCK_CIPHER_STR, DECRYPTION); - m_cmac = new MAC_Filter(MAC_STR); - m_encipherPipe.append(m_encipherFilter); - m_decipherPipe.append(m_decipherFilter); - m_macPipe.append(m_cmac); - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } -} - -void Codec::GenerateWriteKey(const char *userPassword, int passwordLength) -{ - try - { -#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,4) - PBKDF *pbkdf = get_pbkdf(PBKDF_STR); - SymmetricKey masterKey = - pbkdf->derive_key(KEY_SIZE + IV_DERIVATION_KEY_SIZE, std::string(userPassword, passwordLength), - (const byte*)SALT_STR.c_str(), SALT_SIZE, PBKDF_ITERATIONS); -#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0) - S2K* s2k = get_s2k(PBKDF_STR); - s2k->set_iterations(PBKDF_ITERATIONS); - s2k->change_salt((const byte*)SALT_STR.c_str(), SALT_SIZE); - - SymmetricKey masterKey = - s2k->derive_key(KEY_SIZE + IV_DERIVATION_KEY_SIZE, std::string(userPassword, passwordLength)); -#else -#error "This code requires botan 1.8 or newer" -#endif - m_writeKey = SymmetricKey(masterKey.bits_of(), KEY_SIZE); - m_ivWriteKey = SymmetricKey(masterKey.bits_of() + KEY_SIZE, IV_DERIVATION_KEY_SIZE); - - m_hasWriteKey = true; - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } -} - -void Codec::DropWriteKey() -{ - m_hasWriteKey = false; -} - -void Codec::SetReadIsWrite() -{ - m_readKey = m_writeKey; - m_ivReadKey = m_ivWriteKey; - m_hasReadKey = m_hasWriteKey; -} - -void Codec::SetWriteIsRead() -{ - m_writeKey = m_readKey; - m_ivWriteKey = m_ivReadKey; - m_hasWriteKey = m_hasReadKey; -} - -unsigned char* Codec::Encrypt(int page, unsigned char *data, bool useWriteKey) -{ - memcpy(m_page, data, m_pageSize); - - try - { - m_encipherFilter->set_key(useWriteKey ? m_writeKey : m_readKey); - m_encipherFilter->set_iv(GetIVForPage(page, useWriteKey)); - m_encipherPipe.process_msg(m_page, m_pageSize); - m_encipherPipe.read(m_page, m_encipherPipe.remaining(Pipe::LAST_MESSAGE), Pipe::LAST_MESSAGE); - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } - - return m_page; //return location of newly ciphered data -} - -void Codec::Decrypt(int page, unsigned char *data) -{ - try - { - m_decipherFilter->set_key(m_readKey); - m_decipherFilter->set_iv(GetIVForPage(page, false)); - m_decipherPipe.process_msg(data, m_pageSize); - m_decipherPipe.read(data, m_decipherPipe.remaining(Pipe::LAST_MESSAGE), Pipe::LAST_MESSAGE); - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } -} - -InitializationVector Codec::GetIVForPage(u32bit page, bool useWriteKey) -{ - try - { - static unsigned char *intiv[4]; - store_le(page, (byte*)intiv); - m_cmac->set_key(useWriteKey ? m_ivWriteKey : m_ivReadKey); - m_macPipe.process_msg((byte*)intiv, 4); - return m_macPipe.read_all(Pipe::LAST_MESSAGE); - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } -} - -const char* Codec::GetAndResetError() -{ - const char *message = m_botanErrorMsg; - m_botanErrorMsg = 0; - return message; -} - -#include "codec_c_interface.h" - -void InitializeBotan() { -} -void* InitializeNewCodec(void *db) { - return new Codec(db); -} -void* InitializeFromOtherCodec(const void *otherCodec, void *db) { - return new Codec((Codec*)otherCodec, db); -} -void GenerateWriteKey(void *codec, const char *userPassword, int passwordLength) { - ((Codec*)codec)->GenerateWriteKey(userPassword, passwordLength); -} -void DropWriteKey(void *codec) { - ((Codec*)codec)->DropWriteKey(); -} -void SetWriteIsRead(void *codec) { - ((Codec*)codec)->SetWriteIsRead(); -} -void SetReadIsWrite(void *codec) { - ((Codec*)codec)->SetReadIsWrite(); -} -unsigned char* Encrypt(void *codec, int page, unsigned char *data, Bool useWriteKey) { - return ((Codec*)codec)->Encrypt(page, data, useWriteKey); -} -void Decrypt(void *codec, int page, unsigned char *data) { - ((Codec*)codec)->Decrypt(page, data); -} -void SetPageSize(void *codec, int pageSize) { - ((Codec*)codec)->SetPageSize(pageSize); -} -Bool HasReadKey(void *codec) { - return ((Codec*)codec)->HasReadKey(); -} -Bool HasWriteKey(void *codec) { - return ((Codec*)codec)->HasWriteKey(); -} -void* GetDB(void *codec) { - return ((Codec*)codec)->GetDB(); -} -const char* GetAndResetError(void *codec) -{ - return ((Codec*)codec)->GetAndResetError(); -} -void DeleteCodec(void *codec) { - Codec *deleteThisCodec = (Codec*)codec; - delete deleteThisCodec; -} diff --git a/src/contrib/sqlite/codec.h b/src/contrib/sqlite/codec.h deleted file mode 100644 index 673de2480..000000000 --- a/src/contrib/sqlite/codec.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Codec class for SQLite3 encryption codec. - * (C) 2010 Olivier de Gaalon - * - * Botan is released under the Simplified BSD License (see license.txt) - */ - -#ifndef _CODEC_H_ -#define _CODEC_H_ - -#include <string> -#include <botan/botan.h> -#include <botan/loadstor.h> - -using namespace std; -using namespace Botan; - -/*These constants can be used to tweak the codec behavior as follows - *Note that once you've encrypted a database with these settings, - *recompiling with any different settings will give you a library that - *cannot read that database, even given the same passphrase.*/ - -//BLOCK_CIPHER_STR: Cipher and mode used for encrypting the database -//make sure to add "/NoPadding" for modes that use padding schemes -const string BLOCK_CIPHER_STR = "Twofish/XTS"; - -//PBKDF_STR: Key derivation function used to derive both the encryption -//and IV derivation keys from the given database passphrase -const string PBKDF_STR = "PBKDF2(SHA-160)"; - -//SALT_STR: Hard coded salt used to derive the key from the passphrase. -const string SALT_STR = "&g#nB'9]"; - -//SALT_SIZE: Size of the salt in bytes (as given in SALT_STR) -const int SALT_SIZE = 64/8; //64 bit, 8 byte salt - -//MAC_STR: CMAC used to derive the IV that is used for db page -//encryption -const string MAC_STR = "CMAC(Twofish)"; - -//PBKDF_ITERATIONS: Number of hash iterations used in the key derivation -//process. -const int PBKDF_ITERATIONS = 10000; - -//KEY_SIZE: Size of the encryption key. Note that XTS splits the key -//between two ciphers, so if you're using XTS, double the intended key -//size. (ie, "AES-128/XTS" should have a 256 bit KEY_SIZE) -const int KEY_SIZE = 512/8; //512 bit, 64 byte key. (256 bit XTS key) - -//IV_DERIVATION_KEY_SIZE: Size of the key used with the CMAC (MAC_STR) -//above. -const int IV_DERIVATION_KEY_SIZE = 256/8; //256 bit, 32 byte key - -//This is definited in sqlite.h and very unlikely to change -#define SQLITE_MAX_PAGE_SIZE 32768 - -class Codec -{ -public: - Codec(void *db); - Codec(const Codec* other, void *db); - - void GenerateWriteKey(const char *userPassword, int passwordLength); - void DropWriteKey(); - void SetWriteIsRead(); - void SetReadIsWrite(); - - unsigned char* Encrypt(int page, unsigned char *data, bool useWriteKey); - void Decrypt(int page, unsigned char *data); - - void SetPageSize(int pageSize) { m_pageSize = pageSize; } - - bool HasReadKey() { return m_hasReadKey; } - bool HasWriteKey() { return m_hasWriteKey; } - void* GetDB() { return m_db; } - const char* GetAndResetError(); - -private: - bool m_hasReadKey; - bool m_hasWriteKey; - - SymmetricKey - m_readKey, - m_writeKey, - m_ivReadKey, - m_ivWriteKey; - - Pipe - m_encipherPipe, - m_decipherPipe, - m_macPipe; - - Keyed_Filter *m_encipherFilter; - Keyed_Filter *m_decipherFilter; - MAC_Filter *m_cmac; - - int m_pageSize; - unsigned char m_page[SQLITE_MAX_PAGE_SIZE]; - void *m_db; - const char *m_botanErrorMsg; - - InitializationVector GetIVForPage(u32bit page, bool useWriteKey); - void InitializeCodec(void *db); -}; - -#endif diff --git a/src/contrib/sqlite/codec_c_interface.h b/src/contrib/sqlite/codec_c_interface.h deleted file mode 100644 index 9f515c113..000000000 --- a/src/contrib/sqlite/codec_c_interface.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Encryption codec class C interface - * (C) 2010 Olivier de Gaalon - * - * Botan is released under the Simplified BSD License (see license.txt) - */ - -#ifndef _CODEC_C_INTERFACE_H_ -#define _CODEC_C_INTERFACE_H_ - -#ifdef __cplusplus -typedef unsigned char Bool; -#endif - -#ifdef __cplusplus -extern "C" -#endif -void InitializeBotan(); - -#ifdef __cplusplus -extern "C" -#endif -void* InitializeNewCodec(void *db); - -#ifdef __cplusplus -extern "C" -#endif -void* InitializeFromOtherCodec(const void *otherCodec, void *db); - -#ifdef __cplusplus -extern "C" -#endif -void GenerateWriteKey(void *codec, const char *userPassword, int passwordLength); - -#ifdef __cplusplus -extern "C" -#endif -void DropWriteKey(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -void SetWriteIsRead(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -void SetReadIsWrite(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -unsigned char* Encrypt(void *codec, int page, unsigned char *data, Bool useWriteKey); - -#ifdef __cplusplus -extern "C" -#endif -void Decrypt(void *codec, int page, unsigned char *data); - -#ifdef __cplusplus -extern "C" -#endif -void SetPageSize(void *codec, int pageSize); - -#ifdef __cplusplus -extern "C" -#endif -Bool HasReadKey(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -Bool HasWriteKey(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -void* GetDB(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -const char* GetAndResetError(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -void DeleteCodec(void *codec); - -#endif
\ No newline at end of file diff --git a/src/contrib/sqlite/codecext.c b/src/contrib/sqlite/codecext.c deleted file mode 100644 index f44c04a2e..000000000 --- a/src/contrib/sqlite/codecext.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Encryption codec implementation - * (C) 2010 Olivier de Gaalon - * - * Botan is released under the Simplified BSD License (see license.txt) - */ - -#ifndef SQLITE_OMIT_DISKIO -#ifdef SQLITE_HAS_CODEC - -#include "codec_c_interface.h" - -Bool HandleError(void *pCodec) -{ - const char *error = GetAndResetError(pCodec); - if (error) { - sqlite3Error((sqlite3*)GetDB(pCodec), SQLITE_ERROR, "Botan Error: %s", error); - return 1; - } - return 0; -} - -// Guessing that "see" is related to SQLite Encryption Extension" (the semi-official, for-pay, encryption codec) -// Just as useful for initializing Botan. -void sqlite3_activate_see(const char *info) -{ - InitializeBotan(); -} - -// Free the encryption codec, called from pager.c (address passed in sqlite3PagerSetCodec) -void sqlite3PagerFreeCodec(void *pCodec) -{ - if (pCodec) - DeleteCodec(pCodec); -} - -// Report the page size to the codec, called from pager.c (address passed in sqlite3PagerSetCodec) -void sqlite3CodecSizeChange(void *pCodec, int pageSize, int nReserve) -{ - SetPageSize(pCodec, pageSize); -} - -// Encrypt/Decrypt functionality, called by pager.c -void* sqlite3Codec(void *pCodec, void *data, Pgno nPageNum, int nMode) -{ - if (pCodec == NULL) //Db not encrypted - return data; - - switch(nMode) - { - case 0: // Undo a "case 7" journal file encryption - case 2: // Reload a page - case 3: // Load a page - if (HasReadKey(pCodec)) - Decrypt(pCodec, nPageNum, (unsigned char*) data); - break; - case 6: // Encrypt a page for the main database file - if (HasWriteKey(pCodec)) - data = Encrypt(pCodec, nPageNum, (unsigned char*) data, 1); - break; - case 7: // Encrypt a page for the journal file - /* - *Under normal circumstances, the readkey is the same as the writekey. However, - *when the database is being rekeyed, the readkey is not the same as the writekey. - *(The writekey is the "destination key" for the rekey operation and the readkey - *is the key the db is currently encrypted with) - *Therefore, for case 7, when the rollback is being written, always encrypt using - *the database's readkey, which is guaranteed to be the same key that was used to - *read and write the original data. - */ - if (HasReadKey(pCodec)) - data = Encrypt(pCodec, nPageNum, (unsigned char*) data, 0); - break; - } - - HandleError(pCodec); - - return data; -} - -int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *zKey, int nKey) -{ - void *pCodec; - - if (zKey == NULL || nKey <= 0) - { - // No key specified, could mean either use the main db's encryption or no encryption - if (nDb != 0 && nKey < 0) - { - //Is an attached database, therefore use the key of main database, if main database is encrypted - void *pMainCodec = sqlite3PagerGetCodec(sqlite3BtreePager(db->aDb[0].pBt)); - if (pMainCodec != NULL) - { - pCodec = InitializeFromOtherCodec(pMainCodec, db); - sqlite3PagerSetCodec(sqlite3BtreePager(db->aDb[nDb].pBt), - sqlite3Codec, - sqlite3CodecSizeChange, - sqlite3PagerFreeCodec, pCodec); - } - } - } - else - { - // Key specified, setup encryption key for database - pCodec = InitializeNewCodec(db); - GenerateWriteKey(pCodec, (const char*) zKey, nKey); - SetReadIsWrite(pCodec); - sqlite3PagerSetCodec(sqlite3BtreePager(db->aDb[nDb].pBt), - sqlite3Codec, - sqlite3CodecSizeChange, - sqlite3PagerFreeCodec, pCodec); - } - - if (HandleError(pCodec)) - return SQLITE_ERROR; - - return SQLITE_OK; -} - -void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) -{ - // The unencrypted password is not stored for security reasons - // therefore always return NULL - *zKey = NULL; - *nKey = -1; -} - -int sqlite3_key(sqlite3 *db, const void *zKey, int nKey) -{ - // The key is only set for the main database, not the temp database - return sqlite3CodecAttach(db, 0, zKey, nKey); -} - -int sqlite3_rekey(sqlite3 *db, const void *zKey, int nKey) -{ - // Changes the encryption key for an existing database. - int rc = SQLITE_ERROR; - Btree *pbt = db->aDb[0].pBt; - Pager *pPager = sqlite3BtreePager(pbt); - void *pCodec = sqlite3PagerGetCodec(pPager); - - if ((zKey == NULL || nKey == 0) && pCodec == NULL) - { - // Database not encrypted and key not specified. Do nothing - return SQLITE_OK; - } - - if (pCodec == NULL) - { - // Database not encrypted, but key specified. Encrypt database - pCodec = InitializeNewCodec(db); - GenerateWriteKey(pCodec, (const char*) zKey, nKey); - - if (HandleError(pCodec)) - return SQLITE_ERROR; - - sqlite3PagerSetCodec(pPager, sqlite3Codec, sqlite3CodecSizeChange, sqlite3PagerFreeCodec, pCodec); - } - else if (zKey == NULL || nKey == 0) - { - // Database encrypted, but key not specified. Decrypt database - // Keep read key, drop write key - DropWriteKey(pCodec); - } - else - { - // Database encrypted and key specified. Re-encrypt database with new key - // Keep read key, change write key to new key - GenerateWriteKey(pCodec, (const char*) zKey, nKey); - if (HandleError(pCodec)) - return SQLITE_ERROR; - } - - // Start transaction - rc = sqlite3BtreeBeginTrans(pbt, 1); - if (rc == SQLITE_OK) - { - // Rewrite all pages using the new encryption key (if specified) - int nPageCount = -1; - sqlite3PagerPagecount(pPager, &nPageCount); - Pgno nPage = (Pgno) nPageCount; - - Pgno nSkip = PAGER_MJ_PGNO(pPager); - DbPage *pPage; - - Pgno n; - for (n = 1; rc == SQLITE_OK && n <= nPage; n++) - { - if (n == nSkip) - continue; - - rc = sqlite3PagerGet(pPager, n, &pPage); - - if (!rc) - { - rc = sqlite3PagerWrite(pPage); - sqlite3PagerUnref(pPage); - } - else - sqlite3Error(db, SQLITE_ERROR, "%s", "Error while rekeying database page. Transaction Canceled."); - } - } - else - sqlite3Error(db, SQLITE_ERROR, "%s", "Error beginning rekey transaction. Make sure that the current encryption key is correct."); - - if (rc == SQLITE_OK) - { - // All good, commit - rc = sqlite3BtreeCommit(pbt); - - if (rc == SQLITE_OK) - { - //Database rekeyed and committed successfully, update read key - if (HasWriteKey(pCodec)) - SetReadIsWrite(pCodec); - else //No write key == no longer encrypted - sqlite3PagerSetCodec(pPager, NULL, NULL, NULL, NULL); - } - else - { - //FIXME: can't trigger this, not sure if rollback is needed, reference implementation didn't rollback - sqlite3Error(db, SQLITE_ERROR, "%s", "Could not commit rekey transaction."); - } - } - else - { - // Rollback, rekey failed - sqlite3BtreeRollback(pbt, SQLITE_ERROR); - - // go back to read key - if (HasReadKey(pCodec)) - SetWriteIsRead(pCodec); - else //Database wasn't encrypted to start with - sqlite3PagerSetCodec(pPager, NULL, NULL, NULL, NULL); - } - - return rc; -} - -#endif // SQLITE_HAS_CODEC - -#endif // SQLITE_OMIT_DISKIO diff --git a/src/contrib/sqlite/readme.txt b/src/contrib/sqlite/readme.txt deleted file mode 100644 index 4971fd44b..000000000 --- a/src/contrib/sqlite/readme.txt +++ /dev/null @@ -1,35 +0,0 @@ -Build instructions for BotanSqlite3 ---- - -Requirements: - 1. Botan 1.9.0 or later - 2. SQLite3 amalgamation source, version 3.7.12.1 or later (previous versions may work, some will need minor changes) - - -Building: - -1. Extract sqlite3 amalgamation to a directory and add BotanSqlite3 source files - - If desired, codec.h can be modified to tweak the encryption algothrithms and parameters. (Defaults to Twofish/XTS with 256 bit key) - -2. Apply the patch "sqlite3.diff": - $ patch -p0 < sqlite3-amalgamation.patch - - If the patching fails for some reason (ie, changes in SQLite3), it should be trivial to do it manually. - -3. Compile the sqlite3 library with Botan encryption support: - $ gcc -c sqlite3.c -o botansqlite3.o && gcc -c codec.cpp -o codec.o `pkg-config --cflags botan-1.10` && ar rcs libbotansqlite3.a botansqlite3.o codec.o - - (replace "botan-1.10" with appropriate version) - -Testing: - -1. Build the test: - $ g++ test_sqlite.cpp -o test_sqlite `botan-config-1.10 --libs` ./libbotansqlite3.a - - (replace botan-config-1.10 w/ appropriate version) - -2. Run the test - $ ./test_sqlite - -3. Look for "All seems good" diff --git a/src/contrib/sqlite/sqlite3-amalgamation.patch b/src/contrib/sqlite/sqlite3-amalgamation.patch deleted file mode 100644 index 1c2a5c69d..000000000 --- a/src/contrib/sqlite/sqlite3-amalgamation.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- ./sqlite3.c.orig 2011-05-12 10:03:32.051879390 +0800 -+++ ./sqlite3.c 2011-05-12 10:09:04.028550281 +0800 -@@ -17,6 +17,7 @@ - ** language. The code for the "sqlite3" command-line shell is also in a - ** separate file. This file contains only code for the core SQLite library. - */ -+#define SQLITE_HAS_CODEC 1 - #define SQLITE_CORE 1 - #define SQLITE_AMALGAMATION 1 - #ifndef SQLITE_PRIVATE -@@ -125956,3 +125957,4 @@ - #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - - /************** End of fts3_icu.c ********************************************/ -+#include "codecext.c" diff --git a/src/contrib/sqlite/test_sqlite.cpp b/src/contrib/sqlite/test_sqlite.cpp deleted file mode 100644 index 74bf24b06..000000000 --- a/src/contrib/sqlite/test_sqlite.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Quick and dirty test for SQLite3 encryption codec. - * (C) 2010 Olivier de Gaalon - * - * Botan is released under the Simplified BSD License (see license.txt) - */ - -#define SQLITE_HAS_CODEC 1 - -#include <sqlite3.h> -#include <stdio.h> - -namespace SQL -{ - const char * CREATE_TABLE_TEST = - "create table 'test' (id INTEGER PRIMARY KEY, name TEXT, creationtime TEXT);"; - const char * CREATE_TABLE_TEST2 = - "create table 'test2' (id INTEGER PRIMARY KEY, name TEXT, creationtime TEXT);"; - const char * INSERT_INTO_TEST = - "INSERT INTO test (name, creationtime) VALUES ('widget', '1st time');\ - INSERT INTO test (name, creationtime) VALUES ('widget', '2nd time');\ - INSERT INTO test (name, creationtime) VALUES ('widget', '3rd time');\ - INSERT INTO test (name, creationtime) VALUES ('widget', '4th time');\ - INSERT INTO test (name, creationtime) VALUES ('widget', '5th time');"; - const char * INSERT_INTO_TEST2 = - "INSERT INTO test2 (name, creationtime) VALUES ('widget2', '1st time2');\ - INSERT INTO test2 (name, creationtime) VALUES ('widget2', '2nd time2');\ - INSERT INTO test2 (name, creationtime) VALUES ('widget2', '3rd time2');\ - INSERT INTO test2 (name, creationtime) VALUES ('widget2', '4th time2');\ - INSERT INTO test2 (name, creationtime) VALUES ('widget2', '5th time2');"; - const char * SELECT_FROM_TEST = - "SELECT * FROM test;"; - const char * SELECT_FROM_TEST2 = - "SELECT * FROM test2;"; -}; - -static int callback(void *NotUsed, int argc, char **argv, char **azColName){ - int i; - fprintf(stderr, "\t"); - for(i=0; i<argc; i++){ - fprintf(stderr, "%s = %s | ", azColName[i], argv[i] ? argv[i] : "NULL"); - } - fprintf(stderr, "\n"); - return 0; -} - -int main(int argc, char** argv) -{ - sqlite3 * db; - const char * key = "anotherkey"; - const char * dbname = "./testdb"; - int keylen = 7; - char * error=0; - - fprintf(stderr, "Creating Database \"%s\"\n", dbname); - int rc = sqlite3_open(dbname, &db); - if (rc != SQLITE_OK) { fprintf(stderr, "Can't open/create database: %s\n", sqlite3_errmsg(db)); return 1; } - - fprintf(stderr, "Keying Database with key \"%s\"\n", key); - rc = sqlite3_key(db, key, keylen); - if (rc != SQLITE_OK) { fprintf(stderr, "Can't key database: %s\n", sqlite3_errmsg(db)); return 1; } - - fprintf(stderr, "Creating table \"test\"\n"); - rc = sqlite3_exec(db, SQL::CREATE_TABLE_TEST, 0, 0, &error); - if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } - - fprintf(stderr, "Creating table \"test2\"\n"); - rc = sqlite3_exec(db, SQL::CREATE_TABLE_TEST2, 0, 0, &error); - if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } - - fprintf(stderr, "Inserting into table \"test\"\n"); - rc = sqlite3_exec(db, SQL::INSERT_INTO_TEST, 0, 0, &error); - if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } - - fprintf(stderr, "Inserting into table \"test2\"\n"); - rc = sqlite3_exec(db, SQL::INSERT_INTO_TEST2, 0, 0, &error); - if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } - - fprintf(stderr, "Closing Database \"%s\"\n", dbname); - sqlite3_close(db); - - fprintf(stderr, "Opening Database \"%s\"\n", dbname); - rc = sqlite3_open(dbname, &db); - if (rc != SQLITE_OK) { fprintf(stderr, "Can't open/create database: %s\n", sqlite3_errmsg(db)); return 1; } - - fprintf(stderr, "Keying Database with key \"%s\"\n", key); - rc = sqlite3_key(db, key, keylen); - if (rc != SQLITE_OK) { fprintf(stderr, "Can't key database: %s\n", sqlite3_errmsg(db)); return 1; } - - fprintf(stderr, "Selecting all from test\n"); - rc = sqlite3_exec(db, SQL::SELECT_FROM_TEST, callback, 0, &error); - if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } - - fprintf(stderr, "Selecting all from test2\n"); - rc = sqlite3_exec(db, SQL::SELECT_FROM_TEST2, callback, 0, &error); - if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } - - fprintf(stderr, "Closing Database \"%s\"\n", dbname); - sqlite3_close(db); - - fprintf(stderr, "All Seems Good \n"); - return 0; -} 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 diff --git a/src/ocaml/botan.ml b/src/ocaml/botan.ml deleted file mode 100644 index 091f44c27..000000000 --- a/src/ocaml/botan.ml +++ /dev/null @@ -1,189 +0,0 @@ -(* -* OCaml binding for botan (http://botan.randombit.net) -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*) - -open Ctypes -open Foreign - -exception Botan_Error of int - -(* TODO: translate error code to string -TODO: Don't evaluate res unless rc == 0 -*) -let result_or_exn rc res = - match rc with - | 0 -> res - | _ as ec -> raise (Botan_Error ec) - -let to_size_t i = Unsigned.Size_t.of_int i -let to_uint32 i = Unsigned.UInt32.of_int i - -module Botan = struct - - let version = - let version_major = - foreign "botan_version_major" (void @-> returning int32_t) in - let version_minor = - foreign "botan_version_minor" (void @-> returning int32_t) in - let version_patch = - foreign "botan_version_patch" (void @-> returning int32_t) in - let major = Int32.to_int (version_major ()) in - let minor = Int32.to_int (version_minor ()) in - let patch = Int32.to_int (version_patch ()) in - (major, minor, patch) - - let version_string = - let version_string = - foreign "botan_version_string" (void @-> returning string) in - version_string () - - let version_date = - let version_datestamp = - foreign "botan_version_datestamp" (void @-> returning int32_t) in - Int32.to_int (version_datestamp ()) - - let ffi_version = - let ffi_version = - foreign "botan_ffi_api_version" (void @-> returning int32_t) in - Int32.to_int (ffi_version ()) - - let hex_encode bin = - let hex_encode = - foreign "botan_hex_encode" (string @-> size_t @-> ptr char @-> uint32_t @-> returning int) in - let bin_len = String.length bin in - let hex_len = 2*bin_len in - let hex = allocate_n ~count:hex_len char in - let rc = hex_encode bin (to_size_t bin_len) hex (to_uint32 0) in - result_or_exn rc (string_from_ptr hex hex_len) - - (* Bcrypt *) - let bcrypt pass rng work_factor = - let bcrypt = - foreign "botan_bcrypt_generate" (ptr char @-> ptr size_t @-> - string @-> ptr void @-> size_t @-> uint32_t @-> returning int) in - let bcrypt_size = 61 (* FIXME *) in - let alloc_size = allocate size_t (to_size_t bcrypt_size) in - let res = allocate_n ~count:bcrypt_size char in - let rc = bcrypt res alloc_size pass rng (to_size_t work_factor) (to_uint32 0) in - result_or_exn rc (string_from_ptr res (Unsigned.Size_t.to_int (!@ alloc_size))) - - let check_bcrypt pass hash = - let check_bcrypt = - foreign "botan_bcrypt_is_valid" (string @-> string @-> returning int) in - let rc = check_bcrypt pass hash in - match rc with - | 0 -> true - | -100 -> false - | _ as ec -> raise (Botan_Error ec) - - module Hash = struct - type t = unit ptr - let hash_t : t typ = ptr void - - let create name = - let hash_init = - foreign "botan_hash_init" (ptr hash_t @-> string @-> uint32_t @-> returning int) in - let o = allocate_n ~count:1 hash_t in - let rc = hash_init o name (to_uint32 0) in - result_or_exn rc (!@ o) - - let destroy hash = - let hash_destroy = - foreign "botan_hash_destroy" (hash_t @-> returning int) in - let rc = hash_destroy hash in - result_or_exn rc () - - let output_length hash = - let hash_output_length = - foreign "botan_hash_output_length" (hash_t @-> ptr size_t @-> returning int) in - let ol = allocate_n ~count:1 size_t in - let rc = hash_output_length hash ol in - result_or_exn rc (Unsigned.Size_t.to_int (!@ ol)) - - let clear hash = - let hash_clear = - foreign "botan_hash_clear" (hash_t @-> returning int) in - let rc = hash_clear hash in - result_or_exn rc () - - let update hash input = - let hash_update = - foreign "botan_hash_update" (hash_t @-> string @-> size_t @-> returning int) in - let input_len = (String.length input) in - let rc = hash_update hash input (to_size_t input_len) in - result_or_exn rc () - - let final hash = - let hash_final = - foreign "botan_hash_final" (hash_t @-> ptr char @-> returning int) in - let ol = output_length hash in - let res = allocate_n ~count:ol char in - let rc = hash_final hash res in - result_or_exn rc (string_from_ptr res ol) - - end (* Hash *) - - module RNG = struct - type t = unit ptr - let rng_t : t typ = ptr void - - let create name = - let rng_init = - foreign "botan_rng_init" (ptr rng_t @-> string @-> uint32_t @-> returning int) in - let o = allocate_n ~count:1 rng_t in - let rc = rng_init o name (to_uint32 0) in - result_or_exn rc (!@ o) - - let destroy rng = - let rng_destroy = - foreign "botan_rng_destroy" (rng_t @-> returning int) in - let rc = rng_destroy rng in - result_or_exn rc () - - let generate rng out_len = - let rng_generate = - foreign "botan_rng_get" (rng_t @-> ptr char @-> size_t @-> returning int) in - let res = allocate_n ~count:out_len char in - let rc = rng_generate rng res (to_size_t out_len) in - result_or_exn rc (string_from_ptr res out_len) - - let reseed rng bits = - let rng_reseed = - foreign "botan_rng_reseed" (rng_t @-> size_t @-> returning int) in - let rc = rng_reseed rng (to_size_t bits) in - - result_or_exn rc () - - let update rng input = - let rng_update = - foreign "botan_rng_update" (rng_t @-> string @-> size_t @-> returning int) in - let input_len = (String.length input) in - let rc = rng_update rng input (to_size_t input_len) in - result_or_exn rc () - - end (* RNG *) - -end (* Botan *) - -let () = - let rng = Botan.RNG.create "system" in - let bcrypt = Botan.bcrypt "pass" rng 10 in - let ok = Botan.check_bcrypt "pass" bcrypt in - let nok = Botan.check_bcrypt "something else" bcrypt in - print_string (Printf.sprintf "%s %B %B\n" bcrypt ok nok) - -let () = - let (maj,min,patch) = Botan.version in - let ver_str = Botan.version_string in - print_string (Printf.sprintf "%d.%d.%d\n%s\n" maj min patch ver_str) - -let () = - let h = Botan.Hash.create "SHA-384" in - begin - Botan.Hash.update h "hi"; - print_string (Botan.hex_encode (Botan.Hash.final h) ^ "\n"); - Botan.Hash.destroy h - end diff --git a/src/ocaml/botan.mli b/src/ocaml/botan.mli deleted file mode 100644 index 0407177bb..000000000 --- a/src/ocaml/botan.mli +++ /dev/null @@ -1,38 +0,0 @@ -(* -* OCaml binding for botan (http://botan.randombit.net) -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*) - - -module Botan : sig - val version : (int * int * int) - val version_string : string - val version_date : int - val ffi_version : int - - val hex_encode : string -> string - - module RNG : sig - type t - val create : string -> t - val destroy: t -> unit (* TODO: GC finalize instead *) - val generate : t -> int -> string - val reseed : t -> int -> unit - end - - val bcrypt : string -> RNG.t -> int -> string - val check_bcrypt : string -> string -> bool - - module Hash : sig - type t - val create : string -> t - val destroy: t -> unit (* TODO: GC finalize instead *) - val output_length : t -> int - val clear : t -> unit - val update : t -> string -> unit - val final: t -> string - end - -end diff --git a/src/ocaml/build.sh b/src/ocaml/build.sh deleted file mode 100755 index a79f7d6ac..000000000 --- a/src/ocaml/build.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -set -e -which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available - -# extra ../ is needed due to ocamlbuild chdiring into _build -ocamlbuild -pkg ctypes.foreign -lflags -cclib,-L../../.. -lflags -cclib,-lbotan-1.11 botan.native diff --git a/src/python/botan.py b/src/python/botan.py index a28f3ddb0..04e574746 100755 --- a/src/python/botan.py +++ b/src/python/botan.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 """ Python wrapper of the botan crypto library @@ -29,6 +29,40 @@ botan_api_rev = botan.botan_ffi_api_version() if botan_api_rev != expected_api_rev: raise Exception("Bad botan API rev got %d expected %d" % (botan_api_rev, expected_api_rev)) +# Internal utilities +def _call_fn_returning_string(guess, fn): + + buf = create_string_buffer(guess) + buf_len = c_size_t(len(buf)) + + rc = fn(buf, byref(buf_len)) + if rc < 0: + if buf_len.value > len(buf): + #print("Calling again with %d" % (buf_len.value)) + return _call_fn_returning_string(buf_len.value, fn) + else: + raise Exception("Call failed: %d" % (rc)) + + assert buf_len.value <= len(buf) + return str(buf.raw[0:buf_len.value]) + +def _call_fn_returning_vec(guess, fn): + + buf = create_string_buffer(guess) + buf_len = c_size_t(len(buf)) + + rc = fn(buf, byref(buf_len)) + if rc < 0: + if buf_len.value > len(buf): + #print("Calling again with %d" % (buf_len.value)) + return _call_fn_returning_vec(buf_len.value, fn) + else: + raise Exception("Call failed: %d" % (rc)) + + assert buf_len.value <= len(buf) + return buf.raw[0:buf_len.value] + + """ Versions """ @@ -57,7 +91,7 @@ class rng(object): rc = botan.botan_rng_init(byref(self.rng), rng_type) else: rc = botan.botan_rng_init(byref(self.rng), rng_type.encode('ascii')) - + if rc != 0 or self.rng is None: raise Exception("No rng " + algo + " for you!") @@ -256,7 +290,6 @@ class cipher(object): """ Bcrypt -TODO: might not be enabled - handle that gracefully! """ def bcrypt(passwd, rng, work_factor = 10): botan.botan_bcrypt_generate.argtypes = [POINTER(c_char), POINTER(c_size_t), @@ -322,12 +355,17 @@ class public_key(object): def algo_name(self): botan.botan_pubkey_algo_name.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)] + return _call_fn_returning_string(32, lambda b,bl: botan.botan_pubkey_algo_name(self.pubkey, b, bl)) - buf = create_string_buffer(64) - buf_len = c_size_t(len(buf)) - botan.botan_pubkey_algo_name(self.pubkey, buf, byref(buf_len)) - assert buf_len.value <= len(buf) - return buf.raw[0:buf_len.value] + def encoding(self, pem = False): + botan.botan_pubkey_export.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t), c_uint32] + + flag = 1 if pem else 0 + + if pem: + return _call_fn_returning_string(0, lambda b,bl: botan.botan_pubkey_export(self.pubkey, b, bl, 1)) + else: + return _call_fn_returning_string(0, lambda b,bl: botan.botan_pubkey_export(self.pubkey, b, bl, 0)) def fingerprint(self, hash = 'SHA-256'): botan.botan_pubkey_fingerprint.argtypes = [c_void_p, c_char_p, @@ -338,7 +376,7 @@ class public_key(object): buf_len = c_size_t(n) if sys.version_info[0] > 2: hash = hash.encode('utf-8') - + botan.botan_pubkey_fingerprint(self.pubkey, hash, buf, byref(buf_len)) return hexlify(buf[0:buf_len.value]) @@ -347,6 +385,7 @@ class private_key(object): botan.botan_privkey_create_rsa.argtypes = [c_void_p, c_void_p, c_size_t] botan.botan_privkey_create_ecdsa.argtypes = [c_void_p, c_void_p, c_char_p] botan.botan_privkey_create_ecdh.argtypes = [c_void_p, c_void_p, c_char_p] + botan.botan_privkey_create_mceliece.argtypes = [c_void_p, c_void_p, c_size_t, c_size_t] self.privkey = c_void_p(0) if alg == 'rsa': @@ -355,6 +394,8 @@ class private_key(object): botan.botan_privkey_create_ecdsa(byref(self.privkey), rng.rng, param) elif alg == 'ecdh': botan.botan_privkey_create_ecdh(byref(self.privkey), rng.rng, param) + elif alg in ['mce', 'mceliece']: + botan.botan_privkey_create_mceliece(byref(self.privkey), rng.rng, param[0], param[1]) else: raise Exception('Unknown public key algo ' + alg) @@ -385,7 +426,6 @@ class private_key(object): botan.botan_privkey_export(self.privkey, buf, byref(buf_len)) return buf[0:buf_len.value] - class pk_op_encrypt(object): def __init__(self, key, padding): botan.botan_pk_op_encrypt_create.argtypes = [c_void_p, c_void_p, c_char_p, c_uint32] @@ -417,7 +457,7 @@ class pk_op_encrypt(object): #print("encrypt: outbuf_sz.value=%d" % outbuf_sz.value) return outbuf.raw[0:outbuf_sz.value] - + class pk_op_decrypt(object): def __init__(self, key, padding): botan.botan_pk_op_decrypt_create.argtypes = [c_void_p, c_void_p, c_char_p, c_uint32] @@ -497,6 +537,24 @@ class pk_op_verify(object): return True return False +""" +MCEIES encryption +Must be used with McEliece keys +""" +def mceies_encrypt(mce, rng, aead, pt, ad): + botan.botan_mceies_encrypt.argtypes = [c_void_p, c_void_p, c_char_p, POINTER(c_char), c_size_t, + POINTER(c_char), c_size_t, POINTER(c_char), POINTER(c_size_t)] + + return _call_fn_returning_string(0, lambda b,bl: + botan.botan_mceies_encrypt(mce.pubkey, rng.rng, aead, pt, len(pt), ad, len(ad), b, bl)) + +def mceies_decrypt(mce, aead, pt, ad): + botan.botan_mceies_decrypt.argtypes = [c_void_p, c_char_p, POINTER(c_char), c_size_t, + POINTER(c_char), c_size_t, POINTER(c_char), POINTER(c_size_t)] + + return _call_fn_returning_string(0, lambda b,bl: + botan.botan_mceies_decrypt(mce.privkey, aead, pt, len(pt), ad, len(ad), b, bl)) + class pk_op_key_agreement(object): def __init__(self, key, kdf): botan.botan_pk_op_key_agreement_create.argtypes = [c_void_p, c_void_p, c_char_p, c_uint32] @@ -507,10 +565,7 @@ class pk_op_key_agreement(object): if not self.op: raise Exception("No key agreement for you") - pub = create_string_buffer(4096) - pub_len = c_size_t(len(pub)) - botan.botan_pk_op_key_agreement_export_public(key.privkey, pub, byref(pub_len)) - self.m_public_value = pub.raw[0:pub_len.value] + self.m_public_value = _call_fn_returning_string(0, lambda b, bl: botan.botan_pk_op_key_agreement_export_public(key.privkey, b, bl)) def __del__(self): botan.botan_pk_op_key_agreement_destroy.argtypes = [c_void_p] @@ -523,28 +578,73 @@ class pk_op_key_agreement(object): botan.botan_pk_op_key_agreement.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t), POINTER(c_char), c_size_t, POINTER(c_char), c_size_t] - outbuf_sz = c_size_t(key_len) - outbuf = create_string_buffer(outbuf_sz.value) - rc = botan.botan_pk_op_key_agreement(self.op, outbuf, byref(outbuf_sz), - other, len(other), salt, len(salt)) + return _call_fn_returning_string(key_len, + lambda b,bl: botan.botan_pk_op_key_agreement(self.op, b, bl, + other, len(other), + salt, len(salt))) + +class x509_cert(object): + def __init__(self, filename): + botan.botan_x509_cert_load_file.argtypes = [POINTER(c_void_p), c_char_p] + self.x509_cert = c_void_p(0) + if sys.version_info[0] > 2: + filename = cast(filename, c_char_p) + botan.botan_x509_cert_load_file(byref(self.x509_cert), filename) + + def __del__(self): + botan.botan_x509_cert_destroy.argtypes = [c_void_p] + botan.botan_x509_cert_destroy(self.x509_cert) + + # TODO: have these convert to a python datetime + def time_starts(self): + botan.botan_x509_cert_get_time_starts.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)] + return _call_fn_returning_string(16, lambda b,bl: botan.botan_x509_cert_get_time_starts(self.x509_cert, b, bl)) + + def time_expires(self): + botan.botan_x509_cert_get_time_expires.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)] + return _call_fn_returning_string(16, lambda b,bl: botan.botan_x509_cert_get_time_expires(self.x509_cert, b, bl)) + + def to_string(self): + botan.botan_x509_cert_to_string.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)] + return _call_fn_returning_string(0, lambda b,bl: botan.botan_x509_cert_to_string(self.x509_cert, b, bl)) + + def fingerprint(self, hash_algo = 'SHA-256'): + botan.botan_x509_cert_get_fingerprint.argtypes = [c_void_p, c_char_p, + POINTER(c_char), POINTER(c_size_t)] + + n = hash_function(hash_algo).output_length() * 3 + if sys.version_info[0] > 2: + hash_algo = hash_algo.encode('utf-8') + + return _call_fn_returning_string(n, lambda b,bl: botan.botan_x509_cert_get_fingerprint(self.x509_cert, hash_algo, b, bl)) + + def serial_number(self): + botan.botan_x509_cert_get_serial_number.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)] + return _call_fn_returning_vec(0, lambda b,bl: botan.botan_x509_cert_get_serial_number(self.x509_cert, b, bl)) + + def authority_key_id(self): + botan.botan_x509_cert_get_authority_key_id.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)] + return _call_fn_returning_vec(0, lambda b,bl: botan.botan_x509_cert_get_authority_key_id(self.x509_cert, b, bl)) + + def subject_key_id(self): + botan.botan_x509_cert_get_subject_key_id.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)] + return _call_fn_returning_vec(0, lambda b,bl: botan.botan_x509_cert_get_subject_key_id(self.x509_cert, b, bl)) + + def subject_public_key_bits(self): + botan.botan_x509_cert_get_public_key_bits.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)] + return _call_fn_returning_vec(0, lambda b,bl: botan.botan_x509_cert_get_public_key_bits(self.x509_cert, b, bl)) - if rc == -1 and outbuf_sz.value > len(outbuf): - outbuf = create_string_buffer(outbuf_sz.value) - botan.botan_pk_op_key_agreement(self.op, outbuf, byref(outbuf_sz), - other, len(other), salt, len(salt)) - return outbuf.raw[0:outbuf_sz.value] """ Tests and examples """ def test(): - r = rng("user") + r = rng("user") print("\n%s" % version_string().decode('utf-8')) print("v%d.%d.%d\n" % (version_major(), version_minor(), version_patch())) - print("KDF2(SHA-1) %s" % hexlify(kdf('KDF2(SHA-1)'.encode('ascii'), unhexlify('701F3480DFE95F57941F804B1B2413EF'), 7, unhexlify('55A4E9DD5F4CA2EF82')) @@ -559,18 +659,12 @@ def test(): print("good output %s\n" % '59B2B1143B4CB1059EC58D9722FB1C72471E0D85C6F7543BA5228526375B0127') - - (salt,iterations,psk) = pbkdf_timed('PBKDF2(SHA-256)'.encode('ascii'), 'xyz'.encode('utf-8'), 32, 200) - if sys.version_info[0] < 3: - print("PBKDF2(SHA-256) x=timed, y=iterated; salt = %s (len=%d) #iterations = %d\n" % - (hexlify(salt), len(salt), iterations) ) - else: - print("PBKDF2(SHA-256) x=timed, y=iterated; salt = %s (len=%d) #iterations = %d\n" % - (hexlify(salt).decode('ascii'), len(salt), iterations) ) - + print("PBKDF2(SHA-256) x=timed, y=iterated; salt = %s (len=%d) #iterations = %d\n" % + (hexlify(salt).decode('ascii'), len(salt), iterations)) + print('x %s' % hexlify(psk).decode('utf-8')) print('y %s\n' % (hexlify(pbkdf('PBKDF2(SHA-256)'.encode('utf-8'), @@ -579,7 +673,7 @@ def test(): hmac = message_authentication_code('HMAC(SHA-256)'.encode('ascii')) hmac.set_key(unhexlify('0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20')) hmac.update(unhexlify('616263')) - + hmac_output = hmac.final() if hmac_output != unhexlify('A21B1F5D4CF4F73A4DD939750F7A066A7F98CC131CB16A6692759021CFAB8181'): @@ -587,7 +681,7 @@ def test(): print("vs good: \tA21B1F5D4CF4F73A4DD939750F7A066A7F98CC131CB16A6692759021CFAB8181"); else: print("HMAC output (good): %s\n" % hexlify(hmac_output).decode('utf-8')) - + print("rng output:\n\t%s\n\t%s\n\t%s\n" % (hexlify(r.get(42)).decode('utf-8'), hexlify(r.get(13)).decode('utf-8'), @@ -642,13 +736,31 @@ def test(): print("OCB pt %s %d" % (hexlify(pt).decode('utf-8'), len(pt))) print("OCB de %s %d\n" % (hexlify(dec).decode('utf-8'), len(dec))) + + mce_priv = private_key('mce', [2960,57], r) + mce_pub = mce_priv.get_public_key() + + mce_plaintext = 'mce plaintext' + mce_ad = 'mce AD' + mce_ciphertext = mceies_encrypt(mce_pub, r, 'ChaCha20Poly1305', mce_plaintext, mce_ad) + + print "mce", len(mce_plaintext), len(mce_ciphertext) + + mce_decrypt = mceies_decrypt(mce_priv, 'ChaCha20Poly1305', mce_ciphertext, mce_ad) + + print("mce_pub %s/SHA-1 fingerprint: %s (estimated strength %s) (len %d)" % + (mce_pub.algo_name().decode('utf-8'), mce_pub.fingerprint("SHA-1").decode('utf-8'), + mce_pub.estimated_strength(), len(mce_pub.encoding()) + ) + ) + rsapriv = private_key('rsa', 1536, r) rsapub = rsapriv.get_public_key() - - print("rsapub %s/SHA-1 fingerprint: %s (estimated strength %s)" % + + print("rsapub %s SHA-1 fingerprint: %s estimated strength %d len %d" % (rsapub.algo_name().decode('utf-8'), rsapub.fingerprint("SHA-1").decode('utf-8'), - rsapub.estimated_strength() + rsapub.estimated_strength(), len(rsapub.encoding()) ) ) @@ -656,7 +768,7 @@ def test(): enc = pk_op_encrypt(rsapub, "EME1(SHA-256)".encode('utf-8')) ctext = enc.encrypt('foof'.encode('utf-8'), r) - print("ptext \'%s\'" % 'foof') + print("ptext \'%s\'" % 'foof') print("ctext \'%s\'" % hexlify(ctext).decode('utf-8')) print("decrypt \'%s\'\n" % dec.decrypt(ctext).decode('utf-8')) @@ -669,7 +781,7 @@ def test(): r.reseed(200) print("EMSA4(SHA-384) signature: %s" % hexlify(sig).decode('utf-8')) - + verify = pk_op_verify(rsapub, 'EMSA4(SHA-384)'.encode('utf-8')) verify.update('mess'.encode('utf-8')) @@ -683,32 +795,44 @@ def test(): verify.update('message'.encode('utf-8')) print("good sig accepted? %s\n" % verify.check_signature(sig)) - dh_grp = 'secp256r1'.encode('utf-8') - #dh_grp = 'curve25519'.encode('utf-8') - dh_kdf = 'KDF2(SHA-384)'.encode('utf-8') - a_dh_priv = private_key('ecdh', dh_grp, r) - a_dh_pub = a_dh_priv.get_public_key() + for dh_grps in ['secp256r1', 'curve25519']: + dh_grp = dh_grps.encode('utf-8') + dh_kdf = 'KDF2(SHA-384)'.encode('utf-8') + a_dh_priv = private_key('ecdh', dh_grp, r) + a_dh_pub = a_dh_priv.get_public_key() + + b_dh_priv = private_key('ecdh', dh_grp, r) + b_dh_pub = b_dh_priv.get_public_key() + + a_dh = pk_op_key_agreement(a_dh_priv, dh_kdf) + b_dh = pk_op_key_agreement(b_dh_priv, dh_kdf) + + print("ecdh %s pubs:\n %s\n %s\n" % + (dh_grps, + hexlify(a_dh.public_value()).decode('utf-8'), + hexlify(b_dh.public_value()).decode('utf-8'))) - b_dh_priv = private_key('ecdh', dh_grp, r) - b_dh_pub = b_dh_priv.get_public_key() + a_key = a_dh.agree(b_dh.public_value(), 20, 'salt'.encode('utf-8')) + b_key = b_dh.agree(a_dh.public_value(), 20, 'salt'.encode('utf-8')) - a_dh = pk_op_key_agreement(a_dh_priv, dh_kdf) - b_dh = pk_op_key_agreement(b_dh_priv, dh_kdf) + print("ecdh %s shared:\n %s\n %s\n" % + (dh_grps, hexlify(a_key).decode('utf-8'), hexlify(b_key).decode('utf-8'))) - print("ecdh pubs:\n %s\n %s\n" % - (hexlify(a_dh.public_value()).decode('utf-8'), - hexlify(b_dh.public_value()).decode('utf-8'))) + cert = x509_cert("src/tests/data/ecc/CSCA.CSCA.csca-germany.1.crt") + print(cert.fingerprint("SHA-1")) + print("32:42:1C:C3:EC:54:D7:E9:43:EC:51:F0:19:23:BD:85:1D:F2:1B:B9") - a_key = a_dh.agree(b_dh.public_value(), 20, 'salt'.encode('utf-8')) - b_key = b_dh.agree(a_dh.public_value(), 20, 'salt'.encode('utf-8')) + print(cert.time_starts()) + print(cert.time_expires()) - print("ecdh shared:\n %s\n %s\n" % - (hexlify(a_key).decode('utf-8'), hexlify(b_key).decode('utf-8'))) + print(hexlify(cert.serial_number())) + print(hexlify(cert.authority_key_id())) + print(hexlify(cert.subject_key_id())) + print(hexlify(cert.subject_public_key_bits())) + print(cert.to_string()) - #f = open('key.ber','wb') - #f.write(blob) - #f.close() + return def main(args = None): diff --git a/src/scripts/ci/after_success.sh b/src/scripts/ci/after_success.sh deleted file mode 100755 index 5cd01b39a..000000000 --- a/src/scripts/ci/after_success.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -set -ev -which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available - -if [ "$BUILD_MODE" = "coverage" ]; then - GCOV="/usr/bin/gcov-4.8" - /tmp/usr/bin/lcov --gcov-tool "$GCOV" --directory . --capture --output-file coverage.info - /tmp/usr/bin/lcov --gcov-tool "$GCOV" --remove coverage.info 'tests/*' '/usr/*' --output-file coverage.info - /tmp/usr/bin/lcov --gcov-tool "$GCOV" --list coverage.info - - # Assume that $COVERALLS_REPO_TOKEN might not be set (e.g. pull requests) - coveralls-lcov --repo-token="$COVERALLS_REPO_TOKEN" coverage.info -fi diff --git a/src/scripts/ci/appveyor.yml b/src/scripts/ci/appveyor.yml index aa0c3890c..37edf615a 100644 --- a/src/scripts/ci/appveyor.yml +++ b/src/scripts/ci/appveyor.yml @@ -4,12 +4,18 @@ platform: - x86 - x86_amd64 +environment: + matrix: + - MODE: --enable-shared + - MODE: --disable-shared + install: - call "%ProgramFiles(x86)%\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" %PLATFORM% - cl # check compiler version +# always build via amalgamation due to build time constraints on appveyor build_script: - - python configure.py --disable-shared --via-amalgamation --cpu=%PLATFORM% --cc=msvc + - python configure.py --cc=msvc --via-amalgamation --cpu=%PLATFORM% %MODE% - nmake - botan-test - nmake install diff --git a/src/scripts/ci/build.sh b/src/scripts/ci/build.sh deleted file mode 100755 index 9bf7b0e84..000000000 --- a/src/scripts/ci/build.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -set -ev -which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available - -if [ "$BUILD_MODE" = "static" ]; then - CFG_FLAGS=(--disable-shared --via-amalgamation) -elif [ "$BUILD_MODE" = "shared" ]; then - CFG_FLAGS=() -elif [ "$BUILD_MODE" = "coverage" ]; then - # lcov gets confused by symlinks - CFG_FLAGS=(--build-mode=coverage --link-method=copy) -elif [ "$BUILD_MODE" = "sanitizer" ]; then - CFG_FLAGS=(--build-mode=sanitizer) -fi - -if [ "$MODULES" = "min" ]; then - CFG_FLAGS+=(--no-autoload --enable-modules=base) -fi - -# Workaround for missing update-alternatives -# https://github.com/travis-ci/travis-ci/issues/3668 -if [ "$CXX" = "g++" ]; then - export CXX="/usr/bin/g++-4.8" -fi - -#enable ccache -if [ "$TRAVIS_OS_NAME" = "linux" ]; then - ccache --max-size=30M - ccache --show-stats - - export CXX="ccache $CXX" -fi - -$CXX --version -./configure.py "${CFG_FLAGS[@]}" --cc="$CC" --cc-bin="$CXX" \ - --with-openssl --with-sqlite --with-zlib \ - --prefix=/tmp/botan-installation -make -j 2 - -if [ "$MODULES" != "min" ]; then - ./botan-test -fi - -make install diff --git a/src/scripts/ci/circle/clang-shared-debug.sh b/src/scripts/ci/circle/clang-shared-debug.sh new file mode 100755 index 000000000..2ef4e6dd5 --- /dev/null +++ b/src/scripts/ci/circle/clang-shared-debug.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -ev +which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available + +BUILD_NICKNAME=$(basename "$0" .sh) +BUILD_DIR="./build-$BUILD_NICKNAME" + +./configure.py --with-build-dir="$BUILD_DIR" --build-mode=debug --cc=clang +make -j 2 -f "$BUILD_DIR"/Makefile +"$BUILD_DIR"/botan-test diff --git a/src/scripts/ci/circle/clang-static-debug.sh b/src/scripts/ci/circle/clang-static-debug.sh new file mode 100755 index 000000000..6341dd467 --- /dev/null +++ b/src/scripts/ci/circle/clang-static-debug.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -ev +which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available + +BUILD_NICKNAME=$(basename "$0" .sh) +BUILD_DIR="./build-$BUILD_NICKNAME" + +./configure.py --with-build-dir="$BUILD_DIR" --build-mode=debug --cc=clang --disable-shared +make -j 2 -f "$BUILD_DIR"/Makefile +"$BUILD_DIR"/botan-test diff --git a/src/scripts/ci/circle/gcc-shared-debug.sh b/src/scripts/ci/circle/gcc-shared-debug.sh new file mode 100755 index 000000000..93530b8ac --- /dev/null +++ b/src/scripts/ci/circle/gcc-shared-debug.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -ev +which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available + +BUILD_NICKNAME=$(basename "$0" .sh) +BUILD_DIR="./build-$BUILD_NICKNAME" + +./configure.py --with-build-dir="$BUILD_DIR" --build-mode=debug +make -j 2 -f "$BUILD_DIR"/Makefile +"$BUILD_DIR"/botan-test diff --git a/src/scripts/ci/circle/gcc-static-debug.sh b/src/scripts/ci/circle/gcc-static-debug.sh new file mode 100755 index 000000000..c7d23b9b0 --- /dev/null +++ b/src/scripts/ci/circle/gcc-static-debug.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -ev +which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available + +BUILD_NICKNAME=$(basename "$0" .sh) +BUILD_DIR="./build-$BUILD_NICKNAME" + +./configure.py --with-build-dir="$BUILD_DIR" --build-mode=debug --disable-shared --via-amalgamation +make -j 2 -f "$BUILD_DIR"/Makefile +"$BUILD_DIR"/botan-test diff --git a/src/scripts/ci/install.sh b/src/scripts/ci/install.sh deleted file mode 100755 index 364d447bf..000000000 --- a/src/scripts/ci/install.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -set -ev -which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available - -if [ "$BUILD_MODE" = "coverage" ]; then - wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz - tar -xvf lcov_1.11.orig.tar.gz - export PREFIX="/tmp" - make -C lcov-1.11/ install - gem install coveralls-lcov -fi diff --git a/src/scripts/ci/travis/after_success.sh b/src/scripts/ci/travis/after_success.sh new file mode 100755 index 000000000..178586b6d --- /dev/null +++ b/src/scripts/ci/travis/after_success.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -ev +which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available + +if [ "$BUILD_MODE" = "coverage" ]; then + GCOV="/usr/bin/gcov-4.8" + /tmp/usr/bin/lcov --gcov-tool "$GCOV" --directory . --capture --output-file coverage.info + /tmp/usr/bin/lcov --gcov-tool "$GCOV" --remove coverage.info 'tests/*' '/usr/*' --output-file coverage.info + /tmp/usr/bin/lcov --gcov-tool "$GCOV" --list coverage.info + + codecov +fi diff --git a/src/scripts/ci/travis/build.sh b/src/scripts/ci/travis/build.sh new file mode 100755 index 000000000..369450091 --- /dev/null +++ b/src/scripts/ci/travis/build.sh @@ -0,0 +1,63 @@ +#!/bin/bash +set -ev +which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available + +if [ "$BUILD_MODE" = "static" ]; then + CFG_FLAGS=(--disable-shared --via-amalgamation) +elif [ "$BUILD_MODE" = "shared" ]; then + CFG_FLAGS=() +elif [ "$BUILD_MODE" = "coverage" ]; then + # lcov gets confused by symlinks + CFG_FLAGS=(--build-mode=coverage --link-method=copy) +elif [ "$BUILD_MODE" = "sanitizer" ]; then + CFG_FLAGS=(--build-mode=sanitizer) +fi + +if [ "$MODULES" = "min" ]; then + CFG_FLAGS+=(--minimized-build --enable-modules=base) +fi + +# Workaround for missing update-alternatives +# https://github.com/travis-ci/travis-ci/issues/3668 +if [ "$CXX" = "g++" ]; then + export CXX="/usr/bin/g++-4.8" +fi + +# enable ccache +if [ "$TRAVIS_OS_NAME" = "linux" ]; then + ccache --max-size=30M + ccache --show-stats + + export CXX="ccache $CXX" +fi + +# configure +if [ "$TARGETOS" = "ios32" ]; then + ./configure.py "${CFG_FLAGS[@]}" --cpu=armv7 --cc=clang \ + --cc-abi-flags="-arch armv7 -arch armv7s -stdlib=libc++" \ + --prefix=/tmp/botan-installation + +elif [ "$TARGETOS" = "ios64" ]; then + ./configure.py "${CFG_FLAGS[@]}" --cpu=armv8-a --cc=clang \ + --cc-abi-flags="-arch arm64 -stdlib=libc++" \ + --prefix=/tmp/botan-installation + +else + $CXX --version + ./configure.py "${CFG_FLAGS[@]}" --cc="$CC" --cc-bin="$CXX" \ + --with-bzip2 --with-lzma --with-openssl --with-sqlite --with-zlib \ + --prefix=/tmp/botan-installation +fi + +# build +if [ "${TARGETOS:0:3}" = "ios" ]; then + xcrun --sdk iphoneos make -j 2 +else + make -j 2 +fi + +if [ "$MODULES" != "min" ] && [ "${TARGETOS:0:3}" != "ios" ]; then + ./botan-test +fi + +make install diff --git a/src/scripts/ci/travis/install.sh b/src/scripts/ci/travis/install.sh new file mode 100755 index 000000000..830834d3e --- /dev/null +++ b/src/scripts/ci/travis/install.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -ev +which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available + +if [ "$BUILD_MODE" = "coverage" ]; then + wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz + tar -xvf lcov_1.11.orig.tar.gz + export PREFIX="/tmp" + make -C lcov-1.11/ install + + pip install --user codecov +fi + +if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$TARGETOS" != "ios" ]; then + ./src/scripts/ci/travis/install_osx_packages.sh +fi diff --git a/src/scripts/ci/travis/install_osx_packages.sh b/src/scripts/ci/travis/install_osx_packages.sh new file mode 100755 index 000000000..1d4a5e001 --- /dev/null +++ b/src/scripts/ci/travis/install_osx_packages.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -ev +which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available + +# Workaround for https://github.com/Homebrew/homebrew/issues/42553 +brew update || brew update + +brew install xz diff --git a/src/scripts/install.py b/src/scripts/install.py index d3fb7c124..d1d62b6c5 100755 --- a/src/scripts/install.py +++ b/src/scripts/install.py @@ -69,6 +69,15 @@ def makedirs(dirname, exist_ok = True): if e.errno != errno.EEXIST or not exist_ok: raise e +# Clear link and create new one +def force_symlink(target, linkname): + try: + os.unlink(linkname) + except OSError as e: + if e.errno != errno.ENOENT: + raise e + os.symlink(target, linkname) + def main(args = None): if args is None: args = sys.argv @@ -143,36 +152,23 @@ def main(args = None): if bool(cfg['build_shared_lib']): if str(cfg['os']) == "windows": - shared_lib = process_template('%{lib_prefix}%{libname}.%{so_suffix}') # botan.dll - copy_executable(os.path.join(out_dir, shared_lib), - os.path.join(lib_dir, os.path.basename(shared_lib))) + soname_base = process_template('%{soname_base}') # botan.dll + copy_executable(os.path.join(out_dir, soname_base), + os.path.join(lib_dir, soname_base)) else: - shared_lib = process_template('%{lib_prefix}%{libname}.%{so_suffix}.%{so_abi_rev}.%{version_patch}') - soname = process_template('%{lib_prefix}%{libname}.%{so_suffix}.%{so_abi_rev}') - baselib = process_template('%{lib_prefix}%{libname}.%{so_suffix}') + soname_patch = process_template('%{soname_patch}') + soname_abi = process_template('%{soname_abi}') + soname_base = process_template('%{soname_base}') - copy_executable(os.path.join(out_dir, shared_lib), - os.path.join(lib_dir, os.path.basename(shared_lib))) + copy_executable(os.path.join(out_dir, soname_patch), + os.path.join(lib_dir, soname_patch)) prev_cwd = os.getcwd() try: os.chdir(lib_dir) - - try: - os.unlink(soname) - except OSError as e: - if e.errno != errno.ENOENT: - raise e - - try: - os.unlink(baselib) - except OSError as e: - if e.errno != errno.ENOENT: - raise e - - os.symlink(shared_lib, soname) - os.symlink(soname, baselib) + force_symlink(soname_patch, soname_abi) + force_symlink(soname_patch, soname_base) finally: os.chdir(prev_cwd) @@ -185,11 +181,12 @@ def main(args = None): os.path.join(pkgconfig_dir, os.path.basename(cfg['botan_pkgconfig']))) if 'ffi' in cfg['mod_list'].split('\n'): - py_lib_path = os.path.join(lib_dir, 'python%s' % (cfg['python_version']), 'site-packages') - logging.debug('Installing python module to %s' % (py_lib_path)) - makedirs(py_lib_path) - for py in ['botan.py']: - copy_file(os.path.join(cfg['python_dir'], py), os.path.join(py_lib_path, py)) + for ver in cfg['python_version'].split(','): + py_lib_path = os.path.join(lib_dir, 'python%s' % (ver), 'site-packages') + logging.debug('Installing python module to %s' % (py_lib_path)) + makedirs(py_lib_path) + for py in ['botan.py']: + copy_file(os.path.join(cfg['python_dir'], py), os.path.join(py_lib_path, py)) shutil.rmtree(target_doc_dir, True) shutil.copytree(cfg['doc_output_dir'], target_doc_dir) diff --git a/src/scripts/website.sh b/src/scripts/website.sh index 525b2fcca..5b7e1c6cb 100755 --- a/src/scripts/website.sh +++ b/src/scripts/website.sh @@ -12,8 +12,8 @@ rm -rf $WEBSITE_SRC_DIR $WEBSITE_DIR mkdir -p $WEBSITE_SRC_DIR cp readme.rst $WEBSITE_SRC_DIR/index.rst -cp -r doc/news.rst $WEBSITE_SRC_DIR -echo -e ".. toctree::\n\n index\n news\n" > $WEBSITE_SRC_DIR/contents.rst +cp -r doc/news.rst doc/security.rst $WEBSITE_SRC_DIR +echo -e ".. toctree::\n\n index\n news\n security\n" > $WEBSITE_SRC_DIR/contents.rst sphinx-build -t website -c "$SPHINX_CONFIG" -b "$SPHINX_BUILDER" $WEBSITE_SRC_DIR $WEBSITE_DIR sphinx-build -t website -c "$SPHINX_CONFIG" -b "$SPHINX_BUILDER" doc/manual $WEBSITE_DIR/manual diff --git a/src/tests/catchy/catchy_tests.h b/src/tests/catchy/catchy_tests.h index 99ad03f31..ab621d0f9 100644 --- a/src/tests/catchy/catchy_tests.h +++ b/src/tests/catchy/catchy_tests.h @@ -66,10 +66,10 @@ namespace Matchers { virtual ~Equals() override {} - virtual bool match( bool const& expr ) const { + virtual bool match( bool const& expr ) const override { return m_expected == expr; } - virtual std::string toString() const { + virtual std::string toString() const override { return "== " + Catch::toString(m_expected); } @@ -86,10 +86,10 @@ namespace Matchers { virtual ~Equals() override {} - virtual bool match( T const& expr ) const { + virtual bool match( T const& expr ) const override { return m_expected == expr; } - virtual std::string toString() const { + virtual std::string toString() const override { return "== " + Catch::toString(m_expected); } diff --git a/src/tests/data/pubkey/mce.vec b/src/tests/data/pubkey/mce.vec new file mode 100644 index 000000000..44817949b --- /dev/null +++ b/src/tests/data/pubkey/mce.vec @@ -0,0 +1,58 @@ + +McElieceSeed = C9A3649B5AC1AAFCE2E15B8C74FB0F2C776B10AB6C52F69AEB70700341479428 +KeyN = 1632 +KeyT = 33 +PublicKeyFingerprint = 2F5C0F9FF3E46D40E21AA4165B63DE2780F424438F9106D9C798801B7FAD05F5 +PrivateKeyFingerprint = 89AFCE27857051AF842A58FC903324414470AB0876A9FB8F739FB43485823CD9 +EncryptPRNGSeed = AABF99BAD11411A430D0AA2940148EE67D77DC44BE8734DA4A8B274561CBA2EC +SharedKey = A656D63F7FC8EF345AFBEE89B121BF5E45D301C5F5FF17DCDB227D84F22CF3D9DED9B00F5495B81CA41789549691BF4D6CF3E7069857E1CBFE9D63855949A89A +Ciphertext = E053B0773BDADE3C7625E108CC0B3746C36386E283F931970B7F4FE39F24498248458891A7843A843C4CAE3CAABB4CD0A80B1F944685A09CFFD944BFC9E41473769B8310E0BEED9E6C174E3C1E8A9E84A54C3120B5440B1F0F669830FAABA53FA2F00FD45CBC0522E647A5CDDC9135E805A88DCFB97ECAEEA2FF9577B2319F3828FB31C7D6470850DEC5B919FF5F3DC21C0BEC42DFADFDDE2675E03380222A480D0002B1C9D70F6C0A6D8F452FC556EDA9753C71BDC2DD530CE3314AB515F5118AD338A2165ED13DE0626707 + +McElieceSeed = C9A3649B5AC1AAFCE2E15B8C74FB0F2C776B10AB6C52F69AEB70700341479429 +KeyN = 2480 +KeyT = 45 +PublicKeyFingerprint = DDAC6EDF03B982E85FD60414E6C608F88694BB0C0FCCE99FCB044838E0C9CC9D +PrivateKeyFingerprint = 1949DFF555144AA0E2ED17CB4A3C71F4D7EEC1CCD9A3199D11E49BCA7FC81E4E +EncryptPRNGSeed = AABF99BAD11411A430D0AA2940148EE67D77DC44BE8734DA4A8B274561CBA2ED +SharedKey = 8F533C41E820EB0A6763FCC6AA88FE4FFFB2BAB1567639E8DB0E239CC4F595A1C6041B4EE3362D332A87FD81B9A81E413D4168CF67AE50519D2E5E698990CB0D +Ciphertext = 0CADE39676249382B1216579A4E4825325E13BE3198EDF913C4F35911DB3DD7CAE7D42158A9DC7599E2324B04A164E247BD5EA0CCDF964955AFF150561FB8CBB8A3FD712CEA114699FA2CEBC2CE837B1115D3E93819BBBB01785007B5380421266D8C3D2B802C8A4ECD5207EC675FFDBD8499A344E29E781A4E15C973D03130819D9B238A2596F68A59ED6628E49FE4ABEBAA5A0D4EACDA4DF1816F1C82F44025A2734FCE26FB7592B0BADF4D9FEDFAB37D54F2CA92D65A876D0E0F18A2FB586A80BD647D465190290FD856B1A8EED967BD77CD1637FD11655D1B135591A2D52B2D83E4A48B5777BB18D0E4D5E6392875AF9CF13B36AB4BBAE80073C8740B4987C3B28AC7778CFE6CDCE5E1ACBB05BB9E142B7C2239E1A41152F3617052D6EF96186CB6C2B4F684438CBA4F59954465466CD67E4457F + + +McElieceSeed = C9A3649B5AC1AAFCE2E15B8C74FB0F2C776B10AB6C52F69AEB70700341479430 +KeyN = 2960 +KeyT = 57 +PublicKeyFingerprint = 05707644DAE98856D432C24C19C41CDA333E36C04C81413E2D15E88EE129B4F7 +PrivateKeyFingerprint = 7BA1FEDF2E520945EC0321CE84F2A07B8407FFEC42EC715839AC0941BA1E9404 +EncryptPRNGSeed = AABF99BAD11411A430D0AA2940148EE67D77DC44BE8734DA4A8B274561CBA2EF +SharedKey = DEDFB2DBA755E94AD609F1DCA7F81D4BC5A39A4E07BF108D88A031F9E4CD2F46708EF1F9FDD27AAE56318928A5D89FA16C5F7F8D6ABF8019B549139E25142D2B +Ciphertext = AD9D75F29BD735082E95611DD8C1B9897FB35ABBA968AE8C66E99CECB679BB19344369404E73BA5C6549A8BFA25A2C3F90D3DC3C82E3B06815B0F02E013B3A9FB8EA9C38FEC8C61E58D260989D774DE0DBC8AE27A4C0B2AEAAC2EF43589A2F66D07FDA9B288C5F9DE5E9A59EB00A4C0A69581F7997830BAA9C6D77816DD78D574AD7BD732EA5A7F44E31FE6A30E4CC34896EB45D16C5227F3E31E1F3185614F5157F4D2B3A4B765BC9E3C24EC6D0AF02EDDDED78FB3874F0DAF7FF960FFF7E9445EEBE049200A43412AE99E16CB11BC7BD86BD61A0DB0402092E1D77153E24B5855D736125FDAE5957FBB79F7A5488CF53912681C80E58AF5DA31326A525342A60FAFD1B06E350A01209F7F77FCA2D66B13F17EC8880247F1B975F70A3CC96B5B90F418DE14D445BFC4897FAAFF52931306E84980B23F5D632AF0437AFBD4E6AF672B51AA2862BBDA3340EE77F2FDC4BEE06DB41592136549B55721CDD14FE06F475175EA15598EC65274B02D7D183A66622 + +McElieceSeed = C9A3649B5AC1AAFCE2E15B8C74FB0F2C776B10AB6C52F69AEB70700341479431 +KeyN = 3408 +KeyT = 67 +PublicKeyFingerprint = 87D94945188A898EFE3F62DDBB083DED2FAF74D83614F811DEE44ED1195B8DD4 +PrivateKeyFingerprint = D774748F55B9678D21A4234CF4141C073F5A389D52B64497E517EEE447B1762C +EncryptPRNGSeed = AABF99BAD11411A430D0AA2940148EE67D77DC44BE8734DA4A8B274561CBA2EF +SharedKey = E958F5A7EC2E284927BA6678169343359FE0768F9D1B2C0BDABA2D6E22FBD46BAE9C9FF0DA8238D2AAF9A125CC60F2FC757C47987850293934303D206DFBE06C +Ciphertext = AD9D75F09BD635082EB5611DD9C1E9897FB35E33E168AE0C66E9DCECA679BB19344369484E73AA5E6549A8BFA25A2C5F90D3D43C82E3B4681790F02E017B3A8FB8EA9C38FEC8C60E58D270989F774DE0DB48AE37A4C0B28EAAC2EF43589A0F66D07F5A9B2888DF9DE5E9A59EB00A4C0A6B581F7997838BAA9C6D67814DD68D574AD7BD732EA5A7F44C31FE6E30E4CC34896EB47D5685227F3E31C1D35A5614F5157F4D6B324B7E59C9E3C34CC6D0AF02EDDCEF78FB3874F2DAF7FF9607FF7E9445EEBE049210A53412AF99C16CB11BC7BD8EBD61A0FB0402896F1D57153E243585DD7B6125FDBE5957FBB79F7A5488CF13952681C00E59AF5DA31326A525142A60FAFD5B06E350A41209F7F77FC22D66B12F13EC8A80207B1B975F70F26A400CCCFC8A4AE20053EF1F8A3E7D2099AFE09A5812D50191461CABADE85E2249BFC78509CD45655AA1CBDF37707634F95A3818629AB4BA13AA3C2D78937CD05B38AFA01FADD1E7C558A5BEA03A022E7A61A7CCEDF3F78C12C888DFF3442033797CCECDC6A7006BFA1E5F17F23E4396DD5E18A324394E30A4B508D511E55C14DD89296085904E280D1E71970E + +McElieceSeed = 31C9A3649B5AC1AAFCE2E15B8C74FB0F2C776B10AB6C52F69AEB707003414794 +KeyN = 4624 +KeyT = 95 +PublicKeyFingerprint = E37CF72DE6ECD0E540316C1F4BC6F0391983D4E7B60C8ED13DCA801EEFA9A4E9 +PrivateKeyFingerprint = CDD13DFD3B067DE0A50D37C7CE97CF30E5024CDEF6A20043C09F81219B14B03E +EncryptPRNGSeed = CCBF99BAD11411A430D0AA2940148EE67D77DC44BE8734DA4A8B274561CBA22E +SharedKey = 8102784D063499813404A5FBEE50D64122E2C46217C9BAA76AE9021479B0E36D026809C8AEE2443772CEA7C13335017F9825E8BBA67D13786930C474771673FB +Ciphertext = BE6802091325EF912BC47FC694A0E26F015700F5987C057A70F2D984D3FF589FD6A3DC541912AF4DEA19F6A1C155972578CEA9F5C3A5AD02F85E28E5667FF129222A9585B85FD25A956A572487FBF3B62BBB0A96D360336D4DCBBBD194FC352837028C97F63C6BEBAC5D76A36968DD384F9F884594566E833AB87A8B9EEE5AA0CC9F0D45BE5E61C98C57DD52487F7EFD0AB085EB6D2DA652F7F1BAF6700EA52265412DBA0098B8055C82A46A43C7E89734371ADFB0FFD24D450BE5CE2477BC79BB2F6D85017289C582576AB95CCA9D3B10C4C60111AC9CEDE47294F476CEEF7611A189A5866151A6BA5EB6C362FB6F5A32CF930EFD9ED0CBD110D47060330AB71D9AB00403BF1CF7CDACFA2B1F373FF11B05E3820C93F6BD9D118161A585587A91AF356EF8254CD4CC2CEED87DE3724DDD5F2BDCFB0B75D230779A0D9E4AED49D630ACCFEC81DBF94064A21197BAC57AFFB2D82A637F36F7E64B7336B98288C65EAF18E37B0F8C06457BDA61FA3931480296BB32AACCECEC08E0FF6705352EA69BF12E64C1E6F837E857465148174915E1F1E7714739BED8133FB638ACC6F0D49392080B9E54E7386B430F6BC06DE38C2C92C351B7FCD7F247CB793DBB4E9430F8184C50213C02A9B32B7034A6E30B59CEEFCFA57DB0FE122F7B5A1B9D3EB290BCA9FDB9A2DF9C1638CE3AD84CA2267613D503F210A1A23E5B98B1CE1314FACDBC9C2D45278C312F9CC1A00CFC5086676ED2E9A67965F23D157C350DCFFD98511A4853F3BE54F5109B3D9C98EBB6558E14A427BE6AC73158454E5DDFA402CA3C2E45 + +McElieceSeed = 31C9A3649B5AC1AAFCE2E15B8C74FB0F2C776B10AB6C52F69AEB707003414795 +KeyN = 6624 +KeyT = 115 +PublicKeyFingerprint = 29A7BE3A3181534ABD5FF006EB8D5CCE71FDD27E0FD62E774A3C75C20BE84268 +PrivateKeyFingerprint = AA75AFB38ADA856FBEE6C973D53DF0AD07395C54AE83805BE59D57112A9EF6A3 +EncryptPRNGSeed = CCBF99BAD11411A430D0AA2940148EE67D77DC44BE8734DA4A8B274561CBA22F +SharedKey = F50F3E58A4788C03C44DBDE2C61ACC97A7CA8ADC6CC1D371416A7D6250BB3DD7526C55E666C9FCA31ADC5FA79CBEF72AA24B5BDC5F2E7AD255A0091A0DB7D127 +Ciphertext = 4A69DFA02182A20C59FD3D1291D110749C4BA57F38CE66D90485588C2CC4E1548180E9CBB58517479B978DF62A9B4E583D2D1C9BA3E61EDCF4D0249C54160E8547B8A91C5A2FE0E00FE95EF18FC865BFCD39EEE81DD79CAC36885AD2454FCFF4AB740CABD34563E08FA203FF96CEEF5E4FBA43DEC6C316E503B033DD4034F0E432DF646833603EEB8693843727F9F007CD78300A434BD379AA64BC1E1A04282C0BC23ACC6316DBC4919EFD123E4C87BF45F56E43C440453F85F93B014AEEB36CA0DCF9A7543C16C47625057B22A5E6E5681E3C2919225466DF16A32D32D475DF842E4D85C23DD9BD49BAC8D759B96FCBA00086095B7E3CCA2FD30AB884948003CDD64FD1E68AA7B36B2B740BAE029794193284AA4C1CF6DFC2916D2EA1AA20B64A81EEEF815456E260B77DC20C900F874E47962B0995E33A0832ED458EABDAE495B21178EDCBD3A973668E9C8F171139168B1AC442A387C9AA3D1ED9A6583A807BBCBF1A1A94E04B7638695D6F0C09F18B0732A2B5F4111C0D5F84E2F175280DE43525AEE72C036932927B3DDC4FD526B9DBD117C9CD37D64B0F77C103644FD7073977BB69F7367417E79D6A901686DB00E8E7C16C889E566CFB44D1C66E9C84251CB9CAFFB6FCA9B88999B08F8EC6203DEAF668E86689621D5BD56A1FB89623E2388FC93A92F9269ED2ADB70BC92E5F77D1DFE8805039F71A8132535110D1F1E4384BD2C21817DBB7D03DD88035D154106E2E3F7E1C3D4BD15C7F5AE469AC8BD016F98C9B01A66B8D8A0F72C7C9C176C2AEDC967B9AB4FCBF0FD99D0BEF8B151B224DCDA3691885414BC36B3707D2C97D44EE9F83A4F2F194E57533B16FBE673176E1FFC21C9F9A35AB35BDF94B9FDDDA179D035AA282DEE80DBC55489C6DE676C2B6D24790CCC15044AE952CACE8E7B4AA75C51632ACB52F75EE6A660979C46E89354C92C1FE60BDB7140BAAF7D22CAB8FC8865A1FA070416A28FEF51262E27E5F7C06CB46D68682BF2731014BB17CD18940563818EBA720A85A78E08491E7379E071A7B92253DF2BF6A8C14473D7247B81CBD565057BBF45116F1AD2045C6685257C39B12764DD0AAF8A9857D35960E41E44985DA2CC4E4A06D26157E01BAC866E40A3C1B28DED234129B89DEE47A2E22724F766876E6986B8C65 + + + diff --git a/src/tests/test_bigint.cpp b/src/tests/test_bigint.cpp index 7bac56bc7..e6aa4a434 100644 --- a/src/tests/test_bigint.cpp +++ b/src/tests/test_bigint.cpp @@ -31,55 +31,6 @@ using namespace Botan; namespace { -class Test_State - { - public: - void started(const std::string& /*msg*/) { m_tests_run++; } - - void test_ran(const char* msg); - - void failure(const char* test, const std::string& what_failed) - { - std::cout << "FAIL " << test << " " << what_failed << "\n"; - m_tests_failed++; - } - - size_t ran() const { return m_tests_run; } - size_t failed() const { return m_tests_failed; } - private: - size_t m_tests_run = 0, m_tests_failed = 0; - }; - -#define BOTAN_CONFIRM_NOTHROW(block) do { \ - try { block } \ - catch(std::exception& e) { \ - _test.failure(BOTAN_CURRENT_FUNCTION, e.what()); \ - } } while(0) \ - -#define BOTAN_TEST(lhs, rhs, msg) do { \ - _test.started(msg); \ - BOTAN_CONFIRM_NOTHROW({ \ - const auto lhs_val = lhs; \ - const auto rhs_val = rhs; \ - const bool cmp = lhs_val == rhs_val; \ - if(!cmp) \ - { \ - std::ostringstream fmt; \ - fmt << "expr '" << #lhs << " == " << #rhs << "' false, " \ - << "actually " << lhs_val << " " << rhs_val \ - << " (" << msg << ")"; \ - _test.failure(BOTAN_CURRENT_FUNCTION, fmt.str()); \ - } \ - }); \ - } while(0) - -#define BOTAN_TEST_CASE(name, descr, block) size_t test_ ## name() { \ - Test_State _test; \ - BOTAN_CONFIRM_NOTHROW(block); \ - test_report(descr, _test.ran(), _test.failed()); \ - return _test.failed(); \ - } - BOTAN_TEST_CASE(bigint_to_u32bit, "BigInt to_u32bit", { for(size_t i = 0; i != 32; ++i) { diff --git a/src/tests/test_block.cpp b/src/tests/test_block.cpp index 509cf1c0c..b688ec84e 100644 --- a/src/tests/test_block.cpp +++ b/src/tests/test_block.cpp @@ -7,7 +7,6 @@ #include "tests.h" #include <botan/block_cipher.h> -#include <botan/lookup.h> #include <botan/hex.h> #include <iostream> #include <fstream> @@ -25,15 +24,18 @@ size_t block_test(const std::string& algo, const secure_vector<byte> pt = hex_decode_locked(in_hex); const secure_vector<byte> ct = hex_decode_locked(out_hex); - const std::vector<std::string> providers = get_block_cipher_providers(algo); + const std::vector<std::string> providers = BlockCipher::providers(algo); size_t fails = 0; if(providers.empty()) - throw std::runtime_error("Unknown block cipher " + algo); + { + std::cout << "Unknown block cipher " + algo + " skipping test\n"; + return 0; + } for(auto provider: providers) { - std::unique_ptr<BlockCipher> cipher(get_block_cipher(algo, provider)); + std::unique_ptr<BlockCipher> cipher(BlockCipher::create(algo, provider)); if(!cipher) { diff --git a/src/tests/test_compression.cpp b/src/tests/test_compression.cpp index b68262385..902455fc7 100644 --- a/src/tests/test_compression.cpp +++ b/src/tests/test_compression.cpp @@ -93,12 +93,15 @@ size_t test_compression() const size_t text_len = strlen(text_str); + const secure_vector<byte> empty; const secure_vector<byte> all_zeros(text_len, 0); const secure_vector<byte> random_binary = test_rng().random_vec(text_len); const byte* textb = reinterpret_cast<const byte*>(text_str); const secure_vector<byte> text(textb, textb + text_len); + const size_t c1_e = run_compression(*c1, *d, empty); + const size_t c9_e = run_compression(*c9, *d, empty); const size_t c1_z = run_compression(*c1, *d, all_zeros); const size_t c9_z = run_compression(*c9, *d, all_zeros); const size_t c1_r = run_compression(*c1, *d, random_binary); @@ -108,6 +111,10 @@ size_t test_compression() #define BOTAN_TEST_GTE(x, y, msg) if(x < y) { ++fails; std::cout << "FAIL: " << x << " " << y << " " << msg << std::endl; } + BOTAN_TEST_GTE(c1_e, 1, "Empty input compresses to non-empty output"); + BOTAN_TEST_GTE(c9_e, 1, "Empty input compresses to non-empty output"); + + BOTAN_TEST_GTE(c1_e, c9_e, "Level 9 compresses at least as well as level 1"); BOTAN_TEST_GTE(c1_z, c9_z, "Level 9 compresses at least as well as level 1"); BOTAN_TEST_GTE(c1_t, c9_t, "Level 9 compresses at least as well as level 1"); BOTAN_TEST_GTE(c1_r, c9_r, "Level 9 compresses at least as well as level 1"); diff --git a/src/tests/test_dlies.cpp b/src/tests/test_dlies.cpp index f282a9387..bf367efb8 100644 --- a/src/tests/test_dlies.cpp +++ b/src/tests/test_dlies.cpp @@ -19,7 +19,6 @@ #include <botan/dh.h> #include <botan/hex.h> #include <botan/pubkey.h> -#include <botan/lookup.h> using namespace Botan; @@ -54,13 +53,13 @@ size_t dlies_kat(const std::string& p, const size_t mac_key_len = to_u32bit(options[2]); DLIES_Encryptor e(from, - get_kdf(options[0]), - get_mac(options[1]), + KDF::create(options[0]).release(), + MessageAuthenticationCode::create(options[1]).release(), mac_key_len); DLIES_Decryptor d(to, - get_kdf(options[0]), - get_mac(options[1]), + KDF::create(options[0]).release(), + MessageAuthenticationCode::create(options[1]).release(), mac_key_len); e.set_other_key(to.public_value()); diff --git a/src/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp index a2ec8d115..1e8dcb7d7 100644 --- a/src/tests/test_ecdsa.cpp +++ b/src/tests/test_ecdsa.cpp @@ -25,7 +25,6 @@ size_t ecdsa_sig_kat(const std::string& group_id, const std::string& x, const std::string& hash, const std::string& msg, - const std::string& nonce, const std::string& signature) { auto& rng = test_rng(); @@ -35,11 +34,11 @@ size_t ecdsa_sig_kat(const std::string& group_id, const std::string padding = "EMSA1(" + hash + ")"; - PK_Verifier verify(ecdsa, padding); - PK_Signer sign(ecdsa, padding); + PK_Verifier verify(ecdsa, padding, IEEE_1363, "base"); + PK_Signer sign(ecdsa, padding, IEEE_1363, "base"); - return validate_signature(verify, sign, "ECDSA/" + group_id + '/' + hash, - msg, rng, nonce, signature); + return validate_signature(verify, sign, "ECDSA/" + group_id + "/" + hash, + msg, rng, signature); } } @@ -53,7 +52,7 @@ size_t test_ecdsa() fails += run_tests_bb(ecdsa_sig, "ECDSA Signature", "Signature", false, [](std::map<std::string, std::string> m) -> size_t { - return ecdsa_sig_kat(m["Group"], m["X"], m["Hash"], m["Msg"], m["Nonce"], m["Signature"]); + return ecdsa_sig_kat(m["Group"], m["X"], m["Hash"], m["Msg"], m["Signature"]); }); return fails; diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp index 297351a98..edc06f90a 100644 --- a/src/tests/test_ffi.cpp +++ b/src/tests/test_ffi.cpp @@ -152,15 +152,14 @@ TEST_CASE("FFI PBKDF", "[ffi]") passphrase.c_str(), salt.data(), salt.size(), 100, &iters_100ms), Equals(0)); + CHECK(iters_10ms >= 10000); + /* * Tests deactivated due to consistetly failing in debug mode where -W0 is set * (./configure.py --build-mode=debug). * See also: https://github.com/randombit/botan/commit/30b0e3c88e94ba04c1843798f7ac74a008e01d9b */ - /* - CHECK(iters_10ms >= 10000); - INFO("Iterations " << iters_10ms << " " << iters_100ms); const double ratio = static_cast<double>(iters_100ms) / iters_10ms; // Loose timing to avoid false positives on CI @@ -194,7 +193,7 @@ TEST_CASE("FFI bcrypt", "[ffi]") CHECK_THAT(botan_bcrypt_generate(outbuf.data(), &ol, "password", rng, 10, 0), Equals(0)); botan_rng_destroy(rng); - CHECK_THAT(botan_bcrypt_is_valid("wrong", reinterpret_cast<const char*>(outbuf.data())), Equals(1)); + REQUIRE(botan_bcrypt_is_valid("wrong", reinterpret_cast<const char*>(outbuf.data())) < 0); CHECK_THAT(botan_bcrypt_is_valid("password", reinterpret_cast<const char*>(outbuf.data())), Equals(0)); } @@ -347,9 +346,9 @@ TEST_CASE("FFI ECDH", "[ffi]") botan_rng_init(&rng, "system"); botan_privkey_t priv1; - CHECK_THAT(botan_privkey_create_ecdh(&priv1, rng, "secp256r1"), Equals(0)); + REQUIRE_THAT(botan_privkey_create_ecdh(&priv1, rng, "secp256r1"), Equals(0)); botan_privkey_t priv2; - CHECK_THAT(botan_privkey_create_ecdh(&priv2, rng, "secp256r1"), Equals(0)); + REQUIRE_THAT(botan_privkey_create_ecdh(&priv2, rng, "secp256r1"), Equals(0)); botan_pubkey_t pub1; CHECK_THAT(botan_privkey_export_pubkey(&pub1, priv1), Equals(0)); @@ -357,9 +356,9 @@ TEST_CASE("FFI ECDH", "[ffi]") CHECK_THAT(botan_privkey_export_pubkey(&pub2, priv2), Equals(0)); botan_pk_op_ka_t ka1; - CHECK_THAT(botan_pk_op_key_agreement_create(&ka1, priv1, "KDF2(SHA-256)", 0), Equals(0)); + REQUIRE_THAT(botan_pk_op_key_agreement_create(&ka1, priv1, "KDF2(SHA-256)", 0), Equals(0)); botan_pk_op_ka_t ka2; - CHECK_THAT(botan_pk_op_key_agreement_create(&ka2, priv2, "KDF2(SHA-256)", 0), Equals(0)); + REQUIRE_THAT(botan_pk_op_key_agreement_create(&ka2, priv2, "KDF2(SHA-256)", 0), Equals(0)); std::vector<uint8_t> pubkey1(256); // length problem again size_t pubkey1_len = pubkey1.size(); @@ -372,7 +371,7 @@ TEST_CASE("FFI ECDH", "[ffi]") pubkey2.resize(pubkey2_len); std::vector<uint8_t> salt(32); - CHECK_THAT(botan_rng_get(rng, salt.data(), salt.size()), Equals(0)); + REQUIRE_THAT(botan_rng_get(rng, salt.data(), salt.size()), Equals(0)); const size_t shared_key_len = 64; diff --git a/src/tests/test_fuzzer.cpp b/src/tests/test_fuzzer.cpp index 212a313a8..f2343dc1f 100644 --- a/src/tests/test_fuzzer.cpp +++ b/src/tests/test_fuzzer.cpp @@ -8,61 +8,72 @@ #include <chrono> #include <iostream> -#if defined(BOTAN_HAS_X509_CERTIFICATES) +#include <botan/internal/filesystem.h> +#if defined(BOTAN_HAS_X509_CERTIFICATES) #include <botan/x509cert.h> #include <botan/x509_crl.h> -#include <botan/internal/filesystem.h> #include <botan/base64.h> - #endif +using namespace Botan; + namespace { +const std::string TEST_DATA_DIR_FUZZ_X509 = TEST_DATA_DIR "/fuzz/x509"; + +#if defined(BOTAN_HAS_X509_CERTIFICATES) size_t test_x509_fuzz() { size_t fails = 0; - -#if defined(BOTAN_HAS_X509_CERTIFICATES) - size_t tests = 0; - const std::string fuzz_data = TEST_DATA_DIR "/fuzz"; - for(auto vec: Botan::get_files_recursive(fuzz_data + "/x509")) + try { - ++tests; - - auto start = std::chrono::system_clock::now(); - try + for(auto vec_file: get_files_recursive(TEST_DATA_DIR_FUZZ_X509)) { - // TODO: check for memory consumption? - Botan::X509_Certificate cert(vec); + ++tests; + + auto start = std::chrono::steady_clock::now(); + try + { + // TODO: check for memory consumption? + X509_Certificate cert(vec_file); + } + catch(std::exception& e) + { + //std::cout << e.what() << "\n"; + } + auto end = std::chrono::steady_clock::now(); + + uint64_t duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); + + if(duration > 100) + { + std::cout << "Fuzzer test " << vec_file << " took " << duration << " ms" << std::endl; + } } - catch(std::exception& e) - { - //std::cout << e.what() << "\n"; - } - auto end = std::chrono::system_clock::now(); - - uint64_t duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); - if(duration > 100) - { - std::cout << "Fuzzer test " << vec << " took " << duration << " ms" << std::endl; - } + test_report("Fuzzer checks", tests, fails); + } + catch(No_Filesystem_Access) + { + std::cout << "Warning: No filesystem access available to read test files in '" + << TEST_DATA_DIR_FUZZ_X509 << "'" << std::endl; + return 0; } - - test_report("Fuzzer checks", tests, fails); -#endif return fails; } +#endif } size_t test_fuzzer() { size_t fails = 0; +#if defined(BOTAN_HAS_X509_CERTIFICATES) fails += test_x509_fuzz(); +#endif return fails; } diff --git a/src/tests/test_gf2m.cpp b/src/tests/test_gf2m.cpp new file mode 100644 index 000000000..7557672a6 --- /dev/null +++ b/src/tests/test_gf2m.cpp @@ -0,0 +1,46 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "tests.h" + +#if defined(BOTAN_HAS_MCELIECE) + +#include <botan/gf2m_small_m.h> + +BOTAN_TEST_CASE(gf2m, "GF(2^m)", { + + using namespace Botan; + + for(size_t degree = 2; degree <= 16; ++degree) + { + GF2m_Field field(degree); + + for(size_t i = 0; i <= field.gf_ord(); ++i) + { + gf2m a = i; + + BOTAN_TEST(field.gf_square(a), field.gf_mul(a, a), "Square and multiply"); + + /* + * This sequence is from the start of gf2m_decomp_rootfind_state::calc_Fxj_j_neq_0 + */ + { + const gf2m jl_gray = field.gf_l_from_n(a); + gf2m xl_j_tt_5 = field.gf_square_rr(jl_gray); + const gf2m xl_gray_tt_3 = field.gf_mul_rrr(xl_j_tt_5, jl_gray); + xl_j_tt_5 = field.gf_mul_rrr(xl_j_tt_5, xl_gray_tt_3); + gf2m s = field.gf_mul_nrr(xl_gray_tt_3, field.gf_ord()); + BOTAN_CONFIRM(s <= field.gf_ord(), "Less than order"); + } + } + } + }); + +#else + +SKIP_TEST(gf2m); + +#endif diff --git a/src/tests/test_hash.cpp b/src/tests/test_hash.cpp index a69ba3ef3..42ffcc11a 100644 --- a/src/tests/test_hash.cpp +++ b/src/tests/test_hash.cpp @@ -6,7 +6,6 @@ #include "tests.h" -#include <botan/lookup.h> #include <botan/hash.h> #include <botan/hex.h> #include <iostream> @@ -22,17 +21,17 @@ size_t hash_test(const std::string& algo, { size_t fails = 0; - const std::vector<std::string> providers = get_hash_function_providers(algo); + const std::vector<std::string> providers = HashFunction::providers(algo); if(providers.empty()) { std::cout << "Unknown hash '" << algo << "'" << std::endl; - ++fails; + return 0; } for(auto provider: providers) { - std::unique_ptr<HashFunction> hash(get_hash(algo, provider)); + std::unique_ptr<HashFunction> hash(HashFunction::create(algo, provider)); if(!hash) { diff --git a/src/tests/test_kdf.cpp b/src/tests/test_kdf.cpp index 65814f0d6..30541d459 100644 --- a/src/tests/test_kdf.cpp +++ b/src/tests/test_kdf.cpp @@ -9,7 +9,6 @@ #if defined(BOTAN_HAS_KDF_BASE) #include <botan/kdf.h> -#include <botan/lookup.h> #include <botan/hex.h> #include <iostream> #include <fstream> diff --git a/src/tests/test_mac.cpp b/src/tests/test_mac.cpp index 6ab87274f..e161e5921 100644 --- a/src/tests/test_mac.cpp +++ b/src/tests/test_mac.cpp @@ -8,7 +8,6 @@ #if defined(BOTAN_HAS_MAC) -#include <botan/lookup.h> #include <botan/mac.h> #include <botan/hex.h> #include <iostream> @@ -23,18 +22,18 @@ size_t mac_test(const std::string& algo, const std::string& in_hex, const std::string& out_hex) { - const std::vector<std::string> providers = get_mac_providers(algo); + const std::vector<std::string> providers = MessageAuthenticationCode::providers(algo); size_t fails = 0; if(providers.empty()) { std::cout << "Unknown algo " << algo << std::endl; - ++fails; + return 0; } for(auto provider: providers) { - std::unique_ptr<MessageAuthenticationCode> mac(get_mac(algo, provider)); + std::unique_ptr<MessageAuthenticationCode> mac(MessageAuthenticationCode::create(algo, provider)); if(!mac) { diff --git a/src/tests/test_mce.cpp b/src/tests/test_mce.cpp new file mode 100644 index 000000000..dbe5cc046 --- /dev/null +++ b/src/tests/test_mce.cpp @@ -0,0 +1,104 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "tests.h" + +#if defined(BOTAN_HAS_MCELIECE) + +#include <botan/mceliece.h> +#include <botan/mce_kem.h> +#include <botan/hmac_drbg.h> +#include <botan/hash.h> +#include <botan/hex.h> +#include <iostream> +#include <fstream> + +using namespace Botan; + +namespace { + +std::string hash_bytes(const byte b[], size_t len) + { + std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-256")); + hash->update(b, len); + return hex_encode(hash->final()); + } + +template<typename A> +std::string hash_bytes(const std::vector<byte, A>& v) + { + return hash_bytes(v.data(), v.size()); + } + +size_t mce_test(const std::string& key_seed_hex, + size_t n, size_t t, + const std::string& exp_fingerprint_pub, + const std::string& exp_fingerprint_priv, + const std::string& encrypt_rng_seed_hex, + const std::string& ct_hex, + const std::string& shared_key_hex) + { + const secure_vector<byte> keygen_seed = hex_decode_locked(key_seed_hex); + const secure_vector<byte> encrypt_seed = hex_decode_locked(encrypt_rng_seed_hex); + + Test_State _test; + + HMAC_DRBG rng("HMAC(SHA-384)"); + + rng.add_entropy(keygen_seed.data(), keygen_seed.size()); + + McEliece_PrivateKey mce_priv(rng, n, t); + + const std::string f_pub = hash_bytes(mce_priv.x509_subject_public_key()); + const std::string f_priv = hash_bytes(mce_priv.pkcs8_private_key()); + + BOTAN_TEST(f_pub, exp_fingerprint_pub, "Public fingerprint"); + BOTAN_TEST(f_priv, exp_fingerprint_priv, "Private fingerprint"); + + rng.clear(); + rng.add_entropy(encrypt_seed.data(), encrypt_seed.size()); + + McEliece_KEM_Encryptor kem_enc(mce_priv); + McEliece_KEM_Decryptor kem_dec(mce_priv); + + const std::pair<secure_vector<byte>,secure_vector<byte> > ciphertext__sym_key = kem_enc.encrypt(rng); + const secure_vector<byte>& ciphertext = ciphertext__sym_key.first; + const secure_vector<byte>& sym_key_encr = ciphertext__sym_key.second; + + const secure_vector<byte> sym_key_decr = kem_dec.decrypt(ciphertext.data(), ciphertext.size()); + + BOTAN_TEST(ct_hex, hex_encode(ciphertext), "Ciphertext"); + BOTAN_TEST(hex_encode(sym_key_encr), shared_key_hex, "Encrypted key"); + BOTAN_TEST(hex_encode(sym_key_decr), shared_key_hex, "Decrypted key"); + + return _test.failed(); + } + +} + +size_t test_mce() + { + + std::ifstream vec(TEST_DATA_DIR "/pubkey/mce.vec"); + return run_tests_bb(vec, "McElieceSeed", "Ciphertext", true, + [](std::map<std::string, std::string> m) -> size_t + { + return mce_test(m["McElieceSeed"], + to_u32bit(m["KeyN"]), + to_u32bit(m["KeyT"]), + m["PublicKeyFingerprint"], + m["PrivateKeyFingerprint"], + m["EncryptPRNGSeed"], + m["Ciphertext"], + m["SharedKey"]); + }); + } + +#else + +SKIP_TEST(mce); + +#endif diff --git a/src/tests/test_mceliece.cpp b/src/tests/test_mceliece.cpp index 616f64be9..fc20d93f7 100644 --- a/src/tests/test_mceliece.cpp +++ b/src/tests/test_mceliece.cpp @@ -13,6 +13,7 @@ #include <botan/pubkey.h> #include <botan/oids.h> #include <botan/mceliece.h> +#include <botan/internal/code_based_util.h> #include <botan/mce_kem.h> #include <botan/loadstor.h> #include <botan/hex.h> @@ -32,35 +33,6 @@ namespace { const size_t MCE_RUNS = 5; -size_t test_mceliece_message_parts(RandomNumberGenerator& rng, size_t code_length, size_t error_weight) - { - secure_vector<gf2m> err_pos1 = create_random_error_positions(code_length, error_weight, rng); - secure_vector<byte> message1((code_length+7)/8); - rng.randomize(message1.data(), message1.size() - 1); - mceliece_message_parts parts1(err_pos1, message1, code_length); - secure_vector<byte> err_vec1 = parts1.get_error_vector(); - - secure_vector<byte> concat1 = parts1.get_concat(); - - mceliece_message_parts parts2( concat1.data(), concat1.size(), code_length); - - secure_vector<byte> err_vec2 = parts2.get_error_vector(); - if(err_vec1 != err_vec2) - { - std::cout << "error with error vector from message parts" << std::endl; - return 1; - } - - secure_vector<byte> message2 = parts2.get_message_word(); - if(message1 != message2) - { - std::cout << "error with message word from message parts" << std::endl; - return 1; - } - - return 0; - } - size_t test_mceliece_kem(const McEliece_PrivateKey& sk, const McEliece_PublicKey& pk, RandomNumberGenerator& rng) @@ -83,50 +55,26 @@ size_t test_mceliece_kem(const McEliece_PrivateKey& sk, std::cout << "mce KEM test failed, error during encryption/decryption" << std::endl; ++fails; } - -#if 0 - // takes a long time: - for(size_t j = 0; j < code_length; j++) - { - // flip the j-th bit in the ciphertext - secure_vector<byte> wrong_ct(ciphertext); - size_t byte_pos = j/8; - size_t bit_pos = j % 8; - wrong_ct[byte_pos] ^= 1 << bit_pos; - try - { - secure_vector<byte> decrypted = priv_op.decrypt(wrong_ct.data(), wrong_ct.size()); - } - catch(const Integrity_Failure) - { - continue; - } - std::cout << "manipulation in ciphertext not detected" << std::endl; - err_cnt++; - } -#endif - } return fails; } +/* size_t test_mceliece_raw(const McEliece_PrivateKey& sk, const McEliece_PublicKey& pk, RandomNumberGenerator& rng) { const size_t code_length = pk.get_code_length(); McEliece_Private_Operation priv_op(sk); - McEliece_Public_Operation pub_op(pk, code_length); + McEliece_Public_Operation pub_op(pk); size_t err_cnt = 0; for(size_t i = 0; i != MCE_RUNS; i++) { - secure_vector<byte> plaintext((pk.get_message_word_bit_length()+7)/8); - rng.randomize(plaintext.data(), plaintext.size() - 1); + const secure_vector<byte> plaintext = pk.random_plaintext_element(rng); secure_vector<gf2m> err_pos = create_random_error_positions(code_length, pk.get_t(), rng); - mceliece_message_parts parts(err_pos, plaintext, 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); @@ -152,12 +100,12 @@ size_t test_mceliece_raw(const McEliece_PrivateKey& sk, for(size_t j = 0; j < err_pos.size(); j++) std::printf("%u, ", err_pos[j]); printf("\n"); return 1; - continue; } } return err_cnt; } +*/ #if defined(BOTAN_HAS_MCEIES) size_t test_mceies(const McEliece_PrivateKey& sk, @@ -173,8 +121,8 @@ size_t test_mceies(const McEliece_PrivateKey& sk, const size_t ad_len = sizeof(ad); const secure_vector<byte> pt = rng.random_vec(rng.next_byte()); - const secure_vector<byte> ct = mceies_encrypt(pk, pt, ad, ad_len, rng); - const secure_vector<byte> dec = mceies_decrypt(sk, ct, ad, ad_len); + const secure_vector<byte> ct = mceies_encrypt(pk, pt.data(), pt.size(), ad, ad_len, rng); + const secure_vector<byte> dec = mceies_decrypt(sk, ct.data(), ct.size(), ad, ad_len); if(pt != dec) { @@ -195,7 +143,7 @@ size_t test_mceies(const McEliece_PrivateKey& sk, try { - mceies_decrypt(sk, bad_ct, ad, ad_len); + mceies_decrypt(sk, bad_ct.data(), bad_ct.size(), ad, ad_len); std::cout << "Successfully decrypted manipulated ciphertext!" << std::endl; ++fails; } @@ -234,17 +182,6 @@ size_t test_mceliece() { //std::cout << "testing parameters n = " << code_length << ", t = " << t << std::endl; - try - { - fails += test_mceliece_message_parts(rng, code_length, t); - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - fails++; - } - tests += 1; - McEliece_PrivateKey sk1(rng, code_length, t); const McEliece_PublicKey& pk1 = sk1; @@ -274,17 +211,6 @@ size_t test_mceliece() try { - fails += test_mceliece_raw(sk, pk, rng); - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - fails++; - } - tests += 1; - - try - { fails += test_mceliece_kem(sk, pk, rng); } catch(std::exception& e) diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp index bfbb46355..f443ddabf 100644 --- a/src/tests/test_modes.cpp +++ b/src/tests/test_modes.cpp @@ -8,12 +8,8 @@ #if defined(BOTAN_HAS_MODES) -#if defined(BOTAN_HAS_FILTERS) - #include <botan/hex.h> -#include <botan/lookup.h> #include <botan/cipher_mode.h> -#include <botan/filters.h> #include <iostream> #include <fstream> #include <memory> @@ -28,21 +24,16 @@ secure_vector<byte> run_mode(const std::string& algo, const secure_vector<byte>& nonce, const secure_vector<byte>& key) { -#if 0 - std::unique_ptr<Cipher_Mode> cipher(get_cipher(algo, dir)); + std::unique_ptr<Cipher_Mode> cipher(get_cipher_mode(algo, dir)); + if(!cipher) + throw std::runtime_error("No cipher " + algo + " enabled in build"); cipher->set_key(key); cipher->start(nonce); secure_vector<byte> ct = pt; cipher->finish(ct); -#endif - - Pipe pipe(get_cipher(algo, SymmetricKey(key), InitializationVector(nonce), dir)); - - pipe.process_msg(pt); - - return pipe.read_all(); + return ct; } size_t mode_test(const std::string& algo, @@ -103,12 +94,6 @@ size_t test_modes() #else -UNTESTED_WARNING(modes); - -#endif // BOTAN_HAS_FILTERS - -#else - SKIP_TEST(modes); #endif // BOTAN_HAS_MODES diff --git a/src/tests/test_ocb.cpp b/src/tests/test_ocb.cpp index 4069625b5..891ecb54d 100644 --- a/src/tests/test_ocb.cpp +++ b/src/tests/test_ocb.cpp @@ -16,7 +16,6 @@ #include <botan/sha2_32.h> #include <botan/aes.h> #include <botan/loadstor.h> -#include <botan/lookup.h> using namespace Botan; @@ -63,9 +62,12 @@ size_t test_ocb_long(size_t keylen, size_t taglen, const std::string algo = "AES-" + std::to_string(keylen); - OCB_Encryption enc(get_block_cipher(algo), taglen / 8); + std::unique_ptr<BlockCipher> aes(BlockCipher::create(algo)); + if(!aes) + throw Algorithm_Not_Found(algo); - OCB_Decryption dec(get_block_cipher(algo), taglen / 8); + OCB_Encryption enc(aes->clone(), taglen / 8); + OCB_Decryption dec(aes->clone(), taglen / 8); std::vector<byte> key(keylen/8); key[keylen/8-1] = taglen; diff --git a/src/tests/test_pbkdf.cpp b/src/tests/test_pbkdf.cpp index 8f765fa1d..1f5a0a6a1 100644 --- a/src/tests/test_pbkdf.cpp +++ b/src/tests/test_pbkdf.cpp @@ -9,7 +9,6 @@ #if defined(BOTAN_HAS_PBKDF) #include <botan/pbkdf.h> -#include <botan/lookup.h> #include <botan/hex.h> #include <iostream> #include <fstream> diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp index c3f2017f6..09f3843bb 100644 --- a/src/tests/test_pubkey.cpp +++ b/src/tests/test_pubkey.cpp @@ -22,6 +22,7 @@ #include <botan/x509_key.h> #include <botan/pkcs8.h> #include <botan/pubkey.h> +#include <botan/hex.h> #if defined(BOTAN_HAS_RSA) #include <botan/rsa.h> @@ -64,8 +65,8 @@ #include <botan/kdf.h> #endif -#include <botan/filters.h> #include <botan/numthry.h> + using namespace Botan; namespace { @@ -73,12 +74,8 @@ namespace { void dump_data(const std::vector<byte>& out, const std::vector<byte>& expected) { - Pipe pipe(new Hex_Encoder); - - pipe.process_msg(out); - pipe.process_msg(expected); - std::cout << "Got: " << pipe.read_all_as_string(0) << std::endl; - std::cout << "Exp: " << pipe.read_all_as_string(1) << std::endl; + std::cout << "Got: " << hex_encode(out) << std::endl; + std::cout << "Exp: " << hex_encode(expected) << std::endl; } size_t validate_save_and_load(const Private_Key* priv_key, @@ -253,11 +250,7 @@ size_t validate_signature(PK_Verifier& v, PK_Signer& s, const std::string& algo, PK_TEST(v.verify_message(message, sig), "Correct signature is valid"); - zero_mem(sig.data(), sig.size()); - - PK_TEST(!v.verify_message(message, sig), "All-zero signature is invalid"); - - for(size_t i = 0; i != 3; ++i) + for(size_t i = 0; i != 5; ++i) { auto bad_sig = sig; @@ -267,6 +260,10 @@ size_t validate_signature(PK_Verifier& v, PK_Signer& s, const std::string& algo, PK_TEST(!v.verify_message(message, bad_sig), "Incorrect signature is invalid"); } + zero_mem(sig.data(), sig.size()); + + PK_TEST(!v.verify_message(message, sig), "All-zero signature is invalid"); + return fails; } diff --git a/src/tests/test_rng.cpp b/src/tests/test_rng.cpp index d129ed208..2eb8328ee 100644 --- a/src/tests/test_rng.cpp +++ b/src/tests/test_rng.cpp @@ -8,7 +8,6 @@ #include "tests.h" #include <botan/hex.h> -#include <botan/lookup.h> #include <iostream> #include <fstream> @@ -47,12 +46,13 @@ RandomNumberGenerator* get_rng(const std::string& algo_str, const std::string& i #if defined(BOTAN_HAS_HMAC_DRBG) if(rng_name == "HMAC_DRBG") - return new HMAC_DRBG(get_mac("HMAC(" + algo_name[1] + ")"), new AllOnce_RNG(ikm)); + return new HMAC_DRBG(MessageAuthenticationCode::create("HMAC(" + algo_name[1] + ")").release(), + new AllOnce_RNG(ikm)); #endif #if defined(BOTAN_HAS_X931_RNG) if(rng_name == "X9.31-RNG") - return new ANSI_X931_RNG(get_block_cipher(algo_name[1]), + return new ANSI_X931_RNG(BlockCipher::create(algo_name[1]).release(), new Fixed_Output_RNG(ikm)); #endif @@ -67,7 +67,10 @@ size_t x931_test(const std::string& algo, std::unique_ptr<RandomNumberGenerator> rng(get_rng(algo, ikm)); if(!rng) - throw std::runtime_error("Unknown RNG " + algo); + { + std::cout << "Unknown RNG " + algo + " skipping test\n"; + return 0; + } const std::string got = hex_encode(rng->random_vec(L)); @@ -87,7 +90,10 @@ size_t hmac_drbg_test(std::map<std::string, std::string> m) std::unique_ptr<RandomNumberGenerator> rng(get_rng(algo, ikm)); if(!rng) - throw std::runtime_error("Unknown RNG " + algo); + { + std::cout << "Unknown RNG " + algo + " skipping test\n"; + return 0; + } rng->reseed(0); // force initialization diff --git a/src/tests/test_rsa.cpp b/src/tests/test_rsa.cpp index 940525574..dcc741bd2 100644 --- a/src/tests/test_rsa.cpp +++ b/src/tests/test_rsa.cpp @@ -37,7 +37,7 @@ size_t rsaes_kat(const std::string& e, if(padding == "") padding = "Raw"; - PK_Encryptor_EME enc(pubkey, padding); + PK_Encryptor_EME enc(pubkey, padding, "base"); PK_Decryptor_EME dec(privkey, padding); return validate_encryption(enc, dec, "RSAES/" + padding, msg, nonce, output); @@ -61,7 +61,7 @@ size_t rsa_sig_kat(const std::string& e, padding = "Raw"; PK_Verifier verify(pubkey, padding); - PK_Signer sign(privkey, padding); + PK_Signer sign(privkey, padding, IEEE_1363, "base"); return validate_signature(verify, sign, "RSA/" + padding, msg, rng, nonce, output); } diff --git a/src/tests/test_stream.cpp b/src/tests/test_stream.cpp index 4828d44fd..d91d28d9b 100644 --- a/src/tests/test_stream.cpp +++ b/src/tests/test_stream.cpp @@ -9,7 +9,6 @@ #if defined(BOTAN_HAS_STREAM_CIPHER) #include <botan/stream_cipher.h> -#include <botan/lookup.h> #include <botan/hex.h> #include <iostream> #include <fstream> @@ -29,18 +28,18 @@ size_t stream_test(const std::string& algo, const secure_vector<byte> ct = hex_decode_locked(out_hex); const secure_vector<byte> nonce = hex_decode_locked(nonce_hex); - const std::vector<std::string> providers = get_stream_cipher_providers(algo); + const std::vector<std::string> providers = StreamCipher::providers(algo); size_t fails = 0; if(providers.empty()) { std::cout << "Unknown stream cipher " << algo << std::endl; - ++fails; + return 0; } for(auto provider: providers) { - std::unique_ptr<StreamCipher> cipher(get_stream_cipher(algo, provider)); + std::unique_ptr<StreamCipher> cipher(StreamCipher::create(algo, provider)); if(!cipher) { diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 63e6761ac..d213b6a3a 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -301,9 +301,12 @@ int main(int argc, char* argv[]) DEF_TEST(ecdsa); DEF_TEST(gost_3410); DEF_TEST(curve25519); + DEF_TEST(gf2m); DEF_TEST(mceliece); + DEF_TEST(mce); DEF_TEST(ecc_unit); + DEF_TEST(ecc_randomized); DEF_TEST(ecdsa_unit); DEF_TEST(ecdh_unit); DEF_TEST(pk_keygen); diff --git a/src/tests/tests.h b/src/tests/tests.h index 88102f289..6d6a2d34c 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -16,6 +16,7 @@ #include <string> #include <vector> #include <iostream> +#include <sstream> Botan::RandomNumberGenerator& test_rng(); @@ -45,7 +46,69 @@ typedef std::function<size_t ()> test_fn; size_t run_tests(const std::vector<std::pair<std::string, test_fn>>& tests); void test_report(const std::string& name, size_t ran, size_t failed); -#define TEST(expr, msg) do { if(!(expr)) { ++fails; std::cout << msg; } while(0) +class Test_State + { + public: + void started(const std::string& /*msg*/) { m_tests_run++; } + + void test_ran(const char* msg); + + void failure(const char* test, const std::string& what_failed) + { + std::cout << "FAIL " << test << " " << what_failed << "\n"; + m_tests_failed++; + } + + size_t ran() const { return m_tests_run; } + size_t failed() const { return m_tests_failed; } + private: + size_t m_tests_run = 0, m_tests_failed = 0; + }; + +#define BOTAN_CONFIRM_NOTHROW(block) do { \ + try { block } \ + catch(std::exception& e) { \ + _test.failure(BOTAN_CURRENT_FUNCTION, e.what()); \ + } } while(0) \ + +#define BOTAN_TEST(lhs, rhs, msg) do { \ + _test.started(msg); \ + BOTAN_CONFIRM_NOTHROW({ \ + const auto lhs_val = lhs; \ + const auto rhs_val = rhs; \ + const bool cmp = lhs_val == rhs_val; \ + if(!cmp) \ + { \ + std::ostringstream fmt; \ + fmt << "expr '" << #lhs << " == " << #rhs << "' false, " \ + << "actually " << lhs_val << " " << rhs_val \ + << " (" << msg << ")"; \ + _test.failure(BOTAN_CURRENT_FUNCTION, fmt.str()); \ + } \ + }); \ + } while(0) + +#define BOTAN_CONFIRM(expr, msg) do { \ + _test.started(msg); \ + BOTAN_CONFIRM_NOTHROW({ \ + const bool expr_val = expr; \ + if(!expr_val) \ + { \ + std::ostringstream fmt; \ + fmt << "expr '" << #expr << " false (" << msg << ")"; \ + _test.failure(BOTAN_CURRENT_FUNCTION, fmt.str()); \ + } \ + }); \ + } while(0) + +#define BOTAN_TEST_CASE(name, descr, block) size_t test_ ## name() { \ + Test_State _test; \ + BOTAN_CONFIRM_NOTHROW(block); \ + test_report(descr, _test.ran(), _test.failed()); \ + return _test.failed(); \ + } + +//#define TEST(expr, msg) do { if(!(expr)) { ++fails; std::cout << msg; } while(0) #define TEST_DATA_DIR "src/tests/data" #define TEST_DATA_DIR_PK "src/tests/data/pubkey" @@ -75,10 +138,13 @@ size_t test_dh(); size_t test_dlies(); size_t test_elgamal(); size_t test_ecc_pointmul(); +size_t test_ecc_random(); size_t test_ecdsa(); size_t test_gost_3410(); size_t test_curve25519(); +size_t test_gf2m(); size_t test_mceliece(); +size_t test_mce(); // One off tests size_t test_ocb(); @@ -94,6 +160,7 @@ size_t test_pk_keygen(); size_t test_bigint(); size_t test_ecc_unit(); +size_t test_ecc_randomized(); size_t test_ecdsa_unit(); size_t test_ecdh_unit(); diff --git a/src/tests/unit_ecc.cpp b/src/tests/unit_ecc.cpp index 8498e3b43..bd813b37e 100644 --- a/src/tests/unit_ecc.cpp +++ b/src/tests/unit_ecc.cpp @@ -816,9 +816,9 @@ size_t test_curve_cp_ctor() return 0; } -size_t ecc_randomized_test() - { - const std::vector<std::string> groups = { +namespace { + +const std::vector<std::string> ec_groups = { "brainpool160r1", "brainpool192r1", "brainpool224r1", @@ -849,11 +849,16 @@ size_t ecc_randomized_test() "x962_p239v3" }; +} + +} + +BOTAN_TEST_CASE(ecc_randomized, "ECC Randomized", { auto& rng = test_rng(); size_t fails = 0; size_t tests = 0; - for(auto&& group_name : groups) + for(auto&& group_name : ec_groups) { EC_Group group(group_name); @@ -861,8 +866,8 @@ size_t ecc_randomized_test() const BigInt& group_order = group.get_order(); const PointGFp inf = base_point * group_order; - CHECK(inf.is_zero()); - CHECK(inf.on_the_curve()); + BOTAN_CONFIRM(inf.is_zero(), "Group math ok"); + BOTAN_CONFIRM(inf.on_the_curve(), "Infinity still on the curve"); try { @@ -870,6 +875,9 @@ size_t ecc_randomized_test() { ++tests; + const size_t h = 1 + (rng.next_byte() % 8); + Blinded_Point_Multiply blind(base_point, group_order, h); + const BigInt a = BigInt::random_integer(rng, 2, group_order); const BigInt b = BigInt::random_integer(rng, 2, group_order); const BigInt c = a + b; @@ -878,16 +886,24 @@ size_t ecc_randomized_test() const PointGFp Q = base_point * b; const PointGFp R = base_point * c; + const PointGFp P1 = blind.blinded_multiply(a, rng); + const PointGFp Q1 = blind.blinded_multiply(b, rng); + const PointGFp R1 = blind.blinded_multiply(c, rng); + const PointGFp A1 = P + Q; const PointGFp A2 = Q + P; - CHECK(A1 == R); - CHECK(A2 == R); - CHECK(P.on_the_curve()); - CHECK(Q.on_the_curve()); - CHECK(R.on_the_curve()); - CHECK(A1.on_the_curve()); - CHECK(A2.on_the_curve()); + BOTAN_TEST(A1, R, "Addition"); + BOTAN_TEST(A2, R, "Addition"); + BOTAN_CONFIRM(P.on_the_curve(), "On the curve"); + BOTAN_CONFIRM(Q.on_the_curve(), "On the curve"); + BOTAN_CONFIRM(R.on_the_curve(), "On the curve"); + BOTAN_CONFIRM(A1.on_the_curve(), "On the curve"); + BOTAN_CONFIRM(A2.on_the_curve(), "On the curve"); + + BOTAN_TEST(P, P1, "P1"); + BOTAN_TEST(Q, Q1, "Q1"); + BOTAN_TEST(R, R1, "R1"); } } catch(std::exception& e) @@ -896,12 +912,8 @@ size_t ecc_randomized_test() ++fails; } } + }); - test_report("ECC Randomized", tests, fails); - return fails; - } - -} size_t test_ecc_unit() { @@ -934,13 +946,12 @@ size_t test_ecc_unit() test_report("ECC", 0, fails); - ecc_randomized_test(); - return fails; } #else SKIP_TEST(ecc_unit); +SKIP_TEST(ecc_randomized); #endif // BOTAN_HAS_ECC_GROUP diff --git a/src/tests/unit_ecdsa.cpp b/src/tests/unit_ecdsa.cpp index 22625d230..9983de7cc 100644 --- a/src/tests/unit_ecdsa.cpp +++ b/src/tests/unit_ecdsa.cpp @@ -107,6 +107,7 @@ size_t test_decode_ecdsa_X509() CHECK_MESSAGE(hex_encode(cert.serial_number()) == "01", "error reading serial from x509 ecdsa certificate"); CHECK_MESSAGE(hex_encode(cert.authority_key_id()) == "0096452DE588F966C4CCDF161DD1F3F5341B71E7", "error reading authority key id from x509 ecdsa certificate"); CHECK_MESSAGE(hex_encode(cert.subject_key_id()) == "0096452DE588F966C4CCDF161DD1F3F5341B71E7", "error reading Subject key id from x509 ecdsa certificate"); + CHECK_MESSAGE(cert.fingerprint("SHA-1") == "32:42:1C:C3:EC:54:D7:E9:43:EC:51:F0:19:23:BD:85:1D:F2:1B:B9", "Incorrect fingerprint"); std::unique_ptr<X509_PublicKey> pubkey(cert.subject_public_key()); bool ver_ec = cert.check_signature(*pubkey); diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp index f77be1992..0d3946012 100644 --- a/src/tests/unit_x509.cpp +++ b/src/tests/unit_x509.cpp @@ -11,8 +11,8 @@ #if defined(BOTAN_HAS_RSA) && defined(BOTAN_HAS_DSA) #include <botan/calendar.h> -#include <botan/filters.h> #include <botan/pkcs8.h> +#include <botan/hash.h> #include <botan/pkcs10.h> #include <botan/x509self.h> #include <botan/x509path.h> @@ -45,22 +45,12 @@ X509_Time from_date(const int y, const int m, const int d) u64bit key_id(const Public_Key* key) { - Pipe pipe(new Hash_Filter("SHA-1", 8)); - pipe.start_msg(); - pipe.write(key->algo_name()); - pipe.write(key->algorithm_identifier().parameters); - pipe.write(key->x509_subject_public_key()); - pipe.end_msg(); - - secure_vector<byte> output = pipe.read_all(); - - if(output.size() != 8) - throw Internal_Error("Public_Key::key_id: Incorrect output size"); - - u64bit id = 0; - for(u32bit j = 0; j != 8; ++j) - id = (id << 8) | output[j]; - return id; + std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-1")); + hash->update(key->algo_name()); + hash->update(key->algorithm_identifier().parameters); + hash->update(key->x509_subject_public_key()); + secure_vector<byte> output = hash->final(); + return load_be<u64bit>(output.data(), 0); } |