updated pycrypto
This commit is contained in:
@@ -36,9 +36,6 @@ import warnings
|
||||
from Crypto.pct_warnings import ClockRewindWarning
|
||||
import SHAd256
|
||||
|
||||
# If the system has monotonic time, we'll use it.
|
||||
from Crypto.Util._time import maybe_monotonic_time
|
||||
|
||||
import FortunaGenerator
|
||||
|
||||
class FortunaPool(object):
|
||||
@@ -97,25 +94,8 @@ def which_pools(r):
|
||||
|
||||
class FortunaAccumulator(object):
|
||||
|
||||
# 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
|
||||
min_pool_size = 64 # TODO: explain why
|
||||
reseed_interval = 0.100 # 100 ms TODO: explain why
|
||||
|
||||
def __init__(self):
|
||||
self.reseed_count = 0
|
||||
@@ -129,17 +109,8 @@ class FortunaAccumulator(object):
|
||||
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 = maybe_monotonic_time()
|
||||
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
|
||||
warnings.warn("Clock rewind detected. Resetting last_reseed.", ClockRewindWarning)
|
||||
self.last_reseed = None
|
||||
@@ -152,7 +123,7 @@ class FortunaAccumulator(object):
|
||||
|
||||
def _reseed(self, current_time=None):
|
||||
if current_time is None:
|
||||
current_time = maybe_monotonic_time()
|
||||
current_time = time.time()
|
||||
seed = []
|
||||
self.reseed_count += 1
|
||||
self.last_reseed = current_time
|
||||
|
@@ -25,7 +25,7 @@
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
|
||||
if sys.version_info[0] is 2 and sys.version_info[1] is 1:
|
||||
from Crypto.Util.py21compat import *
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
__revision__ = "$Id$"
|
||||
__all__ = ['WindowsRNG']
|
||||
|
||||
from Crypto.Random.OSRNG import winrandom
|
||||
import winrandom
|
||||
from rng_base import BaseRNG
|
||||
|
||||
class WindowsRNG(BaseRNG):
|
||||
|
@@ -90,24 +90,9 @@ class _UserFriendlyRNG(object):
|
||||
"""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
|
||||
|
@@ -103,13 +103,13 @@ class StrongRandom(object):
|
||||
|
||||
def shuffle(self, x):
|
||||
"""Shuffle the sequence in place."""
|
||||
# Fisher-Yates shuffle. O(n)
|
||||
# See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
|
||||
# Working backwards from the end of the array, we choose a random item
|
||||
# from the remaining items until all items have been chosen.
|
||||
for i in xrange(len(x)-1, 0, -1): # iterate from len(x)-1 downto 1
|
||||
j = self.randrange(0, i+1) # choose random j such that 0 <= j <= i
|
||||
x[i], x[j] = x[j], x[i] # exchange x[i] and x[j]
|
||||
# Make a (copy) of the list of objects we want to shuffle
|
||||
items = list(x)
|
||||
|
||||
# Choose a random item (without replacement) until all the items have been
|
||||
# chosen.
|
||||
for i in xrange(len(x)):
|
||||
x[i] = items.pop(self.randrange(len(items)))
|
||||
|
||||
def sample(self, population, k):
|
||||
"""Return a k-length list of unique elements chosen from the population sequence."""
|
||||
|
Reference in New Issue
Block a user