/*************************************************
* Global RNG Seeding Source File                 *
* (C) 1999-2004 The Botan Project                *
*************************************************/

#include <botan/rng.h>
#include <botan/es_file.h>
#include <memory>

#if defined(BOTAN_EXT_ENTROPY_SRC_EGD)
  #include <botan/es_egd.h>
#endif

#if defined(BOTAN_EXT_ENTROPY_SRC_UNIX)
  #include <botan/es_unix.h>
#endif

#if defined(BOTAN_EXT_ENTROPY_SRC_BEOS)
  #include <botan/es_beos.h>
#endif

#if defined(BOTAN_EXT_ENTROPY_SRC_CAPI)
  #include <botan/es_capi.h>
#endif

#if defined(BOTAN_EXT_ENTROPY_SRC_WIN32)
  #include <botan/es_win32.h>
#endif

#if defined(BOTAN_EXT_ENTROPY_SRC_FTW)
  #include <botan/es_ftw.h>
#endif

namespace Botan {

namespace {

/*************************************************
* Try to do a poll on an EntropySource           *
*************************************************/
u32bit poll_es(EntropySource* source_ptr, bool slow_poll)
   {
   std::auto_ptr<EntropySource> source(source_ptr);

   SecureVector<byte> buffer(256);
   u32bit got = 0;

   if(slow_poll) got = source->slow_poll(buffer.begin(), buffer.size());
   else          got = source->fast_poll(buffer.begin(), buffer.size());

   Global_RNG::add_entropy(buffer.begin(), got);
   return entropy_estimate(buffer.begin(), got);
   }

}

namespace Global_RNG {

/*************************************************
* Seed the global RNG                            *
*************************************************/
u32bit seed(bool slow_poll, u32bit bits_to_get)
   {
   u32bit bits = 0;

   bits += poll_es(new File_EntropySource, slow_poll);

#if defined(BOTAN_EXT_ENTROPY_SRC_EGD)
   bits += poll_es(new EGD_EntropySource, slow_poll);
#endif

#if defined(BOTAN_EXT_ENTROPY_SRC_CAPI)
   bits += poll_es(new Win32_CAPI_EntropySource, slow_poll);
#endif

   if(bits_to_get && bits >= bits_to_get)
      return bits;

#if defined(BOTAN_EXT_ENTROPY_SRC_WIN32)
   bits += poll_es(new Win32_EntropySource, slow_poll);
#endif

#if defined(BOTAN_EXT_ENTROPY_SRC_UNIX)
   bits += poll_es(new Unix_EntropySource, slow_poll);
#endif

#if defined(BOTAN_EXT_ENTROPY_SRC_BEOS)
   bits += poll_es(new BeOS_EntropySource, slow_poll);
#endif

   if(bits_to_get && bits >= bits_to_get)
      return bits;

#if defined(BOTAN_EXT_ENTROPY_SRC_FTW)
   bits += poll_es(new FTW_EntropySource, slow_poll);
#endif

   return bits;
   }

}

}
