aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/lib
diff options
context:
space:
mode:
authorDavid M. Syzdek <david@syzdek.net>2022-03-22 21:02:09 -0800
committerDavid M. Syzdek <david@syzdek.net>2022-03-22 22:02:33 -0800
commit482344848f0a5167b127131a7385b524590d9be3 (patch)
tree5d4e90757925e75510f11f5a9d76d7baa2cb6002 /lib
parent9fd0295c20cb9cbe5d1d7ee2a62cbae28ca250e2 (diff)
downloadtinyrad-482344848f0a5167b127131a7385b524590d9be3.tar.gz
tinyrad-482344848f0a5167b127131a7385b524590d9be3.tar.bz2
tinyrad-482344848f0a5167b127131a7385b524590d9be3.tar.xz
tinyrad-482344848f0a5167b127131a7385b524590d9be3.zip
libtinyrad: adding random functions
Diffstat (limited to 'lib')
-rw-r--r--lib/libtinyrad/lconf.c12
-rw-r--r--lib/libtinyrad/libtinyrad.h2
-rw-r--r--lib/libtinyrad/lmemory.c252
-rw-r--r--lib/libtinyrad/lmemory.h12
4 files changed, 252 insertions, 26 deletions
diff --git a/lib/libtinyrad/lconf.c b/lib/libtinyrad/lconf.c
index bf3327a..ca5f909 100644
--- a/lib/libtinyrad/lconf.c
+++ b/lib/libtinyrad/lconf.c
@@ -75,6 +75,7 @@
75#define TRAD_CONF_STOPINIT 8 75#define TRAD_CONF_STOPINIT 8
76#define TRAD_CONF_TIMEOUT 9 76#define TRAD_CONF_TIMEOUT 9
77#define TRAD_CONF_URI 10 77#define TRAD_CONF_URI 10
78#define TRAD_CONF_RANDOM 11
78 79
79 80
80///////////////// 81/////////////////
@@ -92,6 +93,7 @@ static const TinyRadMap tinyrad_conf_options[] =
92 { "DICTIONARY", TRAD_CONF_DICTIONARY }, 93 { "DICTIONARY", TRAD_CONF_DICTIONARY },
93 { "NETWORK_TIMEOUT", TRAD_CONF_NETWORK_TIMEOUT }, 94 { "NETWORK_TIMEOUT", TRAD_CONF_NETWORK_TIMEOUT },
94 { "PATHS", TRAD_CONF_PATHS }, 95 { "PATHS", TRAD_CONF_PATHS },
96 { "RANDOM", TRAD_CONF_RANDOM },
95 { "SECRET", TRAD_CONF_SECRET }, 97 { "SECRET", TRAD_CONF_SECRET },
96 { "SECRET_FILE", TRAD_CONF_SECRET_FILE }, 98 { "SECRET_FILE", TRAD_CONF_SECRET_FILE },
97 { "STOPINIT", TRAD_CONF_STOPINIT }, 99 { "STOPINIT", TRAD_CONF_STOPINIT },
@@ -389,6 +391,16 @@ tinyrad_conf_opt(
389 dict->paths = strs; 391 dict->paths = strs;
390 return(TRAD_SUCCESS); 392 return(TRAD_SUCCESS);
391 393
394 case TRAD_CONF_RANDOM:
395 TinyRadDebug(TRAD_DEBUG_ARGS, " == %s( tr, TRAD_CONF_RANDOM, \"%s\" )", __func__, (((value)) ? value : "(null)"));
396 if ( (!(tr)) || (!(value)) || ((tr->opts & TRAD_RANDOM_MASK)) )
397 return(TRAD_SUCCESS);
398 else if (!(strcasecmp(value, "rand"))) i = TRAD_RAND;
399 else if (!(strcasecmp(value, "random"))) i = TRAD_RANDOM;
400 else if (!(strcasecmp(value, "urandom"))) i = TRAD_URANDOM;
401 else return(TRAD_SUCCESS);
402 return(tinyrad_set_option(tr, TRAD_OPT_RANDOM, &i));
403
392 case TRAD_CONF_SECRET: 404 case TRAD_CONF_SECRET:
393 TinyRadDebug(TRAD_DEBUG_ARGS, " == %s( tr, TRAD_CONF_SECRET, \"%s\" )", __func__, (((value)) ? value : "(null)")); 405 TinyRadDebug(TRAD_DEBUG_ARGS, " == %s( tr, TRAD_CONF_SECRET, \"%s\" )", __func__, (((value)) ? value : "(null)"));
394 if ( (!(tr)) || ((tr->secret)) || (!(value)) ) 406 if ( (!(tr)) || ((tr->secret)) || (!(value)) )
diff --git a/lib/libtinyrad/libtinyrad.h b/lib/libtinyrad/libtinyrad.h
index 0389a8e..846f787 100644
--- a/lib/libtinyrad/libtinyrad.h
+++ b/lib/libtinyrad/libtinyrad.h
@@ -127,6 +127,8 @@ struct _tinyrad
127 unsigned opts_neg; 127 unsigned opts_neg;
128 int s; 128 int s;
129 int timeout; 129 int timeout;
130 int rand;
131 int padint;
130}; 132};
131 133
132 134
diff --git a/lib/libtinyrad/lmemory.c b/lib/libtinyrad/lmemory.c
index 35b615f..b74d375 100644
--- a/lib/libtinyrad/lmemory.c
+++ b/lib/libtinyrad/lmemory.c
@@ -76,6 +76,22 @@
76////////////////// 76//////////////////
77#pragma mark - Prototypes 77#pragma mark - Prototypes
78 78
79//-------------------//
80// random prototypes //
81//-------------------//
82#pragma mark random prototypes
83
84int
85tinyrad_srandom(
86 TinyRad * tr );
87
88
89int
90tinyrad_srandom_seed(
91 void * dst,
92 size_t n );
93
94
79//--------------------// 95//--------------------//
80// TinyRad prototypes // 96// TinyRad prototypes //
81//--------------------// 97//--------------------//
@@ -110,11 +126,182 @@ tinyrad_verify_is_obj(
110 126
111///////////////// 127/////////////////
112// // 128// //
129// Variables //
130// //
131/////////////////
132#pragma mark - Variables
133
134static atomic_flag tinyrad_rand_init = ATOMIC_FLAG_INIT;
135
136
137/////////////////
138// //
113// Functions // 139// Functions //
114// // 140// //
115///////////////// 141/////////////////
116#pragma mark - Functions 142#pragma mark - Functions
117 143
144//------------------//
145// random functions //
146//------------------//
147#pragma mark random functions
148
149int
150tinyrad_random_buf(
151 TinyRad * tr,
152 void * buf,
153 size_t nbytes )
154{
155 long rnd;
156 size_t off;
157 size_t size;
158 ssize_t rc;
159
160 TinyRadDebugTrace();
161
162 // read from random number file
163 if (tr->rand != -1)
164 if ((rc = read(tr->rand, buf, nbytes)) == (ssize_t)nbytes)
165 return(TRAD_SUCCESS);
166
167 // fall back to random()
168 for(off = 0; (off < nbytes); off += sizeof(rnd))
169 {
170 rnd = random();
171 size = ((off + sizeof(rnd)) < nbytes) ? sizeof(rnd) : (nbytes - off);
172 memcpy(&((uint8_t *)buf)[off], &rnd, size);
173 };
174
175 return(TRAD_SUCCESS);
176}
177
178
179int
180tinyrad_srandom(
181 TinyRad * tr )
182{
183 unsigned seed;
184 const char * file;
185
186 TinyRadDebugTrace();
187
188 assert(tr != NULL);
189
190 // set default random file option
191 if (!(tr->opts & TRAD_RANDOM_MASK))
192 tr->opts |= TRAD_URANDOM;
193
194 // closes existing random number file
195 if (tr->rand != -1)
196 close(tr->rand);
197 tr->rand = -1;
198
199 // initialize random number generator
200 if (!(atomic_flag_test_and_set(&tinyrad_rand_init)))
201 {
202 tinyrad_srandom_seed(&seed, sizeof(seed));
203 srandom(seed);
204 };
205
206 // determine name of random number file
207 switch(tr->opts & TRAD_RANDOM_MASK)
208 {
209 case TRAD_RAND: return(TRAD_SUCCESS);
210 case TRAD_RANDOM: file = "/dev/random"; break;
211 case TRAD_URANDOM: file = "/dev/urandom"; break;
212 default: return(TRAD_EUNKNOWN);
213 };
214
215 // open random number file
216 if ((tr->rand = open(file, O_RDONLY)) == -1)
217 return(TRAD_EUNKNOWN);
218
219 return(TRAD_SUCCESS);
220}
221
222
223int
224tinyrad_srandom_seed(
225 void * buf,
226 size_t nbytes )
227{
228 int fd;
229 ssize_t rc;
230 size_t off;
231 uint32_t rnd;
232 struct timespec ts;
233 size_t size;
234
235 TinyRadDebugTrace();
236
237 // attempt to use random file
238 if ((fd = open("/dev/unrandom", O_RDONLY)) == -1)
239 fd = open("/dev/nrandom", O_RDONLY);
240 if (fd != -1)
241 {
242 rc = read(fd, buf, nbytes);
243 close(fd);
244 if (rc == (ssize_t)nbytes)
245 return(TRAD_SUCCESS);
246 };
247
248 // fall back to using time
249 for(off = 0; (off < nbytes); off += sizeof(rnd))
250 {
251 // generate a, not random, possibly hard to predict number (there is a
252 // reason this is the fall back method and not the primary method for
253 // seeding the random number generator). Better recommendations are
254 // welcome.
255 rnd = 0;
256 // add realtime seconds and nanoseconds to rnd
257 memset(&ts, 0, sizeof(ts));
258 clock_gettime(CLOCK_REALTIME, &ts);
259 rnd += (ts.tv_sec % 0xffffffff);
260 rnd += (ts.tv_nsec % 0xffffffff);
261 // add monotonic time seconds and nanoseconds to rnd
262 memset(&ts, 0, sizeof(ts));
263 clock_gettime(CLOCK_MONOTONIC, &ts);
264 rnd += (ts.tv_sec % 0xffffffff);
265 rnd += (ts.tv_nsec % 0xffffffff);
266#ifdef _POSIX_CPUTIME
267 // add process CPU time seconds and nanoseconds to rnd
268 memset(&ts, 0, sizeof(ts));
269 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
270 rnd += (ts.tv_sec % 0xffffffff);
271 rnd += (ts.tv_nsec % 0xffffffff);
272#endif
273 // reverse bits
274 rnd = ((rnd & 0xffff0000) >> 16) | ((rnd & 0x0000ffff) << 16);
275 rnd = ((rnd & 0xff00ff00) >> 8) | ((rnd & 0x00ff00ff) << 8);
276 rnd = ((rnd & 0xf0f0f0f0) >> 4) | ((rnd & 0x0f0f0f0f) << 4);
277 rnd = ((rnd & 0xcccccccc) >> 2) | ((rnd & 0x33333333) << 2);
278 rnd = ((rnd & 0xaaaaaaaa) >> 1) | ((rnd & 0x55555555) << 1);
279 // add realtime seconds and nanoseconds to rnd
280 memset(&ts, 0, sizeof(ts));
281 clock_gettime(CLOCK_REALTIME, &ts);
282 rnd += (ts.tv_sec % 0xffffffff);
283 rnd += (ts.tv_nsec % 0xffffffff);
284 // add monotonic time seconds and nanoseconds to rnd
285 memset(&ts, 0, sizeof(ts));
286 clock_gettime(CLOCK_MONOTONIC, &ts);
287 rnd += (ts.tv_sec % 0xffffffff);
288 rnd += (ts.tv_nsec % 0xffffffff);
289#ifdef _POSIX_CPUTIME
290 // add process CPU time seconds and nanoseconds to rnd
291 memset(&ts, 0, sizeof(ts));
292 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
293 rnd += (ts.tv_sec % 0xffffffff);
294 rnd += (ts.tv_nsec % 0xffffffff);
295#endif
296
297 size = ((off + sizeof(rnd)) < nbytes) ? sizeof(rnd) : (nbytes - off);
298 memcpy(&((uint8_t *)buf)[off], &rnd, size);
299 };
300
301 return(TRAD_SUCCESS);
302}
303
304
118//-------------------// 305//-------------------//
119// TinyRad functions // 306// TinyRad functions //
120//-------------------// 307//-------------------//
@@ -205,6 +392,10 @@ tinyrad_tiyrad_free(
205 close(tr->s); 392 close(tr->s);
206 tr->s = -1; 393 tr->s = -1;
207 394
395 if (tr->rand != -1)
396 close(tr->rand);
397 tr->rand = -1;
398
208 memset(tr, 0, sizeof(TinyRad)); 399 memset(tr, 0, sizeof(TinyRad));
209 free(tr); 400 free(tr);
210 401
@@ -292,6 +483,17 @@ tinyrad_get_option(
292 ((struct timeval *)outvalue)->tv_usec = tr->net_timeout->tv_usec; 483 ((struct timeval *)outvalue)->tv_usec = tr->net_timeout->tv_usec;
293 break; 484 break;
294 485
486 case TRAD_OPT_RANDOM:
487 TinyRadDebug(TRAD_DEBUG_ARGS, " == %s( tr, TRAD_OPT_RANDOM, outvalue )", __func__);
488 switch(tr->opts & TRAD_RANDOM_MASK)
489 { case TRAD_RAND: TinyRadDebug(TRAD_DEBUG_ARGS, " <= outvalue: %s", "TRAD_RAND"); break;
490 case TRAD_RANDOM: TinyRadDebug(TRAD_DEBUG_ARGS, " <= outvalue: %s", "TRAD_RANDOM"); break;
491 case TRAD_URANDOM: TinyRadDebug(TRAD_DEBUG_ARGS, " <= outvalue: %s", "TRAD_URANDOM"); break;
492 default: TinyRadDebug(TRAD_DEBUG_ARGS, " <= outvalue: %i", (tr->opts & TRAD_RANDOM_MASK)); break;
493 };
494 *((int *)outvalue) = tr->opts & TRAD_RANDOM_MASK;
495 break;
496
295 case TRAD_OPT_SCHEME: 497 case TRAD_OPT_SCHEME:
296 TinyRadDebug(TRAD_DEBUG_ARGS, " == %s( tr, TRAD_OPT_SCHEME, outvalue )", __func__); 498 TinyRadDebug(TRAD_DEBUG_ARGS, " == %s( tr, TRAD_OPT_SCHEME, outvalue )", __func__);
297 TinyRadDebug(TRAD_DEBUG_ARGS, " <= outvalue: %i", tr->scheme); 499 TinyRadDebug(TRAD_DEBUG_ARGS, " <= outvalue: %i", tr->scheme);
@@ -355,9 +557,6 @@ tinyrad_initialize(
355{ 557{
356 TinyRad * tr; 558 TinyRad * tr;
357 int rc; 559 int rc;
358 int fd;
359 uint32_t u32;
360 struct timespec ts;
361 int opt; 560 int opt;
362 561
363 TinyRadDebugTrace(); 562 TinyRadDebugTrace();
@@ -371,6 +570,7 @@ tinyrad_initialize(
371 tr->opts = (uint32_t)(opts & TRAD_OPTS_USER); 570 tr->opts = (uint32_t)(opts & TRAD_OPTS_USER);
372 tr->s = -1; 571 tr->s = -1;
373 tr->timeout = -1; 572 tr->timeout = -1;
573 tr->rand = -1;
374 574
375 // parses and saves URL 575 // parses and saves URL
376 if ((url)) 576 if ((url))
@@ -418,32 +618,19 @@ tinyrad_initialize(
418 return(rc); 618 return(rc);
419 }; 619 };
420 620
621 // initialize random number generator
622 if ((rc = tinyrad_srandom(tr)) != TRAD_SUCCESS)
623 {
624 tinyrad_tiyrad_free(tr);
625 return(rc);
626 };
627
421 // generates initial authenticator 628 // generates initial authenticator
422 if ((fd = open("/dev/urandom", O_RDONLY)) != -1) 629 if ((rc = tinyrad_random_buf(tr, &tr->authenticator, sizeof(tr->authenticator))) != TRAD_SUCCESS)
423 { 630 {
424 read(fd, &u32, sizeof(u32)); 631 tinyrad_tiyrad_free(tr);
425 close(fd); 632 return(rc);
426 } else {
427 u32 = 0;
428 clock_gettime(CLOCK_REALTIME, &ts);
429 u32 += (ts.tv_sec % 0xffffffff);
430 u32 += (ts.tv_nsec % 0xffffffff);
431 clock_gettime(CLOCK_MONOTONIC, &ts);
432 u32 += (ts.tv_sec % 0xffffffff);
433 u32 += (ts.tv_nsec % 0xffffffff);
434 u32 = ((u32 & 0xffff0000) >> 16) | ((u32 & 0x0000ffff) << 16);
435 u32 = ((u32 & 0xff00ff00) >> 8) | ((u32 & 0x00ff00ff) << 8);
436 u32 = ((u32 & 0xf0f0f0f0) >> 4) | ((u32 & 0x0f0f0f0f) << 4);
437 u32 = ((u32 & 0xcccccccc) >> 2) | ((u32 & 0x33333333) << 2);
438 u32 = ((u32 & 0xaaaaaaaa) >> 1) | ((u32 & 0x55555555) << 1);
439 clock_gettime(CLOCK_REALTIME, &ts);
440 u32 += (ts.tv_sec % 0xffffffff);
441 u32 += (ts.tv_nsec % 0xffffffff);
442 clock_gettime(CLOCK_MONOTONIC, &ts);
443 u32 += (ts.tv_sec % 0xffffffff);
444 u32 += (ts.tv_nsec % 0xffffffff);
445 }; 633 };
446 tr->authenticator = u32;
447 634
448 *trp = tinyrad_obj_retain(&tr->obj); 635 *trp = tinyrad_obj_retain(&tr->obj);
449 636
@@ -547,6 +734,19 @@ tinyrad_set_option(
547 memcpy(tr->net_timeout, ((const struct timeval *)invalue), sizeof(struct timeval)); 734 memcpy(tr->net_timeout, ((const struct timeval *)invalue), sizeof(struct timeval));
548 break; 735 break;
549 736
737 case TRAD_OPT_RANDOM:
738 TinyRadDebug(TRAD_DEBUG_ARGS, " == %s( tr, TRAD_OPT_RANDOM, invalue )", __func__);
739 switch( *((const int *)invalue) & TRAD_RANDOM_MASK)
740 { case TRAD_RAND: TinyRadDebug(TRAD_DEBUG_ARGS, " <= invalue: %s", "TRAD_RAND"); break;
741 case TRAD_RANDOM: TinyRadDebug(TRAD_DEBUG_ARGS, " <= invalue: %s", "TRAD_RANDOM"); break;
742 case TRAD_URANDOM: TinyRadDebug(TRAD_DEBUG_ARGS, " <= invalue: %s", "TRAD_URANDOM"); break;
743 default: TinyRadDebug(TRAD_DEBUG_ARGS, " <= invalue: %i", *((const int *)invalue)); break;
744 };
745 tr->opts &= ~(TRAD_RANDOM_MASK);
746 tr->opts |= (TRAD_RANDOM_MASK & (*((const int *)invalue)));
747 tinyrad_srandom(tr);
748 break;
749
550 case TRAD_OPT_SCHEME: 750 case TRAD_OPT_SCHEME:
551 TinyRadDebug(TRAD_DEBUG_ARGS, " == %s( tr, TRAD_OPT_SCHEME, invalue )", __func__); 751 TinyRadDebug(TRAD_DEBUG_ARGS, " == %s( tr, TRAD_OPT_SCHEME, invalue )", __func__);
552 return(TRAD_EOPTERR); 752 return(TRAD_EOPTERR);
diff --git a/lib/libtinyrad/lmemory.h b/lib/libtinyrad/lmemory.h
index e8384fe..9979dba 100644
--- a/lib/libtinyrad/lmemory.h
+++ b/lib/libtinyrad/lmemory.h
@@ -62,6 +62,18 @@
62////////////////// 62//////////////////
63#pragma mark - Prototypes 63#pragma mark - Prototypes
64 64
65//------------------//
66// random functions //
67//------------------//
68#pragma mark random functions
69
70int
71tinyrad_random_buf(
72 TinyRad * tr,
73 void * buf,
74 size_t nbytes );
75
76
65//--------------------------------// 77//--------------------------------//
66// TinyRadBinValue list functions // 78// TinyRadBinValue list functions //
67//--------------------------------// 79//--------------------------------//