From 7677f329b5f8b4976d2c858c31a6e48d31d2db9c Mon Sep 17 00:00:00 2001 From: bogdan Date: Wed, 5 Aug 2015 18:09:01 +0300 Subject: Add template constructor to secure_allocator This is required by the Standard for an allocator. As far as I can tell, not having it breaks compilation in MSVC 2015, at least when iterator debugging is enabled. More details here: http://stackoverflow.com/q/31802806/4326278. --- src/lib/alloc/secmem.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/lib') diff --git a/src/lib/alloc/secmem.h b/src/lib/alloc/secmem.h index 98707ad4e..453acc5d8 100644 --- a/src/lib/alloc/secmem.h +++ b/src/lib/alloc/secmem.h @@ -36,6 +36,9 @@ class secure_allocator secure_allocator() BOTAN_NOEXCEPT {} + template + secure_allocator(const secure_allocator&) BOTAN_NOEXCEPT {} + ~secure_allocator() BOTAN_NOEXCEPT {} pointer address(reference x) const BOTAN_NOEXCEPT -- cgit v1.2.3 From 5bedae43e66002aefadce0b6d43bf6791d5156ca Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 20 Aug 2015 19:49:31 +0200 Subject: Refactor ./botan speed * Add random_prime benchmark * Add is_prime benchmark * Respect runtime in benchmark_transform(). This sets default runtime from 2s to 0.5s per configuration --- src/cmd/implementation/speed.h | 28 + src/cmd/implementation/speed_prime.cpp | 96 +++ src/cmd/implementation/speed_public_key.cpp | 878 ++++++++++++++++++++++++++++ src/cmd/implementation/speed_transform.cpp | 67 +++ src/cmd/implementation/timer.cpp | 60 ++ src/cmd/implementation/timer.h | 55 ++ src/cmd/speed.cpp | 105 +--- src/cmd/speed.h | 16 - src/cmd/speed_pk.cpp | 878 ---------------------------- src/cmd/timer.cpp | 60 -- src/cmd/timer.h | 55 -- src/lib/misc/benchmark/benchmark.cpp | 18 +- src/lib/utils/exceptn.h | 10 + 13 files changed, 1235 insertions(+), 1091 deletions(-) create mode 100644 src/cmd/implementation/speed.h create mode 100644 src/cmd/implementation/speed_prime.cpp create mode 100644 src/cmd/implementation/speed_public_key.cpp create mode 100644 src/cmd/implementation/speed_transform.cpp create mode 100644 src/cmd/implementation/timer.cpp create mode 100644 src/cmd/implementation/timer.h delete mode 100644 src/cmd/speed.h delete mode 100644 src/cmd/speed_pk.cpp delete mode 100644 src/cmd/timer.cpp delete mode 100644 src/cmd/timer.h (limited to 'src/lib') diff --git a/src/cmd/implementation/speed.h b/src/cmd/implementation/speed.h new file mode 100644 index 000000000..1f082eb52 --- /dev/null +++ b/src/cmd/implementation/speed.h @@ -0,0 +1,28 @@ +/* +* (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 +#include +#include + +void benchmark_public_key(Botan::RandomNumberGenerator& rng, + const std::string& algo, double seconds); + +std::map benchmark_is_prime(Botan::RandomNumberGenerator &rng, + const std::chrono::milliseconds runtime); + +std::map 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 +#include + +namespace { +const size_t RSA_EXP = 65537; +const size_t RSA_BITS = 2048; + +const auto SAMPLE_DATA = std::vector{ + 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 benchmark_is_prime(RandomNumberGenerator& rng, + const std::chrono::milliseconds runtime) + { + std::map 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(time_used.count()) / 1000000000; + speeds["base"] = reps / seconds_used; // ie, return ops per second + +#endif // BOTAN_HAS_NUMBERTHEORY + + return speeds; + } + +std::map benchmark_random_prime(RandomNumberGenerator& rng, + const std::chrono::milliseconds runtime) + { + std::map 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(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/implementation/speed_public_key.cpp b/src/cmd/implementation/speed_public_key.cpp new file mode 100644 index 000000000..1e14f7eca --- /dev/null +++ b/src/cmd/implementation/speed_public_key.cpp @@ -0,0 +1,878 @@ +/* +* (C) 2009-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "../apps.h" + +#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) + +#include "speed.h" +#include "timer.h" + +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_RSA) + #include +#endif + +#if defined(BOTAN_HAS_DSA) + #include +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + #include +#endif + +#if defined(BOTAN_HAS_CURVE_25519) + #include +#endif + +#if defined(BOTAN_HAS_NYBERG_RUEPPEL) + #include +#endif + +#if defined(BOTAN_HAS_RW) + #include +#endif + +#if defined(BOTAN_HAS_ELGAMAL) + #include +#endif + +#if defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_KDF2) + #include + #include + #include + #include +#endif + +#if defined(BOTAN_HAS_ECDSA) + #include +#endif + +#if defined(BOTAN_HAS_ECDH) + #include +#endif + +#if defined(BOTAN_HAS_GOST_34_10_2001) + #include +#endif + +#if defined(BOTAN_HAS_MCELIECE) + #include + #include +#endif + +using namespace Botan; + +#include +#include +#include +#include +#include + +namespace { + +const char* ec_domains[] = { + "secp160r2", + "secp192r1", + "secp224r1", + "secp256r1", + "secp384r1", + "secp521r1", + nullptr +}; + +class Benchmark_Report + { + public: + void report(const std::string& name, Timer timer) + { + std::cout << name << " " << timer << std::endl; + data[name].insert(timer); + } + + private: + std::map > data; + }; + +void benchmark_enc_dec(PK_Encryptor& enc, PK_Decryptor& dec, + Timer& enc_timer, Timer& dec_timer, + RandomNumberGenerator& rng, + u32bit runs, double seconds) + { + std::vector plaintext, ciphertext; + + for(u32bit i = 0; i != runs; ++i) + { + if(enc_timer.seconds() < seconds || ciphertext.size() == 0) + { + plaintext.resize(enc.maximum_input_size()); + + // Ensure for Raw, etc, it stays large + if((i % 100) == 0) + { + rng.randomize(&plaintext[0], plaintext.size()); + plaintext[0] |= 0x80; + } + + enc_timer.start(); + ciphertext = enc.encrypt(plaintext, rng); + enc_timer.stop(); + } + + if(dec_timer.seconds() < seconds) + { + dec_timer.start(); + std::vector plaintext_out = unlock(dec.decrypt(ciphertext)); + dec_timer.stop(); + + if(plaintext_out != plaintext) + { // has never happened... + std::cerr << "Contents mismatched on decryption during benchmark!" << std::endl; + } + } + } + } + +void benchmark_sig_ver(PK_Verifier& ver, PK_Signer& sig, + Timer& verify_timer, Timer& sig_timer, + RandomNumberGenerator& rng, + u32bit runs, double seconds) + { + std::vector message, signature, sig_random; + + for(u32bit i = 0; i != runs; ++i) + { + if(sig_timer.seconds() < seconds || signature.size() == 0) + { + if((i % 100) == 0) + { + message.resize(48); + rng.randomize(&message[0], message.size()); + } + + sig_timer.start(); + signature = sig.sign_message(message, rng); + sig_timer.stop(); + } + + if(verify_timer.seconds() < seconds) + { + verify_timer.start(); + const bool verified = ver.verify_message(message, signature); + verify_timer.stop(); + + if(!verified) + std::cerr << "Signature verification failure" << std::endl; + + if((i % 100) == 0) + { + sig_random = unlock(rng.random_vec(signature.size())); + + verify_timer.start(); + const bool verified_bad = ver.verify_message(message, sig_random); + verify_timer.stop(); + + if(verified_bad) + std::cerr << "Signature verification failure (bad sig OK)" << std::endl; + } + } + } + } + +/* + Between benchmark_rsa_rw + benchmark_dsa_nr: + Type of the key + Arguments to the constructor (A list of some arbitrary type?) + Type of padding +*/ + +#if defined(BOTAN_HAS_RSA) +void benchmark_rsa(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + + size_t keylens[] = { 1024, 2048, 4096, 6144, 0 }; + + for(size_t i = 0; keylens[i]; ++i) + { + 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 = "EMSA-PKCS1-v1_5(SHA-1)"; + const std::string enc_padding = "EME-PKCS1-v1_5"; + + Timer keygen_timer("keygen"); + Timer verify_timer(sig_padding + " verify"); + Timer sig_timer(sig_padding + " signature"); + Timer enc_timer(enc_padding + " encrypt"); + Timer dec_timer(enc_padding + " decrypt"); + + try + { + +#if 0 + // for profiling + PKCS8_PrivateKey* pkcs8_key = + PKCS8::load_key("rsa/" + to_string(keylen) + ".pem", rng); + RSA_PrivateKey* key_ptr = dynamic_cast(pkcs8_key); + + RSA_PrivateKey key = *key_ptr; +#else + keygen_timer.start(); + RSA_PrivateKey key(rng, keylen); + keygen_timer.stop(); +#endif + + while(verify_timer.seconds() < seconds || + sig_timer.seconds() < seconds) + { + PK_Encryptor_EME enc(key, enc_padding); + PK_Decryptor_EME dec(key, enc_padding); + + benchmark_enc_dec(enc, dec, enc_timer, dec_timer, + rng, 10000, seconds); + + PK_Signer sig(key, sig_padding); + PK_Verifier ver(key, sig_padding); + + benchmark_sig_ver(ver, sig, verify_timer, + sig_timer, rng, 10000, seconds); + } + + const std::string rsa_keylen = "RSA-" + std::to_string(keylen); + + report.report(rsa_keylen, keygen_timer); + report.report(rsa_keylen, verify_timer); + report.report(rsa_keylen, sig_timer); + report.report(rsa_keylen, enc_timer); + report.report(rsa_keylen, dec_timer); + } + catch(Stream_IO_Error) + { + } + catch(Exception& e) + { + std::cout << e.what() << std::endl; + } + } + + } +#endif + +#if defined(BOTAN_HAS_RW) +void benchmark_rw(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + + const u32bit keylens[] = { 1024, 2048, 4096, 6144, 0 }; + + for(size_t j = 0; keylens[j]; j++) + { + u32bit keylen = keylens[j]; + + std::string padding = "EMSA2(SHA-256)"; + + Timer keygen_timer("keygen"); + Timer verify_timer(padding + " verify"); + Timer sig_timer(padding + " signature"); + + while(verify_timer.seconds() < seconds || + sig_timer.seconds() < seconds) + { + keygen_timer.start(); + RW_PrivateKey key(rng, keylen); + keygen_timer.stop(); + + PK_Signer sig(key, padding); + PK_Verifier ver(key, padding); + + benchmark_sig_ver(ver, sig, verify_timer, sig_timer, + rng, 10000, seconds); + } + + const std::string nm = "RW-" + std::to_string(keylen); + report.report(nm, keygen_timer); + report.report(nm, verify_timer); + report.report(nm, sig_timer); + } + } +#endif + +#if defined(BOTAN_HAS_ECDSA) + +void benchmark_ecdsa(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + for(size_t j = 0; ec_domains[j]; j++) + { + EC_Group params(ec_domains[j]); + + const size_t pbits = params.get_curve().get_p().bits(); + + size_t hashbits = pbits; + + if(hashbits <= 192) + hashbits = 160; + if(hashbits == 521) + hashbits = 512; + + const std::string padding = "EMSA1(SHA-" + std::to_string(hashbits) + ")"; + + Timer keygen_timer("keygen"); + Timer verify_timer(padding + " verify"); + Timer sig_timer(padding + " signature"); + + while(verify_timer.seconds() < seconds || + sig_timer.seconds() < seconds) + { + keygen_timer.start(); + ECDSA_PrivateKey key(rng, params); + keygen_timer.stop(); + + PK_Signer sig(key, padding, IEEE_1363); + PK_Verifier ver(key, padding); + + benchmark_sig_ver(ver, sig, verify_timer, + sig_timer, rng, 1000, seconds); + } + + const std::string nm = "ECDSA-" + std::to_string(pbits); + + report.report(nm, keygen_timer); + report.report(nm, verify_timer); + report.report(nm, sig_timer); + } + } + +#endif + +#if defined(BOTAN_HAS_GOST_34_10_2001) + +void benchmark_gost_3410(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + for(size_t j = 0; ec_domains[j]; j++) + { + EC_Group params(ec_domains[j]); + + const size_t pbits = params.get_curve().get_p().bits(); + + const std::string padding = "EMSA1(GOST-34.11)"; + + Timer keygen_timer("keygen"); + Timer verify_timer(padding + " verify"); + Timer sig_timer(padding + " signature"); + + while(verify_timer.seconds() < seconds || + sig_timer.seconds() < seconds) + { + keygen_timer.start(); + GOST_3410_PrivateKey key(rng, params); + keygen_timer.stop(); + + PK_Signer sig(key, padding, IEEE_1363); + PK_Verifier ver(key, padding); + + benchmark_sig_ver(ver, sig, verify_timer, + sig_timer, rng, 1000, seconds); + } + + const std::string nm = "GOST-34.10-" + std::to_string(pbits); + + report.report(nm, keygen_timer); + report.report(nm, verify_timer); + report.report(nm, sig_timer); + } + } + +#endif + +#if defined(BOTAN_HAS_ECDH) + +void benchmark_ecdh(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + for(size_t j = 0; ec_domains[j]; j++) + { + EC_Group params(ec_domains[j]); + + size_t pbits = params.get_curve().get_p().bits(); + + Timer keygen_timer("keygen"); + Timer kex_timer("key exchange"); + + while(kex_timer.seconds() < seconds) + { + keygen_timer.start(); + ECDH_PrivateKey ecdh1(rng, params); + keygen_timer.stop(); + + keygen_timer.start(); + ECDH_PrivateKey ecdh2(rng, params); + keygen_timer.stop(); + + PK_Key_Agreement ka1(ecdh1, "KDF2(SHA-1)"); + PK_Key_Agreement ka2(ecdh2, "KDF2(SHA-1)"); + + SymmetricKey secret1, secret2; + + for(size_t i = 0; i != 1000; ++i) + { + if(kex_timer.seconds() > seconds) + break; + + kex_timer.start(); + secret1 = ka1.derive_key(32, ecdh2.public_value()); + kex_timer.stop(); + + kex_timer.start(); + secret2 = ka2.derive_key(32, ecdh1.public_value()); + kex_timer.stop(); + + if(secret1 != secret2) + std::cerr << "ECDH secrets did not match" << std::endl; + } + } + + const std::string nm = "ECDH-" + std::to_string(pbits); + report.report(nm, keygen_timer); + report.report(nm, kex_timer); + } + } + +#endif + +template +void benchmark_dsa_nr(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { +#if defined(BOTAN_HAS_NYBERG_RUEPPEL) || defined(BOTAN_HAS_DSA) + const char* domains[] = { "dsa/jce/1024", + "dsa/botan/2048", + "dsa/botan/3072", + nullptr }; + + std::string algo_name; + + for(size_t j = 0; domains[j]; j++) + { + size_t pbits = to_u32bit(split_on(domains[j], '/')[2]); + size_t qbits = (pbits <= 1024) ? 160 : 256; + + const std::string padding = "EMSA1(SHA-" + std::to_string(qbits) + ")"; + + Timer keygen_timer("keygen"); + Timer verify_timer(padding + " verify"); + Timer sig_timer(padding + " signature"); + + while(verify_timer.seconds() < seconds || + sig_timer.seconds() < seconds) + { + DL_Group group(domains[j]); + + keygen_timer.start(); + PRIV_KEY_TYPE key(rng, group); + algo_name = key.algo_name(); + keygen_timer.stop(); + + PK_Signer sig(key, padding, IEEE_1363); + PK_Verifier ver(key, padding); + + benchmark_sig_ver(ver, sig, verify_timer, + sig_timer, rng, 1000, seconds); + } + + const std::string nm = algo_name + "-" + std::to_string(pbits); + report.report(nm, keygen_timer); + report.report(nm, verify_timer); + report.report(nm, sig_timer); + } +#endif + } + +#if defined(BOTAN_HAS_CURVE_25519) +void benchmark_curve25519(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + Timer keygen_timer("keygen"); + Timer kex_timer("key exchange"); + + while(kex_timer.seconds() < seconds) + { + keygen_timer.start(); + Curve25519_PrivateKey key1(rng); + keygen_timer.stop(); + + keygen_timer.start(); + Curve25519_PrivateKey key2(rng); + keygen_timer.stop(); + + PK_Key_Agreement ka1(key1, "KDF2(SHA-256)"); + PK_Key_Agreement ka2(key2, "KDF2(SHA-256)"); + + SymmetricKey secret1, secret2; + + for(size_t i = 0; i != 1000; ++i) + { + if(kex_timer.seconds() > seconds) + break; + + kex_timer.start(); + secret1 = ka1.derive_key(32, key2.public_value()); + kex_timer.stop(); + + kex_timer.start(); + secret2 = ka2.derive_key(32, key1.public_value()); + kex_timer.stop(); + + if(secret1 != secret2) + std::cerr << "Curve25519 secrets did not match" << std::endl; + } + } + + const std::string nm = "Curve25519"; + report.report(nm, keygen_timer); + report.report(nm, kex_timer); + } +#endif + +#ifdef BOTAN_HAS_DIFFIE_HELLMAN +void benchmark_dh(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + const char* domains[] = { "modp/ietf/1024", + "modp/ietf/2048", + "modp/ietf/3072", + "modp/ietf/4096", + "modp/ietf/6144", + "modp/ietf/8192", + nullptr }; + + for(size_t j = 0; domains[j]; j++) + { + Timer keygen_timer("keygen"); + Timer kex_timer("key exchange"); + + while(kex_timer.seconds() < seconds) + { + DL_Group group(domains[j]); + + keygen_timer.start(); + DH_PrivateKey dh1(rng, group); + keygen_timer.stop(); + + keygen_timer.start(); + DH_PrivateKey dh2(rng, group); + keygen_timer.stop(); + + PK_Key_Agreement ka1(dh1, "KDF2(SHA-1)"); + PK_Key_Agreement ka2(dh2, "KDF2(SHA-1)"); + + SymmetricKey secret1, secret2; + + for(size_t i = 0; i != 1000; ++i) + { + if(kex_timer.seconds() > seconds) + break; + + kex_timer.start(); + secret1 = ka1.derive_key(32, dh2.public_value()); + kex_timer.stop(); + + kex_timer.start(); + secret2 = ka2.derive_key(32, dh1.public_value()); + kex_timer.stop(); + + if(secret1 != secret2) + std::cerr << "DH secrets did not match" << std::endl; + } + } + + const std::string nm = "DH-" + split_on(domains[j], '/')[2]; + report.report(nm, keygen_timer); + report.report(nm, kex_timer); + } + } +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) && defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_KDF2) +void benchmark_dlies(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + const char* domains[] = { "modp/ietf/768", + "modp/ietf/1024", + "modp/ietf/2048", + "modp/ietf/3072", + "modp/ietf/4096", + "modp/ietf/6144", + "modp/ietf/8192", + nullptr }; + + for(size_t j = 0; domains[j]; j++) + { + Timer keygen_timer("keygen"); + Timer kex_timer("key exchange"); + + Timer enc_timer("encrypt"); + Timer dec_timer("decrypt"); + + while(enc_timer.seconds() < seconds || dec_timer.seconds() < seconds) + { + DL_Group group(domains[j]); + + keygen_timer.start(); + DH_PrivateKey dh1_priv(rng, group); + keygen_timer.stop(); + + keygen_timer.start(); + DH_PrivateKey dh2_priv(rng, group); + keygen_timer.stop(); + + DH_PublicKey dh2_pub(dh2_priv); + + DLIES_Encryptor dlies_enc(dh1_priv, + new KDF2(new SHA_160), + new HMAC(new SHA_160)); + + dlies_enc.set_other_key(dh2_pub.public_value()); + + DLIES_Decryptor dlies_dec(dh2_priv, + new KDF2(new SHA_160), + new HMAC(new SHA_160)); + + benchmark_enc_dec(dlies_enc, dlies_dec, + enc_timer, dec_timer, rng, + 1000, seconds); + } + + const std::string nm = "DLIES-" + split_on(domains[j], '/')[2]; + report.report(nm, keygen_timer); + report.report(nm, enc_timer); + report.report(nm, dec_timer); + } + } +#endif + +#ifdef BOTAN_HAS_ELGAMAL +void benchmark_elg(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + const char* domains[] = { "modp/ietf/768", + "modp/ietf/1024", + "modp/ietf/2048", + "modp/ietf/3072", + "modp/ietf/4096", + "modp/ietf/6144", + "modp/ietf/8192", + nullptr }; + + const std::string algo_name = "ElGamal"; + + for(size_t j = 0; domains[j]; j++) + { + size_t pbits = to_u32bit(split_on(domains[j], '/')[2]); + + const std::string padding = "EME1(SHA-1)"; + + Timer keygen_timer("keygen"); + Timer enc_timer(padding + " encrypt"); + Timer dec_timer(padding + " decrypt"); + + while(enc_timer.seconds() < seconds || + dec_timer.seconds() < seconds) + { + DL_Group group(domains[j]); + + keygen_timer.start(); + ElGamal_PrivateKey key(rng, group); + keygen_timer.stop(); + + PK_Decryptor_EME dec(key, padding); + PK_Encryptor_EME enc(key, padding); + + benchmark_enc_dec(enc, dec, enc_timer, dec_timer, + rng, 1000, seconds); + } + + const std::string nm = algo_name + "-" + std::to_string(pbits); + report.report(nm, keygen_timer); + report.report(nm, enc_timer); + report.report(nm, dec_timer); + } + } +#endif + +#if defined(BOTAN_HAS_MCELIECE) +void benchmark_mce(RandomNumberGenerator& rng, + double seconds, + Benchmark_Report& report) + { + const std::vector> params = { + { 1024, 35 }, + { 2048, 50 }, + { 2960, 56 }, + { 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"); + + keygen_timer.start(); + McEliece_PrivateKey priv_key(rng, param.first, param.second); + McEliece_PublicKey pub_key(priv_key.x509_subject_public_key()); + keygen_timer.stop(); + + McEliece_KEM_Encryptor enc_kem(pub_key); + McEliece_KEM_Decryptor dec_kem(priv_key); + + while(enc_timer.seconds() < seconds || + dec_timer.seconds() < seconds) + { + enc_timer.start(); + auto enc_pair = enc_kem.encrypt(rng); + enc_timer.stop(); + + dec_timer.start(); + auto dec_key = dec_kem.decrypt_vec(enc_pair.first); + dec_timer.stop(); + + BOTAN_ASSERT_EQUAL(enc_pair.second, dec_key, "KEM result matches"); + } + + const std::string nm = algo_name + "-" + + std::to_string(param.first) + "," + + 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)"; + + report.report(nm + " " + keysize_report.str(), keygen_timer); + report.report(nm, enc_timer); + report.report(nm, dec_timer); + } + } +#endif + +} + +void benchmark_public_key(RandomNumberGenerator& rng, + const std::string& algo, double seconds) + { + /* + There is some strangeness going on here. It looks like algorithms + at the end take some kind of penalty. For example, running the RW tests + first got a result of: + RW-1024: 148.14 ms / private operation + but running them last output: + RW-1024: 363.54 ms / private operation + + I think it's from memory fragmentation in the allocators, but I'm + not really sure. Need to investigate. + + Until then, I've basically ordered the tests in order of most important + algorithms (RSA, DSA) to least important (NR, RW). + + This strange behaviour does not seem to occur with DH (?) + + To get more accurate runs, use --bench-algo (RSA|DSA|DH|ELG|NR); in this + case the distortion is less than 5%, which is good enough. + + We do random keys with the DL schemes, since it's so easy and fast to + generate keys for them. For RSA and RW, we load the keys from a file. The + RSA keys are stored in a PKCS #8 structure, while RW is stored in a more + ad-hoc format (the RW algorithm has no assigned OID that I know of, so + there is no way to encode a RW key into a PKCS #8 structure). + */ + + Benchmark_Report report; + +#if defined(BOTAN_HAS_RSA) + if(algo == "All" || algo == "RSA") + benchmark_rsa(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_DSA) + if(algo == "All" || algo == "DSA") + benchmark_dsa_nr(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_ECDSA) + if(algo == "All" || algo == "ECDSA") + benchmark_ecdsa(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_ECDH) + if(algo == "All" || algo == "ECDH") + benchmark_ecdh(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_GOST_34_10_2001) + if(algo == "All" || algo == "GOST-34.10") + benchmark_gost_3410(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_CURVE_25519) + if(algo == "All" || algo == "Curve25519") + benchmark_curve25519(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + if(algo == "All" || algo == "DH") + benchmark_dh(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) && defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_KDF2) + if(algo == "All" || algo == "DLIES") + benchmark_dlies(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_ELGAMAL) + if(algo == "All" || algo == "ELG" || algo == "ElGamal") + benchmark_elg(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_NYBERG_RUEPPEL) + if(algo == "All" || algo == "NR") + benchmark_dsa_nr(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_RW) + if(algo == "All" || algo == "RW") + benchmark_rw(rng, seconds, report); +#endif + +#if defined(BOTAN_HAS_MCELIECE) + if(algo == "All" || algo == "McEliece") + benchmark_mce(rng, seconds, report); +#endif + } +#endif // BOTAN_HAS_PUBLIC_KEY_CRYPTO 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 +#include + +#include +#include + +using namespace Botan; + +namespace { +void benchmark_transform(std::unique_ptr tf, + RandomNumberGenerator& rng, + const std::chrono::milliseconds runtime) + { + for(size_t buf_size : { 16, 64, 256, 1024, 8192 }) + { + secure_vector 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 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(time_used).count(); + + const double seconds_used = static_cast(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 tf; + tf.reset(get_cipher_mode(algo_name, ENCRYPTION)); + if(!tf) + return false; + + if(Keyed_Transform* keyed = dynamic_cast(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/implementation/timer.cpp b/src/cmd/implementation/timer.cpp new file mode 100644 index 000000000..14e55316b --- /dev/null +++ b/src/cmd/implementation/timer.cpp @@ -0,0 +1,60 @@ +/* +* (C) 2009 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "timer.h" +#include +#include + +void Timer::start() + { + stop(); + m_timer_start = get_clock(); + } + +void Timer::stop() + { + if(m_timer_start) + { + const u64bit now = get_clock(); + + if(now > m_timer_start) + m_time_used += (now - m_timer_start); + + m_timer_start = 0; + ++m_event_count; + } + } + +u64bit Timer::get_clock() + { + auto now = std::chrono::high_resolution_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count(); + } + +std::ostream& operator<<(std::ostream& out, Timer& timer) + { + //out << timer.value() << " "; + + double events_per_second_fl = + static_cast(timer.events() / timer.seconds()); + + u64bit events_per_second = static_cast(events_per_second_fl); + + out << events_per_second << " " << timer.get_name() << " per second; "; + + std::string op_or_ops = (timer.events() == 1) ? "op" : "ops"; + + const std::ios::fmtflags flags = out.flags(); + + out << std::setprecision(2) << std::fixed + << timer.ms_per_event() << " ms/op" + << " (" << timer.events() << " " << op_or_ops << " in " + << timer.milliseconds() << " ms)"; + + out.flags(flags); + + return out; + } diff --git a/src/cmd/implementation/timer.h b/src/cmd/implementation/timer.h new file mode 100644 index 000000000..ac5bd5cef --- /dev/null +++ b/src/cmd/implementation/timer.h @@ -0,0 +1,55 @@ +/* +* (C) 2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BENCHMARK_TIMER_H__ +#define BOTAN_BENCHMARK_TIMER_H__ + +#include +#include +#include + +using Botan::u64bit; +using Botan::u32bit; + +class Timer + { + public: + static u64bit get_clock(); + + Timer(const std::string& name, u32bit event_mult = 1) : + m_name(name), m_event_mult(event_mult) {} + + void start(); + void stop(); + + u64bit value() { stop(); return m_time_used; } + double seconds() { return milliseconds() / 1000.0; } + double milliseconds() { return value() / 1000000.0; } + + double ms_per_event() { return milliseconds() / events(); } + double seconds_per_event() { return seconds() / events(); } + + u64bit events() const { return m_event_count * m_event_mult; } + std::string get_name() const { return m_name; } + private: + std::string m_name; + u64bit m_time_used = 0, m_timer_start = 0; + u64bit m_event_count = 0, m_event_mult = 0; + }; + +inline bool operator<(const Timer& x, const Timer& y) + { + return (x.get_name() < y.get_name()); + } + +inline bool operator==(const Timer& x, const Timer& y) + { + return (x.get_name() == y.get_name()); + } + +std::ostream& operator<<(std::ostream&, Timer&); + +#endif diff --git a/src/cmd/speed.cpp b/src/cmd/speed.cpp index eea3a7c60..91b2f4fbd 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 #include #include #include -#include -#include -#include -#include -#include - -#include - -typedef std::chrono::high_resolution_clock benchmark_clock; - using namespace Botan; namespace { - const std::vector default_benchmark_list = { /* Block ciphers */ "AES-128", @@ -90,7 +80,11 @@ const std::vector 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,78 +117,43 @@ void report_results(const std::string& algo, std::cout.flags(flags); } -void time_transform(std::unique_ptr tf, - RandomNumberGenerator& rng) +void bench_algo(const std::string& algo, + 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 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 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; - } + std::chrono::milliseconds runtime( + static_cast(seconds * 1000)); - const u64bit nsec_used = std::chrono::duration_cast(time_used).count(); - - const double seconds_used = static_cast(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 time_transform(const std::string& algo, RandomNumberGenerator& rng) + if (algo == "random_prime") { - std::unique_ptr tf; - tf.reset(get_cipher_mode(algo, ENCRYPTION)); - if(!tf) - return false; - - if(Keyed_Transform* keyed = dynamic_cast(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(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 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, seconds); + #endif + } } int speed(int argc, char* argv[]) 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 -#include - -void bench_pk(Botan::RandomNumberGenerator& rng, - const std::string& algo, double seconds); - -#endif diff --git a/src/cmd/speed_pk.cpp b/src/cmd/speed_pk.cpp deleted file mode 100644 index 035b9a3af..000000000 --- a/src/cmd/speed_pk.cpp +++ /dev/null @@ -1,878 +0,0 @@ -/* -* (C) 2009-2010 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include "apps.h" - -#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) - -#include "speed.h" -#include "timer.h" - -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOTAN_HAS_RSA) - #include -#endif - -#if defined(BOTAN_HAS_DSA) - #include -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - #include -#endif - -#if defined(BOTAN_HAS_CURVE_25519) - #include -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) - #include -#endif - -#if defined(BOTAN_HAS_RW) - #include -#endif - -#if defined(BOTAN_HAS_ELGAMAL) - #include -#endif - -#if defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_KDF2) - #include - #include - #include - #include -#endif - -#if defined(BOTAN_HAS_ECDSA) - #include -#endif - -#if defined(BOTAN_HAS_ECDH) - #include -#endif - -#if defined(BOTAN_HAS_GOST_34_10_2001) - #include -#endif - -#if defined(BOTAN_HAS_MCELIECE) - #include - #include -#endif - -using namespace Botan; - -#include -#include -#include -#include -#include - -namespace { - -const char* ec_domains[] = { - "secp160r2", - "secp192r1", - "secp224r1", - "secp256r1", - "secp384r1", - "secp521r1", - nullptr -}; - -class Benchmark_Report - { - public: - void report(const std::string& name, Timer timer) - { - std::cout << name << " " << timer << std::endl; - data[name].insert(timer); - } - - private: - std::map > data; - }; - -void benchmark_enc_dec(PK_Encryptor& enc, PK_Decryptor& dec, - Timer& enc_timer, Timer& dec_timer, - RandomNumberGenerator& rng, - u32bit runs, double seconds) - { - std::vector plaintext, ciphertext; - - for(u32bit i = 0; i != runs; ++i) - { - if(enc_timer.seconds() < seconds || ciphertext.size() == 0) - { - plaintext.resize(enc.maximum_input_size()); - - // Ensure for Raw, etc, it stays large - if((i % 100) == 0) - { - rng.randomize(&plaintext[0], plaintext.size()); - plaintext[0] |= 0x80; - } - - enc_timer.start(); - ciphertext = enc.encrypt(plaintext, rng); - enc_timer.stop(); - } - - if(dec_timer.seconds() < seconds) - { - dec_timer.start(); - std::vector plaintext_out = unlock(dec.decrypt(ciphertext)); - dec_timer.stop(); - - if(plaintext_out != plaintext) - { // has never happened... - std::cerr << "Contents mismatched on decryption during benchmark!" << std::endl; - } - } - } - } - -void benchmark_sig_ver(PK_Verifier& ver, PK_Signer& sig, - Timer& verify_timer, Timer& sig_timer, - RandomNumberGenerator& rng, - u32bit runs, double seconds) - { - std::vector message, signature, sig_random; - - for(u32bit i = 0; i != runs; ++i) - { - if(sig_timer.seconds() < seconds || signature.size() == 0) - { - if((i % 100) == 0) - { - message.resize(48); - rng.randomize(&message[0], message.size()); - } - - sig_timer.start(); - signature = sig.sign_message(message, rng); - sig_timer.stop(); - } - - if(verify_timer.seconds() < seconds) - { - verify_timer.start(); - const bool verified = ver.verify_message(message, signature); - verify_timer.stop(); - - if(!verified) - std::cerr << "Signature verification failure" << std::endl; - - if((i % 100) == 0) - { - sig_random = unlock(rng.random_vec(signature.size())); - - verify_timer.start(); - const bool verified_bad = ver.verify_message(message, sig_random); - verify_timer.stop(); - - if(verified_bad) - std::cerr << "Signature verification failure (bad sig OK)" << std::endl; - } - } - } - } - -/* - Between benchmark_rsa_rw + benchmark_dsa_nr: - Type of the key - Arguments to the constructor (A list of some arbitrary type?) - Type of padding -*/ - -#if defined(BOTAN_HAS_RSA) -void benchmark_rsa(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - - size_t keylens[] = { 1024, 2048, 4096, 6144, 0 }; - - for(size_t i = 0; keylens[i]; ++i) - { - 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 = "EMSA-PKCS1-v1_5(SHA-1)"; - const std::string enc_padding = "EME-PKCS1-v1_5"; - - Timer keygen_timer("keygen"); - Timer verify_timer(sig_padding + " verify"); - Timer sig_timer(sig_padding + " signature"); - Timer enc_timer(enc_padding + " encrypt"); - Timer dec_timer(enc_padding + " decrypt"); - - try - { - -#if 0 - // for profiling - PKCS8_PrivateKey* pkcs8_key = - PKCS8::load_key("rsa/" + to_string(keylen) + ".pem", rng); - RSA_PrivateKey* key_ptr = dynamic_cast(pkcs8_key); - - RSA_PrivateKey key = *key_ptr; -#else - keygen_timer.start(); - RSA_PrivateKey key(rng, keylen); - keygen_timer.stop(); -#endif - - while(verify_timer.seconds() < seconds || - sig_timer.seconds() < seconds) - { - PK_Encryptor_EME enc(key, enc_padding); - PK_Decryptor_EME dec(key, enc_padding); - - benchmark_enc_dec(enc, dec, enc_timer, dec_timer, - rng, 10000, seconds); - - PK_Signer sig(key, sig_padding); - PK_Verifier ver(key, sig_padding); - - benchmark_sig_ver(ver, sig, verify_timer, - sig_timer, rng, 10000, seconds); - } - - const std::string rsa_keylen = "RSA-" + std::to_string(keylen); - - report.report(rsa_keylen, keygen_timer); - report.report(rsa_keylen, verify_timer); - report.report(rsa_keylen, sig_timer); - report.report(rsa_keylen, enc_timer); - report.report(rsa_keylen, dec_timer); - } - catch(Stream_IO_Error) - { - } - catch(Exception& e) - { - std::cout << e.what() << std::endl; - } - } - - } -#endif - -#if defined(BOTAN_HAS_RW) -void benchmark_rw(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - - const u32bit keylens[] = { 1024, 2048, 4096, 6144, 0 }; - - for(size_t j = 0; keylens[j]; j++) - { - u32bit keylen = keylens[j]; - - std::string padding = "EMSA2(SHA-256)"; - - Timer keygen_timer("keygen"); - Timer verify_timer(padding + " verify"); - Timer sig_timer(padding + " signature"); - - while(verify_timer.seconds() < seconds || - sig_timer.seconds() < seconds) - { - keygen_timer.start(); - RW_PrivateKey key(rng, keylen); - keygen_timer.stop(); - - PK_Signer sig(key, padding); - PK_Verifier ver(key, padding); - - benchmark_sig_ver(ver, sig, verify_timer, sig_timer, - rng, 10000, seconds); - } - - const std::string nm = "RW-" + std::to_string(keylen); - report.report(nm, keygen_timer); - report.report(nm, verify_timer); - report.report(nm, sig_timer); - } - } -#endif - -#if defined(BOTAN_HAS_ECDSA) - -void benchmark_ecdsa(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - for(size_t j = 0; ec_domains[j]; j++) - { - EC_Group params(ec_domains[j]); - - const size_t pbits = params.get_curve().get_p().bits(); - - size_t hashbits = pbits; - - if(hashbits <= 192) - hashbits = 160; - if(hashbits == 521) - hashbits = 512; - - const std::string padding = "EMSA1(SHA-" + std::to_string(hashbits) + ")"; - - Timer keygen_timer("keygen"); - Timer verify_timer(padding + " verify"); - Timer sig_timer(padding + " signature"); - - while(verify_timer.seconds() < seconds || - sig_timer.seconds() < seconds) - { - keygen_timer.start(); - ECDSA_PrivateKey key(rng, params); - keygen_timer.stop(); - - PK_Signer sig(key, padding, IEEE_1363); - PK_Verifier ver(key, padding); - - benchmark_sig_ver(ver, sig, verify_timer, - sig_timer, rng, 1000, seconds); - } - - const std::string nm = "ECDSA-" + std::to_string(pbits); - - report.report(nm, keygen_timer); - report.report(nm, verify_timer); - report.report(nm, sig_timer); - } - } - -#endif - -#if defined(BOTAN_HAS_GOST_34_10_2001) - -void benchmark_gost_3410(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - for(size_t j = 0; ec_domains[j]; j++) - { - EC_Group params(ec_domains[j]); - - const size_t pbits = params.get_curve().get_p().bits(); - - const std::string padding = "EMSA1(GOST-34.11)"; - - Timer keygen_timer("keygen"); - Timer verify_timer(padding + " verify"); - Timer sig_timer(padding + " signature"); - - while(verify_timer.seconds() < seconds || - sig_timer.seconds() < seconds) - { - keygen_timer.start(); - GOST_3410_PrivateKey key(rng, params); - keygen_timer.stop(); - - PK_Signer sig(key, padding, IEEE_1363); - PK_Verifier ver(key, padding); - - benchmark_sig_ver(ver, sig, verify_timer, - sig_timer, rng, 1000, seconds); - } - - const std::string nm = "GOST-34.10-" + std::to_string(pbits); - - report.report(nm, keygen_timer); - report.report(nm, verify_timer); - report.report(nm, sig_timer); - } - } - -#endif - -#if defined(BOTAN_HAS_ECDH) - -void benchmark_ecdh(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - for(size_t j = 0; ec_domains[j]; j++) - { - EC_Group params(ec_domains[j]); - - size_t pbits = params.get_curve().get_p().bits(); - - Timer keygen_timer("keygen"); - Timer kex_timer("key exchange"); - - while(kex_timer.seconds() < seconds) - { - keygen_timer.start(); - ECDH_PrivateKey ecdh1(rng, params); - keygen_timer.stop(); - - keygen_timer.start(); - ECDH_PrivateKey ecdh2(rng, params); - keygen_timer.stop(); - - PK_Key_Agreement ka1(ecdh1, "KDF2(SHA-1)"); - PK_Key_Agreement ka2(ecdh2, "KDF2(SHA-1)"); - - SymmetricKey secret1, secret2; - - for(size_t i = 0; i != 1000; ++i) - { - if(kex_timer.seconds() > seconds) - break; - - kex_timer.start(); - secret1 = ka1.derive_key(32, ecdh2.public_value()); - kex_timer.stop(); - - kex_timer.start(); - secret2 = ka2.derive_key(32, ecdh1.public_value()); - kex_timer.stop(); - - if(secret1 != secret2) - std::cerr << "ECDH secrets did not match" << std::endl; - } - } - - const std::string nm = "ECDH-" + std::to_string(pbits); - report.report(nm, keygen_timer); - report.report(nm, kex_timer); - } - } - -#endif - -template -void benchmark_dsa_nr(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) || defined(BOTAN_HAS_DSA) - const char* domains[] = { "dsa/jce/1024", - "dsa/botan/2048", - "dsa/botan/3072", - nullptr }; - - std::string algo_name; - - for(size_t j = 0; domains[j]; j++) - { - size_t pbits = to_u32bit(split_on(domains[j], '/')[2]); - size_t qbits = (pbits <= 1024) ? 160 : 256; - - const std::string padding = "EMSA1(SHA-" + std::to_string(qbits) + ")"; - - Timer keygen_timer("keygen"); - Timer verify_timer(padding + " verify"); - Timer sig_timer(padding + " signature"); - - while(verify_timer.seconds() < seconds || - sig_timer.seconds() < seconds) - { - DL_Group group(domains[j]); - - keygen_timer.start(); - PRIV_KEY_TYPE key(rng, group); - algo_name = key.algo_name(); - keygen_timer.stop(); - - PK_Signer sig(key, padding, IEEE_1363); - PK_Verifier ver(key, padding); - - benchmark_sig_ver(ver, sig, verify_timer, - sig_timer, rng, 1000, seconds); - } - - const std::string nm = algo_name + "-" + std::to_string(pbits); - report.report(nm, keygen_timer); - report.report(nm, verify_timer); - report.report(nm, sig_timer); - } -#endif - } - -#if defined(BOTAN_HAS_CURVE_25519) -void benchmark_curve25519(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - Timer keygen_timer("keygen"); - Timer kex_timer("key exchange"); - - while(kex_timer.seconds() < seconds) - { - keygen_timer.start(); - Curve25519_PrivateKey key1(rng); - keygen_timer.stop(); - - keygen_timer.start(); - Curve25519_PrivateKey key2(rng); - keygen_timer.stop(); - - PK_Key_Agreement ka1(key1, "KDF2(SHA-256)"); - PK_Key_Agreement ka2(key2, "KDF2(SHA-256)"); - - SymmetricKey secret1, secret2; - - for(size_t i = 0; i != 1000; ++i) - { - if(kex_timer.seconds() > seconds) - break; - - kex_timer.start(); - secret1 = ka1.derive_key(32, key2.public_value()); - kex_timer.stop(); - - kex_timer.start(); - secret2 = ka2.derive_key(32, key1.public_value()); - kex_timer.stop(); - - if(secret1 != secret2) - std::cerr << "Curve25519 secrets did not match" << std::endl; - } - } - - const std::string nm = "Curve25519"; - report.report(nm, keygen_timer); - report.report(nm, kex_timer); - } -#endif - -#ifdef BOTAN_HAS_DIFFIE_HELLMAN -void benchmark_dh(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - const char* domains[] = { "modp/ietf/1024", - "modp/ietf/2048", - "modp/ietf/3072", - "modp/ietf/4096", - "modp/ietf/6144", - "modp/ietf/8192", - nullptr }; - - for(size_t j = 0; domains[j]; j++) - { - Timer keygen_timer("keygen"); - Timer kex_timer("key exchange"); - - while(kex_timer.seconds() < seconds) - { - DL_Group group(domains[j]); - - keygen_timer.start(); - DH_PrivateKey dh1(rng, group); - keygen_timer.stop(); - - keygen_timer.start(); - DH_PrivateKey dh2(rng, group); - keygen_timer.stop(); - - PK_Key_Agreement ka1(dh1, "KDF2(SHA-1)"); - PK_Key_Agreement ka2(dh2, "KDF2(SHA-1)"); - - SymmetricKey secret1, secret2; - - for(size_t i = 0; i != 1000; ++i) - { - if(kex_timer.seconds() > seconds) - break; - - kex_timer.start(); - secret1 = ka1.derive_key(32, dh2.public_value()); - kex_timer.stop(); - - kex_timer.start(); - secret2 = ka2.derive_key(32, dh1.public_value()); - kex_timer.stop(); - - if(secret1 != secret2) - std::cerr << "DH secrets did not match" << std::endl; - } - } - - const std::string nm = "DH-" + split_on(domains[j], '/')[2]; - report.report(nm, keygen_timer); - report.report(nm, kex_timer); - } - } -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) && defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_KDF2) -void benchmark_dlies(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - const char* domains[] = { "modp/ietf/768", - "modp/ietf/1024", - "modp/ietf/2048", - "modp/ietf/3072", - "modp/ietf/4096", - "modp/ietf/6144", - "modp/ietf/8192", - nullptr }; - - for(size_t j = 0; domains[j]; j++) - { - Timer keygen_timer("keygen"); - Timer kex_timer("key exchange"); - - Timer enc_timer("encrypt"); - Timer dec_timer("decrypt"); - - while(enc_timer.seconds() < seconds || dec_timer.seconds() < seconds) - { - DL_Group group(domains[j]); - - keygen_timer.start(); - DH_PrivateKey dh1_priv(rng, group); - keygen_timer.stop(); - - keygen_timer.start(); - DH_PrivateKey dh2_priv(rng, group); - keygen_timer.stop(); - - DH_PublicKey dh2_pub(dh2_priv); - - DLIES_Encryptor dlies_enc(dh1_priv, - new KDF2(new SHA_160), - new HMAC(new SHA_160)); - - dlies_enc.set_other_key(dh2_pub.public_value()); - - DLIES_Decryptor dlies_dec(dh2_priv, - new KDF2(new SHA_160), - new HMAC(new SHA_160)); - - benchmark_enc_dec(dlies_enc, dlies_dec, - enc_timer, dec_timer, rng, - 1000, seconds); - } - - const std::string nm = "DLIES-" + split_on(domains[j], '/')[2]; - report.report(nm, keygen_timer); - report.report(nm, enc_timer); - report.report(nm, dec_timer); - } - } -#endif - -#ifdef BOTAN_HAS_ELGAMAL -void benchmark_elg(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - const char* domains[] = { "modp/ietf/768", - "modp/ietf/1024", - "modp/ietf/2048", - "modp/ietf/3072", - "modp/ietf/4096", - "modp/ietf/6144", - "modp/ietf/8192", - nullptr }; - - const std::string algo_name = "ElGamal"; - - for(size_t j = 0; domains[j]; j++) - { - size_t pbits = to_u32bit(split_on(domains[j], '/')[2]); - - const std::string padding = "EME1(SHA-1)"; - - Timer keygen_timer("keygen"); - Timer enc_timer(padding + " encrypt"); - Timer dec_timer(padding + " decrypt"); - - while(enc_timer.seconds() < seconds || - dec_timer.seconds() < seconds) - { - DL_Group group(domains[j]); - - keygen_timer.start(); - ElGamal_PrivateKey key(rng, group); - keygen_timer.stop(); - - PK_Decryptor_EME dec(key, padding); - PK_Encryptor_EME enc(key, padding); - - benchmark_enc_dec(enc, dec, enc_timer, dec_timer, - rng, 1000, seconds); - } - - const std::string nm = algo_name + "-" + std::to_string(pbits); - report.report(nm, keygen_timer); - report.report(nm, enc_timer); - report.report(nm, dec_timer); - } - } -#endif - -#if defined(BOTAN_HAS_MCELIECE) -void benchmark_mce(RandomNumberGenerator& rng, - double seconds, - Benchmark_Report& report) - { - const std::vector> params = { - { 1024, 35 }, - { 2048, 50 }, - { 2960, 56 }, - { 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"); - - keygen_timer.start(); - McEliece_PrivateKey priv_key(rng, param.first, param.second); - McEliece_PublicKey pub_key(priv_key.x509_subject_public_key()); - keygen_timer.stop(); - - McEliece_KEM_Encryptor enc_kem(pub_key); - McEliece_KEM_Decryptor dec_kem(priv_key); - - while(enc_timer.seconds() < seconds || - dec_timer.seconds() < seconds) - { - enc_timer.start(); - auto enc_pair = enc_kem.encrypt(rng); - enc_timer.stop(); - - dec_timer.start(); - auto dec_key = dec_kem.decrypt_vec(enc_pair.first); - dec_timer.stop(); - - BOTAN_ASSERT_EQUAL(enc_pair.second, dec_key, "KEM result matches"); - } - - const std::string nm = algo_name + "-" + - std::to_string(param.first) + "," + - 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)"; - - report.report(nm + " " + keysize_report.str(), keygen_timer); - report.report(nm, enc_timer); - report.report(nm, dec_timer); - } - } -#endif - -} - -void bench_pk(RandomNumberGenerator& rng, - const std::string& algo, double seconds) - { - /* - There is some strangeness going on here. It looks like algorithms - at the end take some kind of penalty. For example, running the RW tests - first got a result of: - RW-1024: 148.14 ms / private operation - but running them last output: - RW-1024: 363.54 ms / private operation - - I think it's from memory fragmentation in the allocators, but I'm - not really sure. Need to investigate. - - Until then, I've basically ordered the tests in order of most important - algorithms (RSA, DSA) to least important (NR, RW). - - This strange behaviour does not seem to occur with DH (?) - - To get more accurate runs, use --bench-algo (RSA|DSA|DH|ELG|NR); in this - case the distortion is less than 5%, which is good enough. - - We do random keys with the DL schemes, since it's so easy and fast to - generate keys for them. For RSA and RW, we load the keys from a file. The - RSA keys are stored in a PKCS #8 structure, while RW is stored in a more - ad-hoc format (the RW algorithm has no assigned OID that I know of, so - there is no way to encode a RW key into a PKCS #8 structure). - */ - - Benchmark_Report report; - -#if defined(BOTAN_HAS_RSA) - if(algo == "All" || algo == "RSA") - benchmark_rsa(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_DSA) - if(algo == "All" || algo == "DSA") - benchmark_dsa_nr(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_ECDSA) - if(algo == "All" || algo == "ECDSA") - benchmark_ecdsa(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_ECDH) - if(algo == "All" || algo == "ECDH") - benchmark_ecdh(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_GOST_34_10_2001) - if(algo == "All" || algo == "GOST-34.10") - benchmark_gost_3410(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_CURVE_25519) - if(algo == "All" || algo == "Curve25519") - benchmark_curve25519(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - if(algo == "All" || algo == "DH") - benchmark_dh(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) && defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_KDF2) - if(algo == "All" || algo == "DLIES") - benchmark_dlies(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_ELGAMAL) - if(algo == "All" || algo == "ELG" || algo == "ElGamal") - benchmark_elg(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) - if(algo == "All" || algo == "NR") - benchmark_dsa_nr(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_RW) - if(algo == "All" || algo == "RW") - benchmark_rw(rng, seconds, report); -#endif - -#if defined(BOTAN_HAS_MCELIECE) - if(algo == "All" || algo == "McEliece") - benchmark_mce(rng, seconds, report); -#endif - } -#endif // BOTAN_HAS_PUBLIC_KEY_CRYPTO diff --git a/src/cmd/timer.cpp b/src/cmd/timer.cpp deleted file mode 100644 index 14e55316b..000000000 --- a/src/cmd/timer.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include "timer.h" -#include -#include - -void Timer::start() - { - stop(); - m_timer_start = get_clock(); - } - -void Timer::stop() - { - if(m_timer_start) - { - const u64bit now = get_clock(); - - if(now > m_timer_start) - m_time_used += (now - m_timer_start); - - m_timer_start = 0; - ++m_event_count; - } - } - -u64bit Timer::get_clock() - { - auto now = std::chrono::high_resolution_clock::now().time_since_epoch(); - return std::chrono::duration_cast(now).count(); - } - -std::ostream& operator<<(std::ostream& out, Timer& timer) - { - //out << timer.value() << " "; - - double events_per_second_fl = - static_cast(timer.events() / timer.seconds()); - - u64bit events_per_second = static_cast(events_per_second_fl); - - out << events_per_second << " " << timer.get_name() << " per second; "; - - std::string op_or_ops = (timer.events() == 1) ? "op" : "ops"; - - const std::ios::fmtflags flags = out.flags(); - - out << std::setprecision(2) << std::fixed - << timer.ms_per_event() << " ms/op" - << " (" << timer.events() << " " << op_or_ops << " in " - << timer.milliseconds() << " ms)"; - - out.flags(flags); - - return out; - } diff --git a/src/cmd/timer.h b/src/cmd/timer.h deleted file mode 100644 index ac5bd5cef..000000000 --- a/src/cmd/timer.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* (C) 2014 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_BENCHMARK_TIMER_H__ -#define BOTAN_BENCHMARK_TIMER_H__ - -#include -#include -#include - -using Botan::u64bit; -using Botan::u32bit; - -class Timer - { - public: - static u64bit get_clock(); - - Timer(const std::string& name, u32bit event_mult = 1) : - m_name(name), m_event_mult(event_mult) {} - - void start(); - void stop(); - - u64bit value() { stop(); return m_time_used; } - double seconds() { return milliseconds() / 1000.0; } - double milliseconds() { return value() / 1000000.0; } - - double ms_per_event() { return milliseconds() / events(); } - double seconds_per_event() { return seconds() / events(); } - - u64bit events() const { return m_event_count * m_event_mult; } - std::string get_name() const { return m_name; } - private: - std::string m_name; - u64bit m_time_used = 0, m_timer_start = 0; - u64bit m_event_count = 0, m_event_mult = 0; - }; - -inline bool operator<(const Timer& x, const Timer& y) - { - return (x.get_name() < y.get_name()); - } - -inline bool operator==(const Timer& x, const Timer& y) - { - return (x.get_name() == y.get_name()); - } - -std::ostream& operator<<(std::ostream&, Timer&); - -#endif diff --git a/src/lib/misc/benchmark/benchmark.cpp b/src/lib/misc/benchmark/benchmark.cpp index 90d8b1aca..152b45d37 100644 --- a/src/lib/misc/benchmark/benchmark.cpp +++ b/src/lib/misc/benchmark/benchmark.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -153,19 +154,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 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/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 @@ -112,6 +112,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 */ -- cgit v1.2.3 From a063dbe048a7434863de9b3bdf03d9f1409dbca4 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Fri, 21 Aug 2015 14:54:12 +0200 Subject: Add m_ prefix to member variable Power_Mod::m_core --- src/lib/math/numbertheory/pow_mod.cpp | 44 +++++++++++++++++------------------ src/lib/math/numbertheory/pow_mod.h | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/lib') 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; }; /** -- cgit v1.2.3 From ca155a7e54ec39e60f9dd6c53567ebf283b3e8d0 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 21 Aug 2015 19:21:16 -0400 Subject: Add power analysis countermeasures for ECC point multiplications. The plain PointGFp operator* now uses Montgomery ladder exclusively. Adds a blinded point multiply algorithm which uses exponent and point randomization, as well as a Montgomery ladder technique that takes a random walk of the possible addition chains for k. --- src/lib/math/ec_gfp/point_gfp.cpp | 328 +++++++++++++++++++++------------ src/lib/math/ec_gfp/point_gfp.h | 51 +++-- src/lib/pubkey/ecdsa/ecdsa.cpp | 34 ++-- src/lib/pubkey/gost_3410/gost_3410.cpp | 38 ++-- src/lib/rng/rng.h | 30 ++- src/tests/test_bigint.cpp | 49 ----- src/tests/test_ecdsa.cpp | 5 +- src/tests/tests.cpp | 1 + src/tests/tests.h | 67 ++++++- src/tests/unit_ecc.cpp | 50 +++-- 10 files changed, 411 insertions(+), 242 deletions(-) (limited to 'src/lib') diff --git a/src/lib/math/ec_gfp/point_gfp.cpp b/src/lib/math/ec_gfp/point_gfp.cpp index 2505e4d54..a319d8657 100644 --- a/src/lib/math/ec_gfp/point_gfp.cpp +++ b/src/lib/math/ec_gfp/point_gfp.cpp @@ -2,36 +2,55 @@ * 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 #include +#include namespace Botan { +const size_t BOTAN_POINTGFP_MONTGOMERY_BLINDING_BITS = 20; +const size_t BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS = 48; + +#define BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER 1 + 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) + { + 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) { - curve.to_rep(coord_x, ws); - curve.to_rep(coord_y, ws); - curve.to_rep(coord_z, ws); + BigInt mask(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 +58,15 @@ void PointGFp::add(const PointGFp& rhs, std::vector& 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 +83,13 @@ void PointGFp::add(const PointGFp& rhs, std::vector& 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 +109,10 @@ void PointGFp::add(const PointGFp& rhs, std::vector& 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 +122,22 @@ void PointGFp::add(const PointGFp& rhs, std::vector& 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 +145,9 @@ void PointGFp::mult2(std::vector& 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 +155,7 @@ void PointGFp::mult2(std::vector& 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 +167,17 @@ void PointGFp::mult2(std::vector& 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 +202,14 @@ void PointGFp::mult2(std::vector& 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 +243,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 ws(9); @@ -251,22 +273,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 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 +299,164 @@ 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_order(order), m_h(h ? h : 4), 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; + m_U.resize(1 << m_h); + m_U[0] = PointGFp::zero_of(curve); + m_U[1] = base; + + for(size_t i = 2; i < m_U.size(); ++i) + { + m_U[i] = m_U[i-1]; + m_U[i].add(base, m_ws); + } +#endif + } - std::vector Ps(1 << window_bits); - Ps[0] = x1; - Ps[1] = point; +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"); + + // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure) + const u64bit mask = rng.gen_mask(BOTAN_POINTGFP_MONTGOMERY_BLINDING_BITS); + const BigInt scalar = scalar_in + m_order * mask; + 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); + + /* + Algorithm 7 from "Randomizing the Montgomery Powering Ladder" + Duc-Phong Le, Chik How Tan and Michael Tunstall + http://eprint.iacr.org/2015/657 - for(size_t i = 2; i < Ps.size(); ++i) + 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--) { - Ps[i] = Ps[i-1]; - Ps[i].add(point, ws); + const int32_t ki = scalar.get_bit(i); + + // choose gamma from -h,...,h + const int32_t gamma = static_cast((rng.next_byte() % (2*m_h))) - m_h; + const int32_t l = gamma - 2*alpha + ki - (ki ^ 1); + + R.mult2(m_ws); + R.add(m_U.at(3*m_h + 1 + l), m_ws); + alpha = gamma; } - while(bits_left >= window_bits) + const int32_t k0 = scalar.get_bit(0); + R.add(m_U[3*m_h + 1 - alpha - (k0 ^ 1)], m_ws); + +#else + + size_t bits_left = scalar_bits; + + PointGFp R = m_U[0]; + + while(bits_left >= m_h) { - for(size_t i = 0; i != window_bits; ++i) - x1.mult2(ws); + for(size_t i = 0; i != m_h; ++i) + R.mult2(m_ws); - const u32bit nibble = scalar.get_substring(bits_left - window_bits, window_bits); - x1.add(Ps[nibble], ws); - bits_left -= window_bits; + const u32bit nibble = scalar.get_substring(bits_left - m_h, m_h); + R.add(m_U[nibble], m_ws); + bits_left -= m_h; } while(bits_left) { - x1.mult2(ws); + R.mult2(m_ws); if(scalar.get_bit(bits_left-1)) - x1.add(point, ws); + R.add(m_U[1], m_ws); --bits_left; } - #endif - if(scalar.is_negative()) - x1.negate(); + //BOTAN_ASSERT(R.on_the_curve(), "Output is on the curve"); - //BOTAN_ASSERT(x1.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 +470,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 +494,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..bb3438697 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 @@ -184,34 +190,41 @@ 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& workspace); - CurveGFp curve; - BigInt coord_x, coord_y, coord_z; - mutable secure_vector ws; // workspace for Montgomery + CurveGFp m_curve; + BigInt m_coord_x, m_coord_y, m_coord_z; + mutable secure_vector m_monty_ws; // workspace for Montgomery }; // relational operators @@ -270,6 +283,22 @@ template PointGFp OS2ECP(const std::vector& 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 BigInt& m_order; + const size_t m_h; + std::vector m_ws; + std::vector m_U; + }; + } namespace std { diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index 2518a14fe..c327a37c3 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 #include -#include #include #include @@ -41,9 +40,10 @@ class ECDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA 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 +52,36 @@ 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 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 = base_point * k; + 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 output(2*order.bytes()); + secure_vector 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/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 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 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 @@ -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 output(2*order.bytes()); + secure_vector 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/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,16 +47,34 @@ class BOTAN_DLL RandomNumberGenerator } /** - * Return a random byte - * @return random byte + * Only usable with POD types, only useful with integers + * get_random() */ - byte next_byte() + template T get_random() { - byte out; - this->randomize(&out, 1); - return out; + T r; + this->randomize(reinterpret_cast(&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() & mask; + } + + /** + * Return a random byte + * @return random byte + */ + byte next_byte() { return get_random(); } + /** * Check whether this RNG is seeded. * @return true if this RNG was already seeded, false otherwise. 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_ecdsa.cpp b/src/tests/test_ecdsa.cpp index a2ec8d115..8d385b4bf 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(); @@ -39,7 +38,7 @@ size_t ecdsa_sig_kat(const std::string& group_id, PK_Signer sign(ecdsa, padding); return validate_signature(verify, sign, "ECDSA/" + group_id + '/' + hash, - msg, rng, nonce, signature); + msg, rng, signature); } } @@ -53,7 +52,7 @@ size_t test_ecdsa() fails += run_tests_bb(ecdsa_sig, "ECDSA Signature", "Signature", false, [](std::map 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/tests.cpp b/src/tests/tests.cpp index 63e6761ac..763417209 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -304,6 +304,7 @@ int main(int argc, char* argv[]) DEF_TEST(mceliece); 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..14ec5a17b 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -16,6 +16,7 @@ #include #include #include +#include Botan::RandomNumberGenerator& test_rng(); @@ -45,7 +46,69 @@ typedef std::function test_fn; size_t run_tests(const std::vector>& 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,6 +138,7 @@ 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(); @@ -94,6 +158,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..3cb1436d3 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 groups = { +namespace { + +const std::vector 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,8 +946,6 @@ size_t test_ecc_unit() test_report("ECC", 0, fails); - ecc_randomized_test(); - return fails; } -- cgit v1.2.3 From 9aa2b72c0cc8792b736fcd8016f5dec901f1ecdd Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 21 Aug 2015 19:34:10 -0400 Subject: In RSA, check that the input is less than the modulus n before blinding rather than after. After blinding the value is always reduced mod n so the condition is never met. This may be the cause of RSA test failures described in GH #174 The scenario was that during randomized corruption tests we occasionally provide an input which was greater than the modulus. When that happened the value was effectively reduced mod n, so the self-check would later fail, because the decrypted result (reduced mod n) would be compared with the original (larger than n) input. --- src/lib/pubkey/rsa/rsa.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/lib') 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); } }; -- cgit v1.2.3 From c019ed737729d61dc50a4f8446a7b896add05a16 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 21 Aug 2015 19:41:42 -0400 Subject: Missing add --- src/lib/pubkey/pk_utils.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/lib') 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 #include #include +#include #include namespace Botan { -- cgit v1.2.3 From 04f422d744c4f6db7881f9e2d7caf7c6fc6dcd82 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 22 Aug 2015 20:56:11 -0400 Subject: Remove high bit set char from comment as it broke amalgamation generation under Python3. Ironically there doesn't seem to be any way to portably handle non-ASCII in a way that is compatible with Python 2.7 and 3 at the same time. --- src/lib/asn1/asn1_time.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/lib') 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; -- cgit v1.2.3 From ce849c364c29ce020369685ce8d221f8e67cf538 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 24 Aug 2015 07:46:51 -0400 Subject: Guard rlimit reset with a defined check for RLIMIT_MEMLOCK as it is missing on Solaris at least. On such systems it's probably safe to assume that no amount of memory can be mlock'ed from userspace, so just return zero to disable the allocator entirely. GH #262 --- src/lib/alloc/locking_allocator/locking_allocator.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/lib') diff --git a/src/lib/alloc/locking_allocator/locking_allocator.cpp b/src/lib/alloc/locking_allocator/locking_allocator.cpp index 6a9cc2579..ec294d8f0 100644 --- a/src/lib/alloc/locking_allocator/locking_allocator.cpp +++ b/src/lib/alloc/locking_allocator/locking_allocator.cpp @@ -26,7 +26,9 @@ 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 +39,9 @@ size_t reset_mlock_limit(size_t max_req) } return std::min(limits.rlim_cur, max_req); +#endif + + return 0; } size_t mlock_limit() -- cgit v1.2.3 From 294b66f579b6892fc60a88c27790c9da9da8c590 Mon Sep 17 00:00:00 2001 From: Daniel Seither Date: Fri, 28 Aug 2015 16:23:03 +0200 Subject: Compression: Prevent undefined behavior when feeding empty input &emptyVector[n] triggers undefined behavior because it is an out-of- bounds access, even if n == 0. emptyVector.data() does not (but may return nullptr). --- src/lib/compression/compression.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/lib') diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp index 6057f9408..22ee700b6 100644 --- a/src/lib/compression/compression.cpp +++ b/src/lib/compression/compression.cpp @@ -104,8 +104,8 @@ void Stream_Compression::process(secure_vector& 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); + 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 +115,7 @@ void Stream_Compression::process(secure_vector& 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 +170,8 @@ void Stream_Decompression::process(secure_vector& 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 +189,14 @@ void Stream_Decompression::process(secure_vector& 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) { -- cgit v1.2.3 From 584cc4c0aca4b037fd04f8d37c53757aecf2062f Mon Sep 17 00:00:00 2001 From: Daniel Seither Date: Fri, 28 Aug 2015 16:26:31 +0200 Subject: Compression: Fix zlib failure on compression of empty input zlib treats a nullptr output buffer as an error. This commit fixes the failing compression tests. --- src/lib/compression/compression.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/lib') diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp index 22ee700b6..ddbcd7cec 100644 --- a/src/lib/compression/compression.cpp +++ b/src/lib/compression/compression.cpp @@ -104,6 +104,14 @@ void Stream_Compression::process(secure_vector& buf, size_t offset, u32bit if(m_buffer.size() < buf.size() + offset) m_buffer.resize(buf.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); -- cgit v1.2.3 From 937426a903c2199fb677082f92038b14dc0b519e Mon Sep 17 00:00:00 2001 From: bogdan Date: Sat, 29 Aug 2015 01:15:12 +0300 Subject: Make the equality operators standard-compliant. The equality operators need to support different specializations as well; this is also part of the standard allocator requirements. --- src/lib/alloc/secmem.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/lib') diff --git a/src/lib/alloc/secmem.h b/src/lib/alloc/secmem.h index 453acc5d8..63d4e5296 100644 --- a/src/lib/alloc/secmem.h +++ b/src/lib/alloc/secmem.h @@ -85,12 +85,12 @@ class secure_allocator template void destroy(U* p) { p->~U(); } }; -template inline bool -operator==(const secure_allocator&, const secure_allocator&) +template inline bool +operator==(const secure_allocator&, const secure_allocator&) { return true; } -template inline bool -operator!=(const secure_allocator&, const secure_allocator&) +template inline bool +operator!=(const secure_allocator&, const secure_allocator&) { return false; } template using secure_vector = std::vector>; -- cgit v1.2.3 From 1502e1efcb3ac37c4e0b0176b9c3042bcb6c9069 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 28 Aug 2015 19:49:29 -0400 Subject: Gzip_Decompression should be a subclass of Stream_Decompression GH #264 --- src/lib/compression/zlib/zlib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/compression/zlib/zlib.h b/src/lib/compression/zlib/zlib.h index 19bae3480..d968a1804 100644 --- a/src/lib/compression/zlib/zlib.h +++ b/src/lib/compression/zlib/zlib.h @@ -106,7 +106,7 @@ 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"; } -- cgit v1.2.3 From 9c3d1e61185768a5a2b184b0705ff46b41fe255c Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 28 Aug 2015 19:49:58 -0400 Subject: Add override specifiers to zlib.h --- src/lib/compression/zlib/zlib.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/lib') diff --git a/src/lib/compression/zlib/zlib.h b/src/lib/compression/zlib/zlib.h index d968a1804..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; @@ -112,7 +112,7 @@ class BOTAN_DLL Gzip_Decompression : public Stream_Decompression std::string name() const override { return "Gzip_Decompression"; } private: - Compression_Stream* make_stream() const; + Compression_Stream* make_stream() const override; }; } -- cgit v1.2.3 From 89ae754db15c9e78ddd52cf7cd92caf253a2bd81 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 28 Aug 2015 19:50:57 -0400 Subject: Use 16 byte alignment for all allocations in the mlock allocator --- src/lib/alloc/locking_allocator/locking_allocator.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/lib') diff --git a/src/lib/alloc/locking_allocator/locking_allocator.cpp b/src/lib/alloc/locking_allocator/locking_allocator.cpp index ec294d8f0..c145cfd7f 100644 --- a/src/lib/alloc/locking_allocator/locking_allocator.cpp +++ b/src/lib/alloc/locking_allocator/locking_allocator.cpp @@ -18,12 +18,6 @@ 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) @@ -104,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! -- cgit v1.2.3 From e76e1f5f41b2ead518061a33ebc833f5c642bc34 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 28 Aug 2015 20:17:40 -0400 Subject: Move GF(p) side channel countermeasure toggles to build.h Some tweaks for point multiplication using fixed windows. --- src/build-data/buildh.in | 16 +++++++++ src/lib/math/ec_gfp/point_gfp.cpp | 69 ++++++++++++++++++++++++--------------- src/lib/math/ec_gfp/point_gfp.h | 2 +- 3 files changed, 59 insertions(+), 28 deletions(-) (limited to 'src/lib') diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index 5db2ce566..eaf4181b5 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -57,6 +57,22 @@ * If enabled the ECC implementation will use Montgomery ladder * instead of a fixed window implementation. */ +#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 64 + #define BOTAN_CURVE_GFP_USE_MONTGOMERY_LADDER 0 /* PK key consistency checking toggles */ diff --git a/src/lib/math/ec_gfp/point_gfp.cpp b/src/lib/math/ec_gfp/point_gfp.cpp index a319d8657..705b14c52 100644 --- a/src/lib/math/ec_gfp/point_gfp.cpp +++ b/src/lib/math/ec_gfp/point_gfp.cpp @@ -10,13 +10,10 @@ #include #include #include +#include namespace Botan { -const size_t BOTAN_POINTGFP_MONTGOMERY_BLINDING_BITS = 20; -const size_t BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS = 48; - -#define BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER 1 PointGFp::PointGFp(const CurveGFp& curve) : m_curve(curve), @@ -42,15 +39,20 @@ PointGFp::PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y) : void PointGFp::randomize_repr(RandomNumberGenerator& rng) { - BigInt mask(rng, BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS, false); + 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_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); + 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 @@ -317,7 +319,7 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point) } Blinded_Point_Multiply::Blinded_Point_Multiply(const PointGFp& base, const BigInt& order, size_t h) : - m_order(order), m_h(h ? h : 4), m_ws(9) + 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) @@ -362,9 +364,14 @@ PointGFp Blinded_Point_Multiply::blinded_multiply(const BigInt& scalar_in, 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 u64bit mask = rng.gen_mask(BOTAN_POINTGFP_MONTGOMERY_BLINDING_BITS); + 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) @@ -403,26 +410,34 @@ PointGFp Blinded_Point_Multiply::blinded_multiply(const BigInt& scalar_in, #else - size_t bits_left = scalar_bits; + // N-bit windowing exponentiation: + + size_t windows = round_up(scalar_bits, m_h) / m_h; PointGFp R = m_U[0]; - while(bits_left >= m_h) + if(windows > 0) { - for(size_t i = 0; i != m_h; ++i) - R.mult2(m_ws); - - const u32bit nibble = scalar.get_substring(bits_left - m_h, m_h); + windows--; + const u32bit nibble = scalar.get_substring(windows*m_h, m_h); R.add(m_U[nibble], m_ws); - bits_left -= m_h; - } - while(bits_left) - { - R.mult2(m_ws); - if(scalar.get_bit(bits_left-1)) - R.add(m_U[1], m_ws); - --bits_left; + /* + 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 diff --git a/src/lib/math/ec_gfp/point_gfp.h b/src/lib/math/ec_gfp/point_gfp.h index bb3438697..206e43155 100644 --- a/src/lib/math/ec_gfp/point_gfp.h +++ b/src/lib/math/ec_gfp/point_gfp.h @@ -293,8 +293,8 @@ class BOTAN_DLL Blinded_Point_Multiply PointGFp blinded_multiply(const BigInt& scalar, RandomNumberGenerator& rng); private: - const BigInt& m_order; const size_t m_h; + const BigInt& m_order; std::vector m_ws; std::vector m_U; }; -- cgit v1.2.3 From 200e1e5c0498d5b22f980d43cc03981ea9599660 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 28 Aug 2015 20:24:57 -0400 Subject: Remove unused variable --- src/lib/pubkey/ecdsa/ecdsa.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/lib') diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index c327a37c3..4a4b0c037 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -39,7 +39,6 @@ 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()), m_order(ecdsa.domain().get_order()), m_base_point(ecdsa.domain().get_base_point(), m_order), m_x(ecdsa.private_value()), @@ -56,7 +55,6 @@ class ECDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA size_t max_input_bits() const override { return m_order.bits(); } private: - const PointGFp& base_point; const BigInt& m_order; Blinded_Point_Multiply m_base_point; const BigInt& m_x; @@ -72,7 +70,6 @@ ECDSA_Signature_Operation::raw_sign(const byte msg[], size_t msg_len, const BigInt k = generate_rfc6979_nonce(m_x, m_order, m, m_hash); - //const PointGFp k_times_P = base_point * k; 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)); -- cgit v1.2.3 From 582ee4a3102bbbd8a7710ad32d380a9cc7b7aca4 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 28 Aug 2015 20:29:47 -0400 Subject: Add ECDSA provider using OpenSSL Unfortunately the signer cannot be tested in current framework because OpenSSL does not use RFC 6979 deterministic signatures. --- doc/news.rst | 4 +- src/lib/vendor/openssl/openssl_ecdsa.cpp | 217 +++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 src/lib/vendor/openssl/openssl_ecdsa.cpp (limited to 'src/lib') diff --git a/doc/news.rst b/doc/news.rst index 101dd370b..73d024c51 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -6,7 +6,9 @@ Version 1.11.20, Not Yet Released * Additional countermeasures were added to ECC point multiplications to help protect against side channel attacks. - + +* An ECDSA provider using OpenSSL has been added. + * On OS X, rename libs to avoid trailing version numbers, e.g. libbotan-1.11.dylib.19 -> libbotan-1.11.19.dylib. Gh #241 diff --git a/src/lib/vendor/openssl/openssl_ecdsa.cpp b/src/lib/vendor/openssl/openssl_ecdsa.cpp new file mode 100644 index 000000000..9016986da --- /dev/null +++ b/src/lib/vendor/openssl/openssl_ecdsa.cpp @@ -0,0 +1,217 @@ +/* +* ECDSA via OpenSSL +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +#include +#include + +#if defined(BOTAN_HAS_ECDSA) && !defined(OPENSSL_NO_ECDSA) + +#include +#include +#include +#include + +#include +#include +#include + +namespace Botan { + +namespace { + +secure_vector 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(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(); + } + +class OpenSSL_Error : public Exception + { + public: + OpenSSL_Error(const std::string& what) : + Exception(what + " failed: " + ERR_error_string(ERR_get_error(), nullptr)) {} + }; + +int OpenSSL_EC_nid_for(const OID& oid) + { + if(oid.empty()) + return -1; + + static const std::map 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(&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> 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 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> 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> 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(&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 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 raw_sign(const byte msg[], size_t msg_len, + RandomNumberGenerator&) override + { + std::unique_ptr> 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 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> 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", 255); + +BOTAN_REGISTER_TYPE(PK_Ops::Signature, OpenSSL_ECDSA_Signing_Operation, "ECDSA", + OpenSSL_ECDSA_Signing_Operation::make, "openssl", 255); + +} + +} + +#endif // BOTAN_HAS_ECDSA && !OPENSSL_NO_ECDSA -- cgit v1.2.3 From 1b5819fb2f1eca1ef6a58a9a3c8a6cd6291a6c17 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 28 Aug 2015 20:32:34 -0400 Subject: Avoid a crash in the TLS server if the client sends ALPN but no next protocol handler was specified to the Server constructor. GH #252 --- src/lib/tls/tls_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') 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) -- cgit v1.2.3 From d9de3157bc1d06c4f5f250b5b7ef635474973c85 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 29 Aug 2015 07:55:30 -0400 Subject: Fix minimized builds and amalgamation builds No need to include the pk_utils.h header until we know ECDSA is enabled in the build. Move OpenSSL_Error to an internal header, was previously defined twice when all sources were combined. --- src/lib/vendor/openssl/info.txt | 4 ++++ src/lib/vendor/openssl/openssl.h | 28 ++++++++++++++++++++++++++++ src/lib/vendor/openssl/openssl_ecdsa.cpp | 15 ++------------- src/lib/vendor/openssl/openssl_rsa.cpp | 9 +-------- 4 files changed, 35 insertions(+), 21 deletions(-) create mode 100644 src/lib/vendor/openssl/openssl.h (limited to 'src/lib') diff --git a/src/lib/vendor/openssl/info.txt b/src/lib/vendor/openssl/info.txt index a1faac3e3..0ca78a88e 100644 --- a/src/lib/vendor/openssl/info.txt +++ b/src/lib/vendor/openssl/info.txt @@ -1,5 +1,9 @@ load_on vendor + +openssl.h + + all -> crypto diff --git a/src/lib/vendor/openssl/openssl.h b/src/lib/vendor/openssl/openssl.h new file mode 100644 index 000000000..1ffaed519 --- /dev/null +++ b/src/lib/vendor/openssl/openssl.h @@ -0,0 +1,28 @@ +/* +* Utils for calling OpenSSL +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CALL_OPENSSL_H__ +#define BOTAN_CALL_OPENSSL_H__ + +#include +#include +#include + +#include + +namespace Botan { + +class OpenSSL_Error : public Exception + { + public: + OpenSSL_Error(const std::string& what) : + Exception(what + " failed: " + ERR_error_string(ERR_get_error(), nullptr)) {} + }; + +} + +#endif diff --git a/src/lib/vendor/openssl/openssl_ecdsa.cpp b/src/lib/vendor/openssl/openssl_ecdsa.cpp index 9016986da..9031944d4 100644 --- a/src/lib/vendor/openssl/openssl_ecdsa.cpp +++ b/src/lib/vendor/openssl/openssl_ecdsa.cpp @@ -5,13 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include -#include -#include -#include - +#include #include -#include #if defined(BOTAN_HAS_ECDSA) && !defined(OPENSSL_NO_ECDSA) @@ -19,6 +14,7 @@ #include #include #include +#include #include #include @@ -47,13 +43,6 @@ secure_vector PKCS8_for_openssl(const EC_PrivateKey& ec) .get_contents(); } -class OpenSSL_Error : public Exception - { - public: - OpenSSL_Error(const std::string& what) : - Exception(what + " failed: " + ERR_error_string(ERR_get_error(), nullptr)) {} - }; - int OpenSSL_EC_nid_for(const OID& oid) { if(oid.empty()) diff --git a/src/lib/vendor/openssl/openssl_rsa.cpp b/src/lib/vendor/openssl/openssl_rsa.cpp index ef86bf91a..ad2e47683 100644 --- a/src/lib/vendor/openssl/openssl_rsa.cpp +++ b/src/lib/vendor/openssl/openssl_rsa.cpp @@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include +#include #if defined(BOTAN_HAS_RSA) @@ -34,13 +34,6 @@ std::pair get_openssl_enc_pad(const std::string& eme) 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: -- cgit v1.2.3 From 3103f299dfd9517a4ef3c40358c1a4cad38b7305 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 29 Aug 2015 11:53:06 -0400 Subject: Reverse the algorithm priority ordering Previously 0 was the highest priority and 255 was the lowest. But this is really quite confusing, instead treat 0 as lowest and 255 as highest so normal integer intuitions apply. --- doc/news.rst | 7 +++++++ src/lib/base/algo_registry.h | 17 ++++++++++------- src/lib/block/aes_ni/aes_ni.cpp | 6 +++--- src/lib/block/aes_ssse3/aes_ssse3.cpp | 9 ++++++--- src/lib/block/idea_sse2/idea_sse2.cpp | 3 ++- src/lib/block/noekeon_simd/noekeon_simd.cpp | 3 ++- src/lib/block/serpent_simd/serp_simd.cpp | 3 ++- src/lib/block/threefish_avx2/threefish_avx2.cpp | 3 ++- src/lib/block/xtea_simd/xtea_simd.cpp | 3 ++- src/lib/hash/sha1_sse2/sha1_sse2.cpp | 3 ++- src/lib/vendor/openssl/info.txt | 2 ++ src/lib/vendor/openssl/openssl.h | 9 +++++++-- src/lib/vendor/openssl/openssl_block.cpp | 7 +++++-- src/lib/vendor/openssl/openssl_hash.cpp | 3 ++- src/lib/vendor/openssl/openssl_rc4.cpp | 4 +++- 15 files changed, 57 insertions(+), 25 deletions(-) (limited to 'src/lib') diff --git a/doc/news.rst b/doc/news.rst index 73d024c51..af46787fc 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -9,6 +9,13 @@ Version 1.11.20, Not Yet Released * An ECDSA provider using OpenSSL has been added. +* The ordering of algorithm priorities has been reversed. Previously + 255 was the lowest priority and 0 was the highest priority. Now it + is the reverse, with 0 being lowest priority and 255 being highest. + The default priority for the base algorithms is 100. This only + affects external providers or applications which directly set + provider preferences. + * On OS X, rename libs to avoid trailing version numbers, e.g. libbotan-1.11.dylib.19 -> libbotan-1.11.19.dylib. Gh #241 diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h index 918206577..498021194 100644 --- a/src/lib/base/algo_registry.h +++ b/src/lib/base/algo_registry.h @@ -152,7 +152,7 @@ class Algo_Registry return r; } private: - std::multimap m_prefs; + std::multimap> m_prefs; std::unordered_map m_maker_fns; }; @@ -224,24 +224,27 @@ make_new_T_1X(const typename Algo_Registry::Spec& spec) namespace { Algo_Registry::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, "base", 128) + BOTAN_REGISTER_TYPE(T, type, #type, make_new_T, "base", BOTAN_DEFAULT_ALGORITHM_PRIO) #define BOTAN_REGISTER_T_1LEN(T, type, def) \ - BOTAN_REGISTER_TYPE(T, type, #type, (make_new_T_1len), "base", 128) + BOTAN_REGISTER_TYPE(T, type, #type, (make_new_T_1len), "base", BOTAN_DEFAULT_ALGORITHM_PRIO) #define BOTAN_REGISTER_NAMED_T_NOARGS(T, type, name, provider) \ - BOTAN_REGISTER_TYPE(T, type, name, make_new_T, provider, 128) + BOTAN_REGISTER_TYPE(T, type, name, make_new_T, 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, provider, pref) #define BOTAN_REGISTER_NAMED_T_2LEN(T, type, name, provider, len1, len2) \ - BOTAN_REGISTER_TYPE(T, type, name, (make_new_T_2len), provider, 128) + BOTAN_REGISTER_TYPE(T, type, name, (make_new_T_2len), 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/block/aes_ni/aes_ni.cpp b/src/lib/block/aes_ni/aes_ni.cpp index 20aa63c54..29e729da4 100644 --- a/src/lib/block/aes_ni/aes_ni.cpp +++ b/src/lib/block/aes_ni/aes_ni.cpp @@ -12,9 +12,9 @@ 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); +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); namespace { diff --git a/src/lib/block/aes_ssse3/aes_ssse3.cpp b/src/lib/block/aes_ssse3/aes_ssse3.cpp index f0d506b6e..50acd7668 100644 --- a/src/lib/block/aes_ssse3/aes_ssse3.cpp +++ b/src/lib/block/aes_ssse3/aes_ssse3.cpp @@ -17,9 +17,12 @@ 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); +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); namespace { diff --git a/src/lib/block/idea_sse2/idea_sse2.cpp b/src/lib/block/idea_sse2/idea_sse2.cpp index af7e2182d..8549d74d7 100644 --- a/src/lib/block/idea_sse2/idea_sse2.cpp +++ b/src/lib/block/idea_sse2/idea_sse2.cpp @@ -12,7 +12,8 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_sse2(), IDEA_SSE2, "IDEA", "sse2", 64); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_sse2(), IDEA_SSE2, "IDEA", + "sse2", BOTAN_SIMD_ALGORITHM_PRIO); namespace { diff --git a/src/lib/block/noekeon_simd/noekeon_simd.cpp b/src/lib/block/noekeon_simd/noekeon_simd.cpp index a5d757d3c..a51c6bc8f 100644 --- a/src/lib/block/noekeon_simd/noekeon_simd.cpp +++ b/src/lib/block/noekeon_simd/noekeon_simd.cpp @@ -11,7 +11,8 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Noekeon_SIMD, "Noekeon", "simd32", 64); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Noekeon_SIMD, "Noekeon", + "simd32", BOTAN_SIMD_ALGORITHM_PRIO); /* * Noekeon's Theta Operation diff --git a/src/lib/block/serpent_simd/serp_simd.cpp b/src/lib/block/serpent_simd/serp_simd.cpp index 7b957598f..56747dd16 100644 --- a/src/lib/block/serpent_simd/serp_simd.cpp +++ b/src/lib/block/serpent_simd/serp_simd.cpp @@ -12,7 +12,8 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Serpent_SIMD, "Serpent", "simd32", 64); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Serpent_SIMD, "Serpent", + "simd32", BOTAN_SIMD_ALGORITHM_PRIO); namespace { diff --git a/src/lib/block/threefish_avx2/threefish_avx2.cpp b/src/lib/block/threefish_avx2/threefish_avx2.cpp index e17146162..435c75dbf 100644 --- a/src/lib/block/threefish_avx2/threefish_avx2.cpp +++ b/src/lib/block/threefish_avx2/threefish_avx2.cpp @@ -12,7 +12,8 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_avx2(), Threefish_512_AVX2, "Threefish-512", "avx2", 64); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_avx2(), Threefish_512_AVX2, "Threefish-512", + "avx2", BOTAN_SIMD_ALGORITHM_PRIO); namespace { diff --git a/src/lib/block/xtea_simd/xtea_simd.cpp b/src/lib/block/xtea_simd/xtea_simd.cpp index ffd2eb560..a9984ce23 100644 --- a/src/lib/block/xtea_simd/xtea_simd.cpp +++ b/src/lib/block/xtea_simd/xtea_simd.cpp @@ -11,7 +11,8 @@ namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), XTEA_SIMD, "XTEA", "simd32", 64); +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), XTEA_SIMD, "XTEA", + "simd32", BOTAN_SIMD_ALGORITHM_PRIO); namespace { diff --git a/src/lib/hash/sha1_sse2/sha1_sse2.cpp b/src/lib/hash/sha1_sse2/sha1_sse2.cpp index 1fc62d957..7cd457597 100644 --- a/src/lib/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/lib/hash/sha1_sse2/sha1_sse2.cpp @@ -14,7 +14,8 @@ namespace Botan { -BOTAN_REGISTER_HASH_NOARGS_IF(CPUID::has_sse2(), SHA_160_SSE2, "SHA-160", "sse2", 64); +BOTAN_REGISTER_HASH_NOARGS_IF(CPUID::has_sse2(), SHA_160_SSE2, "SHA-160", + "sse2", BOTAN_SIMD_ALGORITHM_PRIO); namespace SHA1_SSE2_F { diff --git a/src/lib/vendor/openssl/info.txt b/src/lib/vendor/openssl/info.txt index 0ca78a88e..1381e2019 100644 --- a/src/lib/vendor/openssl/info.txt +++ b/src/lib/vendor/openssl/info.txt @@ -1,3 +1,5 @@ +define OPENSSL 20150829 + load_on vendor diff --git a/src/lib/vendor/openssl/openssl.h b/src/lib/vendor/openssl/openssl.h index 1ffaed519..4fa37cc54 100644 --- a/src/lib/vendor/openssl/openssl.h +++ b/src/lib/vendor/openssl/openssl.h @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#ifndef BOTAN_CALL_OPENSSL_H__ -#define BOTAN_CALL_OPENSSL_H__ +#ifndef BOTAN_OPENSSL_H__ +#define BOTAN_OPENSSL_H__ #include #include @@ -23,6 +23,11 @@ class OpenSSL_Error : public Exception 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 + + } #endif diff --git a/src/lib/vendor/openssl/openssl_block.cpp b/src/lib/vendor/openssl/openssl_block.cpp index 4fd41112b..b74f184c7 100644 --- a/src/lib/vendor/openssl/openssl_block.cpp +++ b/src/lib/vendor/openssl/openssl_block.cpp @@ -6,6 +6,7 @@ */ #include +#include #include namespace Botan { @@ -165,14 +166,16 @@ make_evp_block_maker_keylen(const EVP_CIPHER* cipher, const char* algo, }; } +#define BOTAN_OPENSSL_BLOCK_PRIO 150 + #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/vendor/openssl/openssl_hash.cpp b/src/lib/vendor/openssl/openssl_hash.cpp index 6133e36a4..6e055c0e6 100644 --- a/src/lib/vendor/openssl/openssl_hash.cpp +++ b/src/lib/vendor/openssl/openssl_hash.cpp @@ -6,6 +6,7 @@ */ #include +#include #include namespace Botan { @@ -78,7 +79,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/vendor/openssl/openssl_rc4.cpp b/src/lib/vendor/openssl/openssl_rc4.cpp index 494b30974..ac30cd288 100644 --- a/src/lib/vendor/openssl/openssl_rc4.cpp +++ b/src/lib/vendor/openssl/openssl_rc4.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -48,6 +49,7 @@ class OpenSSL_RC4 : public StreamCipher } -BOTAN_REGISTER_TYPE(StreamCipher, OpenSSL_RC4, "RC4", (make_new_T_1len), "openssl", 64); +BOTAN_REGISTER_TYPE(StreamCipher, OpenSSL_RC4, "RC4", (make_new_T_1len), + "openssl", BOTAN_OPENSSL_RC4_PRIO); } -- cgit v1.2.3 From b403ea921b9ebb35bea8bc19eeae4fa75b71bd22 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 29 Aug 2015 11:55:36 -0400 Subject: Fix OpenSSL RSA to better handle no padding mode. In raw mode pad out plaintext inputs with zeros as needed as otherwise OpenSSL rejects the input as too small. And when decrypting, strip leading zeros to match the behavior of the base implementation. --- src/lib/vendor/openssl/openssl.h | 3 ++ src/lib/vendor/openssl/openssl_ecdsa.cpp | 5 ++-- src/lib/vendor/openssl/openssl_rsa.cpp | 47 ++++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 10 deletions(-) (limited to 'src/lib') diff --git a/src/lib/vendor/openssl/openssl.h b/src/lib/vendor/openssl/openssl.h index 4fa37cc54..86cc8fd35 100644 --- a/src/lib/vendor/openssl/openssl.h +++ b/src/lib/vendor/openssl/openssl.h @@ -27,6 +27,9 @@ class OpenSSL_Error : public Exception #define BOTAN_OPENSSL_HASH_PRIO 150 #define BOTAN_OPENSSL_RC4_PRIO 150 +#define BOTAN_OPENSSL_RSA_PRIO 90 +#define BOTAN_OPENSSL_ECDSA_PRIO 90 + } diff --git a/src/lib/vendor/openssl/openssl_ecdsa.cpp b/src/lib/vendor/openssl/openssl_ecdsa.cpp index 9031944d4..0651cc280 100644 --- a/src/lib/vendor/openssl/openssl_ecdsa.cpp +++ b/src/lib/vendor/openssl/openssl_ecdsa.cpp @@ -194,10 +194,11 @@ class OpenSSL_ECDSA_Signing_Operation : public PK_Ops::Signature_with_EMSA BOTAN_REGISTER_TYPE(PK_Ops::Verification, OpenSSL_ECDSA_Verification_Operation, "ECDSA", OpenSSL_ECDSA_Verification_Operation::make, - "openssl", 255); + "openssl", BOTAN_OPENSSL_ECDSA_PRIO); BOTAN_REGISTER_TYPE(PK_Ops::Signature, OpenSSL_ECDSA_Signing_Operation, "ECDSA", - OpenSSL_ECDSA_Signing_Operation::make, "openssl", 255); + OpenSSL_ECDSA_Signing_Operation::make, + "openssl", BOTAN_OPENSSL_ECDSA_PRIO); } diff --git a/src/lib/vendor/openssl/openssl_rsa.cpp b/src/lib/vendor/openssl/openssl_rsa.cpp index ad2e47683..f8ab2bcd1 100644 --- a/src/lib/vendor/openssl/openssl_rsa.cpp +++ b/src/lib/vendor/openssl/openssl_rsa.cpp @@ -59,11 +59,11 @@ class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption { const std::vector der = rsa.x509_subject_public_key(); const byte* der_ptr = der.data(); - m_openssl_rsa.reset(d2i_RSAPublicKey(nullptr, &der_ptr, der.size())); + 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); + m_bits = 8 * n_size() - pad_overhead; } size_t max_input_bits() const override { return m_bits; }; @@ -71,15 +71,35 @@ class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption secure_vector encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&) override { + const size_t mod_sz = n_size(); - secure_vector buf(::RSA_size(m_openssl_rsa.get())); - int rc = ::RSA_public_encrypt(msg_len, msg, buf.data(), m_openssl_rsa.get(), m_padding); + if(msg_len > mod_sz) + throw Invalid_Argument("Input too large for RSA key"); + + secure_vector outbuf(mod_sz); + + secure_vector 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 buf; + + return outbuf; } private: + size_t n_size() const { return ::RSA_size(m_openssl_rsa.get()); } std::unique_ptr> m_openssl_rsa; size_t m_bits = 0; int m_padding = 0; @@ -114,7 +134,7 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption if(!m_openssl_rsa) throw OpenSSL_Error("d2i_RSAPrivateKey"); - m_bits = 8 * RSA_size(m_openssl_rsa.get()); + m_bits = 8 * ::RSA_size(m_openssl_rsa.get()); } size_t max_input_bits() const override { return m_bits; }; @@ -126,6 +146,17 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption if(rc < 0 || static_cast(rc) > buf.size()) throw OpenSSL_Error("RSA_private_decrypt"); buf.resize(rc); + + if(m_padding == RSA_NO_PADDING) + { + size_t leading_0s = 0; + while(leading_0s < buf.size() && buf[leading_0s] == 0) + leading_0s++; + + if(leading_0s) + return secure_vector(&buf[leading_0s], &buf[buf.size()]); + } + return buf; } @@ -136,9 +167,9 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption }; BOTAN_REGISTER_TYPE(PK_Ops::Encryption, OpenSSL_RSA_Encryption_Operation, "RSA", - OpenSSL_RSA_Encryption_Operation::make, "openssl", 255); + 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", 255); + OpenSSL_RSA_Decryption_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO); } -- cgit v1.2.3 From 1723d63c3b9a26fadfc8c6e414f3815b30b237f1 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 29 Aug 2015 12:04:35 -0400 Subject: Remove alloc module; move secmem.h to base and locking_allocator to utils --- src/lib/alloc/info.txt | 3 - src/lib/alloc/locking_allocator/info.txt | 10 - .../alloc/locking_allocator/locking_allocator.cpp | 304 --------------------- .../alloc/locking_allocator/locking_allocator.h | 44 --- src/lib/alloc/secmem.h | 205 -------------- src/lib/base/info.txt | 2 +- src/lib/base/secmem.h | 205 ++++++++++++++ src/lib/entropy/proc_walk/info.txt | 4 - src/lib/hash/keccak/info.txt | 4 - src/lib/math/bigint/info.txt | 1 - src/lib/pk_pad/info.txt | 1 - src/lib/pubkey/ecc_key/info.txt | 1 - src/lib/pubkey/ecdh/info.txt | 1 - src/lib/pubkey/gost_3410/info.txt | 1 - src/lib/pubkey/info.txt | 1 - src/lib/utils/datastor/info.txt | 3 - src/lib/utils/locking_allocator/info.txt | 10 + .../utils/locking_allocator/locking_allocator.cpp | 304 +++++++++++++++++++++ .../utils/locking_allocator/locking_allocator.h | 44 +++ 19 files changed, 564 insertions(+), 584 deletions(-) delete mode 100644 src/lib/alloc/info.txt delete mode 100644 src/lib/alloc/locking_allocator/info.txt delete mode 100644 src/lib/alloc/locking_allocator/locking_allocator.cpp delete mode 100644 src/lib/alloc/locking_allocator/locking_allocator.h delete mode 100644 src/lib/alloc/secmem.h create mode 100644 src/lib/base/secmem.h create mode 100644 src/lib/utils/locking_allocator/info.txt create mode 100644 src/lib/utils/locking_allocator/locking_allocator.cpp create mode 100644 src/lib/utils/locking_allocator/locking_allocator.h (limited to 'src/lib') 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 @@ - -secmem.h - diff --git a/src/lib/alloc/locking_allocator/info.txt b/src/lib/alloc/locking_allocator/info.txt deleted file mode 100644 index d3b5e86f8..000000000 --- a/src/lib/alloc/locking_allocator/info.txt +++ /dev/null @@ -1,10 +0,0 @@ -define LOCKING_ALLOCATOR 20131128 - - -android -linux -freebsd -netbsd -openbsd -solaris - diff --git a/src/lib/alloc/locking_allocator/locking_allocator.cpp b/src/lib/alloc/locking_allocator/locking_allocator.cpp deleted file mode 100644 index c145cfd7f..000000000 --- a/src/lib/alloc/locking_allocator/locking_allocator.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/* -* Mlock Allocator -* (C) 2012,2014 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include -#include -#include -#include - -#include -#include - -namespace Botan { - -namespace { - -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) - { - limits.rlim_cur = limits.rlim_max; - ::setrlimit(RLIMIT_MEMLOCK, &limits); - ::getrlimit(RLIMIT_MEMLOCK, &limits); - } - - return std::min(limits.rlim_cur, max_req); -#endif - - return 0; - } - -size_t mlock_limit() - { - /* - * Linux defaults to only 64 KiB of mlockable memory per process - * (too small) but BSDs offer a small fraction of total RAM (more - * than we need). Bound the total mlock size to 512 KiB which is - * enough to run the entire test suite without spilling to non-mlock - * memory (and thus presumably also enough for many useful - * programs), but small enough that we should not cause problems - * even if many processes are mlocking on the same machine. - */ - size_t mlock_requested = 512; - - /* - * Allow override via env variable - */ - if(const char* env = ::getenv("BOTAN_MLOCK_POOL_SIZE")) - { - try - { - const size_t user_req = std::stoul(env, nullptr); - mlock_requested = std::min(user_req, mlock_requested); - } - catch(std::exception&) { /* ignore it */ } - } - - return reset_mlock_limit(mlock_requested*1024); - } - -bool ptr_in_pool(const void* pool_ptr, size_t poolsize, - const void* buf_ptr, size_t bufsize) - { - const uintptr_t pool = reinterpret_cast(pool_ptr); - const uintptr_t buf = reinterpret_cast(buf_ptr); - - if(buf < pool || buf >= pool + poolsize) - return false; - - BOTAN_ASSERT(buf + bufsize <= pool + poolsize, - "Pointer does not partially overlap pool"); - - return true; - } - -size_t padding_for_alignment(size_t offset, size_t desired_alignment) - { - size_t mod = offset % desired_alignment; - if(mod == 0) - return 0; // already right on - return desired_alignment - mod; - } - -} - -void* mlock_allocator::allocate(size_t num_elems, size_t elem_size) - { - if(!m_pool) - return nullptr; - - const size_t n = num_elems * elem_size; - const size_t alignment = 16; - - if(n / elem_size != num_elems) - return nullptr; // overflow! - - if(n > m_poolsize) - return nullptr; - if(n < BOTAN_MLOCK_ALLOCATOR_MIN_ALLOCATION || n > BOTAN_MLOCK_ALLOCATOR_MAX_ALLOCATION) - return nullptr; - - std::lock_guard lock(m_mutex); - - auto best_fit = m_freelist.end(); - - for(auto i = m_freelist.begin(); i != m_freelist.end(); ++i) - { - // If we have a perfect fit, use it immediately - if(i->second == n && (i->first % alignment) == 0) - { - const size_t offset = i->first; - m_freelist.erase(i); - clear_mem(m_pool + offset, n); - - BOTAN_ASSERT((reinterpret_cast(m_pool) + offset) % alignment == 0, - "Returning correctly aligned pointer"); - - return m_pool + offset; - } - - if((i->second >= (n + padding_for_alignment(i->first, alignment)) && - ((best_fit == m_freelist.end()) || (best_fit->second > i->second)))) - { - best_fit = i; - } - } - - if(best_fit != m_freelist.end()) - { - const size_t offset = best_fit->first; - - const size_t alignment_padding = padding_for_alignment(offset, alignment); - - best_fit->first += n + alignment_padding; - best_fit->second -= n + alignment_padding; - - // Need to realign, split the block - if(alignment_padding) - { - /* - If we used the entire block except for small piece used for - alignment at the beginning, so just update the entry already - in place (as it is in the correct location), rather than - deleting the empty range and inserting the new one in the - same location. - */ - if(best_fit->second == 0) - { - best_fit->first = offset; - best_fit->second = alignment_padding; - } - else - m_freelist.insert(best_fit, std::make_pair(offset, alignment_padding)); - } - - clear_mem(m_pool + offset + alignment_padding, n); - - BOTAN_ASSERT((reinterpret_cast(m_pool) + offset + alignment_padding) % alignment == 0, - "Returning correctly aligned pointer"); - - return m_pool + offset + alignment_padding; - } - - return nullptr; - } - -bool mlock_allocator::deallocate(void* p, size_t num_elems, size_t elem_size) - { - if(!m_pool) - return false; - - /* - We do not have to zero the memory here, as - secure_allocator::deallocate does that for all arguments before - invoking the deallocator (us or delete[]) - */ - - size_t n = num_elems * elem_size; - - /* - We return nullptr in allocate if there was an overflow, so we - should never ever see an overflow in a deallocation. - */ - BOTAN_ASSERT(n / elem_size == num_elems, - "No overflow in deallocation"); - - if(!ptr_in_pool(m_pool, m_poolsize, p, n)) - return false; - - std::lock_guard lock(m_mutex); - - const size_t start = static_cast(p) - m_pool; - - auto comp = [](std::pair x, std::pair y){ return x.first < y.first; }; - - auto i = std::lower_bound(m_freelist.begin(), m_freelist.end(), - std::make_pair(start, 0), comp); - - // try to merge with later block - if(i != m_freelist.end() && start + n == i->first) - { - i->first = start; - i->second += n; - n = 0; - } - - // try to merge with previous block - if(i != m_freelist.begin()) - { - auto prev = std::prev(i); - - if(prev->first + prev->second == start) - { - if(n) - { - prev->second += n; - n = 0; - } - else - { - // merge adjoining - prev->second += i->second; - m_freelist.erase(i); - } - } - } - - if(n != 0) // no merge possible? - m_freelist.insert(i, std::make_pair(start, n)); - - return true; - } - -mlock_allocator::mlock_allocator() : - m_poolsize(mlock_limit()), - m_pool(nullptr) - { -#if !defined(MAP_NOCORE) - #define MAP_NOCORE 0 -#endif - -#if !defined(MAP_ANONYMOUS) - #define MAP_ANONYMOUS MAP_ANON -#endif - - if(m_poolsize) - { - m_pool = static_cast( - ::mmap( - nullptr, m_poolsize, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_SHARED | MAP_NOCORE, - -1, 0)); - - if(m_pool == static_cast(MAP_FAILED)) - { - m_pool = nullptr; - throw std::runtime_error("Failed to mmap locking_allocator pool"); - } - - clear_mem(m_pool, m_poolsize); - - if(::mlock(m_pool, m_poolsize) != 0) - { - ::munmap(m_pool, m_poolsize); - m_pool = nullptr; - throw std::runtime_error("Could not mlock " + std::to_string(m_poolsize) + " bytes"); - } - -#if defined(MADV_DONTDUMP) - ::madvise(m_pool, m_poolsize, MADV_DONTDUMP); -#endif - - m_freelist.push_back(std::make_pair(0, m_poolsize)); - } - } - -mlock_allocator::~mlock_allocator() - { - if(m_pool) - { - clear_mem(m_pool, m_poolsize); - ::munlock(m_pool, m_poolsize); - ::munmap(m_pool, m_poolsize); - m_pool = nullptr; - } - } - -mlock_allocator& mlock_allocator::instance() - { - static mlock_allocator mlock; - return mlock; - } - -} diff --git a/src/lib/alloc/locking_allocator/locking_allocator.h b/src/lib/alloc/locking_allocator/locking_allocator.h deleted file mode 100644 index 2aca2dfa9..000000000 --- a/src/lib/alloc/locking_allocator/locking_allocator.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* Mlock Allocator -* (C) 2012 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_MLOCK_ALLOCATOR_H__ -#define BOTAN_MLOCK_ALLOCATOR_H__ - -#include -#include -#include - -namespace Botan { - -class BOTAN_DLL mlock_allocator - { - public: - static mlock_allocator& instance(); - - void* allocate(size_t num_elems, size_t elem_size); - - bool deallocate(void* p, size_t num_elems, size_t elem_size); - - mlock_allocator(const mlock_allocator&) = delete; - - mlock_allocator& operator=(const mlock_allocator&) = delete; - - private: - mlock_allocator(); - - ~mlock_allocator(); - - const size_t m_poolsize; - - std::mutex m_mutex; - std::vector> m_freelist; - byte* m_pool; - }; - -} - -#endif diff --git a/src/lib/alloc/secmem.h b/src/lib/alloc/secmem.h deleted file mode 100644 index 63d4e5296..000000000 --- a/src/lib/alloc/secmem.h +++ /dev/null @@ -1,205 +0,0 @@ -/* -* Secure Memory Buffers -* (C) 1999-2007,2012 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__ -#define BOTAN_SECURE_MEMORY_BUFFERS_H__ - -#include -#include -#include -#include - -#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) - #include -#endif - -namespace Botan { - -template -class secure_allocator - { - public: - typedef T value_type; - - typedef T* pointer; - typedef const T* const_pointer; - - typedef T& reference; - typedef const T& const_reference; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - secure_allocator() BOTAN_NOEXCEPT {} - - template - secure_allocator(const secure_allocator&) BOTAN_NOEXCEPT {} - - ~secure_allocator() BOTAN_NOEXCEPT {} - - pointer address(reference x) const BOTAN_NOEXCEPT - { return std::addressof(x); } - - const_pointer address(const_reference x) const BOTAN_NOEXCEPT - { return std::addressof(x); } - - pointer allocate(size_type n, const void* = 0) - { -#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) - if(pointer p = static_cast(mlock_allocator::instance().allocate(n, sizeof(T)))) - return p; -#endif - - pointer p = new T[n]; - clear_mem(p, n); - return p; - } - - void deallocate(pointer p, size_type n) - { - zero_mem(p, n); - -#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) - if(mlock_allocator::instance().deallocate(p, n, sizeof(T))) - return; -#endif - - delete [] p; - } - - size_type max_size() const BOTAN_NOEXCEPT - { - return static_cast(-1) / sizeof(T); - } - - template - void construct(U* p, Args&&... args) - { - ::new(static_cast(p)) U(std::forward(args)...); - } - - template void destroy(U* p) { p->~U(); } - }; - -template inline bool -operator==(const secure_allocator&, const secure_allocator&) - { return true; } - -template inline bool -operator!=(const secure_allocator&, const secure_allocator&) - { return false; } - -template using secure_vector = std::vector>; -template using secure_deque = std::deque>; - -template -std::vector unlock(const secure_vector& in) - { - std::vector out(in.size()); - copy_mem(out.data(), in.data(), in.size()); - return out; - } - -template -size_t buffer_insert(std::vector& buf, - size_t buf_offset, - const T input[], - size_t input_length) - { - const size_t to_copy = std::min(input_length, buf.size() - buf_offset); - if (to_copy > 0) - { - copy_mem(&buf[buf_offset], input, to_copy); - } - return to_copy; - } - -template -size_t buffer_insert(std::vector& buf, - size_t buf_offset, - const std::vector& input) - { - const size_t to_copy = std::min(input.size(), buf.size() - buf_offset); - if (to_copy > 0) - { - copy_mem(&buf[buf_offset], input.data(), to_copy); - } - return to_copy; - } - -template -std::vector& -operator+=(std::vector& out, - const std::vector& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.size()); - if (in.size() > 0) - { - copy_mem(&out[copy_offset], in.data(), in.size()); - } - return out; - } - -template -std::vector& operator+=(std::vector& out, T in) - { - out.push_back(in); - return out; - } - -template -std::vector& operator+=(std::vector& out, - const std::pair& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.second); - if (in.second > 0) - { - copy_mem(&out[copy_offset], in.first, in.second); - } - return out; - } - -template -std::vector& operator+=(std::vector& out, - const std::pair& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.second); - if (in.second > 0) - { - copy_mem(&out[copy_offset], in.first, in.second); - } - return out; - } - -/** -* Zeroise the values; length remains unchanged -* @param vec the vector to zeroise -*/ -template -void zeroise(std::vector& vec) - { - clear_mem(vec.data(), vec.size()); - } - -/** -* Zeroise the values then free the memory -* @param vec the vector to zeroise and free -*/ -template -void zap(std::vector& vec) - { - zeroise(vec); - vec.clear(); - vec.shrink_to_fit(); - } - -} - -#endif diff --git a/src/lib/base/info.txt b/src/lib/base/info.txt index e09351596..19eee6608 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,7 +18,6 @@ algo_registry.h define TRANSFORM 20131209 -alloc block hash hex diff --git a/src/lib/base/secmem.h b/src/lib/base/secmem.h new file mode 100644 index 000000000..63d4e5296 --- /dev/null +++ b/src/lib/base/secmem.h @@ -0,0 +1,205 @@ +/* +* Secure Memory Buffers +* (C) 1999-2007,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__ +#define BOTAN_SECURE_MEMORY_BUFFERS_H__ + +#include +#include +#include +#include + +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + #include +#endif + +namespace Botan { + +template +class secure_allocator + { + public: + typedef T value_type; + + typedef T* pointer; + typedef const T* const_pointer; + + typedef T& reference; + typedef const T& const_reference; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + secure_allocator() BOTAN_NOEXCEPT {} + + template + secure_allocator(const secure_allocator&) BOTAN_NOEXCEPT {} + + ~secure_allocator() BOTAN_NOEXCEPT {} + + pointer address(reference x) const BOTAN_NOEXCEPT + { return std::addressof(x); } + + const_pointer address(const_reference x) const BOTAN_NOEXCEPT + { return std::addressof(x); } + + pointer allocate(size_type n, const void* = 0) + { +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + if(pointer p = static_cast(mlock_allocator::instance().allocate(n, sizeof(T)))) + return p; +#endif + + pointer p = new T[n]; + clear_mem(p, n); + return p; + } + + void deallocate(pointer p, size_type n) + { + zero_mem(p, n); + +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + if(mlock_allocator::instance().deallocate(p, n, sizeof(T))) + return; +#endif + + delete [] p; + } + + size_type max_size() const BOTAN_NOEXCEPT + { + return static_cast(-1) / sizeof(T); + } + + template + void construct(U* p, Args&&... args) + { + ::new(static_cast(p)) U(std::forward(args)...); + } + + template void destroy(U* p) { p->~U(); } + }; + +template inline bool +operator==(const secure_allocator&, const secure_allocator&) + { return true; } + +template inline bool +operator!=(const secure_allocator&, const secure_allocator&) + { return false; } + +template using secure_vector = std::vector>; +template using secure_deque = std::deque>; + +template +std::vector unlock(const secure_vector& in) + { + std::vector out(in.size()); + copy_mem(out.data(), in.data(), in.size()); + return out; + } + +template +size_t buffer_insert(std::vector& buf, + size_t buf_offset, + const T input[], + size_t input_length) + { + const size_t to_copy = std::min(input_length, buf.size() - buf_offset); + if (to_copy > 0) + { + copy_mem(&buf[buf_offset], input, to_copy); + } + return to_copy; + } + +template +size_t buffer_insert(std::vector& buf, + size_t buf_offset, + const std::vector& input) + { + const size_t to_copy = std::min(input.size(), buf.size() - buf_offset); + if (to_copy > 0) + { + copy_mem(&buf[buf_offset], input.data(), to_copy); + } + return to_copy; + } + +template +std::vector& +operator+=(std::vector& out, + const std::vector& in) + { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.size()); + if (in.size() > 0) + { + copy_mem(&out[copy_offset], in.data(), in.size()); + } + return out; + } + +template +std::vector& operator+=(std::vector& out, T in) + { + out.push_back(in); + return out; + } + +template +std::vector& operator+=(std::vector& out, + const std::pair& in) + { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.second); + if (in.second > 0) + { + copy_mem(&out[copy_offset], in.first, in.second); + } + return out; + } + +template +std::vector& operator+=(std::vector& out, + const std::pair& in) + { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.second); + if (in.second > 0) + { + copy_mem(&out[copy_offset], in.first, in.second); + } + return out; + } + +/** +* Zeroise the values; length remains unchanged +* @param vec the vector to zeroise +*/ +template +void zeroise(std::vector& vec) + { + clear_mem(vec.data(), vec.size()); + } + +/** +* Zeroise the values then free the memory +* @param vec the vector to zeroise and free +*/ +template +void zap(std::vector& vec) + { + zeroise(vec); + vec.clear(); + vec.shrink_to_fit(); + } + +} + +#endif 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 - - -alloc - 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 - - -alloc - 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 -alloc mp hex rng diff --git a/src/lib/pk_pad/info.txt b/src/lib/pk_pad/info.txt index d77e1defd..cc3a3fb3b 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 -alloc rng 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 -alloc asn1 bigint ec_gfp 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 -alloc asn1 ec_group ecc_key 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 -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 -alloc asn1 bigint kdf 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 @@ - -alloc - diff --git a/src/lib/utils/locking_allocator/info.txt b/src/lib/utils/locking_allocator/info.txt new file mode 100644 index 000000000..d3b5e86f8 --- /dev/null +++ b/src/lib/utils/locking_allocator/info.txt @@ -0,0 +1,10 @@ +define LOCKING_ALLOCATOR 20131128 + + +android +linux +freebsd +netbsd +openbsd +solaris + diff --git a/src/lib/utils/locking_allocator/locking_allocator.cpp b/src/lib/utils/locking_allocator/locking_allocator.cpp new file mode 100644 index 000000000..c145cfd7f --- /dev/null +++ b/src/lib/utils/locking_allocator/locking_allocator.cpp @@ -0,0 +1,304 @@ +/* +* Mlock Allocator +* (C) 2012,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +#include +#include + +namespace Botan { + +namespace { + +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) + { + limits.rlim_cur = limits.rlim_max; + ::setrlimit(RLIMIT_MEMLOCK, &limits); + ::getrlimit(RLIMIT_MEMLOCK, &limits); + } + + return std::min(limits.rlim_cur, max_req); +#endif + + return 0; + } + +size_t mlock_limit() + { + /* + * Linux defaults to only 64 KiB of mlockable memory per process + * (too small) but BSDs offer a small fraction of total RAM (more + * than we need). Bound the total mlock size to 512 KiB which is + * enough to run the entire test suite without spilling to non-mlock + * memory (and thus presumably also enough for many useful + * programs), but small enough that we should not cause problems + * even if many processes are mlocking on the same machine. + */ + size_t mlock_requested = 512; + + /* + * Allow override via env variable + */ + if(const char* env = ::getenv("BOTAN_MLOCK_POOL_SIZE")) + { + try + { + const size_t user_req = std::stoul(env, nullptr); + mlock_requested = std::min(user_req, mlock_requested); + } + catch(std::exception&) { /* ignore it */ } + } + + return reset_mlock_limit(mlock_requested*1024); + } + +bool ptr_in_pool(const void* pool_ptr, size_t poolsize, + const void* buf_ptr, size_t bufsize) + { + const uintptr_t pool = reinterpret_cast(pool_ptr); + const uintptr_t buf = reinterpret_cast(buf_ptr); + + if(buf < pool || buf >= pool + poolsize) + return false; + + BOTAN_ASSERT(buf + bufsize <= pool + poolsize, + "Pointer does not partially overlap pool"); + + return true; + } + +size_t padding_for_alignment(size_t offset, size_t desired_alignment) + { + size_t mod = offset % desired_alignment; + if(mod == 0) + return 0; // already right on + return desired_alignment - mod; + } + +} + +void* mlock_allocator::allocate(size_t num_elems, size_t elem_size) + { + if(!m_pool) + return nullptr; + + const size_t n = num_elems * elem_size; + const size_t alignment = 16; + + if(n / elem_size != num_elems) + return nullptr; // overflow! + + if(n > m_poolsize) + return nullptr; + if(n < BOTAN_MLOCK_ALLOCATOR_MIN_ALLOCATION || n > BOTAN_MLOCK_ALLOCATOR_MAX_ALLOCATION) + return nullptr; + + std::lock_guard lock(m_mutex); + + auto best_fit = m_freelist.end(); + + for(auto i = m_freelist.begin(); i != m_freelist.end(); ++i) + { + // If we have a perfect fit, use it immediately + if(i->second == n && (i->first % alignment) == 0) + { + const size_t offset = i->first; + m_freelist.erase(i); + clear_mem(m_pool + offset, n); + + BOTAN_ASSERT((reinterpret_cast(m_pool) + offset) % alignment == 0, + "Returning correctly aligned pointer"); + + return m_pool + offset; + } + + if((i->second >= (n + padding_for_alignment(i->first, alignment)) && + ((best_fit == m_freelist.end()) || (best_fit->second > i->second)))) + { + best_fit = i; + } + } + + if(best_fit != m_freelist.end()) + { + const size_t offset = best_fit->first; + + const size_t alignment_padding = padding_for_alignment(offset, alignment); + + best_fit->first += n + alignment_padding; + best_fit->second -= n + alignment_padding; + + // Need to realign, split the block + if(alignment_padding) + { + /* + If we used the entire block except for small piece used for + alignment at the beginning, so just update the entry already + in place (as it is in the correct location), rather than + deleting the empty range and inserting the new one in the + same location. + */ + if(best_fit->second == 0) + { + best_fit->first = offset; + best_fit->second = alignment_padding; + } + else + m_freelist.insert(best_fit, std::make_pair(offset, alignment_padding)); + } + + clear_mem(m_pool + offset + alignment_padding, n); + + BOTAN_ASSERT((reinterpret_cast(m_pool) + offset + alignment_padding) % alignment == 0, + "Returning correctly aligned pointer"); + + return m_pool + offset + alignment_padding; + } + + return nullptr; + } + +bool mlock_allocator::deallocate(void* p, size_t num_elems, size_t elem_size) + { + if(!m_pool) + return false; + + /* + We do not have to zero the memory here, as + secure_allocator::deallocate does that for all arguments before + invoking the deallocator (us or delete[]) + */ + + size_t n = num_elems * elem_size; + + /* + We return nullptr in allocate if there was an overflow, so we + should never ever see an overflow in a deallocation. + */ + BOTAN_ASSERT(n / elem_size == num_elems, + "No overflow in deallocation"); + + if(!ptr_in_pool(m_pool, m_poolsize, p, n)) + return false; + + std::lock_guard lock(m_mutex); + + const size_t start = static_cast(p) - m_pool; + + auto comp = [](std::pair x, std::pair y){ return x.first < y.first; }; + + auto i = std::lower_bound(m_freelist.begin(), m_freelist.end(), + std::make_pair(start, 0), comp); + + // try to merge with later block + if(i != m_freelist.end() && start + n == i->first) + { + i->first = start; + i->second += n; + n = 0; + } + + // try to merge with previous block + if(i != m_freelist.begin()) + { + auto prev = std::prev(i); + + if(prev->first + prev->second == start) + { + if(n) + { + prev->second += n; + n = 0; + } + else + { + // merge adjoining + prev->second += i->second; + m_freelist.erase(i); + } + } + } + + if(n != 0) // no merge possible? + m_freelist.insert(i, std::make_pair(start, n)); + + return true; + } + +mlock_allocator::mlock_allocator() : + m_poolsize(mlock_limit()), + m_pool(nullptr) + { +#if !defined(MAP_NOCORE) + #define MAP_NOCORE 0 +#endif + +#if !defined(MAP_ANONYMOUS) + #define MAP_ANONYMOUS MAP_ANON +#endif + + if(m_poolsize) + { + m_pool = static_cast( + ::mmap( + nullptr, m_poolsize, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED | MAP_NOCORE, + -1, 0)); + + if(m_pool == static_cast(MAP_FAILED)) + { + m_pool = nullptr; + throw std::runtime_error("Failed to mmap locking_allocator pool"); + } + + clear_mem(m_pool, m_poolsize); + + if(::mlock(m_pool, m_poolsize) != 0) + { + ::munmap(m_pool, m_poolsize); + m_pool = nullptr; + throw std::runtime_error("Could not mlock " + std::to_string(m_poolsize) + " bytes"); + } + +#if defined(MADV_DONTDUMP) + ::madvise(m_pool, m_poolsize, MADV_DONTDUMP); +#endif + + m_freelist.push_back(std::make_pair(0, m_poolsize)); + } + } + +mlock_allocator::~mlock_allocator() + { + if(m_pool) + { + clear_mem(m_pool, m_poolsize); + ::munlock(m_pool, m_poolsize); + ::munmap(m_pool, m_poolsize); + m_pool = nullptr; + } + } + +mlock_allocator& mlock_allocator::instance() + { + static mlock_allocator mlock; + return mlock; + } + +} diff --git a/src/lib/utils/locking_allocator/locking_allocator.h b/src/lib/utils/locking_allocator/locking_allocator.h new file mode 100644 index 000000000..2aca2dfa9 --- /dev/null +++ b/src/lib/utils/locking_allocator/locking_allocator.h @@ -0,0 +1,44 @@ +/* +* Mlock Allocator +* (C) 2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MLOCK_ALLOCATOR_H__ +#define BOTAN_MLOCK_ALLOCATOR_H__ + +#include +#include +#include + +namespace Botan { + +class BOTAN_DLL mlock_allocator + { + public: + static mlock_allocator& instance(); + + void* allocate(size_t num_elems, size_t elem_size); + + bool deallocate(void* p, size_t num_elems, size_t elem_size); + + mlock_allocator(const mlock_allocator&) = delete; + + mlock_allocator& operator=(const mlock_allocator&) = delete; + + private: + mlock_allocator(); + + ~mlock_allocator(); + + const size_t m_poolsize; + + std::mutex m_mutex; + std::vector> m_freelist; + byte* m_pool; + }; + +} + +#endif -- cgit v1.2.3 From 6ec30c701a38f1abc39b60d23e0442d61e80c196 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 29 Aug 2015 12:15:25 -0400 Subject: Move Credentials_Manager to TLS --- src/lib/credentials/credentials_manager.cpp | 135 -------------------- src/lib/credentials/credentials_manager.h | 189 ---------------------------- src/lib/credentials/info.txt | 5 - src/lib/tls/credentials_manager.cpp | 135 ++++++++++++++++++++ src/lib/tls/credentials_manager.h | 189 ++++++++++++++++++++++++++++ src/lib/tls/info.txt | 2 +- 6 files changed, 325 insertions(+), 330 deletions(-) delete mode 100644 src/lib/credentials/credentials_manager.cpp delete mode 100644 src/lib/credentials/credentials_manager.h delete mode 100644 src/lib/credentials/info.txt create mode 100644 src/lib/tls/credentials_manager.cpp create mode 100644 src/lib/tls/credentials_manager.h (limited to 'src/lib') diff --git a/src/lib/credentials/credentials_manager.cpp b/src/lib/credentials/credentials_manager.cpp deleted file mode 100644 index 6443bb246..000000000 --- a/src/lib/credentials/credentials_manager.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* -* Credentials Manager -* (C) 2011,2012 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include - -namespace Botan { - -std::string Credentials_Manager::psk_identity_hint(const std::string&, - const std::string&) - { - return ""; - } - -std::string Credentials_Manager::psk_identity(const std::string&, - const std::string&, - const std::string&) - { - return ""; - } - -SymmetricKey Credentials_Manager::psk(const std::string&, - const std::string&, - const std::string& identity) - { - throw Internal_Error("No PSK set for identity " + identity); - } - -bool Credentials_Manager::attempt_srp(const std::string&, - const std::string&) - { - return false; - } - -std::string Credentials_Manager::srp_identifier(const std::string&, - const std::string&) - { - return ""; - } - -std::string Credentials_Manager::srp_password(const std::string&, - const std::string&, - const std::string&) - { - return ""; - } - -bool Credentials_Manager::srp_verifier(const std::string&, - const std::string&, - const std::string&, - std::string&, - BigInt&, - std::vector&, - bool) - { - return false; - } - -std::vector Credentials_Manager::cert_chain( - const std::vector&, - const std::string&, - const std::string&) - { - return std::vector(); - } - -std::vector Credentials_Manager::cert_chain_single_type( - const std::string& cert_key_type, - const std::string& type, - const std::string& context) - { - std::vector cert_types; - cert_types.push_back(cert_key_type); - return cert_chain(cert_types, type, context); - } - -Private_Key* Credentials_Manager::private_key_for(const X509_Certificate&, - const std::string&, - const std::string&) - { - return nullptr; - } - -std::vector -Credentials_Manager::trusted_certificate_authorities( - const std::string&, - const std::string&) - { - return std::vector(); - } - -namespace { - -bool cert_in_some_store(const std::vector& trusted_CAs, - const X509_Certificate& trust_root) - { - for(auto CAs : trusted_CAs) - if(CAs->certificate_known(trust_root)) - return true; - return false; - } - -} - -void Credentials_Manager::verify_certificate_chain( - const std::string& type, - const std::string& purported_hostname, - const std::vector& cert_chain) - { - if(cert_chain.empty()) - throw std::invalid_argument("Certificate chain was empty"); - - auto trusted_CAs = trusted_certificate_authorities(type, purported_hostname); - - Path_Validation_Restrictions restrictions; - - auto result = x509_path_validate(cert_chain, - restrictions, - trusted_CAs); - - if(!result.successful_validation()) - throw std::runtime_error("Certificate validation failure: " + result.result_string()); - - if(!cert_in_some_store(trusted_CAs, result.trust_root())) - throw std::runtime_error("Certificate chain roots in unknown/untrusted CA"); - - if(purported_hostname != "" && !cert_chain[0].matches_dns_name(purported_hostname)) - throw std::runtime_error("Certificate did not match hostname"); - } - -} diff --git a/src/lib/credentials/credentials_manager.h b/src/lib/credentials/credentials_manager.h deleted file mode 100644 index 96e840d13..000000000 --- a/src/lib/credentials/credentials_manager.h +++ /dev/null @@ -1,189 +0,0 @@ -/* -* Credentials Manager -* (C) 2011,2012 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_CREDENTIALS_MANAGER_H__ -#define BOTAN_CREDENTIALS_MANAGER_H__ - -#include -#include -#include -#include - -namespace Botan { - -class BigInt; - -/** -* Interface for a credentials manager. -* -* A type is a fairly static value that represents the general nature -* of the transaction occurring. Currently used values are "tls-client" -* and "tls-server". Context represents a hostname, email address, -* username, or other identifier. -*/ -class BOTAN_DLL Credentials_Manager - { - public: - virtual ~Credentials_Manager() {} - - /** - * Return a list of the certificates of CAs that we trust in this - * type/context. - * - * @param type specifies the type of operation occurring - * - * @param context specifies a context relative to type. For instance - * for type "tls-client", context specifies the servers name. - */ - virtual std::vector trusted_certificate_authorities( - const std::string& type, - const std::string& context); - - /** - * Check the certificate chain is valid up to a trusted root, and - * optionally (if hostname != "") that the hostname given is - * consistent with the leaf certificate. - * - * This function should throw an exception derived from - * std::exception with an informative what() result if the - * certificate chain cannot be verified. - - * @param type specifies the type of operation occurring - * @param hostname specifies the purported hostname - * @param cert_chain specifies a certificate chain leading to a - * trusted root CA certificate. - */ - virtual void verify_certificate_chain( - const std::string& type, - const std::string& hostname, - const std::vector& cert_chain); - - /** - * Return a cert chain we can use, ordered from leaf to root, - * or else an empty vector. - * - * It is assumed that the caller can get the private key of the - * leaf with private_key_for - * - * @param cert_key_types specifies the key types desired ("RSA", - * "DSA", "ECDSA", etc), or empty if there - * is no preference by the caller. - * - * @param type specifies the type of operation occurring - * - * @param context specifies a context relative to type. - */ - virtual std::vector cert_chain( - const std::vector& cert_key_types, - const std::string& type, - const std::string& context); - - /** - * Return a cert chain we can use, ordered from leaf to root, - * or else an empty vector. - * - * It is assumed that the caller can get the private key of the - * leaf with private_key_for - * - * @param cert_key_type specifies the type of key requested - * ("RSA", "DSA", "ECDSA", etc) - * - * @param type specifies the type of operation occurring - * - * @param context specifies a context relative to type. - */ - std::vector cert_chain_single_type( - const std::string& cert_key_type, - const std::string& type, - const std::string& context); - - /** - * @return private key associated with this certificate if we should - * use it with this context. cert was returned by cert_chain - * @note this object should retain ownership of the returned key; - * it should not be deleted by the caller. - */ - virtual Private_Key* private_key_for(const X509_Certificate& cert, - const std::string& type, - const std::string& context); - - /** - * @param type specifies the type of operation occurring - * @param context specifies a context relative to type. - * @return true if we should attempt SRP authentication - */ - virtual bool attempt_srp(const std::string& type, - const std::string& context); - - /** - * @param type specifies the type of operation occurring - * @param context specifies a context relative to type. - * @return identifier for client-side SRP auth, if available - for this type/context. Should return empty string - if password auth not desired/available. - */ - virtual std::string srp_identifier(const std::string& type, - const std::string& context); - - /** - * @param type specifies the type of operation occurring - * @param context specifies a context relative to type. - * @param identifier specifies what identifier we want the - * password for. This will be a value previously returned - * by srp_identifier. - * @return password for client-side SRP auth, if available - for this identifier/type/context. - */ - virtual std::string srp_password(const std::string& type, - const std::string& context, - const std::string& identifier); - - /** - * Retrieve SRP verifier parameters - */ - virtual bool srp_verifier(const std::string& type, - const std::string& context, - const std::string& identifier, - std::string& group_name, - BigInt& verifier, - std::vector& salt, - bool generate_fake_on_unknown); - - /** - * @param type specifies the type of operation occurring - * @param context specifies a context relative to type. - * @return the PSK identity hint for this type/context - */ - virtual std::string psk_identity_hint(const std::string& type, - const std::string& context); - - /** - * @param type specifies the type of operation occurring - * @param context specifies a context relative to type. - * @param identity_hint was passed by the server (but may be empty) - * @return the PSK identity we want to use - */ - virtual std::string psk_identity(const std::string& type, - const std::string& context, - const std::string& identity_hint); - - /** - * @param type specifies the type of operation occurring - * @param context specifies a context relative to type. - * @param identity is a PSK identity previously returned by - psk_identity for the same type and context. - * @return the PSK used for identity, or throw an exception if no - * key exists - */ - virtual SymmetricKey psk(const std::string& type, - const std::string& context, - const std::string& identity); - }; - -} - -#endif 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 - - -x509 - diff --git a/src/lib/tls/credentials_manager.cpp b/src/lib/tls/credentials_manager.cpp new file mode 100644 index 000000000..6443bb246 --- /dev/null +++ b/src/lib/tls/credentials_manager.cpp @@ -0,0 +1,135 @@ +/* +* Credentials Manager +* (C) 2011,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +std::string Credentials_Manager::psk_identity_hint(const std::string&, + const std::string&) + { + return ""; + } + +std::string Credentials_Manager::psk_identity(const std::string&, + const std::string&, + const std::string&) + { + return ""; + } + +SymmetricKey Credentials_Manager::psk(const std::string&, + const std::string&, + const std::string& identity) + { + throw Internal_Error("No PSK set for identity " + identity); + } + +bool Credentials_Manager::attempt_srp(const std::string&, + const std::string&) + { + return false; + } + +std::string Credentials_Manager::srp_identifier(const std::string&, + const std::string&) + { + return ""; + } + +std::string Credentials_Manager::srp_password(const std::string&, + const std::string&, + const std::string&) + { + return ""; + } + +bool Credentials_Manager::srp_verifier(const std::string&, + const std::string&, + const std::string&, + std::string&, + BigInt&, + std::vector&, + bool) + { + return false; + } + +std::vector Credentials_Manager::cert_chain( + const std::vector&, + const std::string&, + const std::string&) + { + return std::vector(); + } + +std::vector Credentials_Manager::cert_chain_single_type( + const std::string& cert_key_type, + const std::string& type, + const std::string& context) + { + std::vector cert_types; + cert_types.push_back(cert_key_type); + return cert_chain(cert_types, type, context); + } + +Private_Key* Credentials_Manager::private_key_for(const X509_Certificate&, + const std::string&, + const std::string&) + { + return nullptr; + } + +std::vector +Credentials_Manager::trusted_certificate_authorities( + const std::string&, + const std::string&) + { + return std::vector(); + } + +namespace { + +bool cert_in_some_store(const std::vector& trusted_CAs, + const X509_Certificate& trust_root) + { + for(auto CAs : trusted_CAs) + if(CAs->certificate_known(trust_root)) + return true; + return false; + } + +} + +void Credentials_Manager::verify_certificate_chain( + const std::string& type, + const std::string& purported_hostname, + const std::vector& cert_chain) + { + if(cert_chain.empty()) + throw std::invalid_argument("Certificate chain was empty"); + + auto trusted_CAs = trusted_certificate_authorities(type, purported_hostname); + + Path_Validation_Restrictions restrictions; + + auto result = x509_path_validate(cert_chain, + restrictions, + trusted_CAs); + + if(!result.successful_validation()) + throw std::runtime_error("Certificate validation failure: " + result.result_string()); + + if(!cert_in_some_store(trusted_CAs, result.trust_root())) + throw std::runtime_error("Certificate chain roots in unknown/untrusted CA"); + + if(purported_hostname != "" && !cert_chain[0].matches_dns_name(purported_hostname)) + throw std::runtime_error("Certificate did not match hostname"); + } + +} diff --git a/src/lib/tls/credentials_manager.h b/src/lib/tls/credentials_manager.h new file mode 100644 index 000000000..96e840d13 --- /dev/null +++ b/src/lib/tls/credentials_manager.h @@ -0,0 +1,189 @@ +/* +* Credentials Manager +* (C) 2011,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CREDENTIALS_MANAGER_H__ +#define BOTAN_CREDENTIALS_MANAGER_H__ + +#include +#include +#include +#include + +namespace Botan { + +class BigInt; + +/** +* Interface for a credentials manager. +* +* A type is a fairly static value that represents the general nature +* of the transaction occurring. Currently used values are "tls-client" +* and "tls-server". Context represents a hostname, email address, +* username, or other identifier. +*/ +class BOTAN_DLL Credentials_Manager + { + public: + virtual ~Credentials_Manager() {} + + /** + * Return a list of the certificates of CAs that we trust in this + * type/context. + * + * @param type specifies the type of operation occurring + * + * @param context specifies a context relative to type. For instance + * for type "tls-client", context specifies the servers name. + */ + virtual std::vector trusted_certificate_authorities( + const std::string& type, + const std::string& context); + + /** + * Check the certificate chain is valid up to a trusted root, and + * optionally (if hostname != "") that the hostname given is + * consistent with the leaf certificate. + * + * This function should throw an exception derived from + * std::exception with an informative what() result if the + * certificate chain cannot be verified. + + * @param type specifies the type of operation occurring + * @param hostname specifies the purported hostname + * @param cert_chain specifies a certificate chain leading to a + * trusted root CA certificate. + */ + virtual void verify_certificate_chain( + const std::string& type, + const std::string& hostname, + const std::vector& cert_chain); + + /** + * Return a cert chain we can use, ordered from leaf to root, + * or else an empty vector. + * + * It is assumed that the caller can get the private key of the + * leaf with private_key_for + * + * @param cert_key_types specifies the key types desired ("RSA", + * "DSA", "ECDSA", etc), or empty if there + * is no preference by the caller. + * + * @param type specifies the type of operation occurring + * + * @param context specifies a context relative to type. + */ + virtual std::vector cert_chain( + const std::vector& cert_key_types, + const std::string& type, + const std::string& context); + + /** + * Return a cert chain we can use, ordered from leaf to root, + * or else an empty vector. + * + * It is assumed that the caller can get the private key of the + * leaf with private_key_for + * + * @param cert_key_type specifies the type of key requested + * ("RSA", "DSA", "ECDSA", etc) + * + * @param type specifies the type of operation occurring + * + * @param context specifies a context relative to type. + */ + std::vector cert_chain_single_type( + const std::string& cert_key_type, + const std::string& type, + const std::string& context); + + /** + * @return private key associated with this certificate if we should + * use it with this context. cert was returned by cert_chain + * @note this object should retain ownership of the returned key; + * it should not be deleted by the caller. + */ + virtual Private_Key* private_key_for(const X509_Certificate& cert, + const std::string& type, + const std::string& context); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @return true if we should attempt SRP authentication + */ + virtual bool attempt_srp(const std::string& type, + const std::string& context); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @return identifier for client-side SRP auth, if available + for this type/context. Should return empty string + if password auth not desired/available. + */ + virtual std::string srp_identifier(const std::string& type, + const std::string& context); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @param identifier specifies what identifier we want the + * password for. This will be a value previously returned + * by srp_identifier. + * @return password for client-side SRP auth, if available + for this identifier/type/context. + */ + virtual std::string srp_password(const std::string& type, + const std::string& context, + const std::string& identifier); + + /** + * Retrieve SRP verifier parameters + */ + virtual bool srp_verifier(const std::string& type, + const std::string& context, + const std::string& identifier, + std::string& group_name, + BigInt& verifier, + std::vector& salt, + bool generate_fake_on_unknown); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @return the PSK identity hint for this type/context + */ + virtual std::string psk_identity_hint(const std::string& type, + const std::string& context); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @param identity_hint was passed by the server (but may be empty) + * @return the PSK identity we want to use + */ + virtual std::string psk_identity(const std::string& type, + const std::string& context, + const std::string& identity_hint); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @param identity is a PSK identity previously returned by + psk_identity for the same type and context. + * @return the PSK used for identity, or throw an exception if no + * key exists + */ + virtual SymmetricKey psk(const std::string& type, + const std::string& context, + const std::string& identity); + }; + +} + +#endif 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 +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 -- cgit v1.2.3 From 8b799db5d4ede2010189db97e7801aad19af1fd2 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 1 Sep 2015 10:02:21 +0200 Subject: Add missing compression overrides --- src/lib/compression/bzip2/bzip2.h | 2 +- src/lib/compression/compression.h | 1 + src/lib/compression/lzma/lzma.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/lib') 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.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& buf, size_t offset = 0) override; void clear() override; + private: secure_vector 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; }; -- cgit v1.2.3 From d21de17f070863c7e0b7e8d254eb35689001a53a Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 10 Sep 2015 01:45:47 -0400 Subject: Fix static lib registration for block, hash, mac, stream, kdf The support problems from having static libraries not work in the obvious way will be endless trouble. Instead have each set of registrations tag along in a source file for the basic type, at the cost of some extra ifdefs. On shared libs this is harmless - everything is going into the shared object anyway. With static libs, this means pulling in a single block cipher pulls in the text of all the them. But that's still strictly better than the amalgamation (which is really pulling in everything), and it works (unlike status quo). --- src/lib/base/algo_registry.h | 8 +- src/lib/block/aes/aes.cpp | 6 +- src/lib/block/aes_ni/aes_ni.cpp | 6 +- src/lib/block/aes_ssse3/aes_ssse3.cpp | 8 - src/lib/block/block_cipher.cpp | 290 ++++++++++++++++++++++++ src/lib/block/block_cipher.h | 2 + src/lib/block/block_utils.h | 11 +- src/lib/block/blowfish/blowfish.cpp | 4 +- src/lib/block/camellia/camellia.cpp | 6 +- src/lib/block/cascade/cascade.cpp | 4 +- src/lib/block/cast/cast128.cpp | 4 +- src/lib/block/cast/cast256.cpp | 4 +- src/lib/block/des/des.cpp | 5 +- src/lib/block/des/desx.cpp | 4 +- src/lib/block/gost_28147/gost_28147.cpp | 4 +- src/lib/block/idea/idea.cpp | 4 +- src/lib/block/idea_sse2/idea_sse2.cpp | 4 - src/lib/block/kasumi/kasumi.cpp | 4 +- src/lib/block/lion/lion.cpp | 11 +- src/lib/block/lion/lion.h | 2 + src/lib/block/mars/mars.cpp | 4 +- src/lib/block/misty1/misty1.cpp | 4 +- src/lib/block/noekeon/noekeon.cpp | 4 +- src/lib/block/noekeon_simd/noekeon_simd.cpp | 4 - src/lib/block/rc2/rc2.cpp | 4 +- src/lib/block/rc5/rc5.cpp | 4 +- src/lib/block/rc6/rc6.cpp | 4 +- src/lib/block/safer/safer_sk.cpp | 4 +- src/lib/block/seed/seed.cpp | 4 +- src/lib/block/serpent/serpent.cpp | 4 +- src/lib/block/serpent_simd/serp_simd.cpp | 4 - src/lib/block/tea/tea.cpp | 4 +- src/lib/block/threefish/threefish.cpp | 4 +- src/lib/block/threefish_avx2/threefish_avx2.cpp | 4 - src/lib/block/twofish/twofish.cpp | 5 +- src/lib/block/xtea/xtea.cpp | 4 +- src/lib/block/xtea_simd/xtea_simd.cpp | 4 - src/lib/hash/checksum/adler32/adler32.cpp | 2 - src/lib/hash/checksum/crc24/crc24.cpp | 2 - src/lib/hash/checksum/crc32/crc32.cpp | 2 - src/lib/hash/comb4p/comb4p.cpp | 2 - src/lib/hash/gost_3411/gost_3411.cpp | 2 - src/lib/hash/has160/has160.cpp | 2 - src/lib/hash/hash.cpp | 180 +++++++++++++++ src/lib/hash/hash.h | 6 +- src/lib/hash/keccak/keccak.cpp | 2 - src/lib/hash/md2/md2.cpp | 2 - src/lib/hash/md4/md4.cpp | 2 - src/lib/hash/md5/md5.cpp | 2 - src/lib/hash/par_hash/par_hash.cpp | 2 - src/lib/hash/rmd128/rmd128.cpp | 2 - src/lib/hash/rmd160/rmd160.cpp | 2 - src/lib/hash/sha1/sha160.cpp | 2 - src/lib/hash/sha1_sse2/sha1_sse2.cpp | 3 - src/lib/hash/sha2_32/sha2_32.cpp | 3 - src/lib/hash/sha2_64/sha2_64.cpp | 4 - src/lib/hash/skein/skein_512.cpp | 2 - src/lib/hash/tiger/tiger.cpp | 2 - src/lib/hash/whirlpool/whirlpool.cpp | 2 - src/lib/kdf/hkdf/hkdf.cpp | 2 - src/lib/kdf/kdf.cpp | 51 ++++- src/lib/kdf/kdf1/kdf1.cpp | 2 - src/lib/kdf/kdf2/kdf2.cpp | 2 - src/lib/kdf/prf_tls/prf_tls.cpp | 3 - src/lib/kdf/prf_x942/prf_x942.cpp | 2 - src/lib/mac/cbc_mac/cbc_mac.cpp | 2 - src/lib/mac/cmac/cmac.cpp | 2 - src/lib/mac/hmac/hmac.cpp | 2 - src/lib/mac/mac.cpp | 52 +++++ src/lib/mac/mac.h | 6 +- src/lib/mac/poly1305/poly1305.cpp | 2 - src/lib/mac/siphash/siphash.cpp | 2 - src/lib/mac/x919_mac/x919_mac.cpp | 2 - src/lib/stream/chacha/chacha.cpp | 2 - src/lib/stream/ctr/ctr.cpp | 2 - src/lib/stream/ofb/ofb.cpp | 2 - src/lib/stream/rc4/rc4.cpp | 2 - src/lib/stream/salsa20/salsa20.cpp | 2 - src/lib/stream/stream_cipher.cpp | 61 +++++ src/lib/stream/stream_cipher.h | 10 +- 80 files changed, 685 insertions(+), 218 deletions(-) create mode 100644 src/lib/block/block_cipher.cpp create mode 100644 src/lib/hash/hash.cpp create mode 100644 src/lib/stream/stream_cipher.cpp (limited to 'src/lib') diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h index 498021194..8151551d3 100644 --- a/src/lib/base/algo_registry.h +++ b/src/lib/base/algo_registry.h @@ -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 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 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 providers() const 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 #include +#include 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 29e729da4..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 #include +#include #include #include namespace Botan { -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); - 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 50acd7668..bfc76ecee 100644 --- a/src/lib/block/aes_ssse3/aes_ssse3.cpp +++ b/src/lib/block/aes_ssse3/aes_ssse3.cpp @@ -10,20 +10,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include namespace Botan { -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); - 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..cc9d16737 --- /dev/null +++ b/src/lib/block/block_cipher.cpp @@ -0,0 +1,290 @@ +/* +* Block Ciphers +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +#if defined(BOTAN_HAS_AES) + #include +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + #include +#endif + +#if defined(BOTAN_HAS_AES_NI) + #include +#endif + +#if defined(BOTAN_HAS_BLOWFISH) + #include +#endif + +#if defined(BOTAN_HAS_CAMELLIA) + #include +#endif + +#if defined(BOTAN_HAS_CAST) + #include + #include +#endif + +#if defined(BOTAN_HAS_CASCADE) + #include +#endif + +#if defined(BOTAN_HAS_DES) + #include + #include +#endif + +#if defined(BOTAN_HAS_GOST_28147_89) + #include +#endif + +#if defined(BOTAN_HAS_IDEA) + #include +#endif + +#if defined(BOTAN_HAS_IDEA_SSE2) + #include +#endif + +#if defined(BOTAN_HAS_KASUMI) + #include +#endif + +#if defined(BOTAN_HAS_LION) + #include +#endif + +#if defined(BOTAN_HAS_LUBY_RACKOFF) + #include +#endif + +#if defined(BOTAN_HAS_MARS) + #include +#endif + +#if defined(BOTAN_HAS_MISTY1) + #include +#endif + +#if defined(BOTAN_HAS_NOEKEON) + #include +#endif + +#if defined(BOTAN_HAS_NOEKEON_SIMD) + #include +#endif + +#if defined(BOTAN_HAS_RC2) + #include +#endif + +#if defined(BOTAN_HAS_RC5) + #include +#endif + +#if defined(BOTAN_HAS_RC6) + #include +#endif + +#if defined(BOTAN_HAS_SAFER) + #include +#endif + +#if defined(BOTAN_HAS_SEED) + #include +#endif + +#if defined(BOTAN_HAS_SERPENT) + #include +#endif + +#if defined(BOTAN_HAS_SERPENT_SIMD) + #include +#endif + +#if defined(BOTAN_HAS_SKIPJACK) + #include +#endif + +#if defined(BOTAN_HAS_SQUARE) + #include +#endif + +#if defined(BOTAN_HAS_TEA) + #include +#endif + +#if defined(BOTAN_HAS_TWOFISH) + #include +#endif + +#if defined(BOTAN_HAS_THREEFISH_512) + #include +#endif + +#if defined(BOTAN_HAS_THREEFISH_512_AVX2) + #include +#endif + +#if defined(BOTAN_HAS_XTEA) + #include +#endif + +#if defined(BOTAN_HAS_XTEA_SIMD) + #include +#endif + +namespace Botan { + +BlockCipher::~BlockCipher() {} + +#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(SIMD_32::enabled(), 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(SIMD_32::enabled(), 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(SIMD_32::enabled(), 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..3f017dc89 100644 --- a/src/lib/block/block_cipher.h +++ b/src/lib/block/block_cipher.h @@ -141,6 +141,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 index 89f8a3dd3..c1eee27b1 100644 --- a/src/lib/block/block_utils.h +++ b/src/lib/block/block_utils.h @@ -1,20 +1,15 @@ /* -* Block Cipher Utility Header +* Internal 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__ +#ifndef BOTAN_INTERNAL_BLOCK_CIPHER_UTILS_H__ +#define BOTAN_INTERNAL_BLOCK_CIPHER_UTILS_H__ #include #include -#include -#include -#include -#include -#include namespace Botan { 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 #include +#include 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..dc57e26bc 100644 --- a/src/lib/block/camellia/camellia.cpp +++ b/src/lib/block/camellia/camellia.cpp @@ -5,16 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include +#include 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 Camellia_F { namespace { diff --git a/src/lib/block/cascade/cascade.cpp b/src/lib/block/cascade/cascade.cpp index 3b59a4362..66ff293ff 100644 --- a/src/lib/block/cascade/cascade.cpp +++ b/src/lib/block/cascade/cascade.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include 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 c1(get_block_cipher(spec.arg(0))); 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 #include #include +#include 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 #include #include +#include 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 #include +#include 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..4ab568638 100644 --- a/src/lib/block/des/desx.cpp +++ b/src/lib/block/des/desx.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include 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 #include +#include 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..ddfd8e5fb 100644 --- a/src/lib/block/idea/idea.cpp +++ b/src/lib/block/idea/idea.cpp @@ -5,13 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(IDEA); - namespace { /* diff --git a/src/lib/block/idea_sse2/idea_sse2.cpp b/src/lib/block/idea_sse2/idea_sse2.cpp index 8549d74d7..a2a54ac32 100644 --- a/src/lib/block/idea_sse2/idea_sse2.cpp +++ b/src/lib/block/idea_sse2/idea_sse2.cpp @@ -5,16 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_sse2(), IDEA_SSE2, "IDEA", - "sse2", BOTAN_SIMD_ALGORITHM_PRIO); - namespace { inline __m128i mul(__m128i X, u16bit K_16) 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 #include +#include 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..336828d89 100644 --- a/src/lib/block/lion/lion.cpp +++ b/src/lib/block/lion/lion.cpp @@ -5,15 +5,14 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include #include +#include namespace Botan { -namespace { - -Lion* make_lion(const BlockCipher::Spec& spec) +Lion* Lion::make(const BlockCipher::Spec& spec) { if(spec.arg_count_between(2, 3)) { @@ -29,10 +28,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 #include +#include 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 #include +#include #include 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 #include +#include 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 a51c6bc8f..07fcf19ff 100644 --- a/src/lib/block/noekeon_simd/noekeon_simd.cpp +++ b/src/lib/block/noekeon_simd/noekeon_simd.cpp @@ -5,15 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Noekeon_SIMD, "Noekeon", - "simd32", BOTAN_SIMD_ALGORITHM_PRIO); - /* * Noekeon's Theta Operation */ 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 #include +#include 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 #include +#include #include 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 #include +#include 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 #include +#include #include 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 #include +#include 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 #include +#include #include 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 56747dd16..02fe7d6d9 100644 --- a/src/lib/block/serpent_simd/serp_simd.cpp +++ b/src/lib/block/serpent_simd/serp_simd.cpp @@ -5,16 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Serpent_SIMD, "Serpent", - "simd32", BOTAN_SIMD_ALGORITHM_PRIO); - 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 #include +#include 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 #include +#include 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 435c75dbf..bed98fafa 100644 --- a/src/lib/block/threefish_avx2/threefish_avx2.cpp +++ b/src/lib/block/threefish_avx2/threefish_avx2.cpp @@ -5,16 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_avx2(), Threefish_512_AVX2, "Threefish-512", - "avx2", BOTAN_SIMD_ALGORITHM_PRIO); - 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 #include +#include +#include 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 #include +#include 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 a9984ce23..6e50f4ff7 100644 --- a/src/lib/block/xtea_simd/xtea_simd.cpp +++ b/src/lib/block/xtea_simd/xtea_simd.cpp @@ -5,15 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include namespace Botan { -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), XTEA_SIMD, "XTEA", - "simd32", BOTAN_SIMD_ALGORITHM_PRIO); - namespace { void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) diff --git a/src/lib/hash/checksum/adler32/adler32.cpp b/src/lib/hash/checksum/adler32/adler32.cpp index f2385c5b8..aadc5d39f 100644 --- a/src/lib/hash/checksum/adler32/adler32.cpp +++ b/src/lib/hash/checksum/adler32/adler32.cpp @@ -10,8 +10,6 @@ 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..054d23684 100644 --- a/src/lib/hash/checksum/crc24/crc24.cpp +++ b/src/lib/hash/checksum/crc24/crc24.cpp @@ -11,8 +11,6 @@ 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..ca9514c26 100644 --- a/src/lib/hash/checksum/crc32/crc32.cpp +++ b/src/lib/hash/checksum/crc32/crc32.cpp @@ -10,8 +10,6 @@ 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..ec39bbc31 100644 --- a/src/lib/hash/comb4p/comb4p.cpp +++ b/src/lib/hash/comb4p/comb4p.cpp @@ -12,8 +12,6 @@ namespace Botan { -BOTAN_REGISTER_NAMED_T(HashFunction, "Comb4P", Comb4P, Comb4P::make); - namespace { void comb4p_round(secure_vector& out, diff --git a/src/lib/hash/gost_3411/gost_3411.cpp b/src/lib/hash/gost_3411/gost_3411.cpp index 918556ca0..fb1c39384 100644 --- a/src/lib/hash/gost_3411/gost_3411.cpp +++ b/src/lib/hash/gost_3411/gost_3411.cpp @@ -11,8 +11,6 @@ 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..dd4bc1428 100644 --- a/src/lib/hash/has160/has160.cpp +++ b/src/lib/hash/has160/has160.cpp @@ -10,8 +10,6 @@ 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..723a7eba7 --- /dev/null +++ b/src/lib/hash/hash.cpp @@ -0,0 +1,180 @@ +/* +* Hash Functions +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_HAS_ADLER32) + #include +#endif + +#if defined(BOTAN_HAS_CRC24) + #include +#endif + +#if defined(BOTAN_HAS_CRC32) + #include +#endif + +#if defined(BOTAN_HAS_GOST_34_11) + #include +#endif + +#if defined(BOTAN_HAS_HAS_160) + #include +#endif + +#if defined(BOTAN_HAS_KECCAK) + #include +#endif + +#if defined(BOTAN_HAS_MD2) + #include +#endif + +#if defined(BOTAN_HAS_MD4) + #include +#endif + +#if defined(BOTAN_HAS_MD5) + #include +#endif + +#if defined(BOTAN_HAS_RIPEMD_128) + #include +#endif + +#if defined(BOTAN_HAS_RIPEMD_160) + #include +#endif + +#if defined(BOTAN_HAS_SHA1) + #include +#endif + +#if defined(BOTAN_HAS_SHA1_SSE2) + #include +#endif + +#if defined(BOTAN_HAS_SHA2_32) + #include +#endif + +#if defined(BOTAN_HAS_SHA2_64) + #include +#endif + +#if defined(BOTAN_HAS_SKEIN_512) + #include +#endif + +#if defined(BOTAN_HAS_TIGER) + #include +#endif + +#if defined(BOTAN_HAS_WHIRLPOOL) + #include +#endif + +#if defined(BOTAN_HAS_PARALLEL_HASH) + #include +#endif + +#if defined(BOTAN_HAS_COMB4P) + #include +#endif + +namespace Botan { + +HashFunction::~HashFunction() {} + +#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..8406a4c0f 100644 --- a/src/lib/hash/hash.h +++ b/src/lib/hash/hash.h @@ -20,11 +20,15 @@ namespace Botan { class BOTAN_DLL HashFunction : public Buffered_Computation { public: + typedef SCAN_Name Spec; + /** * @return new object representing the same algorithm as *this */ virtual HashFunction* clone() const = 0; + virtual ~HashFunction(); + virtual void clear() = 0; virtual std::string name() const = 0; @@ -33,8 +37,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/keccak/keccak.cpp b/src/lib/hash/keccak/keccak.cpp index 8ee2357b6..3cebe42da 100644 --- a/src/lib/hash/keccak/keccak.cpp +++ b/src/lib/hash/keccak/keccak.cpp @@ -13,8 +13,6 @@ 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..8b8810941 100644 --- a/src/lib/hash/md2/md2.cpp +++ b/src/lib/hash/md2/md2.cpp @@ -11,8 +11,6 @@ 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..f8cbb2b6b 100644 --- a/src/lib/hash/md4/md4.cpp +++ b/src/lib/hash/md4/md4.cpp @@ -10,8 +10,6 @@ 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..61d8aa980 100644 --- a/src/lib/hash/md5/md5.cpp +++ b/src/lib/hash/md5/md5.cpp @@ -10,8 +10,6 @@ namespace Botan { -BOTAN_REGISTER_HASH_NOARGS(MD5); - namespace { /* diff --git a/src/lib/hash/par_hash/par_hash.cpp b/src/lib/hash/par_hash/par_hash.cpp index b6133929c..12271640a 100644 --- a/src/lib/hash/par_hash/par_hash.cpp +++ b/src/lib/hash/par_hash/par_hash.cpp @@ -11,8 +11,6 @@ namespace Botan { -BOTAN_REGISTER_NAMED_T(HashFunction, "Parallel", Parallel, Parallel::make); - Parallel* Parallel::make(const Spec& spec) { std::vector> hashes; diff --git a/src/lib/hash/rmd128/rmd128.cpp b/src/lib/hash/rmd128/rmd128.cpp index 7138d54d7..1f655199e 100644 --- a/src/lib/hash/rmd128/rmd128.cpp +++ b/src/lib/hash/rmd128/rmd128.cpp @@ -10,8 +10,6 @@ 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..c1b1032ae 100644 --- a/src/lib/hash/rmd160/rmd160.cpp +++ b/src/lib/hash/rmd160/rmd160.cpp @@ -10,8 +10,6 @@ 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..04227c6bb 100644 --- a/src/lib/hash/sha1/sha160.cpp +++ b/src/lib/hash/sha1/sha160.cpp @@ -10,8 +10,6 @@ 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 7cd457597..fefea52af 100644 --- a/src/lib/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/lib/hash/sha1_sse2/sha1_sse2.cpp @@ -14,9 +14,6 @@ namespace Botan { -BOTAN_REGISTER_HASH_NOARGS_IF(CPUID::has_sse2(), SHA_160_SSE2, "SHA-160", - "sse2", BOTAN_SIMD_ALGORITHM_PRIO); - 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..a867e6dd0 100644 --- a/src/lib/hash/sha2_32/sha2_32.cpp +++ b/src/lib/hash/sha2_32/sha2_32.cpp @@ -11,9 +11,6 @@ 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..98d16900b 100644 --- a/src/lib/hash/sha2_64/sha2_64.cpp +++ b/src/lib/hash/sha2_64/sha2_64.cpp @@ -10,10 +10,6 @@ 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..ce0e8353d 100644 --- a/src/lib/hash/skein/skein_512.cpp +++ b/src/lib/hash/skein/skein_512.cpp @@ -14,8 +14,6 @@ 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..d724c3da8 100644 --- a/src/lib/hash/tiger/tiger.cpp +++ b/src/lib/hash/tiger/tiger.cpp @@ -12,8 +12,6 @@ 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..edcc31d26 100644 --- a/src/lib/hash/whirlpool/whirlpool.cpp +++ b/src/lib/hash/whirlpool/whirlpool.cpp @@ -10,8 +10,6 @@ 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..df6e49fad 100644 --- a/src/lib/kdf/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -10,8 +10,6 @@ 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))) diff --git a/src/lib/kdf/kdf.cpp b/src/lib/kdf/kdf.cpp index 793cd3d62..89bb8d58a 100644 --- a/src/lib/kdf/kdf.cpp +++ b/src/lib/kdf/kdf.cpp @@ -6,8 +6,31 @@ */ #include -#include -#include +#include + +#if defined(BOTAN_HAS_HKDF) +#include +#endif + +#if defined(BOTAN_HAS_KDF1) +#include +#endif + +#if defined(BOTAN_HAS_KDF2) +#include +#endif + +#if defined(BOTAN_HAS_TLS_V10_PRF) +#include +#endif + +#if defined(BOTAN_HAS_TLS_V12_PRF) +#include +#endif + +#if defined(BOTAN_HAS_X942_PRF) +#include +#endif namespace Botan { @@ -23,4 +46,28 @@ KDF* get_kdf(const std::string& algo_spec) throw Algorithm_Not_Found(algo_spec); } +#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/kdf1/kdf1.cpp b/src/lib/kdf/kdf1/kdf1.cpp index fa3432467..c87bacd27 100644 --- a/src/lib/kdf/kdf1/kdf1.cpp +++ b/src/lib/kdf/kdf1/kdf1.cpp @@ -10,8 +10,6 @@ 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..1b1c3638a 100644 --- a/src/lib/kdf/kdf2/kdf2.cpp +++ b/src/lib/kdf/kdf2/kdf2.cpp @@ -10,8 +10,6 @@ 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/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp index 4fdec8fef..ef130d5ba 100644 --- a/src/lib/kdf/prf_tls/prf_tls.cpp +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -20,9 +20,6 @@ TLS_12_PRF* TLS_12_PRF::make(const Spec& spec) 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)")) diff --git a/src/lib/kdf/prf_x942/prf_x942.cpp b/src/lib/kdf/prf_x942/prf_x942.cpp index 622d68c1a..e8f234e49 100644 --- a/src/lib/kdf/prf_x942/prf_x942.cpp +++ b/src/lib/kdf/prf_x942/prf_x942.cpp @@ -15,8 +15,6 @@ namespace Botan { -BOTAN_REGISTER_KDF_NAMED_1STR(X942_PRF, "X9.42-PRF"); - namespace { /* diff --git a/src/lib/mac/cbc_mac/cbc_mac.cpp b/src/lib/mac/cbc_mac/cbc_mac.cpp index b58372c78..29507f17b 100644 --- a/src/lib/mac/cbc_mac/cbc_mac.cpp +++ b/src/lib/mac/cbc_mac/cbc_mac.cpp @@ -20,8 +20,6 @@ CBC_MAC* CBC_MAC::make(const Spec& spec) 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..85c19c19f 100644 --- a/src/lib/mac/cmac/cmac.cpp +++ b/src/lib/mac/cmac/cmac.cpp @@ -20,8 +20,6 @@ CMAC* CMAC::make(const Spec& spec) 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..2cd512746 100644 --- a/src/lib/mac/hmac/hmac.cpp +++ b/src/lib/mac/hmac/hmac.cpp @@ -21,8 +21,6 @@ HMAC* HMAC::make(const Spec& spec) return nullptr; } -BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "HMAC", HMAC, HMAC::make); - /* * Update a HMAC Calculation */ diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp index 0bb1939c7..af59bd4c6 100644 --- a/src/lib/mac/mac.cpp +++ b/src/lib/mac/mac.cpp @@ -6,10 +6,37 @@ */ #include +#include #include +#if defined(BOTAN_HAS_CBC_MAC) + #include +#endif + +#if defined(BOTAN_HAS_CMAC) + #include +#endif + +#if defined(BOTAN_HAS_HMAC) + #include +#endif + +#if defined(BOTAN_HAS_POLY1305) + #include +#endif + +#if defined(BOTAN_HAS_SIPHASH) + #include +#endif + +#if defined(BOTAN_HAS_ANSI_X919_MAC) + #include +#endif + namespace Botan { +MessageAuthenticationCode::~MessageAuthenticationCode() {} + /* * Default (deterministic) MAC verification operation */ @@ -23,4 +50,29 @@ 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_MAC_NOARGS(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_MAC_NAMED_NOARGS(ANSI_X919_MAC, "X9.19-MAC"); +#endif + } diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h index 8ad2d1e99..28894bbcd 100644 --- a/src/lib/mac/mac.h +++ b/src/lib/mac/mac.h @@ -22,6 +22,10 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, public SymmetricAlgorithm { public: + typedef SCAN_Name Spec; + + virtual ~MessageAuthenticationCode(); + /** * Verify a MAC. * @param in the MAC to verify as a byte array @@ -34,8 +38,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/poly1305/poly1305.cpp b/src/lib/mac/poly1305/poly1305.cpp index 659667baf..1a072c6b4 100644 --- a/src/lib/mac/poly1305/poly1305.cpp +++ b/src/lib/mac/poly1305/poly1305.cpp @@ -16,8 +16,6 @@ namespace Botan { -BOTAN_REGISTER_MAC_NOARGS(Poly1305); - namespace { void poly1305_init(secure_vector& X, const byte key[32]) diff --git a/src/lib/mac/siphash/siphash.cpp b/src/lib/mac/siphash/siphash.cpp index f8ed28a84..689d03c13 100644 --- a/src/lib/mac/siphash/siphash.cpp +++ b/src/lib/mac/siphash/siphash.cpp @@ -10,8 +10,6 @@ namespace Botan { -BOTAN_REGISTER_NAMED_T_2LEN(MessageAuthenticationCode, SipHash, "SipHash", "base", 2, 4); - namespace { void SipRounds(u64bit M, secure_vector& 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..ce7c38ebb 100644 --- a/src/lib/mac/x919_mac/x919_mac.cpp +++ b/src/lib/mac/x919_mac/x919_mac.cpp @@ -10,8 +10,6 @@ namespace Botan { -BOTAN_REGISTER_MAC_NAMED_NOARGS(ANSI_X919_MAC, "X9.19-MAC"); - /* * Update an ANSI X9.19 MAC Calculation */ diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp index 9841f99a2..9aa3c2a73 100644 --- a/src/lib/stream/chacha/chacha.cpp +++ b/src/lib/stream/chacha/chacha.cpp @@ -10,8 +10,6 @@ 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..d025a03d3 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -10,8 +10,6 @@ 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) diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index b98f81be3..73ffef980 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -10,8 +10,6 @@ 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) diff --git a/src/lib/stream/rc4/rc4.cpp b/src/lib/stream/rc4/rc4.cpp index 3fd0d2276..31fd2cca0 100644 --- a/src/lib/stream/rc4/rc4.cpp +++ b/src/lib/stream/rc4/rc4.cpp @@ -10,8 +10,6 @@ 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..141d9e51e 100644 --- a/src/lib/stream/salsa20/salsa20.cpp +++ b/src/lib/stream/salsa20/salsa20.cpp @@ -10,8 +10,6 @@ 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..2f1538914 --- /dev/null +++ b/src/lib/stream/stream_cipher.cpp @@ -0,0 +1,61 @@ +/* +* Stream Ciphers +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#if defined(BOTAN_HAS_CHACHA) +#include +#endif + +#if defined(BOTAN_HAS_SALSA20) +#include +#endif + +#if defined(BOTAN_HAS_CTR_BE) +#include +#endif + +#if defined(BOTAN_HAS_OFB) +#include +#endif + +#if defined(BOTAN_HAS_RC4) +#include +#endif + +namespace Botan { + +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_STREAM_CIPHER_NOARGS(ChaCha); +#endif + +#if defined(BOTAN_HAS_SALSA20) +BOTAN_REGISTER_STREAM_CIPHER_NOARGS(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..5500bca49 100644 --- a/src/lib/stream/stream_cipher.h +++ b/src/lib/stream/stream_cipher.h @@ -20,6 +20,8 @@ namespace Botan { class BOTAN_DLL StreamCipher : public SymmetricAlgorithm { public: + typedef SCAN_Name Spec; + /** * Encrypt or decrypt a message * @param in the plaintext @@ -53,11 +55,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 +68,7 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm */ virtual StreamCipher* clone() const = 0; - typedef SCAN_Name Spec; + virtual ~StreamCipher(); }; } -- cgit v1.2.3 From 53082a739c78d50fd54422ac1b8a34f742890b10 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 10 Sep 2015 01:57:42 -0400 Subject: Reduce likelyhood of stray pointer writes via ffi layer. In error cases the output value was not intialized, so callers which ignored the error return might blindly use an uninitialized pointer. --- src/lib/ffi/ffi.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/lib') diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 8d96a0fc7..625b1947b 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -912,6 +912,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 +957,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 +1001,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 +1092,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; -- cgit v1.2.3 From 8211fdc11fa3bbe692b50d42126f74d259a4a96a Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 10 Sep 2015 02:42:48 -0400 Subject: Same treatment for cipher modes --- src/lib/modes/aead/aead.cpp | 51 +++++++++++++++++ src/lib/modes/aead/aead.h | 2 + src/lib/modes/aead/ccm/ccm.cpp | 2 - .../aead/chacha20poly1305/chacha20poly1305.cpp | 3 - src/lib/modes/aead/eax/eax.cpp | 2 - src/lib/modes/aead/gcm/gcm.cpp | 2 - src/lib/modes/aead/ocb/ocb.cpp | 2 - src/lib/modes/aead/siv/siv.cpp | 2 - src/lib/modes/cbc/cbc.cpp | 21 ------- src/lib/modes/cfb/cfb.cpp | 2 - src/lib/modes/cipher_mode.cpp | 65 ++++++++++++++++++++++ src/lib/modes/ecb/ecb.cpp | 13 ----- src/lib/modes/xts/xts.cpp | 2 - 13 files changed, 118 insertions(+), 51 deletions(-) (limited to 'src/lib') diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp index 1f2099d2e..c101480b4 100644 --- a/src/lib/modes/aead/aead.cpp +++ b/src/lib/modes/aead/aead.cpp @@ -7,8 +7,59 @@ #include #include +#if defined(BOTAN_HAS_AEAD_CCM) +#include +#endif + +#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305) +#include +#endif + +#if defined(BOTAN_HAS_AEAD_EAX) +#include +#endif + +#if defined(BOTAN_HAS_AEAD_GCM) +#include +#endif + +#if defined(BOTAN_HAS_AEAD_OCB) +#include +#endif + +#if defined(BOTAN_HAS_AEAD_SIV) +#include +#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 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..329e2e713 100644 --- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp +++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp @@ -10,9 +10,6 @@ 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")) 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& 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 -Transform* make_cbc_mode(const Transform::Spec& spec) - { - std::unique_ptr 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)); -BOTAN_REGISTER_TRANSFORM(CBC_Decryption, (make_cbc_mode)); - 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..98e2218dc 100644 --- a/src/lib/modes/cipher_mode.cpp +++ b/src/lib/modes/cipher_mode.cpp @@ -8,10 +8,75 @@ #include #include #include +#include #include +#if defined(BOTAN_HAS_MODE_ECB) +#include +#endif + +#if defined(BOTAN_HAS_MODE_CBC) +#include +#endif + +#if defined(BOTAN_HAS_MODE_CFB) +#include +#endif + +#if defined(BOTAN_HAS_MODE_XTS) +#include +#endif + namespace Botan { +#if defined(BOTAN_HAS_MODE_ECB) + +template +Transform* make_ecb_mode(const Transform::Spec& spec) + { + std::unique_ptr bc(get_block_cipher(spec.arg(0))); + std::unique_ptr 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); +BOTAN_REGISTER_TRANSFORM(ECB_Decryption, make_ecb_mode); +#endif + +#if defined(BOTAN_HAS_MODE_CBC) + +template +Transform* make_cbc_mode(const Transform::Spec& spec) + { + std::unique_ptr 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)); +BOTAN_REGISTER_TRANSFORM(CBC_Decryption, (make_cbc_mode)); +#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 = ""; 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 -Transform* make_ecb_mode(const Transform::Spec& spec) - { - std::unique_ptr bc(get_block_cipher(spec.arg(0))); - std::unique_ptr 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); -BOTAN_REGISTER_TRANSFORM(ECB_Decryption, make_ecb_mode); - ECB_Mode::ECB_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : m_cipher(cipher), m_padding(padding) 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[]) -- cgit v1.2.3 From 72719f52640d2ac3ff00fce46a72082e5938d212 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 11 Sep 2015 22:44:45 -0400 Subject: Fix pbkdf, pk padding and ECDH registration for static linking. With this change the tests pass when linked against a static library built in the normal (non-amalgamation) fashion. Remove the restriction in configure.py, and have circleci build the clang static build as a non-amalg. --- configure.py | 4 -- src/lib/kdf/kdf.cpp | 2 + src/lib/kdf/kdf.h | 2 +- src/lib/pbkdf/info.txt | 4 -- src/lib/pbkdf/pbkdf.cpp | 20 ++++++++ src/lib/pbkdf/pbkdf1/pbkdf1.cpp | 3 -- src/lib/pbkdf/pbkdf2/pbkdf2.cpp | 4 +- src/lib/pbkdf/pbkdf_utils.h | 23 --------- src/lib/pk_pad/eme.cpp | 38 +++++++++++++++ src/lib/pk_pad/eme_oaep/oaep.cpp | 6 +-- src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp | 3 -- src/lib/pk_pad/eme_raw/eme_raw.cpp | 3 -- src/lib/pk_pad/emsa.cpp | 74 +++++++++++++++++++++++++++++ src/lib/pk_pad/emsa.h | 7 ++- src/lib/pk_pad/emsa1/emsa1.cpp | 3 -- src/lib/pk_pad/emsa1_bsi/emsa1_bsi.cpp | 3 -- src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp | 8 +--- src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h | 2 + src/lib/pk_pad/emsa_pssr/pssr.cpp | 4 +- src/lib/pk_pad/emsa_raw/emsa_raw.cpp | 2 - src/lib/pk_pad/emsa_x931/emsa_x931.cpp | 3 -- src/lib/pk_pad/get_pk_pad.cpp | 38 --------------- src/lib/pk_pad/pad_utils.h | 3 -- src/lib/pubkey/ecdh/ecdh.cpp | 2 + src/lib/pubkey/ecdh/ecdh.h | 2 +- src/scripts/ci/circle/clang-static-debug.sh | 2 +- src/tests/test_ffi.cpp | 10 ++-- 27 files changed, 155 insertions(+), 120 deletions(-) delete mode 100644 src/lib/pbkdf/pbkdf_utils.h create mode 100644 src/lib/pk_pad/emsa.cpp delete mode 100644 src/lib/pk_pad/get_pk_pad.cpp (limited to 'src/lib') diff --git a/configure.py b/configure.py index 235c631ef..68ecf3a7a 100755 --- a/configure.py +++ b/configure.py @@ -1922,10 +1922,6 @@ def main(argv = None): if options.via_amalgamation: options.gen_amalgamation = True - if not options.build_shared_lib and not options.via_amalgamation: - raise Exception('Static build is only supported using amalgamation. ' - 'Add --via-amalgamation.') - if options.build_shared_lib and not osinfo.building_shared_supported: raise Exception('Botan does not support building as shared library on the target os. ' 'Build static using --disable-shared.') diff --git a/src/lib/kdf/kdf.cpp b/src/lib/kdf/kdf.cpp index 89bb8d58a..836e9b982 100644 --- a/src/lib/kdf/kdf.cpp +++ b/src/lib/kdf/kdf.cpp @@ -34,6 +34,8 @@ namespace Botan { +KDF::~KDF() {} + KDF* get_kdf(const std::string& algo_spec) { SCAN_Name request(algo_spec); diff --git a/src/lib/kdf/kdf.h b/src/lib/kdf/kdf.h index d69c1ece5..936e7c5f1 100644 --- a/src/lib/kdf/kdf.h +++ b/src/lib/kdf/kdf.h @@ -21,7 +21,7 @@ namespace Botan { class BOTAN_DLL KDF { public: - virtual ~KDF() {} + virtual ~KDF(); virtual std::string name() const = 0; 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 pbkdf.h - - -pbkdf_utils.h - diff --git a/src/lib/pbkdf/pbkdf.cpp b/src/lib/pbkdf/pbkdf.cpp index 7f0a68a01..f11fbc44d 100644 --- a/src/lib/pbkdf/pbkdf.cpp +++ b/src/lib/pbkdf/pbkdf.cpp @@ -6,10 +6,30 @@ */ #include +#include #include +#if defined(BOTAN_HAS_PBKDF1) +#include +#endif + +#if defined(BOTAN_HAS_PBKDF2) +#include +#endif + namespace Botan { +#define BOTAN_REGISTER_PBKDF_1HASH(type, name) \ + BOTAN_REGISTER_NAMED_T(PBKDF, name, type, (make_new_T_1X)) + +#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 + 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/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 #include #include 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..a5b7f011e 100644 --- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp +++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -5,16 +5,14 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include #include #include #include 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))) 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 -#include - -namespace Botan { - -#define BOTAN_REGISTER_PBKDF_1HASH(type, name) \ - BOTAN_REGISTER_NAMED_T(PBKDF, name, type, (make_new_T_1X)) -#define BOTAN_REGISTER_PBKDF_1MAC(type, name) \ - BOTAN_REGISTER_NAMED_T(PBKDF, name, type, (make_new_T_1X)) - -} - -#endif diff --git a/src/lib/pk_pad/eme.cpp b/src/lib/pk_pad/eme.cpp index 9398b4c83..153ef8922 100644 --- a/src/lib/pk_pad/eme.cpp +++ b/src/lib/pk_pad/eme.cpp @@ -6,9 +6,47 @@ */ #include +#include + +#if defined(BOTAN_HAS_EME_OAEP) +#include +#endif + +#if defined(BOTAN_HAS_EME_PKCS1v15) +#include +#endif + +#if defined(BOTAN_HAS_EME_RAW) +#include +#endif namespace Botan { +#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(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..a484202da 100644 --- a/src/lib/pk_pad/eme_oaep/oaep.cpp +++ b/src/lib/pk_pad/eme_oaep/oaep.cpp @@ -5,11 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include - +#include namespace Botan { @@ -28,9 +27,6 @@ OAEP* OAEP::make(const Spec& request) return nullptr; } -BOTAN_REGISTER_NAMED_T(EME, "OAEP", OAEP, OAEP::make); - - /* * OAEP Pad Operation */ diff --git a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp index 90af17565..65d29cd59 100644 --- a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp +++ b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp @@ -5,13 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { -BOTAN_REGISTER_EME_NAMED_NOARGS(EME_PKCS1v15, "PKCS1v15"); - /* * PKCS1 Pad Operation */ 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 #include #include namespace Botan { -BOTAN_REGISTER_EME_NAMED_NOARGS(EME_Raw, "Raw"); - secure_vector 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..9682d9b6e --- /dev/null +++ b/src/lib/pk_pad/emsa.cpp @@ -0,0 +1,74 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#if defined(BOTAN_HAS_EMSA1) + #include +#endif + +#if defined(BOTAN_HAS_EMSA1_BSI) + #include +#endif + +#if defined(BOTAN_HAS_EMSA_X931) + #include +#endif + +#if defined(BOTAN_HAS_EMSA_PKCS1) + #include +#endif + +#if defined(BOTAN_HAS_EMSA_PSSR) + #include +#endif + +#if defined(BOTAN_HAS_EMSA_RAW) + #include +#endif + +namespace Botan { + +EMSA::~EMSA() {} + +EMSA* get_emsa(const std::string& algo_spec) + { + SCAN_Name request(algo_spec); + + if(EMSA* emsa = make_a(algo_spec)) + return emsa; + + throw Algorithm_Not_Found(algo_spec); + } + +#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& coded, const secure_vector& 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 #include namespace Botan { -BOTAN_REGISTER_EMSA_1HASH(EMSA1, "EMSA1"); - namespace { secure_vector emsa1_encoding(const secure_vector& 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 #include 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..d928511d3 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp @@ -11,9 +11,7 @@ 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; @@ -25,10 +23,6 @@ EMSA* make_pkcs1v15(const EMSA::Spec& spec) return nullptr; } -} - -BOTAN_REGISTER_NAMED_T(EMSA, "EMSA_PKCS1", EMSA_PCS1v15, make_pkcs1v15); - namespace { secure_vector emsa3_encoding(const secure_vector& 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..06ca007c8 100644 --- a/src/lib/pk_pad/emsa_pssr/pssr.cpp +++ b/src/lib/pk_pad/emsa_pssr/pssr.cpp @@ -5,10 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include +#include namespace Botan { @@ -26,8 +26,6 @@ PSSR* PSSR::make(const Spec& request) 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..287acb233 100644 --- a/src/lib/pk_pad/emsa_raw/emsa_raw.cpp +++ b/src/lib/pk_pad/emsa_raw/emsa_raw.cpp @@ -10,8 +10,6 @@ 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 #include #include namespace Botan { -BOTAN_REGISTER_EMSA_1HASH(EMSA_X931, "EMSA_X931"); - namespace { secure_vector emsa2_encoding(const secure_vector& 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 -#include -#include -#include - -namespace Botan { - -EMSA* get_emsa(const std::string& algo_spec) - { - SCAN_Name request(algo_spec); - - if(EMSA* emsa = make_a(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(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/pad_utils.h b/src/lib/pk_pad/pad_utils.h index 3918e133a..ba2de65ea 100644 --- a/src/lib/pk_pad/pad_utils.h +++ b/src/lib/pk_pad/pad_utils.h @@ -9,9 +9,6 @@ #define BOTAN_PK_PAD_UTILS_H__ #include -#include -#include -#include namespace Botan { 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/scripts/ci/circle/clang-static-debug.sh b/src/scripts/ci/circle/clang-static-debug.sh index 8bf96fcfe..6341dd467 100755 --- a/src/scripts/ci/circle/clang-static-debug.sh +++ b/src/scripts/ci/circle/clang-static-debug.sh @@ -5,6 +5,6 @@ which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if avai BUILD_NICKNAME=$(basename "$0" .sh) BUILD_DIR="./build-$BUILD_NICKNAME" -./configure.py --with-build-dir="$BUILD_DIR" --build-mode=debug --cc=clang --disable-shared --via-amalgamation +./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/tests/test_ffi.cpp b/src/tests/test_ffi.cpp index 5aa4930b9..63f8a5b20 100644 --- a/src/tests/test_ffi.cpp +++ b/src/tests/test_ffi.cpp @@ -346,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)); @@ -356,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 pubkey1(256); // length problem again size_t pubkey1_len = pubkey1.size(); @@ -371,7 +371,7 @@ TEST_CASE("FFI ECDH", "[ffi]") pubkey2.resize(pubkey2_len); std::vector 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; -- cgit v1.2.3 From d83ef010522373a6f8ed3876c812b18b55513103 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 11 Sep 2015 23:37:49 -0400 Subject: Fix for minimized builds --- src/lib/block/block_cipher.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp index cc9d16737..616c6df5b 100644 --- a/src/lib/block/block_cipher.cpp +++ b/src/lib/block/block_cipher.cpp @@ -7,9 +7,12 @@ #include #include -#include #include +#if defined(BOTAN_HAS_SIMD_32) +#include +#endif + #if defined(BOTAN_HAS_AES) #include #endif -- cgit v1.2.3 From e2e0f8f2b595122c1f8acb3b3a46501f96a2b218 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 17 Sep 2015 17:08:01 -0400 Subject: Handle dependencies re static linking. GH #279 Previously we were hanging on the type destructors to pull in the relevant objects. However that fails in many simple cases where the object is never deleted. For every type involved in the algo registry add static create and providers functions to access the algo registry. Modify lookup.h to be inline and call those functions, and move a few to sub-headers (eg, get_pbkdf going to pbkdf.h). So accessing the registry involves going through the same file that handles the initialization, so there is no way to end up with missing objs. --- src/lib/base/algo_registry.h | 2 +- src/lib/base/info.txt | 1 - src/lib/base/lookup.cpp | 109 ------------------------------- src/lib/base/lookup.h | 108 ++++++++++++++++++++---------- src/lib/base/transform.cpp | 20 ++++++ src/lib/block/block_cipher.cpp | 11 ++++ src/lib/block/block_cipher.h | 13 ++++ src/lib/hash/comb4p/comb4p.cpp | 5 +- src/lib/hash/hash.cpp | 13 ++++ src/lib/hash/hash.h | 15 +++++ src/lib/hash/par_hash/par_hash.cpp | 2 +- src/lib/kdf/hkdf/hkdf.cpp | 2 +- src/lib/kdf/info.txt | 4 -- src/lib/kdf/kdf.cpp | 28 ++++++-- src/lib/kdf/kdf.h | 13 ++++ src/lib/kdf/kdf1/kdf1.cpp | 1 - src/lib/kdf/kdf2/kdf2.cpp | 1 - src/lib/kdf/kdf_utils.h | 28 -------- src/lib/kdf/prf_tls/prf_tls.cpp | 3 +- src/lib/kdf/prf_x942/prf_x942.cpp | 2 +- src/lib/mac/cbc_mac/cbc_mac.cpp | 1 + src/lib/mac/cmac/cmac.cpp | 1 + src/lib/mac/hmac/hmac.cpp | 1 + src/lib/mac/mac.cpp | 11 ++++ src/lib/mac/mac.h | 13 ++++ src/lib/mac/x919_mac/x919_mac.cpp | 1 + src/lib/modes/aead/aead.cpp | 1 + src/lib/modes/mode_utils.h | 1 + src/lib/pbkdf/pbkdf.cpp | 13 ++++ src/lib/pbkdf/pbkdf.h | 30 ++++++++- src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp | 1 + src/lib/stream/ctr/ctr.cpp | 1 + src/lib/stream/ofb/ofb.cpp | 1 + src/lib/stream/stream_cipher.cpp | 12 ++++ src/lib/stream/stream_cipher.h | 14 ++++ 35 files changed, 291 insertions(+), 192 deletions(-) delete mode 100644 src/lib/base/lookup.cpp create mode 100644 src/lib/base/transform.cpp delete mode 100644 src/lib/kdf/kdf_utils.h (limited to 'src/lib') diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h index 8151551d3..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 +#include #include #include #include diff --git a/src/lib/base/info.txt b/src/lib/base/info.txt index 19eee6608..33d22a279 100644 --- a/src/lib/base/info.txt +++ b/src/lib/base/info.txt @@ -23,7 +23,6 @@ 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 -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -Transform* get_transform(const std::string& specstr, - const std::string& provider, - const std::string& dirstr) - { - Algo_Registry::Spec spec(specstr, dirstr); - return Algo_Registry::global_registry().make(spec, provider); - } - -BlockCipher* get_block_cipher(const std::string& algo_spec, const std::string& provider) - { - return make_a(algo_spec, provider); - } - -StreamCipher* get_stream_cipher(const std::string& algo_spec, const std::string& provider) - { - return make_a(algo_spec, provider); - } - -HashFunction* get_hash_function(const std::string& algo_spec, const std::string& provider) - { - return make_a(algo_spec, provider); - } - -MessageAuthenticationCode* get_mac(const std::string& algo_spec, const std::string& provider) - { - return make_a(algo_spec, provider); - } - -std::unique_ptr 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(x); - throw Algorithm_Not_Found(algo_spec); - } - -std::unique_ptr 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(x); - throw Algorithm_Not_Found(algo_spec); - } - -std::unique_ptr 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(x); - throw Algorithm_Not_Found(algo_spec); - } - -std::unique_ptr make_message_auth(const std::string& algo_spec, - const std::string& provider) - { - if(auto x = get_mac(algo_spec, provider)) - return std::unique_ptr(x); - throw Algorithm_Not_Found(algo_spec); - } - -std::vector get_block_cipher_providers(const std::string& algo_spec) - { - return providers_of(BlockCipher::Spec(algo_spec)); - } - -std::vector get_stream_cipher_providers(const std::string& algo_spec) - { - return providers_of(StreamCipher::Spec(algo_spec)); - } - -std::vector get_hash_function_providers(const std::string& algo_spec) - { - return providers_of(HashFunction::Spec(algo_spec)); - } - -std::vector get_mac_providers(const std::string& algo_spec) - { - return providers_of(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(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 +#include +#include +#include +#include +#include #include #include #include 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 make_block_cipher(const std::string& algo_spec, - const std::string& provider = ""); +inline std::unique_ptr make_block_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + std::unique_ptr p(BlockCipher::create(algo_spec, provider)); + if(p) + return p; + throw Algorithm_Not_Found(algo_spec); + } -BOTAN_DLL std::vector get_block_cipher_providers(const std::string& algo_spec); +inline std::vector 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 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 make_stream_cipher(const std::string& algo_spec, - const std::string& provider = ""); +inline std::unique_ptr make_stream_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + std::unique_ptr p(StreamCipher::create(algo_spec, provider)); + if(p) + return p; + throw Algorithm_Not_Found(algo_spec); + } -BOTAN_DLL std::vector get_stream_cipher_providers(const std::string& algo_spec); +inline std::vector 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 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 make_hash_function(const std::string& algo_spec, - const std::string& provider = ""); +inline std::unique_ptr make_hash_function(const std::string& algo_spec, + const std::string& provider = "") + { + std::unique_ptr 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 get_hash_function_providers(const std::string& algo_spec); +inline std::vector 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 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 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 get_mac_providers(const std::string& algo_spec); +inline std::unique_ptr make_message_auth(const std::string& algo_spec, + const std::string& provider = "") + { + std::unique_ptr 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 get_mac_providers(const std::string& algo_spec) + { + return MessageAuthenticationCode::providers(algo_spec); + } } 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 +#include + +namespace Botan { + +Transform* get_transform(const std::string& specstr, + const std::string& provider, + const std::string& dirstr) + { + Algo_Registry::Spec spec(specstr, dirstr); + return Algo_Registry::global_registry().make(spec, provider); + } + +} diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp index 616c6df5b..60e6d0db2 100644 --- a/src/lib/block/block_cipher.cpp +++ b/src/lib/block/block_cipher.cpp @@ -151,6 +151,17 @@ namespace Botan { BlockCipher::~BlockCipher() {} +std::unique_ptr BlockCipher::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr(make_a(algo_spec, provider)); + } + +std::vector BlockCipher::providers(const std::string& algo_spec) + { + return providers_of(BlockCipher::Spec(algo_spec)); + } + #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"); diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h index 3f017dc89..cea07ac2d 100644 --- a/src/lib/block/block_cipher.h +++ b/src/lib/block/block_cipher.h @@ -21,6 +21,19 @@ class BOTAN_DLL BlockCipher : 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 providers is empty then best available is chosen. + */ + static std::unique_ptr 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 providers(const std::string& algo_spec); + /** * @return block size of this algorithm */ diff --git a/src/lib/hash/comb4p/comb4p.cpp b/src/lib/hash/comb4p/comb4p.cpp index ec39bbc31..ef5f74a38 100644 --- a/src/lib/hash/comb4p/comb4p.cpp +++ b/src/lib/hash/comb4p/comb4p.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include @@ -39,8 +38,8 @@ Comb4P* Comb4P::make(const Spec& spec) { if(spec.arg_count() == 2) { - std::unique_ptr h1(make_hash_function(spec.arg(0))); - std::unique_ptr h2(make_hash_function(spec.arg(1))); + std::unique_ptr h1(HashFunction::create(spec.arg(0))); + std::unique_ptr h2(HashFunction::create(spec.arg(1))); if(h1 && h2) return new Comb4P(h1.release(), h2.release()); diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp index 723a7eba7..f965cfde8 100644 --- a/src/lib/hash/hash.cpp +++ b/src/lib/hash/hash.cpp @@ -91,6 +91,19 @@ namespace Botan { +std::unique_ptr HashFunction::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr(make_a(algo_spec, provider)); + } + +std::vector HashFunction::providers(const std::string& algo_spec) + { + return providers_of(HashFunction::Spec(algo_spec)); + } + +HashFunction::HashFunction() {} + HashFunction::~HashFunction() {} #if defined(BOTAN_HAS_ADLER32) diff --git a/src/lib/hash/hash.h b/src/lib/hash/hash.h index 8406a4c0f..76c9d5cd7 100644 --- a/src/lib/hash/hash.h +++ b/src/lib/hash/hash.h @@ -22,11 +22,26 @@ 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 providers is empty then best available is chosen. + */ + static std::unique_ptr 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 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; diff --git a/src/lib/hash/par_hash/par_hash.cpp b/src/lib/hash/par_hash/par_hash.cpp index 12271640a..57140f0a8 100644 --- a/src/lib/hash/par_hash/par_hash.cpp +++ b/src/lib/hash/par_hash/par_hash.cpp @@ -17,7 +17,7 @@ Parallel* Parallel::make(const Spec& spec) for(size_t i = 0; i != spec.arg_count(); ++i) { - std::unique_ptr 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/kdf/hkdf/hkdf.cpp b/src/lib/kdf/hkdf/hkdf.cpp index df6e49fad..d4c688afc 100644 --- a/src/lib/kdf/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include namespace Botan { 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 kdf.h - - -kdf_utils.h - diff --git a/src/lib/kdf/kdf.cpp b/src/lib/kdf/kdf.cpp index 836e9b982..3eba8a5cd 100644 --- a/src/lib/kdf/kdf.cpp +++ b/src/lib/kdf/kdf.cpp @@ -6,7 +6,7 @@ */ #include -#include +#include #if defined(BOTAN_HAS_HKDF) #include @@ -32,10 +32,29 @@ #include #endif +#define BOTAN_REGISTER_KDF_NOARGS(type, name) \ + BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T)) +#define BOTAN_REGISTER_KDF_1HASH(type, name) \ + BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T_1X)) + +#define BOTAN_REGISTER_KDF_NAMED_1STR(type, name) \ + BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T_1str_req)) + namespace Botan { KDF::~KDF() {} +std::unique_ptr KDF::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr(make_a(algo_spec, provider)); + } + +std::vector KDF::providers(const std::string& algo_spec) + { + return providers_of(KDF::Spec(algo_spec)); + } + KDF* get_kdf(const std::string& algo_spec) { SCAN_Name request(algo_spec); @@ -43,9 +62,10 @@ KDF* get_kdf(const std::string& algo_spec) if(request.algo_name() == "Raw") return nullptr; // No KDF - if(KDF* kdf = make_a(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) diff --git a/src/lib/kdf/kdf.h b/src/lib/kdf/kdf.h index 936e7c5f1..a8d4650e0 100644 --- a/src/lib/kdf/kdf.h +++ b/src/lib/kdf/kdf.h @@ -23,6 +23,19 @@ class BOTAN_DLL KDF public: virtual ~KDF(); + /** + * Create an instance based on a name + * Will return a null pointer if the algo/provider combination cannot + * be found. If providers is empty then best available is chosen. + */ + static std::unique_ptr 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 providers(const std::string& algo_spec); + virtual std::string name() const = 0; virtual size_t kdf(byte key[], size_t key_len, diff --git a/src/lib/kdf/kdf1/kdf1.cpp b/src/lib/kdf/kdf1/kdf1.cpp index c87bacd27..c7ea3c37e 100644 --- a/src/lib/kdf/kdf1/kdf1.cpp +++ b/src/lib/kdf/kdf1/kdf1.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/kdf/kdf2/kdf2.cpp b/src/lib/kdf/kdf2/kdf2.cpp index 1b1c3638a..df2b7a91c 100644 --- a/src/lib/kdf/kdf2/kdf2.cpp +++ b/src/lib/kdf/kdf2/kdf2.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { 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 -#include -#include -#include - -namespace Botan { - -#define BOTAN_REGISTER_KDF_NOARGS(type, name) \ - BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T)) -#define BOTAN_REGISTER_KDF_1HASH(type, name) \ - BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T_1X)) - -#define BOTAN_REGISTER_KDF_NAMED_1STR(type, name) \ - BOTAN_REGISTER_NAMED_T(KDF, name, type, (make_new_T_1str_req)) - -} - -#endif diff --git a/src/lib/kdf/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp index ef130d5ba..08a2a0899 100644 --- a/src/lib/kdf/prf_tls/prf_tls.cpp +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -5,9 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include +#include +#include namespace Botan { diff --git a/src/lib/kdf/prf_x942/prf_x942.cpp b/src/lib/kdf/prf_x942/prf_x942.cpp index e8f234e49..443e207f2 100644 --- a/src/lib/kdf/prf_x942/prf_x942.cpp +++ b/src/lib/kdf/prf_x942/prf_x942.cpp @@ -5,12 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include #include #include +#include #include namespace Botan { diff --git a/src/lib/mac/cbc_mac/cbc_mac.cpp b/src/lib/mac/cbc_mac/cbc_mac.cpp index 29507f17b..70a7e4116 100644 --- a/src/lib/mac/cbc_mac/cbc_mac.cpp +++ b/src/lib/mac/cbc_mac/cbc_mac.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace Botan { diff --git a/src/lib/mac/cmac/cmac.cpp b/src/lib/mac/cmac/cmac.cpp index 85c19c19f..f3f6c6296 100644 --- a/src/lib/mac/cmac/cmac.cpp +++ b/src/lib/mac/cmac/cmac.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace Botan { diff --git a/src/lib/mac/hmac/hmac.cpp b/src/lib/mac/hmac/hmac.cpp index 2cd512746..94f455c56 100644 --- a/src/lib/mac/hmac/hmac.cpp +++ b/src/lib/mac/hmac/hmac.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace Botan { diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp index af59bd4c6..da94a1daf 100644 --- a/src/lib/mac/mac.cpp +++ b/src/lib/mac/mac.cpp @@ -35,6 +35,17 @@ namespace Botan { +std::unique_ptr MessageAuthenticationCode::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr(make_a(algo_spec, provider)); + } + +std::vector MessageAuthenticationCode::providers(const std::string& algo_spec) + { + return providers_of(MessageAuthenticationCode::Spec(algo_spec)); + } + MessageAuthenticationCode::~MessageAuthenticationCode() {} /* diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h index 28894bbcd..6f18fce19 100644 --- a/src/lib/mac/mac.h +++ b/src/lib/mac/mac.h @@ -24,6 +24,19 @@ class BOTAN_DLL MessageAuthenticationCode : 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 providers is empty then best available is chosen. + */ + static std::unique_ptr 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 providers(const std::string& algo_spec); + virtual ~MessageAuthenticationCode(); /** diff --git a/src/lib/mac/x919_mac/x919_mac.cpp b/src/lib/mac/x919_mac/x919_mac.cpp index ce7c38ebb..a58b07248 100644 --- a/src/lib/mac/x919_mac/x919_mac.cpp +++ b/src/lib/mac/x919_mac/x919_mac.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace Botan { diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp index c101480b4..600e0eb18 100644 --- a/src/lib/modes/aead/aead.cpp +++ b/src/lib/modes/aead/aead.cpp @@ -6,6 +6,7 @@ #include #include +#include #if defined(BOTAN_HAS_AEAD_CCM) #include diff --git a/src/lib/modes/mode_utils.h b/src/lib/modes/mode_utils.h index 53aa41745..d8c185f7a 100644 --- a/src/lib/modes/mode_utils.h +++ b/src/lib/modes/mode_utils.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/src/lib/pbkdf/pbkdf.cpp b/src/lib/pbkdf/pbkdf.cpp index f11fbc44d..6d7a6542f 100644 --- a/src/lib/pbkdf/pbkdf.cpp +++ b/src/lib/pbkdf/pbkdf.cpp @@ -30,6 +30,19 @@ BOTAN_REGISTER_PBKDF_1HASH(PKCS5_PBKDF1, "PBKDF1"); BOTAN_REGISTER_NAMED_T(PBKDF, "PBKDF2", PKCS5_PBKDF2, PKCS5_PBKDF2::make); #endif +PBKDF::~PBKDF() {} + +std::unique_ptr PBKDF::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr(make_a(algo_spec, provider)); + } + +std::vector PBKDF::providers(const std::string& algo_spec) + { + return providers_of(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..1a1299c75 100644 --- a/src/lib/pbkdf/pbkdf.h +++ b/src/lib/pbkdf/pbkdf.h @@ -10,6 +10,8 @@ #include #include +#include +#include #include 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 providers is empty then best available is chosen. + */ + static std::unique_ptr 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 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 p(PBKDF::create(algo_spec, provider)); + if(p) + return p.release(); + throw Algorithm_Not_Found(algo_spec); + } + } #endif diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp index d928511d3..ecb7a6f29 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace Botan { diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index d025a03d3..e6d4b9d3e 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace Botan { diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index 73ffef980..1979c676f 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace Botan { diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp index 2f1538914..3b8d35bc7 100644 --- a/src/lib/stream/stream_cipher.cpp +++ b/src/lib/stream/stream_cipher.cpp @@ -30,6 +30,18 @@ namespace Botan { +std::unique_ptr StreamCipher::create(const std::string& algo_spec, + const std::string& provider) + { + return std::unique_ptr(make_a(algo_spec, provider)); + } + +std::vector StreamCipher::providers(const std::string& algo_spec) + { + return providers_of(StreamCipher::Spec(algo_spec)); + } + +StreamCipher::StreamCipher() {} StreamCipher::~StreamCipher() {} void StreamCipher::set_iv(const byte[], size_t iv_len) diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h index 5500bca49..68c97f1c1 100644 --- a/src/lib/stream/stream_cipher.h +++ b/src/lib/stream/stream_cipher.h @@ -22,6 +22,19 @@ 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 providers is empty then best available is chosen. + */ + static std::unique_ptr 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 providers(const std::string& algo_spec); + /** * Encrypt or decrypt a message * @param in the plaintext @@ -68,6 +81,7 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm */ virtual StreamCipher* clone() const = 0; + StreamCipher(); virtual ~StreamCipher(); }; -- cgit v1.2.3 From e1ae1d68309573134fc1242c3bfb8a8ce0672737 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 19 Sep 2015 07:43:45 -0400 Subject: Internal header cleanups Only user-visible change is the removal of get_byte.h --- src/lib/asn1/ber_dec.cpp | 2 +- src/lib/asn1/der_enc.cpp | 2 +- src/lib/base/buf_comp.h | 2 +- src/lib/base/symkey.cpp | 1 - src/lib/block/block_cipher.cpp | 17 +++- src/lib/block/block_utils.h | 33 -------- src/lib/block/des/desx.cpp | 1 - src/lib/block/info.txt | 4 - src/lib/block/lion/lion.cpp | 1 - src/lib/hash/checksum/adler32/adler32.cpp | 2 +- src/lib/hash/checksum/crc24/crc24.cpp | 3 +- src/lib/hash/checksum/crc32/crc32.cpp | 2 +- src/lib/hash/comb4p/comb4p.cpp | 1 - src/lib/hash/gost_3411/gost_3411.cpp | 2 - src/lib/hash/has160/has160.cpp | 1 - src/lib/hash/hash.cpp | 15 +++- src/lib/hash/hash_utils.h | 33 -------- src/lib/hash/info.txt | 4 - src/lib/hash/keccak/keccak.cpp | 2 - src/lib/hash/md2/md2.cpp | 2 - src/lib/hash/md4/md4.cpp | 1 - src/lib/hash/md5/md5.cpp | 1 - src/lib/hash/par_hash/par_hash.cpp | 1 - src/lib/hash/rmd128/rmd128.cpp | 1 - src/lib/hash/rmd160/rmd160.cpp | 1 - src/lib/hash/sha1/sha160.cpp | 1 - src/lib/hash/sha1_sse2/sha1_sse2.cpp | 1 - src/lib/hash/sha2_32/sha2_32.cpp | 1 - src/lib/hash/sha2_64/sha2_64.cpp | 1 - src/lib/hash/skein/skein_512.cpp | 2 - src/lib/hash/tiger/tiger.cpp | 1 - src/lib/hash/whirlpool/whirlpool.cpp | 1 - src/lib/kdf/prf_tls/prf_tls.cpp | 1 - src/lib/mac/cbc_mac/cbc_mac.cpp | 1 - src/lib/mac/cmac/cmac.cpp | 1 - src/lib/mac/hmac/hmac.cpp | 1 - src/lib/mac/info.txt | 4 - src/lib/mac/mac.cpp | 7 +- src/lib/mac/mac_utils.h | 35 -------- src/lib/mac/poly1305/poly1305.cpp | 1 - src/lib/mac/siphash/siphash.cpp | 1 - src/lib/mac/x919_mac/x919_mac.cpp | 1 - src/lib/math/bigint/bigint.cpp | 2 +- src/lib/math/bigint/bigint.h | 2 +- src/lib/misc/aont/package.cpp | 3 +- src/lib/misc/cryptobox/cryptobox.cpp | 2 +- src/lib/misc/rfc3394/rfc3394.cpp | 1 - src/lib/modes/mode_utils.h | 1 - src/lib/pbkdf/pbkdf2/pbkdf2.cpp | 3 +- src/lib/pk_pad/eme.cpp | 8 +- src/lib/pk_pad/emsa.cpp | 11 ++- src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp | 1 - src/lib/pk_pad/emsa_raw/emsa_raw.cpp | 1 - src/lib/pk_pad/info.txt | 4 - src/lib/pk_pad/mgf1/mgf1.cpp | 1 - src/lib/pk_pad/pad_utils.h | 41 ---------- src/lib/pubkey/dlies/dlies.cpp | 1 - src/lib/pubkey/mce/binary_matrix.cpp | 1 - src/lib/pubkey/mce/mceliece.cpp | 1 - src/lib/rng/hmac_rng/hmac_rng.cpp | 2 - src/lib/rng/x931_rng/x931_rng.cpp | 1 - src/lib/stream/chacha/chacha.cpp | 2 +- src/lib/stream/ctr/ctr.cpp | 1 - src/lib/stream/info.txt | 4 - src/lib/stream/ofb/ofb.cpp | 1 - src/lib/stream/rc4/rc4.cpp | 1 - src/lib/stream/salsa20/salsa20.cpp | 2 +- src/lib/stream/stream_cipher.cpp | 6 +- src/lib/stream/stream_utils.h | 31 -------- src/lib/tls/tls_record.cpp | 1 - src/lib/tls/tls_version.h | 2 +- src/lib/utils/cpuid.cpp | 2 +- src/lib/utils/get_byte.h | 12 --- src/lib/utils/info.txt | 4 +- src/lib/utils/loadstor.h | 14 +++- src/lib/utils/mem_ops.h | 127 ++++++++++++++++++++++++++++++ src/lib/utils/parsing.cpp | 2 +- src/lib/vendor/openssl/openssl_block.cpp | 4 +- src/lib/vendor/openssl/openssl_hash.cpp | 1 - src/lib/vendor/openssl/openssl_rc4.cpp | 2 +- 80 files changed, 213 insertions(+), 289 deletions(-) delete mode 100644 src/lib/block/block_utils.h delete mode 100644 src/lib/hash/hash_utils.h delete mode 100644 src/lib/mac/mac_utils.h delete mode 100644 src/lib/pk_pad/pad_utils.h delete mode 100644 src/lib/stream/stream_utils.h (limited to 'src/lib') 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 #include -#include +#include 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 #include #include -#include +#include #include #include #include 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 -#include +#include #include namespace Botan { 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 -#include #include #include #include diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp index 60e6d0db2..e4d6c5817 100644 --- a/src/lib/block/block_cipher.cpp +++ b/src/lib/block/block_cipher.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #if defined(BOTAN_HAS_SIMD_32) #include @@ -162,6 +162,21 @@ std::vector BlockCipher::providers(const std::string& algo_spec) return providers_of(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) +#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1LEN(type, name, def) \ + BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, (make_new_T_1len)) +#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(type, name, def) \ + BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, std::bind(make_new_T_1str, 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"); diff --git a/src/lib/block/block_utils.h b/src/lib/block/block_utils.h deleted file mode 100644 index c1eee27b1..000000000 --- a/src/lib/block/block_utils.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Internal Block Cipher Utility Header -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_INTERNAL_BLOCK_CIPHER_UTILS_H__ -#define BOTAN_INTERNAL_BLOCK_CIPHER_UTILS_H__ - -#include -#include - -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) -#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, (make_new_T_1len)) -#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(type, name, def) \ - BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, std::bind(make_new_T_1str, 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/des/desx.cpp b/src/lib/block/des/desx.cpp index 4ab568638..f6538748c 100644 --- a/src/lib/block/des/desx.cpp +++ b/src/lib/block/des/desx.cpp @@ -6,7 +6,6 @@ */ #include -#include namespace Botan { 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 block_cipher.h - - -block_utils.h - diff --git a/src/lib/block/lion/lion.cpp b/src/lib/block/lion/lion.cpp index 336828d89..bbd24a3c1 100644 --- a/src/lib/block/lion/lion.cpp +++ b/src/lib/block/lion/lion.cpp @@ -8,7 +8,6 @@ #include #include #include -#include namespace Botan { diff --git a/src/lib/hash/checksum/adler32/adler32.cpp b/src/lib/hash/checksum/adler32/adler32.cpp index aadc5d39f..f368b627c 100644 --- a/src/lib/hash/checksum/adler32/adler32.cpp +++ b/src/lib/hash/checksum/adler32/adler32.cpp @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include namespace Botan { diff --git a/src/lib/hash/checksum/crc24/crc24.cpp b/src/lib/hash/checksum/crc24/crc24.cpp index 054d23684..1484f643d 100644 --- a/src/lib/hash/checksum/crc24/crc24.cpp +++ b/src/lib/hash/checksum/crc24/crc24.cpp @@ -5,9 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include -#include +#include namespace Botan { diff --git a/src/lib/hash/checksum/crc32/crc32.cpp b/src/lib/hash/checksum/crc32/crc32.cpp index ca9514c26..10d989cc6 100644 --- a/src/lib/hash/checksum/crc32/crc32.cpp +++ b/src/lib/hash/checksum/crc32/crc32.cpp @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include namespace Botan { diff --git a/src/lib/hash/comb4p/comb4p.cpp b/src/lib/hash/comb4p/comb4p.cpp index ef5f74a38..4222eaf54 100644 --- a/src/lib/hash/comb4p/comb4p.cpp +++ b/src/lib/hash/comb4p/comb4p.cpp @@ -6,7 +6,6 @@ */ #include -#include #include namespace Botan { diff --git a/src/lib/hash/gost_3411/gost_3411.cpp b/src/lib/hash/gost_3411/gost_3411.cpp index fb1c39384..f8c9c0069 100644 --- a/src/lib/hash/gost_3411/gost_3411.cpp +++ b/src/lib/hash/gost_3411/gost_3411.cpp @@ -5,9 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include -#include namespace Botan { diff --git a/src/lib/hash/has160/has160.cpp b/src/lib/hash/has160/has160.cpp index dd4bc1428..6b12e10ad 100644 --- a/src/lib/hash/has160/has160.cpp +++ b/src/lib/hash/has160/has160.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp index f965cfde8..fe210705e 100644 --- a/src/lib/hash/hash.cpp +++ b/src/lib/hash/hash.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #if defined(BOTAN_HAS_ADLER32) #include @@ -106,6 +106,19 @@ 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) +#define BOTAN_REGISTER_HASH_NAMED_1LEN(type, name, def) \ + BOTAN_REGISTER_NAMED_T(HashFunction, name, type, (make_new_T_1len)) + +#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 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 -#include -#include -#include - -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) -#define BOTAN_REGISTER_HASH_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(HashFunction, name, type, (make_new_T_1len)) - -#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 @@ - -hash_utils.h - - hash.h diff --git a/src/lib/hash/keccak/keccak.cpp b/src/lib/hash/keccak/keccak.cpp index 3cebe42da..39d0c822b 100644 --- a/src/lib/hash/keccak/keccak.cpp +++ b/src/lib/hash/keccak/keccak.cpp @@ -5,11 +5,9 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include -#include namespace Botan { diff --git a/src/lib/hash/md2/md2.cpp b/src/lib/hash/md2/md2.cpp index 8b8810941..8fe016962 100644 --- a/src/lib/hash/md2/md2.cpp +++ b/src/lib/hash/md2/md2.cpp @@ -5,9 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include -#include namespace Botan { diff --git a/src/lib/hash/md4/md4.cpp b/src/lib/hash/md4/md4.cpp index f8cbb2b6b..6f4503ac0 100644 --- a/src/lib/hash/md4/md4.cpp +++ b/src/lib/hash/md4/md4.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/hash/md5/md5.cpp b/src/lib/hash/md5/md5.cpp index 61d8aa980..89ca52419 100644 --- a/src/lib/hash/md5/md5.cpp +++ b/src/lib/hash/md5/md5.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/hash/par_hash/par_hash.cpp b/src/lib/hash/par_hash/par_hash.cpp index 57140f0a8..5e970ab13 100644 --- a/src/lib/hash/par_hash/par_hash.cpp +++ b/src/lib/hash/par_hash/par_hash.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include diff --git a/src/lib/hash/rmd128/rmd128.cpp b/src/lib/hash/rmd128/rmd128.cpp index 1f655199e..394bf2acf 100644 --- a/src/lib/hash/rmd128/rmd128.cpp +++ b/src/lib/hash/rmd128/rmd128.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/hash/rmd160/rmd160.cpp b/src/lib/hash/rmd160/rmd160.cpp index c1b1032ae..56d063338 100644 --- a/src/lib/hash/rmd160/rmd160.cpp +++ b/src/lib/hash/rmd160/rmd160.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/hash/sha1/sha160.cpp b/src/lib/hash/sha1/sha160.cpp index 04227c6bb..39d14f486 100644 --- a/src/lib/hash/sha1/sha160.cpp +++ b/src/lib/hash/sha1/sha160.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/hash/sha1_sse2/sha1_sse2.cpp b/src/lib/hash/sha1_sse2/sha1_sse2.cpp index fefea52af..2e0688185 100644 --- a/src/lib/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/lib/hash/sha1_sse2/sha1_sse2.cpp @@ -7,7 +7,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include diff --git a/src/lib/hash/sha2_32/sha2_32.cpp b/src/lib/hash/sha2_32/sha2_32.cpp index a867e6dd0..5215164cf 100644 --- a/src/lib/hash/sha2_32/sha2_32.cpp +++ b/src/lib/hash/sha2_32/sha2_32.cpp @@ -6,7 +6,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/hash/sha2_64/sha2_64.cpp b/src/lib/hash/sha2_64/sha2_64.cpp index 98d16900b..d7c3f1325 100644 --- a/src/lib/hash/sha2_64/sha2_64.cpp +++ b/src/lib/hash/sha2_64/sha2_64.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/hash/skein/skein_512.cpp b/src/lib/hash/skein/skein_512.cpp index ce0e8353d..fe95dd7a5 100644 --- a/src/lib/hash/skein/skein_512.cpp +++ b/src/lib/hash/skein/skein_512.cpp @@ -5,11 +5,9 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include -#include #include namespace Botan { diff --git a/src/lib/hash/tiger/tiger.cpp b/src/lib/hash/tiger/tiger.cpp index d724c3da8..79708a902 100644 --- a/src/lib/hash/tiger/tiger.cpp +++ b/src/lib/hash/tiger/tiger.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include diff --git a/src/lib/hash/whirlpool/whirlpool.cpp b/src/lib/hash/whirlpool/whirlpool.cpp index edcc31d26..9bebdfa7c 100644 --- a/src/lib/hash/whirlpool/whirlpool.cpp +++ b/src/lib/hash/whirlpool/whirlpool.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/kdf/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp index 08a2a0899..382f527ea 100644 --- a/src/lib/kdf/prf_tls/prf_tls.cpp +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -8,7 +8,6 @@ #include #include #include -#include namespace Botan { diff --git a/src/lib/mac/cbc_mac/cbc_mac.cpp b/src/lib/mac/cbc_mac/cbc_mac.cpp index 70a7e4116..8133b9a6f 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 #include #include diff --git a/src/lib/mac/cmac/cmac.cpp b/src/lib/mac/cmac/cmac.cpp index f3f6c6296..0e42e3823 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 #include #include diff --git a/src/lib/mac/hmac/hmac.cpp b/src/lib/mac/hmac/hmac.cpp index 94f455c56..40da31887 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 #include #include 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 mac.h - - -mac_utils.h - diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp index da94a1daf..8c1185c55 100644 --- a/src/lib/mac/mac.cpp +++ b/src/lib/mac/mac.cpp @@ -6,7 +6,7 @@ */ #include -#include +#include #include #if defined(BOTAN_HAS_CBC_MAC) @@ -61,7 +61,6 @@ 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 @@ -75,7 +74,7 @@ BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "HMAC", HMAC, HMAC::make); #endif #if defined(BOTAN_HAS_POLY1305) -BOTAN_REGISTER_MAC_NOARGS(Poly1305); +BOTAN_REGISTER_T_NOARGS(MessageAuthenticationCode, Poly1305); #endif #if defined(BOTAN_HAS_SIPHASH) @@ -83,7 +82,7 @@ BOTAN_REGISTER_NAMED_T_2LEN(MessageAuthenticationCode, SipHash, "SipHash", "base #endif #if defined(BOTAN_HAS_ANSI_X919_MAC) -BOTAN_REGISTER_MAC_NAMED_NOARGS(ANSI_X919_MAC, "X9.19-MAC"); +BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "X9.19-MAC", ANSI_X919_MAC, make_new_T); #endif } 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 -#include -#include -#include -#include - -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) - -#define BOTAN_REGISTER_MAC_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, name, type, (make_new_T_1len)) -#define BOTAN_REGISTER_MAC_NAMED_1STR(type, name, def) \ - BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, name, type, \ - std::bind(make_new_T_1str, std::placeholders::_1, def)); - -} - -#endif diff --git a/src/lib/mac/poly1305/poly1305.cpp b/src/lib/mac/poly1305/poly1305.cpp index 1a072c6b4..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 #include #include #include diff --git a/src/lib/mac/siphash/siphash.cpp b/src/lib/mac/siphash/siphash.cpp index 689d03c13..4a9ffe8ea 100644 --- a/src/lib/mac/siphash/siphash.cpp +++ b/src/lib/mac/siphash/siphash.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/mac/x919_mac/x919_mac.cpp b/src/lib/mac/x919_mac/x919_mac.cpp index a58b07248..2e1fa374f 100644 --- a/src/lib/mac/x919_mac/x919_mac.cpp +++ b/src/lib/mac/x919_mac/x919_mac.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include 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 #include -#include +#include #include #include #include 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 #include #include -#include +#include #include namespace Botan { 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 #include #include -#include -#include +#include namespace Botan { diff --git a/src/lib/misc/cryptobox/cryptobox.cpp b/src/lib/misc/cryptobox/cryptobox.cpp index d7e7bb72b..752561248 100644 --- a/src/lib/misc/cryptobox/cryptobox.cpp +++ b/src/lib/misc/cryptobox/cryptobox.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include namespace Botan { diff --git a/src/lib/misc/rfc3394/rfc3394.cpp b/src/lib/misc/rfc3394/rfc3394.cpp index a199cc599..3e1ed8b40 100644 --- a/src/lib/misc/rfc3394/rfc3394.cpp +++ b/src/lib/misc/rfc3394/rfc3394.cpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace Botan { diff --git a/src/lib/modes/mode_utils.h b/src/lib/modes/mode_utils.h index d8c185f7a..b93884206 100644 --- a/src/lib/modes/mode_utils.h +++ b/src/lib/modes/mode_utils.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp index a5b7f011e..480b43d4b 100644 --- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp +++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -7,8 +7,7 @@ #include #include -#include -#include +#include #include namespace Botan { diff --git a/src/lib/pk_pad/eme.cpp b/src/lib/pk_pad/eme.cpp index 153ef8922..4804a8a81 100644 --- a/src/lib/pk_pad/eme.cpp +++ b/src/lib/pk_pad/eme.cpp @@ -6,7 +6,7 @@ */ #include -#include +#include #if defined(BOTAN_HAS_EME_OAEP) #include @@ -22,6 +22,12 @@ 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) + #if defined(BOTAN_HAS_EME_OAEP) BOTAN_REGISTER_NAMED_T(EME, "OAEP", OAEP, OAEP::make); #endif diff --git a/src/lib/pk_pad/emsa.cpp b/src/lib/pk_pad/emsa.cpp index 9682d9b6e..e20286a7d 100644 --- a/src/lib/pk_pad/emsa.cpp +++ b/src/lib/pk_pad/emsa.cpp @@ -5,7 +5,7 @@ */ #include -#include +#include #if defined(BOTAN_HAS_EMSA1) #include @@ -45,6 +45,15 @@ EMSA* get_emsa(const std::string& algo_spec) throw Algorithm_Not_Found(algo_spec); } +#define BOTAN_REGISTER_EMSA_NAMED_NOARGS(type, name) \ + BOTAN_REGISTER_NAMED_T(EMSA, name, type, make_new_T) + +#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)) + #if defined(BOTAN_HAS_EMSA1) BOTAN_REGISTER_EMSA_1HASH(EMSA1, "EMSA1"); #endif diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp index ecb7a6f29..5e8462d4f 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include #include diff --git a/src/lib/pk_pad/emsa_raw/emsa_raw.cpp b/src/lib/pk_pad/emsa_raw/emsa_raw.cpp index 287acb233..4560bd3c3 100644 --- a/src/lib/pk_pad/emsa_raw/emsa_raw.cpp +++ b/src/lib/pk_pad/emsa_raw/emsa_raw.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/pk_pad/info.txt b/src/lib/pk_pad/info.txt index cc3a3fb3b..8cb935faa 100644 --- a/src/lib/pk_pad/info.txt +++ b/src/lib/pk_pad/info.txt @@ -10,7 +10,3 @@ rng eme.h emsa.h - - -pad_utils.h - 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 #include -#include #include 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 ba2de65ea..000000000 --- a/src/lib/pk_pad/pad_utils.h +++ /dev/null @@ -1,41 +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 - -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) - -#define BOTAN_REGISTER_EMSA_1HASH_1LEN(type, name) \ - BOTAN_REGISTER_NAMED_T(EMSA, name, type, (make_new_T_1X_1len)) - -#define BOTAN_REGISTER_EME_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(EME, name, type, (make_new_T_1len)) -#define BOTAN_REGISTER_EME_NAMED_1STR(type, name, def) \ - BOTAN_REGISTER_NAMED_T(EME, name, type, \ - std::bind(make_new_T_1str, std::placeholders::_1, def)); - -#define BOTAN_REGISTER_EMSA_NAMED_NOARGS(type, name) \ - BOTAN_REGISTER_NAMED_T(EMSA, name, type, make_new_T) - -#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)) - -} - -#endif 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 -#include namespace Botan { diff --git a/src/lib/pubkey/mce/binary_matrix.cpp b/src/lib/pubkey/mce/binary_matrix.cpp index 12c842669..45c9aab13 100644 --- a/src/lib/pubkey/mce/binary_matrix.cpp +++ b/src/lib/pubkey/mce/binary_matrix.cpp @@ -10,7 +10,6 @@ */ #include -#include namespace Botan { diff --git a/src/lib/pubkey/mce/mceliece.cpp b/src/lib/pubkey/mce/mceliece.cpp index 6bbe93ce3..08b3f13a3 100644 --- a/src/lib/pubkey/mce/mceliece.cpp +++ b/src/lib/pubkey/mce/mceliece.cpp @@ -16,7 +16,6 @@ #include #include #include -#include namespace Botan { 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 -#include #include -#include #include #include 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 -#include #include namespace Botan { diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp index 9aa3c2a73..0a32c720b 100644 --- a/src/lib/stream/chacha/chacha.cpp +++ b/src/lib/stream/chacha/chacha.cpp @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include namespace Botan { diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index e6d4b9d3e..3b573448b 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include 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 stream_cipher.h - - -stream_utils.h - diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index 1979c676f..1e6615fc0 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include diff --git a/src/lib/stream/rc4/rc4.cpp b/src/lib/stream/rc4/rc4.cpp index 31fd2cca0..6146e2818 100644 --- a/src/lib/stream/rc4/rc4.cpp +++ b/src/lib/stream/rc4/rc4.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include namespace Botan { diff --git a/src/lib/stream/salsa20/salsa20.cpp b/src/lib/stream/salsa20/salsa20.cpp index 141d9e51e..1d3fe3d28 100644 --- a/src/lib/stream/salsa20/salsa20.cpp +++ b/src/lib/stream/salsa20/salsa20.cpp @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include namespace Botan { diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp index 3b8d35bc7..91b68b38a 100644 --- a/src/lib/stream/stream_cipher.cpp +++ b/src/lib/stream/stream_cipher.cpp @@ -6,7 +6,7 @@ */ #include -#include +#include #if defined(BOTAN_HAS_CHACHA) #include @@ -51,11 +51,11 @@ void StreamCipher::set_iv(const byte[], size_t iv_len) } #if defined(BOTAN_HAS_CHACHA) -BOTAN_REGISTER_STREAM_CIPHER_NOARGS(ChaCha); +BOTAN_REGISTER_T_NOARGS(StreamCipher, ChaCha); #endif #if defined(BOTAN_HAS_SALSA20) -BOTAN_REGISTER_STREAM_CIPHER_NOARGS(Salsa20); +BOTAN_REGISTER_T_NOARGS(StreamCipher, Salsa20); #endif #if defined(BOTAN_HAS_CTR_BE) 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 -#include -#include -#include -#include -#include - -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) -#define BOTAN_REGISTER_STREAM_CIPHER_NAMED_1LEN(type, name, def) \ - BOTAN_REGISTER_NAMED_T(StreamCipher, name, type, (make_new_T_1len)) - -} - -#endif diff --git a/src/lib/tls/tls_record.cpp b/src/lib/tls/tls_record.cpp index 3ba02f039..53521c5da 100644 --- a/src/lib/tls/tls_record.cpp +++ b/src/lib/tls/tls_record.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include 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 +#include #include namespace Botan { diff --git a/src/lib/utils/cpuid.cpp b/src/lib/utils/cpuid.cpp index 817bf4f52..218b6553c 100644 --- a/src/lib/utils/cpuid.cpp +++ b/src/lib/utils/cpuid.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include 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 inline byte get_byte(size_t byte_num, T input) - { - return static_cast( - 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..7d3216b1c 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 @@ -10,7 +10,6 @@ charset.h cpuid.h database.h exceptn.h -get_byte.h loadstor.h mem_ops.h mul128.h @@ -29,5 +28,4 @@ rounding.h semaphore.h stl_util.h ta_utils.h -xor_buf.h 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 #include -#include #include #include @@ -39,6 +38,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 inline byte get_byte(size_t byte_num, T input) + { + return static_cast( + input >> ((sizeof(T)-1-(byte_num&(sizeof(T)-1))) << 3) + ); + } + /** * Make a u16bit from two bytes * @param i0 the first byte 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 #include +#include namespace Botan { @@ -70,6 +71,132 @@ template 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 +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 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 out[], const byte in[], size_t length) + { + while(length >= 8) + { + *reinterpret_cast(out) ^= *reinterpret_cast(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 out[], + const byte in[], + const byte in2[], + size_t length) + { + while(length >= 8) + { + *reinterpret_cast(out) = + *reinterpret_cast(in) ^ + *reinterpret_cast(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 +void xor_buf(std::vector& out, + const std::vector& in, + size_t n) + { + xor_buf(out.data(), in.data(), n); + } + +template +void xor_buf(std::vector& out, + const byte* in, + size_t n) + { + xor_buf(out.data(), in, n); + } + +template +void xor_buf(std::vector& out, + const byte* in, + const std::vector& in2, + size_t n) + { + xor_buf(out.data(), in, in2.data(), n); + } + +template +std::vector& +operator^=(std::vector& out, + const std::vector& 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/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 #include #include -#include +#include #include #include #include diff --git a/src/lib/vendor/openssl/openssl_block.cpp b/src/lib/vendor/openssl/openssl_block.cpp index b74f184c7..701317ed8 100644 --- a/src/lib/vendor/openssl/openssl_block.cpp +++ b/src/lib/vendor/openssl/openssl_block.cpp @@ -1,11 +1,11 @@ /* -* 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 +#include #include #include diff --git a/src/lib/vendor/openssl/openssl_hash.cpp b/src/lib/vendor/openssl/openssl_hash.cpp index 6e055c0e6..f517ae6af 100644 --- a/src/lib/vendor/openssl/openssl_hash.cpp +++ b/src/lib/vendor/openssl/openssl_hash.cpp @@ -5,7 +5,6 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include #include diff --git a/src/lib/vendor/openssl/openssl_rc4.cpp b/src/lib/vendor/openssl/openssl_rc4.cpp index ac30cd288..5156ff6cc 100644 --- a/src/lib/vendor/openssl/openssl_rc4.cpp +++ b/src/lib/vendor/openssl/openssl_rc4.cpp @@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include +#include #include #include #include -- cgit v1.2.3 From e94e615e528e73f2a9354291d844514b4e1c0636 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 19 Sep 2015 10:38:24 -0400 Subject: Fix includes for openssl --- src/lib/vendor/openssl/openssl_block.cpp | 1 + src/lib/vendor/openssl/openssl_hash.cpp | 2 ++ src/lib/vendor/openssl/openssl_rc4.cpp | 1 + 3 files changed, 4 insertions(+) (limited to 'src/lib') diff --git a/src/lib/vendor/openssl/openssl_block.cpp b/src/lib/vendor/openssl/openssl_block.cpp index 701317ed8..5c28f46b1 100644 --- a/src/lib/vendor/openssl/openssl_block.cpp +++ b/src/lib/vendor/openssl/openssl_block.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include diff --git a/src/lib/vendor/openssl/openssl_hash.cpp b/src/lib/vendor/openssl/openssl_hash.cpp index f517ae6af..c89dd777d 100644 --- a/src/lib/vendor/openssl/openssl_hash.cpp +++ b/src/lib/vendor/openssl/openssl_hash.cpp @@ -5,7 +5,9 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include #include +#include #include namespace Botan { diff --git a/src/lib/vendor/openssl/openssl_rc4.cpp b/src/lib/vendor/openssl/openssl_rc4.cpp index 5156ff6cc..1f5675095 100644 --- a/src/lib/vendor/openssl/openssl_rc4.cpp +++ b/src/lib/vendor/openssl/openssl_rc4.cpp @@ -5,6 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include #include #include #include -- cgit v1.2.3 From 408ea0a9b8ed0f575f8ee26891473920b42ef026 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 21 Sep 2015 12:24:08 -0400 Subject: Address some review comments by Simon. GH #279 --- src/lib/block/block_cipher.cpp | 2 +- src/lib/block/block_cipher.h | 2 +- src/lib/hash/hash.h | 2 +- src/lib/kdf/kdf.h | 2 +- src/lib/mac/mac.h | 2 +- src/lib/modes/aead/aead.cpp | 12 ++++++------ src/lib/modes/cipher_mode.cpp | 8 ++++---- src/lib/pbkdf/pbkdf.h | 2 +- src/lib/stream/stream_cipher.cpp | 10 +++++----- src/lib/stream/stream_cipher.h | 2 +- 10 files changed, 22 insertions(+), 22 deletions(-) (limited to 'src/lib') diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp index e4d6c5817..5b9c4f0ba 100644 --- a/src/lib/block/block_cipher.cpp +++ b/src/lib/block/block_cipher.cpp @@ -10,7 +10,7 @@ #include #if defined(BOTAN_HAS_SIMD_32) -#include + #include #endif #if defined(BOTAN_HAS_AES) diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h index cea07ac2d..0f4c2c1c5 100644 --- a/src/lib/block/block_cipher.h +++ b/src/lib/block/block_cipher.h @@ -24,7 +24,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm /** * Create an instance based on a name * Will return a null pointer if the algo/provider combination cannot - * be found. If providers is empty then best available is chosen. + * be found. If provider is empty then best available is chosen. */ static std::unique_ptr create(const std::string& algo_spec, const std::string& provider = ""); diff --git a/src/lib/hash/hash.h b/src/lib/hash/hash.h index 76c9d5cd7..ac1c22a65 100644 --- a/src/lib/hash/hash.h +++ b/src/lib/hash/hash.h @@ -25,7 +25,7 @@ class BOTAN_DLL HashFunction : public Buffered_Computation /** * Create an instance based on a name * Will return a null pointer if the algo/provider combination cannot - * be found. If providers is empty then best available is chosen. + * be found. If provider is empty then best available is chosen. */ static std::unique_ptr create(const std::string& algo_spec, const std::string& provider = ""); diff --git a/src/lib/kdf/kdf.h b/src/lib/kdf/kdf.h index a8d4650e0..88b50c8b8 100644 --- a/src/lib/kdf/kdf.h +++ b/src/lib/kdf/kdf.h @@ -26,7 +26,7 @@ class BOTAN_DLL KDF /** * Create an instance based on a name * Will return a null pointer if the algo/provider combination cannot - * be found. If providers is empty then best available is chosen. + * be found. If provider is empty then best available is chosen. */ static std::unique_ptr create(const std::string& algo_spec, const std::string& provider = ""); diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h index 6f18fce19..90ef4db15 100644 --- a/src/lib/mac/mac.h +++ b/src/lib/mac/mac.h @@ -27,7 +27,7 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, /** * Create an instance based on a name * Will return a null pointer if the algo/provider combination cannot - * be found. If providers is empty then best available is chosen. + * be found. If provider is empty then best available is chosen. */ static std::unique_ptr create(const std::string& algo_spec, const std::string& provider = ""); diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp index 600e0eb18..1e66dbd43 100644 --- a/src/lib/modes/aead/aead.cpp +++ b/src/lib/modes/aead/aead.cpp @@ -9,27 +9,27 @@ #include #if defined(BOTAN_HAS_AEAD_CCM) -#include + #include #endif #if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305) -#include + #include #endif #if defined(BOTAN_HAS_AEAD_EAX) -#include + #include #endif #if defined(BOTAN_HAS_AEAD_GCM) -#include + #include #endif #if defined(BOTAN_HAS_AEAD_OCB) -#include + #include #endif #if defined(BOTAN_HAS_AEAD_SIV) -#include + #include #endif namespace Botan { diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp index 98e2218dc..262c41434 100644 --- a/src/lib/modes/cipher_mode.cpp +++ b/src/lib/modes/cipher_mode.cpp @@ -12,19 +12,19 @@ #include #if defined(BOTAN_HAS_MODE_ECB) -#include + #include #endif #if defined(BOTAN_HAS_MODE_CBC) -#include + #include #endif #if defined(BOTAN_HAS_MODE_CFB) -#include + #include #endif #if defined(BOTAN_HAS_MODE_XTS) -#include + #include #endif namespace Botan { diff --git a/src/lib/pbkdf/pbkdf.h b/src/lib/pbkdf/pbkdf.h index 1a1299c75..495da0ac9 100644 --- a/src/lib/pbkdf/pbkdf.h +++ b/src/lib/pbkdf/pbkdf.h @@ -27,7 +27,7 @@ class BOTAN_DLL PBKDF /** * Create an instance based on a name * Will return a null pointer if the algo/provider combination cannot - * be found. If providers is empty then best available is chosen. + * be found. If provider is empty then best available is chosen. */ static std::unique_ptr create(const std::string& algo_spec, const std::string& provider = ""); diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp index 91b68b38a..060e65d86 100644 --- a/src/lib/stream/stream_cipher.cpp +++ b/src/lib/stream/stream_cipher.cpp @@ -9,23 +9,23 @@ #include #if defined(BOTAN_HAS_CHACHA) -#include + #include #endif #if defined(BOTAN_HAS_SALSA20) -#include + #include #endif #if defined(BOTAN_HAS_CTR_BE) -#include + #include #endif #if defined(BOTAN_HAS_OFB) -#include + #include #endif #if defined(BOTAN_HAS_RC4) -#include + #include #endif namespace Botan { diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h index 68c97f1c1..8c9b28147 100644 --- a/src/lib/stream/stream_cipher.h +++ b/src/lib/stream/stream_cipher.h @@ -25,7 +25,7 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm /** * Create an instance based on a name * Will return a null pointer if the algo/provider combination cannot - * be found. If providers is empty then best available is chosen. + * be found. If provider is empty then best available is chosen. */ static std::unique_ptr create(const std::string& algo_spec, const std::string& provider = ""); -- cgit v1.2.3 From 04319af23bf8ed467b17f9b74c814343e051ab6b Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 21 Sep 2015 14:59:01 -0400 Subject: Remove use of lookup.h in favor of new T::create API. --- src/cmd/hash.cpp | 1 - src/lib/block/cascade/cascade.cpp | 5 ++--- src/lib/block/lion/lion.cpp | 5 ++--- src/lib/cert/x509/ocsp_types.cpp | 5 ++--- src/lib/cert/x509/x509_ca.cpp | 7 ++++-- src/lib/cert/x509/x509cert.cpp | 3 +-- src/lib/ffi/ffi.cpp | 13 +++++------ src/lib/filters/algo_filt.cpp | 25 ++++++++++++++-------- src/lib/kdf/hkdf/hkdf.cpp | 9 ++++---- src/lib/kdf/prf_tls/prf_tls.cpp | 17 +++++++++------ src/lib/kdf/prf_x942/prf_x942.cpp | 3 +-- src/lib/mac/cbc_mac/cbc_mac.cpp | 3 +-- src/lib/mac/cmac/cmac.cpp | 5 ++--- src/lib/mac/hmac/hmac.cpp | 5 ++--- src/lib/mac/x919_mac/x919_mac.cpp | 8 +++---- src/lib/math/numbertheory/dsa_gen.cpp | 6 ++++-- src/lib/misc/benchmark/benchmark.cpp | 25 +++++++--------------- src/lib/misc/cryptobox/cryptobox.cpp | 1 - src/lib/misc/pbes2/pbes2.cpp | 1 - src/lib/misc/rfc3394/rfc3394.cpp | 11 +++++++--- src/lib/misc/srp6/srp6.cpp | 11 +++++++--- src/lib/modes/aead/aead.cpp | 1 - .../aead/chacha20poly1305/chacha20poly1305.cpp | 9 +++++--- src/lib/modes/cipher_mode.cpp | 9 ++++---- src/lib/modes/mode_utils.h | 13 ++++++----- src/lib/passhash/passhash9/passhash9.cpp | 21 +++++++++--------- src/lib/pbkdf/pbkdf2/pbkdf2.cpp | 9 ++++---- src/lib/pk_pad/eme_oaep/oaep.cpp | 5 ++--- src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp | 5 ++--- src/lib/pk_pad/emsa_pssr/pssr.cpp | 7 +++--- src/lib/pubkey/rfc6979/rfc6979.cpp | 4 ++-- src/lib/rng/rng.cpp | 8 ++++--- src/lib/stream/ctr/ctr.cpp | 5 ++--- src/lib/stream/ofb/ofb.cpp | 5 ++--- src/lib/tls/msg_hello_verify.cpp | 3 +-- .../tls/sessions_sql/tls_session_manager_sql.cpp | 1 - src/lib/tls/tls_ciphersuite.cpp | 10 +++------ src/lib/tls/tls_handshake_hash.cpp | 3 +-- src/lib/tls/tls_record.cpp | 22 ++++++++----------- src/tests/test_block.cpp | 5 ++--- src/tests/test_dlies.cpp | 9 ++++---- src/tests/test_hash.cpp | 5 ++--- src/tests/test_kdf.cpp | 1 - src/tests/test_mac.cpp | 5 ++--- src/tests/test_modes.cpp | 1 - src/tests/test_ocb.cpp | 8 ++++--- src/tests/test_pbkdf.cpp | 1 - src/tests/test_rng.cpp | 6 +++--- src/tests/test_stream.cpp | 5 ++--- 49 files changed, 169 insertions(+), 186 deletions(-) (limited to 'src/lib') 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 #include #include #include diff --git a/src/lib/block/cascade/cascade.cpp b/src/lib/block/cascade/cascade.cpp index 66ff293ff..100fb33ab 100644 --- a/src/lib/block/cascade/cascade.cpp +++ b/src/lib/block/cascade/cascade.cpp @@ -6,14 +6,13 @@ */ #include -#include namespace Botan { Cascade_Cipher* Cascade_Cipher::make(const BlockCipher::Spec& spec) { - std::unique_ptr c1(get_block_cipher(spec.arg(0))); - std::unique_ptr c2(get_block_cipher(spec.arg(1))); + std::unique_ptr c1(BlockCipher::create(spec.arg(0))); + std::unique_ptr c2(BlockCipher::create(spec.arg(1))); if(c1 && c2) return new Cascade_Cipher(c1.release(), c2.release()); diff --git a/src/lib/block/lion/lion.cpp b/src/lib/block/lion/lion.cpp index bbd24a3c1..559816aea 100644 --- a/src/lib/block/lion/lion.cpp +++ b/src/lib/block/lion/lion.cpp @@ -6,7 +6,6 @@ */ #include -#include #include namespace Botan { @@ -15,8 +14,8 @@ Lion* Lion::make(const BlockCipher::Spec& spec) { if(spec.arg_count_between(2, 3)) { - std::unique_ptr hash(get_hash_function(spec.arg(0))); - std::unique_ptr stream(get_stream_cipher(spec.arg(1))); + std::unique_ptr hash(HashFunction::create(spec.arg(0))); + std::unique_ptr stream(StreamCipher::create(spec.arg(1))); if(hash && stream) { 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 #include #include -#include #include #include @@ -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 hash(get_hash("SHA-160")); + std::unique_ptr 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 hash(get_hash(OIDS::lookup(m_hash_id.oid))); + std::unique_ptr 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..b6bb5d8ce 100644 --- a/src/lib/cert/x509/x509_ca.cpp +++ b/src/lib/cert/x509/x509_ca.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -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& 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 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& 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 hash(get_hash(hash_fn)); + std::unique_ptr hash(HashFunction::create(hash_fn)); if(!hash) throw Algorithm_Not_Found(hash_fn); 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 #include #include -#include #include #include #include @@ -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 hash(get_hash(hash_name)); + std::unique_ptr hash(HashFunction::create(hash_name)); hash->update(this->BER_encode()); const auto hex_print = hex_encode(hash->final()); diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 8d96a0fc7..aad6e0faf 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -277,9 +276,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 +328,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; } } @@ -898,7 +899,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 h(Botan::get_hash(hash_fn)); + std::unique_ptr h(Botan::HashFunction::create(hash_fn)); return write_vec_output(out, out_len, h->process(key.x509_subject_public_key())); }); } 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 -#include #include 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 output = m_hash->final(); if(m_out_len) send(output, std::min(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/kdf/hkdf/hkdf.cpp b/src/lib/kdf/hkdf/hkdf.cpp index d4c688afc..6f83853f9 100644 --- a/src/lib/kdf/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -6,17 +6,16 @@ */ #include -#include namespace Botan { 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/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp index 382f527ea..547b0c9c8 100644 --- a/src/lib/kdf/prf_tls/prf_tls.cpp +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -7,23 +7,26 @@ #include #include -#include 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; } 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 443e207f2..fb8de1e85 100644 --- a/src/lib/kdf/prf_x942/prf_x942.cpp +++ b/src/lib/kdf/prf_x942/prf_x942.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace Botan { @@ -33,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 hash(make_hash_function("SHA-160")); + std::unique_ptr hash(HashFunction::create("SHA-160")); const OID kek_algo(m_key_wrap_oid); secure_vector h; diff --git a/src/lib/mac/cbc_mac/cbc_mac.cpp b/src/lib/mac/cbc_mac/cbc_mac.cpp index 8133b9a6f..449865255 100644 --- a/src/lib/mac/cbc_mac/cbc_mac.cpp +++ b/src/lib/mac/cbc_mac/cbc_mac.cpp @@ -6,7 +6,6 @@ */ #include -#include namespace Botan { @@ -14,7 +13,7 @@ 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; diff --git a/src/lib/mac/cmac/cmac.cpp b/src/lib/mac/cmac/cmac.cpp index 0e42e3823..27edda233 100644 --- a/src/lib/mac/cmac/cmac.cpp +++ b/src/lib/mac/cmac/cmac.cpp @@ -6,7 +6,6 @@ */ #include -#include namespace Botan { @@ -14,8 +13,8 @@ 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; } diff --git a/src/lib/mac/hmac/hmac.cpp b/src/lib/mac/hmac/hmac.cpp index 40da31887..f445ab0cf 100644 --- a/src/lib/mac/hmac/hmac.cpp +++ b/src/lib/mac/hmac/hmac.cpp @@ -7,7 +7,6 @@ */ #include -#include namespace Botan { @@ -15,8 +14,8 @@ 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; } diff --git a/src/lib/mac/x919_mac/x919_mac.cpp b/src/lib/mac/x919_mac/x919_mac.cpp index 2e1fa374f..205d812c2 100644 --- a/src/lib/mac/x919_mac/x919_mac.cpp +++ b/src/lib/mac/x919_mac/x919_mac.cpp @@ -6,7 +6,6 @@ */ #include -#include namespace Botan { @@ -86,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/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 -#include #include #include #include @@ -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 hash(make_hash_function("SHA-" + std::to_string(qbits))); + const std::string hash_name = "SHA-" + std::to_string(qbits); + std::unique_ptr 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/misc/benchmark/benchmark.cpp b/src/lib/misc/benchmark/benchmark.cpp index 152b45d37..d5e3694b5 100644 --- a/src/lib/misc/benchmark/benchmark.cpp +++ b/src/lib/misc/benchmark/benchmark.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -56,10 +55,8 @@ time_algorithm_ops(const std::string& name, const double mb_mult = buffer.size() / static_cast(Mebibyte); - if(BlockCipher* p = get_block_cipher(name, provider)) + if(auto bc = BlockCipher::create(name, provider)) { - std::unique_ptr bc(p); - const SymmetricKey key(rng, bc->maximum_keylength()); return std::map({ @@ -68,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 sc(p); - const SymmetricKey key(rng, sc->maximum_keylength()); return std::map({ @@ -79,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 h(p); - return std::map({ { "", 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 mac(p); - const SymmetricKey key(rng, mac->maximum_keylength()); return std::map({ @@ -137,10 +128,10 @@ std::set get_all_providers_of(const std::string& algo) auto add_to_set = [&provs](const std::vector& 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; } diff --git a/src/lib/misc/cryptobox/cryptobox.cpp b/src/lib/misc/cryptobox/cryptobox.cpp index 752561248..c0fc9b777 100644 --- a/src/lib/misc/cryptobox/cryptobox.cpp +++ b/src/lib/misc/cryptobox/cryptobox.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/src/lib/misc/pbes2/pbes2.cpp b/src/lib/misc/pbes2/pbes2.cpp index 89af01e9d..ab740ff5d 100644 --- a/src/lib/misc/pbes2/pbes2.cpp +++ b/src/lib/misc/pbes2/pbes2.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/src/lib/misc/rfc3394/rfc3394.cpp b/src/lib/misc/rfc3394/rfc3394.cpp index 3e1ed8b40..582e8c92d 100644 --- a/src/lib/misc/rfc3394/rfc3394.cpp +++ b/src/lib/misc/rfc3394/rfc3394.cpp @@ -6,7 +6,6 @@ */ #include -#include #include #include #include @@ -22,7 +21,10 @@ secure_vector rfc3394_keywrap(const secure_vector& 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 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 aes(BlockCipher::create(cipher_name)); + if(!aes) + throw Algorithm_Not_Found(cipher_name); aes->set_key(kek); const size_t n = key.size() / 8; @@ -66,7 +68,10 @@ secure_vector rfc3394_keyunwrap(const secure_vector& 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 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 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 #include #include -#include namespace Botan { @@ -19,7 +18,10 @@ BigInt hash_seq(const std::string& hash_id, const BigInt& in1, const BigInt& in2) { - std::unique_ptr hash_fn(get_hash(hash_id)); + std::unique_ptr 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& salt) { - std::unique_ptr hash_fn(get_hash(hash_id)); + std::unique_ptr 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 1e66dbd43..61918c310 100644 --- a/src/lib/modes/aead/aead.cpp +++ b/src/lib/modes/aead/aead.cpp @@ -6,7 +6,6 @@ #include #include -#include #if defined(BOTAN_HAS_AEAD_CCM) #include diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp index 329e2e713..0aef6a747 100644 --- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp +++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp @@ -11,9 +11,12 @@ namespace Botan { 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/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp index 262c41434..27ee26327 100644 --- a/src/lib/modes/cipher_mode.cpp +++ b/src/lib/modes/cipher_mode.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include @@ -34,7 +33,7 @@ namespace Botan { template Transform* make_ecb_mode(const Transform::Spec& spec) { - std::unique_ptr bc(get_block_cipher(spec.arg(0))); + std::unique_ptr bc(BlockCipher::create(spec.arg(0))); std::unique_ptr pad(get_bc_pad(spec.arg(1, "NoPadding"))); if(bc && pad) return new T(bc.release(), pad.release()); @@ -50,7 +49,7 @@ BOTAN_REGISTER_TRANSFORM(ECB_Decryption, make_ecb_mode); template Transform* make_cbc_mode(const Transform::Spec& spec) { - std::unique_ptr bc(get_block_cipher(spec.arg(0))); + std::unique_ptr bc(BlockCipher::create(spec.arg(0))); if(bc) { @@ -131,8 +130,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/mode_utils.h b/src/lib/modes/mode_utils.h index b93884206..a61c22a4f 100644 --- a/src/lib/modes/mode_utils.h +++ b/src/lib/modes/mode_utils.h @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -22,18 +21,18 @@ namespace Botan { template 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 bc = BlockCipher::create(spec.arg(0))) + return new T(bc.release()); return nullptr; } template T* make_block_cipher_mode_len(const Transform::Spec& spec) { - if(BlockCipher* bc = get_block_cipher(spec.arg(0))) + if(std::unique_ptr 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 +41,11 @@ T* make_block_cipher_mode_len(const Transform::Spec& spec) template T* make_block_cipher_mode_len2(const Transform::Spec& spec) { - if(BlockCipher* bc = get_block_cipher(spec.arg(0))) + if(std::unique_ptr 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/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 #include -#include #include #include @@ -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 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 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 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 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 cmp = kdf.derive_key( PASSHASH9_PBKDF_OUTPUT_LEN, diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp index 480b43d4b..c1ac2c534 100644 --- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp +++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -6,7 +6,6 @@ */ #include -#include #include #include @@ -14,11 +13,11 @@ namespace Botan { 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/pk_pad/eme_oaep/oaep.cpp b/src/lib/pk_pad/eme_oaep/oaep.cpp index a484202da..f214c25d2 100644 --- a/src/lib/pk_pad/eme_oaep/oaep.cpp +++ b/src/lib/pk_pad/eme_oaep/oaep.cpp @@ -8,7 +8,6 @@ #include #include #include -#include namespace Botan { @@ -19,8 +18,8 @@ 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()); } } diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp index 5e8462d4f..940f91c9a 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp @@ -7,7 +7,6 @@ #include #include -#include namespace Botan { @@ -17,8 +16,8 @@ EMSA* EMSA_PKCS1v15::make(const EMSA::Spec& spec) 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; } diff --git a/src/lib/pk_pad/emsa_pssr/pssr.cpp b/src/lib/pk_pad/emsa_pssr/pssr.cpp index 06ca007c8..36b0ab64c 100644 --- a/src/lib/pk_pad/emsa_pssr/pssr.cpp +++ b/src/lib/pk_pad/emsa_pssr/pssr.cpp @@ -8,7 +8,6 @@ #include #include #include -#include namespace Botan { @@ -17,10 +16,10 @@ 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; 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 #include +#include #include -#include 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/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 #include -#include namespace Botan { RandomNumberGenerator* RandomNumberGenerator::make_rng() { - std::unique_ptr h1(make_message_auth("HMAC(SHA-512)")); - std::unique_ptr h2(h1->clone()); + std::unique_ptr h1(MessageAuthenticationCode::create("HMAC(SHA-512)")); + std::unique_ptr h2(MessageAuthenticationCode::create("HMAC(SHA-512)")); + + if(!h1 || !h2) + throw Algorithm_Not_Found("HMAC_RNG HMACs"); std::unique_ptr rng(new HMAC_RNG(h1.release(), h2.release())); rng->reseed(256); diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index 3b573448b..e90bb43a4 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -6,7 +6,6 @@ */ #include -#include namespace Botan { @@ -14,8 +13,8 @@ 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/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index 1e6615fc0..e8cb463db 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -6,7 +6,6 @@ */ #include -#include namespace Botan { @@ -14,8 +13,8 @@ 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/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 #include -#include namespace Botan { @@ -36,7 +35,7 @@ Hello_Verify_Request::Hello_Verify_Request(const std::vector& client_hello const std::string& client_identity, const SymmetricKey& secret_key) { - std::unique_ptr hmac(get_mac("HMAC(SHA-256)")); + std::unique_ptr 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 #include #include -#include #include #include #include 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 #include -#include #include #include #include @@ -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 #include -#include #include namespace Botan { @@ -29,7 +28,7 @@ secure_vector Handshake_Hash::final(Protocol_Version version, return mac_algo.c_str(); }; - std::unique_ptr hash(make_hash_function(choose_hash())); + std::unique_ptr 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 53521c5da..71542de16 100644 --- a/src/lib/tls/tls_record.cpp +++ b/src/lib/tls/tls_record.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include namespace Botan { @@ -62,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/tests/test_block.cpp b/src/tests/test_block.cpp index 509cf1c0c..32e175899 100644 --- a/src/tests/test_block.cpp +++ b/src/tests/test_block.cpp @@ -7,7 +7,6 @@ #include "tests.h" #include -#include #include #include #include @@ -25,7 +24,7 @@ size_t block_test(const std::string& algo, const secure_vector pt = hex_decode_locked(in_hex); const secure_vector ct = hex_decode_locked(out_hex); - const std::vector providers = get_block_cipher_providers(algo); + const std::vector providers = BlockCipher::providers(algo); size_t fails = 0; if(providers.empty()) @@ -33,7 +32,7 @@ size_t block_test(const std::string& algo, for(auto provider: providers) { - std::unique_ptr cipher(get_block_cipher(algo, provider)); + std::unique_ptr cipher(BlockCipher::create(algo, provider)); if(!cipher) { 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 #include #include -#include 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_hash.cpp b/src/tests/test_hash.cpp index a69ba3ef3..d37a9dc14 100644 --- a/src/tests/test_hash.cpp +++ b/src/tests/test_hash.cpp @@ -6,7 +6,6 @@ #include "tests.h" -#include #include #include #include @@ -22,7 +21,7 @@ size_t hash_test(const std::string& algo, { size_t fails = 0; - const std::vector providers = get_hash_function_providers(algo); + const std::vector providers = HashFunction::providers(algo); if(providers.empty()) { @@ -32,7 +31,7 @@ size_t hash_test(const std::string& algo, for(auto provider: providers) { - std::unique_ptr hash(get_hash(algo, provider)); + std::unique_ptr 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 -#include #include #include #include diff --git a/src/tests/test_mac.cpp b/src/tests/test_mac.cpp index 6ab87274f..4009a6c4d 100644 --- a/src/tests/test_mac.cpp +++ b/src/tests/test_mac.cpp @@ -8,7 +8,6 @@ #if defined(BOTAN_HAS_MAC) -#include #include #include #include @@ -23,7 +22,7 @@ size_t mac_test(const std::string& algo, const std::string& in_hex, const std::string& out_hex) { - const std::vector providers = get_mac_providers(algo); + const std::vector providers = MessageAuthenticationCode::providers(algo); size_t fails = 0; if(providers.empty()) @@ -34,7 +33,7 @@ size_t mac_test(const std::string& algo, for(auto provider: providers) { - std::unique_ptr mac(get_mac(algo, provider)); + std::unique_ptr mac(MessageAuthenticationCode::create(algo, provider)); if(!mac) { diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp index bfbb46355..09e0be8ba 100644 --- a/src/tests/test_modes.cpp +++ b/src/tests/test_modes.cpp @@ -11,7 +11,6 @@ #if defined(BOTAN_HAS_FILTERS) #include -#include #include #include #include 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 #include #include -#include 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 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 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 -#include #include #include #include diff --git a/src/tests/test_rng.cpp b/src/tests/test_rng.cpp index d129ed208..7cbd50fa0 100644 --- a/src/tests/test_rng.cpp +++ b/src/tests/test_rng.cpp @@ -8,7 +8,6 @@ #include "tests.h" #include -#include #include #include @@ -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 diff --git a/src/tests/test_stream.cpp b/src/tests/test_stream.cpp index 4828d44fd..046c199ec 100644 --- a/src/tests/test_stream.cpp +++ b/src/tests/test_stream.cpp @@ -9,7 +9,6 @@ #if defined(BOTAN_HAS_STREAM_CIPHER) #include -#include #include #include #include @@ -29,7 +28,7 @@ size_t stream_test(const std::string& algo, const secure_vector ct = hex_decode_locked(out_hex); const secure_vector nonce = hex_decode_locked(nonce_hex); - const std::vector providers = get_stream_cipher_providers(algo); + const std::vector providers = StreamCipher::providers(algo); size_t fails = 0; if(providers.empty()) @@ -40,7 +39,7 @@ size_t stream_test(const std::string& algo, for(auto provider: providers) { - std::unique_ptr cipher(get_stream_cipher(algo, provider)); + std::unique_ptr cipher(StreamCipher::create(algo, provider)); if(!cipher) { -- cgit v1.2.3 From b999079ebdfd1c9bd288763ae06dfdf6a31325e0 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 21 Sep 2015 17:23:45 -0400 Subject: Move check for SIMD instructions to CPUID Avoids needing to include simd_32 to see if SIMD is disabled. This had caused a build break on Linux x86-32 as SSE2 must be enabled on a per-file basis. --- src/lib/block/block_cipher.cpp | 10 +++------- src/lib/utils/cpuid.cpp | 13 +++++++++++++ src/lib/utils/cpuid.h | 2 ++ src/lib/utils/simd/simd_altivec/simd_altivec.h | 2 -- src/lib/utils/simd/simd_scalar/simd_scalar.h | 2 -- src/lib/utils/simd/simd_sse2/simd_sse2.h | 2 -- 6 files changed, 18 insertions(+), 13 deletions(-) (limited to 'src/lib') diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp index 5b9c4f0ba..7b52f8716 100644 --- a/src/lib/block/block_cipher.cpp +++ b/src/lib/block/block_cipher.cpp @@ -9,10 +9,6 @@ #include #include -#if defined(BOTAN_HAS_SIMD_32) - #include -#endif - #if defined(BOTAN_HAS_AES) #include #endif @@ -249,7 +245,7 @@ BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Noekeon); #endif #if defined(BOTAN_HAS_NOEKEON_SIMD) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Noekeon_SIMD, "Noekeon", +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_simd_32(), Noekeon_SIMD, "Noekeon", "simd32", BOTAN_SIMD_ALGORITHM_PRIO); #endif @@ -278,7 +274,7 @@ BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Serpent); #endif #if defined(BOTAN_HAS_SERPENT_SIMD) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), Serpent_SIMD, "Serpent", +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_simd_32(), Serpent_SIMD, "Serpent", "simd32", BOTAN_SIMD_ALGORITHM_PRIO); #endif @@ -304,7 +300,7 @@ BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(XTEA); #endif #if defined(BOTAN_HAS_XTEA_SIMD) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), XTEA_SIMD, "XTEA", +BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_simd_32(), XTEA_SIMD, "XTEA", "simd32", BOTAN_SIMD_ALGORITHM_PRIO); #endif diff --git a/src/lib/utils/cpuid.cpp b/src/lib/utils/cpuid.cpp index 218b6553c..c98829789 100644 --- a/src/lib/utils/cpuid.cpp +++ b/src/lib/utils/cpuid.cpp @@ -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/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 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(B)); -- cgit v1.2.3 From a2267040583137c2192d593fcd4cb09b388a3bd6 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 22 Sep 2015 10:07:43 -0400 Subject: Move boost and sqlite3 to utils --- src/lib/utils/boost/info.txt | 11 +++ src/lib/utils/sqlite3/info.txt | 10 +++ src/lib/utils/sqlite3/sqlite3.cpp | 143 +++++++++++++++++++++++++++++++++++++ src/lib/utils/sqlite3/sqlite3.h | 56 +++++++++++++++ src/lib/vendor/boost/info.txt | 11 --- src/lib/vendor/sqlite3/info.txt | 10 --- src/lib/vendor/sqlite3/sqlite3.cpp | 143 ------------------------------------- src/lib/vendor/sqlite3/sqlite3.h | 56 --------------- 8 files changed, 220 insertions(+), 220 deletions(-) create mode 100644 src/lib/utils/boost/info.txt create mode 100644 src/lib/utils/sqlite3/info.txt create mode 100644 src/lib/utils/sqlite3/sqlite3.cpp create mode 100644 src/lib/utils/sqlite3/sqlite3.h delete mode 100644 src/lib/vendor/boost/info.txt delete mode 100644 src/lib/vendor/sqlite3/info.txt delete mode 100644 src/lib/vendor/sqlite3/sqlite3.cpp delete mode 100644 src/lib/vendor/sqlite3/sqlite3.h (limited to 'src/lib') diff --git a/src/lib/utils/boost/info.txt b/src/lib/utils/boost/info.txt new file mode 100644 index 000000000..8748c0bf1 --- /dev/null +++ b/src/lib/utils/boost/info.txt @@ -0,0 +1,11 @@ +define BOOST_FILESYSTEM 20131228 +define BOOST_ASIO 20131228 +define BOOST_DATETIME 20150720 + +load_on vendor + + +all -> boost_system,boost_filesystem + + + diff --git a/src/lib/utils/sqlite3/info.txt b/src/lib/utils/sqlite3/info.txt new file mode 100644 index 000000000..98ce5f796 --- /dev/null +++ b/src/lib/utils/sqlite3/info.txt @@ -0,0 +1,10 @@ + +load_on vendor + + +all -> sqlite3 + + + +sqlite3.h + diff --git a/src/lib/utils/sqlite3/sqlite3.cpp b/src/lib/utils/sqlite3/sqlite3.cpp new file mode 100644 index 000000000..be3c2b227 --- /dev/null +++ b/src/lib/utils/sqlite3/sqlite3.cpp @@ -0,0 +1,143 @@ +/* +* SQLite wrapper +* (C) 2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +Sqlite3_Database::Sqlite3_Database(const std::string& db_filename) + { + int rc = ::sqlite3_open(db_filename.c_str(), &m_db); + + if(rc) + { + const std::string err_msg = ::sqlite3_errmsg(m_db); + ::sqlite3_close(m_db); + m_db = nullptr; + throw std::runtime_error("sqlite3_open failed - " + err_msg); + } + } + +Sqlite3_Database::~Sqlite3_Database() + { + if(m_db) + ::sqlite3_close(m_db); + m_db = nullptr; + } + +std::shared_ptr Sqlite3_Database::new_statement(const std::string& base_sql) const + { + return std::make_shared(m_db, base_sql); + } + +size_t Sqlite3_Database::row_count(const std::string& table_name) + { + auto stmt = new_statement("select count(*) from " + table_name); + + if(stmt->step()) + return stmt->get_size_t(0); + else + throw std::runtime_error("Querying size of table " + table_name + " failed"); + } + +void Sqlite3_Database::create_table(const std::string& table_schema) + { + char* errmsg = nullptr; + int rc = ::sqlite3_exec(m_db, table_schema.c_str(), nullptr, nullptr, &errmsg); + + if(rc != SQLITE_OK) + { + const std::string err_msg = errmsg; + ::sqlite3_free(errmsg); + ::sqlite3_close(m_db); + m_db = nullptr; + throw std::runtime_error("sqlite3_exec for table failed - " + err_msg); + } + } + +Sqlite3_Database::Sqlite3_Statement::Sqlite3_Statement(sqlite3* db, const std::string& base_sql) + { + int rc = ::sqlite3_prepare_v2(db, base_sql.c_str(), -1, &m_stmt, nullptr); + + if(rc != SQLITE_OK) + throw std::runtime_error("sqlite3_prepare failed " + base_sql + + ", code " + std::to_string(rc)); + } + +void Sqlite3_Database::Sqlite3_Statement::bind(int column, const std::string& val) + { + int rc = ::sqlite3_bind_text(m_stmt, column, val.c_str(), -1, SQLITE_TRANSIENT); + if(rc != SQLITE_OK) + throw std::runtime_error("sqlite3_bind_text failed, code " + std::to_string(rc)); + } + +void Sqlite3_Database::Sqlite3_Statement::bind(int column, size_t val) + { + if(val != static_cast(static_cast(val))) // is this legit? + throw std::runtime_error("sqlite3 cannot store " + std::to_string(val) + " without truncation"); + int rc = ::sqlite3_bind_int(m_stmt, column, val); + if(rc != SQLITE_OK) + throw std::runtime_error("sqlite3_bind_int failed, code " + std::to_string(rc)); + } + +void Sqlite3_Database::Sqlite3_Statement::bind(int column, std::chrono::system_clock::time_point time) + { + const int timeval = std::chrono::duration_cast(time.time_since_epoch()).count(); + bind(column, timeval); + } + +void Sqlite3_Database::Sqlite3_Statement::bind(int column, const std::vector& val) + { + int rc = ::sqlite3_bind_blob(m_stmt, column, val.data(), val.size(), SQLITE_TRANSIENT); + if(rc != SQLITE_OK) + throw std::runtime_error("sqlite3_bind_text failed, code " + std::to_string(rc)); + } + +std::pair Sqlite3_Database::Sqlite3_Statement::get_blob(int column) + { + BOTAN_ASSERT(::sqlite3_column_type(m_stmt, 0) == SQLITE_BLOB, + "Return value is a blob"); + + const void* session_blob = ::sqlite3_column_blob(m_stmt, column); + const int session_blob_size = ::sqlite3_column_bytes(m_stmt, column); + + BOTAN_ASSERT(session_blob_size >= 0, "Blob size is non-negative"); + + return std::make_pair(static_cast(session_blob), + static_cast(session_blob_size)); + } + +size_t Sqlite3_Database::Sqlite3_Statement::get_size_t(int column) + { + BOTAN_ASSERT(::sqlite3_column_type(m_stmt, column) == SQLITE_INTEGER, + "Return count is an integer"); + + const int sessions_int = ::sqlite3_column_int(m_stmt, column); + + BOTAN_ASSERT(sessions_int >= 0, "Expected size_t is non-negative"); + + return static_cast(sessions_int); + } + +void Sqlite3_Database::Sqlite3_Statement::spin() + { + while(step()) {} + } + +bool Sqlite3_Database::Sqlite3_Statement::step() + { + return (::sqlite3_step(m_stmt) == SQLITE_ROW); + } + +Sqlite3_Database::Sqlite3_Statement::~Sqlite3_Statement() + { + ::sqlite3_finalize(m_stmt); + } + +} diff --git a/src/lib/utils/sqlite3/sqlite3.h b/src/lib/utils/sqlite3/sqlite3.h new file mode 100644 index 000000000..8495a1d1b --- /dev/null +++ b/src/lib/utils/sqlite3/sqlite3.h @@ -0,0 +1,56 @@ +/* +* SQLite3 wrapper +* (C) 2012,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_UTILS_SQLITE3_H__ +#define BOTAN_UTILS_SQLITE3_H__ + +#include + +class sqlite3; +class sqlite3_stmt; + +namespace Botan { + +class BOTAN_DLL Sqlite3_Database : public SQL_Database + { + public: + Sqlite3_Database(const std::string& file); + + ~Sqlite3_Database(); + + size_t row_count(const std::string& table_name) override; + + void create_table(const std::string& table_schema) override; + + std::shared_ptr new_statement(const std::string& sql) const override; + private: + class Sqlite3_Statement : public Statement + { + public: + void bind(int column, const std::string& val) override; + void bind(int column, size_t val) override; + void bind(int column, std::chrono::system_clock::time_point time) override; + void bind(int column, const std::vector& val) override; + + std::pair get_blob(int column) override; + size_t get_size_t(int column) override; + + void spin() override; + bool step() override; + + Sqlite3_Statement(sqlite3* db, const std::string& base_sql); + ~Sqlite3_Statement(); + private: + sqlite3_stmt* m_stmt; + }; + + sqlite3* m_db; + }; + +} + +#endif diff --git a/src/lib/vendor/boost/info.txt b/src/lib/vendor/boost/info.txt deleted file mode 100644 index 8748c0bf1..000000000 --- a/src/lib/vendor/boost/info.txt +++ /dev/null @@ -1,11 +0,0 @@ -define BOOST_FILESYSTEM 20131228 -define BOOST_ASIO 20131228 -define BOOST_DATETIME 20150720 - -load_on vendor - - -all -> boost_system,boost_filesystem - - - diff --git a/src/lib/vendor/sqlite3/info.txt b/src/lib/vendor/sqlite3/info.txt deleted file mode 100644 index 98ce5f796..000000000 --- a/src/lib/vendor/sqlite3/info.txt +++ /dev/null @@ -1,10 +0,0 @@ - -load_on vendor - - -all -> sqlite3 - - - -sqlite3.h - diff --git a/src/lib/vendor/sqlite3/sqlite3.cpp b/src/lib/vendor/sqlite3/sqlite3.cpp deleted file mode 100644 index be3c2b227..000000000 --- a/src/lib/vendor/sqlite3/sqlite3.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* -* SQLite wrapper -* (C) 2012 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include -#include - -namespace Botan { - -Sqlite3_Database::Sqlite3_Database(const std::string& db_filename) - { - int rc = ::sqlite3_open(db_filename.c_str(), &m_db); - - if(rc) - { - const std::string err_msg = ::sqlite3_errmsg(m_db); - ::sqlite3_close(m_db); - m_db = nullptr; - throw std::runtime_error("sqlite3_open failed - " + err_msg); - } - } - -Sqlite3_Database::~Sqlite3_Database() - { - if(m_db) - ::sqlite3_close(m_db); - m_db = nullptr; - } - -std::shared_ptr Sqlite3_Database::new_statement(const std::string& base_sql) const - { - return std::make_shared(m_db, base_sql); - } - -size_t Sqlite3_Database::row_count(const std::string& table_name) - { - auto stmt = new_statement("select count(*) from " + table_name); - - if(stmt->step()) - return stmt->get_size_t(0); - else - throw std::runtime_error("Querying size of table " + table_name + " failed"); - } - -void Sqlite3_Database::create_table(const std::string& table_schema) - { - char* errmsg = nullptr; - int rc = ::sqlite3_exec(m_db, table_schema.c_str(), nullptr, nullptr, &errmsg); - - if(rc != SQLITE_OK) - { - const std::string err_msg = errmsg; - ::sqlite3_free(errmsg); - ::sqlite3_close(m_db); - m_db = nullptr; - throw std::runtime_error("sqlite3_exec for table failed - " + err_msg); - } - } - -Sqlite3_Database::Sqlite3_Statement::Sqlite3_Statement(sqlite3* db, const std::string& base_sql) - { - int rc = ::sqlite3_prepare_v2(db, base_sql.c_str(), -1, &m_stmt, nullptr); - - if(rc != SQLITE_OK) - throw std::runtime_error("sqlite3_prepare failed " + base_sql + - ", code " + std::to_string(rc)); - } - -void Sqlite3_Database::Sqlite3_Statement::bind(int column, const std::string& val) - { - int rc = ::sqlite3_bind_text(m_stmt, column, val.c_str(), -1, SQLITE_TRANSIENT); - if(rc != SQLITE_OK) - throw std::runtime_error("sqlite3_bind_text failed, code " + std::to_string(rc)); - } - -void Sqlite3_Database::Sqlite3_Statement::bind(int column, size_t val) - { - if(val != static_cast(static_cast(val))) // is this legit? - throw std::runtime_error("sqlite3 cannot store " + std::to_string(val) + " without truncation"); - int rc = ::sqlite3_bind_int(m_stmt, column, val); - if(rc != SQLITE_OK) - throw std::runtime_error("sqlite3_bind_int failed, code " + std::to_string(rc)); - } - -void Sqlite3_Database::Sqlite3_Statement::bind(int column, std::chrono::system_clock::time_point time) - { - const int timeval = std::chrono::duration_cast(time.time_since_epoch()).count(); - bind(column, timeval); - } - -void Sqlite3_Database::Sqlite3_Statement::bind(int column, const std::vector& val) - { - int rc = ::sqlite3_bind_blob(m_stmt, column, val.data(), val.size(), SQLITE_TRANSIENT); - if(rc != SQLITE_OK) - throw std::runtime_error("sqlite3_bind_text failed, code " + std::to_string(rc)); - } - -std::pair Sqlite3_Database::Sqlite3_Statement::get_blob(int column) - { - BOTAN_ASSERT(::sqlite3_column_type(m_stmt, 0) == SQLITE_BLOB, - "Return value is a blob"); - - const void* session_blob = ::sqlite3_column_blob(m_stmt, column); - const int session_blob_size = ::sqlite3_column_bytes(m_stmt, column); - - BOTAN_ASSERT(session_blob_size >= 0, "Blob size is non-negative"); - - return std::make_pair(static_cast(session_blob), - static_cast(session_blob_size)); - } - -size_t Sqlite3_Database::Sqlite3_Statement::get_size_t(int column) - { - BOTAN_ASSERT(::sqlite3_column_type(m_stmt, column) == SQLITE_INTEGER, - "Return count is an integer"); - - const int sessions_int = ::sqlite3_column_int(m_stmt, column); - - BOTAN_ASSERT(sessions_int >= 0, "Expected size_t is non-negative"); - - return static_cast(sessions_int); - } - -void Sqlite3_Database::Sqlite3_Statement::spin() - { - while(step()) {} - } - -bool Sqlite3_Database::Sqlite3_Statement::step() - { - return (::sqlite3_step(m_stmt) == SQLITE_ROW); - } - -Sqlite3_Database::Sqlite3_Statement::~Sqlite3_Statement() - { - ::sqlite3_finalize(m_stmt); - } - -} diff --git a/src/lib/vendor/sqlite3/sqlite3.h b/src/lib/vendor/sqlite3/sqlite3.h deleted file mode 100644 index 8495a1d1b..000000000 --- a/src/lib/vendor/sqlite3/sqlite3.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* SQLite3 wrapper -* (C) 2012,2014 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_UTILS_SQLITE3_H__ -#define BOTAN_UTILS_SQLITE3_H__ - -#include - -class sqlite3; -class sqlite3_stmt; - -namespace Botan { - -class BOTAN_DLL Sqlite3_Database : public SQL_Database - { - public: - Sqlite3_Database(const std::string& file); - - ~Sqlite3_Database(); - - size_t row_count(const std::string& table_name) override; - - void create_table(const std::string& table_schema) override; - - std::shared_ptr new_statement(const std::string& sql) const override; - private: - class Sqlite3_Statement : public Statement - { - public: - void bind(int column, const std::string& val) override; - void bind(int column, size_t val) override; - void bind(int column, std::chrono::system_clock::time_point time) override; - void bind(int column, const std::vector& val) override; - - std::pair get_blob(int column) override; - size_t get_size_t(int column) override; - - void spin() override; - bool step() override; - - Sqlite3_Statement(sqlite3* db, const std::string& base_sql); - ~Sqlite3_Statement(); - private: - sqlite3_stmt* m_stmt; - }; - - sqlite3* m_db; - }; - -} - -#endif -- cgit v1.2.3 From 38a50cbabe70ae2d8f67f27a8092509b886b85e6 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 22 Sep 2015 10:54:17 -0400 Subject: Cleanup includes --- src/lib/modes/aead/aead.cpp | 3 ++- src/lib/modes/cipher_mode.cpp | 1 + src/lib/modes/mode_utils.h | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp index 61918c310..3d04887d0 100644 --- a/src/lib/modes/aead/aead.cpp +++ b/src/lib/modes/aead/aead.cpp @@ -4,8 +4,9 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include #include +#include +#include #if defined(BOTAN_HAS_AEAD_CCM) #include diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp index 27ee26327..acd5e23e2 100644 --- a/src/lib/modes/cipher_mode.cpp +++ b/src/lib/modes/cipher_mode.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #if defined(BOTAN_HAS_MODE_ECB) diff --git a/src/lib/modes/mode_utils.h b/src/lib/modes/mode_utils.h index a61c22a4f..44524c4f6 100644 --- a/src/lib/modes/mode_utils.h +++ b/src/lib/modes/mode_utils.h @@ -9,7 +9,6 @@ #define BOTAN_MODE_UTILS_H__ #include -#include #include #include #include -- cgit v1.2.3 From bd99a4fe3e04d85d46e1bd88bde295e01abcb1de Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 22 Sep 2015 11:19:05 -0400 Subject: Inline Camellia sbox tables to source file --- src/lib/block/camellia/camellia.cpp | 533 +++++++++++++++++++++++++++++++++++- 1 file changed, 530 insertions(+), 3 deletions(-) (limited to 'src/lib') diff --git a/src/lib/block/camellia/camellia.cpp b/src/lib/block/camellia/camellia.cpp index dc57e26bc..e9b10c528 100644 --- a/src/lib/block/camellia/camellia.cpp +++ b/src/lib/block/camellia/camellia.cpp @@ -6,15 +6,542 @@ */ #include -#include #include namespace Botan { -namespace Camellia_F { - namespace { +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 Camellia_F { + /* * We use the slow byte-wise version of F in the first and last rounds * to help protect against timing attacks -- cgit v1.2.3 From 45690f3392108e5183e363ef1b8024943cbedf07 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 22 Sep 2015 11:19:36 -0400 Subject: Delete Camellia sbox header. Two part commit with bd99a4f to work around git's insane rename system. --- src/lib/block/camellia/camellia_sbox.h | 545 --------------------------------- src/lib/block/camellia/info.txt | 6 +- 2 files changed, 1 insertion(+), 550 deletions(-) delete mode 100644 src/lib/block/camellia/camellia_sbox.h (limited to 'src/lib') 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 - -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 - - -camellia_sbox.h - +define CAMELLIA 20150922 camellia.h -- cgit v1.2.3 From ac9689990da914cd58788dab9d5e0d7bebb72e30 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 22 Sep 2015 11:48:32 -0400 Subject: Add HMAC_DRBG constructor taking a name for the MAC instead of an obj --- src/lib/rng/hmac_drbg/hmac_drbg.cpp | 12 ++++++++++++ src/lib/rng/hmac_drbg/hmac_drbg.h | 3 +++ 2 files changed, 15 insertions(+) (limited to 'src/lib') diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/lib/rng/hmac_drbg/hmac_drbg.cpp index af0565120..22236c0cb 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(m_mac->output_length(), 0x00)); } +HMAC_DRBG::HMAC_DRBG(const std::string& mac_name, + RandomNumberGenerator* prng) : + m_prng(prng), + m_V(m_mac->output_length(), 0x01), + m_reseed_counter(0) + { + m_mac = MessageAuthenticationCode::create(mac_name); + if(!m_mac) + throw Algorithm_Not_Found(mac_name); + m_mac->set_key(std::vector(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); -- cgit v1.2.3 From 1f62dbcd0108a2cd99ad473299e041163a638b1c Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 22 Sep 2015 23:13:08 +0200 Subject: Avoid concatination of chars Ever tried? auto str = "some long string"; auto str2 = str + '\n'; It's not with the brainfuck finding the bug. --- src/lib/asn1/asn1_oid.cpp | 2 +- src/lib/base/scan_name.cpp | 10 +++++----- src/lib/cert/x509/x509_ca.cpp | 2 +- src/lib/entropy/proc_walk/proc_walk.cpp | 2 +- src/lib/misc/openpgp/openpgp.cpp | 8 ++++---- src/lib/utils/filesystem.cpp | 2 +- src/tests/test_ecdsa.cpp | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/lib') 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/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/cert/x509/x509_ca.cpp b/src/lib/cert/x509/x509_ca.cpp index b6bb5d8ce..d329bfdd8 100644 --- a/src/lib/cert/x509/x509_ca.cpp +++ b/src/lib/cert/x509/x509_ca.cpp @@ -243,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/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/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::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/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 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/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp index 8d385b4bf..3fe9bff5e 100644 --- a/src/tests/test_ecdsa.cpp +++ b/src/tests/test_ecdsa.cpp @@ -37,7 +37,7 @@ size_t ecdsa_sig_kat(const std::string& group_id, PK_Verifier verify(ecdsa, padding); PK_Signer sign(ecdsa, padding); - return validate_signature(verify, sign, "ECDSA/" + group_id + '/' + hash, + return validate_signature(verify, sign, "ECDSA/" + group_id + "/" + hash, msg, rng, signature); } -- cgit v1.2.3 From ee0460cff538a3de7ca89fb54d37215757659a42 Mon Sep 17 00:00:00 2001 From: Daniel Seither Date: Fri, 25 Sep 2015 14:10:01 +0200 Subject: Add the Darwin_SecRandom entropy source It uses the SecRandomCopyBytes function from the Security framework of OS X and iOS. We need this because it is the official way to get cryptographically secure random numbers on iOS, where /dev/random is not accessible due to sandboxing. --- .../entropy/darwin_secrandom/darwin_secrandom.cpp | 28 +++++++++++++++++++ .../entropy/darwin_secrandom/darwin_secrandom.h | 31 ++++++++++++++++++++++ src/lib/entropy/darwin_secrandom/info.txt | 17 ++++++++++++ src/lib/entropy/entropy_srcs.cpp | 8 ++++++ 4 files changed, 84 insertions(+) create mode 100644 src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp create mode 100644 src/lib/entropy/darwin_secrandom/darwin_secrandom.h create mode 100644 src/lib/entropy/darwin_secrandom/info.txt (limited to 'src/lib') 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 +#include + +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 + +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 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 + + +darwin_secrandom.cpp + + + +darwin_secrandom.h + + + +darwin + + + +darwin -> Security + \ 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 #endif +#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) + #include +#endif + namespace Botan { namespace { @@ -97,6 +101,10 @@ std::vector> get_default_entropy_sources() )); #endif +#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) + sources.push_back(std::unique_ptr(new Darwin_SecRandom)); +#endif + return sources; } -- cgit v1.2.3 From 1e59c4492314cda2d91c5b06dd447bc27e026e2b Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 8 Sep 2015 23:32:39 +0200 Subject: Remove warning: assuming signed overflow does not occur warning: assuming signed overflow does not occur when reducing constant in comparison [-Wstrict-overflow] cond1 = r0.get_degree() <= break_deg - 1; --- src/lib/pubkey/mce/polyn_gf2m.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/pubkey/mce/polyn_gf2m.cpp b/src/lib/pubkey/mce/polyn_gf2m.cpp index 9b3366757..70404c57c 100644 --- a/src/lib/pubkey/mce/polyn_gf2m.cpp +++ b/src/lib/pubkey/mce/polyn_gf2m.cpp @@ -512,7 +512,7 @@ std::pair 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; } -- cgit v1.2.3 From 2a6f5f10cc9713230bdd6204c57219451584f4a4 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 22 Sep 2015 12:10:24 -0400 Subject: McEliece cleanups Remove and consolidate various headers Reduce memory usage of GF2m_Field by sharing the log and exponent tables across all instances of a particular word size. Remove McEliece_Public_Operation and McEliece_Private_Operation which were difficult to use safely. Instead only the KEM operations are exposed. Add McEliece_PublicKey::random_plaintext_element Add command line `mce` tool and some McEliece documentation Convert the speed program to check McEliece keys of the suggested size Add McEliece KATs for both key generation and KEM Fix HMAC_DRBG constructor which derefed a pointer before its time --- doc/manual/contents.rst | 1 + doc/manual/mceliece.rst | 74 ++++ src/cmd/implementation/speed_public_key.cpp | 19 +- src/cmd/mce.cpp | 117 ++++++ src/lib/pubkey/mce/binary_matrix.cpp | 95 ----- src/lib/pubkey/mce/binary_matrix.h | 60 ---- src/lib/pubkey/mce/code_based_key_gen.cpp | 133 ++++++- src/lib/pubkey/mce/code_based_key_gen.h | 26 -- src/lib/pubkey/mce/code_based_util.h | 9 +- src/lib/pubkey/mce/gf2m_rootfind_dcmp.cpp | 531 ++++++++++++++-------------- src/lib/pubkey/mce/gf2m_rootfind_dcmp.h | 24 -- src/lib/pubkey/mce/gf2m_small_m.cpp | 115 +++--- src/lib/pubkey/mce/gf2m_small_m.h | 296 ++++++++-------- src/lib/pubkey/mce/goppa_code.cpp | 57 ++- src/lib/pubkey/mce/goppa_code.h | 32 -- src/lib/pubkey/mce/info.txt | 16 +- src/lib/pubkey/mce/mce_internal.h | 52 +++ src/lib/pubkey/mce/mce_kem.cpp | 38 +- src/lib/pubkey/mce/mce_kem.h | 6 +- src/lib/pubkey/mce/mceliece.cpp | 173 ++++----- src/lib/pubkey/mce/mceliece.h | 203 +++++------ src/lib/pubkey/mce/mceliece_key.cpp | 75 ++-- src/lib/pubkey/mce/mceliece_key.h | 126 ------- src/lib/pubkey/mce/polyn_gf2m.cpp | 38 +- src/lib/pubkey/mce/polyn_gf2m.h | 26 +- src/lib/pubkey/mce/workfactor.cpp | 5 +- src/lib/pubkey/mceies/mceies.cpp | 25 +- src/lib/pubkey/mceies/mceies.h | 12 +- src/lib/pubkey/pk_algs.cpp | 14 + src/lib/rng/hmac_drbg/hmac_drbg.cpp | 2 +- src/tests/data/pubkey/mce.vec | 58 +++ src/tests/test_gf2m.cpp | 46 +++ src/tests/test_mce.cpp | 96 +++++ src/tests/test_mceliece.cpp | 91 +---- src/tests/tests.cpp | 2 + src/tests/tests.h | 2 + 36 files changed, 1402 insertions(+), 1293 deletions(-) create mode 100644 doc/manual/mceliece.rst create mode 100644 src/cmd/mce.cpp delete mode 100644 src/lib/pubkey/mce/binary_matrix.cpp delete mode 100644 src/lib/pubkey/mce/binary_matrix.h delete mode 100644 src/lib/pubkey/mce/code_based_key_gen.h delete mode 100644 src/lib/pubkey/mce/gf2m_rootfind_dcmp.h delete mode 100644 src/lib/pubkey/mce/goppa_code.h create mode 100644 src/lib/pubkey/mce/mce_internal.h delete mode 100644 src/lib/pubkey/mce/mceliece_key.h create mode 100644 src/tests/data/pubkey/mce.vec create mode 100644 src/tests/test_gf2m.cpp create mode 100644 src/tests/test_mce.cpp (limited to 'src/lib') diff --git a/doc/manual/contents.rst b/doc/manual/contents.rst index b0bc04e57..f69b7d77e 100644 --- a/doc/manual/contents.rst +++ b/doc/manual/contents.rst @@ -12,6 +12,7 @@ Contents rng filters pubkey + mceliece x509 ocsp tls diff --git a/doc/manual/mceliece.rst b/doc/manual/mceliece.rst new file mode 100644 index 000000000..51fa084e7 --- /dev/null +++ b/doc/manual/mceliece.rst @@ -0,0 +1,74 @@ +McEliece +======================================== + +McEliece is a cryptographic scheme based on error correcting codes which is +thought to be resistent to quantum computers. First proposed in 1978, it is fast +and patent-free. Variants have been proposed and broken, but with suitable +parameters the original scheme remains secure. However the public keys are quite +large, which has hindered deployment in the past. + +The implementation of McEliece in Botan was contributed by cryptosource GmbH. It +is based on the implementation HyMES, with the kind permission of Nicolas +Sendrier and INRIA to release a C++ adaption of their original C code under the +Botan license. It was then modified by Falko Strenzke to add side channel and +fault attack countermeasures. You can read more about the implementation at +http://www.cryptosource.de/docs/mceliece_in_botan.pdf + +Encryption in the McEliece scheme consists of choosing a message block of size +`n`, encoding it in the error correcting code which is the public key, then +adding `t` bit errors. The code is created such that knowing only the public +key, decoding `t` errors is intractible, but with the additional knowledge of +the secret structure of the code a fast decoding technique exists. + +The McEliece implementation in HyMES, and also in Botan, uses an optimization to +reduce the public key size, by converting the public key into a systemic code. +This means a portion of the public key is a identity matrix, and can be excluded +from the published public key. However it also means that in McEliece the +plaintext is represented directly in the ciphertext, with only a small number of +bit errors. Thus it is absolutely essential to only use McEliece with a CCA2 +secure scheme. + +One such scheme, KEM, is provided in Botan currently. It it a somewhat unusual +scheme in that it outputs two values, a symmetric key for use with an AEAD, and +an encrypted key. It does this by choosing a random plaintext (n - log2(n)*t +bits) using ``McEliece_PublicKey::random_plaintext_element``. Then a random +error mask is chosen and the message is coded and masked. The symmetric key is +SHA-512(plaintext || error_mask). As long as the resulting key is used with a +secure AEAD scheme (which can be used for transporting arbitrary amounts of +data), CCA2 security is provided. + +In ``mcies.h`` there are functions for this combination: + +.. cpp:function:: secure_vector mceies_encrypt(const McEliece_PublicKey& pubkey, \ + const secure_vector& pt, \ + byte ad[], size_t ad_len, \ + RandomNumberGenerator& rng, \ + const std::string& aead = "AES-256/OCB") + +.. cpp:function:: secure_vector mceies_decrypt(const McEliece_PrivateKey& privkey, \ + const secure_vector& ct, \ + byte ad[], size_t ad_len, \ + const std::string& aead = "AES-256/OCB") + +For a given security level (SL) a McEliece key would use +parameters n and t, and have the cooresponding key sizes listed: + ++-----+------+-----+--------------------------------+ +| SL | n | t | public key KB | private key KB | ++=====+======+=====+===============+================+ +| 80 | 1632 | 33 | 59 | 140 | ++-----+------+-----+---------------+----------------+ +| 107 | 2280 | 45 | 128 | 300 | ++-----+------+-----+---------------+----------------+ +| 128 | 2960 | 57 | 195 | 459 | ++-----+------+-----+---------------+----------------+ +| 147 | 3408 | 67 | 265 | 622 | ++-----+------+-----+---------------+----------------+ +| 191 | 4624 | 95 | 516 | 1234 | ++-----+------+-----+---------------+----------------+ +| 256 | 6624 | 115 | 942 | 2184 | ++-----+------+-----+---------------+----------------+ + +You can check the speed of McEliece with the suggested parameters above +using ``botan speed McEliece``, and can encrypt files using the ``botan mce`` +command. diff --git a/src/cmd/implementation/speed_public_key.cpp b/src/cmd/implementation/speed_public_key.cpp index 73bbd7c1e..83c0156ae 100644 --- a/src/cmd/implementation/speed_public_key.cpp +++ b/src/cmd/implementation/speed_public_key.cpp @@ -734,20 +734,21 @@ void benchmark_mce(RandomNumberGenerator& rng, Benchmark_Report& report) { const std::vector> 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); @@ -776,9 +777,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); 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 +#include +#include +#include + +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 priv = PKCS8::BER_encode(pk); + std::vector 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 p8(X509::load_key(argv[3])); + const McEliece_PublicKey* key = dynamic_cast(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(in)), std::istreambuf_iterator()); + + secure_vector ct = mceies_encrypt(*key, + reinterpret_cast(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(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 p8(PKCS8::load_key(key_file, rng, pass)); + const McEliece_PrivateKey* key = dynamic_cast(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(in)), std::istreambuf_iterator()); + + secure_vector pt = mceies_decrypt(*key, + reinterpret_cast(ct.data()), + ct.size(), + nullptr, 0, "AES-128/GCM"); + + std::ofstream out("mce.plaintext", std::ios::binary); + out.write(reinterpret_cast(pt.data()), pt.size()); + out.close(); + } + return 0; + } + +} + +REGISTER_APP(mce); + +#endif diff --git a/src/lib/pubkey/mce/binary_matrix.cpp b/src/lib/pubkey/mce/binary_matrix.cpp deleted file mode 100644 index 45c9aab13..000000000 --- a/src/lib/pubkey/mce/binary_matrix.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/** - * (C) Copyright Projet SECRET, INRIA, Rocquencourt - * (C) Bhaskar Biswas and Nicolas Sendrier - * - * (C) 2014 cryptosource GmbH - * (C) 2014 Falko Strenzke fstrenzke@cryptosource.de - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#include - -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(m_rown * m_rwdcnt); - } - -void binary_matrix::row_xor(u32bit a, u32bit b) - { - u32bit i; - for(i=0;i binary_matrix::row_reduced_echelon_form() - { - u32bit i, failcnt, findrow, max=m_coln - 1; - - secure_vector perm(m_coln); - for(i=0;i=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 fstrenzke@cryptosource.de - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#ifndef BOTAN_BINARY_MATRIX_H__ -#define BOTAN_BINARY_MATRIX_H__ - -#include - -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 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 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 -#include -#include -#include +#include +#include #include -#include namespace Botan { namespace { +struct binary_matrix + { + public: + binary_matrix(u32bit m_rown, u32bit m_coln); + + void row_xor(u32bit a, u32bit b); + secure_vector 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(1) << ((j) % 32)) ; + }; + + void toggle_coeff(u32bit i, u32bit j) + { + m_elem[(i) * m_rwdcnt + (j) / 32] ^= (static_cast(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 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(m_rown * m_rwdcnt); + } + +void binary_matrix::row_xor(u32bit a, u32bit b) + { + u32bit i; + for(i=0;i binary_matrix::row_reduced_echelon_form() + { + u32bit i, failcnt, findrow, max=m_coln - 1; + + secure_vector perm(m_coln); + for(i=0;i=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 & 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(&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 & L, RandomNumberGenerator & } } -std::unique_ptr generate_R(std::vector &L, polyn_gf2m* g, std::shared_ptr sp_field, u32bit code_length, u32bit t ) +std::unique_ptr generate_R(std::vector &L, polyn_gf2m* g, std::shared_ptr 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 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 sp_field ( new Gf2m_Field(ext_deg )); + std::shared_ptr sp_field ( new GF2m_Field(ext_deg )); //pick the support......... std::vector 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 fstrenzke@cryptosource.de - * - * 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 - -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 +#include 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 -#include +#include #include -#include +#include -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 find_roots(const polyn_gf2m & sigma); - u32bit get_code_length() const { return code_length; }; - u32bit code_length; - secure_vector m_Lik; // size is outer_summands * m - secure_vector 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 find_roots(const polyn_gf2m & sigma); + u32bit get_code_length() const { return code_length; }; + u32bit code_length; + secure_vector m_Lik; // size is outer_summands * m + secure_vector 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 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 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 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(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(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 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(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 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(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(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(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 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 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_decomp_rootfind_state::find_roots(const polyn_gf2m & sigma) + { + secure_vector 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(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_decomp_rootfind_state::find_roots(const polyn_gf2m & sigma) -{ - - secure_vector 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(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 fstrenzke@cryptosource.de - * - * Botan is released under the Simplified BSD License (see license.txt) - */ - -#ifndef BOTAN_GF2M_ROOTFIND_DCMP_H__ -#define BOTAN_GF2M_ROOTFIND_DCMP_H__ - -#include - -namespace Botan { - -/** -* Find the roots of a polynomial over GF(2^m) using the method by Federenko -* et al. -*/ -secure_vector 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 -#include #include #include 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 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 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& exp_table(size_t deg) { - gf2m result; - result = mem[0] << 8; - result |= mem[1]; - return result; + static std::vector 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 gf_log_table(size_t deg, const std::vector& exp) { - m_gf_exp_table.resize(1 << get_extension_degree()); + std::vector 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& log_table(size_t deg) { - m_gf_log_table.resize(1 << get_extension_degree()); + static std::vector 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(m_gf_log_table[x]) - static_cast( m_gf_log_table[y]); - s32bit modq_res = static_cast(_gf_modq_1(sub_res)); - s32bit div_res = static_cast(x) ? static_cast(m_gf_exp_table[modq_res]) : 0; + const s32bit sub_res = static_cast(gf_log(x) - static_cast(gf_log(y))); + const s32bit modq_res = static_cast(_gf_modq_1(sub_res)); + const s32bit div_res = static_cast(x) ? static_cast(gf_exp(modq_res)) : 0; return static_cast(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 m_gf_log_table; - std::vector 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(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& m_gf_log_table; + const std::vector& 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 - -#include -#include +#include +#include namespace Botan { @@ -48,7 +46,7 @@ secure_vector goppa_decode(const polyn_gf2m & syndrom_polyn, u32bit code_length = Linv.size(); u32bit t = g.get_degree(); - std::shared_ptr sp_field = g.get_sp_field(); + std::shared_ptr sp_field = g.get_sp_field(); std::pair h__aux = polyn_gf2m::eea_with_coefficients( syndrom_polyn, g, 1); polyn_gf2m & h = h__aux.first; @@ -125,6 +123,37 @@ secure_vector goppa_decode(const polyn_gf2m & syndrom_polyn, } } +void mceliece_decrypt(secure_vector& plaintext_out, + secure_vector& error_mask_out, + const secure_vector& ciphertext, + const McEliece_PrivateKey& key) + { + mceliece_decrypt(plaintext_out, error_mask_out, ciphertext.data(), ciphertext.size(), key); + } + +void mceliece_decrypt( + secure_vector& plaintext, + secure_vector & error_mask, + const byte ciphertext[], + size_t ciphertext_len, + const McEliece_PrivateKey & key) + { + secure_vector error_pos; + plaintext = mceliece_decrypt(error_pos, ciphertext, ciphertext_len, key); + + const size_t code_length = key.get_code_length(); + secure_vector 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 mceliece_decrypt( throw Invalid_Argument("mce-decryption: wrong length of cleartext buffer"); } - secure_vector 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 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 cleartext(cleartext_len); copy_mem(cleartext.data(), ciphertext, cleartext_len); @@ -192,6 +218,7 @@ secure_vector 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 fstrenzke@cryptosource.de - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#ifndef BOTAN_MCE_GOPPA_CODE_H__ -#define BOTAN_MCE_GOPPA_CODE_H__ - -#include -#include - -namespace Botan { - -std::vector mceliece_encrypt(const secure_vector& cleartext, - const std::vector& public_matrix, - const secure_vector & err_pos, - u32bit code_length); - -secure_vector mceliece_decrypt(secure_vector & 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 -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 -binary_matrix.h -code_based_key_gen.h +code_based_util.h +mce_internal.h + + +sha2_64 + 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 fstrenzke@cryptosource.de + * + * Botan is released under the Simplified BSD License (see license.txt) + * + */ + +#ifndef BOTAN_MCELIECE_INTERNAL_H__ +#define BOTAN_MCELIECE_INTERNAL_H__ + +#include +#include +#include +#include + +namespace Botan { + +void mceliece_decrypt(secure_vector& plaintext_out, + secure_vector& error_mask_out, + const byte ciphertext[], + size_t ciphertext_len, + const McEliece_PrivateKey& key); + +void mceliece_decrypt(secure_vector& plaintext_out, + secure_vector& error_mask_out, + const secure_vector& ciphertext, + const McEliece_PrivateKey& key); + +secure_vector mceliece_decrypt( + secure_vector & error_pos, + const byte *ciphertext, u32bit ciphertext_len, + const McEliece_PrivateKey & key); + +void mceliece_encrypt(secure_vector& ciphertext_out, + secure_vector& error_mask_out, + const secure_vector& 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 +#include #include 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> McEliece_KEM_Encryptor::encrypt(RandomNumberGenerator& rng) { - const McEliece_PublicKey& key = m_raw_pub_op.get_key(); - secure_vector plaintext((key.get_message_word_bit_length()+7)/8); - rng.randomize(plaintext.data(), plaintext.size()); + const secure_vector 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 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 message_and_error_input = parts.get_concat(); + secure_vector 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 sym_key = hash.final(); - secure_vector 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 McEliece_KEM_Decryptor::decrypt(const byte msg[], size_t msg_len) { - secure_vector message_and_error = m_raw_priv_op.decrypt(msg, msg_len); + secure_vector 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 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> 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 decrypt_vec(const std::vector& 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 08b3f13a3..dd05b8212 100644 --- a/src/lib/pubkey/mce/mceliece.cpp +++ b/src/lib/pubkey/mce/mceliece.cpp @@ -9,164 +9,127 @@ * */ +#include #include -#include -#include -#include -#include -#include +#include #include +#include namespace Botan { namespace { -void concat_vectors(byte* x, const byte* a, const byte* b, u32bit dimension, u32bit codimension) +secure_vector concat_vectors(const secure_vector& a, const secure_vector& b, + u32bit dimension, u32bit codimension) { - if(dimension % 8 == 0) + secure_vector 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(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(a[l] & ((1 << final_bits) - 1)); + + for(u32bit k = 0; k < codimension / 8; ++k) { - x[l] ^= static_cast(b[k] << i); + x[l] ^= static_cast(b[k] << final_bits); ++l; - x[l] = static_cast(b[k] >> j); + x[l] = static_cast(b[k] >> (8 - final_bits)); } - x[l] ^= static_cast(b[k] << i); + x[l] ^= static_cast(b[codimension/8] << final_bits); } + + return x; } -std::vector mult_by_pubkey(const byte *cleartext, - std::vector const& public_matrix, - u32bit code_length, u32bit t) +secure_vector mult_by_pubkey(const secure_vector& cleartext, + std::vector const& public_matrix, + u32bit code_length, u32bit t) { - std::vector 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 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 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 ciphertext = concat_vectors(cleartext, cR, dimension, codimension); + ciphertext.resize((code_length+7)/8); return ciphertext; } -} - -secure_vector create_random_error_positions(unsigned code_length, - unsigned error_weight, - RandomNumberGenerator& rng) - { - secure_vector 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 create_random_error_vector(unsigned code_length, + unsigned error_weight, + RandomNumberGenerator& rng) { - } - -secure_vector McEliece_Private_Operation::decrypt(const byte msg[], size_t msg_len) - { - secure_vector err_pos; + secure_vector result((code_length+7)/8); - secure_vector 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 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 err_pos = parts.get_error_positions(); - secure_vector message_word = parts.get_message_word(); - secure_vector 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 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 mceliece_encrypt(const secure_vector & cleartext, - std::vector const& public_matrix, - const secure_vector & err_pos, - u32bit code_length) +} + +void mceliece_encrypt(secure_vector& ciphertext_out, + secure_vector& error_mask_out, + const secure_vector& plaintext, + const McEliece_PublicKey& key, + RandomNumberGenerator& rng) { - std::vector ciphertext = mult_by_pubkey(cleartext.data(), public_matrix, code_length, err_pos.size()); + secure_vector 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 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 -#include -#include -#include - -#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 +#include +#include namespace Botan { -secure_vector 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& key_bits); - mceliece_message_parts(const secure_vector& 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& err_pos, const secure_vector& 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 error_vector_from_error_positions(const gf2m* err_pos, size_t err_pos_len, size_t code_length) - { - secure_vector 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(err_vec_start_pos); - copy_mem(m_message_word.data(), message_concat_errors, err_vec_start_pos); - m_error_vector = secure_vector(err_vec_len); - copy_mem(m_error_vector.data(), &message_concat_errors[err_vec_start_pos], err_vec_len); - } - - secure_vector get_concat() const - { - secure_vector 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 get_error_positions() const - { - secure_vector 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 get_error_vector() const { return m_error_vector; } - secure_vector get_message_word() const { return m_message_word; } - private: - secure_vector m_error_vector; - secure_vector m_message_word; - unsigned m_code_length; - }; + McEliece_PublicKey(std::vector 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 random_plaintext_element(RandomNumberGenerator& rng) const; - secure_vector 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 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& 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 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& key_bits); + + McEliece_PrivateKey(polyn_gf2m const& goppa_polyn, + std::vector const& parity_check_matrix_coeffs, + std::vector const& square_root_matrix, + std::vector const& inverse_support, + std::vector 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 encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&) override; + polyn_gf2m const& get_goppa_polyn() const { return m_g; } + std::vector const& get_H_coeffs() const { return m_coeffs; } + std::vector const& get_Linv() const { return m_Linv; } + std::vector 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 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 m_sqrtmod; + std::vector m_Linv; + std::vector 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 -#include -#include #include -#include -#include +#include +#include +#include #include #include -#include 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 McEliece_PublicKey::random_plaintext_element(RandomNumberGenerator& rng) const + { + const size_t bits = get_message_word_bit_length(); + + secure_vector 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()); @@ -55,16 +69,15 @@ AlgorithmIdentifier McEliece_PublicKey::algorithm_identifier() const std::vector McEliece_PublicKey::x509_subject_public_key() const { - // encode the public key - return unlock(DER_Encoder() - .start_cons(SEQUENCE) - .start_cons(SEQUENCE) - .encode(static_cast(get_code_length())) - .encode(static_cast(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(get_code_length())) + .encode(static_cast(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& key_bits) @@ -135,19 +146,20 @@ secure_vector 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 plaintext = this->random_plaintext_element(rng); - secure_vector plaintext((this->get_message_word_bit_length()+7)/8); - rng.randomize(plaintext.data(), plaintext.size() - 1); - const secure_vector err_pos = create_random_error_positions(this->get_code_length(), this->get_t(), rng); + secure_vector ciphertext; + secure_vector errors; + mceliece_encrypt(ciphertext, errors, plaintext, *this, rng); - mceliece_message_parts parts(err_pos, plaintext, this->get_code_length()); - secure_vector message_and_error_input = parts.get_concat(); - secure_vector ciphertext = pub_op.encrypt(message_and_error_input.data(), message_and_error_input.size(), rng); - secure_vector message_and_error_output = priv_op.decrypt(ciphertext.data(), ciphertext.size()); + secure_vector plaintext_out; + secure_vector 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& key_bits) @@ -172,7 +184,7 @@ McEliece_PrivateKey::McEliece_PrivateKey(const secure_vector& key_bits) m_codimension = (ext_deg * t); m_dimension = (n - m_codimension); - std::shared_ptr sp_field(new gf2m_small_m::Gf2m_Field(ext_deg)); + std::shared_ptr sp_field(new GF2m_Field(ext_deg)); m_g = polyn_gf2m(g_enc, sp_field); if(m_g.get_degree() != static_cast(t)) { @@ -231,7 +243,6 @@ McEliece_PrivateKey::McEliece_PrivateKey(const secure_vector& key_bits) } - bool McEliece_PrivateKey::operator==(const McEliece_PrivateKey & other) const { if(*static_cast(this) != *static_cast(&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 fstrenzke@cryptosource.de - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#ifndef BOTAN_MCELIECE_KEY_H__ -#define BOTAN_MCELIECE_KEY_H__ - -#include -#include -#include - -namespace Botan { - -class BOTAN_DLL McEliece_PublicKey : public virtual Public_Key - { - public: - - McEliece_PublicKey(const std::vector& key_bits); - - McEliece_PublicKey(std::vector 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 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 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 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& key_bits); - - McEliece_PrivateKey(polyn_gf2m const& goppa_polyn, - std::vector const& parity_check_matrix_coeffs, - std::vector const& square_root_matrix, - std::vector const& inverse_support, - std::vector 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 const& get_H_coeffs() const { return m_coeffs; }; - std::vector const& get_Linv() const { return m_Linv; }; - std::vector 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 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 m_sqrtmod; - std::vector m_Linv; - std::vector 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..9133f9174 100644 --- a/src/lib/pubkey/mce/polyn_gf2m.cpp +++ b/src/lib/pubkey/mce/polyn_gf2m.cpp @@ -10,15 +10,13 @@ */ #include -#include -#include -#include +#include #include +#include +#include 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 sp_field) +polyn_gf2m::polyn_gf2m( int d, std::shared_ptr 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(new_size); } -polyn_gf2m::polyn_gf2m(const byte* mem, u32bit mem_len, std::shared_ptr sp_field) +polyn_gf2m::polyn_gf2m(const byte* mem, u32bit mem_len, std::shared_ptr 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_ptrm_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 sp_field ) +polyn_gf2m::polyn_gf2m( std::shared_ptr 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 sp_field) +polyn_gf2m::polyn_gf2m(int degree, const unsigned char* mem, u32bit mem_byte_len, std::shared_ptr 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 sp_field) +static gf2m eval_aux(const gf2m * /*restrict*/ coeff, gf2m a, int d, std::shared_ptr 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 msp_field = g.msp_field; + std::shared_ptr 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 & sq, int d) { int i, j; gf2m la; - std::shared_ptr sp_field = this->msp_field; + std::shared_ptr 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::eea_with_coefficients( const polyn_gf2m & p, const polyn_gf2m & g, int break_deg) { - std::shared_ptr msp_field = g.msp_field; + std::shared_ptr msp_field = g.msp_field; int i, j, dr, du, delta; gf2m a; polyn_gf2m aux; @@ -625,7 +621,7 @@ std::pair 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 sp_field) +polyn_gf2m::polyn_gf2m(int t, Botan::RandomNumberGenerator& rng, std::shared_ptr 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 msp_field = g.msp_field; + std::shared_ptr 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::sqrt_mod_init(const polyn_gf2m & g) { u32bit i, t; u32bit nb_polyn_sqrt_mat; - std::shared_ptr msp_field = g.msp_field; + std::shared_ptr msp_field = g.msp_field; std::vector result; t = g.get_degree(); nb_polyn_sqrt_mat = t/2; @@ -717,7 +713,7 @@ std::vector syndrome_init(polyn_gf2m const& generator, std::vector msp_field = generator.msp_field; + std::shared_ptr msp_field = generator.msp_field; std::vector result; t = generator.get_degree(); @@ -744,7 +740,7 @@ std::vector syndrome_init(polyn_gf2m const& generator, std::vector& encoded, std::shared_ptr sp_field ) +polyn_gf2m::polyn_gf2m(const secure_vector& encoded, std::shared_ptr 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 #include -#include #include #include 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 sp_field ); + polyn_gf2m( std::shared_ptr sp_field ); polyn_gf2m() :m_deg(-1) {}; - polyn_gf2m(const secure_vector& encoded, std::shared_ptr sp_field ); + polyn_gf2m(const secure_vector& encoded, std::shared_ptr 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 sp_field); + polyn_gf2m(int d, std::shared_ptr 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 sp_field); + polyn_gf2m(int t, RandomNumberGenerator& rng, std::shared_ptr sp_field); - std::shared_ptr get_sp_field() const + std::shared_ptr 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 sp_field); + polyn_gf2m(const byte* mem, u32bit mem_len, std::shared_ptr 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 sp_field); + polyn_gf2m(int degree, const unsigned char* mem, u32bit mem_byte_len, std::shared_ptr 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 coeff; - std::shared_ptr msp_field; + std::shared_ptr msp_field; }; gf2m random_code_element(unsigned code_length, RandomNumberGenerator& rng); std::vector syndrome_init(polyn_gf2m const& generator, std::vector const& support, int n); +/** +* Find the roots of a polynomial over GF(2^m) using the method by Federenko +* et al. +*/ +secure_vector 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 +#include #include 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 aead_key(const secure_vector& mk, secure_vector mceies_encrypt(const McEliece_PublicKey& pubkey, - const secure_vector& 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(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 nonce = rng.random_vec(nonce_len); - secure_vector msg(mce_ciphertext.size() + nonce.size() + pt.size()); + secure_vector 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 mceies_decrypt(const McEliece_PrivateKey& privkey, - const secure_vector& 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(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 mce_key = kem_op.decrypt(ct.data(), mce_code_bytes); + const secure_vector 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 pt(ct.begin() + mce_code_bytes + nonce_len, ct.end()); + secure_vector 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 BOTAN_DLL mceies_encrypt(const McEliece_PublicKey& pubkey, - const secure_vector& 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 BOTAN_DLL mceies_decrypt(const McEliece_PrivateKey& privkey, - const secure_vector& 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 #endif +#if defined(BOTAN_HAS_MCELIECE) + #include +#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/rng/hmac_drbg/hmac_drbg.cpp b/src/lib/rng/hmac_drbg/hmac_drbg.cpp index 22236c0cb..ad731b6b3 100644 --- a/src/lib/rng/hmac_drbg/hmac_drbg.cpp +++ b/src/lib/rng/hmac_drbg/hmac_drbg.cpp @@ -23,12 +23,12 @@ HMAC_DRBG::HMAC_DRBG(MessageAuthenticationCode* mac, HMAC_DRBG::HMAC_DRBG(const std::string& mac_name, RandomNumberGenerator* prng) : m_prng(prng), - m_V(m_mac->output_length(), 0x01), m_reseed_counter(0) { m_mac = MessageAuthenticationCode::create(mac_name); if(!m_mac) throw Algorithm_Not_Found(mac_name); + m_V = secure_vector(m_mac->output_length(), 0x01), m_mac->set_key(std::vector(m_mac->output_length(), 0x00)); } 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_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_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_mce.cpp b/src/tests/test_mce.cpp new file mode 100644 index 000000000..cd85cdab1 --- /dev/null +++ b/src/tests/test_mce.cpp @@ -0,0 +1,96 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "tests.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace Botan; + +namespace { + +std::string hash_bytes(const byte b[], size_t len) + { + std::unique_ptr hash(HashFunction::create("SHA-256")); + hash->update(b, len); + return hex_encode(hash->final()); + } + +template +std::string hash_bytes(const std::vector& 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 keygen_seed = hex_decode_locked(key_seed_hex); + const secure_vector 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 > ciphertext__sym_key = kem_enc.encrypt(rng); + const secure_vector& ciphertext = ciphertext__sym_key.first; + const secure_vector& sym_key_encr = ciphertext__sym_key.second; + + const secure_vector 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 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"]); + }); + } diff --git a/src/tests/test_mceliece.cpp b/src/tests/test_mceliece.cpp index 616f64be9..a82588a8f 100644 --- a/src/tests/test_mceliece.cpp +++ b/src/tests/test_mceliece.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -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 err_pos1 = create_random_error_positions(code_length, error_weight, rng); - secure_vector message1((code_length+7)/8); - rng.randomize(message1.data(), message1.size() - 1); - mceliece_message_parts parts1(err_pos1, message1, code_length); - secure_vector err_vec1 = parts1.get_error_vector(); - - secure_vector concat1 = parts1.get_concat(); - - mceliece_message_parts parts2( concat1.data(), concat1.size(), code_length); - - secure_vector 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 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 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 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 plaintext((pk.get_message_word_bit_length()+7)/8); - rng.randomize(plaintext.data(), plaintext.size() - 1); + const secure_vector plaintext = pk.random_plaintext_element(rng); secure_vector err_pos = create_random_error_positions(code_length, pk.get_t(), rng); - mceliece_message_parts parts(err_pos, plaintext, code_length); secure_vector message_and_error_input = parts.get_concat(); secure_vector ciphertext = pub_op.encrypt(message_and_error_input.data(), message_and_error_input.size(), rng); @@ -158,6 +106,7 @@ size_t test_mceliece_raw(const McEliece_PrivateKey& sk, return err_cnt; } +*/ #if defined(BOTAN_HAS_MCEIES) size_t test_mceies(const McEliece_PrivateKey& sk, @@ -173,8 +122,8 @@ size_t test_mceies(const McEliece_PrivateKey& sk, const size_t ad_len = sizeof(ad); const secure_vector pt = rng.random_vec(rng.next_byte()); - const secure_vector ct = mceies_encrypt(pk, pt, ad, ad_len, rng); - const secure_vector dec = mceies_decrypt(sk, ct, ad, ad_len); + const secure_vector ct = mceies_encrypt(pk, pt.data(), pt.size(), ad, ad_len, rng); + const secure_vector dec = mceies_decrypt(sk, ct.data(), ct.size(), ad, ad_len); if(pt != dec) { @@ -195,7 +144,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; } @@ -232,18 +181,7 @@ size_t test_mceliece() size_t code_length = params__n__t_min_max[i]; for(size_t t = params__n__t_min_max[i+1]; t <= params__n__t_min_max[i+2]; t++) { - //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; + std::cout << "testing parameters n = " << code_length << ", t = " << t << std::endl; McEliece_PrivateKey sk1(rng, code_length, t); const McEliece_PublicKey& pk1 = sk1; @@ -272,17 +210,6 @@ size_t test_mceliece() ++fails; } - 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); diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 763417209..d213b6a3a 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -301,7 +301,9 @@ 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); diff --git a/src/tests/tests.h b/src/tests/tests.h index 14ec5a17b..6d6a2d34c 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -142,7 +142,9 @@ 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(); -- cgit v1.2.3 From 7bbee7e62e65d5de1d46b912b73440070feab0ff Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 1 Oct 2015 16:59:47 -0400 Subject: Export X.509 certificates to ffi and python Missing path validation, probably other things --- src/lib/cert/x509/key_constraint.h | 1 + src/lib/ffi/ffi.cpp | 155 ++++++++++++++++++++++++++++++++- src/lib/ffi/ffi.h | 125 ++++++++++++++++++++++++--- src/lib/ffi/info.txt | 1 + src/python/botan.py | 170 ++++++++++++++++++++++++++++--------- 5 files changed, 396 insertions(+), 56 deletions(-) (limited to 'src/lib') 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/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 606415575..608bd291b 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -161,12 +163,14 @@ 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); + /* * Versioning */ uint32_t botan_ffi_api_version() { - return 20150210; // should match value in info.txt + return BOTAN_HAS_FFI; } const char* botan_version_string() @@ -636,7 +640,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, @@ -654,9 +657,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) { @@ -674,6 +681,7 @@ int botan_bcrypt_is_valid(const char* pass, const char* hash) { try { + #define BOTAN_ if(Botan::check_bcrypt(pass, hash)) return 0; // success return 1; @@ -690,8 +698,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 @@ -1137,5 +1143,146 @@ 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 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 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) + { + *key = nullptr; + return -1; + //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(key_usage); + if(cert.allowed_usage(k)) + return 0; + return 1; + }); + } + } diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h index a516529b4..1402ec129 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,46 @@ extern "C" { #endif -#include -#include -#include - /* +This header exports some of botan's functionality via a C89 interface. 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). + +- No ownership of memory transfers across the API boundary. The API will write + to buffers provided by the caller, or return opaque pointers which may not be + dereferenced. + +- 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 it is insufficient, an + error is returned. So passing nullptr/0 + +This API is uesd by the Python and OCaml bindings via those languages respective +ctypes libraries. + +The API is not currently documented, nor should it be considered stable. It is +buggy as heck, most likely. 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 +#include +#include + /* * Versioning */ @@ -37,11 +65,30 @@ 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__); + +#define botan_make_error_inf(s) return botan_make_error(s, BOTAN_FUNCTION, __LINE__); + +* +* Later call: +* const char* botan_get_error_str(int); +* To recover the msg, func, and line + */ #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); @@ -53,6 +100,9 @@ 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 @@ -198,8 +248,6 @@ BOTAN_DLL int botan_kdf(const char* kdf_algo, /* * Bcrypt */ -#if defined(BOTAN_HAS_BCRYPT) - BOTAN_DLL int botan_bcrypt_generate(uint8_t* out, size_t* out_len, const char* pass, botan_rng_t rng, @@ -213,8 +261,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, ... */ @@ -359,6 +405,63 @@ 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); + +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) */ @@ -368,6 +471,7 @@ 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 // TODO: peer certs, validation, ... typedef struct botan_tls_channel_struct* botan_tls_channel_t; @@ -401,7 +505,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..52885e8e1 100644 --- a/src/lib/ffi/info.txt +++ b/src/lib/ffi/info.txt @@ -6,6 +6,7 @@ filters kdf pbkdf pubkey +x509 auto_rng system_rng diff --git a/src/python/botan.py b/src/python/botan.py index a28f3ddb0..054130b80 100755 --- a/src/python/botan.py +++ b/src/python/botan.py @@ -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 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,7 @@ class public_key(object): def algo_name(self): botan.botan_pubkey_algo_name.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)] - - 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] + return _call_fn_returning_string(32, lambda b,bl: botan.botan_pubkey_algo_name(self.pubkey, b, bl)) def fingerprint(self, hash = 'SHA-256'): botan.botan_pubkey_fingerprint.argtypes = [c_void_p, c_char_p, @@ -338,7 +366,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]) @@ -385,7 +413,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 +444,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] @@ -534,17 +561,68 @@ class pk_op_key_agreement(object): other, len(other), salt, len(salt)) return outbuf.raw[0:outbuf_sz.value] +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)) + + """ 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 +637,16 @@ 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: + 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('x %s' % hexlify(psk).decode('utf-8')) print('y %s\n' % (hexlify(pbkdf('PBKDF2(SHA-256)'.encode('utf-8'), @@ -579,7 +655,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 +663,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'), @@ -645,7 +721,7 @@ def test(): rsapriv = private_key('rsa', 1536, r) rsapub = rsapriv.get_public_key() - + print("rsapub %s/SHA-1 fingerprint: %s (estimated strength %s)" % (rsapub.algo_name().decode('utf-8'), rsapub.fingerprint("SHA-1").decode('utf-8'), rsapub.estimated_strength() @@ -656,7 +732,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 +745,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 +759,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): -- cgit v1.2.3 From 7612e065a76501f7888f62edd10e061bd9e71e2f Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 1 Oct 2015 23:46:00 -0400 Subject: Add McEliece keygen and MCEIES to C89 API. Plus random fiddling --- src/lib/ffi/ffi.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/lib/ffi/ffi.h | 107 +++++++++++++++++++++++++++++++--------- src/lib/ffi/info.txt | 3 +- src/python/botan.py | 84 +++++++++++++++++++++++--------- 4 files changed, 272 insertions(+), 56 deletions(-) (limited to 'src/lib') diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 608bd291b..27dcc6015 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -39,6 +41,15 @@ #include #endif +#if defined(BOTAN_HAS_MCELIECE) + #include +#endif + +#if defined(BOTAN_HAS_MCEIES) + #include +#endif + + #if defined(BOTAN_HAS_BCRYPT) #include #endif @@ -72,6 +83,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 T& safe_get(botan_struct* p) { @@ -108,15 +125,19 @@ int apply_fn(botan_struct* 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 @@ -164,6 +185,7 @@ BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_verify_struct, Botan::PK_Verifier, 0x2B91F9 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); +BOTAN_FFI_DECLARE_STRUCT(botan_tls_channel_struct, Botan::TLS::Channel, 0x0212FE99); /* * Versioning @@ -185,7 +207,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) @@ -681,10 +703,12 @@ int botan_bcrypt_is_valid(const char* pass, const char* hash) { try { - #define BOTAN_ +#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) { @@ -714,6 +738,8 @@ int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size std::unique_ptr 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) @@ -740,6 +766,8 @@ int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, co std::unique_ptr 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) @@ -750,6 +778,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 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 @@ -1250,8 +1303,7 @@ 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) { - *key = nullptr; - return -1; + 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()); }); } @@ -1284,5 +1336,73 @@ int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage }); } +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(&key); + if(!mce) + return -2; + + const Botan::secure_vector 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(&key); + if(!mce) + return -2; + + Botan::secure_vector 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 1402ec129..18a41938b 100644 --- a/src/lib/ffi/ffi.h +++ b/src/lib/ffi/ffi.h @@ -13,10 +13,14 @@ extern "C" { #endif /* -This header exports some of botan's functionality via a C89 interface. 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: +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. @@ -24,20 +28,25 @@ others, so to make things easy this API follows a few simple rules: - All functions return an int error code (except the version calls, which are assumed to always have something to say). -- No ownership of memory transfers across the API boundary. The API will write - to buffers provided by the caller, or return opaque pointers which may not be - dereferenced. +- 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 it is insufficient, an - error is returned. So passing nullptr/0 + 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. -This API is uesd by the Python and OCaml bindings via those languages respective -ctypes libraries. + 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. However the goal is to provide a long term API -usable for language bindings, or for use by systems written in C. Suggestions on +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: @@ -68,6 +77,7 @@ BOTAN_DLL uint32_t botan_version_datestamp(); * * 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. @@ -77,14 +87,26 @@ int botan_make_error(const char* msg, const char* func, int line); 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) @@ -93,7 +115,7 @@ int botan_make_error(const char* msg, const char* func, int line); //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); @@ -271,7 +293,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; @@ -406,6 +429,26 @@ BOTAN_DLL int botan_pk_op_key_agreement(botan_pk_op_ka_t op, 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); @@ -439,7 +482,6 @@ 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); @@ -469,17 +511,29 @@ BOTAN_DLL int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int 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 +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, @@ -497,6 +551,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); diff --git a/src/lib/ffi/info.txt b/src/lib/ffi/info.txt index 52885e8e1..8d6c5237e 100644 --- a/src/lib/ffi/info.txt +++ b/src/lib/ffi/info.txt @@ -1,4 +1,4 @@ -define FFI 20150210 +define FFI 20151001 aead @@ -7,6 +7,7 @@ kdf pbkdf pubkey x509 +#tls auto_rng system_rng diff --git a/src/python/botan.py b/src/python/botan.py index 054130b80..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 @@ -44,7 +44,7 @@ def _call_fn_returning_string(guess, fn): raise Exception("Call failed: %d" % (rc)) assert buf_len.value <= len(buf) - return buf.raw[0:buf_len.value] + return str(buf.raw[0:buf_len.value]) def _call_fn_returning_vec(guess, fn): @@ -357,6 +357,16 @@ class public_key(object): 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)) + 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, POINTER(c_char), POINTER(c_size_t)] @@ -375,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': @@ -383,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) @@ -524,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] @@ -534,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] @@ -550,16 +578,10 @@ 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)) - - 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] + 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): @@ -640,12 +662,8 @@ def test(): (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' % @@ -718,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()) ) ) -- cgit v1.2.3 From 6ab96139fa5bce258972bb3678e4c106c0bfe5bd Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 3 Oct 2015 08:00:56 -0400 Subject: Fix bcrypt test --- src/lib/ffi/ffi.h | 4 +++- src/tests/test_ffi.cpp | 2 +- src/tests/test_mceliece.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/lib') diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h index 18a41938b..ce2253725 100644 --- a/src/lib/ffi/ffi.h +++ b/src/lib/ffi/ffi.h @@ -269,9 +269,11 @@ BOTAN_DLL int botan_kdf(const char* kdf_algo, /* * Bcrypt +* *out_len should be 64 bytes +* Output is formatted bcrypt $2a$... */ 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); diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp index 63f8a5b20..edc06f90a 100644 --- a/src/tests/test_ffi.cpp +++ b/src/tests/test_ffi.cpp @@ -193,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(outbuf.data())), Equals(1)); + REQUIRE(botan_bcrypt_is_valid("wrong", reinterpret_cast(outbuf.data())) < 0); CHECK_THAT(botan_bcrypt_is_valid("password", reinterpret_cast(outbuf.data())), Equals(0)); } diff --git a/src/tests/test_mceliece.cpp b/src/tests/test_mceliece.cpp index 0ed62b5ea..fc20d93f7 100644 --- a/src/tests/test_mceliece.cpp +++ b/src/tests/test_mceliece.cpp @@ -180,7 +180,7 @@ size_t test_mceliece() size_t code_length = params__n__t_min_max[i]; for(size_t t = params__n__t_min_max[i+1]; t <= params__n__t_min_max[i+2]; t++) { - std::cout << "testing parameters n = " << code_length << ", t = " << t << std::endl; + //std::cout << "testing parameters n = " << code_length << ", t = " << t << std::endl; McEliece_PrivateKey sk1(rng, code_length, t); const McEliece_PublicKey& pk1 = sk1; -- cgit v1.2.3 From aad256035d4ecb9c4e87a7698f74f6f3178da0e2 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sun, 11 Oct 2015 11:08:42 -0400 Subject: Add missing null pointer check to PBES2 --- src/lib/misc/pbes2/pbes2.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/lib') diff --git a/src/lib/misc/pbes2/pbes2.cpp b/src/lib/misc/pbes2/pbes2.cpp index ab740ff5d..470e33cb0 100644 --- a/src/lib/misc/pbes2/pbes2.cpp +++ b/src/lib/misc/pbes2/pbes2.cpp @@ -81,6 +81,9 @@ pbes2_encrypt(const secure_vector& key_bits, std::unique_ptr enc(get_cipher_mode(cipher, ENCRYPTION)); + if(!enc) + throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher); + std::unique_ptr pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); const size_t key_length = enc->key_spec().maximum_keylength(); -- cgit v1.2.3 From 29b560eba79631436fa475dde1f18ece434befed Mon Sep 17 00:00:00 2001 From: Daniel Seither Date: Tue, 13 Oct 2015 12:50:31 +0200 Subject: Initial support for 64 bit ARM This adds support for 64 bit ARM cores as used in many high-end phones such as all iPhones beginning with the 5s. While these newer phones still run 32 bit ARM code, Apple doesn't allow apps to be submitted to the app store if they don't provide a 64 bit build. This commit adds a new arm64 arch and renames arm to arm32 to stay consistent with the other architectures. The name arm can still be used for configuring because it has been added as an alias for arm32. Additionally, the one piece of ARM inline assembly that can be found in Botan doesn't work on 64 bit ARM, so I use the solution that has been proposed in #180: Use __builtin_bswap32 instead of inline assembly. --- src/build-data/arch/arm.txt | 45 ------------------------------------------- src/build-data/arch/arm32.txt | 45 +++++++++++++++++++++++++++++++++++++++++++ src/build-data/arch/arm64.txt | 12 ++++++++++++ src/lib/utils/bswap.h | 4 ++-- 4 files changed, 59 insertions(+), 47 deletions(-) delete mode 100644 src/build-data/arch/arm.txt create mode 100644 src/build-data/arch/arm32.txt create mode 100644 src/build-data/arch/arm64.txt (limited to 'src/lib') diff --git a/src/build-data/arch/arm.txt b/src/build-data/arch/arm.txt deleted file mode 100644 index 81ecc05c3..000000000 --- a/src/build-data/arch/arm.txt +++ /dev/null @@ -1,45 +0,0 @@ - -endian little -family arm - - -armel # For Debian -armhf # For Debian -evbarm # For NetBSD - - - -armv2 -armv2a -armv3 -armv3m -armv4 -armv5 -armv5e -armv5te -armv6 -armv6j -armv6t2 -armv6z -armv6zk -armv6-m -armv7 -armv7-a -armv7-r -armv7-m -iwmmxt -iwmmxt2 -ep9312 - - - -strongarm -> armv4 -xscale -> armv5te -cortex-a8 -> armv7-a -cortex-a9 -> armv7-a - - - -neon - - diff --git a/src/build-data/arch/arm32.txt b/src/build-data/arch/arm32.txt new file mode 100644 index 000000000..67be376d6 --- /dev/null +++ b/src/build-data/arch/arm32.txt @@ -0,0 +1,45 @@ +endian little +family arm + + +arm +armel # For Debian +armhf # For Debian +evbarm # For NetBSD + + + +armv2 +armv2a +armv3 +armv3m +armv4 +armv5 +armv5e +armv5te +armv6 +armv6j +armv6t2 +armv6z +armv6zk +armv6-m +armv7 +armv7-a +armv7-r +armv7-m +iwmmxt +iwmmxt2 +ep9312 + + + +strongarm -> armv4 +xscale -> armv5te +cortex-a8 -> armv7-a +cortex-a9 -> armv7-a + + + +neon + + 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 + + +aarch64 + + + +armv8-a + 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" -- cgit v1.2.3 From 39052451400dd9beb12c350d87c2d48ff476210e Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 14 Oct 2015 16:32:17 -0400 Subject: Move DataSource to utils and rewrite PEM encoding to avoid filters Removes filters as as an internal dependency pretty much entirely (outside of some dusty corners in misc). --- src/lib/asn1/info.txt | 1 - src/lib/ffi/info.txt | 1 - src/lib/filters/data_src.cpp | 212 ------------------------------------------- src/lib/filters/data_src.h | 180 ------------------------------------ src/lib/filters/info.txt | 2 - src/lib/misc/pem/info.txt | 2 +- src/lib/misc/pem/pem.cpp | 41 ++++++--- src/lib/pubkey/x509_key.h | 2 +- src/lib/utils/data_src.cpp | 212 +++++++++++++++++++++++++++++++++++++++++++ src/lib/utils/data_src.h | 180 ++++++++++++++++++++++++++++++++++++ src/lib/utils/info.txt | 1 + src/tests/test_modes.cpp | 20 +--- src/tests/test_pubkey.cpp | 11 +-- src/tests/unit_x509.cpp | 23 ++--- 14 files changed, 438 insertions(+), 450 deletions(-) delete mode 100644 src/lib/filters/data_src.cpp delete mode 100644 src/lib/filters/data_src.h create mode 100644 src/lib/utils/data_src.cpp create mode 100644 src/lib/utils/data_src.h (limited to 'src/lib') 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 -filters bigint oid_lookup diff --git a/src/lib/ffi/info.txt b/src/lib/ffi/info.txt index 8d6c5237e..4018e4064 100644 --- a/src/lib/ffi/info.txt +++ b/src/lib/ffi/info.txt @@ -2,7 +2,6 @@ define FFI 20151001 aead -filters kdf pbkdf pubkey diff --git a/src/lib/filters/data_src.cpp b/src/lib/filters/data_src.cpp deleted file mode 100644 index 4e0725943..000000000 --- a/src/lib/filters/data_src.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* -* DataSource -* (C) 1999-2007 Jack Lloyd -* 2005 Matthew Gregan -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include -#include -#include - -namespace Botan { - -/* -* Read a single byte from the DataSource -*/ -size_t DataSource::read_byte(byte& out) - { - return read(&out, 1); - } - -/* -* Peek a single byte from the DataSource -*/ -size_t DataSource::peek_byte(byte& out) const - { - return peek(&out, 1, 0); - } - -/* -* Discard the next N bytes of the data -*/ -size_t DataSource::discard_next(size_t n) - { - byte buf[64] = { 0 }; - size_t discarded = 0; - - while(n) - { - const size_t got = this->read(buf, std::min(n, sizeof(buf))); - discarded += got; - - if(got == 0) - break; - } - - return discarded; - } - -/* -* Read from a memory buffer -*/ -size_t DataSource_Memory::read(byte out[], size_t length) - { - size_t got = std::min(source.size() - offset, length); - copy_mem(out, source.data() + offset, got); - offset += got; - return got; - } - -bool DataSource_Memory::check_available(size_t n) - { - return (n <= (source.size() - offset)); - } - -/* -* Peek into a memory buffer -*/ -size_t DataSource_Memory::peek(byte out[], size_t length, - size_t peek_offset) const - { - const size_t bytes_left = source.size() - offset; - if(peek_offset >= bytes_left) return 0; - - size_t got = std::min(bytes_left - peek_offset, length); - copy_mem(out, &source[offset + peek_offset], got); - return got; - } - -/* -* Check if the memory buffer is empty -*/ -bool DataSource_Memory::end_of_data() const - { - return (offset == source.size()); - } - -/* -* DataSource_Memory Constructor -*/ -DataSource_Memory::DataSource_Memory(const std::string& in) : - source(reinterpret_cast(in.data()), - reinterpret_cast(in.data()) + in.length()), - offset(0) - { - offset = 0; - } - -/* -* Read from a stream -*/ -size_t DataSource_Stream::read(byte out[], size_t length) - { - source.read(reinterpret_cast(out), length); - if(source.bad()) - throw Stream_IO_Error("DataSource_Stream::read: Source failure"); - - size_t got = source.gcount(); - total_read += got; - return got; - } - -bool DataSource_Stream::check_available(size_t n) - { - const std::streampos orig_pos = source.tellg(); - source.seekg(0, std::ios::end); - const size_t avail = source.tellg() - orig_pos; - source.seekg(orig_pos); - return (avail >= n); - } - -/* -* Peek into a stream -*/ -size_t DataSource_Stream::peek(byte out[], size_t length, size_t offset) const - { - if(end_of_data()) - throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); - - size_t got = 0; - - if(offset) - { - secure_vector buf(offset); - source.read(reinterpret_cast(buf.data()), buf.size()); - if(source.bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = source.gcount(); - } - - if(got == offset) - { - source.read(reinterpret_cast(out), length); - if(source.bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = source.gcount(); - } - - if(source.eof()) - source.clear(); - source.seekg(total_read, std::ios::beg); - - return got; - } - -/* -* Check if the stream is empty or in error -*/ -bool DataSource_Stream::end_of_data() const - { - return (!source.good()); - } - -/* -* Return a human-readable ID for this stream -*/ -std::string DataSource_Stream::id() const - { - return identifier; - } - -/* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(const std::string& path, - bool use_binary) : - identifier(path), - source_p(new std::ifstream(path, - use_binary ? std::ios::binary : std::ios::in)), - source(*source_p), - total_read(0) - { - if(!source.good()) - { - delete source_p; - throw Stream_IO_Error("DataSource: Failure opening file " + path); - } - } - -/* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(std::istream& in, - const std::string& name) : - identifier(name), - source_p(nullptr), - source(in), - total_read(0) - { - } - -/* -* DataSource_Stream Destructor -*/ -DataSource_Stream::~DataSource_Stream() - { - delete source_p; - } - -} diff --git a/src/lib/filters/data_src.h b/src/lib/filters/data_src.h deleted file mode 100644 index 2b6998448..000000000 --- a/src/lib/filters/data_src.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -* DataSource -* (C) 1999-2007 Jack Lloyd -* 2012 Markus Wanner -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_DATA_SRC_H__ -#define BOTAN_DATA_SRC_H__ - -#include -#include -#include - -namespace Botan { - -/** -* This class represents an abstract data source object. -*/ -class BOTAN_DLL DataSource - { - public: - /** - * Read from the source. Moves the internal offset so that every - * call to read will return a new portion of the source. - * - * @param out the byte array to write the result to - * @param length the length of the byte array out - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t read(byte out[], size_t length) = 0; - - virtual bool check_available(size_t n) = 0; - - /** - * Read from the source but do not modify the internal - * offset. Consecutive calls to peek() will return portions of - * the source starting at the same position. - * - * @param out the byte array to write the output to - * @param length the length of the byte array out - * @param peek_offset the offset into the stream to read at - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t peek(byte out[], size_t length, - size_t peek_offset) const = 0; - - /** - * Test whether the source still has data that can be read. - * @return true if there is still data to read, false otherwise - */ - virtual bool end_of_data() const = 0; - /** - * return the id of this data source - * @return std::string representing the id of this data source - */ - virtual std::string id() const { return ""; } - - /** - * Read one byte. - * @param out the byte to read to - * @return length in bytes that was actually read and put - * into out - */ - size_t read_byte(byte& out); - - /** - * Peek at one byte. - * @param out an output byte - * @return length in bytes that was actually read and put - * into out - */ - size_t peek_byte(byte& out) const; - - /** - * Discard the next N bytes of the data - * @param N the number of bytes to discard - * @return number of bytes actually discarded - */ - size_t discard_next(size_t N); - - /** - * @return number of bytes read so far. - */ - virtual size_t get_bytes_read() const = 0; - - DataSource() {} - virtual ~DataSource() {} - DataSource& operator=(const DataSource&) = delete; - DataSource(const DataSource&) = delete; - }; - -/** -* This class represents a Memory-Based DataSource -*/ -class BOTAN_DLL DataSource_Memory : public DataSource - { - public: - size_t read(byte[], size_t) override; - size_t peek(byte[], size_t, size_t) const override; - bool check_available(size_t n) override; - bool end_of_data() const override; - - /** - * Construct a memory source that reads from a string - * @param in the string to read from - */ - DataSource_Memory(const std::string& in); - - /** - * Construct a memory source that reads from a byte array - * @param in the byte array to read from - * @param length the length of the byte array - */ - DataSource_Memory(const byte in[], size_t length) : - source(in, in + length), offset(0) {} - - /** - * Construct a memory source that reads from a secure_vector - * @param in the MemoryRegion to read from - */ - DataSource_Memory(const secure_vector& in) : - source(in), offset(0) {} - - /** - * Construct a memory source that reads from a std::vector - * @param in the MemoryRegion to read from - */ - DataSource_Memory(const std::vector& in) : - source(in.begin(), in.end()), offset(0) {} - - size_t get_bytes_read() const override { return offset; } - private: - secure_vector source; - size_t offset; - }; - -/** -* This class represents a Stream-Based DataSource. -*/ -class BOTAN_DLL DataSource_Stream : public DataSource - { - public: - size_t read(byte[], size_t) override; - size_t peek(byte[], size_t, size_t) const override; - bool check_available(size_t n) override; - bool end_of_data() const override; - std::string id() const override; - - DataSource_Stream(std::istream&, - const std::string& id = ""); - - /** - * Construct a Stream-Based DataSource from file - * @param file the name of the file - * @param use_binary whether to treat the file as binary or not - */ - DataSource_Stream(const std::string& file, bool use_binary = false); - - DataSource_Stream(const DataSource_Stream&) = delete; - - DataSource_Stream& operator=(const DataSource_Stream&) = delete; - - ~DataSource_Stream(); - - size_t get_bytes_read() const override { return total_read; } - private: - const std::string identifier; - - std::istream* source_p; - std::istream& source; - size_t total_read; - }; - -} - -#endif 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/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 -codec_filt +base64 diff --git a/src/lib/misc/pem/pem.cpp b/src/lib/misc/pem/pem.cpp index f33016c70..1279b665e 100644 --- a/src/lib/misc/pem/pem.cpp +++ b/src/lib/misc/pem/pem.cpp @@ -6,25 +6,45 @@ */ #include -#include +#include #include 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 +99,7 @@ secure_vector decode(DataSource& source, std::string& label) label += static_cast(b); } - Pipe base64(new Base64_Decoder); - base64.start_msg(); + std::vector b64; const std::string PEM_TRAILER = "-----END " + label + "-----"; position = 0; @@ -95,10 +114,10 @@ secure_vector 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 decode_check_label(const std::string& pem, 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 #include -#include +#include #include namespace Botan { diff --git a/src/lib/utils/data_src.cpp b/src/lib/utils/data_src.cpp new file mode 100644 index 000000000..4e0725943 --- /dev/null +++ b/src/lib/utils/data_src.cpp @@ -0,0 +1,212 @@ +/* +* DataSource +* (C) 1999-2007 Jack Lloyd +* 2005 Matthew Gregan +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* Read a single byte from the DataSource +*/ +size_t DataSource::read_byte(byte& out) + { + return read(&out, 1); + } + +/* +* Peek a single byte from the DataSource +*/ +size_t DataSource::peek_byte(byte& out) const + { + return peek(&out, 1, 0); + } + +/* +* Discard the next N bytes of the data +*/ +size_t DataSource::discard_next(size_t n) + { + byte buf[64] = { 0 }; + size_t discarded = 0; + + while(n) + { + const size_t got = this->read(buf, std::min(n, sizeof(buf))); + discarded += got; + + if(got == 0) + break; + } + + return discarded; + } + +/* +* Read from a memory buffer +*/ +size_t DataSource_Memory::read(byte out[], size_t length) + { + size_t got = std::min(source.size() - offset, length); + copy_mem(out, source.data() + offset, got); + offset += got; + return got; + } + +bool DataSource_Memory::check_available(size_t n) + { + return (n <= (source.size() - offset)); + } + +/* +* Peek into a memory buffer +*/ +size_t DataSource_Memory::peek(byte out[], size_t length, + size_t peek_offset) const + { + const size_t bytes_left = source.size() - offset; + if(peek_offset >= bytes_left) return 0; + + size_t got = std::min(bytes_left - peek_offset, length); + copy_mem(out, &source[offset + peek_offset], got); + return got; + } + +/* +* Check if the memory buffer is empty +*/ +bool DataSource_Memory::end_of_data() const + { + return (offset == source.size()); + } + +/* +* DataSource_Memory Constructor +*/ +DataSource_Memory::DataSource_Memory(const std::string& in) : + source(reinterpret_cast(in.data()), + reinterpret_cast(in.data()) + in.length()), + offset(0) + { + offset = 0; + } + +/* +* Read from a stream +*/ +size_t DataSource_Stream::read(byte out[], size_t length) + { + source.read(reinterpret_cast(out), length); + if(source.bad()) + throw Stream_IO_Error("DataSource_Stream::read: Source failure"); + + size_t got = source.gcount(); + total_read += got; + return got; + } + +bool DataSource_Stream::check_available(size_t n) + { + const std::streampos orig_pos = source.tellg(); + source.seekg(0, std::ios::end); + const size_t avail = source.tellg() - orig_pos; + source.seekg(orig_pos); + return (avail >= n); + } + +/* +* Peek into a stream +*/ +size_t DataSource_Stream::peek(byte out[], size_t length, size_t offset) const + { + if(end_of_data()) + throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); + + size_t got = 0; + + if(offset) + { + secure_vector buf(offset); + source.read(reinterpret_cast(buf.data()), buf.size()); + if(source.bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = source.gcount(); + } + + if(got == offset) + { + source.read(reinterpret_cast(out), length); + if(source.bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = source.gcount(); + } + + if(source.eof()) + source.clear(); + source.seekg(total_read, std::ios::beg); + + return got; + } + +/* +* Check if the stream is empty or in error +*/ +bool DataSource_Stream::end_of_data() const + { + return (!source.good()); + } + +/* +* Return a human-readable ID for this stream +*/ +std::string DataSource_Stream::id() const + { + return identifier; + } + +/* +* DataSource_Stream Constructor +*/ +DataSource_Stream::DataSource_Stream(const std::string& path, + bool use_binary) : + identifier(path), + source_p(new std::ifstream(path, + use_binary ? std::ios::binary : std::ios::in)), + source(*source_p), + total_read(0) + { + if(!source.good()) + { + delete source_p; + throw Stream_IO_Error("DataSource: Failure opening file " + path); + } + } + +/* +* DataSource_Stream Constructor +*/ +DataSource_Stream::DataSource_Stream(std::istream& in, + const std::string& name) : + identifier(name), + source_p(nullptr), + source(in), + total_read(0) + { + } + +/* +* DataSource_Stream Destructor +*/ +DataSource_Stream::~DataSource_Stream() + { + delete source_p; + } + +} diff --git a/src/lib/utils/data_src.h b/src/lib/utils/data_src.h new file mode 100644 index 000000000..2b6998448 --- /dev/null +++ b/src/lib/utils/data_src.h @@ -0,0 +1,180 @@ +/* +* DataSource +* (C) 1999-2007 Jack Lloyd +* 2012 Markus Wanner +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DATA_SRC_H__ +#define BOTAN_DATA_SRC_H__ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents an abstract data source object. +*/ +class BOTAN_DLL DataSource + { + public: + /** + * Read from the source. Moves the internal offset so that every + * call to read will return a new portion of the source. + * + * @param out the byte array to write the result to + * @param length the length of the byte array out + * @return length in bytes that was actually read and put + * into out + */ + virtual size_t read(byte out[], size_t length) = 0; + + virtual bool check_available(size_t n) = 0; + + /** + * Read from the source but do not modify the internal + * offset. Consecutive calls to peek() will return portions of + * the source starting at the same position. + * + * @param out the byte array to write the output to + * @param length the length of the byte array out + * @param peek_offset the offset into the stream to read at + * @return length in bytes that was actually read and put + * into out + */ + virtual size_t peek(byte out[], size_t length, + size_t peek_offset) const = 0; + + /** + * Test whether the source still has data that can be read. + * @return true if there is still data to read, false otherwise + */ + virtual bool end_of_data() const = 0; + /** + * return the id of this data source + * @return std::string representing the id of this data source + */ + virtual std::string id() const { return ""; } + + /** + * Read one byte. + * @param out the byte to read to + * @return length in bytes that was actually read and put + * into out + */ + size_t read_byte(byte& out); + + /** + * Peek at one byte. + * @param out an output byte + * @return length in bytes that was actually read and put + * into out + */ + size_t peek_byte(byte& out) const; + + /** + * Discard the next N bytes of the data + * @param N the number of bytes to discard + * @return number of bytes actually discarded + */ + size_t discard_next(size_t N); + + /** + * @return number of bytes read so far. + */ + virtual size_t get_bytes_read() const = 0; + + DataSource() {} + virtual ~DataSource() {} + DataSource& operator=(const DataSource&) = delete; + DataSource(const DataSource&) = delete; + }; + +/** +* This class represents a Memory-Based DataSource +*/ +class BOTAN_DLL DataSource_Memory : public DataSource + { + public: + size_t read(byte[], size_t) override; + size_t peek(byte[], size_t, size_t) const override; + bool check_available(size_t n) override; + bool end_of_data() const override; + + /** + * Construct a memory source that reads from a string + * @param in the string to read from + */ + DataSource_Memory(const std::string& in); + + /** + * Construct a memory source that reads from a byte array + * @param in the byte array to read from + * @param length the length of the byte array + */ + DataSource_Memory(const byte in[], size_t length) : + source(in, in + length), offset(0) {} + + /** + * Construct a memory source that reads from a secure_vector + * @param in the MemoryRegion to read from + */ + DataSource_Memory(const secure_vector& in) : + source(in), offset(0) {} + + /** + * Construct a memory source that reads from a std::vector + * @param in the MemoryRegion to read from + */ + DataSource_Memory(const std::vector& in) : + source(in.begin(), in.end()), offset(0) {} + + size_t get_bytes_read() const override { return offset; } + private: + secure_vector source; + size_t offset; + }; + +/** +* This class represents a Stream-Based DataSource. +*/ +class BOTAN_DLL DataSource_Stream : public DataSource + { + public: + size_t read(byte[], size_t) override; + size_t peek(byte[], size_t, size_t) const override; + bool check_available(size_t n) override; + bool end_of_data() const override; + std::string id() const override; + + DataSource_Stream(std::istream&, + const std::string& id = ""); + + /** + * Construct a Stream-Based DataSource from file + * @param file the name of the file + * @param use_binary whether to treat the file as binary or not + */ + DataSource_Stream(const std::string& file, bool use_binary = false); + + DataSource_Stream(const DataSource_Stream&) = delete; + + DataSource_Stream& operator=(const DataSource_Stream&) = delete; + + ~DataSource_Stream(); + + size_t get_bytes_read() const override { return total_read; } + private: + const std::string identifier; + + std::istream* source_p; + std::istream& source; + size_t total_read; + }; + +} + +#endif diff --git a/src/lib/utils/info.txt b/src/lib/utils/info.txt index 7d3216b1c..79026d7a9 100644 --- a/src/lib/utils/info.txt +++ b/src/lib/utils/info.txt @@ -9,6 +9,7 @@ calendar.h charset.h cpuid.h database.h +data_src.h exceptn.h loadstor.h mem_ops.h diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp index 81a15445e..f443ddabf 100644 --- a/src/tests/test_modes.cpp +++ b/src/tests/test_modes.cpp @@ -8,11 +8,8 @@ #if defined(BOTAN_HAS_MODES) -#if defined(BOTAN_HAS_FILTERS) - #include #include -#include #include #include #include @@ -27,21 +24,16 @@ secure_vector run_mode(const std::string& algo, const secure_vector& nonce, const secure_vector& key) { -#if 0 std::unique_ptr 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 ct = pt; cipher->finish(ct); -#else - Pipe pipe(get_cipher(algo, SymmetricKey(key), InitializationVector(nonce), dir)); - - pipe.process_msg(pt); - - return pipe.read_all(); -#endif + return ct; } size_t mode_test(const std::string& algo, @@ -102,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_pubkey.cpp b/src/tests/test_pubkey.cpp index f5528af12..09f3843bb 100644 --- a/src/tests/test_pubkey.cpp +++ b/src/tests/test_pubkey.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #if defined(BOTAN_HAS_RSA) #include @@ -64,8 +65,8 @@ #include #endif -#include #include + using namespace Botan; namespace { @@ -73,12 +74,8 @@ namespace { void dump_data(const std::vector& out, const std::vector& 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, diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp index f77be1992..2040e4bbf 100644 --- a/src/tests/unit_x509.cpp +++ b/src/tests/unit_x509.cpp @@ -11,7 +11,6 @@ #if defined(BOTAN_HAS_RSA) && defined(BOTAN_HAS_DSA) #include -#include #include #include #include @@ -45,22 +44,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 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 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 output = hash->final(); + return load_be(output.data()); } -- cgit v1.2.3 From c7ceff4a3a3b6b61a02b99db05eef88f7ca4b735 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 14 Oct 2015 16:39:41 -0400 Subject: Add null pointer check to pbes2_decrypt, fix message in pbes2_encrypt --- src/lib/misc/pbes2/pbes2.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/misc/pbes2/pbes2.cpp b/src/lib/misc/pbes2/pbes2.cpp index 470e33cb0..ec5a10ba8 100644 --- a/src/lib/misc/pbes2/pbes2.cpp +++ b/src/lib/misc/pbes2/pbes2.cpp @@ -82,7 +82,7 @@ pbes2_encrypt(const secure_vector& key_bits, std::unique_ptr enc(get_cipher_mode(cipher, ENCRYPTION)); if(!enc) - throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher); + throw Encoding_Error("PBE-PKCS5 cannot encrypt no cipher " + cipher); std::unique_ptr pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); @@ -157,6 +157,8 @@ pbes2_decrypt(const secure_vector& key_bits, std::unique_ptr pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); std::unique_ptr dec(get_cipher_mode(cipher, DECRYPTION)); + if(!enc) + throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher); if(key_length == 0) key_length = dec->key_spec().maximum_keylength(); -- cgit v1.2.3 From 4bfd5d6828f23e0eef04e5cf079c323274136499 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 14 Oct 2015 18:37:13 -0400 Subject: Build fix --- src/lib/misc/pbes2/pbes2.cpp | 4 ++-- src/lib/misc/pem/pem.cpp | 1 + src/tests/unit_x509.cpp | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/lib') diff --git a/src/lib/misc/pbes2/pbes2.cpp b/src/lib/misc/pbes2/pbes2.cpp index ec5a10ba8..c66b293e8 100644 --- a/src/lib/misc/pbes2/pbes2.cpp +++ b/src/lib/misc/pbes2/pbes2.cpp @@ -82,7 +82,7 @@ pbes2_encrypt(const secure_vector& key_bits, std::unique_ptr enc(get_cipher_mode(cipher, ENCRYPTION)); if(!enc) - throw Encoding_Error("PBE-PKCS5 cannot encrypt no cipher " + cipher); + throw Decoding_Error("PBE-PKCS5 cannot encrypt no cipher " + cipher); std::unique_ptr pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); @@ -157,7 +157,7 @@ pbes2_decrypt(const secure_vector& key_bits, std::unique_ptr pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); std::unique_ptr dec(get_cipher_mode(cipher, DECRYPTION)); - if(!enc) + if(!dec) throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher); if(key_length == 0) diff --git a/src/lib/misc/pem/pem.cpp b/src/lib/misc/pem/pem.cpp index 1279b665e..83b48c07b 100644 --- a/src/lib/misc/pem/pem.cpp +++ b/src/lib/misc/pem/pem.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace Botan { diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp index 2040e4bbf..0d3946012 100644 --- a/src/tests/unit_x509.cpp +++ b/src/tests/unit_x509.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -49,7 +50,7 @@ u64bit key_id(const Public_Key* key) hash->update(key->algorithm_identifier().parameters); hash->update(key->x509_subject_public_key()); secure_vector output = hash->final(); - return load_be(output.data()); + return load_be(output.data(), 0); } -- cgit v1.2.3 From 4e90017c204d3297df1444af59337db89f8180d9 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 14 Oct 2015 19:23:55 -0400 Subject: Expose providers for public key operations For PK_Encryptor and company they are requested via a new provider param to the constructors. The speed command gets a --provider option so you can see benchmark results with the different versions. --- src/cmd/implementation/speed.h | 4 +- src/cmd/implementation/speed_public_key.cpp | 30 +++++++------ src/cmd/speed.cpp | 13 ++++-- src/lib/pubkey/pubkey.cpp | 36 +++++++++------ src/lib/pubkey/pubkey.h | 68 ++++++++++++++++------------- src/lib/vendor/openssl/openssl_rsa.cpp | 9 ++-- src/tests/test_rsa.cpp | 4 +- 7 files changed, 97 insertions(+), 67 deletions(-) (limited to 'src/lib') diff --git a/src/cmd/implementation/speed.h b/src/cmd/implementation/speed.h index 1f082eb52..3cfd0ef61 100644 --- a/src/cmd/implementation/speed.h +++ b/src/cmd/implementation/speed.h @@ -13,7 +13,9 @@ #include void benchmark_public_key(Botan::RandomNumberGenerator& rng, - const std::string& algo, double seconds); + const std::string& algo, + const std::string& provider, + double seconds); std::map benchmark_is_prime(Botan::RandomNumberGenerator &rng, const std::chrono::milliseconds runtime); diff --git a/src/cmd/implementation/speed_public_key.cpp b/src/cmd/implementation/speed_public_key.cpp index 83c0156ae..00bf4b438 100644 --- a/src/cmd/implementation/speed_public_key.cpp +++ b/src/cmd/implementation/speed_public_key.cpp @@ -202,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) { @@ -213,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"; @@ -243,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); + PK_Verifier ver(key, sig_padding, IEEE_1363); benchmark_sig_ver(ver, sig, verify_timer, sig_timer, rng, 10000, seconds); @@ -318,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) { @@ -348,8 +350,8 @@ 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); @@ -791,7 +793,9 @@ void benchmark_mce(RandomNumberGenerator& rng, } void benchmark_public_key(RandomNumberGenerator& rng, - const std::string& algo, double seconds) + const std::string& algo, + const std::string& provider, + double seconds) { /* There is some strangeness going on here. It looks like algorithms @@ -823,7 +827,7 @@ void benchmark_public_key(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) @@ -833,7 +837,7 @@ void benchmark_public_key(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/speed.cpp b/src/cmd/speed.cpp index 91b2f4fbd..990c6a364 100644 --- a/src/cmd/speed.cpp +++ b/src/cmd/speed.cpp @@ -118,6 +118,7 @@ void report_results(const std::string& algo, } void bench_algo(const std::string& algo, + const std::string& provider, RandomNumberGenerator& rng, double seconds, size_t buf_size) @@ -151,7 +152,7 @@ void bench_algo(const std::string& algo, catch (No_Provider_Found) { #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) - benchmark_public_key(rng, algo, seconds); + benchmark_public_key(rng, algo, provider, seconds); #endif } } @@ -159,7 +160,7 @@ void bench_algo(const std::string& algo, 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; @@ -185,7 +186,9 @@ int speed(int argc, char* argv[]) } } - auto args = opts.arguments(); + const std::string provider = opts.value_if_set("provider"); + + std::vector args = opts.arguments(); if(args.empty()) args = default_benchmark_list; @@ -199,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/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 -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::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::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("Encryption", key, eme)); + m_op.reset(get_pk_op("Encryption", key, padding, provider)); } std::vector @@ -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("Decryption", key, eme)); + m_op.reset(get_pk_op("Decryption", key, padding, provider)); } secure_vector PK_Decryptor_EME::dec(const byte msg[], size_t length) const @@ -108,9 +116,10 @@ std::vector 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("Signing", key, emsa)); + m_op.reset(get_pk_op("Signing", key, emsa, provider)); m_sig_format = format; } @@ -135,9 +144,10 @@ std::vector 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("Verification", key, emsa_name)); + m_op.reset(get_pk_op("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 m_op; Signature_Format m_sig_format; @@ -204,6 +206,17 @@ class BOTAN_DLL PK_Signer 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 @@ -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 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 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 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 dec(const byte[], size_t) const override; diff --git a/src/lib/vendor/openssl/openssl_rsa.cpp b/src/lib/vendor/openssl/openssl_rsa.cpp index f8ab2bcd1..ac8416405 100644 --- a/src/lib/vendor/openssl/openssl_rsa.cpp +++ b/src/lib/vendor/openssl/openssl_rsa.cpp @@ -24,11 +24,12 @@ namespace { std::pair 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 == "EME1(SHA-1)") + 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); @@ -63,10 +64,10 @@ class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption if(!m_openssl_rsa) throw OpenSSL_Error("d2i_RSAPublicKey"); - m_bits = 8 * n_size() - pad_overhead; + m_bits = 8 * (n_size() - pad_overhead); } - size_t max_input_bits() const override { return m_bits; }; + size_t max_input_bits() const override { return m_bits - 1; }; secure_vector encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&) override @@ -137,7 +138,7 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption m_bits = 8 * ::RSA_size(m_openssl_rsa.get()); } - size_t max_input_bits() const override { return m_bits; }; + size_t max_input_bits() const override { return m_bits - 1; } secure_vector decrypt(const byte msg[], size_t msg_len) override { 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); } -- cgit v1.2.3 From cf084300d49360d03e1066db005d2cd0abc73f6b Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 14 Oct 2015 20:25:34 -0400 Subject: Add support for RSA signing and verification via OpenSSL --- doc/news.rst | 6 ++ src/cmd/implementation/speed_public_key.cpp | 4 +- src/lib/vendor/openssl/openssl_rsa.cpp | 144 +++++++++++++++++++++++++--- 3 files changed, 139 insertions(+), 15 deletions(-) (limited to 'src/lib') diff --git a/doc/news.rst b/doc/news.rst index cab97c782..e1ee423f8 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -4,6 +4,12 @@ Release Notes Version 1.11.22, Not Yet Released ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* Public key operations can now be used with specified providers + by passing an additional parameter to the constructor of + the PK operation. + +* OpenSSL RSA provider now supports signatures and verification. + * The `configure.py` option `--no-autoload` is now also available under the more understandable name `--minimized-build`. diff --git a/src/cmd/implementation/speed_public_key.cpp b/src/cmd/implementation/speed_public_key.cpp index 00bf4b438..2ff49bd15 100644 --- a/src/cmd/implementation/speed_public_key.cpp +++ b/src/cmd/implementation/speed_public_key.cpp @@ -250,8 +250,8 @@ void benchmark_rsa(const std::string& provider, benchmark_enc_dec(enc, dec, enc_timer, dec_timer, rng, 10000, seconds); - PK_Signer sig(key, sig_padding, IEEE_1363); - PK_Verifier ver(key, sig_padding, IEEE_1363); + 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); diff --git a/src/lib/vendor/openssl/openssl_rsa.cpp b/src/lib/vendor/openssl/openssl_rsa.cpp index ac8416405..3a7cd0dcf 100644 --- a/src/lib/vendor/openssl/openssl_rsa.cpp +++ b/src/lib/vendor/openssl/openssl_rsa.cpp @@ -35,6 +35,22 @@ std::pair get_openssl_enc_pad(const std::string& eme) throw Lookup_Error("OpenSSL RSA does not support EME " + eme); } +secure_vector strip_leading_zeros(const secure_vector& input) + { + size_t leading_zeros = 0; + + for(size_t i = 0; i != input.size(); ++i) + { + if(input[i] != 0) + break; + ++leading_zeros; + } + + secure_vector output(&input[leading_zeros], + &input[input.size()]); + return output; + } + class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption { public: @@ -64,10 +80,10 @@ class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption if(!m_openssl_rsa) throw OpenSSL_Error("d2i_RSAPublicKey"); - m_bits = 8 * (n_size() - pad_overhead); + m_bits = 8 * (n_size() - pad_overhead) - 1; } - size_t max_input_bits() const override { return m_bits - 1; }; + size_t max_input_bits() const override { return m_bits; }; secure_vector encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&) override @@ -134,11 +150,9 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption 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 - 1; } + size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; } secure_vector decrypt(const byte msg[], size_t msg_len) override { @@ -150,25 +164,129 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption if(m_padding == RSA_NO_PADDING) { - size_t leading_0s = 0; - while(leading_0s < buf.size() && buf[leading_0s] == 0) - leading_0s++; - - if(leading_0s) - return secure_vector(&buf[leading_0s], &buf[buf.size()]); + return strip_leading_zeros(buf); } - return buf; } private: std::unique_ptr> m_openssl_rsa; - size_t m_bits = 0; 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(&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 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 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 inbuf(mod_sz); + copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len); + + secure_vector 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> 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(&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 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 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 inbuf(mod_sz); + copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len); + + secure_vector 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> 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); -- cgit v1.2.3 From 83fe87cc13b4dd6285fbc15465c7bd39fdadb53d Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 15 Oct 2015 09:28:25 -0400 Subject: Add System_RNG which is an instantiatable RNG that uses the system RNG Previously you couldn't have an unique_ptr that might point to either a system rng or an autoseed rng depending on availability. That was already needed in ffi and is useful elsewhere. --- src/lib/ffi/ffi.cpp | 17 +---------------- src/lib/rng/system_rng/system_rng.cpp | 16 ++++++++-------- src/lib/rng/system_rng/system_rng.h | 25 ++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 25 deletions(-) (limited to 'src/lib') diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 27dcc6015..978a76c0f 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -228,21 +228,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); @@ -255,7 +240,7 @@ int botan_rng_init(botan_rng_t* rng_out, const char* rng_type) std::unique_ptr 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); 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(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 -- cgit v1.2.3 From 3181dfa7abfe7b623d8823e078f04a374775e978 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 15 Oct 2015 10:07:36 -0400 Subject: Periodically reinitialize the blinding sequence instead of always deriving it by squaring the previous value. --- doc/news.rst | 18 ++++++++++++++---- src/build-data/buildh.in | 15 +++++++++++++-- src/lib/pubkey/blinding.cpp | 40 ++++++++++++++++++++++++++++------------ src/lib/pubkey/blinding.h | 12 +++++++++++- 4 files changed, 66 insertions(+), 19 deletions(-) (limited to 'src/lib') diff --git a/doc/news.rst b/doc/news.rst index e1ee423f8..cae2270bd 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -4,11 +4,21 @@ Release Notes Version 1.11.22, Not Yet Released ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -* Public key operations can now be used with specified providers - by passing an additional parameter to the constructor of - the PK operation. +* Public key operations can now be used with specified providers by passing an + additional parameter to the constructor of the PK operation. -* OpenSSL RSA provider now supports signatures and verification. +* OpenSSL RSA provider now supports signature creation and verification. + +* The blinding code used for RSA, Diffie-Hellman, ElGamal and Rabin-Williams now + periodically reinitializes the sequence of blinding values instead of always + deriving the next value by squaring the previous ones. The reinitializion + interval can be controlled by + +* Add System_RNG type. Previously the global system RNG was only accessible via + `system_rng` which returned a reference to the object. However is at times + useful to have a unique_ptr which will be either the + system RNG or an AutoSeeded_RNG, depending on availability, which this + additional type allows. * The `configure.py` option `--no-autoload` is now also available under the more understandable name `--minimized-build`. diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index eaf4181b5..31069f0ae 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -71,9 +71,20 @@ * representation of an ECC point. Set to zero to diable this * side-channel countermeasure. */ -#define BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS 64 +#define BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS 80 -#define BOTAN_CURVE_GFP_USE_MONTGOMERY_LADDER 0 +/* +* 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 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 fwd_func, - std::function inv_func) + std::function fwd, + std::function 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..2525276ca 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 */ @@ -33,8 +35,16 @@ class BOTAN_DLL Blinder std::function inv_func); private: + BigInt blinding_nonce() const; + Modular_Reducer m_reducer; + std::unique_ptr m_rng; + std::function m_fwd_fn; + std::function m_inv_fn; + size_t m_modulus_bits = 0; + mutable BigInt m_e, m_d; + mutable size_t m_counter = 0; }; } -- cgit v1.2.3 From 9f6665aff8a633131212422bec4a150da3bdf4ed Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 15 Oct 2015 10:13:19 -0400 Subject: Prohibit creating a DL_Group smaller than 1024 bits --- doc/news.rst | 4 +++- src/lib/pubkey/dl_group/dl_group.cpp | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/lib') diff --git a/doc/news.rst b/doc/news.rst index cae2270bd..99ff04238 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -12,7 +12,9 @@ Version 1.11.22, Not Yet Released * The blinding code used for RSA, Diffie-Hellman, ElGamal and Rabin-Williams now periodically reinitializes the sequence of blinding values instead of always deriving the next value by squaring the previous ones. The reinitializion - interval can be controlled by + interval can be controlled by the build.h parameter BOTAN_BLINDING_REINIT_INTERVAL. + +* DL_Group now prohibits creating a group smaller than 1024 bits. * Add System_RNG type. Previously the global system RNG was only accessible via `system_rng` which returned a reference to the object. However is at times 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"); -- cgit v1.2.3 From 7335eefcf419a2ab7a770c3aa6fbb06956891bad Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 15 Oct 2015 11:50:42 -0400 Subject: Add prime and dl_group command line tools. Some cleanups in random_prime. Increase probability in prime tests from 1/2**64 to 1/2**128. Also break out of the sieve loop early if it has failed. --- doc/news.rst | 2 + src/cmd/dl_group.cpp | 85 ++++++++++++++++++++++++++++++++++ src/cmd/prime.cpp | 48 +++++++++++++++++++ src/lib/math/numbertheory/make_prm.cpp | 56 ++++++++++++++++------ 4 files changed, 177 insertions(+), 14 deletions(-) create mode 100644 src/cmd/dl_group.cpp create mode 100644 src/cmd/prime.cpp (limited to 'src/lib') diff --git a/doc/news.rst b/doc/news.rst index 99ff04238..9eddabd5c 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -22,6 +22,8 @@ Version 1.11.22, Not Yet Released system RNG or an AutoSeeded_RNG, depending on availability, which this additional type allows. +* New command line tools `dl_group` and `prime` + * The `configure.py` option `--no-autoload` is now also available under the more understandable name `--minimized-build`. 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 +#include + +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 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/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 + +#include +#include + +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/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; } -- cgit v1.2.3 From dcc448d5004653c52dada3d04fd92db3bd08f10e Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 15 Oct 2015 12:45:01 -0400 Subject: MSVC build fix --- src/lib/pubkey/blinding.h | 4 ++++ src/lib/pubkey/elgamal/elgamal.cpp | 15 ++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src/lib') diff --git a/src/lib/pubkey/blinding.h b/src/lib/pubkey/blinding.h index 2525276ca..c1999feb7 100644 --- a/src/lib/pubkey/blinding.h +++ b/src/lib/pubkey/blinding.h @@ -34,6 +34,10 @@ class BOTAN_DLL Blinder std::function fwd_func, std::function inv_func); + Blinder(const Blinder&) = delete; + + Blinder& operator=(const Blinder&) = delete; + private: BigInt blinding_nonce() const; 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 -- cgit v1.2.3 From be33a49c734b5b83cbf64fa132c062ba8643bbe1 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 15 Oct 2015 15:33:32 -0400 Subject: Fix compile of ffi when tls is disabled. GH #300 --- src/lib/ffi/ffi.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/lib') diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 978a76c0f..eb30b4831 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include @@ -49,11 +47,15 @@ #include #endif - #if defined(BOTAN_HAS_BCRYPT) #include #endif +#if defined(BOTAN_HAS_TLS) + #include + #include +#endif + namespace { #define BOTAN_ASSERT_ARG_NON_NULL(p) \ @@ -185,7 +187,10 @@ BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_verify_struct, Botan::PK_Verifier, 0x2B91F9 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 -- cgit v1.2.3 From ea07110c86c7ae2601e71dd3c1134873ccfd721f Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 16 Oct 2015 17:39:43 -0400 Subject: Make PKCS #1 and OAEP decoding constant time to avoid oracle attacks via timing channels. Add annotations for checking constant-time code using ctgrind to PKCS #1 and OAEP, as well as IDEA and Curve25519 which were already written as constant time code. --- doc/news.rst | 17 +++ src/build-data/buildh.in | 6 + src/lib/block/idea/idea.cpp | 37 ++++-- src/lib/block/idea_sse2/idea_sse2.cpp | 10 +- src/lib/pk_pad/eme_oaep/oaep.cpp | 32 +++--- src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp | 46 +++++--- src/lib/pubkey/curve25519/donna.cpp | 9 ++ src/lib/utils/ct_utils.h | 207 ++++++++++++++++++++++++++++++++++ src/lib/utils/info.txt | 4 +- src/lib/utils/ta_utils.cpp | 66 ----------- src/lib/utils/ta_utils.h | 57 ---------- 11 files changed, 323 insertions(+), 168 deletions(-) create mode 100644 src/lib/utils/ct_utils.h delete mode 100644 src/lib/utils/ta_utils.cpp delete mode 100644 src/lib/utils/ta_utils.h (limited to 'src/lib') diff --git a/doc/news.rst b/doc/news.rst index 9eddabd5c..00a102427 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -4,6 +4,23 @@ Release Notes Version 1.11.22, Not Yet Released ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* The routines for decoding PKCS #1 encryption and OAEP blocks have been + rewritten to run without secret indexes or branches. These cryptographic + operations are vulnerable to oracle attacks, including via side channels such + as timing or cache-based analysis. In theory it would be possible to attack + the previous implementations using such a side channel, which could allow + an attacker to mount a plaintext recovery attack. + + By writing the code such that it does not depend on secret inputs for branch + or memory indexes, such a side channel would be much less likely to exist. + +* Add support for using ctgrind (https://github.com/agl/ctgrind) to test that + sections of code do not use secret inputs to decide branches or memory indexes. + The testing relies on dynamic checking using valgrind. + + So far PKCS #1 decoding, OAEP decoding, IDEA, and Curve25519 have been notated + and confirmed to be constant time. + * Public key operations can now be used with specified providers by passing an additional parameter to the constructor of the PK operation. diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index 31069f0ae..3061c9608 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -91,6 +91,12 @@ #define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD 0 #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/lib/block/idea/idea.cpp b/src/lib/block/idea/idea.cpp index ddfd8e5fb..c7706b372 100644 --- a/src/lib/block/idea/idea.cpp +++ b/src/lib/block/idea/idea.cpp @@ -1,12 +1,13 @@ /* * IDEA -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include #include +#include namespace Botan { @@ -19,8 +20,7 @@ inline u16bit mul(u16bit x, u16bit y) { const u32bit P = static_cast(x) * y; - // P ? 0xFFFF : 0 - const u16bit P_mask = !P - 1; + const u16bit Z_mask = static_cast(ct_expand_mask_32(P) & 0xFFFF); const u32bit P_hi = P >> 16; const u32bit P_lo = P & 0xFFFF; @@ -28,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); } /* @@ -62,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(in, 0); - u16bit X2 = load_be(in, 1); - u16bit X3 = load_be(in, 2); - u16bit X4 = load_be(in, 3); + u16bit X1 = load_be(in + BLOCK_SIZE*i, 0); + u16bit X2 = load_be(in + BLOCK_SIZE*i, 1); + u16bit X3 = load_be(in + BLOCK_SIZE*i, 2); + u16bit X4 = load_be(in + BLOCK_SIZE*i, 3); for(size_t j = 0; j != 8; ++j) { @@ -94,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); } } @@ -127,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(key, i); @@ -158,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 a2a54ac32..51b5e909b 100644 --- a/src/lib/block/idea_sse2/idea_sse2.cpp +++ b/src/lib/block/idea_sse2/idea_sse2.cpp @@ -7,6 +7,7 @@ #include #include +#include #include namespace Botan { @@ -130,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(in); __m128i B0 = _mm_loadu_si128(in_mm + 0); @@ -153,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]); @@ -190,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/pk_pad/eme_oaep/oaep.cpp b/src/lib/pk_pad/eme_oaep/oaep.cpp index f214c25d2..48a9b5c63 100644 --- a/src/lib/pk_pad/eme_oaep/oaep.cpp +++ b/src/lib/pk_pad/eme_oaep/oaep.cpp @@ -1,13 +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 #include -#include +#include namespace Botan { @@ -92,33 +92,33 @@ secure_vector OAEP::unpad(const byte in[], size_t in_length, input.data(), m_Phash.size(), &input[m_Phash.size()], input.size() - m_Phash.size()); - bool waiting_for_delim = true; - bool bad_input = false; + BOTAN_CONST_TIME_POISON(input.data(), input.size()); + size_t delim_idx = 2 * m_Phash.size(); + 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[m_Phash.size()], m_Phash.data(), m_Phash.size())); - 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 65d29cd59..219e93251 100644 --- a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp +++ b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp @@ -1,11 +1,12 @@ /* -* 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 +#include namespace Botan { @@ -38,22 +39,39 @@ secure_vector EME_PKCS1v15::pad(const byte in[], size_t inlen, * PKCS1 Unpad Operation */ secure_vector 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(&in[separator + 1], &in[inlen]); + return secure_vector(&in[delim_idx + 1], &in[inlen]); } /* 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 #include #include +#include #include 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/utils/ct_utils.h b/src/lib/utils/ct_utils.h new file mode 100644 index 000000000..02148001e --- /dev/null +++ b/src/lib/utils/ct_utils.h @@ -0,0 +1,207 @@ +/* +* 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 +#include + +#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 + +/* +* Constant time operations for 32 bit values: +* mask, select, zero, equals, min, max +*/ + +/* +* 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) + { + uint32_t r = x; + r |= r >> 1; + r |= r >> 2; + r |= r >> 4; + r |= r >> 8; + r |= r >> 16; + r &= 1; + 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_select_cond_32(bool cond, uint32_t a, uint32_t b) + { + return ct_select_mask_32(ct_expand_mask_32(static_cast(cond)), a, b); + } + +inline uint32_t ct_get_high_bit_32(uint32_t x) + { + return (x >> (8 * sizeof(x) - 1)); + } + +/* +* If x is zero, return 0xFFFF... +* Otherwise returns zero +*/ +inline uint32_t ct_is_zero_32(uint32_t x) + { + return ct_expand_mask_32(ct_get_high_bit_32(~x & (x-1))); + } + +inline uint32_t ct_is_equal_32(uint32_t x, uint32_t y) + { + return ct_is_zero_32(x ^ y); + } + +/** +* Branch-free maximum +* Note: assumes twos-complement signed representation +* @param a an integer +* @param b an integer +* @return max(a,b) +*/ +inline uint32_t ct_max_32(uint32_t a, uint32_t b) + { + const uint32_t s = b - a; + return ct_select_cond_32(ct_get_high_bit_32(s), a, b); + } + +/** +* Branch-free minimum +* Note: assumes twos-complement signed representation +* @param a an integer +* @param b an integer +* @return min(a,b) +*/ +inline uint32_t ct_min_32(uint32_t a, uint32_t b) + { + const uint32_t s = b - a; + return ct_select_cond_32(ct_get_high_bit_32(s), b, a); + } + +/* +* Constant time operations for 16 bit values: +* mask, select, zero, equals +*/ +inline uint16_t ct_expand_mask_16(uint16_t x) + { + uint16_t r = x; + r |= r >> 1; + r |= r >> 2; + r |= r >> 4; + r |= r >> 8; + 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_select_cond_16(bool cond, uint16_t a, uint16_t b) + { + return ct_select_mask_16(ct_expand_mask_16(static_cast(cond)), a, b); + } + +inline uint16_t ct_get_high_bit_16(uint16_t x) + { + return (x >> (8 * sizeof(x) - 1)); + } + +inline uint16_t ct_is_zero_16(uint16_t x) + { + //uint16_t z = x & (x - 1) + //return ct_expand_mask_16((~x & (x-1)) + return ct_expand_mask_16(ct_get_high_bit_16(~x & (x-1))); + } + +inline uint16_t ct_is_equal_16(uint16_t x, uint16_t y) + { + return ct_is_zero_16(x ^ y); + } + +/* +* Constant time operations for 8 bit values: +* mask, select, zero, equals +*/ + +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_select_cond_8(bool cond, uint8_t a, uint8_t b) + { + return ct_select_mask_8(ct_expand_mask_8(static_cast(cond)), a, b); + } + +inline uint8_t ct_get_high_bit_8(uint8_t x) + { + return (x >> (8 * sizeof(x) - 1)); + } + +inline uint8_t ct_is_zero_8(uint8_t x) + { + return ct_expand_mask_8(ct_get_high_bit_8(~x & (x-1))); + } + +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/utils/info.txt b/src/lib/utils/info.txt index 79026d7a9..228fccd82 100644 --- a/src/lib/utils/info.txt +++ b/src/lib/utils/info.txt @@ -8,8 +8,8 @@ bswap.h calendar.h charset.h cpuid.h -database.h data_src.h +database.h exceptn.h loadstor.h mem_ops.h @@ -22,11 +22,11 @@ version.h bit_ops.h +ct_utils.h donna128.h filesystem.h prefetch.h rounding.h semaphore.h stl_util.h -ta_utils.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 - -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 -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(in); - } - -u16bit expand_mask_u16bit(u16bit in) - { - return expand_mask(in); - } - -u32bit max_32(u32bit a, u32bit b) - { - const u32bit a_larger = b - a; /* negative if a larger */ - const u32bit mask = expand_mask(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(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 - -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 -- cgit v1.2.3 From ada3ce066d1edfe95ee8bffa82f0c2846908a4e1 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 17 Oct 2015 23:21:14 -0400 Subject: Cleanups in ct and oaep In OAEP expand the const time block to cover MGF1 also --- src/lib/pk_pad/eme_oaep/oaep.cpp | 20 ++++---- src/lib/utils/ct_utils.h | 99 +++++----------------------------------- 2 files changed, 23 insertions(+), 96 deletions(-) (limited to 'src/lib') diff --git a/src/lib/pk_pad/eme_oaep/oaep.cpp b/src/lib/pk_pad/eme_oaep/oaep.cpp index 48a9b5c63..b114afb8b 100644 --- a/src/lib/pk_pad/eme_oaep/oaep.cpp +++ b/src/lib/pk_pad/eme_oaep/oaep.cpp @@ -61,7 +61,7 @@ secure_vector OAEP::pad(const byte in[], size_t in_length, * OAEP Unpad Operation */ secure_vector 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 @@ -84,17 +84,19 @@ secure_vector OAEP::unpad(const byte in[], size_t in_length, secure_vector input(key_length); buffer_insert(input, key_length - in_length, in, in_length); - mgf1_mask(*m_hash, - &input[m_Phash.size()], input.size() - m_Phash.size(), - input.data(), m_Phash.size()); + BOTAN_CONST_TIME_POISON(input.data(), input.size()); + + const size_t hlen = m_Phash.size(); mgf1_mask(*m_hash, - input.data(), m_Phash.size(), - &input[m_Phash.size()], input.size() - m_Phash.size()); + &input[hlen], input.size() - hlen, + input.data(), hlen); - BOTAN_CONST_TIME_POISON(input.data(), input.size()); + mgf1_mask(*m_hash, + input.data(), hlen, + &input[hlen], input.size() - hlen); - size_t delim_idx = 2 * m_Phash.size(); + size_t delim_idx = 2 * hlen; byte waiting_for_delim = 0xFF; byte bad_input = 0; @@ -114,7 +116,7 @@ secure_vector OAEP::unpad(const byte in[], size_t in_length, // 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[m_Phash.size()], m_Phash.data(), m_Phash.size())); + bad_input |= ct_expand_mask_8(!same_mem(&input[hlen], m_Phash.data(), hlen)); BOTAN_CONST_TIME_UNPOISON(input.data(), input.size()); BOTAN_CONST_TIME_UNPOISON(&bad_input, sizeof(bad_input)); diff --git a/src/lib/utils/ct_utils.h b/src/lib/utils/ct_utils.h index 02148001e..4ae735330 100644 --- a/src/lib/utils/ct_utils.h +++ b/src/lib/utils/ct_utils.h @@ -39,26 +39,22 @@ namespace Botan { #endif -/* -* Constant time operations for 32 bit values: -* mask, select, zero, equals, min, max -*/ - /* * 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 >> 1; - r |= r >> 2; - r |= r >> 4; - r |= r >> 8; 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; } @@ -68,23 +64,9 @@ 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_select_cond_32(bool cond, uint32_t a, uint32_t b) - { - return ct_select_mask_32(ct_expand_mask_32(static_cast(cond)), a, b); - } - -inline uint32_t ct_get_high_bit_32(uint32_t x) - { - return (x >> (8 * sizeof(x) - 1)); - } - -/* -* If x is zero, return 0xFFFF... -* Otherwise returns zero -*/ inline uint32_t ct_is_zero_32(uint32_t x) { - return ct_expand_mask_32(ct_get_high_bit_32(~x & (x-1))); + return ~ct_expand_mask_32(x); } inline uint32_t ct_is_equal_32(uint32_t x, uint32_t y) @@ -92,43 +74,13 @@ inline uint32_t ct_is_equal_32(uint32_t x, uint32_t y) return ct_is_zero_32(x ^ y); } -/** -* Branch-free maximum -* Note: assumes twos-complement signed representation -* @param a an integer -* @param b an integer -* @return max(a,b) -*/ -inline uint32_t ct_max_32(uint32_t a, uint32_t b) - { - const uint32_t s = b - a; - return ct_select_cond_32(ct_get_high_bit_32(s), a, b); - } - -/** -* Branch-free minimum -* Note: assumes twos-complement signed representation -* @param a an integer -* @param b an integer -* @return min(a,b) -*/ -inline uint32_t ct_min_32(uint32_t a, uint32_t b) - { - const uint32_t s = b - a; - return ct_select_cond_32(ct_get_high_bit_32(s), b, a); - } - -/* -* Constant time operations for 16 bit values: -* mask, select, zero, equals -*/ inline uint16_t ct_expand_mask_16(uint16_t x) { uint16_t r = x; - r |= r >> 1; - r |= r >> 2; - r |= r >> 4; r |= r >> 8; + r |= r >> 4; + r |= r >> 2; + r |= r >> 1; r &= 1; r = ~(r - 1); return r; @@ -139,21 +91,9 @@ 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_select_cond_16(bool cond, uint16_t a, uint16_t b) - { - return ct_select_mask_16(ct_expand_mask_16(static_cast(cond)), a, b); - } - -inline uint16_t ct_get_high_bit_16(uint16_t x) - { - return (x >> (8 * sizeof(x) - 1)); - } - inline uint16_t ct_is_zero_16(uint16_t x) { - //uint16_t z = x & (x - 1) - //return ct_expand_mask_16((~x & (x-1)) - return ct_expand_mask_16(ct_get_high_bit_16(~x & (x-1))); + return ~ct_expand_mask_16(x); } inline uint16_t ct_is_equal_16(uint16_t x, uint16_t y) @@ -161,11 +101,6 @@ inline uint16_t ct_is_equal_16(uint16_t x, uint16_t y) return ct_is_zero_16(x ^ y); } -/* -* Constant time operations for 8 bit values: -* mask, select, zero, equals -*/ - inline uint8_t ct_expand_mask_8(uint8_t x) { uint8_t r = x; @@ -182,19 +117,9 @@ 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_select_cond_8(bool cond, uint8_t a, uint8_t b) - { - return ct_select_mask_8(ct_expand_mask_8(static_cast(cond)), a, b); - } - -inline uint8_t ct_get_high_bit_8(uint8_t x) - { - return (x >> (8 * sizeof(x) - 1)); - } - inline uint8_t ct_is_zero_8(uint8_t x) { - return ct_expand_mask_8(ct_get_high_bit_8(~x & (x-1))); + return ~ct_expand_mask_8(x); } inline uint8_t ct_is_equal_8(uint8_t x, uint8_t y) -- cgit v1.2.3 From dbe3754faf68687ccf58743d6f500d36e6419e77 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 19 Oct 2015 19:25:28 -0400 Subject: Break up openssl provider For RSA, RC4, and ECDSA put the openssl versions in the same directory as the base version. They just rely on a macro check for the openssl module to test for the desire to use OpenSSL. --- src/lib/block/openssl_block/info.txt | 5 + src/lib/block/openssl_block/openssl_block.cpp | 214 +++++++++++++++++++ src/lib/hash/openssl_hash/info.txt | 5 + src/lib/hash/openssl_hash/openssl_hash.cpp | 117 ++++++++++ src/lib/pubkey/ecdsa/openssl_ecdsa.cpp | 213 ++++++++++++++++++ src/lib/pubkey/rsa/openssl_rsa.cpp | 297 ++++++++++++++++++++++++++ src/lib/stream/rc4/openssl_rc4.cpp | 61 ++++++ src/lib/utils/openssl/info.txt | 16 ++ src/lib/utils/openssl/openssl.h | 35 +++ src/lib/vendor/openssl/info.txt | 11 - src/lib/vendor/openssl/openssl.h | 36 ---- src/lib/vendor/openssl/openssl_block.cpp | 216 ------------------- src/lib/vendor/openssl/openssl_ecdsa.cpp | 207 ------------------ src/lib/vendor/openssl/openssl_hash.cpp | 117 ---------- src/lib/vendor/openssl/openssl_rc4.cpp | 56 ----- src/lib/vendor/openssl/openssl_rsa.cpp | 297 -------------------------- 16 files changed, 963 insertions(+), 940 deletions(-) create mode 100644 src/lib/block/openssl_block/info.txt create mode 100644 src/lib/block/openssl_block/openssl_block.cpp create mode 100644 src/lib/hash/openssl_hash/info.txt create mode 100644 src/lib/hash/openssl_hash/openssl_hash.cpp create mode 100644 src/lib/pubkey/ecdsa/openssl_ecdsa.cpp create mode 100644 src/lib/pubkey/rsa/openssl_rsa.cpp create mode 100644 src/lib/stream/rc4/openssl_rc4.cpp create mode 100644 src/lib/utils/openssl/info.txt create mode 100644 src/lib/utils/openssl/openssl.h delete mode 100644 src/lib/vendor/openssl/info.txt delete mode 100644 src/lib/vendor/openssl/openssl.h delete mode 100644 src/lib/vendor/openssl/openssl_block.cpp delete mode 100644 src/lib/vendor/openssl/openssl_ecdsa.cpp delete mode 100644 src/lib/vendor/openssl/openssl_hash.cpp delete mode 100644 src/lib/vendor/openssl/openssl_rc4.cpp delete mode 100644 src/lib/vendor/openssl/openssl_rsa.cpp (limited to 'src/lib') 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 + + +openssl + diff --git a/src/lib/block/openssl_block/openssl_block.cpp b/src/lib/block/openssl_block/openssl_block.cpp new file mode 100644 index 000000000..a35919e3a --- /dev/null +++ b/src/lib/block/openssl_block/openssl_block.cpp @@ -0,0 +1,214 @@ +/* +* Block Ciphers via OpenSSL +* (C) 1999-2010,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +class OpenSSL_BlockCipher : public BlockCipher + { + public: + void clear(); + std::string name() const { return cipher_name; } + BlockCipher* clone() const; + + size_t block_size() const { return block_sz; } + + OpenSSL_BlockCipher(const EVP_CIPHER*, const std::string&); + + OpenSSL_BlockCipher(const EVP_CIPHER*, const std::string&, + size_t, size_t, size_t); + + Key_Length_Specification key_spec() const { return cipher_key_spec; } + + ~OpenSSL_BlockCipher(); + private: + void encrypt_n(const byte in[], byte out[], size_t blocks) const + { + int out_len = 0; + EVP_EncryptUpdate(&encrypt, out, &out_len, in, blocks * block_sz); + } + + void decrypt_n(const byte in[], byte out[], size_t blocks) const + { + int out_len = 0; + EVP_DecryptUpdate(&decrypt, out, &out_len, in, blocks * block_sz); + } + + void key_schedule(const byte[], size_t); + + size_t block_sz; + Key_Length_Specification cipher_key_spec; + std::string cipher_name; + mutable EVP_CIPHER_CTX encrypt, decrypt; + }; + +OpenSSL_BlockCipher::OpenSSL_BlockCipher(const EVP_CIPHER* algo, + const std::string& algo_name) : + block_sz(EVP_CIPHER_block_size(algo)), + cipher_key_spec(EVP_CIPHER_key_length(algo)), + cipher_name(algo_name) + { + if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE) + throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in"); + + EVP_CIPHER_CTX_init(&encrypt); + EVP_CIPHER_CTX_init(&decrypt); + + EVP_EncryptInit_ex(&encrypt, algo, nullptr, nullptr, nullptr); + EVP_DecryptInit_ex(&decrypt, algo, nullptr, nullptr, nullptr); + + EVP_CIPHER_CTX_set_padding(&encrypt, 0); + EVP_CIPHER_CTX_set_padding(&decrypt, 0); + } + +OpenSSL_BlockCipher::OpenSSL_BlockCipher(const EVP_CIPHER* algo, + const std::string& algo_name, + size_t key_min, size_t key_max, + size_t key_mod) : + block_sz(EVP_CIPHER_block_size(algo)), + cipher_key_spec(key_min, key_max, key_mod), + cipher_name(algo_name) + { + if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE) + throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in"); + + EVP_CIPHER_CTX_init(&encrypt); + EVP_CIPHER_CTX_init(&decrypt); + + EVP_EncryptInit_ex(&encrypt, algo, nullptr, nullptr, nullptr); + EVP_DecryptInit_ex(&decrypt, algo, nullptr, nullptr, nullptr); + + EVP_CIPHER_CTX_set_padding(&encrypt, 0); + EVP_CIPHER_CTX_set_padding(&decrypt, 0); + } + +OpenSSL_BlockCipher::~OpenSSL_BlockCipher() + { + EVP_CIPHER_CTX_cleanup(&encrypt); + EVP_CIPHER_CTX_cleanup(&decrypt); + } + +/* +* Set the key +*/ +void OpenSSL_BlockCipher::key_schedule(const byte key[], size_t length) + { + secure_vector full_key(key, key + length); + + if(cipher_name == "TripleDES" && length == 16) + { + full_key += std::make_pair(key, 8); + } + else + if(EVP_CIPHER_CTX_set_key_length(&encrypt, length) == 0 || + EVP_CIPHER_CTX_set_key_length(&decrypt, length) == 0) + throw Invalid_Argument("OpenSSL_BlockCipher: Bad key length for " + + cipher_name); + + EVP_EncryptInit_ex(&encrypt, nullptr, nullptr, full_key.data(), nullptr); + EVP_DecryptInit_ex(&decrypt, nullptr, nullptr, full_key.data(), nullptr); + } + +/* +* Return a clone of this object +*/ +BlockCipher* OpenSSL_BlockCipher::clone() const + { + return new OpenSSL_BlockCipher(EVP_CIPHER_CTX_cipher(&encrypt), + cipher_name, + cipher_key_spec.minimum_keylength(), + cipher_key_spec.maximum_keylength(), + cipher_key_spec.keylength_multiple()); + } + +/* +* Clear memory of sensitive data +*/ +void OpenSSL_BlockCipher::clear() + { + const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(&encrypt); + + EVP_CIPHER_CTX_cleanup(&encrypt); + EVP_CIPHER_CTX_cleanup(&decrypt); + EVP_CIPHER_CTX_init(&encrypt); + EVP_CIPHER_CTX_init(&decrypt); + EVP_EncryptInit_ex(&encrypt, algo, nullptr, nullptr, nullptr); + EVP_DecryptInit_ex(&decrypt, algo, nullptr, nullptr, nullptr); + EVP_CIPHER_CTX_set_padding(&encrypt, 0); + EVP_CIPHER_CTX_set_padding(&decrypt, 0); + } + +std::function +make_evp_block_maker(const EVP_CIPHER* cipher, const char* algo) + { + return [cipher,algo](const BlockCipher::Spec&) + { + return new OpenSSL_BlockCipher(cipher, algo); + }; + } + +std::function +make_evp_block_maker_keylen(const EVP_CIPHER* cipher, const char* algo, + size_t kmin, size_t kmax, size_t kmod) + { + return [cipher,algo,kmin,kmax,kmod](const BlockCipher::Spec&) + { + return new OpenSSL_BlockCipher(cipher, algo, kmin, kmax, kmod); + }; + } + +#define BOTAN_REGISTER_OPENSSL_EVP_BLOCK(NAME, EVP) \ + BOTAN_REGISTER_TYPE(BlockCipher, EVP_BlockCipher ## EVP, NAME, \ + 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", BOTAN_OPENSSL_BLOCK_PRIO); + +#if !defined(OPENSSL_NO_AES) + BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-128", EVP_aes_128_ecb); + BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-192", EVP_aes_192_ecb); + BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-256", EVP_aes_256_ecb); +#endif + +#if !defined(OPENSSL_NO_DES) + BOTAN_REGISTER_OPENSSL_EVP_BLOCK("DES", EVP_des_ecb); + BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN("TripleDES", EVP_des_ede3_ecb, 16, 24, 8); +#endif + +#if !defined(OPENSSL_NO_BF) + BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN("Blowfish", EVP_bf_ecb, 1, 56, 1); +#endif + +#if !defined(OPENSSL_NO_CAST) + BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN("CAST-128", EVP_cast5_ecb, 1, 16, 1); +#endif + +#if !defined(OPENSSL_NO_CAMELLIA) + BOTAN_REGISTER_OPENSSL_EVP_BLOCK("Camellia-128", EVP_camellia_128_ecb); + BOTAN_REGISTER_OPENSSL_EVP_BLOCK("Camellia-192", EVP_camellia_192_ecb); + BOTAN_REGISTER_OPENSSL_EVP_BLOCK("Camellia-256", EVP_camellia_256_ecb); +#endif + +#if !defined(OPENSSL_NO_IDEA) + BOTAN_REGISTER_OPENSSL_EVP_BLOCK("IDEA", EVP_idea_ecb); +#endif + +#if !defined(OPENSSL_NO_SEED) + BOTAN_REGISTER_OPENSSL_EVP_BLOCK("SEED", EVP_seed_ecb); +#endif + +} + +} 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 + + +openssl + diff --git a/src/lib/hash/openssl_hash/openssl_hash.cpp b/src/lib/hash/openssl_hash/openssl_hash.cpp new file mode 100644 index 000000000..c89dd777d --- /dev/null +++ b/src/lib/hash/openssl_hash/openssl_hash.cpp @@ -0,0 +1,117 @@ +/* +* OpenSSL Hash Functions +* (C) 1999-2007,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +class OpenSSL_HashFunction : public HashFunction + { + public: + void clear() + { + const EVP_MD* algo = EVP_MD_CTX_md(&m_md); + EVP_DigestInit_ex(&m_md, algo, nullptr); + } + + std::string name() const { return m_name; } + + HashFunction* clone() const + { + const EVP_MD* algo = EVP_MD_CTX_md(&m_md); + return new OpenSSL_HashFunction(algo, name()); + } + + size_t output_length() const + { + return EVP_MD_size(EVP_MD_CTX_md(&m_md)); + } + + size_t hash_block_size() const + { + return EVP_MD_block_size(EVP_MD_CTX_md(&m_md)); + } + + OpenSSL_HashFunction(const EVP_MD* md, const std::string& name) : m_name(name) + { + EVP_MD_CTX_init(&m_md); + EVP_DigestInit_ex(&m_md, md, nullptr); + } + + ~OpenSSL_HashFunction() + { + EVP_MD_CTX_cleanup(&m_md); + } + + private: + void add_data(const byte input[], size_t length) + { + EVP_DigestUpdate(&m_md, input, length); + } + + void final_result(byte output[]) + { + EVP_DigestFinal_ex(&m_md, output, nullptr); + const EVP_MD* algo = EVP_MD_CTX_md(&m_md); + EVP_DigestInit_ex(&m_md, algo, nullptr); + } + + std::string m_name; + EVP_MD_CTX m_md; + }; + +std::function +make_evp_hash_maker(const EVP_MD* md, const char* algo) + { + return [md,algo](const HashFunction::Spec&) + { + return new OpenSSL_HashFunction(md, algo); + }; + } + +#define BOTAN_REGISTER_OPENSSL_EVP_HASH(NAME, EVP) \ + BOTAN_REGISTER_TYPE(HashFunction, OpenSSL_HashFunction ## EVP, NAME, \ + 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); +#endif + +#if !defined(OPENSSL_NO_SHA256) + BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-224", EVP_sha224); + BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-256", EVP_sha256); +#endif + +#if !defined(OPENSSL_NO_SHA512) + BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-384", EVP_sha384); + BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-512", EVP_sha512); +#endif + +#if !defined(OPENSSL_NO_MD2) + BOTAN_REGISTER_OPENSSL_EVP_HASH("MD2", EVP_md2); +#endif + +#if !defined(OPENSSL_NO_MD4) + BOTAN_REGISTER_OPENSSL_EVP_HASH("MD4", EVP_md4); +#endif + +#if !defined(OPENSSL_NO_MD5) + BOTAN_REGISTER_OPENSSL_EVP_HASH("MD5", EVP_md5); +#endif + +#if !defined(OPENSSL_NO_RIPEMD) + BOTAN_REGISTER_OPENSSL_EVP_HASH("RIPEMD-160", EVP_ripemd160); +#endif + +} + +} 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 + +#if defined(BOTAN_HAS_OPENSSL) + +#include +#include + +#if !defined(OPENSSL_NO_ECDSA) + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace Botan { + +namespace { + +secure_vector 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(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 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(&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> 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 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> 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> 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(&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 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 raw_sign(const byte msg[], size_t msg_len, + RandomNumberGenerator&) override + { + std::unique_ptr> 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 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> 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/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 + +#if defined(BOTAN_HAS_OPENSSL) + +#include +#include +#include +#include + +#include +#include +#include + +namespace Botan { + +namespace { + +std::pair 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 strip_leading_zeros(const secure_vector& input) + { + size_t leading_zeros = 0; + + for(size_t i = 0; i != input.size(); ++i) + { + if(input[i] != 0) + break; + ++leading_zeros; + } + + secure_vector 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(&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 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 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 outbuf(mod_sz); + + secure_vector 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> 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(&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 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 decrypt(const byte msg[], size_t msg_len) override + { + secure_vector 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(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> 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(&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 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 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 inbuf(mod_sz); + copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len); + + secure_vector 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> 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(&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 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 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 inbuf(mod_sz); + copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len); + + secure_vector 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> 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/stream/rc4/openssl_rc4.cpp b/src/lib/stream/rc4/openssl_rc4.cpp new file mode 100644 index 000000000..e4f180a9b --- /dev/null +++ b/src/lib/stream/rc4/openssl_rc4.cpp @@ -0,0 +1,61 @@ +/* +* OpenSSL RC4 +* (C) 1999-2007,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +#if defined(BOTAN_HAS_OPENSSL) + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +class OpenSSL_RC4 : public StreamCipher + { + public: + void clear() { clear_mem(&m_rc4, 1); } + + std::string name() const { return "RC4"; } + StreamCipher* clone() const { return new OpenSSL_RC4; } + + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(1, 32); + } + + OpenSSL_RC4(size_t skip = 0) : m_skip(skip) { clear(); } + ~OpenSSL_RC4() { clear(); } + private: + void cipher(const byte in[], byte out[], size_t length) + { + ::RC4(&m_rc4, length, in, out); + } + + void key_schedule(const byte key[], size_t length) + { + ::RC4_set_key(&m_rc4, length, key); + byte d = 0; + for(size_t i = 0; i != m_skip; ++i) + ::RC4(&m_rc4, 1, &d, &d); + } + + size_t m_skip; + RC4_KEY m_rc4; + }; + +} + +BOTAN_REGISTER_TYPE(StreamCipher, OpenSSL_RC4, "RC4", (make_new_T_1len), + "openssl", BOTAN_OPENSSL_RC4_PRIO); + +} + +#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 + + +openssl.h + + + +all -> crypto + diff --git a/src/lib/utils/openssl/openssl.h b/src/lib/utils/openssl/openssl.h new file mode 100644 index 000000000..022db6223 --- /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 +#include +#include + +#include + +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 150 +#define BOTAN_OPENSSL_ECDSA_PRIO 150 + +} + +#endif diff --git a/src/lib/vendor/openssl/info.txt b/src/lib/vendor/openssl/info.txt deleted file mode 100644 index 1381e2019..000000000 --- a/src/lib/vendor/openssl/info.txt +++ /dev/null @@ -1,11 +0,0 @@ -define OPENSSL 20150829 - -load_on vendor - - -openssl.h - - - -all -> crypto - diff --git a/src/lib/vendor/openssl/openssl.h b/src/lib/vendor/openssl/openssl.h deleted file mode 100644 index 86cc8fd35..000000000 --- a/src/lib/vendor/openssl/openssl.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* 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 -#include -#include - -#include - -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/vendor/openssl/openssl_block.cpp b/src/lib/vendor/openssl/openssl_block.cpp deleted file mode 100644 index 5c28f46b1..000000000 --- a/src/lib/vendor/openssl/openssl_block.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* -* Block Ciphers via OpenSSL -* (C) 1999-2010,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include -#include -#include - -namespace Botan { - -namespace { - -class OpenSSL_BlockCipher : public BlockCipher - { - public: - void clear(); - std::string name() const { return cipher_name; } - BlockCipher* clone() const; - - size_t block_size() const { return block_sz; } - - OpenSSL_BlockCipher(const EVP_CIPHER*, const std::string&); - - OpenSSL_BlockCipher(const EVP_CIPHER*, const std::string&, - size_t, size_t, size_t); - - Key_Length_Specification key_spec() const { return cipher_key_spec; } - - ~OpenSSL_BlockCipher(); - private: - void encrypt_n(const byte in[], byte out[], size_t blocks) const - { - int out_len = 0; - EVP_EncryptUpdate(&encrypt, out, &out_len, in, blocks * block_sz); - } - - void decrypt_n(const byte in[], byte out[], size_t blocks) const - { - int out_len = 0; - EVP_DecryptUpdate(&decrypt, out, &out_len, in, blocks * block_sz); - } - - void key_schedule(const byte[], size_t); - - size_t block_sz; - Key_Length_Specification cipher_key_spec; - std::string cipher_name; - mutable EVP_CIPHER_CTX encrypt, decrypt; - }; - -OpenSSL_BlockCipher::OpenSSL_BlockCipher(const EVP_CIPHER* algo, - const std::string& algo_name) : - block_sz(EVP_CIPHER_block_size(algo)), - cipher_key_spec(EVP_CIPHER_key_length(algo)), - cipher_name(algo_name) - { - if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE) - throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in"); - - EVP_CIPHER_CTX_init(&encrypt); - EVP_CIPHER_CTX_init(&decrypt); - - EVP_EncryptInit_ex(&encrypt, algo, nullptr, nullptr, nullptr); - EVP_DecryptInit_ex(&decrypt, algo, nullptr, nullptr, nullptr); - - EVP_CIPHER_CTX_set_padding(&encrypt, 0); - EVP_CIPHER_CTX_set_padding(&decrypt, 0); - } - -OpenSSL_BlockCipher::OpenSSL_BlockCipher(const EVP_CIPHER* algo, - const std::string& algo_name, - size_t key_min, size_t key_max, - size_t key_mod) : - block_sz(EVP_CIPHER_block_size(algo)), - cipher_key_spec(key_min, key_max, key_mod), - cipher_name(algo_name) - { - if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE) - throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in"); - - EVP_CIPHER_CTX_init(&encrypt); - EVP_CIPHER_CTX_init(&decrypt); - - EVP_EncryptInit_ex(&encrypt, algo, nullptr, nullptr, nullptr); - EVP_DecryptInit_ex(&decrypt, algo, nullptr, nullptr, nullptr); - - EVP_CIPHER_CTX_set_padding(&encrypt, 0); - EVP_CIPHER_CTX_set_padding(&decrypt, 0); - } - -OpenSSL_BlockCipher::~OpenSSL_BlockCipher() - { - EVP_CIPHER_CTX_cleanup(&encrypt); - EVP_CIPHER_CTX_cleanup(&decrypt); - } - -/* -* Set the key -*/ -void OpenSSL_BlockCipher::key_schedule(const byte key[], size_t length) - { - secure_vector full_key(key, key + length); - - if(cipher_name == "TripleDES" && length == 16) - { - full_key += std::make_pair(key, 8); - } - else - if(EVP_CIPHER_CTX_set_key_length(&encrypt, length) == 0 || - EVP_CIPHER_CTX_set_key_length(&decrypt, length) == 0) - throw Invalid_Argument("OpenSSL_BlockCipher: Bad key length for " + - cipher_name); - - EVP_EncryptInit_ex(&encrypt, nullptr, nullptr, full_key.data(), nullptr); - EVP_DecryptInit_ex(&decrypt, nullptr, nullptr, full_key.data(), nullptr); - } - -/* -* Return a clone of this object -*/ -BlockCipher* OpenSSL_BlockCipher::clone() const - { - return new OpenSSL_BlockCipher(EVP_CIPHER_CTX_cipher(&encrypt), - cipher_name, - cipher_key_spec.minimum_keylength(), - cipher_key_spec.maximum_keylength(), - cipher_key_spec.keylength_multiple()); - } - -/* -* Clear memory of sensitive data -*/ -void OpenSSL_BlockCipher::clear() - { - const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(&encrypt); - - EVP_CIPHER_CTX_cleanup(&encrypt); - EVP_CIPHER_CTX_cleanup(&decrypt); - EVP_CIPHER_CTX_init(&encrypt); - EVP_CIPHER_CTX_init(&decrypt); - EVP_EncryptInit_ex(&encrypt, algo, nullptr, nullptr, nullptr); - EVP_DecryptInit_ex(&decrypt, algo, nullptr, nullptr, nullptr); - EVP_CIPHER_CTX_set_padding(&encrypt, 0); - EVP_CIPHER_CTX_set_padding(&decrypt, 0); - } - -std::function -make_evp_block_maker(const EVP_CIPHER* cipher, const char* algo) - { - return [cipher,algo](const BlockCipher::Spec&) - { - return new OpenSSL_BlockCipher(cipher, algo); - }; - } - -std::function -make_evp_block_maker_keylen(const EVP_CIPHER* cipher, const char* algo, - size_t kmin, size_t kmax, size_t kmod) - { - return [cipher,algo,kmin,kmax,kmod](const BlockCipher::Spec&) - { - return new OpenSSL_BlockCipher(cipher, algo, kmin, kmax, kmod); - }; - } - -#define BOTAN_OPENSSL_BLOCK_PRIO 150 - -#define BOTAN_REGISTER_OPENSSL_EVP_BLOCK(NAME, EVP) \ - BOTAN_REGISTER_TYPE(BlockCipher, EVP_BlockCipher ## EVP, NAME, \ - 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", BOTAN_OPENSSL_BLOCK_PRIO); - -#if !defined(OPENSSL_NO_AES) - BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-128", EVP_aes_128_ecb); - BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-192", EVP_aes_192_ecb); - BOTAN_REGISTER_OPENSSL_EVP_BLOCK("AES-256", EVP_aes_256_ecb); -#endif - -#if !defined(OPENSSL_NO_DES) - BOTAN_REGISTER_OPENSSL_EVP_BLOCK("DES", EVP_des_ecb); - BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN("TripleDES", EVP_des_ede3_ecb, 16, 24, 8); -#endif - -#if !defined(OPENSSL_NO_BF) - BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN("Blowfish", EVP_bf_ecb, 1, 56, 1); -#endif - -#if !defined(OPENSSL_NO_CAST) - BOTAN_REGISTER_OPENSSL_EVP_BLOCK_KEYLEN("CAST-128", EVP_cast5_ecb, 1, 16, 1); -#endif - -#if !defined(OPENSSL_NO_CAMELLIA) - BOTAN_REGISTER_OPENSSL_EVP_BLOCK("Camellia-128", EVP_camellia_128_ecb); - BOTAN_REGISTER_OPENSSL_EVP_BLOCK("Camellia-192", EVP_camellia_192_ecb); - BOTAN_REGISTER_OPENSSL_EVP_BLOCK("Camellia-256", EVP_camellia_256_ecb); -#endif - -#if !defined(OPENSSL_NO_IDEA) - BOTAN_REGISTER_OPENSSL_EVP_BLOCK("IDEA", EVP_idea_ecb); -#endif - -#if !defined(OPENSSL_NO_SEED) - BOTAN_REGISTER_OPENSSL_EVP_BLOCK("SEED", EVP_seed_ecb); -#endif - -} - -} diff --git a/src/lib/vendor/openssl/openssl_ecdsa.cpp b/src/lib/vendor/openssl/openssl_ecdsa.cpp deleted file mode 100644 index 0651cc280..000000000 --- a/src/lib/vendor/openssl/openssl_ecdsa.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* -* ECDSA via OpenSSL -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include - -#if defined(BOTAN_HAS_ECDSA) && !defined(OPENSSL_NO_ECDSA) - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace Botan { - -namespace { - -secure_vector 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(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 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(&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> 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 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> 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> 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(&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 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 raw_sign(const byte msg[], size_t msg_len, - RandomNumberGenerator&) override - { - std::unique_ptr> 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 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> 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 // BOTAN_HAS_ECDSA && !OPENSSL_NO_ECDSA diff --git a/src/lib/vendor/openssl/openssl_hash.cpp b/src/lib/vendor/openssl/openssl_hash.cpp deleted file mode 100644 index c89dd777d..000000000 --- a/src/lib/vendor/openssl/openssl_hash.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* -* OpenSSL Hash Functions -* (C) 1999-2007,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include -#include -#include - -namespace Botan { - -namespace { - -class OpenSSL_HashFunction : public HashFunction - { - public: - void clear() - { - const EVP_MD* algo = EVP_MD_CTX_md(&m_md); - EVP_DigestInit_ex(&m_md, algo, nullptr); - } - - std::string name() const { return m_name; } - - HashFunction* clone() const - { - const EVP_MD* algo = EVP_MD_CTX_md(&m_md); - return new OpenSSL_HashFunction(algo, name()); - } - - size_t output_length() const - { - return EVP_MD_size(EVP_MD_CTX_md(&m_md)); - } - - size_t hash_block_size() const - { - return EVP_MD_block_size(EVP_MD_CTX_md(&m_md)); - } - - OpenSSL_HashFunction(const EVP_MD* md, const std::string& name) : m_name(name) - { - EVP_MD_CTX_init(&m_md); - EVP_DigestInit_ex(&m_md, md, nullptr); - } - - ~OpenSSL_HashFunction() - { - EVP_MD_CTX_cleanup(&m_md); - } - - private: - void add_data(const byte input[], size_t length) - { - EVP_DigestUpdate(&m_md, input, length); - } - - void final_result(byte output[]) - { - EVP_DigestFinal_ex(&m_md, output, nullptr); - const EVP_MD* algo = EVP_MD_CTX_md(&m_md); - EVP_DigestInit_ex(&m_md, algo, nullptr); - } - - std::string m_name; - EVP_MD_CTX m_md; - }; - -std::function -make_evp_hash_maker(const EVP_MD* md, const char* algo) - { - return [md,algo](const HashFunction::Spec&) - { - return new OpenSSL_HashFunction(md, algo); - }; - } - -#define BOTAN_REGISTER_OPENSSL_EVP_HASH(NAME, EVP) \ - BOTAN_REGISTER_TYPE(HashFunction, OpenSSL_HashFunction ## EVP, NAME, \ - 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); -#endif - -#if !defined(OPENSSL_NO_SHA256) - BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-224", EVP_sha224); - BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-256", EVP_sha256); -#endif - -#if !defined(OPENSSL_NO_SHA512) - BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-384", EVP_sha384); - BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-512", EVP_sha512); -#endif - -#if !defined(OPENSSL_NO_MD2) - BOTAN_REGISTER_OPENSSL_EVP_HASH("MD2", EVP_md2); -#endif - -#if !defined(OPENSSL_NO_MD4) - BOTAN_REGISTER_OPENSSL_EVP_HASH("MD4", EVP_md4); -#endif - -#if !defined(OPENSSL_NO_MD5) - BOTAN_REGISTER_OPENSSL_EVP_HASH("MD5", EVP_md5); -#endif - -#if !defined(OPENSSL_NO_RIPEMD) - BOTAN_REGISTER_OPENSSL_EVP_HASH("RIPEMD-160", EVP_ripemd160); -#endif - -} - -} diff --git a/src/lib/vendor/openssl/openssl_rc4.cpp b/src/lib/vendor/openssl/openssl_rc4.cpp deleted file mode 100644 index 1f5675095..000000000 --- a/src/lib/vendor/openssl/openssl_rc4.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* -* OpenSSL RC4 -* (C) 1999-2007,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include -#include -#include -#include - -namespace Botan { - -namespace { - -class OpenSSL_RC4 : public StreamCipher - { - public: - void clear() { clear_mem(&m_rc4, 1); } - - std::string name() const { return "RC4"; } - StreamCipher* clone() const { return new OpenSSL_RC4; } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(1, 32); - } - - OpenSSL_RC4(size_t skip = 0) : m_skip(skip) { clear(); } - ~OpenSSL_RC4() { clear(); } - private: - void cipher(const byte in[], byte out[], size_t length) - { - ::RC4(&m_rc4, length, in, out); - } - - void key_schedule(const byte key[], size_t length) - { - ::RC4_set_key(&m_rc4, length, key); - byte d = 0; - for(size_t i = 0; i != m_skip; ++i) - ::RC4(&m_rc4, 1, &d, &d); - } - - size_t m_skip; - RC4_KEY m_rc4; - }; - -} - -BOTAN_REGISTER_TYPE(StreamCipher, OpenSSL_RC4, "RC4", (make_new_T_1len), - "openssl", BOTAN_OPENSSL_RC4_PRIO); - -} diff --git a/src/lib/vendor/openssl/openssl_rsa.cpp b/src/lib/vendor/openssl/openssl_rsa.cpp deleted file mode 100644 index 3a7cd0dcf..000000000 --- a/src/lib/vendor/openssl/openssl_rsa.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* -* OpenSSL RSA interface -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include - -#if defined(BOTAN_HAS_RSA) - -#include -#include -#include -#include - -#include -#include -#include - -namespace Botan { - -namespace { - -std::pair 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 strip_leading_zeros(const secure_vector& input) - { - size_t leading_zeros = 0; - - for(size_t i = 0; i != input.size(); ++i) - { - if(input[i] != 0) - break; - ++leading_zeros; - } - - secure_vector 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(&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 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 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 outbuf(mod_sz); - - secure_vector 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> 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(&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 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 decrypt(const byte msg[], size_t msg_len) override - { - secure_vector 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(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> 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(&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 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 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 inbuf(mod_sz); - copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len); - - secure_vector 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> 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(&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 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 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 inbuf(mod_sz); - copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len); - - secure_vector 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> 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_RSA -- cgit v1.2.3 From e607a5d625762806048074a8819840bcd6341fa3 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 19 Oct 2015 19:38:33 -0400 Subject: Add missing BOTAN_DLL to Decompression_Filter. GH #304 --- src/lib/filters/comp_filter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') 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, -- cgit v1.2.3 From ee396e6fa028184cf715351311ba3c41e7b8228e Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 19 Oct 2015 20:05:33 -0400 Subject: Make OpenSSL ECDSA and RSA request only until they can be tested --- src/lib/utils/openssl/openssl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/utils/openssl/openssl.h b/src/lib/utils/openssl/openssl.h index 022db6223..05d3e953f 100644 --- a/src/lib/utils/openssl/openssl.h +++ b/src/lib/utils/openssl/openssl.h @@ -27,8 +27,8 @@ class OpenSSL_Error : public Exception #define BOTAN_OPENSSL_HASH_PRIO 150 #define BOTAN_OPENSSL_RC4_PRIO 150 -#define BOTAN_OPENSSL_RSA_PRIO 150 -#define BOTAN_OPENSSL_ECDSA_PRIO 150 +#define BOTAN_OPENSSL_RSA_PRIO 90 +#define BOTAN_OPENSSL_ECDSA_PRIO 90 } -- cgit v1.2.3