LibuvEntropyProvider.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "util/events/libuv/UvWrapper.h"
  16. #include "crypto/random/libuv/LibuvEntropyProvider.h"
  17. #include "crypto/random/Random.h"
  18. #include "memory/Allocator.h"
  19. #include "util/events/EventBase.h"
  20. #include "util/events/Timeout.h"
  21. #include "util/Identity.h"
  22. #include "util/log/Log.h"
  23. #include <inttypes.h>
  24. /**
  25. * Number of milliseconds between samples.
  26. * Set to 1 second so random generator will be refreshed every 256 seconds.
  27. * (4 minutes 16 seconds)
  28. */
  29. #define SAMPLE_MILLISECONDS 1000
  30. struct LibuvEntropyProvider
  31. {
  32. struct Allocator* alloc;
  33. struct Random* rand;
  34. struct Timeout* timeout;
  35. struct Log* logger;
  36. Identity
  37. };
  38. static void takeSample(void* vLibuvEntropyProvider)
  39. {
  40. struct LibuvEntropyProvider* lep =
  41. Identity_check((struct LibuvEntropyProvider*) vLibuvEntropyProvider);
  42. uint64_t nanotime = uv_hrtime();
  43. Log_keys(lep->logger, "Adding high-res time [%" PRIu64 "] to random generator", nanotime);
  44. uint32_t input = (uint32_t) (nanotime ^ (nanotime >> 32));
  45. Random_addRandom(lep->rand, input);
  46. }
  47. void LibuvEntropyProvider_start(struct Random* provideTo,
  48. struct EventBase* base,
  49. struct Log* logger,
  50. struct Allocator* alloc)
  51. {
  52. struct LibuvEntropyProvider* lep =
  53. Allocator_calloc(alloc, sizeof(struct LibuvEntropyProvider), 1);
  54. Log_info(logger, "Taking clock samples every [%d]ms for random generator", SAMPLE_MILLISECONDS);
  55. lep->alloc = alloc;
  56. lep->rand = provideTo;
  57. lep->timeout = Timeout_setInterval(takeSample, lep, SAMPLE_MILLISECONDS, base, alloc);
  58. lep->logger = logger;
  59. Identity_set(lep);
  60. }
  61. struct Random* LibuvEntropyProvider_newDefaultRandom(struct EventBase* base,
  62. struct Log* logger,
  63. struct Except* eh,
  64. struct Allocator* alloc)
  65. {
  66. struct Random* rand = Random_new(alloc, logger, eh);
  67. LibuvEntropyProvider_start(rand, base, logger, alloc);
  68. return rand;
  69. }