[U-Boot] [PATCH v2 4/4] lib: uuid: Fix unseeded PRNG on RANDOM_UUID=y

Heinrich Schuchardt xypron.glpk at gmx.de
Thu May 2 16:19:13 UTC 2019


On 5/2/19 2:27 PM, 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.
>
> Assuming U-Boot with RANDOM_UUID=y is deployed on a large number of
> devices, all those devices would essentially expose the same UUID,
> breaking the assumption of system/RFS/application designers who rely
> on UUID as being globally unique (e.g. a database using UUID as key
> would alias/mix up entries/records due to duplicated UUID).
>
> The root cause seems to be simply _not_ seeding PRNG before generating
> a random value. It turns out this belongs to an established class of
> PRNG-specific problems, commonly known as "unseeded randomness", for
> which I am able to find below bugs/CVE/CWE:
>   - https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2015-0285
>     ("CVE-2015-0285 openssl: handshake with unseeded PRNG")
>   - https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2015-9019
>     ("CVE-2015-9019 libxslt: math.random() in xslt uses unseeded
>     randomness")
>   - https://cwe.mitre.org/data/definitions/336.html
>     ("CWE-336: Same Seed in Pseudo-Random Number Generator (PRNG)")
>
> The first revision [1] of this patch updated the seed based on the
> output of get_timer(), similar to [4].
>
> 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
>
> The above drawbacks have been addressed in the second version [2].
> In its third revision (current), the patch reworded the description
> and summary line to emphasize it is a *fix* rather than an improvement.
>
> Testing [3] consisted of running 'gpt write mmc 1 $partitions' in a
> loop on R-Car3 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] https://patchwork.ozlabs.org/patch/1092945/
> [3] https://gist.github.com/erosca/2820be9d554f76b982edd48474d0e7ca
> [4] commit da384a9d7628 ("net: rename and refactor eth_rand_ethaddr() function")
>
> Reported-by: Roman Stratiienko <roman.stratiienko at globallogic.com>
> Signed-off-by: Eugeniu Rosca <erosca at de.adit-jv.com>
Reviewed-by: Heinrich Schuchardt <xypron.glpk at gmx.de>

> --
> v3:
>   - Reworked the patch summary line and description to emphasize this is
>     a fix rather than an improvement by precisely pointing out the root
>     cause and mentioning related CVE/CWE.
> v2:
>   - https://patchwork.ozlabs.org/patch/1092945/
>   - Replaced get_timer(0) with get_ticks() and added rand() to seed value
>   - Performed extensive testing on R-Car3 (ARMv8). See:
>     https://gist.github.com/erosca/2820be9d554f76b982edd48474d0e7ca
> v1:
>   - https://patchwork.ozlabs.org/patch/1092944/
> ---
>   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