[U-Boot] [PATCH 4/4] lib: uuid: Improve randomness of uuid values on RANDOM_UUID=y
Heinrich Schuchardt
xypron.glpk at gmx.de
Tue Apr 30 19:07:09 UTC 2019
On 4/30/19 4:53 AM, Eugeniu Rosca wrote:
> The random uuid values (enabled via CONFIG_RANDOM_UUID=y) on our
> platform are always the same. Below is consistent on each cold boot:
>
> => ### interrupt autoboot
> => env default -a; gpt write mmc 1 $partitions; print uuid_gpt_misc
> ...
> uuid_gpt_misc=d117f98e-6f2c-d04b-a5b2-331a19f91cb2
> => env default -a; gpt write mmc 1 $partitions; print uuid_gpt_misc
> ...
> uuid_gpt_misc=ad5ec4b6-2d9f-8544-9417-fe3bd1c9b1b3
> => env default -a; gpt write mmc 1 $partitions; print uuid_gpt_misc
> ...
> uuid_gpt_misc=cceb0b18-39cb-d547-9db7-03b405fa77d4
> => env default -a; gpt write mmc 1 $partitions; print uuid_gpt_misc
> ...
> uuid_gpt_misc=d4981a2b-0478-544e-9607-7fd3c651068d
> => env default -a; gpt write mmc 1 $partitions; print uuid_gpt_misc
> ...
> uuid_gpt_misc=6d6c9a36-e919-264d-a9ee-bd00379686c7
>
> While the uuids do change on every 'gpt write' command, the values
> appear to be taken from the same pool, in the same order.
>
> As a user, I expect a trully random uuid value in the above example.
> Otherwise, system/RFS designers and OS people might assume they have
> a reliable/consistent uuid passed by the bootloader, while the truth
> is U-Boot simply lacks entropy to generate a random string.
>
> In its first attempt [1] to improve the uuid randomness, this patch
> updated the seed based on the output of get_timer(), similar to [2].
>
> There are two problems with this approach:
> - get_timer() has a poor _ms_ resolution
> - when gen_rand_uuid() is called in a loop, get_timer() returns the
> same result, leading to the same seed being passed to srand(),
> leading to the same uuid being generated for several partitions
> with different names
>
> This second patch addresses both drawbacks.
>
> My R-Car3 testing [3] consists of running 'gpt write mmc 1 $partitions'
> in a loop for several minutes collecting 8844 randomly generated UUIDS.
> Two consecutive cold boots are concatenated in the log. As a result,
> all uuid values are unique (scripted check).
>
> Thanks to Roman, who reported the issue and provided support in fixing.
>
> [1] https://patchwork.ozlabs.org/patch/1091802/
> [2] commit da384a9d7628 ("net: rename and refactor eth_rand_ethaddr() function")
> [3] https://gist.github.com/erosca/2820be9d554f76b982edd48474d0e7ca
> => while true; do \
> env default -a; \
> gpt write mmc 1 $partitions; \
> print; done
>
> Reported-by: Roman Stratiienko <roman.stratiienko at globallogic.com>
> Signed-off-by: Eugeniu Rosca <erosca at de.adit-jv.com>
This patch may ameliorate the situation for GUIDs a bit. But I dislike:
- This patch is a uuid only solution to introduce time ticks as source
of entropy.
- With timer ticks you possibly introduce very little entropy.
- Our random number generator with only 32 state bits remains
sub-standard.
This is the current situation:
net/bootp.c uses the MAC address to seed the random number generator and
uses random numbers for defining waits.
lib/uuid.c is using it for UUID generation.
In the UEFI sub-system I would like to implement the EFI_RNG_PROTOCOL.
Linux uses it for randomizing memory layout. iPXE needs it for secure
network connections. This requires a good random number generator with
sufficient entropy.
We already have implemented a single hardware random number generator in
drivers/crypto/ace_sha.c (CONFIG_EXYNOS_ACE_SHA).
Many other CPUs come with a hardware random number generator. In Linux's
drivers/char/hw_random/ I found, e.g.
- meson-rng.c (Amlogic)
- mtk-rng.c (MediaTek)
- st-rng.c (STMicroelectronics)
- imx-rng.c (Freescale)
I think we should have a u-class for hardware RNGs as one source of entropy.
I would like a random number generator with a high number of state bits
(> 127) that we initialize with hardware RNG bits and other sources of
entropy. A nice discussion of how Linux does it can be found in [1].
Best regards
Heinrich
[1]
https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/Studies/LinuxRNG/LinuxRNG_EN.pdf
> ---
> v2:
> - Replaced get_timer(0) with get_ticks() and added rand() to seed value
> - Performed extensive testing on R-Car3 (ARMv8)
> v1:
> - https://patchwork.ozlabs.org/patch/1091802/
> ---
> lib/uuid.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/lib/uuid.c b/lib/uuid.c
> index fa20ee39fc32..2d4d6ef7e461 100644
> --- a/lib/uuid.c
> +++ b/lib/uuid.c
> @@ -238,6 +238,8 @@ void gen_rand_uuid(unsigned char *uuid_bin)
> unsigned int *ptr = (unsigned int *)&uuid;
> int i;
>
> + srand(get_ticks() + rand());
> +
> /* Set all fields randomly */
> for (i = 0; i < sizeof(struct uuid) / sizeof(*ptr); i++)
> *(ptr + i) = cpu_to_be32(rand());
>
More information about the U-Boot
mailing list