/*************************************************
* Global RNG Seeding Source File                 *
* (C) 1999-2003 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_PTHREAD)
  #include <botan/es_pthr.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, u32bit buf_size = 256)
   {
   std::auto_ptr<EntropySource> source(source_ptr);

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

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

   Global_RNG::add_entropy(buffer, got);
   return entropy_estimate(buffer, 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, 128);
#endif

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

   if(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 >= bits_to_get) return bits;

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

#if defined(BOTAN_EXT_ENTROPY_SRC_PTHREAD)
   bits += poll_es(new Pthread_EntropySource, slow_poll);
#endif

   return bits;
   }

}

}
