1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21  import sys 
 22  import threading 
 23  from Crypto.Util.randpool import RandomPool as _RandomPool 
 24   
 25  try: 
 26      import platform 
 27  except ImportError: 
 28      platform = None      
 29   
 31      assert len(a) == len(b) 
 32      return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), a, b)) 
  33   
 34   
 35   
 36   
 37   
 38   
 39   
 40   
 41   
 42   
 43   
 44  if ((platform is not None and platform.system().lower() == 'windows') or 
 45          sys.platform == 'win32'): 
 46       
 47      from paramiko import rng_win32 
 48      rng_device = rng_win32.open_rng_device() 
 49  else: 
 50       
 51      from paramiko import rng_posix 
 52      rng_device = rng_posix.open_rng_device() 
 53   
 54   
 56      """Wrapper around RandomPool guaranteeing strong random numbers. 
 57       
 58      Crypto.Util.randpool.RandomPool will silently operate even if it is seeded 
 59      with little or no entropy, and it provides no prediction resistance if its 
 60      state is ever compromised throughout its runtime.  It is also not thread-safe. 
 61   
 62      This wrapper augments RandomPool by XORing its output with random bits from 
 63      the operating system, and by controlling access to the underlying 
 64      RandomPool using an exclusive lock. 
 65      """ 
 66   
 68          if instance is None: 
 69              instance = _RandomPool() 
 70          self.randpool = instance 
 71          self.randpool_lock = threading.Lock() 
 72          self.entropy = rng_device 
 73   
 74           
 75          self.randpool.stir(self.entropy.read(32)) 
 76          self.entropy.randomize() 
  77   
 78 -    def stir(self, s=''): 
  79          self.randpool_lock.acquire() 
 80          try: 
 81              self.randpool.stir(s) 
 82          finally: 
 83              self.randpool_lock.release() 
 84          self.entropy.randomize() 
  85   
 87          self.randpool_lock.acquire() 
 88          try: 
 89              self.randpool.randomize(N) 
 90          finally: 
 91              self.randpool_lock.release() 
 92          self.entropy.randomize() 
  93   
 95          self.randpool_lock.acquire() 
 96          try: 
 97              self.randpool.add_event(s) 
 98          finally: 
 99              self.randpool_lock.release() 
 100   
102          self.randpool_lock.acquire() 
103          try: 
104              randpool_data = self.randpool.get_bytes(N) 
105          finally: 
106              self.randpool_lock.release() 
107          entropy_data = self.entropy.read(N) 
108          result = _strxor(randpool_data, entropy_data) 
109          assert len(randpool_data) == N and len(entropy_data) == N and len(result) == N 
110          return result 
  111   
112   
113