bcm2835_rng.c (54a5ba13a9ffe7d25fc649b0fa9f8314734c8ccc) bcm2835_rng.c (373442ea3a96249991cfad3fc0e83fca5f8558d5)
1/*
2 * BCM2835 Random Number Generator emulation
3 *
4 * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
8 */
9
10#include "qemu/osdep.h"
11#include "qemu/log.h"
1/*
2 * BCM2835 Random Number Generator emulation
3 *
4 * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
8 */
9
10#include "qemu/osdep.h"
11#include "qemu/log.h"
12#include "qapi/error.h"
13#include "crypto/random.h"
12#include "hw/misc/bcm2835_rng.h"
13
14#include "hw/misc/bcm2835_rng.h"
15
16static uint32_t get_random_bytes(void)
17{
18 uint32_t res;
19 Error *err = NULL;
20
21 if (qcrypto_random_bytes((uint8_t *)&res, sizeof(res), &err) < 0) {
22 /* On failure we don't want to return the guest a non-random
23 * value in case they're really using it for cryptographic
24 * purposes, so the best we can do is die here.
25 * This shouldn't happen unless something's broken.
26 * In theory we could implement this device's full FIFO
27 * and interrupt semantics and then just stop filling the
28 * FIFO. That's a lot of work, though, so we assume any
29 * errors are systematic problems and trust that if we didn't
30 * fail as the guest inited then we won't fail later on
31 * mid-run.
32 */
33 error_report_err(err);
34 exit(1);
35 }
36 return res;
37}
38
14static uint64_t bcm2835_rng_read(void *opaque, hwaddr offset,
15 unsigned size)
16{
17 BCM2835RngState *s = (BCM2835RngState *)opaque;
18 uint32_t res = 0;
19
20 assert(size == 4);
21
22 switch (offset) {
23 case 0x0: /* rng_ctrl */
24 res = s->rng_ctrl;
25 break;
26 case 0x4: /* rng_status */
27 res = s->rng_status | (1 << 24);
28 break;
29 case 0x8: /* rng_data */
39static uint64_t bcm2835_rng_read(void *opaque, hwaddr offset,
40 unsigned size)
41{
42 BCM2835RngState *s = (BCM2835RngState *)opaque;
43 uint32_t res = 0;
44
45 assert(size == 4);
46
47 switch (offset) {
48 case 0x0: /* rng_ctrl */
49 res = s->rng_ctrl;
50 break;
51 case 0x4: /* rng_status */
52 res = s->rng_status | (1 << 24);
53 break;
54 case 0x8: /* rng_data */
30 res = rand();
55 res = get_random_bytes();
31 break;
32
33 default:
34 qemu_log_mask(LOG_GUEST_ERROR,
35 "bcm2835_rng_read: Bad offset %x\n",
36 (int)offset);
37 res = 0;
38 break;

--- 86 unchanged lines hidden ---
56 break;
57
58 default:
59 qemu_log_mask(LOG_GUEST_ERROR,
60 "bcm2835_rng_read: Bad offset %x\n",
61 (int)offset);
62 res = 0;
63 break;

--- 86 unchanged lines hidden ---