Hello community,
here is the log from the commit of package python-pycrypto for openSUSE:Factory checked in at 2013-11-28 07:39:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pycrypto (Old)
and /work/SRC/openSUSE:Factory/.python-pycrypto.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pycrypto"
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pycrypto/python-pycrypto.changes 2013-06-19 17:05:08.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-pycrypto.new/python-pycrypto.changes 2013-11-28 07:39:52.000000000 +0100
@@ -1,0 +2,52 @@
+Wed Nov 27 17:37:14 UTC 2013 - p.drouand@gmail.com
+
+- Update to version 2.6.1
+ * [CVE-2013-1445] Fix PRNG not correctly reseeded in some situations.
+ In previous versions of PyCrypto, the Crypto.Random PRNG exhibits a
+ race condition that may cause forked processes to generate identical
+ sequences of 'random' numbers.
+ This is a fairly obscure bug that will (hopefully) not affect many
+ applications, but the failure scenario is pretty bad. Here is some
+ sample code that illustrates the problem:
+ from binascii import hexlify
+ import multiprocessing, pprint, time
+ import Crypto.Random
+
+ def task_main(arg):
+ a = Crypto.Random.get_random_bytes(8)
+ time.sleep(0.1)
+ b = Crypto.Random.get_random_bytes(8)
+ rdy, ack = arg
+ rdy.set()
+ ack.wait()
+ return "%s,%s" % (hexlify(a).decode(),
+ hexlify(b).decode())
+
+ n_procs = 4
+ manager = multiprocessing.Manager()
+ rdys = [manager.Event() for i in range(n_procs)]
+ acks = [manager.Event() for i in range(n_procs)]
+ Crypto.Random.get_random_bytes(1)
+ pool = multiprocessing.Pool(processes=n_procs,
+ initializer=Crypto.Random.atfork)
+ res_async = pool.map_async(task_main, zip(rdys, acks))
+ pool.close()
+ [rdy.wait() for rdy in rdys]
+ [ack.set() for ack in acks]
+ res = res_async.get()
+ pprint.pprint(sorted(res))
+ pool.join()
+
+ The output should be random, but it looked like this:
+
+ ['c607803ae01aa8c0,2e4de6457a304b34',
+ 'c607803ae01aa8c0,af80d08942b4c987',
+ 'c607803ae01aa8c0,b0e4c0853de927c4',
+ 'c607803ae01aa8c0,f0362585b3fceba4']
+
+ This release fixes the problem by resetting the rate-limiter when
+ Crypto.Random.atfork() is invoked. It also adds some tests and a
+ few related comments.
+- Add "-fno-strict-aliasing" to CFLAGS
+
+-------------------------------------------------------------------
Old:
----
pycrypto-2.6.tar.gz
New:
----
pycrypto-2.6.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pycrypto.spec ++++++
--- /var/tmp/diff_new_pack.X2Be6c/_old 2013-11-28 07:39:53.000000000 +0100
+++ /var/tmp/diff_new_pack.X2Be6c/_new 2013-11-28 07:39:53.000000000 +0100
@@ -17,13 +17,13 @@
Name: python-pycrypto
-Version: 2.6
+Version: 2.6.1
Release: 0
Url: http://www.pycrypto.org/
Summary: Cryptographic modules for Python
License: Python-2.0
Group: Development/Languages/Python
-Source: http://pypi.python.org/packages/source/p/pycrypto/pycrypto-%{version}.tar.gz
+Source: https://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-%{version}.tar.gz
# PATCH-FIX-SUSE: We don't have libgmp5 on SLE11
Patch0: ignore-fastmath-warning.diff
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -55,7 +55,7 @@
%endif
%build
-CFLAGS="%{optflags}" python setup.py build
+CFLAGS="%{optflags} -fno-strict-aliasing" python setup.py build
%install
python setup.py install --prefix=%{_prefix} --root=%{buildroot}
++++++ pycrypto-2.6.tar.gz -> pycrypto-2.6.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pycrypto-2.6/ChangeLog new/pycrypto-2.6.1/ChangeLog
--- old/pycrypto-2.6/ChangeLog 2012-05-24 14:55:30.000000000 +0200
+++ new/pycrypto-2.6.1/ChangeLog 2013-10-14 23:38:10.000000000 +0200
@@ -1,3 +1,55 @@
+2.6.1
+=====
+ * [CVE-2013-1445] Fix PRNG not correctly reseeded in some situations.
+
+ In previous versions of PyCrypto, the Crypto.Random PRNG exhibits a
+ race condition that may cause forked processes to generate identical
+ sequences of 'random' numbers.
+
+ This is a fairly obscure bug that will (hopefully) not affect many
+ applications, but the failure scenario is pretty bad. Here is some
+ sample code that illustrates the problem:
+
+ from binascii import hexlify
+ import multiprocessing, pprint, time
+ import Crypto.Random
+
+ def task_main(arg):
+ a = Crypto.Random.get_random_bytes(8)
+ time.sleep(0.1)
+ b = Crypto.Random.get_random_bytes(8)
+ rdy, ack = arg
+ rdy.set()
+ ack.wait()
+ return "%s,%s" % (hexlify(a).decode(),
+ hexlify(b).decode())
+
+ n_procs = 4
+ manager = multiprocessing.Manager()
+ rdys = [manager.Event() for i in range(n_procs)]
+ acks = [manager.Event() for i in range(n_procs)]
+ Crypto.Random.get_random_bytes(1)
+ pool = multiprocessing.Pool(processes=n_procs,
+ initializer=Crypto.Random.atfork)
+ res_async = pool.map_async(task_main, zip(rdys, acks))
+ pool.close()
+ [rdy.wait() for rdy in rdys]
+ [ack.set() for ack in acks]
+ res = res_async.get()
+ pprint.pprint(sorted(res))
+ pool.join()
+
+ The output should be random, but it looked like this:
+
+ ['c607803ae01aa8c0,2e4de6457a304b34',
+ 'c607803ae01aa8c0,af80d08942b4c987',
+ 'c607803ae01aa8c0,b0e4c0853de927c4',
+ 'c607803ae01aa8c0,f0362585b3fceba4']
+
+ This release fixes the problem by resetting the rate-limiter when
+ Crypto.Random.atfork() is invoked. It also adds some tests and a
+ few related comments.
+
2.6
===
* [CVE-2012-2417] Fix LP#985164: insecure ElGamal key generation.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pycrypto-2.6/Doc/pycrypt.rst new/pycrypto-2.6.1/Doc/pycrypt.rst
--- old/pycrypto-2.6/Doc/pycrypt.rst 2012-05-24 14:55:30.000000000 +0200
+++ new/pycrypto-2.6.1/Doc/pycrypt.rst 2013-10-14 23:38:10.000000000 +0200
@@ -2,7 +2,7 @@
Python Cryptography Toolkit
====================================
-**Version 2.6**
+**Version 2.6.1**
The Python Cryptography Toolkit describes a package containing various
cryptographic modules for the Python programming language. This
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pycrypto-2.6/PKG-INFO new/pycrypto-2.6.1/PKG-INFO
--- old/pycrypto-2.6/PKG-INFO 2012-05-24 14:55:32.000000000 +0200
+++ new/pycrypto-2.6.1/PKG-INFO 2013-10-15 00:36:04.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pycrypto
-Version: 2.6
+Version: 2.6.1
Summary: Cryptographic modules for Python.
Home-page: http://www.pycrypto.org/
Author: Dwayne C. Litzenberger
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pycrypto-2.6/lib/Crypto/Random/Fortuna/FortunaAccumulator.py new/pycrypto-2.6.1/lib/Crypto/Random/Fortuna/FortunaAccumulator.py
--- old/pycrypto-2.6/lib/Crypto/Random/Fortuna/FortunaAccumulator.py 2012-05-24 14:55:30.000000000 +0200
+++ new/pycrypto-2.6.1/lib/Crypto/Random/Fortuna/FortunaAccumulator.py 2013-10-14 23:38:10.000000000 +0200
@@ -94,8 +94,25 @@
class FortunaAccumulator(object):
- min_pool_size = 64 # TODO: explain why
- reseed_interval = 0.100 # 100 ms TODO: explain why
+ # An estimate of how many bytes we must append to pool 0 before it will
+ # contain 128 bits of entropy (with respect to an attack). We reseed the
+ # generator only after pool 0 contains `min_pool_size` bytes. Note that
+ # unlike with some other PRNGs, Fortuna's security does not rely on the
+ # accuracy of this estimate---we can accord to be optimistic here.
+ min_pool_size = 64 # size in bytes
+
+ # If an attacker can predict some (but not all) of our entropy sources, the
+ # `min_pool_size` check may not be sufficient to prevent a successful state
+ # compromise extension attack. To resist this attack, Fortuna spreads the
+ # input across 32 pools, which are then consumed (to reseed the output
+ # generator) with exponentially decreasing frequency.
+ #
+ # In order to prevent an attacker from gaining knowledge of all 32 pools
+ # before we have a chance to fill them with enough information that the
+ # attacker cannot predict, we impose a rate limit of 10 reseeds/second (one
+ # per 100 ms). This ensures that a hypothetical 33rd pool would only be
+ # needed after a minimum of 13 years of sustained attack.
+ reseed_interval = 0.100 # time in seconds
def __init__(self):
self.reseed_count = 0
@@ -109,6 +126,15 @@
self.pools = [FortunaPool() for i in range(32)] # 32 pools
assert(self.pools[0] is not self.pools[1])
+ def _forget_last_reseed(self):
+ # This is not part of the standard Fortuna definition, and using this
+ # function frequently can weaken Fortuna's ability to resist a state
+ # compromise extension attack, but we need this in order to properly
+ # implement Crypto.Random.atfork(). Otherwise, forked child processes
+ # might continue to use their parent's PRNG state for up to 100ms in
+ # some cases. (e.g. CVE-2013-1445)
+ self.last_reseed = None
+
def random_data(self, bytes):
current_time = time.time()
if (self.last_reseed is not None and self.last_reseed > current_time): # Avoid float comparison to None to make Py3k happy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pycrypto-2.6/lib/Crypto/Random/_UserFriendlyRNG.py new/pycrypto-2.6.1/lib/Crypto/Random/_UserFriendlyRNG.py
--- old/pycrypto-2.6/lib/Crypto/Random/_UserFriendlyRNG.py 2012-05-24 14:55:30.000000000 +0200
+++ new/pycrypto-2.6.1/lib/Crypto/Random/_UserFriendlyRNG.py 2013-10-14 23:38:10.000000000 +0200
@@ -90,9 +90,24 @@
"""Initialize the random number generator and seed it with entropy from
the operating system.
"""
+
+ # Save the pid (helps ensure that Crypto.Random.atfork() gets called)
self._pid = os.getpid()
+
+ # Collect entropy from the operating system and feed it to
+ # FortunaAccumulator
self._ec.reinit()
+ # Override FortunaAccumulator's 100ms minimum re-seed interval. This
+ # is necessary to avoid a race condition between this function and
+ # self.read(), which that can otherwise cause forked child processes to
+ # produce identical output. (e.g. CVE-2013-1445)
+ #
+ # Note that if this function can be called frequently by an attacker,
+ # (and if the bits from OSRNG are insufficiently random) it will weaken
+ # Fortuna's ability to resist a state compromise extension attack.
+ self._fa._forget_last_reseed()
+
def close(self):
self.closed = True
self._osrng = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pycrypto-2.6/lib/Crypto/SelfTest/Random/__init__.py new/pycrypto-2.6.1/lib/Crypto/SelfTest/Random/__init__.py
--- old/pycrypto-2.6/lib/Crypto/SelfTest/Random/__init__.py 2012-05-24 14:55:30.000000000 +0200
+++ new/pycrypto-2.6.1/lib/Crypto/SelfTest/Random/__init__.py 2013-10-14 23:38:10.000000000 +0200
@@ -32,6 +32,7 @@
from Crypto.SelfTest.Random import OSRNG; tests += OSRNG.get_tests(config=config)
from Crypto.SelfTest.Random import test_random; tests += test_random.get_tests(config=config)
from Crypto.SelfTest.Random import test_rpoolcompat; tests += test_rpoolcompat.get_tests(config=config)
+ from Crypto.SelfTest.Random import test__UserFriendlyRNG; tests += test__UserFriendlyRNG.get_tests(config=config)
return tests
if __name__ == '__main__':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pycrypto-2.6/lib/Crypto/SelfTest/Random/test__UserFriendlyRNG.py new/pycrypto-2.6.1/lib/Crypto/SelfTest/Random/test__UserFriendlyRNG.py
--- old/pycrypto-2.6/lib/Crypto/SelfTest/Random/test__UserFriendlyRNG.py 1970-01-01 01:00:00.000000000 +0100
+++ new/pycrypto-2.6.1/lib/Crypto/SelfTest/Random/test__UserFriendlyRNG.py 2013-10-14 23:38:10.000000000 +0200
@@ -0,0 +1,171 @@
+# -*- coding: utf-8 -*-
+# Self-tests for the user-friendly Crypto.Random interface
+#
+# Written in 2013 by Dwayne C. Litzenberger