[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#701817: unblock: botan1.10/1.10.5-1



Package: release.debian.org
Followup-For: Bug #701817
User: release.debian.org@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ý <ondrej@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; }

Reply to: