Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -863,11 +863,17 @@ AC_SUBST(ENCODINGS_A, "encodings.a") AC_SUBST(ENCODINGS_ENCODINGS_A, "encodings/encodings.a") ]) ]) -AC_CHECK_FUNCS(arc4random random, break) +AC_CHECK_FUNC(arc4random, [ + AC_DEFINE(OF_HAVE_ARC4RANDOM, 1, [Whether we have arc4random()]) +], [ + AC_CHECK_FUNC(random, [ + AC_DEFINE(OF_HAVE_RANDOM, 1, [Whether we have random()]) + ]) +]) AS_IF([test x"$host_os" != x"morphos"], [ AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") ]) AC_CHECK_HEADERS_ONCE(dlfcn.h) Index: src/OFMapTable.m ================================================================== --- src/OFMapTable.m +++ src/OFMapTable.m @@ -163,17 +163,11 @@ _buckets = [self allocZeroedMemoryWithSize: sizeof(*_buckets) count: _capacity]; if (of_hash_seed != 0) -#if defined(HAVE_ARC4RANDOM) - _rotate = arc4random() & 31; -#elif defined(HAVE_RANDOM) - _rotate = random() & 31; -#else - _rotate = rand() & 31; -#endif + _rotate = of_random() & 31; } @catch (id e) { [self release]; @throw e; } @@ -536,17 +530,11 @@ /* * Get a new random value for _rotate, so that it is not less secure * than creating a new hash map. */ if (of_hash_seed != 0) -#if defined(HAVE_ARC4RANDOM) - _rotate = arc4random() & 31; -#elif defined(HAVE_RANDOM) - _rotate = random() & 31; -#else - _rotate = rand() & 31; -#endif + _rotate = of_random() & 31; } - (bool)containsObject: (void *)object { if (object == NULL || _count == 0) Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -250,27 +250,13 @@ objc_setForwardHandler((IMP)&of_forward, (IMP)&of_forward_stret); #endif objc_setEnumerationMutationHandler(enumerationMutationHandler); - of_hash_seed = 0; - while (of_hash_seed == 0) { -#if defined(HAVE_ARC4RANDOM) - of_hash_seed = arc4random(); -#elif defined(HAVE_RANDOM) - struct timeval t; - gettimeofday(&t, NULL); - srandom((unsigned)(t.tv_sec ^ t.tv_usec)); - of_hash_seed = (uint32_t)((random() << 16) | - (random() & 0xFFFF)); -#else - struct timeval t; - gettimeofday(&t, NULL); - srand((unsigned)(t.tv_sec ^ t.tv_usec)); - of_hash_seed = (uint32_t)((rand() << 16) | (rand() & 0xFFFF)); -#endif - } + do { + of_hash_seed = of_random(); + } while (of_hash_seed == 0); } + (void)unload { } Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -846,5 +846,25 @@ static OF_INLINE char of_ascii_tolower(char c) { return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c); } + +/* This does *NOT* provide cryptographically secure randomness! */ +static OF_INLINE uint32_t +of_random(void) { +#if defined(OF_HAVE_ARC4RANDOM) + return arc4random(); +#elif defined(OF_HAVE_RANDOM) + struct timeval tv; + + gettimeofday(&tv, NULL); + srandom((unsigned)(tv.tv_sec ^ tv.tv_usec)); + return (((uint32_t)(random()) << 16) | ((uint32_t)(random()) & 0xFFFF); +#else + struct timeval tv; + + gettimeofday(&tv, NULL); + srand((unsigned)(t.tv_sec ^ t.tv_usec)); + return (((uint32_t)(rand()) << 16) | ((uint32_t)(rand()) & 0xFFFF); +#endif +} Index: src/objfw-defs.h.in ================================================================== --- src/objfw-defs.h.in +++ src/objfw-defs.h.in @@ -2,10 +2,11 @@ #undef LLONG_MAX #undef LLONG_MIN #undef OF_APPLE_RUNTIME #undef OF_BIG_ENDIAN #undef OF_FLOAT_BIG_ENDIAN +#undef OF_HAVE_ARC4RANDOM #undef OF_HAVE_ATOMIC_BUILTINS #undef OF_HAVE_ATOMIC_OPS #undef OF_HAVE_BUILTIN_BSWAP16 #undef OF_HAVE_BUILTIN_BSWAP32 #undef OF_HAVE_BUILTIN_BSWAP64 @@ -24,10 +25,11 @@ #undef OF_HAVE_PLEDGE #undef OF_HAVE_PLUGINS #undef OF_HAVE_PROCESSES #undef OF_HAVE_PTHREADS #undef OF_HAVE_PTHREAD_SPINLOCKS +#undef OF_HAVE_RANDOM #undef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES #undef OF_HAVE_SCHED_YIELD #undef OF_HAVE_SOCKETS #undef OF_HAVE_STDNORETURN #undef OF_HAVE_SYMLINK