From 9f5312cc4ec704d4a58df52b00987109ac327af0 Mon Sep 17 00:00:00 2001 From: nia Date: Thu, 11 Jun 2020 13:32:13 +0100 Subject: [PATCH 1/5] entropy: Add support for BSD sysctl(KERN_ARND) This is basically the same as reading from /dev/urandom on supported systems, only it has a limit of 256 bytes per call, and does not require an open file descriptor (so it can be used in chroots, when resource limits are in place, or are otherwise exhausted). It's functionally equivalent to the comparable function getentropy(), but has been around for longer. It's actually used to implement getentropy in FreeBSD's libc. Discussions about adding getrandom or getentropy to NetBSD are still ongoing. It's present in all supported versions of FreeBSD and NetBSD. It's not present in DragonFly or OpenBSD. Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7 Comparable code in OpenSSL: https://github.com/openssl/openssl/blob/ddec332f329a432a45c0131d83f3bfb46114532b/crypto/rand/rand_unix.c#L208 Signed-off-by: nia --- library/entropy_poll.c | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/library/entropy_poll.c b/library/entropy_poll.c index 8b4a5af9e8..203034eb49 100644 --- a/library/entropy_poll.c +++ b/library/entropy_poll.c @@ -115,6 +115,41 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) #endif /* SYS_getrandom */ #endif /* __linux__ || __midipix__ */ +/* + * Some BSD systems provide KERN_ARND. + * This is equivalent to reading from /dev/urandom, only it doesn't require an + * open file descriptor, and provides up to 256 bytes per call (basically the + * same as getentropy(), but with a longer history). + * + * Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7 + */ +#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(HAVE_GETRANDOM) +#include +#include +#if defined(KERN_ARND) +#define HAVE_SYSCTL_ARND + +static int sysctl_wrapper ( void *buf, size_t buflen ) +{ + int name[2]; + size_t len; + + name[0] = CTL_KERN; + name[1] = KERN_ARND; + + while( buflen > 0 ) + { + len = buflen > 256 ? 256 : buflen; + if( sysctl(name, 2, buf, &len, NULL, 0) == -1 ) + return( -1 ); + buflen -= len; + buf += len; + } + return( 0 ); +} +#endif /* KERN_ARND */ +#endif /* __FreeBSD__ || __NetBSD__ */ + #include int mbedtls_platform_entropy_poll( void *data, @@ -139,6 +174,15 @@ int mbedtls_platform_entropy_poll( void *data, ((void) ret); #endif /* HAVE_GETRANDOM */ +#if defined(HAVE_SYSCTL_ARND) + ((void) file); + ((void) read_len); + if( sysctl_wrapper( output, len ) == -1 ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + *olen = len; + return( 0 ); +#else + *olen = 0; file = fopen( "/dev/urandom", "rb" ); @@ -156,6 +200,7 @@ int mbedtls_platform_entropy_poll( void *data, *olen = len; return( 0 ); +#endif /* HAVE_SYSCTL_ARND */ } #endif /* _WIN32 && !EFIX64 && !EFI32 */ #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ From 6777dcb16f99ea0b7944eef3137683dd41e00854 Mon Sep 17 00:00:00 2001 From: nia Date: Thu, 11 Jun 2020 14:01:07 +0100 Subject: [PATCH 2/5] Add ChangeLog.d entry for kern.arandom support. Signed-off-by: nia --- ChangeLog.d/sysctl-arnd-support.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 ChangeLog.d/sysctl-arnd-support.txt diff --git a/ChangeLog.d/sysctl-arnd-support.txt b/ChangeLog.d/sysctl-arnd-support.txt new file mode 100644 index 0000000000..14ad674123 --- /dev/null +++ b/ChangeLog.d/sysctl-arnd-support.txt @@ -0,0 +1,2 @@ +Features + * Added support to entropy_poll for the kern.arandom syscall supported on some BSD systems. Contributed by Nia Alarie in #3423. From f4d9f21b9b9b39715b708599af8d5fd2bdd1495b Mon Sep 17 00:00:00 2001 From: nia Date: Fri, 19 Jun 2020 16:14:27 +0100 Subject: [PATCH 3/5] entropy: Rename sysctl_wrapper to sysctl_arnd_wrapper Signed-off-by: nia --- library/entropy_poll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/entropy_poll.c b/library/entropy_poll.c index 203034eb49..69d06af48b 100644 --- a/library/entropy_poll.c +++ b/library/entropy_poll.c @@ -129,7 +129,7 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) #if defined(KERN_ARND) #define HAVE_SYSCTL_ARND -static int sysctl_wrapper ( void *buf, size_t buflen ) +static int sysctl_arnd_wrapper( void *buf, size_t buflen ) { int name[2]; size_t len; @@ -177,7 +177,7 @@ int mbedtls_platform_entropy_poll( void *data, #if defined(HAVE_SYSCTL_ARND) ((void) file); ((void) read_len); - if( sysctl_wrapper( output, len ) == -1 ) + if( sysctl_arnd_wrapper( output, len ) == -1 ) return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); *olen = len; return( 0 ); From e3fdcfa45cfec2f38fe27bacd5470a4bf8c77bc1 Mon Sep 17 00:00:00 2001 From: nia Date: Tue, 23 Jun 2020 21:03:01 +0100 Subject: [PATCH 4/5] entropy: Avoid arithmetic on void pointer Signed-off-by: nia --- library/entropy_poll.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/entropy_poll.c b/library/entropy_poll.c index 69d06af48b..aaff26f48e 100644 --- a/library/entropy_poll.c +++ b/library/entropy_poll.c @@ -131,6 +131,7 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) static int sysctl_arnd_wrapper( void *buf, size_t buflen ) { + unsigned char *output = buf; int name[2]; size_t len; @@ -140,10 +141,10 @@ static int sysctl_arnd_wrapper( void *buf, size_t buflen ) while( buflen > 0 ) { len = buflen > 256 ? 256 : buflen; - if( sysctl(name, 2, buf, &len, NULL, 0) == -1 ) + if( sysctl(name, 2, output, &len, NULL, 0) == -1 ) return( -1 ); buflen -= len; - buf += len; + output += len; } return( 0 ); } From 8373c86628bbde28ed7dadf32e7dec80e7045aa2 Mon Sep 17 00:00:00 2001 From: nia Date: Wed, 24 Jun 2020 17:15:02 +0100 Subject: [PATCH 5/5] entropy: Adjust parameter type of internal function to avoid a cast Signed-off-by: nia --- library/entropy_poll.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/library/entropy_poll.c b/library/entropy_poll.c index aaff26f48e..dc621836e5 100644 --- a/library/entropy_poll.c +++ b/library/entropy_poll.c @@ -129,9 +129,8 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) #if defined(KERN_ARND) #define HAVE_SYSCTL_ARND -static int sysctl_arnd_wrapper( void *buf, size_t buflen ) +static int sysctl_arnd_wrapper( unsigned char *buf, size_t buflen ) { - unsigned char *output = buf; int name[2]; size_t len; @@ -141,10 +140,10 @@ static int sysctl_arnd_wrapper( void *buf, size_t buflen ) while( buflen > 0 ) { len = buflen > 256 ? 256 : buflen; - if( sysctl(name, 2, output, &len, NULL, 0) == -1 ) + if( sysctl(name, 2, buf, &len, NULL, 0) == -1 ) return( -1 ); buflen -= len; - output += len; + buf += len; } return( 0 ); }