aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_random.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_random.c')
-rw-r--r--src/util/crypto_random.c199
1 files changed, 99 insertions, 100 deletions
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c
index 7fb2d1428..c74d60f4f 100644
--- a/src/util/crypto_random.c
+++ b/src/util/crypto_random.c
@@ -65,37 +65,37 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i)
65 GNUNET_assert (i > 0); 65 GNUNET_assert (i > 0);
66 66
67 switch (mode) 67 switch (mode)
68 { 68 {
69 case GNUNET_CRYPTO_QUALITY_STRONG: 69 case GNUNET_CRYPTO_QUALITY_STRONG:
70 /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */ 70 /* see http://lists.gnupg.org/pipermail/gcrypt-devel/2004-May/000613.html */
71#ifdef gcry_fast_random_poll 71#ifdef gcry_fast_random_poll
72 if ((invokeCount++ % 256) == 0) 72 if ((invokeCount++ % 256) == 0)
73 gcry_fast_random_poll (); 73 gcry_fast_random_poll ();
74#endif 74#endif
75 ul = UINT32_MAX - (UINT32_MAX % i); 75 ul = UINT32_MAX - (UINT32_MAX % i);
76 do 76 do
77 { 77 {
78 gcry_randomize ((unsigned char *) &ret, sizeof (uint32_t), 78 gcry_randomize ((unsigned char *) &ret, sizeof (uint32_t),
79 GCRY_STRONG_RANDOM); 79 GCRY_STRONG_RANDOM);
80 } 80 }
81 while (ret >= ul); 81 while (ret >= ul);
82 return ret % i; 82 return ret % i;
83 case GNUNET_CRYPTO_QUALITY_NONCE: 83 case GNUNET_CRYPTO_QUALITY_NONCE:
84 ul = UINT32_MAX - (UINT32_MAX % i); 84 ul = UINT32_MAX - (UINT32_MAX % i);
85 do 85 do
86 { 86 {
87 gcry_create_nonce (&ret, sizeof (ret)); 87 gcry_create_nonce (&ret, sizeof (ret));
88 }
89 while (ret >= ul);
90 return ret % i;
91 case GNUNET_CRYPTO_QUALITY_WEAK:
92 ret = i * weak_random ();
93 if (ret >= i)
94 ret = i - 1;
95 return ret;
96 default:
97 GNUNET_assert (0);
98 } 88 }
89 while (ret >= ul);
90 return ret % i;
91 case GNUNET_CRYPTO_QUALITY_WEAK:
92 ret = i * weak_random ();
93 if (ret >= i)
94 ret = i - 1;
95 return ret;
96 default:
97 GNUNET_assert (0);
98 }
99 return 0; 99 return 0;
100} 100}
101 101
@@ -121,12 +121,12 @@ GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n)
121 for (i = 0; i < n; i++) 121 for (i = 0; i < n; i++)
122 ret[i] = i; 122 ret[i] = i;
123 for (i = n - 1; i > 0; i--) 123 for (i = n - 1; i > 0; i--)
124 { 124 {
125 x = GNUNET_CRYPTO_random_u32 (mode, i + 1); 125 x = GNUNET_CRYPTO_random_u32 (mode, i + 1);
126 tmp = ret[x]; 126 tmp = ret[x];
127 ret[x] = ret[i]; 127 ret[x] = ret[i];
128 ret[i] = tmp; 128 ret[i] = tmp;
129 } 129 }
130 return ret; 130 return ret;
131} 131}
132 132
@@ -146,33 +146,33 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
146 146
147 GNUNET_assert (max > 0); 147 GNUNET_assert (max > 0);
148 switch (mode) 148 switch (mode)
149 {
150 case GNUNET_CRYPTO_QUALITY_STRONG:
151 ul = UINT64_MAX - (UINT64_MAX % max);
152 do
149 { 153 {
150 case GNUNET_CRYPTO_QUALITY_STRONG: 154 gcry_randomize ((unsigned char *) &ret, sizeof (uint64_t),
151 ul = UINT64_MAX - (UINT64_MAX % max); 155 GCRY_STRONG_RANDOM);
152 do
153 {
154 gcry_randomize ((unsigned char *) &ret, sizeof (uint64_t),
155 GCRY_STRONG_RANDOM);
156 }
157 while (ret >= ul);
158 return ret % max;
159 case GNUNET_CRYPTO_QUALITY_NONCE:
160 ul = UINT64_MAX - (UINT64_MAX % max);
161 do
162 {
163 gcry_create_nonce (&ret, sizeof (ret));
164 }
165 while (ret >= ul);
166
167 return ret % max;
168 case GNUNET_CRYPTO_QUALITY_WEAK:
169 ret = max * weak_random ();
170 if (ret >= max)
171 ret = max - 1;
172 return ret;
173 default:
174 GNUNET_assert (0);
175 } 156 }
157 while (ret >= ul);
158 return ret % max;
159 case GNUNET_CRYPTO_QUALITY_NONCE:
160 ul = UINT64_MAX - (UINT64_MAX % max);
161 do
162 {
163 gcry_create_nonce (&ret, sizeof (ret));
164 }
165 while (ret >= ul);
166
167 return ret % max;
168 case GNUNET_CRYPTO_QUALITY_WEAK:
169 ret = max * weak_random ();
170 if (ret >= max)
171 ret = max - 1;
172 return ret;
173 default:
174 GNUNET_assert (0);
175 }
176 return 0; 176 return 0;
177} 177}
178 178
@@ -200,7 +200,7 @@ static struct GNUNET_OS_Process *genproc;
200 */ 200 */
201static void 201static void
202entropy_generator (void *cls, const char *what, int printchar, int current, 202entropy_generator (void *cls, const char *what, int printchar, int current,
203 int total) 203 int total)
204{ 204{
205 unsigned long code; 205 unsigned long code;
206 enum GNUNET_OS_ProcessStatusType type; 206 enum GNUNET_OS_ProcessStatusType type;
@@ -209,39 +209,39 @@ entropy_generator (void *cls, const char *what, int printchar, int current,
209 if (0 != strcmp (what, "need_entropy")) 209 if (0 != strcmp (what, "need_entropy"))
210 return; 210 return;
211 if (current == total) 211 if (current == total)
212 {
213 if (genproc != NULL)
212 { 214 {
213 if (genproc != NULL)
214 {
215 if (0 != GNUNET_OS_process_kill (genproc, SIGTERM))
216 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill");
217 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
218 GNUNET_OS_process_close (genproc);
219 genproc = NULL;
220 }
221 return;
222 }
223 if (genproc != NULL)
224 {
225 ret = GNUNET_OS_process_status (genproc, &type, &code);
226 if (ret == GNUNET_NO)
227 return; /* still running */
228 if (ret == GNUNET_SYSERR)
229 {
230 GNUNET_break (0);
231 return;
232 }
233 if (0 != GNUNET_OS_process_kill (genproc, SIGTERM)) 215 if (0 != GNUNET_OS_process_kill (genproc, SIGTERM))
234 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill"); 216 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill");
235 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc)); 217 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
236 GNUNET_OS_process_close (genproc); 218 GNUNET_OS_process_close (genproc);
237 genproc = NULL; 219 genproc = NULL;
238 } 220 }
239 LOG (GNUNET_ERROR_TYPE_INFO, 221 return;
240 _("Starting `%s' process to generate entropy\n"), "find"); 222 }
223 if (genproc != NULL)
224 {
225 ret = GNUNET_OS_process_status (genproc, &type, &code);
226 if (ret == GNUNET_NO)
227 return; /* still running */
228 if (ret == GNUNET_SYSERR)
229 {
230 GNUNET_break (0);
231 return;
232 }
233 if (0 != GNUNET_OS_process_kill (genproc, SIGTERM))
234 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "kill");
235 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
236 GNUNET_OS_process_close (genproc);
237 genproc = NULL;
238 }
239 LOG (GNUNET_ERROR_TYPE_INFO, _("Starting `%s' process to generate entropy\n"),
240 "find");
241 genproc = 241 genproc =
242 GNUNET_OS_start_process (NULL, NULL, "sh", "sh", "-c", 242 GNUNET_OS_start_process (NULL, NULL, "sh", "sh", "-c",
243 "exec find / -mount -type f -exec cp {} /dev/null \\; 2>/dev/null", 243 "exec find / -mount -type f -exec cp {} /dev/null \\; 2>/dev/null",
244 NULL); 244 NULL);
245} 245}
246 246
247 247
@@ -249,11 +249,11 @@ static void
249killfind () 249killfind ()
250{ 250{
251 if (genproc != NULL) 251 if (genproc != NULL)
252 { 252 {
253 GNUNET_OS_process_kill (genproc, SIGKILL); 253 GNUNET_OS_process_kill (genproc, SIGKILL);
254 GNUNET_OS_process_close (genproc); 254 GNUNET_OS_process_close (genproc);
255 genproc = NULL; 255 genproc = NULL;
256 } 256 }
257} 257}
258 258
259 259
@@ -261,21 +261,20 @@ void __attribute__ ((constructor)) GNUNET_CRYPTO_random_init ()
261{ 261{
262 gcry_control (GCRYCTL_DISABLE_SECMEM, 0); 262 gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
263 if (!gcry_check_version (GCRYPT_VERSION)) 263 if (!gcry_check_version (GCRYPT_VERSION))
264 { 264 {
265 fprintf (stderr, 265 fprintf (stderr,
266 _ 266 _
267 ("libgcrypt has not the expected version (version %s is required).\n"), 267 ("libgcrypt has not the expected version (version %s is required).\n"),
268 GCRYPT_VERSION); 268 GCRYPT_VERSION);
269 abort (); 269 abort ();
270 } 270 }
271#ifdef gcry_fast_random_poll 271#ifdef gcry_fast_random_poll
272 gcry_fast_random_poll (); 272 gcry_fast_random_poll ();
273#endif 273#endif
274 gcry_set_progress_handler (&entropy_generator, NULL); 274 gcry_set_progress_handler (&entropy_generator, NULL);
275 atexit (&killfind); 275 atexit (&killfind);
276 SRANDOM (time (NULL) ^ 276 SRANDOM (time (NULL) ^
277 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 277 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
278 UINT32_MAX));
279} 278}
280 279
281 280