Package: release.debian.org Followup-For: Bug #701817 User: release.debian....@packages.debian.org Usertags: unblock
Don't press ENTER after adding patch. -- System Information: Debian Release: 7.0 APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.2.0-3-amd64 (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash
# # # patch "src/pubkey/dh/dh.cpp" # from [87394105b44ac22e9f8727335586b5ae9c95acbb] # to [fd216f648a465f32e2626653acd54b4a36e27d97] # ============================================================ --- src/pubkey/dh/dh.cpp 87394105b44ac22e9f8727335586b5ae9c95acbb +++ src/pubkey/dh/dh.cpp fd216f648a465f32e2626653acd54b4a36e27d97 @@ -87,6 +87,9 @@ SecureVector<byte> DH_KA_Operation::agre { BigInt input = BigInt::decode(w, w_len); + if(input <= 1 || input >= p - 1) + throw Invalid_Argument("DH agreement - invalid key provided"); + BigInt r = blinder.unblind(powermod_x_p(blinder.blind(input))); return BigInt::encode_1363(r, p.bytes());
diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt index e5d52db..cbcfd89 100644 --- a/src/build-data/cc/clang.txt +++ b/src/build-data/cc/clang.txt @@ -27,6 +27,8 @@ visibility_attribute '__attribute__((visibility("default")))' <so_link_flags> # The default works for GNU ld and several other Unix linkers default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" + +darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)" </so_link_flags> <mach_opt>
diff --git a/doc/examples/cms_dec.cpp b/doc/examples/cms_dec.cpp deleted file mode 100644 index 84355fb..0000000 --- a/doc/examples/cms_dec.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/pkcs8.h> -#include <botan/cms_dec.h> -using namespace Botan; - -#include <iostream> -#include <memory> - -int main(int argc, char* argv[]) - { - if(argc != 2) - { - std::cout << "Usage: " << argv[0] << " <filename>\n"; - return 1; - } - - Botan::LibraryInitializer init; - - try { - AutoSeeded_RNG rng; - - X509_Certificate mycert("mycert.pem"); - PKCS8_PrivateKey* mykey = PKCS8::load_key("mykey.pem", rng, "cut"); - - X509_Certificate yourcert("yourcert.pem"); - X509_Certificate cacert("cacert.pem"); - X509_Certificate int_ca("int_ca.pem"); - - X509_Store store; - store.add_cert(mycert); - store.add_cert(yourcert); - store.add_cert(cacert, true); - store.add_cert(int_ca); - - DataSource_Stream message(argv[1]); - - CMS_Decoder decoder(message, store, mykey); - - while(decoder.layer_type() != CMS_Decoder::DATA) - { - CMS_Decoder::Status status = decoder.layer_status(); - CMS_Decoder::Content_Type content = decoder.layer_type(); - - if(status == CMS_Decoder::FAILURE) - { - std::cout << "Failure reading CMS data" << std::endl; - break; - } - - if(content == CMS_Decoder::DIGESTED) - { - std::cout << "Digested data, hash = " << decoder.layer_info() - << std::endl; - std::cout << "Hash is " - << ((status == CMS_Decoder::GOOD) ? "good" : "bad") - << std::endl; - } - - if(content == CMS_Decoder::SIGNED) - { - // how to handle multiple signers? they can all exist within a - // single level... - - std::cout << "Signed by " << decoder.layer_info() << std::endl; - //std::cout << "Sign time: " << decoder.xxx() << std::endl; - std::cout << "Signature is "; - if(status == CMS_Decoder::GOOD) - std::cout << "valid"; - else if(status == CMS_Decoder::BAD) - std::cout << "bad"; - else if(status == CMS_Decoder::NO_KEY) - std::cout << "(cannot check, no known cert)"; - std::cout << std::endl; - } - if(content == CMS_Decoder::ENVELOPED || - content == CMS_Decoder::COMPRESSED || - content == CMS_Decoder::AUTHENTICATED) - { - if(content == CMS_Decoder::ENVELOPED) - std::cout << "Enveloped"; - if(content == CMS_Decoder::COMPRESSED) - std::cout << "Compressed"; - if(content == CMS_Decoder::AUTHENTICATED) - std::cout << "MACed"; - - std::cout << ", algo = " << decoder.layer_info() << std::endl; - - if(content == CMS_Decoder::AUTHENTICATED) - { - std::cout << "MAC status is "; - if(status == CMS_Decoder::GOOD) - std::cout << "valid"; - else if(status == CMS_Decoder::BAD) - std::cout << "bad"; - else if(status == CMS_Decoder::NO_KEY) - std::cout << "(cannot check, no key)"; - std::cout << std::endl; - } - } - decoder.next_layer(); - } - - if(decoder.layer_type() == CMS_Decoder::DATA) - std::cout << "Message is \"" << decoder.get_data() - << '"' << std::endl; - else - std::cout << "No data anywhere?" << std::endl; - } - catch(std::exception& e) - { - std::cerr << e.what() << std::endl; - } - return 0; - } diff --git a/doc/examples/cms_enc.cpp b/doc/examples/cms_enc.cpp deleted file mode 100644 index 2cf8139..0000000 --- a/doc/examples/cms_enc.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/cms_enc.h> -using namespace Botan; - -#include <iostream> -#include <fstream> -#include <memory> - -int main() - { - Botan::LibraryInitializer init; - - try { - - X509_Certificate mycert("mycert.pem"); - X509_Certificate mycert2("mycert2.pem"); - X509_Certificate yourcert("yourcert.pem"); - X509_Certificate cacert("cacert.pem"); - X509_Certificate int_ca("int_ca.pem"); - - AutoSeeded_RNG rng; - - X509_Store store; - store.add_cert(mycert); - store.add_cert(mycert2); - store.add_cert(yourcert); - store.add_cert(int_ca); - store.add_cert(cacert, true); - - const std::string msg = "prioncorp: we don't toy\n"; - - CMS_Encoder encoder(msg); - - encoder.compress("Zlib"); - encoder.digest(); - encoder.encrypt(rng, mycert); - - /* - PKCS8_PrivateKey* mykey = PKCS8::load_key("mykey.pem", rng, "cut"); - encoder.sign(store, *mykey); - */ - - SecureVector<byte> raw = encoder.get_contents(); - std::ofstream out("out.der"); - - out.write((const char*)raw.begin(), raw.size()); - } - catch(std::exception& e) - { - std::cerr << e.what() << std::endl; - } - return 0; - }
# # # patch "src/block/aes_ni/aes_ni.cpp" # from [2c76b0260cf49b6d1fb9fe08b1917772f0a95144] # to [21547e78fa5bdeb0998b3086ed8de2318c95ad22] # ============================================================ --- src/block/aes_ni/aes_ni.cpp 2c76b0260cf49b6d1fb9fe08b1917772f0a95144 +++ src/block/aes_ni/aes_ni.cpp 21547e78fa5bdeb0998b3086ed8de2318c95ad22 @@ -502,19 +502,19 @@ void AES_192_NI::key_schedule(const byte // Now generate decryption keys const __m128i* EK_mm = (const __m128i*)&EK[0]; __m128i* DK_mm = (__m128i*)&DK[0]; - _mm_storeu_si128(DK_mm , EK_mm[12]); - _mm_storeu_si128(DK_mm + 1, _mm_aesimc_si128(EK_mm[11])); - _mm_storeu_si128(DK_mm + 2, _mm_aesimc_si128(EK_mm[10])); - _mm_storeu_si128(DK_mm + 3, _mm_aesimc_si128(EK_mm[9])); - _mm_storeu_si128(DK_mm + 4, _mm_aesimc_si128(EK_mm[8])); - _mm_storeu_si128(DK_mm + 5, _mm_aesimc_si128(EK_mm[7])); - _mm_storeu_si128(DK_mm + 6, _mm_aesimc_si128(EK_mm[6])); - _mm_storeu_si128(DK_mm + 7, _mm_aesimc_si128(EK_mm[5])); - _mm_storeu_si128(DK_mm + 8, _mm_aesimc_si128(EK_mm[4])); - _mm_storeu_si128(DK_mm + 9, _mm_aesimc_si128(EK_mm[3])); - _mm_storeu_si128(DK_mm + 10, _mm_aesimc_si128(EK_mm[2])); - _mm_storeu_si128(DK_mm + 11, _mm_aesimc_si128(EK_mm[1])); - _mm_storeu_si128(DK_mm + 12, EK_mm[0]); + _mm_storeu_si128(DK_mm , _mm_loadu_si128(EK_mm + 12)); + _mm_storeu_si128(DK_mm + 1, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 11))); + _mm_storeu_si128(DK_mm + 2, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 10))); + _mm_storeu_si128(DK_mm + 3, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 9))); + _mm_storeu_si128(DK_mm + 4, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 8))); + _mm_storeu_si128(DK_mm + 5, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 7))); + _mm_storeu_si128(DK_mm + 6, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 6))); + _mm_storeu_si128(DK_mm + 7, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 5))); + _mm_storeu_si128(DK_mm + 8, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 4))); + _mm_storeu_si128(DK_mm + 9, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 3))); + _mm_storeu_si128(DK_mm + 10, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 2))); + _mm_storeu_si128(DK_mm + 11, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 1))); + _mm_storeu_si128(DK_mm + 12, _mm_loadu_si128(EK_mm + 0)); } /*
# # # patch "src/math/numbertheory/powm_fw.cpp" # from [f45138adaa732e081a2c84119219eeb92bbaf0e5] # to [e5892d42e4358a17d21df2b4e95f1dc4bbc78ee6] # # patch "src/math/numbertheory/powm_mnt.cpp" # from [137847433d694030a4e011527252dfb98a792631] # to [6187ca0010f88bb9f172379979cd782fc93753b4] # ============================================================ --- src/math/numbertheory/powm_fw.cpp f45138adaa732e081a2c84119219eeb92bbaf0e5 +++ src/math/numbertheory/powm_fw.cpp e5892d42e4358a17d21df2b4e95f1dc4bbc78ee6 @@ -26,10 +26,12 @@ void Fixed_Window_Exponentiator::set_bas { window_bits = Power_Mod::window_bits(exp.bits(), base.bits(), hints); - g.resize((1 << window_bits) - 1); - g[0] = base; - for(size_t j = 1; j != g.size(); ++j) - g[j] = reducer.multiply(g[j-1], g[0]); + g.resize((1 << window_bits)); + g[0] = 1; + g[1] = base; + + for(size_t i = 2; i != g.size(); ++i) + g[i] = reducer.multiply(g[i-1], g[0]); } /* @@ -40,13 +42,15 @@ BigInt Fixed_Window_Exponentiator::execu const size_t exp_nibbles = (exp.bits() + window_bits - 1) / window_bits; BigInt x = 1; - for(size_t j = exp_nibbles; j > 0; --j) + + for(size_t i = exp_nibbles; i > 0; --i) { - for(size_t k = 0; k != window_bits; ++k) + for(size_t j = 0; j != window_bits; ++j) x = reducer.square(x); - if(u32bit nibble = exp.get_substring(window_bits*(j-1), window_bits)) - x = reducer.multiply(x, g[nibble-1]); + const u32bit nibble = exp.get_substring(window_bits*(i-1), window_bits); + + x = reducer.multiply(x, g[nibble]); } return x; } ============================================================ --- src/math/numbertheory/powm_mnt.cpp 137847433d694030a4e011527252dfb98a792631 +++ src/math/numbertheory/powm_mnt.cpp 6187ca0010f88bb9f172379979cd782fc93753b4 @@ -27,12 +27,12 @@ void Montgomery_Exponentiator::set_base( { window_bits = Power_Mod::window_bits(exp.bits(), base.bits(), hints); - g.resize((1 << window_bits) - 1); + g.resize((1 << window_bits)); SecureVector<word> z(2 * (mod_words + 1)); SecureVector<word> workspace(z.size()); - g[0] = (base >= modulus) ? (base % modulus) : base; + g[0] = 1; bigint_monty_mul(&z[0], z.size(), g[0].data(), g[0].size(), g[0].sig_words(), @@ -42,7 +42,17 @@ void Montgomery_Exponentiator::set_base( g[0].assign(&z[0], mod_words + 1); - const BigInt& x = g[0]; + g[1] = (base >= modulus) ? (base % modulus) : base; + + bigint_monty_mul(&z[0], z.size(), + g[1].data(), g[1].size(), g[1].sig_words(), + R2.data(), R2.size(), R2.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); + + g[1].assign(&z[0], mod_words + 1); + + const BigInt& x = g[1]; const size_t x_sig = x.sig_words(); for(size_t i = 1; i != g.size(); ++i) @@ -86,19 +96,18 @@ BigInt Montgomery_Exponentiator::execute x.assign(&z[0], mod_words + 1); } - if(u32bit nibble = exp.get_substring(window_bits*(i-1), window_bits)) - { - const BigInt& y = g[nibble-1]; + const u32bit nibble = exp.get_substring(window_bits*(i-1), window_bits); - zeroise(z); - bigint_monty_mul(&z[0], z.size(), - x.data(), x.size(), x.sig_words(), - y.data(), y.size(), y.sig_words(), - modulus.data(), mod_words, mod_prime, - &workspace[0]); + const BigInt& y = g[nibble]; - x.assign(&z[0], mod_words + 1); - } + zeroise(z); + bigint_monty_mul(&z[0], z.size(), + x.data(), x.size(), x.sig_words(), + y.data(), y.size(), y.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); + + x.assign(&z[0], mod_words + 1); } x.get_reg().resize(2*mod_words+1);
# # # patch "doc/log.txt" # from [ce6e0cedba8659ef9c40a5b1c475f2a5b1437918] # to [f70aa7f591c3b65f6f82e16c7b9080b4169a60a7] # # patch "src/math/mp/mp_karat.cpp" # from [5aead6888fed71fc3fc08552d948594ff1b5b140] # to [9780759e3f3abae30b9aa3253abd3a13c8cd2daf] # ============================================================ --- src/math/mp/mp_karat.cpp 5aead6888fed71fc3fc08552d948594ff1b5b140 +++ src/math/mp/mp_karat.cpp 9780759e3f3abae30b9aa3253abd3a13c8cd2daf @@ -45,7 +45,7 @@ void karatsuba_mul(word z[], const word clear_mem(workspace, 2*N); - if(cmp0 && cmp1) + //if(cmp0 && cmp1) { if(cmp0 > 0) bigint_sub3(z0, x0, N2, x1, N2); @@ -122,7 +122,7 @@ void karatsuba_sqr(word z[], const word clear_mem(workspace, 2*N); - if(cmp) + //if(cmp) { if(cmp > 0) bigint_sub3(z0, x0, N2, x1, N2);
diff --git a/configure.py b/configure.py index 71d2a3d..b606e06 100755 --- a/configure.py +++ b/configure.py @@ -1780,7 +1780,7 @@ def main(argv = None): gcc_version = stdout.strip() logging.info('Detected gcc version %s' % (gcc_version)) - return gcc_version + return map(int, gcc_version.split('.')[0:2]) except OSError: logging.warning('Could not execute %s for version check' % (gcc_bin)) return None @@ -1792,24 +1792,29 @@ def main(argv = None): gcc_version = get_gcc_version(options.compiler_binary or cc.binary_name) + def gcc_version_matches(matches): + for match in matches.items(): + if gcc_version[0] != match[0]: + continue + + for minor in match[1]: + if minor == gcc_version[1]: + return True + return False + if gcc_version: if not is_64bit_arch(options.arch) and not options.dumb_gcc: - matching_version = '(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])' - - if re.search(matching_version, gcc_version): + if gcc_version_matches({ 4 : [0, 1, 2, 3, 4], 3 : [3, 4], 2 : [95] }): options.dumb_gcc = True - versions_without_tr1 = '(4\.0\.)|(3\.[0-4]\.)|(2\.95\.[0-4])' - if options.with_tr1 == None and \ - re.search(versions_without_tr1, gcc_version): + gcc_version_matches({ 4 : [0], 3 : [0,1,2,3,4], 2 : [95] }): logging.info('Disabling TR1 support for this gcc, too old') options.with_tr1 = 'none' - versions_without_visibility = '(3\.[0-4]\.)|(2\.95\.[0-4])' if options.with_visibility == None and \ - re.search(versions_without_visibility, gcc_version): + gcc_version_matches({ 3 : [0,1,2,3,4], 2 : [95] }): logging.info('Disabling DSO visibility support for this gcc, too old') options.with_visibility = False diff --git a/src/utils/version.cpp b/src/utils/version.cpp index acc8bee..d886587 100644 --- a/src/utils/version.cpp +++ b/src/utils/version.cpp @@ -22,21 +22,23 @@ namespace Botan { */ std::string version_string() { - std::ostringstream out; - - out << "Botan " << version_major() << "." - << version_minor() << "." - << version_patch() << " ("; - - if(BOTAN_VERSION_DATESTAMP == 0) - out << "unreleased version"; - else - out << "released " << version_datestamp(); - - out << ", revision " << BOTAN_VERSION_VC_REVISION; - out << ", distribution " << BOTAN_DISTRIBUTION_INFO << ")"; - - return out.str(); +#define QUOTE(name) #name +#define STR(macro) QUOTE(macro) + + return "Botan " STR(BOTAN_VERSION_MAJOR) "." + STR(BOTAN_VERSION_MINOR) "." + STR(BOTAN_VERSION_PATCH) " (" + +#if (BOTAN_VERSION_DATESTAMP == 0) + "unreleased version" +#else + "released " STR(BOTAN_VERSION_DATESTAMP) +#endif + ", revision " BOTAN_VERSION_VC_REVISION + ", distribution " BOTAN_DISTRIBUTION_INFO ")"; + +#undef STR +#undef QUOTE } u32bit version_datestamp() { return BOTAN_VERSION_DATESTAMP; }
# # # patch "src/constructs/srp6/srp6.cpp" # from [3c70c509526945243ea13638525bf0d7f44fe51c] # to [102f76d03f119924d17195e7223b935776c7671a] # ============================================================ --- src/constructs/srp6/srp6.cpp 3c70c509526945243ea13638525bf0d7f44fe51c +++ src/constructs/srp6/srp6.cpp 102f76d03f119924d17195e7223b935776c7671a @@ -107,7 +107,7 @@ srp6_client_agree(const std::string& ide const size_t p_bytes = group.get_p().bytes(); - if(B % p == 0) + if(B <= 0 || B >= p) throw std::runtime_error("Invalid SRP parameter from server"); BigInt k = hash_seq(hash_id, p_bytes, p, g); @@ -166,7 +166,7 @@ SymmetricKey SRP6_Server_Session::step2( SymmetricKey SRP6_Server_Session::step2(const BigInt& A) { - if(A % p == 0) + if(A <= 0 || A >= p) throw std::runtime_error("Invalid SRP parameter from client"); BigInt u = hash_seq(hash_id, p_bytes, A, B);
diff --git a/src/asn1/alg_id.cpp b/src/asn1/alg_id.cpp index 665e42f..f085d92 100644 --- a/src/asn1/alg_id.cpp +++ b/src/asn1/alg_id.cpp @@ -44,7 +44,7 @@ AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, if(option == USE_NULL_PARAM) { - parameters += std::make_pair<const byte*, size_t>( + parameters += std::pair<const byte*, size_t>( DER_NULL, sizeof(DER_NULL)); } } @@ -61,7 +61,7 @@ AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, if(option == USE_NULL_PARAM) { - parameters += std::make_pair<const byte*, size_t>( + parameters += std::pair<const byte*, size_t>( DER_NULL, sizeof(DER_NULL)); } }
diff --git a/botan_version.py b/botan_version.py index 1ad9b89..db4c1c2 100644 --- a/botan_version.py +++ b/botan_version.py @@ -1,9 +1,9 @@ release_major = 1 release_minor = 10 -release_patch = 3 +release_patch = 5 -release_vc_rev = 'mtn:7b193c2f27bc5bdbdd4297c5e53acfe4e4624bdb' +release_vc_rev = 'mtn:b20e0bf2e33c620314250dcb82eeb479219a0cfd' release_so_abi_rev = 0 -release_datestamp = 20120710 +release_datestamp = 0 diff --git a/doc/log.txt b/doc/log.txt index 5f95cf4..bc0bacb 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -7,6 +7,38 @@ Release Notes Series 1.10 ---------------------------------------- +Version 1.10.5, 2013-03-02 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* A potential crash in the AES-NI implementation of the AES-192 key + schedule (caused by misaligned loads) has been fixed. + +* A previously conditional operation in Montgomery multiplication and + squaring is now always performed, removing a possible timing + channel. + +* Use correct flags for creating a shared library on OS X under Clang. + +* Fix a compile time incompatability with Visual C++ 2012 + +Version 1.10.4, 2013-01-07 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Avoid a conditional operation in the power mod implementations on if + a nibble of the exponent was zero or not. This may help protect + against certain forms of side channel attacks. + +* The SRP6 code was checking for invalid values as specified in RFC + 5054, specifically values equal to zero mod p. However SRP would + accept negative A/B values, or ones larger than p, neither of which + should occur in a normal run of the protocol. These values are now + rejected. Credits to Timothy Prepscius for pointing out these values + are not normally used and probably signal something fishy. + +* The return value of version_string is now a compile time constant + string, so version information can be more easily extracted from + binaries. + Version 1.10.3, 2012-07-10 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/readme.txt b/readme.txt index 1044332..c98b3e6 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ -Botan 1.10.3, 2012-07-10 +Botan 1.10.5, 2013-03-02 http://botan.randombit.net/ Botan is a C++ class library for performing a wide variety of
diff -Nru botan1.10-1.10.3/botan_version.py botan1.10-1.10.5/botan_version.py --- botan1.10-1.10.3/botan_version.py 2012-07-10 15:39:57.000000000 +0200 +++ botan1.10-1.10.5/botan_version.py 2013-03-02 22:19:38.000000000 +0100 @@ -1,9 +1,9 @@ release_major = 1 release_minor = 10 -release_patch = 3 +release_patch = 5 -release_vc_rev = 'mtn:7b193c2f27bc5bdbdd4297c5e53acfe4e4624bdb' +release_vc_rev = 'mtn:b20e0bf2e33c620314250dcb82eeb479219a0cfd' release_so_abi_rev = 0 -release_datestamp = 20120710 +release_datestamp = 0 diff -Nru botan1.10-1.10.3/configure.py botan1.10-1.10.5/configure.py --- botan1.10-1.10.3/configure.py 2012-07-10 15:39:56.000000000 +0200 +++ botan1.10-1.10.5/configure.py 2013-03-02 22:19:36.000000000 +0100 @@ -1780,7 +1780,7 @@ gcc_version = stdout.strip() logging.info('Detected gcc version %s' % (gcc_version)) - return gcc_version + return map(int, gcc_version.split('.')[0:2]) except OSError: logging.warning('Could not execute %s for version check' % (gcc_bin)) return None @@ -1792,24 +1792,29 @@ gcc_version = get_gcc_version(options.compiler_binary or cc.binary_name) + def gcc_version_matches(matches): + for match in matches.items(): + if gcc_version[0] != match[0]: + continue + + for minor in match[1]: + if minor == gcc_version[1]: + return True + return False + if gcc_version: if not is_64bit_arch(options.arch) and not options.dumb_gcc: - matching_version = '(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])' - - if re.search(matching_version, gcc_version): + if gcc_version_matches({ 4 : [0, 1, 2, 3, 4], 3 : [3, 4], 2 : [95] }): options.dumb_gcc = True - versions_without_tr1 = '(4\.0\.)|(3\.[0-4]\.)|(2\.95\.[0-4])' - if options.with_tr1 == None and \ - re.search(versions_without_tr1, gcc_version): + gcc_version_matches({ 4 : [0], 3 : [0,1,2,3,4], 2 : [95] }): logging.info('Disabling TR1 support for this gcc, too old') options.with_tr1 = 'none' - versions_without_visibility = '(3\.[0-4]\.)|(2\.95\.[0-4])' if options.with_visibility == None and \ - re.search(versions_without_visibility, gcc_version): + gcc_version_matches({ 3 : [0,1,2,3,4], 2 : [95] }): logging.info('Disabling DSO visibility support for this gcc, too old') options.with_visibility = False diff -Nru botan1.10-1.10.3/debian/changelog botan1.10-1.10.5/debian/changelog --- botan1.10-1.10.3/debian/changelog 2012-07-10 21:07:15.000000000 +0200 +++ botan1.10-1.10.5/debian/changelog 2013-03-04 09:26:55.000000000 +0100 @@ -1,3 +1,28 @@ +botan1.10 (1.10.5-1) unstable; urgency=low + + * Imported Upstream version 1.10.4 + + Avoid a conditional operation in the power mod implementations on if + a nibble of the exponent was zero or not. This may help protect + against certain forms of side channel attacks. + + The SRP6 code was checking for invalid values as specified in RFC + 5054, specifically values equal to zero mod p. However SRP would + accept negative A/B values, or ones larger than p, neither of which + should occur in a normal run of the protocol. These values are now + rejected. Credits to Timothy Prepscius for pointing out these values + are not normally used and probably signal something fishy. + + The return value of version_string is now a compile time constant + string, so version information can be more easily extracted from + binaries. + * Imported Upstream version 1.10.5 + + A potential crash in the AES-NI implementation of the AES-192 key + schedule (caused by misaligned loads) has been fixed. + + A previously conditional operation in Montgomery multiplication and + squaring is now always performed, removing a possible timing channel. + + Use correct flags for creating a shared library on OS X under Clang. + + Fix a compile time incompatibility with Visual C++ 2012. + + -- Ondřej Surý <ond...@debian.org> Mon, 04 Mar 2013 09:24:12 +0100 + botan1.10 (1.10.3-1) unstable; urgency=high * Imported Upstream version 1.10.3 diff -Nru botan1.10-1.10.3/doc/examples/cms_dec.cpp botan1.10-1.10.5/doc/examples/cms_dec.cpp --- botan1.10-1.10.3/doc/examples/cms_dec.cpp 2012-07-10 15:39:56.000000000 +0200 +++ botan1.10-1.10.5/doc/examples/cms_dec.cpp 1970-01-01 01:00:00.000000000 +0100 @@ -1,120 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/pkcs8.h> -#include <botan/cms_dec.h> -using namespace Botan; - -#include <iostream> -#include <memory> - -int main(int argc, char* argv[]) - { - if(argc != 2) - { - std::cout << "Usage: " << argv[0] << " <filename>\n"; - return 1; - } - - Botan::LibraryInitializer init; - - try { - AutoSeeded_RNG rng; - - X509_Certificate mycert("mycert.pem"); - PKCS8_PrivateKey* mykey = PKCS8::load_key("mykey.pem", rng, "cut"); - - X509_Certificate yourcert("yourcert.pem"); - X509_Certificate cacert("cacert.pem"); - X509_Certificate int_ca("int_ca.pem"); - - X509_Store store; - store.add_cert(mycert); - store.add_cert(yourcert); - store.add_cert(cacert, true); - store.add_cert(int_ca); - - DataSource_Stream message(argv[1]); - - CMS_Decoder decoder(message, store, mykey); - - while(decoder.layer_type() != CMS_Decoder::DATA) - { - CMS_Decoder::Status status = decoder.layer_status(); - CMS_Decoder::Content_Type content = decoder.layer_type(); - - if(status == CMS_Decoder::FAILURE) - { - std::cout << "Failure reading CMS data" << std::endl; - break; - } - - if(content == CMS_Decoder::DIGESTED) - { - std::cout << "Digested data, hash = " << decoder.layer_info() - << std::endl; - std::cout << "Hash is " - << ((status == CMS_Decoder::GOOD) ? "good" : "bad") - << std::endl; - } - - if(content == CMS_Decoder::SIGNED) - { - // how to handle multiple signers? they can all exist within a - // single level... - - std::cout << "Signed by " << decoder.layer_info() << std::endl; - //std::cout << "Sign time: " << decoder.xxx() << std::endl; - std::cout << "Signature is "; - if(status == CMS_Decoder::GOOD) - std::cout << "valid"; - else if(status == CMS_Decoder::BAD) - std::cout << "bad"; - else if(status == CMS_Decoder::NO_KEY) - std::cout << "(cannot check, no known cert)"; - std::cout << std::endl; - } - if(content == CMS_Decoder::ENVELOPED || - content == CMS_Decoder::COMPRESSED || - content == CMS_Decoder::AUTHENTICATED) - { - if(content == CMS_Decoder::ENVELOPED) - std::cout << "Enveloped"; - if(content == CMS_Decoder::COMPRESSED) - std::cout << "Compressed"; - if(content == CMS_Decoder::AUTHENTICATED) - std::cout << "MACed"; - - std::cout << ", algo = " << decoder.layer_info() << std::endl; - - if(content == CMS_Decoder::AUTHENTICATED) - { - std::cout << "MAC status is "; - if(status == CMS_Decoder::GOOD) - std::cout << "valid"; - else if(status == CMS_Decoder::BAD) - std::cout << "bad"; - else if(status == CMS_Decoder::NO_KEY) - std::cout << "(cannot check, no key)"; - std::cout << std::endl; - } - } - decoder.next_layer(); - } - - if(decoder.layer_type() == CMS_Decoder::DATA) - std::cout << "Message is \"" << decoder.get_data() - << '"' << std::endl; - else - std::cout << "No data anywhere?" << std::endl; - } - catch(std::exception& e) - { - std::cerr << e.what() << std::endl; - } - return 0; - } diff -Nru botan1.10-1.10.3/doc/examples/cms_enc.cpp botan1.10-1.10.5/doc/examples/cms_enc.cpp --- botan1.10-1.10.3/doc/examples/cms_enc.cpp 2012-07-10 15:39:56.000000000 +0200 +++ botan1.10-1.10.5/doc/examples/cms_enc.cpp 1970-01-01 01:00:00.000000000 +0100 @@ -1,59 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/botan.h> -#include <botan/cms_enc.h> -using namespace Botan; - -#include <iostream> -#include <fstream> -#include <memory> - -int main() - { - Botan::LibraryInitializer init; - - try { - - X509_Certificate mycert("mycert.pem"); - X509_Certificate mycert2("mycert2.pem"); - X509_Certificate yourcert("yourcert.pem"); - X509_Certificate cacert("cacert.pem"); - X509_Certificate int_ca("int_ca.pem"); - - AutoSeeded_RNG rng; - - X509_Store store; - store.add_cert(mycert); - store.add_cert(mycert2); - store.add_cert(yourcert); - store.add_cert(int_ca); - store.add_cert(cacert, true); - - const std::string msg = "prioncorp: we don't toy\n"; - - CMS_Encoder encoder(msg); - - encoder.compress("Zlib"); - encoder.digest(); - encoder.encrypt(rng, mycert); - - /* - PKCS8_PrivateKey* mykey = PKCS8::load_key("mykey.pem", rng, "cut"); - encoder.sign(store, *mykey); - */ - - SecureVector<byte> raw = encoder.get_contents(); - std::ofstream out("out.der"); - - out.write((const char*)raw.begin(), raw.size()); - } - catch(std::exception& e) - { - std::cerr << e.what() << std::endl; - } - return 0; - } diff -Nru botan1.10-1.10.3/doc/log.txt botan1.10-1.10.5/doc/log.txt --- botan1.10-1.10.3/doc/log.txt 2012-07-10 15:39:56.000000000 +0200 +++ botan1.10-1.10.5/doc/log.txt 2013-03-02 22:19:36.000000000 +0100 @@ -7,6 +7,38 @@ Series 1.10 ---------------------------------------- +Version 1.10.5, 2013-03-02 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* A potential crash in the AES-NI implementation of the AES-192 key + schedule (caused by misaligned loads) has been fixed. + +* A previously conditional operation in Montgomery multiplication and + squaring is now always performed, removing a possible timing + channel. + +* Use correct flags for creating a shared library on OS X under Clang. + +* Fix a compile time incompatability with Visual C++ 2012 + +Version 1.10.4, 2013-01-07 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Avoid a conditional operation in the power mod implementations on if + a nibble of the exponent was zero or not. This may help protect + against certain forms of side channel attacks. + +* The SRP6 code was checking for invalid values as specified in RFC + 5054, specifically values equal to zero mod p. However SRP would + accept negative A/B values, or ones larger than p, neither of which + should occur in a normal run of the protocol. These values are now + rejected. Credits to Timothy Prepscius for pointing out these values + are not normally used and probably signal something fishy. + +* The return value of version_string is now a compile time constant + string, so version information can be more easily extracted from + binaries. + Version 1.10.3, 2012-07-10 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff -Nru botan1.10-1.10.3/readme.txt botan1.10-1.10.5/readme.txt --- botan1.10-1.10.3/readme.txt 2012-07-10 15:39:56.000000000 +0200 +++ botan1.10-1.10.5/readme.txt 2013-03-02 22:19:36.000000000 +0100 @@ -1,4 +1,4 @@ -Botan 1.10.3, 2012-07-10 +Botan 1.10.5, 2013-03-02 http://botan.randombit.net/ Botan is a C++ class library for performing a wide variety of diff -Nru botan1.10-1.10.3/src/asn1/alg_id.cpp botan1.10-1.10.5/src/asn1/alg_id.cpp --- botan1.10-1.10.3/src/asn1/alg_id.cpp 2012-07-10 15:39:56.000000000 +0200 +++ botan1.10-1.10.5/src/asn1/alg_id.cpp 2013-03-02 22:19:37.000000000 +0100 @@ -44,7 +44,7 @@ if(option == USE_NULL_PARAM) { - parameters += std::make_pair<const byte*, size_t>( + parameters += std::pair<const byte*, size_t>( DER_NULL, sizeof(DER_NULL)); } } @@ -61,7 +61,7 @@ if(option == USE_NULL_PARAM) { - parameters += std::make_pair<const byte*, size_t>( + parameters += std::pair<const byte*, size_t>( DER_NULL, sizeof(DER_NULL)); } } diff -Nru botan1.10-1.10.3/src/block/aes_ni/aes_ni.cpp botan1.10-1.10.5/src/block/aes_ni/aes_ni.cpp --- botan1.10-1.10.3/src/block/aes_ni/aes_ni.cpp 2012-07-10 15:39:56.000000000 +0200 +++ botan1.10-1.10.5/src/block/aes_ni/aes_ni.cpp 2013-03-02 22:19:37.000000000 +0100 @@ -502,19 +502,19 @@ // Now generate decryption keys const __m128i* EK_mm = (const __m128i*)&EK[0]; __m128i* DK_mm = (__m128i*)&DK[0]; - _mm_storeu_si128(DK_mm , EK_mm[12]); - _mm_storeu_si128(DK_mm + 1, _mm_aesimc_si128(EK_mm[11])); - _mm_storeu_si128(DK_mm + 2, _mm_aesimc_si128(EK_mm[10])); - _mm_storeu_si128(DK_mm + 3, _mm_aesimc_si128(EK_mm[9])); - _mm_storeu_si128(DK_mm + 4, _mm_aesimc_si128(EK_mm[8])); - _mm_storeu_si128(DK_mm + 5, _mm_aesimc_si128(EK_mm[7])); - _mm_storeu_si128(DK_mm + 6, _mm_aesimc_si128(EK_mm[6])); - _mm_storeu_si128(DK_mm + 7, _mm_aesimc_si128(EK_mm[5])); - _mm_storeu_si128(DK_mm + 8, _mm_aesimc_si128(EK_mm[4])); - _mm_storeu_si128(DK_mm + 9, _mm_aesimc_si128(EK_mm[3])); - _mm_storeu_si128(DK_mm + 10, _mm_aesimc_si128(EK_mm[2])); - _mm_storeu_si128(DK_mm + 11, _mm_aesimc_si128(EK_mm[1])); - _mm_storeu_si128(DK_mm + 12, EK_mm[0]); + _mm_storeu_si128(DK_mm , _mm_loadu_si128(EK_mm + 12)); + _mm_storeu_si128(DK_mm + 1, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 11))); + _mm_storeu_si128(DK_mm + 2, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 10))); + _mm_storeu_si128(DK_mm + 3, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 9))); + _mm_storeu_si128(DK_mm + 4, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 8))); + _mm_storeu_si128(DK_mm + 5, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 7))); + _mm_storeu_si128(DK_mm + 6, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 6))); + _mm_storeu_si128(DK_mm + 7, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 5))); + _mm_storeu_si128(DK_mm + 8, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 4))); + _mm_storeu_si128(DK_mm + 9, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 3))); + _mm_storeu_si128(DK_mm + 10, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 2))); + _mm_storeu_si128(DK_mm + 11, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 1))); + _mm_storeu_si128(DK_mm + 12, _mm_loadu_si128(EK_mm + 0)); } /* diff -Nru botan1.10-1.10.3/src/build-data/cc/clang.txt botan1.10-1.10.5/src/build-data/cc/clang.txt --- botan1.10-1.10.3/src/build-data/cc/clang.txt 2012-07-10 15:39:56.000000000 +0200 +++ botan1.10-1.10.5/src/build-data/cc/clang.txt 2013-03-02 22:19:37.000000000 +0100 @@ -27,6 +27,8 @@ <so_link_flags> # The default works for GNU ld and several other Unix linkers default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" + +darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)" </so_link_flags> <mach_opt> diff -Nru botan1.10-1.10.3/src/constructs/srp6/srp6.cpp botan1.10-1.10.5/src/constructs/srp6/srp6.cpp --- botan1.10-1.10.3/src/constructs/srp6/srp6.cpp 2012-07-10 15:39:56.000000000 +0200 +++ botan1.10-1.10.5/src/constructs/srp6/srp6.cpp 2013-03-02 22:19:37.000000000 +0100 @@ -107,7 +107,7 @@ const size_t p_bytes = group.get_p().bytes(); - if(B % p == 0) + if(B <= 0 || B >= p) throw std::runtime_error("Invalid SRP parameter from server"); BigInt k = hash_seq(hash_id, p_bytes, p, g); @@ -166,7 +166,7 @@ SymmetricKey SRP6_Server_Session::step2(const BigInt& A) { - if(A % p == 0) + if(A <= 0 || A >= p) throw std::runtime_error("Invalid SRP parameter from client"); BigInt u = hash_seq(hash_id, p_bytes, A, B); diff -Nru botan1.10-1.10.3/src/math/mp/mp_karat.cpp botan1.10-1.10.5/src/math/mp/mp_karat.cpp --- botan1.10-1.10.3/src/math/mp/mp_karat.cpp 2012-07-10 15:39:57.000000000 +0200 +++ botan1.10-1.10.5/src/math/mp/mp_karat.cpp 2013-03-02 22:19:37.000000000 +0100 @@ -45,7 +45,7 @@ clear_mem(workspace, 2*N); - if(cmp0 && cmp1) + //if(cmp0 && cmp1) { if(cmp0 > 0) bigint_sub3(z0, x0, N2, x1, N2); @@ -122,7 +122,7 @@ clear_mem(workspace, 2*N); - if(cmp) + //if(cmp) { if(cmp > 0) bigint_sub3(z0, x0, N2, x1, N2); diff -Nru botan1.10-1.10.3/src/math/numbertheory/powm_fw.cpp botan1.10-1.10.5/src/math/numbertheory/powm_fw.cpp --- botan1.10-1.10.3/src/math/numbertheory/powm_fw.cpp 2012-07-10 15:39:57.000000000 +0200 +++ botan1.10-1.10.5/src/math/numbertheory/powm_fw.cpp 2013-03-02 22:19:37.000000000 +0100 @@ -26,10 +26,12 @@ { window_bits = Power_Mod::window_bits(exp.bits(), base.bits(), hints); - g.resize((1 << window_bits) - 1); - g[0] = base; - for(size_t j = 1; j != g.size(); ++j) - g[j] = reducer.multiply(g[j-1], g[0]); + g.resize((1 << window_bits)); + g[0] = 1; + g[1] = base; + + for(size_t i = 2; i != g.size(); ++i) + g[i] = reducer.multiply(g[i-1], g[0]); } /* @@ -40,13 +42,15 @@ const size_t exp_nibbles = (exp.bits() + window_bits - 1) / window_bits; BigInt x = 1; - for(size_t j = exp_nibbles; j > 0; --j) + + for(size_t i = exp_nibbles; i > 0; --i) { - for(size_t k = 0; k != window_bits; ++k) + for(size_t j = 0; j != window_bits; ++j) x = reducer.square(x); - if(u32bit nibble = exp.get_substring(window_bits*(j-1), window_bits)) - x = reducer.multiply(x, g[nibble-1]); + const u32bit nibble = exp.get_substring(window_bits*(i-1), window_bits); + + x = reducer.multiply(x, g[nibble]); } return x; } diff -Nru botan1.10-1.10.3/src/math/numbertheory/powm_mnt.cpp botan1.10-1.10.5/src/math/numbertheory/powm_mnt.cpp --- botan1.10-1.10.3/src/math/numbertheory/powm_mnt.cpp 2012-07-10 15:39:57.000000000 +0200 +++ botan1.10-1.10.5/src/math/numbertheory/powm_mnt.cpp 2013-03-02 22:19:37.000000000 +0100 @@ -27,12 +27,12 @@ { window_bits = Power_Mod::window_bits(exp.bits(), base.bits(), hints); - g.resize((1 << window_bits) - 1); + g.resize((1 << window_bits)); SecureVector<word> z(2 * (mod_words + 1)); SecureVector<word> workspace(z.size()); - g[0] = (base >= modulus) ? (base % modulus) : base; + g[0] = 1; bigint_monty_mul(&z[0], z.size(), g[0].data(), g[0].size(), g[0].sig_words(), @@ -42,7 +42,17 @@ g[0].assign(&z[0], mod_words + 1); - const BigInt& x = g[0]; + g[1] = (base >= modulus) ? (base % modulus) : base; + + bigint_monty_mul(&z[0], z.size(), + g[1].data(), g[1].size(), g[1].sig_words(), + R2.data(), R2.size(), R2.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); + + g[1].assign(&z[0], mod_words + 1); + + const BigInt& x = g[1]; const size_t x_sig = x.sig_words(); for(size_t i = 1; i != g.size(); ++i) @@ -86,19 +96,18 @@ x.assign(&z[0], mod_words + 1); } - if(u32bit nibble = exp.get_substring(window_bits*(i-1), window_bits)) - { - const BigInt& y = g[nibble-1]; + const u32bit nibble = exp.get_substring(window_bits*(i-1), window_bits); - zeroise(z); - bigint_monty_mul(&z[0], z.size(), - x.data(), x.size(), x.sig_words(), - y.data(), y.size(), y.sig_words(), - modulus.data(), mod_words, mod_prime, - &workspace[0]); + const BigInt& y = g[nibble]; - x.assign(&z[0], mod_words + 1); - } + zeroise(z); + bigint_monty_mul(&z[0], z.size(), + x.data(), x.size(), x.sig_words(), + y.data(), y.size(), y.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); + + x.assign(&z[0], mod_words + 1); } x.get_reg().resize(2*mod_words+1); diff -Nru botan1.10-1.10.3/src/pubkey/dh/dh.cpp botan1.10-1.10.5/src/pubkey/dh/dh.cpp --- botan1.10-1.10.3/src/pubkey/dh/dh.cpp 2012-07-10 15:39:57.000000000 +0200 +++ botan1.10-1.10.5/src/pubkey/dh/dh.cpp 2013-03-02 22:19:37.000000000 +0100 @@ -87,6 +87,9 @@ { BigInt input = BigInt::decode(w, w_len); + if(input <= 1 || input >= p - 1) + throw Invalid_Argument("DH agreement - invalid key provided"); + BigInt r = blinder.unblind(powermod_x_p(blinder.blind(input))); return BigInt::encode_1363(r, p.bytes()); diff -Nru botan1.10-1.10.3/src/utils/version.cpp botan1.10-1.10.5/src/utils/version.cpp --- botan1.10-1.10.3/src/utils/version.cpp 2012-07-10 15:39:57.000000000 +0200 +++ botan1.10-1.10.5/src/utils/version.cpp 2013-03-02 22:19:37.000000000 +0100 @@ -22,21 +22,23 @@ */ std::string version_string() { - std::ostringstream out; +#define QUOTE(name) #name +#define STR(macro) QUOTE(macro) - out << "Botan " << version_major() << "." - << version_minor() << "." - << version_patch() << " ("; + return "Botan " STR(BOTAN_VERSION_MAJOR) "." + STR(BOTAN_VERSION_MINOR) "." + STR(BOTAN_VERSION_PATCH) " (" - if(BOTAN_VERSION_DATESTAMP == 0) - out << "unreleased version"; - else - out << "released " << version_datestamp(); +#if (BOTAN_VERSION_DATESTAMP == 0) + "unreleased version" +#else + "released " STR(BOTAN_VERSION_DATESTAMP) +#endif + ", revision " BOTAN_VERSION_VC_REVISION + ", distribution " BOTAN_DISTRIBUTION_INFO ")"; - out << ", revision " << BOTAN_VERSION_VC_REVISION; - out << ", distribution " << BOTAN_DISTRIBUTION_INFO << ")"; - - return out.str(); +#undef STR +#undef QUOTE } u32bit version_datestamp() { return BOTAN_VERSION_DATESTAMP; }