diff options
-rw-r--r-- | random/Makefile.am | 16 | ||||
-rw-r--r-- | random/jitterentropy-base-user.h | 167 | ||||
-rw-r--r-- | random/jitterentropy-noise.c | 6 | ||||
-rw-r--r-- | random/jitterentropy.h | 2 | ||||
-rw-r--r-- | random/rndjent.c | 12 |
5 files changed, 198 insertions, 5 deletions
diff --git a/random/Makefile.am b/random/Makefile.am index 7e6e6f03..33bd2d6e 100644 --- a/random/Makefile.am +++ b/random/Makefile.am @@ -50,9 +50,13 @@ rndegd.c \ rndunix.c \ rndw32.c \ rndw32ce.c \ +jitterentropy-gcd.c jitterentropy-gcd.h \ +jitterentropy-health.c jitterentropy-health.h \ +jitterentropy-noise.c jitterentropy-noise.h \ +jitterentropy-sha3.c jitterentropy-sha3.h \ +jitterentropy-timer.c jitterentropy-timer.h \ jitterentropy-base.c jitterentropy.h jitterentropy-base-user.h - # The rndjent module needs to be compiled without optimization. */ if ENABLE_O_FLAG_MUNGING o_flag_munging = sed -e 's/-O\([1-9sg][1-9sg]*\)/-O0/g' -e 's/-Ofast/-O0/g' @@ -61,9 +65,19 @@ o_flag_munging = cat endif rndjent.o: $(srcdir)/rndjent.c jitterentropy-base-user.h \ + $(srcdir)/jitterentropy-gcd.c $(srcdir)/jitterentropy-gcd.h \ + $(srcdir)/jitterentropy-health.c $(srcdir)/jitterentropy-health.h \ + $(srcdir)/jitterentropy-noise.c $(srcdir)/jitterentropy-noise.h \ + $(srcdir)/jitterentropy-sha3.c $(srcdir)/jitterentropy-sha3.h \ + $(srcdir)/jitterentropy-timer.c $(srcdir)/jitterentropy-timer.h \ $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h `echo $(COMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) ` rndjent.lo: $(srcdir)/rndjent.c jitterentropy-base-user.h \ + $(srcdir)/jitterentropy-gcd.c $(srcdir)/jitterentropy-gcd.h \ + $(srcdir)/jitterentropy-health.c $(srcdir)/jitterentropy-health.h \ + $(srcdir)/jitterentropy-noise.c $(srcdir)/jitterentropy-noise.h \ + $(srcdir)/jitterentropy-sha3.c $(srcdir)/jitterentropy-sha3.h \ + $(srcdir)/jitterentropy-timer.c $(srcdir)/jitterentropy-timer.h \ $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h `echo $(LTCOMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) ` diff --git a/random/jitterentropy-base-user.h b/random/jitterentropy-base-user.h index 8a8dbd55..f0fd4842 100644 --- a/random/jitterentropy-base-user.h +++ b/random/jitterentropy-base-user.h @@ -131,4 +131,171 @@ jent_fips_enabled(void) } +static inline void jent_memset_secure(void *s, size_t n) +{ + memset(s, 0, n); + __asm__ __volatile__("" : : "r" (s) : "memory"); +} + +static inline long jent_ncpu(void) +{ +#ifdef _POSIX_SOURCE + long ncpu = sysconf(_SC_NPROCESSORS_ONLN); + + if (ncpu == -1) + return -errno; + + if (ncpu == 0) + return -EFAULT; + + return ncpu; +#else + return 1; +#endif +} + +#ifdef __linux__ + +# if defined(_SC_LEVEL1_DCACHE_SIZE) && \ + defined(_SC_LEVEL2_CACHE_SIZE) && \ + defined(_SC_LEVEL3_CACHE_SIZE) + +static inline void jent_get_cachesize(long *l1, long *l2, long *l3) +{ + *l1 = sysconf(_SC_LEVEL1_DCACHE_SIZE); + *l2 = sysconf(_SC_LEVEL2_CACHE_SIZE); + *l3 = sysconf(_SC_LEVEL3_CACHE_SIZE); +} + +# else + +static inline void jent_get_cachesize(long *l1, long *l2, long *l3) +{ +#define JENT_SYSFS_CACHE_DIR "/sys/devices/system/cpu/cpu0/cache" + long val; + unsigned int i; + char buf[10], file[50]; + int fd = 0; + + /* Iterate over all caches */ + for (i = 0; i < 4; i++) { + unsigned int shift = 0; + char *ext; + + /* + * Check the cache type - we are only interested in Unified + * and Data caches. + */ + memset(buf, 0, sizeof(buf)); + snprintf(file, sizeof(file), "%s/index%u/type", + JENT_SYSFS_CACHE_DIR, i); + fd = open(file, O_RDONLY); + if (fd < 0) + continue; + while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR); + close(fd); + buf[sizeof(buf) - 1] = '\0'; + + if (strncmp(buf, "Data", 4) && strncmp(buf, "Unified", 7)) + continue; + + /* Get size of cache */ + memset(buf, 0, sizeof(buf)); + snprintf(file, sizeof(file), "%s/index%u/size", + JENT_SYSFS_CACHE_DIR, i); + + fd = open(file, O_RDONLY); + if (fd < 0) + continue; + while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR); + close(fd); + buf[sizeof(buf) - 1] = '\0'; + + ext = strstr(buf, "K"); + if (ext) { + shift = 10; + ext = '\0'; + } else { + ext = strstr(buf, "M"); + if (ext) { + shift = 20; + ext = '\0'; + } + } + + val = strtol(buf, NULL, 10); + if (val == LONG_MAX) + continue; + val <<= shift; + + if (!*l1) + *l1 = val; + else if (!*l2) + *l2 = val; + else { + *l3 = val; + break; + } + } +#undef JENT_SYSFS_CACHE_DIR +} + +# endif + +static inline uint32_t jent_cache_size_roundup(void) +{ + static int checked = 0; + static uint32_t cache_size = 0; + + if (!checked) { + long l1 = 0, l2 = 0, l3 = 0; + + jent_get_cachesize(&l1, &l2, &l3); + checked = 1; + + /* Cache size reported by system */ + if (l1 > 0) + cache_size += (uint32_t)l1; + if (l2 > 0) + cache_size += (uint32_t)l2; + if (l3 > 0) + cache_size += (uint32_t)l3; + + /* + * Force the output_size to be of the form + * (bounding_power_of_2 - 1). + */ + cache_size |= (cache_size >> 1); + cache_size |= (cache_size >> 2); + cache_size |= (cache_size >> 4); + cache_size |= (cache_size >> 8); + cache_size |= (cache_size >> 16); + + if (cache_size == 0) + return 0; + + /* + * Make the output_size the smallest power of 2 strictly + * greater than cache_size. + */ + cache_size++; + } + + return cache_size; +} + +#else /* __linux__ */ + +static inline uint32_t jent_cache_size_roundup(void) +{ + return 0; +} + +#endif /* __linux__ */ + +static inline void jent_yield(void) +{ + sched_yield(); +} + #endif /* GCRYPT_JITTERENTROPY_BASE_USER_H */ diff --git a/random/jitterentropy-noise.c b/random/jitterentropy-noise.c index 0802650f..75443a8f 100644 --- a/random/jitterentropy-noise.c +++ b/random/jitterentropy-noise.c @@ -106,12 +106,13 @@ static void jent_hash_time(struct rand_data *ec, uint64_t time, HASH_CTX_ON_STACK(ctx); uint8_t itermediary[SHA3_256_SIZE_DIGEST]; uint64_t j = 0; + uint64_t hash_loop_cnt; #define MAX_HASH_LOOP 3 #define MIN_HASH_LOOP 0 /* Ensure that macros cannot overflow jent_loop_shuffle() */ BUILD_BUG_ON((MAX_HASH_LOOP + MIN_HASH_LOOP) > 63); - uint64_t hash_loop_cnt = + hash_loop_cnt = jent_loop_shuffle(ec, MAX_HASH_LOOP, MIN_HASH_LOOP); sha3_256_init(&ctx); @@ -189,10 +190,11 @@ static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) uint8_t b[sizeof(uint32_t) * 4]; } prngState = { .u = {0x8e93eec0, 0xce65608a, 0xa8d46b46, 0xe83cef69} }; uint32_t addressMask = ec->memmask; + uint64_t acc_loop_cnt; /* Ensure that macros cannot overflow jent_loop_shuffle() */ BUILD_BUG_ON((MAX_ACC_LOOP_BIT + MIN_ACC_LOOP_BIT) > 63); - uint64_t acc_loop_cnt = + acc_loop_cnt = jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT); if (NULL == ec || NULL == ec->mem) diff --git a/random/jitterentropy.h b/random/jitterentropy.h index 4322c65d..02c60b78 100644 --- a/random/jitterentropy.h +++ b/random/jitterentropy.h @@ -59,7 +59,7 @@ * must offer POSIX threads. If this option is disabled, no linking * with the POSIX threads library is needed. */ -#define JENT_CONF_ENABLE_INTERNAL_TIMER +#undef JENT_CONF_ENABLE_INTERNAL_TIMER /* * Disable the loop shuffle operation diff --git a/random/rndjent.c b/random/rndjent.c index 56648a87..0fab3deb 100644 --- a/random/rndjent.c +++ b/random/rndjent.c @@ -43,6 +43,9 @@ #ifdef HAVE_STDINT_H # include <stdint.h> #endif +#include <unistd.h> +#include <errno.h> +#include <sched.h> #include "types.h" #include "g10lib.h" @@ -84,7 +87,14 @@ #define JENT_PRIVATE_COMPILE 1 #include "jitterentropy-base.c" - +#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER +#include <pthread.h> +#endif /* JENT_CONF_ENABLE_INTERNAL_TIMER */ +#include "jitterentropy-gcd.c" +#include "jitterentropy-health.c" +#include "jitterentropy-noise.c" +#include "jitterentropy-sha3.c" +#include "jitterentropy-timer.c" /* This is the lock we use to serialize access to this RNG. The extra * integer variable is only used to check the locking state; that is, |