I've done some digging on this and its kind of interesting.

What is happening is that the code is calling the BN_consttime_swap function.
This takes a condition variable and two BIGNUMs a and b, and swaps the value of
a and b over if the condition is set. Inside a BIGNUM structure there is a
pointer to an array of ints "d", along with a value dmax which says how many
ints have been allocated in the array and a value top which says how many of
those are actually being used. The values in the array from top up to dmax-1
may not have been initialised. BN_consttime_swap ignores that and goes through
the array values and operates on them anyway even if they haven't been
initialised yet to ensure constant time operation. This doesn't actually matter
because we're never actually going to *use* that data.

I've put together a fix (see below), but not pushed it because I was working on
the assumption that if you had PURIFY defined then you wouldn't care about
constant time operation. I've since been told that possibly some distros define
PURIFY in their production builds. Anyone know of an example where this is used
in a production build?

A work around might be to use a suppression file for valgrind...but obviously
if you happen to use some other tool then that doesn't help, so I'm not sure
about that. Alternatively I could try and initialise everything in constant
time....but looking for good ideas on how to do that! :-)

Hmmm........needs some more thought.

Matt



commit 51518506c10cde225d4eb7590b2bc4f0ea67c959
Author: Matt Caswell <m...@openssl.org>
Date: Thu Jul 3 22:09:08 2014 +0100

Added PURIFY section to initialise variables in BN_consttime_swap to stop
valgrind complaining.

Assumes constant time is not important when PURIFY is defined.

PR#3415

diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index b1e224b..3db3885 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -844,6 +844,19 @@ void BN_consttime_swap(BN_ULONG condition, BIGNUM *a,
BIGNUM *b, int nwords)
bn_wcheck_size(a, nwords);
bn_wcheck_size(b, nwords);

+#ifdef PURIFY
+ /* Valgrind complains because we process the whole array even
+ * if it's not initialised yet. This doesn't matter in this function -
+ * what's important is constant time operation (we're not actually
+ * going to use the data)
+ * It is assumed that when running with PURIFY defined we don't have to
+ * worry about constant time - hence just go through and initialise it
+ * all
+ */
+ for (i=a->top; i<a->dmax; i++) a->d[i]=0;
+ for (i=b->top; i<b->dmax; i++) b->d[i]=0;
+#endif
+
assert(a != b);
assert((condition & (condition - 1)) == 0);
assert(sizeof(BN_ULONG) >= sizeof(int));

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to