Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

ottery_entropy.c 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* Libottery by Nick Mathewson.
  2. This software has been dedicated to the public domain under the CC0
  3. public domain dedication.
  4. To the extent possible under law, the person who associated CC0 with
  5. libottery has waived all copyright and related or neighboring rights
  6. to libottery.
  7. You should have received a copy of the CC0 legalcode along with this
  8. work in doc/cc0.txt. If not, see
  9. <http://creativecommons.org/publicdomain/zero/1.0/>.
  10. */
  11. #define OTTERY_INTERNAL
  12. #include "ottery-internal.h"
  13. #include "ottery.h"
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <unistd.h>
  17. #include <string.h>
  18. #define SRC(x) OTTERY_ENTROPY_SRC_ ## x
  19. #define DOM(x) OTTERY_ENTROPY_DOM_ ## x
  20. #define FL(x) OTTERY_ENTROPY_FL_ ## x
  21. #include "ottery_entropy_cryptgenrandom.c"
  22. #include "ottery_entropy_urandom.c"
  23. #include "ottery_entropy_rdrand.c"
  24. #include "ottery_entropy_egd.c"
  25. /** Table of RNG functions and their properties. */
  26. static struct ottery_randbytes_source {
  27. int (*fn)(const struct ottery_entropy_config *,
  28. struct ottery_entropy_state *,
  29. uint8_t *, size_t);
  30. uint32_t flags;
  31. } RAND_SOURCES[] = {
  32. #ifdef ENTROPY_SOURCE_CRYPTGENRANDOM
  33. ENTROPY_SOURCE_CRYPTGENRANDOM,
  34. #endif
  35. #ifdef ENTROPY_SOURCE_URANDOM
  36. ENTROPY_SOURCE_URANDOM,
  37. #endif
  38. #ifdef ENTROPY_SOURCE_EGD
  39. ENTROPY_SOURCE_EGD,
  40. #endif
  41. #ifdef ENTROPY_SOURCE_RDRAND
  42. ENTROPY_SOURCE_RDRAND,
  43. #endif
  44. { NULL, 0 }
  45. };
  46. size_t
  47. ottery_get_entropy_bufsize_(size_t n)
  48. {
  49. return n * (sizeof(RAND_SOURCES)/sizeof(RAND_SOURCES[0]) - 1);
  50. }
  51. int
  52. ottery_get_entropy_(const struct ottery_entropy_config *config,
  53. struct ottery_entropy_state *state,
  54. uint32_t select_sources,
  55. uint8_t *bytes, size_t n, size_t *buflen,
  56. uint32_t *flags_out)
  57. {
  58. ssize_t err = OTTERY_ERR_INIT_STRONG_RNG, last_err = 0;
  59. int i;
  60. uint32_t got = 0;
  61. uint8_t *next;
  62. const uint32_t disabled_sources = config ? config->disabled_sources : 0;
  63. memset(bytes, 0, *buflen);
  64. next = bytes;
  65. *flags_out = 0;
  66. for (i=0; RAND_SOURCES[i].fn; ++i) {
  67. uint32_t flags = RAND_SOURCES[i].flags;
  68. /* Don't use a disabled source. */
  69. if (0 != (flags & disabled_sources))
  70. continue;
  71. /* If some flags must be set, only use those. */
  72. if ((flags & select_sources) != select_sources)
  73. continue;
  74. /* If we already have input from a certain domain, we don't need more */
  75. if ((flags & (got & OTTERY_ENTROPY_DOM_MASK)) != 0)
  76. continue;
  77. /* If we can't write these bytes, don't try. */
  78. if (next + n > bytes + *buflen)
  79. break;
  80. err = RAND_SOURCES[i].fn(config, state, next, n);
  81. if (err == 0) {
  82. uint32_t flags = RAND_SOURCES[i].flags;
  83. if (config && (flags & config->weak_sources))
  84. flags &= ~OTTERY_ENTROPY_FL_STRONG;
  85. got |= flags;
  86. next += n;
  87. } else {
  88. last_err = err;
  89. }
  90. }
  91. /* Do not report success unless at least one source was strong. */
  92. if (0 == (got & OTTERY_ENTROPY_FL_STRONG))
  93. return last_err ? last_err : OTTERY_ERR_INIT_STRONG_RNG;
  94. *flags_out = got;
  95. *buflen = next - bytes;
  96. return 0;
  97. }