|
@@ -9,8 +9,33 @@
|
|
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qemu/osdep.h"
|
|
#include "qemu/log.h"
|
|
#include "qemu/log.h"
|
|
|
|
+#include "qapi/error.h"
|
|
|
|
+#include "crypto/random.h"
|
|
#include "hw/misc/bcm2835_rng.h"
|
|
#include "hw/misc/bcm2835_rng.h"
|
|
|
|
|
|
|
|
+static uint32_t get_random_bytes(void)
|
|
|
|
+{
|
|
|
|
+ uint32_t res;
|
|
|
|
+ Error *err = NULL;
|
|
|
|
+
|
|
|
|
+ if (qcrypto_random_bytes((uint8_t *)&res, sizeof(res), &err) < 0) {
|
|
|
|
+ /* On failure we don't want to return the guest a non-random
|
|
|
|
+ * value in case they're really using it for cryptographic
|
|
|
|
+ * purposes, so the best we can do is die here.
|
|
|
|
+ * This shouldn't happen unless something's broken.
|
|
|
|
+ * In theory we could implement this device's full FIFO
|
|
|
|
+ * and interrupt semantics and then just stop filling the
|
|
|
|
+ * FIFO. That's a lot of work, though, so we assume any
|
|
|
|
+ * errors are systematic problems and trust that if we didn't
|
|
|
|
+ * fail as the guest inited then we won't fail later on
|
|
|
|
+ * mid-run.
|
|
|
|
+ */
|
|
|
|
+ error_report_err(err);
|
|
|
|
+ exit(1);
|
|
|
|
+ }
|
|
|
|
+ return res;
|
|
|
|
+}
|
|
|
|
+
|
|
static uint64_t bcm2835_rng_read(void *opaque, hwaddr offset,
|
|
static uint64_t bcm2835_rng_read(void *opaque, hwaddr offset,
|
|
unsigned size)
|
|
unsigned size)
|
|
{
|
|
{
|
|
@@ -27,7 +52,7 @@ static uint64_t bcm2835_rng_read(void *opaque, hwaddr offset,
|
|
res = s->rng_status | (1 << 24);
|
|
res = s->rng_status | (1 << 24);
|
|
break;
|
|
break;
|
|
case 0x8: /* rng_data */
|
|
case 0x8: /* rng_data */
|
|
- res = rand();
|
|
|
|
|
|
+ res = get_random_bytes();
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|