Hello community,
here is the log from the commit of package Botan for openSUSE:Factory checked in at 2016-11-16 13:46:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/Botan (Old)
and /work/SRC/openSUSE:Factory/.Botan.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "Botan"
Changes:
--------
--- /work/SRC/openSUSE:Factory/Botan/Botan.changes 2016-05-19 12:04:19.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.Botan.new/Botan.changes 2016-11-16 13:46:17.000000000 +0100
@@ -1,0 +2,8 @@
+Sun Nov 13 01:32:18 UTC 2016 - netsroth@opensuse.org
+
+- Update to 1.10.13
+ * Use constant time modular inverse algorithm to avoid possible side channel attack against ECDSA (CVE-2016-2849)
+ * Use constant time PKCS #1 unpadding to avoid possible side channel attack against RSA decryption (CVE-2015-7827)
+ * Avoid a compilation problem in OpenSSL engine when ECDSA was disabled. Gentoo bug 542010
+
+-------------------------------------------------------------------
Old:
----
Botan-1.10.12.tgz
Botan-1.10.12.tgz.asc
New:
----
Botan-1.10.13.tgz
Botan-1.10.13.tgz.asc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ Botan.spec ++++++
--- /var/tmp/diff_new_pack.xBzXLH/_old 2016-11-16 13:46:19.000000000 +0100
+++ /var/tmp/diff_new_pack.xBzXLH/_new 2016-11-16 13:46:19.000000000 +0100
@@ -19,7 +19,7 @@
%define version_suffix 1_10-1
%define short_version 1.10
Name: Botan
-Version: 1.10.12
+Version: 1.10.13
Release: 0
Summary: A C++ Crypto Library
License: BSD-2-Clause
++++++ Botan-1.10.12.tgz -> Botan-1.10.13.tgz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Botan-1.10.12/botan_version.py new/Botan-1.10.13/botan_version.py
--- old/Botan-1.10.12/botan_version.py 2016-02-03 09:05:05.000000000 +0100
+++ new/Botan-1.10.13/botan_version.py 2016-04-28 16:20:15.000000000 +0200
@@ -1,11 +1,11 @@
release_major = 1
release_minor = 10
-release_patch = 12
+release_patch = 13
release_so_abi_rev = 1
# These are set by the distribution script
-release_vc_rev = 'git:94a3fa8ae0dc4df67f6e9ba780427e651baa9dfd'
-release_datestamp = 20160203
+release_vc_rev = 'git:a4b5f14b6ceac859eec9a0e5825f89ee45eec11c'
+release_datestamp = 20160428
release_type = 'released'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Botan-1.10.12/doc/log.txt new/Botan-1.10.13/doc/log.txt
--- old/Botan-1.10.12/doc/log.txt 2016-02-03 08:57:06.000000000 +0100
+++ new/Botan-1.10.13/doc/log.txt 2016-04-28 15:27:08.000000000 +0200
@@ -7,6 +7,18 @@
Series 1.10
----------------------------------------
+Version 1.10.13, 2016-04-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Use constant time modular inverse algorithm to avoid possible
+ side channel attack against ECDSA (CVE-2016-2849)
+
+* Use constant time PKCS #1 unpadding to avoid possible side channel
+ attack against RSA decryption (CVE-2015-7827)
+
+* Avoid a compilation problem in OpenSSL engine when ECDSA was
+ disabled. Gentoo bug 542010
+
Version 1.10.12, 2016-02-03
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Botan-1.10.12/src/engine/openssl/ossl_pk.cpp new/Botan-1.10.13/src/engine/openssl/ossl_pk.cpp
--- old/Botan-1.10.12/src/engine/openssl/ossl_pk.cpp 2016-02-03 08:57:06.000000000 +0100
+++ new/Botan-1.10.13/src/engine/openssl/ossl_pk.cpp 2016-04-28 15:27:08.000000000 +0200
@@ -12,17 +12,23 @@
#include
#endif
+#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
+ #include
+#endif
+
#if defined(BOTAN_HAS_DSA)
#include
#endif
#if defined(BOTAN_HAS_ECDSA)
#include
+
+ #include
+
+#if !defined(OPENSSL_NO_ECDSA)
#include
#endif
-#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
- #include
#endif
namespace Botan {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Botan-1.10.12/src/math/mp/mp_asm.cpp new/Botan-1.10.13/src/math/mp/mp_asm.cpp
--- old/Botan-1.10.12/src/math/mp/mp_asm.cpp 2016-02-03 08:57:06.000000000 +0100
+++ new/Botan-1.10.13/src/math/mp/mp_asm.cpp 2016-04-28 15:27:08.000000000 +0200
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
@@ -17,6 +18,76 @@
extern "C" {
/*
+* If cond == 0, does nothing.
+* If cond > 0, swaps x[0:size] with y[0:size]
+* Runs in constant time
+*/
+void bigint_cnd_swap(word cnd, word x[], word y[], size_t size)
+ {
+ const word mask = CT::expand_mask(cnd);
+
+ for(size_t i = 0; i != size; ++i)
+ {
+ word a = x[i];
+ word b = y[i];
+ x[i] = CT::select(mask, b, a);
+ y[i] = CT::select(mask, a, b);
+ }
+ }
+
+/*
+* If cond > 0 adds x[0:size] to y[0:size] and returns carry
+* Runs in constant time
+*/
+word bigint_cnd_add(word cnd, word x[], const word y[], size_t size)
+ {
+ const word mask = CT::expand_mask(cnd);
+
+ word carry = 0;
+ for(size_t i = 0; i != size; ++i)
+ {
+ /*
+ Here we are relying on asm version of word_add being
+ a single addcl or equivalent. Fix this.
+ */
+ const word z = word_add(x[i], y[i], &carry);
+ x[i] = CT::select(mask, z, x[i]);
+ }
+
+ return carry & mask;
+ }
+
+/*
+* If cond > 0 subs x[0:size] to y[0:size] and returns borrow
+* Runs in constant time
+*/
+word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size)
+ {
+ const word mask = CT::expand_mask(cnd);
+
+ word carry = 0;
+ for(size_t i = 0; i != size; ++i)
+ {
+ const word z = word_sub(x[i], y[i], &carry);
+ x[i] = CT::select(mask, z, x[i]);
+ }
+
+ return carry & mask;
+ }
+
+void bigint_cnd_abs(word cnd, word x[], size_t size)
+ {
+ const word mask = CT::expand_mask(cnd);
+
+ word carry = mask & 1;
+ for(size_t i = 0; i != size; ++i)
+ {
+ const word z = word_add(~x[i], 0, &carry);
+ x[i] = CT::select(mask, z, x[i]);
+ }
+ }
+
+/*
* Two Operand Addition, No Carry
*/
word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Botan-1.10.12/src/math/mp/mp_core.h new/Botan-1.10.13/src/math/mp/mp_core.h
--- old/Botan-1.10.12/src/math/mp/mp_core.h 2016-02-03 08:57:06.000000000 +0100
+++ new/Botan-1.10.13/src/math/mp/mp_core.h 2016-04-28 15:27:08.000000000 +0200
@@ -20,6 +20,32 @@
extern "C" {
/*
+* If cond == 0, does nothing.
+* If cond > 0, swaps x[0:size] with y[0:size]
+* Runs in constant time
+*/
+void bigint_cnd_swap(word cnd, word x[], word y[], size_t size);
+
+/*
+* If cond > 0 adds x[0:size] to y[0:size] and returns carry
+* Runs in constant time
+*/
+word bigint_cnd_add(word cnd, word x[], const word y[], size_t size);
+
+/*
+* If cond > 0 subs x[0:size] to y[0:size] and returns borrow
+* Runs in constant time
+*/
+word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size);
+
+/*
+* 2s complement absolute value
+* If cond > 0 sets x to ~x + 1
+* Runs in constant time
+*/
+void bigint_cnd_abs(word cnd, word x[], size_t size);
+
+/*
* Addition/Subtraction Operations
*/
void bigint_add2(word x[], size_t x_size,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Botan-1.10.12/src/math/numbertheory/numthry.cpp new/Botan-1.10.13/src/math/numbertheory/numthry.cpp
--- old/Botan-1.10.12/src/math/numbertheory/numthry.cpp 2016-02-03 08:57:06.000000000 +0100
+++ new/Botan-1.10.13/src/math/numbertheory/numthry.cpp 2016-04-28 15:27:08.000000000 +0200
@@ -7,6 +7,7 @@
#include
#include
+#include
#include
#include <algorithm>
@@ -196,6 +197,117 @@
return ((a * b) / gcd(a, b));
}
+namespace {
+
+BigInt ct_inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod)
+ {
+ if(n.is_negative() || mod.is_negative())
+ throw Invalid_Argument("ct_inverse_mod_odd_modulus: arguments must be non-negative");
+ if(mod < 3 || mod.is_even())
+ throw Invalid_Argument("Bad modulus to ct_inverse_mod_odd_modulus");
+
+ /*
+ This uses a modular inversion algorithm designed by Niels Möller
+ and implemented in Nettle. The same algorithm was later also
+ adapted to GMP in mpn_sec_invert.
+
+ It can be easily implemented in a way that does not depend on
+ secret branches or memory lookups, providing resistance against
+ some forms of side channel attack.
+
+ There is also a description of the algorithm in Appendix 5 of "Fast
+ Software Polynomial Multiplication on ARM Processors using the NEON Engine"
+ by Danilo Câmara, Conrado P. L. Gouvêa, Julio López, and Ricardo
+ Dahab in LNCS 8182
+ http://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf
+
+ Thanks to Niels for creating the algorithm, explaining some things
+ about it, and the reference to the paper.
+ */
+
+ // todo allow this to be pre-calculated and passed in as arg
+ BigInt mp1o2 = (mod + 1) >> 1;
+
+ const size_t mod_words = mod.sig_words();
+
+ BigInt a = n;
+ BigInt b = mod;
+ BigInt u = 1, v = 0;
+
+ a.grow_to(mod_words);
+ u.grow_to(mod_words);
+ v.grow_to(mod_words);
+ mp1o2.grow_to(mod_words);
+
+ SecureVector<word>& a_w = a.get_reg();
+ SecureVector<word>& b_w = b.get_reg();
+ SecureVector<word>& u_w = u.get_reg();
+ SecureVector<word>& v_w = v.get_reg();
+
+ // Only n.bits() + mod.bits() iterations are required, but avoid leaking the size of n
+ size_t bits = 2 * mod.bits();
+
+ while(bits--)
+ {
+#if 1
+ const word odd = a.is_odd();
+ a -= odd * b;
+ const word underflow = a.is_negative();
+ b += a * underflow;
+ a.set_sign(BigInt::Positive);
+
+ a >>= 1;
+
+ if(underflow)
+ {
+ std::swap(u, v);
+ }
+
+ u -= odd * v;
+ u += u.is_negative() * mod;
+
+ const word odd_u = u.is_odd();
+
+ u >>= 1;
+ u += mp1o2 * odd_u;
+#else
+ const word odd_a = a_w[0] & 1;
+
+ //if(odd_a) a -= b
+ word underflow = bigint_cnd_sub(odd_a, a_w.begin(), b_w.begin(), mod_words);
+
+ //if(underflow) { b -= a; a = abs(a); swap(u, v); }
+ bigint_cnd_add(underflow, b_w.begin(), a_w.begin(), mod_words);
+ bigint_cnd_abs(underflow, a_w.begin(), mod_words);
+ bigint_cnd_swap(underflow, u_w.begin(), v_w.begin(), mod_words);
+
+ // a >>= 1
+ bigint_shr1(a_w.begin(), mod_words, 0, 1);
+
+ //if(odd_a) u -= v;
+ word borrow = bigint_cnd_sub(odd_a, u_w.begin(), v_w.begin(), mod_words);
+
+ // if(borrow) u += p
+ bigint_cnd_add(borrow, u_w.begin(), mod.data(), mod_words);
+
+ const word odd_u = u_w[0] & 1;
+
+ // u >>= 1
+ bigint_shr1(u_w.begin(), mod_words, 0, 1);
+
+ //if(odd_u) u += mp1o2;
+ bigint_cnd_add(odd_u, u_w.begin(), mp1o2.data(), mod_words);
+#endif
+ }
+
+ if(b != 1)
+ return 0;
+
+ return v;
+ }
+
+}
+
/*
* Find the Modular Inverse
*/
@@ -209,6 +321,9 @@
if(n.is_zero() || (n.is_even() && mod.is_even()))
return 0;
+ if(mod.is_odd())
+ return ct_inverse_mod_odd_modulus(n % mod, mod);
+
BigInt x = mod, y = n, u = mod, v = n;
BigInt A = 1, B = 0, C = 0, D = 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Botan-1.10.12/src/pk_pad/eme_pkcs/eme_pkcs.cpp new/Botan-1.10.13/src/pk_pad/eme_pkcs/eme_pkcs.cpp
--- old/Botan-1.10.12/src/pk_pad/eme_pkcs/eme_pkcs.cpp 2016-02-03 08:57:06.000000000 +0100
+++ new/Botan-1.10.13/src/pk_pad/eme_pkcs/eme_pkcs.cpp 2016-04-28 15:27:08.000000000 +0200
@@ -6,6 +6,7 @@
*/
#include
+#include
namespace Botan {
@@ -40,20 +41,31 @@
SecureVector<byte> EME_PKCS1v15::unpad(const byte in[], size_t inlen,
size_t key_len) const
{
- if(inlen != key_len / 8 || inlen < 10 || in[0] != 0x02)
- throw Decoding_Error("PKCS1::unpad");
- size_t seperator = 0;
- for(size_t j = 0; j != inlen; ++j)
- if(in[j] == 0)
- {
- seperator = j;
- break;
- }
- if(seperator < 9)
- throw Decoding_Error("PKCS1::unpad");
+ byte bad_input_m = 0;
+ byte seen_zero_m = 0;
+ size_t delim_idx = 0;
- return SecureVector<byte>(in + seperator + 1, inlen - seperator - 1);
+ bad_input_m |= ~CT::is_equal<byte>(in[0], 2);
+
+ for(size_t i = 1; i < inlen; ++i)
+ {
+ const byte is_zero_m = CT::is_zero<byte>(in[i]);
+
+ delim_idx += CT::select<byte>(~seen_zero_m, 1, 0);
+
+ bad_input_m |= is_zero_m & CT::expand_mask<byte>(i < 9);
+ seen_zero_m |= is_zero_m;
+ }
+
+ bad_input_m |= ~seen_zero_m;
+ bad_input_m |= CT::is_less(delim_idx, 8);
+
+ SecureVector<byte> output(&in[delim_idx + 1], inlen - (delim_idx + 1));
+
+ if(bad_input_m)
+ throw Decoding_Error("EME_PKCS1v15::unpad invalid ciphertext");
+ return output;
}
/*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Botan-1.10.12/src/utils/ct_utils.h new/Botan-1.10.13/src/utils/ct_utils.h
--- old/Botan-1.10.12/src/utils/ct_utils.h 1970-01-01 01:00:00.000000000 +0100
+++ new/Botan-1.10.13/src/utils/ct_utils.h 2016-04-28 15:27:08.000000000 +0200
@@ -0,0 +1,137 @@
+/*
+* Functions for constant time operations on data and testing of
+* constant time annotations using valgrind.
+*
+* For more information about constant time programming see
+* Wagner, Molnar, et al "The Program Counter Security Model"
+*
+* (C) 2010 Falko Strenzke
+* (C) 2015,2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_TIMING_ATTACK_CM_H__
+#define BOTAN_TIMING_ATTACK_CM_H__
+
+#include
+#include <vector>
+
+namespace Botan {
+
+namespace CT {
+
+/*
+* T should be an unsigned machine integer type
+* Expand to a mask used for other operations
+* @param in an integer
+* @return If n is zero, returns zero. Otherwise
+* returns a T with all bits set for use as a mask with
+* select.
+*/
+template<typename T>
+inline T expand_mask(T x)
+ {
+ T r = x;
+ // First fold r down to a single bit
+ for(size_t i = 1; i != sizeof(T)*8; i *= 2)
+ r |= r >> i;
+ r &= 1;
+ r = ~(r - 1);
+ return r;
+ }
+
+template<typename T>
+inline T select(T mask, T from0, T from1)
+ {
+ return (from0 & mask) | (from1 & ~mask);
+ }
+
+template
+inline ValT val_or_zero(PredT pred_val, ValT val)
+ {
+ return select(CT::expand_mask<ValT>(pred_val), val, static_cast<ValT>(0));
+ }
+
+template<typename T>
+inline T is_zero(T x)
+ {
+ return ~expand_mask(x);
+ }
+
+template<typename T>
+inline T is_equal(T x, T y)
+ {
+ return is_zero(x ^ y);
+ }
+
+template<typename T>
+inline T is_less(T x, T y)
+ {
+ /*
+ This expands to a constant time sequence with GCC 5.2.0 on x86-64
+ but something more complicated may be needed for portable const time.
+ */
+ return expand_mask<T>(x < y);
+ }
+
+template<typename T>
+inline T is_lte(T x, T y)
+ {
+ return expand_mask<T>(x <= y);
+ }
+
+template<typename T>
+inline void conditional_copy_mem(T value,
+ T* to,
+ const T* from0,
+ const T* from1,
+ size_t elems)
+ {
+ const T mask = CT::expand_mask(value);
+
+ for(size_t i = 0; i != elems; ++i)
+ {
+ to[i] = CT::select(mask, from0[i], from1[i]);
+ }
+ }
+
+template<typename T>
+inline void cond_zero_mem(T cond,
+ T* array,
+ size_t elems)
+ {
+ const T mask = CT::expand_mask(cond);
+ const T zero(0);
+
+ for(size_t i = 0; i != elems; ++i)
+ {
+ array[i] = CT::select(mask, zero, array[i]);
+ }
+ }
+
+template<typename T>
+inline T expand_top_bit(T a)
+ {
+ return expand_mask<T>(a >> (sizeof(T)*8-1));
+ }
+
+template<typename T>
+inline T max(T a, T b)
+ {
+ const T a_larger = b - a; // negative if a is larger
+ return select(expand_top_bit(a), a, b);
+ }
+
+template<typename T>
+inline T min(T a, T b)
+ {
+ const T a_larger = b - a; // negative if a is larger
+ return select(expand_top_bit(b), b, a);
+ }
+
+}
+
+}
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Botan-1.10.12/src/utils/info.txt new/Botan-1.10.13/src/utils/info.txt
--- old/Botan-1.10.12/src/utils/info.txt 2016-02-03 08:57:06.000000000 +0100
+++ new/Botan-1.10.13/src/utils/info.txt 2016-04-28 15:27:08.000000000 +0200
@@ -16,6 +16,7 @@
header:internal
assert.h
bit_ops.h
+ct_utils.h
mlock.h
prefetch.h
rounding.h