Re: [PATCH] random: add rng-seed= command line option

From: Mark Salyzyn
Date: Fri Feb 07 2020 - 12:58:34 EST


On 2/7/20 9:28 AM, Kees Cook wrote:
On Fri, Feb 07, 2020 at 07:07:59AM -0800, Mark Salyzyn wrote:
+#if defined(CONFIG_RANDOM_TRUST_BOOTLOADER)
+/* caller called add_device_randomness, but it is from a trusted source */
+void __init credit_trusted_entropy(unsigned int size)
+{
+ credit_entropy_bits(&input_pool, size * 8);
+}
+#endif
As Ted already mentioned, I was expecting the string contents to actually
get added somewhere. Is the idea that it's already been added via the
add_device_randomness(command_line) call, and you just want to explicitly
credit those bytes? If so, that deserves a comment, and I think it should
likely not use 8 bits per character, as that's not how many bits are
possible for an alphanumeric string character; I would expect 6 bits (~32
standard letter/number) -- this likely needs fixing in the fdt patch too.

Yup, responded to Ted as such.

Both can have near-raw 8-bit data as long as they stay away from certain characters.

For the command line space and nul characters. Since rng-seed is stripped out of any views no one needs to get hurt.

For OF some other parse characters need to be skipped. The rng-seed is also memset'd out of existence after being read so no one gets hurt.

I see no harm with multiplying by six in both cases as entropy credit should be realistic, but generators can be more ambitious ...

. . .
+}
+
static void __init setup_command_line(char *command_line)
{
size_t len, xlen = 0, ilen = 0;
+ static const char argsep_str[] __initconst = " -- ";
+ static const char alloc_fail_msg[] __initconst =
+ "%s: Failed to allocate %zu bytes\n";
There's some refactoring in this patch unrelated to the seed logic. Can
you split that out? (I think these changes are good.)

Ok, two patches that come to mind:

- move string constants solely referenced in __init function to __initconst

- boot_command_line is not guaranteed nul terminated, strlen must be replaced with strnlen.

if (extra_command_line)
xlen = strlen(extra_command_line);
Unrelated note: whoa this is based on linux-next which has a massive
change to the boot command line handling and appears to be doing some
bad things. I need to go find that thread...

I took top of linus tree, I did not use linux-next (!) Hopefully all is good.

. . .
@@ -875,6 +909,21 @@ asmlinkage __visible void __init start_kernel(void)
rand_initialize();
add_latent_entropy();
add_device_randomness(command_line, strlen(command_line));
+ if (IS_BUILTIN(CONFIG_RANDOM_TRUST_BOOTLOADER)) {
+ size_t l = strlen(command_line);
+ char *rng_seed = strnstr(command_line, rng_seed_str, l);
+
+ if (rng_seed) {
+ char *end;
+
+ rng_seed += strlen(rng_seed_str);
+ l -= rng_seed - command_line;
+ end = strnchr(rng_seed, l, ' ');
+ if (end)
+ l = end - rng_seed;
+ credit_trusted_entropy(l);
+ }
+ }
Can you pull this out of line and write a new static help that does all
of the rng stuff here? Basically from rand_initialize() through
boot_init_stack_canary(), so it's all in one place and not "open coded"
in start_kernel(). (And then, actually, you don't need a separate
credit_trusted_entropy() function at all -- just call
credit_entropy_bits() directly there (and add a comment about the
command line already getting added).

sgtm, will do.

Thanks both -- Mark