diff options
Diffstat (limited to 'providers/implementations/rands/seeding/rand_unix.c')
-rw-r--r-- | providers/implementations/rands/seeding/rand_unix.c | 160 |
1 files changed, 40 insertions, 120 deletions
diff --git a/providers/implementations/rands/seeding/rand_unix.c b/providers/implementations/rands/seeding/rand_unix.c index 750afca58ed7..c3a5d8b3bf24 100644 --- a/providers/implementations/rands/seeding/rand_unix.c +++ b/providers/implementations/rands/seeding/rand_unix.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,35 +10,40 @@ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif -#include "../e_os.h" +#include "internal/e_os.h" #include <stdio.h> #include "internal/cryptlib.h" #include <openssl/rand.h> #include <openssl/crypto.h> #include "crypto/rand_pool.h" #include "crypto/rand.h" -#include <stdio.h> #include "internal/dso.h" +#include "internal/nelem.h" #include "prov/seeding.h" -#ifdef __linux -# include <sys/syscall.h> -# ifdef DEVRANDOM_WAIT -# include <sys/shm.h> -# include <sys/utsname.h> +#ifndef OPENSSL_SYS_UEFI +# ifdef __linux +# include <sys/syscall.h> +# ifdef DEVRANDOM_WAIT +# include <sys/shm.h> +# include <sys/utsname.h> +# endif +# endif +# if defined(__FreeBSD__) || defined(__NetBSD__) +# include <sys/types.h> +# include <sys/sysctl.h> +# include <sys/param.h> +# endif +# if defined(__FreeBSD__) && __FreeBSD_version >= 1200061 +# include <sys/random.h> +# endif +# if defined(__OpenBSD__) +# include <sys/param.h> +# endif +# if defined(__DragonFly__) +# include <sys/param.h> +# include <sys/random.h> # endif -#endif -#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(OPENSSL_SYS_UEFI) -# include <sys/types.h> -# include <sys/sysctl.h> -# include <sys/param.h> -#endif -#if defined(__OpenBSD__) -# include <sys/param.h> -#endif -#if defined(__DragonFly__) -# include <sys/param.h> -# include <sys/random.h> #endif #if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \ @@ -50,7 +55,6 @@ # include <sys/time.h> static uint64_t get_time_stamp(void); -static uint64_t get_timer_bits(void); /* Macro to convert two thirty two bit values into a sixty four bit one */ # define TWO32TO64(a, b) ((((uint64_t)(a)) << 32) + (b)) @@ -96,7 +100,6 @@ static uint64_t get_timer_bits(void); /* none means none. this simplifies the following logic */ # undef OPENSSL_RAND_SEED_OS # undef OPENSSL_RAND_SEED_GETRANDOM -# undef OPENSSL_RAND_SEED_LIBRANDOM # undef OPENSSL_RAND_SEED_DEVRANDOM # undef OPENSSL_RAND_SEED_RDTSC # undef OPENSSL_RAND_SEED_RDCPU @@ -176,7 +179,7 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) /* Get wall clock time, take 8 bits. */ clock_gettime(CLOCK_REALTIME, &ts); v = (unsigned char)(ts.tv_nsec & 0xFF); - ossl_rand_pool_add(pool, arg, &v, sizeof(v) , 2); + ossl_rand_pool_add(pool, arg, &v, sizeof(v), 2); } return ossl_rand_pool_entropy_available(pool); } @@ -208,10 +211,6 @@ void ossl_rand_pool_keep_random_devices_open(int keep) # define OPENSSL_RAND_SEED_DEVRANDOM # endif -# if defined(OPENSSL_RAND_SEED_LIBRANDOM) -# error "librandom not (yet) supported" -# endif - # if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND) /* * sysctl_random(): Use sysctl() to read a random number from the kernel @@ -320,9 +319,7 @@ static ssize_t sysctl_random(char *buf, size_t buflen) # define __NR_getrandom 352 # elif defined(__cris__) # define __NR_getrandom 356 -# elif defined(__aarch64__) -# define __NR_getrandom 278 -# else /* generic */ +# else /* generic (f.e. aarch64, loongarch, loongarch64) */ # define __NR_getrandom 278 # endif # endif @@ -351,12 +348,11 @@ static ssize_t syscall_random(void *buf, size_t buflen) * - Solaris since 11.3 * - OpenBSD since 5.6 * - Linux since 3.17 with glibc 2.25 - * - FreeBSD since 12.0 (1200061) * * Note: Sometimes getentropy() can be provided but not implemented * internally. So we need to check errno for ENOSYS */ -# if !defined(__DragonFly__) && !defined(__NetBSD__) +# if !defined(__DragonFly__) && !defined(__NetBSD__) && !defined(__FreeBSD__) # if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux) extern int getentropy(void *buffer, size_t length) __attribute__((weak)); @@ -388,16 +384,21 @@ static ssize_t syscall_random(void *buf, size_t buflen) if (p_getentropy.p != NULL) return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1; # endif -# endif /* !__DragonFly__ */ +# endif /* !__DragonFly__ && !__NetBSD__ && !__FreeBSD__ */ /* Linux supports this since version 3.17 */ # if defined(__linux) && defined(__NR_getrandom) return syscall(__NR_getrandom, buf, buflen, 0); -# elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND) - return sysctl_random(buf, buflen); # elif (defined(__DragonFly__) && __DragonFly_version >= 500700) \ - || (defined(__NetBSD__) && __NetBSD_Version >= 1000000000) + || (defined(__NetBSD__) && __NetBSD_Version >= 1000000000) \ + || (defined(__FreeBSD__) && __FreeBSD_version >= 1200061) return getrandom(buf, buflen, 0); +# elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND) + return sysctl_random(buf, buflen); +# elif defined(__wasi__) + if (getentropy(buf, buflen) == 0) + return (ssize_t)buflen; + return -1; # else errno = ENOSYS; return -1; @@ -509,7 +510,7 @@ static int wait_random_seeded(void) * So the handle might have been closed or even reused for opening * another file. */ -static int check_random_device(struct random_device * rd) +static int check_random_device(struct random_device *rd) { struct stat st; @@ -527,7 +528,7 @@ static int check_random_device(struct random_device * rd) static int get_random_device(size_t n) { struct stat st; - struct random_device * rd = &random_devices[n]; + struct random_device *rd = &random_devices[n]; /* reuse existing file descriptor if it is (still) valid */ if (check_random_device(rd)) @@ -556,7 +557,7 @@ static int get_random_device(size_t n) */ static void close_random_device(size_t n) { - struct random_device * rd = &random_devices[n]; + struct random_device *rd = &random_devices[n]; if (check_random_device(rd)) close(rd->fd); @@ -658,12 +659,6 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) return entropy_available; # endif -# if defined(OPENSSL_RAND_SEED_LIBRANDOM) - { - /* Not yet implemented. */ - } -# endif - # if defined(OPENSSL_RAND_SEED_DEVRANDOM) if (wait_random_seeded()) { size_t bytes_needed; @@ -774,31 +769,6 @@ int ossl_pool_add_nonce_data(RAND_POOL *pool) return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); } -int ossl_rand_pool_add_additional_data(RAND_POOL *pool) -{ - struct { - int fork_id; - CRYPTO_THREAD_ID tid; - uint64_t time; - } data; - - /* Erase the entire structure including any padding */ - memset(&data, 0, sizeof(data)); - - /* - * Add some noise from the thread id and a high resolution timer. - * The fork_id adds some extra fork-safety. - * The thread id adds a little randomness if the drbg is accessed - * concurrently (which is the case for the <master> drbg). - */ - data.fork_id = openssl_get_fork_id(); - data.tid = CRYPTO_THREAD_get_current_id(); - data.time = get_timer_bits(); - - return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); -} - - /* * Get the current time with the highest possible resolution * @@ -828,55 +798,5 @@ static uint64_t get_time_stamp(void) return time(NULL); } -/* - * Get an arbitrary timer value of the highest possible resolution - * - * The timer value is added as random noise to the additional data, - * which is not considered a trusted entropy sourec, so any result - * is acceptable. - */ -static uint64_t get_timer_bits(void) -{ - uint64_t res = OPENSSL_rdtsc(); - - if (res != 0) - return res; - -# if defined(__sun) || defined(__hpux) - return gethrtime(); -# elif defined(_AIX) - { - timebasestruct_t t; - - read_wall_time(&t, TIMEBASE_SZ); - return TWO32TO64(t.tb_high, t.tb_low); - } -# elif defined(OSSL_POSIX_TIMER_OKAY) - { - struct timespec ts; - -# ifdef CLOCK_BOOTTIME -# define CLOCK_TYPE CLOCK_BOOTTIME -# elif defined(_POSIX_MONOTONIC_CLOCK) -# define CLOCK_TYPE CLOCK_MONOTONIC -# else -# define CLOCK_TYPE CLOCK_REALTIME -# endif - - if (clock_gettime(CLOCK_TYPE, &ts) == 0) - return TWO32TO64(ts.tv_sec, ts.tv_nsec); - } -# endif -# if defined(__unix__) \ - || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) - { - struct timeval tv; - - if (gettimeofday(&tv, NULL) == 0) - return TWO32TO64(tv.tv_sec, tv.tv_usec); - } -# endif - return time(NULL); -} #endif /* (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) || defined(__DJGPP__) */ |