--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: unblock: botan1.10/1.10.4-1
- From: Ondřej Surý <ondrej@debian.org>
- Date: Wed, 27 Feb 2013 14:52:52 +0100
- Message-id: <20130227135252.7646.27218.reportbug@localhost6.localdomain6>
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package botan1.10
Hi,
I would like to pre-mediate the inclusion of 1.10.4 (e.g. new upstream version).
The patch is very small and fixes three issues. Upstream changelog:
http://botan.randombit.net/relnotes/1_10_4.html
--cut here--
* 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.
--cut here--
The first two issues are security issues and the third could be
included just for the sake of clarity.
$ git diff upstream/1.10.3..upstream/1.10.4 | diffstat
botan_version.py | 6 +++---
configure.py | 23 ++++++++++++++---------
doc/log.txt | 18 ++++++++++++++++++
readme.txt | 2 +-
src/constructs/srp6/srp6.cpp | 4 ++--
src/math/numbertheory/powm_fw.cpp | 20 ++++++++++++--------
src/math/numbertheory/powm_mnt.cpp | 37 +++++++++++++++++++++++--------------
src/pubkey/dh/dh.cpp | 3 +++
src/utils/version.cpp | 32 +++++++++++++++++---------------
9 files changed, 93 insertions(+), 52 deletions(-)
Attached is the 1.10.3 to 1.10.4 patch (I have tried to dig the
individual patches from monotone, but I have discovered that I don't
have a time to learn yet another revision system with weird syntax, so
unless you force me to do it, I would like to skip this part.)
unblock botan1.10/1.10.4-1
-- 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
diff --git a/botan_version.py b/botan_version.py
index 1ad9b89..72fda66 100644
--- a/botan_version.py
+++ b/botan_version.py
@@ -1,9 +1,9 @@
release_major = 1
release_minor = 10
-release_patch = 3
+release_patch = 4
-release_vc_rev = 'mtn:7b193c2f27bc5bdbdd4297c5e53acfe4e4624bdb'
+release_vc_rev = 'mtn:d7a8dbe5ea390b354623a869b96f95c4b2a37bae'
release_so_abi_rev = 0
-release_datestamp = 20120710
+release_datestamp = 20120107
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/doc/log.txt b/doc/log.txt
index 5f95cf4..575f3d4 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -7,6 +7,24 @@ Release Notes
Series 1.10
----------------------------------------
+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..792ad25 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
-Botan 1.10.3, 2012-07-10
+Botan 1.10.4, 2013-01-07
http://botan.randombit.net/
Botan is a C++ class library for performing a wide variety of
diff --git a/src/constructs/srp6/srp6.cpp b/src/constructs/srp6/srp6.cpp
index 0dfe210..b1eefa8 100644
--- a/src/constructs/srp6/srp6.cpp
+++ b/src/constructs/srp6/srp6.cpp
@@ -107,7 +107,7 @@ srp6_client_agree(const std::string& identifier,
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 @@ BigInt SRP6_Server_Session::step1(const BigInt& v,
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/math/numbertheory/powm_fw.cpp b/src/math/numbertheory/powm_fw.cpp
index 3348e55..8c6d7b6 100644
--- a/src/math/numbertheory/powm_fw.cpp
+++ b/src/math/numbertheory/powm_fw.cpp
@@ -26,10 +26,12 @@ void Fixed_Window_Exponentiator::set_base(const BigInt& base)
{
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::execute() const
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 --git a/src/math/numbertheory/powm_mnt.cpp b/src/math/numbertheory/powm_mnt.cpp
index 8993f4b..884766a 100644
--- a/src/math/numbertheory/powm_mnt.cpp
+++ b/src/math/numbertheory/powm_mnt.cpp
@@ -27,12 +27,12 @@ void Montgomery_Exponentiator::set_base(const BigInt& 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(const BigInt& 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() const
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 --git a/src/pubkey/dh/dh.cpp b/src/pubkey/dh/dh.cpp
index d58fece..dacae5a 100644
--- a/src/pubkey/dh/dh.cpp
+++ b/src/pubkey/dh/dh.cpp
@@ -87,6 +87,9 @@ SecureVector<byte> DH_KA_Operation::agree(const byte w[], size_t w_len)
{
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/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; }
--- End Message ---