rbnacl-libsodium 1.0.15.1 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -6
  3. data/CHANGES.md +50 -42
  4. data/Gemfile +1 -1
  5. data/README.md +3 -1
  6. data/Rakefile +46 -0
  7. data/ext/rbnacl/extconf.rb +16 -1
  8. data/lib/rbnacl/libsodium.rb +16 -8
  9. data/lib/rbnacl/libsodium/version.rb +1 -1
  10. data/rbnacl-libsodium.gemspec +3 -0
  11. data/vendor/libsodium/AUTHORS +20 -5
  12. data/vendor/libsodium/ChangeLog +25 -0
  13. data/vendor/libsodium/Makefile.in +3 -1
  14. data/vendor/libsodium/README.markdown +2 -1
  15. data/vendor/libsodium/aclocal.m4 +1 -0
  16. data/vendor/libsodium/autom4te.cache/output.1 +836 -123
  17. data/vendor/libsodium/autom4te.cache/output.4 +21342 -0
  18. data/vendor/libsodium/autom4te.cache/requests +801 -554
  19. data/vendor/libsodium/autom4te.cache/traces.1 +717 -596
  20. data/vendor/libsodium/autom4te.cache/traces.4 +4355 -0
  21. data/vendor/libsodium/builds/Makefile.in +3 -1
  22. data/vendor/libsodium/builds/msvc/resource.h +1 -1
  23. data/vendor/libsodium/builds/msvc/resource.rc +2 -2
  24. data/vendor/libsodium/builds/msvc/version.h +2 -2
  25. data/vendor/libsodium/builds/msvc/vs2010/libsodium/libsodium.vcxproj +17 -8
  26. data/vendor/libsodium/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters +60 -24
  27. data/vendor/libsodium/builds/msvc/vs2012/libsodium/libsodium.vcxproj +17 -8
  28. data/vendor/libsodium/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters +60 -24
  29. data/vendor/libsodium/builds/msvc/vs2013/libsodium/libsodium.vcxproj +17 -8
  30. data/vendor/libsodium/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters +60 -24
  31. data/vendor/libsodium/builds/msvc/vs2015/libsodium/libsodium.vcxproj +17 -8
  32. data/vendor/libsodium/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters +60 -24
  33. data/vendor/libsodium/builds/msvc/vs2017/libsodium/libsodium.vcxproj +17 -8
  34. data/vendor/libsodium/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters +60 -24
  35. data/vendor/libsodium/configure +834 -121
  36. data/vendor/libsodium/configure.ac +55 -13
  37. data/vendor/libsodium/contrib/Findsodium.cmake +22 -3
  38. data/vendor/libsodium/contrib/Makefile.in +3 -1
  39. data/vendor/libsodium/dist-build/Makefile.in +3 -1
  40. data/vendor/libsodium/dist-build/android-build.sh +2 -2
  41. data/vendor/libsodium/dist-build/emscripten-symbols.def +38 -26
  42. data/vendor/libsodium/dist-build/emscripten.sh +23 -8
  43. data/vendor/libsodium/dist-build/msys2-win32.sh +1 -1
  44. data/vendor/libsodium/dist-build/msys2-win64.sh +1 -1
  45. data/vendor/libsodium/libsodium.vcxproj +17 -8
  46. data/vendor/libsodium/libsodium.vcxproj.filters +41 -14
  47. data/vendor/libsodium/m4/ax_tls.m4 +74 -0
  48. data/vendor/libsodium/msvc-scripts/Makefile.in +3 -1
  49. data/vendor/libsodium/msvc-scripts/process.bat +2 -2
  50. data/vendor/libsodium/packaging/dotnet-core/README.md +5 -5
  51. data/vendor/libsodium/packaging/dotnet-core/prepare.py +7 -7
  52. data/vendor/libsodium/packaging/nuget/package.config +1 -1
  53. data/vendor/libsodium/regen-msvc/libsodium.vcxproj +326 -0
  54. data/vendor/libsodium/regen-msvc/libsodium.vcxproj.filters +23 -0
  55. data/vendor/libsodium/regen-msvc/libsodium.vcxproj.filters.tpl +35 -0
  56. data/vendor/libsodium/regen-msvc/libsodium.vcxproj.tpl +93 -0
  57. data/vendor/libsodium/regen-msvc/regen-msvc.py +136 -0
  58. data/vendor/libsodium/regen-msvc/tl_libsodium.vcxproj.filters.tpl +23 -0
  59. data/vendor/libsodium/regen-msvc/tl_libsodium.vcxproj.tpl +331 -0
  60. data/vendor/libsodium/src/Makefile.in +3 -1
  61. data/vendor/libsodium/src/libsodium/Makefile.am +40 -24
  62. data/vendor/libsodium/src/libsodium/Makefile.in +238 -180
  63. data/vendor/libsodium/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c +10 -2
  64. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/core_ed25519.c +79 -0
  65. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c +2031 -0
  66. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/base.h +1344 -0
  67. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/base2.h +40 -0
  68. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/constants.h +20 -0
  69. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/fe.h +220 -0
  70. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/base.h +1344 -0
  71. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/base2.h +40 -0
  72. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/constants.h +21 -0
  73. data/vendor/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/fe.h +116 -0
  74. data/vendor/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2.h +1 -1
  75. data/vendor/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ref.c +2 -1
  76. data/vendor/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-ref.c +14 -82
  77. data/vendor/libsodium/src/libsodium/crypto_generichash/blake2b/ref/generichash_blake2b.c +1 -0
  78. data/vendor/libsodium/src/libsodium/crypto_hash/sha256/cp/hash_sha256_cp.c +3 -3
  79. data/vendor/libsodium/src/libsodium/crypto_hash/sha512/cp/hash_sha512_cp.c +3 -3
  80. data/vendor/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h +1 -7
  81. data/vendor/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c +1 -0
  82. data/vendor/libsodium/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c +0 -6
  83. data/vendor/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-core.c +19 -92
  84. data/vendor/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-core.h +72 -4
  85. data/vendor/libsodium/src/libsodium/crypto_pwhash/argon2/argon2.c +5 -1
  86. data/vendor/libsodium/src/libsodium/crypto_pwhash/argon2/argon2.h +1 -1
  87. data/vendor/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c +10 -7
  88. data/vendor/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c +108 -231
  89. data/vendor/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.h +1 -1
  90. data/vendor/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c +27 -27
  91. data/vendor/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c +2 -1
  92. data/vendor/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c +6 -3
  93. data/vendor/libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.c +3 -11
  94. data/vendor/libsodium/src/libsodium/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c +86 -0
  95. data/vendor/libsodium/src/libsodium/crypto_sign/ed25519/ref10/keypair.c +28 -26
  96. data/vendor/libsodium/src/libsodium/crypto_sign/ed25519/ref10/obsolete.c +32 -30
  97. data/vendor/libsodium/src/libsodium/crypto_sign/ed25519/ref10/open.c +14 -115
  98. data/vendor/libsodium/src/libsodium/crypto_sign/ed25519/ref10/sign.c +56 -13
  99. data/vendor/libsodium/src/libsodium/crypto_sign/ed25519/ref10/{ed25519_ref10.h → sign_ed25519_ref10.h} +2 -5
  100. data/vendor/libsodium/src/libsodium/crypto_sign/ed25519/sign_ed25519.c +1 -1
  101. data/vendor/libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.c +1 -0
  102. data/vendor/libsodium/src/libsodium/crypto_stream/salsa20/stream_salsa20.c +1 -0
  103. data/vendor/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u8.h +1 -1
  104. data/vendor/libsodium/src/libsodium/include/Makefile.am +2 -0
  105. data/vendor/libsodium/src/libsodium/include/Makefile.in +13 -9
  106. data/vendor/libsodium/src/libsodium/include/sodium.h +2 -0
  107. data/vendor/libsodium/src/libsodium/include/sodium/crypto_core_ed25519.h +37 -0
  108. data/vendor/libsodium/src/libsodium/include/sodium/crypto_scalarmult.h +8 -0
  109. data/vendor/libsodium/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h +8 -0
  110. data/vendor/libsodium/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h +41 -0
  111. data/vendor/libsodium/src/libsodium/include/sodium/private/common.h +18 -0
  112. data/vendor/libsodium/src/libsodium/include/sodium/private/ed25519_ref10.h +125 -0
  113. data/vendor/libsodium/src/libsodium/include/sodium/private/ed25519_ref10_fe_25_5.h +1050 -0
  114. data/vendor/libsodium/src/libsodium/include/sodium/private/ed25519_ref10_fe_51.h +518 -0
  115. data/vendor/libsodium/src/libsodium/include/sodium/runtime.h +3 -0
  116. data/vendor/libsodium/src/libsodium/include/sodium/utils.h +3 -0
  117. data/vendor/libsodium/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c +182 -102
  118. data/vendor/libsodium/src/libsodium/sodium/core.c +30 -2
  119. data/vendor/libsodium/src/libsodium/sodium/runtime.c +14 -0
  120. data/vendor/libsodium/src/libsodium/sodium/utils.c +46 -0
  121. data/vendor/libsodium/test/Makefile.in +3 -1
  122. data/vendor/libsodium/test/default/Makefile.am +16 -0
  123. data/vendor/libsodium/test/default/Makefile.in +71 -23
  124. data/vendor/libsodium/test/default/aead_aes256gcm.c +1 -1
  125. data/vendor/libsodium/test/default/cmptest.h +4 -0
  126. data/vendor/libsodium/test/default/core3.c +44 -4
  127. data/vendor/libsodium/test/default/core3.exp +2 -0
  128. data/vendor/libsodium/test/default/core4.c +1 -1
  129. data/vendor/libsodium/test/default/core_ed25519.c +151 -0
  130. data/vendor/libsodium/test/default/core_ed25519.exp +1 -0
  131. data/vendor/libsodium/test/default/ed25519_convert.c +9 -1
  132. data/vendor/libsodium/test/default/index.html.tpl +17 -3
  133. data/vendor/libsodium/test/default/kdf.c +4 -2
  134. data/vendor/libsodium/test/default/metamorphic.c +8 -8
  135. data/vendor/libsodium/test/default/misuse.c +29 -1
  136. data/vendor/libsodium/test/default/pwhash_argon2i.c +9 -3
  137. data/vendor/libsodium/test/default/pwhash_argon2i.exp +2 -2
  138. data/vendor/libsodium/test/default/pwhash_argon2id.c +7 -2
  139. data/vendor/libsodium/test/default/pwhash_argon2id.exp +2 -2
  140. data/vendor/libsodium/test/default/scalarmult.c +0 -2
  141. data/vendor/libsodium/test/default/scalarmult.exp +0 -1
  142. data/vendor/libsodium/test/default/scalarmult_ed25519.c +90 -0
  143. data/vendor/libsodium/test/default/scalarmult_ed25519.exp +1 -0
  144. data/vendor/libsodium/test/default/secretbox_easy2.c +1 -1
  145. data/vendor/libsodium/test/default/secretstream.c +52 -3
  146. data/vendor/libsodium/test/default/sign.c +16 -0
  147. data/vendor/libsodium/test/default/sodium_core.c +1 -0
  148. data/vendor/libsodium/test/default/sodium_utils.c +2 -1
  149. data/vendor/libsodium/test/default/xchacha20.c +2 -1
  150. metadata +63 -12
  151. data/vendor/libsodium/src/libsodium/crypto_core/curve25519/ref10/base.h +0 -1344
  152. data/vendor/libsodium/src/libsodium/crypto_core/curve25519/ref10/base2.h +0 -40
  153. data/vendor/libsodium/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c +0 -2797
  154. data/vendor/libsodium/src/libsodium/crypto_scalarmult/curve25519/donna_c64/curve25519_donna_c64.c +0 -545
  155. data/vendor/libsodium/src/libsodium/crypto_scalarmult/curve25519/donna_c64/curve25519_donna_c64.h +0 -10
  156. data/vendor/libsodium/src/libsodium/include/sodium/private/curve25519_ref10.h +0 -132
  157. data/vendor/libsodium/test/default/index-wasm.html.tpl +0 -118
@@ -38,6 +38,9 @@ int sodium_runtime_has_pclmul(void);
38
38
  SODIUM_EXPORT_WEAK
39
39
  int sodium_runtime_has_aesni(void);
40
40
 
41
+ SODIUM_EXPORT_WEAK
42
+ int sodium_runtime_has_rdrand(void);
43
+
41
44
  /* ------------------------------------------------------------------------- */
42
45
 
43
46
  int _sodium_runtime_get_cpu_features(void);
@@ -21,6 +21,9 @@ extern "C" {
21
21
  SODIUM_EXPORT
22
22
  void sodium_memzero(void * const pnt, const size_t len);
23
23
 
24
+ SODIUM_EXPORT
25
+ void sodium_stackzero(const size_t len);
26
+
24
27
  /*
25
28
  * WARNING: sodium_memcmp() must be used to verify if two secret keys
26
29
  * are equal, in constant time.
@@ -24,14 +24,18 @@
24
24
  # endif
25
25
  # include <poll.h>
26
26
  #endif
27
+ #ifdef HAVE_RDRAND
28
+ # pragma GCC target("rdrnd")
29
+ # include <immintrin.h>
30
+ #endif
27
31
 
28
32
  #include "core.h"
29
33
  #include "crypto_core_salsa20.h"
30
- #include "crypto_generichash.h"
31
34
  #include "crypto_stream_salsa20.h"
32
35
  #include "private/common.h"
33
36
  #include "randombytes.h"
34
37
  #include "randombytes_salsa20_random.h"
38
+ #include "runtime.h"
35
39
  #include "utils.h"
36
40
 
37
41
  #ifdef _WIN32
@@ -50,7 +54,6 @@ BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
50
54
  #endif
51
55
 
52
56
  #define SALSA20_RANDOM_BLOCK_SIZE crypto_core_salsa20_OUTPUTBYTES
53
- #define HASH_BLOCK_SIZE 128U
54
57
 
55
58
  #if defined(__OpenBSD__) || defined(__CloudABI__)
56
59
  # define HAVE_SAFE_ARC4RANDOM 1
@@ -59,55 +62,97 @@ BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
59
62
  #ifndef SSIZE_MAX
60
63
  # define SSIZE_MAX (SIZE_MAX / 2 - 1)
61
64
  #endif
65
+ #ifndef S_ISNAM
66
+ # ifdef __COMPCERT__
67
+ # define S_ISNAM(X) 1
68
+ # else
69
+ # define S_ISNAM(X) 0
70
+ # endif
71
+ #endif
62
72
 
63
- typedef struct Salsa20Random_ {
64
- size_t rnd32_outleft;
65
- int random_data_source_fd;
73
+ #ifndef TLS
74
+ # ifdef _WIN32
75
+ # define TLS __declspec(thread)
76
+ # else
77
+ # define TLS
78
+ # endif
79
+ #endif
80
+
81
+ typedef struct Salsa20RandomGlobal_ {
66
82
  int initialized;
83
+ int random_data_source_fd;
67
84
  int getrandom_available;
68
- unsigned char key[crypto_stream_salsa20_KEYBYTES];
69
- unsigned char rnd32[16U * SALSA20_RANDOM_BLOCK_SIZE];
70
- uint64_t nonce;
85
+ int rdrand_available;
71
86
  #ifdef HAVE_GETPID
72
87
  pid_t pid;
73
88
  #endif
89
+ } Salsa20RandomGlobal;
90
+
91
+ typedef struct Salsa20Random_ {
92
+ int initialized;
93
+ size_t rnd32_outleft;
94
+ unsigned char key[crypto_stream_salsa20_KEYBYTES];
95
+ unsigned char rnd32[16U * SALSA20_RANDOM_BLOCK_SIZE];
96
+ uint64_t nonce;
74
97
  } Salsa20Random;
75
98
 
76
- static Salsa20Random stream = {
77
- SODIUM_C99(.rnd32_outleft =) (size_t) 0U,
78
- SODIUM_C99(.random_data_source_fd =) -1,
99
+ static Salsa20RandomGlobal global = {
100
+ SODIUM_C99(.initialized =) 0,
101
+ SODIUM_C99(.random_data_source_fd =) -1
102
+ };
103
+
104
+ static TLS Salsa20Random stream = {
79
105
  SODIUM_C99(.initialized =) 0,
80
- SODIUM_C99(.getrandom_available =) 0
106
+ SODIUM_C99(.rnd32_outleft =) (size_t) 0U
81
107
  };
82
108
 
109
+
110
+ /*
111
+ * Get a high-resolution timestamp, as a uint64_t value
112
+ */
113
+
114
+ #ifdef _WIN32
83
115
  static uint64_t
84
116
  sodium_hrtime(void)
85
117
  {
86
- uint64_t ts;
87
-
88
- #ifdef _WIN32
89
- {
90
- struct _timeb tb;
118
+ struct _timeb tb;
91
119
  # pragma warning(push)
92
120
  # pragma warning(disable: 4996)
93
- _ftime(&tb);
121
+ _ftime(&tb);
94
122
  # pragma warning(pop)
95
- ts = ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U;
96
- }
97
- #else
98
- {
99
- struct timeval tv;
123
+ return ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U;
124
+ }
100
125
 
101
- if (gettimeofday(&tv, NULL) != 0) {
102
- sodium_misuse(); /* LCOV_EXCL_LINE */
103
- }
104
- ts = ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec;
126
+ #else /* _WIN32 */
127
+
128
+ static uint64_t
129
+ sodium_hrtime(void)
130
+ {
131
+ struct timeval tv;
132
+
133
+ if (gettimeofday(&tv, NULL) != 0) {
134
+ sodium_misuse(); /* LCOV_EXCL_LINE */
105
135
  }
136
+ return ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec;
137
+ }
106
138
  #endif
107
- return ts;
139
+
140
+ /*
141
+ * Initialize the entropy source
142
+ */
143
+
144
+ #ifdef _WIN32
145
+
146
+ static void
147
+ randombytes_salsa20_random_init(void)
148
+ {
149
+ stream.nonce = sodium_hrtime();
150
+ assert(stream.nonce != (uint64_t) 0U);
151
+ global.rdrand_available = sodium_runtime_has_rdrand();
108
152
  }
109
153
 
110
- #ifndef _WIN32
154
+ #else /* _WIN32 */
155
+
111
156
  static ssize_t
112
157
  safe_read(const int fd, void * const buf_, size_t size)
113
158
  {
@@ -131,9 +176,7 @@ safe_read(const int fd, void * const buf_, size_t size)
131
176
 
132
177
  return (ssize_t) (buf - (unsigned char *) buf_);
133
178
  }
134
- #endif
135
179
 
136
- #ifndef _WIN32
137
180
  # if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
138
181
  static int
139
182
  randombytes_block_on_dev_random(void)
@@ -184,15 +227,7 @@ randombytes_salsa20_random_random_dev_open(void)
184
227
  do {
185
228
  fd = open(*device, O_RDONLY);
186
229
  if (fd != -1) {
187
- if (fstat(fd, &st) == 0 &&
188
- # ifdef __COMPCERT__
189
- 1
190
- # elif defined(S_ISNAM)
191
- (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))
192
- # else
193
- S_ISCHR(st.st_mode)
194
- # endif
195
- ) {
230
+ if (fstat(fd, &st) == 0 && (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))) {
196
231
  # if defined(F_SETFD) && defined(FD_CLOEXEC)
197
232
  (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
198
233
  # endif
@@ -257,6 +292,7 @@ randombytes_salsa20_random_init(void)
257
292
  const int errno_save = errno;
258
293
 
259
294
  stream.nonce = sodium_hrtime();
295
+ global.rdrand_available = sodium_runtime_has_rdrand();
260
296
  assert(stream.nonce != (uint64_t) 0U);
261
297
 
262
298
  # ifdef HAVE_SAFE_ARC4RANDOM
@@ -268,15 +304,15 @@ randombytes_salsa20_random_init(void)
268
304
  unsigned char fodder[16];
269
305
 
270
306
  if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) {
271
- stream.getrandom_available = 1;
307
+ global.getrandom_available = 1;
272
308
  errno = errno_save;
273
309
  return;
274
310
  }
275
- stream.getrandom_available = 0;
311
+ global.getrandom_available = 0;
276
312
  }
277
313
  # endif /* SYS_getrandom */
278
314
 
279
- if ((stream.random_data_source_fd =
315
+ if ((global.random_data_source_fd =
280
316
  randombytes_salsa20_random_random_dev_open()) == -1) {
281
317
  sodium_misuse(); /* LCOV_EXCL_LINE */
282
318
  }
@@ -284,64 +320,45 @@ randombytes_salsa20_random_init(void)
284
320
  # endif /* HAVE_SAFE_ARC4RANDOM */
285
321
  }
286
322
 
287
- #else /* _WIN32 */
323
+ #endif /* _WIN32 */
288
324
 
289
- static void
290
- randombytes_salsa20_random_init(void)
291
- {
292
- stream.nonce = sodium_hrtime();
293
- assert(stream.nonce != (uint64_t) 0U);
294
- }
295
- #endif
296
-
297
- static void
298
- randombytes_salsa20_random_rekey(const unsigned char * const mix)
299
- {
300
- unsigned char *key = stream.key;
301
- size_t i;
302
-
303
- for (i = (size_t) 0U; i < sizeof stream.key; i++) {
304
- key[i] ^= mix[i];
305
- }
306
- }
325
+ /*
326
+ * (Re)seed the generator using the entropy source
327
+ */
307
328
 
308
329
  static void
309
330
  randombytes_salsa20_random_stir(void)
310
331
  {
311
- /* constant to personalize the hash function */
312
- const unsigned char hsigma[crypto_generichash_KEYBYTES] = {
313
- 0x54, 0x68, 0x69, 0x73, 0x49, 0x73, 0x4a, 0x75,
314
- 0x73, 0x74, 0x41, 0x54, 0x68, 0x69, 0x72, 0x74,
315
- 0x79, 0x54, 0x77, 0x6f, 0x42, 0x79, 0x74, 0x65,
316
- 0x73, 0x53, 0x65, 0x65, 0x64, 0x2e, 0x2e, 0x2e
317
- };
318
- unsigned char m0[crypto_stream_salsa20_KEYBYTES + HASH_BLOCK_SIZE];
319
- unsigned char *k0 = m0 + crypto_stream_salsa20_KEYBYTES;
320
- size_t sizeof_k0 = sizeof m0 - crypto_stream_salsa20_KEYBYTES;
332
+ unsigned char m0[crypto_stream_salsa20_KEYBYTES +
333
+ crypto_stream_salsa20_NONCEBYTES];
321
334
 
322
335
  memset(stream.rnd32, 0, sizeof stream.rnd32);
323
336
  stream.rnd32_outleft = (size_t) 0U;
324
- if (stream.initialized == 0) {
337
+ if (global.initialized == 0) {
325
338
  randombytes_salsa20_random_init();
326
- stream.initialized = 1;
339
+ global.initialized = 1;
327
340
  }
341
+ #ifdef HAVE_GETPID
342
+ global.pid = getpid();
343
+ #endif
344
+
328
345
  #ifndef _WIN32
329
346
 
330
347
  # ifdef HAVE_SAFE_ARC4RANDOM
331
348
  arc4random_buf(m0, sizeof m0);
332
349
  # elif defined(SYS_getrandom) && defined(__NR_getrandom)
333
- if (stream.getrandom_available != 0) {
350
+ if (global.getrandom_available != 0) {
334
351
  if (randombytes_linux_getrandom(m0, sizeof m0) != 0) {
335
352
  sodium_misuse(); /* LCOV_EXCL_LINE */
336
353
  }
337
- } else if (stream.random_data_source_fd == -1 ||
338
- safe_read(stream.random_data_source_fd, m0,
354
+ } else if (global.random_data_source_fd == -1 ||
355
+ safe_read(global.random_data_source_fd, m0,
339
356
  sizeof m0) != (ssize_t) sizeof m0) {
340
357
  sodium_misuse(); /* LCOV_EXCL_LINE */
341
358
  }
342
359
  # else
343
- if (stream.random_data_source_fd == -1 ||
344
- safe_read(stream.random_data_source_fd, m0,
360
+ if (global.random_data_source_fd == -1 ||
361
+ safe_read(global.random_data_source_fd, m0,
345
362
  sizeof m0) != (ssize_t) sizeof m0) {
346
363
  sodium_misuse(); /* LCOV_EXCL_LINE */
347
364
  }
@@ -352,25 +369,24 @@ randombytes_salsa20_random_stir(void)
352
369
  sodium_misuse(); /* LCOV_EXCL_LINE */
353
370
  }
354
371
  #endif
355
- if (crypto_generichash(stream.key, sizeof stream.key, k0, sizeof_k0,
356
- hsigma, sizeof hsigma) != 0) {
357
- abort(); /* really abort -- it should never happen */ /* LCOV_EXCL_LINE */
358
- }
359
- COMPILER_ASSERT(sizeof stream.key <= sizeof m0);
360
- randombytes_salsa20_random_rekey(m0);
372
+
373
+ crypto_stream_salsa20(stream.key, sizeof stream.key,
374
+ m0 + crypto_stream_salsa20_KEYBYTES, m0);
361
375
  sodium_memzero(m0, sizeof m0);
362
- #ifdef HAVE_GETPID
363
- stream.pid = getpid();
364
- #endif
376
+ stream.initialized = 1;
365
377
  }
366
378
 
379
+ /*
380
+ * Reseed the generator if it hasn't been initialized yet
381
+ */
382
+
367
383
  static void
368
384
  randombytes_salsa20_random_stir_if_needed(void)
369
385
  {
370
386
  #ifdef HAVE_GETPID
371
387
  if (stream.initialized == 0) {
372
388
  randombytes_salsa20_random_stir();
373
- } else if (stream.pid != getpid()) {
389
+ } else if (global.pid != getpid()) {
374
390
  sodium_misuse(); /* LCOV_EXCL_LINE */
375
391
  }
376
392
  #else
@@ -380,18 +396,36 @@ randombytes_salsa20_random_stir_if_needed(void)
380
396
  #endif
381
397
  }
382
398
 
399
+ /*
400
+ * Close the stream, free global resources
401
+ */
402
+
403
+ #ifdef _WIN32
383
404
  static int
384
405
  randombytes_salsa20_random_close(void)
385
406
  {
386
407
  int ret = -1;
387
408
 
388
- #ifndef _WIN32
389
- if (stream.random_data_source_fd != -1 &&
390
- close(stream.random_data_source_fd) == 0) {
391
- stream.random_data_source_fd = -1;
392
- stream.initialized = 0;
409
+ if (global.initialized != 0) {
410
+ global.initialized = 0;
411
+ ret = 0;
412
+ }
413
+ sodium_memzero(&stream, sizeof stream);
414
+
415
+ return ret;
416
+ }
417
+ #else
418
+ static int
419
+ randombytes_salsa20_random_close(void)
420
+ {
421
+ int ret = -1;
422
+
423
+ if (global.random_data_source_fd != -1 &&
424
+ close(global.random_data_source_fd) == 0) {
425
+ global.random_data_source_fd = -1;
426
+ global.initialized = 0;
393
427
  # ifdef HAVE_GETPID
394
- stream.pid = (pid_t) 0;
428
+ global.pid = (pid_t) 0;
395
429
  # endif
396
430
  ret = 0;
397
431
  }
@@ -401,20 +435,57 @@ randombytes_salsa20_random_close(void)
401
435
  # endif
402
436
 
403
437
  # if defined(SYS_getrandom) && defined(__NR_getrandom)
404
- if (stream.getrandom_available != 0) {
438
+ if (global.getrandom_available != 0) {
405
439
  ret = 0;
406
440
  }
407
441
  # endif
408
442
 
409
- #else /* _WIN32 */
410
- if (stream.initialized != 0) {
411
- stream.initialized = 0;
412
- ret = 0;
443
+ sodium_memzero(&stream, sizeof stream);
444
+
445
+ return ret;
446
+ }
447
+ #endif
448
+
449
+ /*
450
+ * RDRAND is only used to mitigate prediction if a key is compromised
451
+ */
452
+
453
+ static void
454
+ randombytes_salsa20_random_xorhwrand(void)
455
+ {
456
+ /* LCOV_EXCL_START */
457
+ #ifdef HAVE_RDRAND
458
+ unsigned int r;
459
+
460
+ if (global.rdrand_available == 0) {
461
+ return;
413
462
  }
463
+ (void) _rdrand32_step(&r);
464
+ * (uint32_t *) (void *)
465
+ &stream.key[crypto_stream_salsa20_KEYBYTES - 4] ^= (uint32_t) r;
414
466
  #endif
415
- return ret;
467
+ /* LCOV_EXCL_STOP */
468
+ }
469
+
470
+ /*
471
+ * XOR the key with another same-length secret
472
+ */
473
+
474
+ static inline void
475
+ randombytes_salsa20_random_xorkey(const unsigned char * const mix)
476
+ {
477
+ unsigned char *key = stream.key;
478
+ size_t i;
479
+
480
+ for (i = (size_t) 0U; i < sizeof stream.key; i++) {
481
+ key[i] ^= mix[i];
482
+ }
416
483
  }
417
484
 
485
+ /*
486
+ * Put `size` random bytes into `buf` and overwrite the key
487
+ */
488
+
418
489
  static void
419
490
  randombytes_salsa20_random_buf(void * const buf, const size_t size)
420
491
  {
@@ -435,11 +506,18 @@ randombytes_salsa20_random_buf(void * const buf, const size_t size)
435
506
  for (i = 0U; i < sizeof size; i++) {
436
507
  stream.key[i] ^= ((const unsigned char *) (const void *) &size)[i];
437
508
  }
509
+ randombytes_salsa20_random_xorhwrand();
438
510
  stream.nonce++;
439
511
  crypto_stream_salsa20_xor(stream.key, stream.key, sizeof stream.key,
440
512
  (unsigned char *) &stream.nonce, stream.key);
441
513
  }
442
514
 
515
+ /*
516
+ * Pop a 32-bit value from the random pool
517
+ *
518
+ * Overwrite the key after the pool gets refilled.
519
+ */
520
+
443
521
  static uint32_t
444
522
  randombytes_salsa20_random(void)
445
523
  {
@@ -458,7 +536,9 @@ randombytes_salsa20_random(void)
458
536
  stream.key);
459
537
  assert(ret == 0);
460
538
  stream.rnd32_outleft = (sizeof stream.rnd32) - (sizeof stream.key);
461
- randombytes_salsa20_random_rekey(&stream.rnd32[stream.rnd32_outleft]);
539
+ randombytes_salsa20_random_xorhwrand();
540
+ randombytes_salsa20_random_xorkey(&stream.rnd32[stream.rnd32_outleft]);
541
+ memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof stream.key);
462
542
  stream.nonce++;
463
543
  }
464
544
  stream.rnd32_outleft -= sizeof val;