void FTW_EntropySource::poll(Entropy_Accumulator& accum)
   {
   const size_t MAX_FILES_READ_PER_POLL = 2048;

   if(!dir)
      dir = new Directory_Walker(path);

   MemoryRegion<byte>& io_buffer = accum.get_io_buffer(4096);

   for(size_t i = 0; i != MAX_FILES_READ_PER_POLL; ++i)
      {
      int fd = dir->next_fd();

      // If we've exhaused this walk of the directory, halt the poll
      if(fd == -1)
         {
         delete dir;
         dir = 0;
         break;
         }

      ssize_t got = ::read(fd, &io_buffer[0], io_buffer.size());
      ::close(fd);

      if(got > 0)
         accum.add(&io_buffer[0], got, .001);

      if(accum.polling_goal_achieved())
         break;
      }
   }
Exemple #2
0
void ProcWalking_EntropySource::poll(Entropy_Accumulator& accum)
   {
   const size_t MAX_FILES_READ_PER_POLL = 2048;
   const double ENTROPY_ESTIMATE = 1.0 / (8*1024);

   std::lock_guard<std::mutex> lock(m_mutex);

   if(!m_dir)
      m_dir.reset(new Directory_Walker(m_path));

   m_buf.resize(4096);

   for(size_t i = 0; i != MAX_FILES_READ_PER_POLL; ++i)
      {
      int fd = m_dir->next_fd();

      // If we've exhaused this walk of the directory, halt the poll
      if(fd == -1)
         {
         m_dir.reset();
         break;
         }

      ssize_t got = ::read(fd, m_buf.data(), m_buf.size());
      ::close(fd);

      if(got > 0)
         accum.add(m_buf.data(), got, ENTROPY_ESTIMATE);

      if(accum.polling_finished())
         break;
      }
   }
Exemple #3
0
void UnixProcessInfo_EntropySource::poll(Entropy_Accumulator& accum)
   {
   accum.add(::getpid(), BOTAN_ENTROPY_ESTIMATE_STATIC_SYSTEM_DATA);
   accum.add(::getppid(), BOTAN_ENTROPY_ESTIMATE_STATIC_SYSTEM_DATA);
   accum.add(::getuid(),  BOTAN_ENTROPY_ESTIMATE_STATIC_SYSTEM_DATA);
   accum.add(::getgid(),  BOTAN_ENTROPY_ESTIMATE_STATIC_SYSTEM_DATA);
   accum.add(::getpgrp(), BOTAN_ENTROPY_ESTIMATE_STATIC_SYSTEM_DATA);

   struct ::rusage usage;
   ::getrusage(RUSAGE_SELF, &usage);
   accum.add(usage, BOTAN_ENTROPY_ESTIMATE_STATIC_SYSTEM_DATA);
   }
Exemple #4
0
/*
* Gather Entropy from Win32 CAPI
*/
void Win32_CAPI_EntropySource::poll(Entropy_Accumulator& accum)
   {
   secure_vector<byte>& buf = accum.get_io_buf(BOTAN_SYSTEM_RNG_POLL_REQUEST);

   for(size_t i = 0; i != m_prov_types.size(); ++i)
      {
      CSP_Handle csp(m_prov_types[i]);

      if(size_t got = csp.gen_random(buf.data(), buf.size()))
         {
         accum.add(buf.data(), got, BOTAN_ENTROPY_ESTIMATE_STRONG_RNG);
         break;
         }
      }
   }
Exemple #5
0
/**
* Gather Entropy from EGD
*/
void EGD_EntropySource::poll(Entropy_Accumulator& accum)
   {
   size_t go_get = std::min<size_t>(accum.desired_remaining_bits() / 8, 32);

   MemoryRegion<byte>& io_buffer = accum.get_io_buffer(go_get);

   for(size_t i = 0; i != sockets.size(); ++i)
      {
      size_t got = sockets[i].read(&io_buffer[0], io_buffer.size());

      if(got)
         {
         accum.add(&io_buffer[0], got, 6);
         break;
         }
      }
   }
void Entropy_Sources::poll(Entropy_Accumulator& accum)
{
    for(size_t i = 0; i != m_srcs.size(); ++i)
    {
        m_srcs[i]->poll(accum);
        if(accum.polling_goal_achieved())
            break;
    }
}
Exemple #7
0
/**
* Gather entropy from a RNG device
*/
void Device_EntropySource::poll(Entropy_Accumulator& accum)
   {
   u32bit go_get = std::min<u32bit>(accum.desired_remaining_bits() / 8, 48);

   u32bit read_wait_ms = std::max<u32bit>(go_get, 1000);
   MemoryRegion<byte>& io_buffer = accum.get_io_buffer(go_get);

   for(size_t i = 0; i != devices.size(); ++i)
      {
      u32bit got = devices[i].get(io_buffer.begin(), io_buffer.size(),
                                  read_wait_ms);

      if(got)
         {
         accum.add(io_buffer.begin(), got, 8);
         break;
         }
      }
   }
Exemple #8
0
/**
* Gather Entropy from EGD
*/
void EGD_EntropySource::poll(Entropy_Accumulator& accum)
   {
   const size_t ENTROPY_BITS_PER_BYTE = 8;

   std::lock_guard<std::mutex> lock(m_mutex);

   secure_vector<byte>& buf = accum.get_io_buf(BOTAN_SYSTEM_RNG_POLL_REQUEST);

   for(size_t i = 0; i != sockets.size(); ++i)
      {
      size_t got = sockets[i].read(buf.data(), buf.size());

      if(got)
         {
         accum.add(buf.data(), got, ENTROPY_BITS_PER_BYTE);
         break;
         }
      }
   }
Exemple #9
0
/*
* Gather Entropy from Win32 CAPI
*/
void Win32_CAPI_EntropySource::poll(Entropy_Accumulator& accum)
   {
   m_buf.resize(32);

   for(size_t i = 0; i != prov_types.size(); ++i)
      {
      CSP_Handle csp(prov_types[i]);

      if(size_t got = csp.gen_random(m_buf.data(), m_buf.size()))
         {
         accum.add(m_buf.data(), got, 6);
         break;
         }
      }
   }
Exemple #10
0
/**
* BeOS entropy poll
*/
void BeOS_EntropySource::poll(Entropy_Accumulator& accum)
   {
   system_info info_sys;
   get_system_info(&info_sys);
   accum.add(info_sys, BOTAN_ENTROPY_ESTIMATE_SYSTEM_DATA);

   key_info info_key; // current state of the keyboard
   get_key_info(&info_key);
   accum.add(info_key, BOTAN_ENTROPY_ESTIMATE_SYSTEM_DATA);

   team_info info_team;
   int32 cookie_team = 0;

   while(get_next_team_info(&cookie_team, &info_team) == B_OK)
      {
      accum.add(info_team, BOTAN_ENTROPY_ESTIMATE_SYSTEM_DATA);

      team_id id = info_team.team;
      int32 cookie = 0;

      thread_info info_thr;
      while(get_next_thread_info(id, &cookie, &info_thr) == B_OK)
         accum.add(info_thr, BOTAN_ENTROPY_ESTIMATE_SYSTEM_DATA);

      cookie = 0;
      image_info info_img;
      while(get_next_image_info(id, &cookie, &info_img) == B_OK)
         accum.add(info_img, BOTAN_ENTROPY_ESTIMATE_SYSTEM_DATA);

      cookie = 0;
      sem_info info_sem;
      while(get_next_sem_info(id, &cookie, &info_sem) == B_OK)
         accum.add(info_sem, BOTAN_ENTROPY_ESTIMATE_SYSTEM_DATA);

      cookie = 0;
      area_info info_area;
      while(get_next_area_info(id, &cookie, &info_area) == B_OK)
         accum.add(info_area, BOTAN_ENTROPY_ESTIMATE_SYSTEM_DATA);

      if(accum.polling_finished())
         break;
      }
   }
Exemple #11
0
/**
* Gather entropy from a RNG device
*/
void Device_EntropySource::poll(Entropy_Accumulator& accum)
   {
   if(m_devices.empty())
      return;

   const size_t ENTROPY_BITS_PER_BYTE = 8;
   const size_t MS_WAIT_TIME = 32;
   const size_t READ_ATTEMPT = 32;

   int max_fd = m_devices[0];
   fd_set read_set;
   FD_ZERO(&read_set);
   for(size_t i = 0; i != m_devices.size(); ++i)
      {
      FD_SET(m_devices[i], &read_set);
      max_fd = std::max(m_devices[i], max_fd);
      }

   struct ::timeval timeout;

   timeout.tv_sec = (MS_WAIT_TIME / 1000);
   timeout.tv_usec = (MS_WAIT_TIME % 1000) * 1000;

   if(::select(max_fd + 1, &read_set, nullptr, nullptr, &timeout) < 0)
      return;

   m_buf.resize(READ_ATTEMPT);

   for(size_t i = 0; i != m_devices.size(); ++i)
      {
      if(FD_ISSET(m_devices[i], &read_set))
         {
         const ssize_t got = ::read(m_devices[i], &m_buf[0], m_buf.size());
         if(got > 0)
            accum.add(&m_buf[0], got, ENTROPY_BITS_PER_BYTE);
         }
      }
   }
Exemple #12
0
/**
* Win32 poll using stats functions including Tooltip32
*/
void Win32_EntropySource::poll(Entropy_Accumulator& accum)
   {
   /*
   First query a bunch of basic statistical stuff, though
   don't count it for much in terms of contributed entropy.
   */
   accum.add(GetTickCount(), 0);
   accum.add(GetMessagePos(), 0);
   accum.add(GetMessageTime(), 0);
   accum.add(GetInputState(), 0);
   accum.add(GetCurrentProcessId(), 0);
   accum.add(GetCurrentThreadId(), 0);

   SYSTEM_INFO sys_info;
   GetSystemInfo(&sys_info);
   accum.add(sys_info, 1);

   MEMORYSTATUS mem_info;
   GlobalMemoryStatus(&mem_info);
   accum.add(mem_info, 1);

   POINT point;
   GetCursorPos(&point);
   accum.add(point, 1);

   GetCaretPos(&point);
   accum.add(point, 1);

   LARGE_INTEGER perf_counter;
   QueryPerformanceCounter(&perf_counter);
   accum.add(perf_counter, 0);

   /*
   Now use the Tooltip library to iterate throug various objects on
   the system, including processes, threads, and heap objects.
   */

   HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);

#define TOOLHELP32_ITER(DATA_TYPE, FUNC_FIRST, FUNC_NEXT) \
   if(!accum.polling_finished())                     \
      {                                                   \
      DATA_TYPE info;                                     \
      info.dwSize = sizeof(DATA_TYPE);                    \
      if(FUNC_FIRST(snapshot, &info))                     \
         {                                                \
         do                                               \
            {                                             \
            accum.add(info, 1);                           \
            } while(FUNC_NEXT(snapshot, &info));          \
         }                                                \
      }

   TOOLHELP32_ITER(MODULEENTRY32, Module32First, Module32Next);
   TOOLHELP32_ITER(PROCESSENTRY32, Process32First, Process32Next);
   TOOLHELP32_ITER(THREADENTRY32, Thread32First, Thread32Next);

#undef TOOLHELP32_ITER

   if(!accum.polling_finished())
      {
      size_t heap_lists_found = 0;
      HEAPLIST32 heap_list;
      heap_list.dwSize = sizeof(HEAPLIST32);

      const size_t HEAP_LISTS_MAX = 32;
      const size_t HEAP_OBJS_PER_LIST = 128;

      if(Heap32ListFirst(snapshot, &heap_list))
         {
         do
            {
            accum.add(heap_list, 1);

            if(++heap_lists_found > HEAP_LISTS_MAX)
               break;

            size_t heap_objs_found = 0;
            HEAPENTRY32 heap_entry;
            heap_entry.dwSize = sizeof(HEAPENTRY32);
            if(Heap32First(&heap_entry, heap_list.th32ProcessID,
                           heap_list.th32HeapID))
               {
               do
                  {
                  if(heap_objs_found++ > HEAP_OBJS_PER_LIST)
                     break;
                  accum.add(heap_entry, 1);
                  } while(Heap32Next(&heap_entry));
               }

            if(accum.polling_finished())
               break;

            } while(Heap32ListNext(snapshot, &heap_list));
         }
      }

   CloseHandle(snapshot);
   }
Exemple #13
0
void Unix_EntropySource::poll(Entropy_Accumulator& accum)
   {
   // refuse to run setuid or setgid, or as root
   if((getuid() != geteuid()) || (getgid() != getegid()) || (geteuid() == 0))
      return;

   std::lock_guard<std::mutex> lock(m_mutex);

   if(m_sources.empty())
      {
      auto sources = get_default_sources();

      for(auto src : sources)
         {
         const std::string path = find_full_path_if_exists(m_trusted_paths, src[0]);
         if(path != "")
            {
            src[0] = path;
            m_sources.push_back(src);
            }
         }
      }

   if(m_sources.empty())
      return; // still empty, really nothing to try

   const size_t MS_WAIT_TIME = 32;

   m_buf.resize(4096);

   while(!accum.polling_finished())
      {
      while(m_procs.size() < m_concurrent)
         m_procs.emplace_back(Unix_Process(next_source()));

      fd_set read_set;
      FD_ZERO(&read_set);

      std::vector<int> fds;

      for(auto& proc : m_procs)
         {
         int fd = proc.fd();
         if(fd > 0)
            {
            fds.push_back(fd);
            FD_SET(fd, &read_set);
            }
         }

      if(fds.empty())
         break;

      const int max_fd = *std::max_element(fds.begin(), fds.end());

      struct ::timeval timeout;
      timeout.tv_sec = (MS_WAIT_TIME / 1000);
      timeout.tv_usec = (MS_WAIT_TIME % 1000) * 1000;

      if(::select(max_fd + 1, &read_set, nullptr, nullptr, &timeout) < 0)
         return; // or continue?

      for(auto& proc : m_procs)
         {
         int fd = proc.fd();

         if(FD_ISSET(fd, &read_set))
            {
            const ssize_t got = ::read(fd, m_buf.data(), m_buf.size());
            if(got > 0)
               accum.add(m_buf.data(), got, BOTAN_ENTROPY_ESTIMATE_SYSTEM_TEXT);
            else
               proc.spawn(next_source());
            }
         }
      }
   }