[PATCH ustream-ssl] ustream-mbedtls: Use getrandom() instead of /dev/urandom
Hauke Mehrtens
hauke at hauke-m.de
Sun Jan 29 08:08:38 PST 2023
On 1/29/23 15:13, Torsten Duwe wrote:
> On Sat, 28 Jan 2023 19:41:13 +0100
> Hauke Mehrtens <hauke at hauke-m.de> wrote:
>
>> Instead of keeping a file descriptor open just use the getrandom syscall
>> to get random data. This is supported by the musl, glibc and Linux for
>> some time now.
>>
>> This also improves the error handling in case this function returns not
>> as many bytes as expected.
>>
>> Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
>> ---
>> ustream-mbedtls.c | 23 +++++------------------
>> 1 file changed, 5 insertions(+), 18 deletions(-)
>>
>> diff --git a/ustream-mbedtls.c b/ustream-mbedtls.c
>> index e79e37b..51ba2fa 100644
>> --- a/ustream-mbedtls.c
>> +++ b/ustream-mbedtls.c
>> @@ -17,6 +17,7 @@
>> */
>>
>> #include <sys/types.h>
>> +#include <sys/random.h>
>> #include <fcntl.h>
>> #include <unistd.h>
>> #include <stdlib.h>
>> @@ -25,8 +26,6 @@
>> #include "ustream-ssl.h"
>> #include "ustream-internal.h"
>>
>> -static int urandom_fd = -1;
>> -
>> static int s_ustream_read(void *ctx, unsigned char *buf, size_t len)
>> {
>> struct ustream *s = ctx;
>> @@ -66,21 +65,12 @@ __hidden void ustream_set_io(struct ustream_ssl_ctx *ctx, void *ssl, struct ustr
>> mbedtls_ssl_set_bio(ssl, conn, s_ustream_write, s_ustream_read, NULL);
>> }
>>
>> -static bool urandom_init(void)
>> -{
>> - if (urandom_fd > -1)
>> - return true;
>> -
>> - urandom_fd = open("/dev/urandom", O_RDONLY);
>> - if (urandom_fd < 0)
>> - return false;
>> -
>> - return true;
>> -}
>> -
>> static int _urandom(void *ctx, unsigned char *out, size_t len)
>> {
>> - if (read(urandom_fd, out, len) < 0)
>> + ssize_t ret;
>> +
>> + ret = getrandom(out, len, 0);
>> + if (ret < 0 || (size_t)ret != len)
>> return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
> [...]
>
> drivers/char/random.c lines 1240- ...
> * Reading from /dev/urandom has the same functionality as calling
> * getrandom(2) with flags=GRND_INSECURE. Because it does not block
> * waiting for the RNG to be ready, it should not be used.
>
> Haven't audited mbedtls, but I assume it reads urandom for "lesser"
> entropy when needed. In any case, getrandom(out, len, GRND_INSECURE)
> would be the proper replacement.
>
> Torsten
Hi Torsten,
The mapage says this:
> By default, getrandom() draws entropy from the urandom source
> (i.e., the same source as the /dev/urandom device). This
> behavior can be changed via the flags argument.
https://man7.org/linux/man-pages/man2/getrandom.2.html
GRND_INSECURE is also not documented in the man page.
The option was added to the Linux kernel 5.6 here:
https://git.kernel.org/linus/75551dbf112c992bc6c99a972990b3f272247e23
The documentation says
> GRND_INSECURE Return non-cryptographic random bytes
We want to use the random bytes in mbedtls for cryptographic operations.
I think giving no flags is the correct option here.
I think the behavior of /dev/random changed some years ago. This article
described it a bit: https://lwn.net/Articles/808575/
As far as I understood the code, giving no flags will guarantee that the
random pool is initialized (crng_ready() returns true) and otherwise it
is the same as using GRND_INSECURE. As we use it for cryptographic
operations I think we should give no flags.
Hauke
More information about the openwrt-devel
mailing list