diff mbox series

[qemu] mips/malta: pass RNG seed to to kernel via env var

Message ID 20220930140520.576374-1-Jason@zx2c4.com
State New
Headers show
Series [qemu] mips/malta: pass RNG seed to to kernel via env var | expand

Commit Message

Jason A. Donenfeld Sept. 30, 2022, 2:05 p.m. UTC
With the kernel patch linked below, Linux ingests a RNG seed
passed from the hypervisor. So, pass this for the Malta platform, and
reinitialize it on reboot too, so that it's always fresh.

Link: https://lore.kernel.org/linux-mips/20220930140138.575751-1-Jason@zx2c4.com/
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 hw/mips/malta.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Comments

Daniel P. Berrangé Sept. 30, 2022, 3:05 p.m. UTC | #1
On Fri, Sep 30, 2022 at 04:05:20PM +0200, Jason A. Donenfeld wrote:
> With the kernel patch linked below, Linux ingests a RNG seed
> passed from the hypervisor. So, pass this for the Malta platform, and
> reinitialize it on reboot too, so that it's always fresh.
> 
> Link: https://lore.kernel.org/linux-mips/20220930140138.575751-1-Jason@zx2c4.com/
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>  hw/mips/malta.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/hw/mips/malta.c b/hw/mips/malta.c
> index 0e932988e0..9d793b3c17 100644
> --- a/hw/mips/malta.c
> +++ b/hw/mips/malta.c
> @@ -26,6 +26,7 @@
>  #include "qemu/units.h"
>  #include "qemu/bitops.h"
>  #include "qemu/datadir.h"
> +#include "qemu/guest-random.h"
>  #include "hw/clock.h"
>  #include "hw/southbridge/piix.h"
>  #include "hw/isa/superio.h"
> @@ -1017,6 +1018,17 @@ static void G_GNUC_PRINTF(3, 4) prom_set(uint32_t *prom_buf, int index,
>      va_end(ap);
>  }
>  
> +static void reinitialize_rng_seed(void *opaque)
> +{
> +    char *rng_seed_hex = opaque;
> +    uint8_t rng_seed[32];
> +
> +    qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
> +    for (size_t i = 0; i < sizeof(rng_seed); ++i) {
> +        sprintf(rng_seed_hex + i * 2, "%02x", rng_seed[i]);
> +    }
> +}
> +
>  /* Kernel */
>  static uint64_t load_kernel(void)
>  {
> @@ -1028,6 +1040,8 @@ static uint64_t load_kernel(void)
>      long prom_size;
>      int prom_index = 0;
>      uint64_t (*xlate_to_kseg0) (void *opaque, uint64_t addr);
> +    uint8_t rng_seed[32];
> +    char rng_seed_hex[sizeof(rng_seed) * 2 + 1];

The +1 suggests you're intending to NUL terminate, but nothing
in this patch ever initializes this last byte.

>  
>  #if TARGET_BIG_ENDIAN
>      big_endian = 1;
> @@ -1115,9 +1129,20 @@ static uint64_t load_kernel(void)
>  
>      prom_set(prom_buf, prom_index++, "modetty0");
>      prom_set(prom_buf, prom_index++, "38400n8r");
> +
> +    qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
> +    for (size_t i = 0; i < sizeof(rng_seed); ++i) {
> +        sprintf(rng_seed_hex + i * 2, "%02x", rng_seed[i]);
> +    }
> +    prom_set(prom_buf, prom_index++, "rngseed");
> +    prom_set(prom_buf, prom_index++, "%s", rng_seed_hex);
> +
>      prom_set(prom_buf, prom_index++, NULL);
>  
>      rom_add_blob_fixed("prom", prom_buf, prom_size, ENVP_PADDR);
> +    qemu_register_reset(reinitialize_rng_seed,
> +                        memmem(rom_ptr(ENVP_PADDR, prom_size), prom_size,
> +                               rng_seed_hex, sizeof(rng_seed_hex)));
>  
>      g_free(prom_buf);
>      return kernel_entry;
> -- 
> 2.37.3
> 
> 

With regards,
Daniel
Jason A. Donenfeld Sept. 30, 2022, 3:06 p.m. UTC | #2
On Fri, Sep 30, 2022 at 5:05 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
> The +1 suggests you're intending to NUL terminate, but nothing
> in this patch ever initializes this last byte.

Incorrect. sprintf("%02x") writes 3 bytes, the last of which is 0.
Jason A. Donenfeld Oct. 1, 2022, 7:06 p.m. UTC | #3
On Fri, Sep 30, 2022 at 04:05:20PM +0200, Jason A. Donenfeld wrote:
> With the kernel patch linked below, Linux ingests a RNG seed
> passed from the hypervisor. So, pass this for the Malta platform, and
> reinitialize it on reboot too, so that it's always fresh.
> 
> Link: https://lore.kernel.org/linux-mips/20220930140138.575751-1-Jason@zx2c4.com/

The kernel side of this has now landed, so we can move ahead on the QEMU
side:
https://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git/commit/?id=056a68cea01edfa78b3474af1bfa39cc6bcc7bee
Bernhard Reutner-Fischer Oct. 1, 2022, 7:32 p.m. UTC | #4
On Sat, 1 Oct 2022 21:06:48 +0200
"Jason A. Donenfeld" <Jason@zx2c4.com> wrote:

> On Fri, Sep 30, 2022 at 04:05:20PM +0200, Jason A. Donenfeld wrote:
> > With the kernel patch linked below, Linux ingests a RNG seed
> > passed from the hypervisor. So, pass this for the Malta platform, and
> > reinitialize it on reboot too, so that it's always fresh.
> > 
> > Link: https://lore.kernel.org/linux-mips/20220930140138.575751-1-Jason@zx2c4.com/  
> 
> The kernel side of this has now landed, so we can move ahead on the QEMU
> side:
> https://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git/commit/?id=056a68cea01edfa78b3474af1bfa39cc6bcc7bee
> 

s/a RNG/an RNG/

What about rngseed=""?
len=min(4711,0)
hex2bin(..0) will return false so ok.
rndseed="0" is problably fine, but is it worthy and desired? 00, 0x0.
Other than that, sounds plausible. IMHO.
thanks,
Jason A. Donenfeld Oct. 1, 2022, 9:33 p.m. UTC | #5
On Sat, Oct 1, 2022 at 9:32 PM Bernhard Reutner-Fischer
<rep.dot.nop@gmail.com> wrote:
>
> On Sat, 1 Oct 2022 21:06:48 +0200
> "Jason A. Donenfeld" <Jason@zx2c4.com> wrote:
>
> > On Fri, Sep 30, 2022 at 04:05:20PM +0200, Jason A. Donenfeld wrote:
> > > With the kernel patch linked below, Linux ingests a RNG seed
> > > passed from the hypervisor. So, pass this for the Malta platform, and
> > > reinitialize it on reboot too, so that it's always fresh.
> > >
> > > Link: https://lore.kernel.org/linux-mips/20220930140138.575751-1-Jason@zx2c4.com/
> >
> > The kernel side of this has now landed, so we can move ahead on the QEMU
> > side:
> > https://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git/commit/?id=056a68cea01edfa78b3474af1bfa39cc6bcc7bee
> >
>
> s/a RNG/an RNG/
>
> What about rngseed=""?
> len=min(4711,0)
> hex2bin(..0) will return false so ok.
> rndseed="0" is problably fine, but is it worthy and desired? 00, 0x0.
> Other than that, sounds plausible. IMHO.
> thanks,

Not sure I understand the substantive part of your message. You're
wondering whether it's okay to ingest length 1 (or one half?) inputs?
The kernel will take whatever the firmware gives it; that's by design.
The firmware in turn provides whatever it can, optimally 32 bytes as
QEMU does with this patch.

Maybe you could use some more words to describe what your thoughts are?

Jason
diff mbox series

Patch

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 0e932988e0..9d793b3c17 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -26,6 +26,7 @@ 
 #include "qemu/units.h"
 #include "qemu/bitops.h"
 #include "qemu/datadir.h"
+#include "qemu/guest-random.h"
 #include "hw/clock.h"
 #include "hw/southbridge/piix.h"
 #include "hw/isa/superio.h"
@@ -1017,6 +1018,17 @@  static void G_GNUC_PRINTF(3, 4) prom_set(uint32_t *prom_buf, int index,
     va_end(ap);
 }
 
+static void reinitialize_rng_seed(void *opaque)
+{
+    char *rng_seed_hex = opaque;
+    uint8_t rng_seed[32];
+
+    qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
+    for (size_t i = 0; i < sizeof(rng_seed); ++i) {
+        sprintf(rng_seed_hex + i * 2, "%02x", rng_seed[i]);
+    }
+}
+
 /* Kernel */
 static uint64_t load_kernel(void)
 {
@@ -1028,6 +1040,8 @@  static uint64_t load_kernel(void)
     long prom_size;
     int prom_index = 0;
     uint64_t (*xlate_to_kseg0) (void *opaque, uint64_t addr);
+    uint8_t rng_seed[32];
+    char rng_seed_hex[sizeof(rng_seed) * 2 + 1];
 
 #if TARGET_BIG_ENDIAN
     big_endian = 1;
@@ -1115,9 +1129,20 @@  static uint64_t load_kernel(void)
 
     prom_set(prom_buf, prom_index++, "modetty0");
     prom_set(prom_buf, prom_index++, "38400n8r");
+
+    qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
+    for (size_t i = 0; i < sizeof(rng_seed); ++i) {
+        sprintf(rng_seed_hex + i * 2, "%02x", rng_seed[i]);
+    }
+    prom_set(prom_buf, prom_index++, "rngseed");
+    prom_set(prom_buf, prom_index++, "%s", rng_seed_hex);
+
     prom_set(prom_buf, prom_index++, NULL);
 
     rom_add_blob_fixed("prom", prom_buf, prom_size, ENVP_PADDR);
+    qemu_register_reset(reinitialize_rng_seed,
+                        memmem(rom_ptr(ENVP_PADDR, prom_size), prom_size,
+                               rng_seed_hex, sizeof(rng_seed_hex)));
 
     g_free(prom_buf);
     return kernel_entry;