From: Thomas Huth <thuth@redhat.com>
To: qemu-ppc@nongnu.org, agraf@suse.de, david@gibson.dropbear.id.au
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] [RFC PATCH] ppc/spapr_hcall: Implement H_RANDOM hypercall
Date: Thu, 6 Aug 2015 10:23:58 +0200 [thread overview]
Message-ID: <1438849438-18552-1-git-send-email-thuth@redhat.com> (raw)
The spapr firmware SLOF likely needs a way to get random numbers
soon. Instead of re-inventing the wheel there, we could simply
use the H_RANDOM hypercall to get the random numbers from QEMU.
For this the H_RANDOM hypercall needs to be implemented first, of
course.
So this patch introduces an OS-specifc helper function called
qemu_random() to get "good" random numbers (from /dev/random on
POSIX systems and via CryptGenRandom() on Windows), and then uses
this helper functions to provide random data to the guest via the
H_RANDOM hypercall.
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
Note: Since I do not have access to the SPAPR spec, I figured out
the calling conventions of the hypercall by looking at the way
the Linux kernel is using this call to retriev random data. So
there might be some bugs or missing pieces here.
Also note that the Windows version of qemu_random() is
compile-tested only (with a MinGW cross-compiler), since I do not
have access to a Windows system right now.
hw/ppc/spapr_hcall.c | 12 ++++++++++++
include/hw/ppc/spapr.h | 1 +
include/qemu/osdep.h | 11 +++++++++++
util/oslib-posix.c | 16 ++++++++++++++++
util/oslib-win32.c | 17 +++++++++++++++++
5 files changed, 57 insertions(+)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index fcfb50c..30f4359 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -931,6 +931,15 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
return H_SUCCESS;
}
+static target_ulong h_random(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ if (qemu_random(&args[0], sizeof(args[0]))) {
+ return H_HARDWARE;
+ }
+ return H_SUCCESS;
+}
+
static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
@@ -1016,6 +1025,9 @@ static void hypercall_register_types(void)
/* ibm,client-architecture-support support */
spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support);
+
+ /* misc */
+ spapr_register_hypercall(H_RANDOM, h_random);
}
type_init(hypercall_register_types)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 46e9704..232cda1 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -331,6 +331,7 @@ struct sPAPRMachineState {
#define H_SET_MPP 0x2D0
#define H_GET_MPP 0x2D4
#define H_XIRR_X 0x2FC
+#define H_RANDOM 0x300
#define H_SET_MODE 0x31C
#define MAX_HCALL_OPCODE H_SET_MODE
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 3247364..1ef0f11 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -261,4 +261,15 @@ void os_mem_prealloc(int fd, char *area, size_t sz);
int qemu_read_password(char *buf, int buf_size);
+/**
+ * qemu_random:
+ * @buf: pointer to the buffer where the values should be stored
+ * @size: amount of bytes that should be stored
+ *
+ * Retrieve random numbers, store them in @buf.
+ *
+ * Returns: 0 on success, error code otherwise
+ */
+int qemu_random(void *buf, int size);
+
#endif
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 3ae4987..43f5a51 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -482,3 +482,19 @@ int qemu_read_password(char *buf, int buf_size)
printf("\n");
return ret;
}
+
+int qemu_random(void *buf, int size)
+{
+ FILE *fh;
+
+ fh = fopen("/dev/random", "rb");
+ if (!fh) {
+ return -errno;
+ }
+ if (fread(buf, 1, size, fh) != size) {
+ return -EIO;
+ }
+ fclose(fh);
+
+ return 0;
+}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 730a670..63f0a94 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -494,3 +494,20 @@ int qemu_read_password(char *buf, int buf_size)
buf[i] = '\0';
return 0;
}
+
+int qemu_random(void *buf, int size)
+{
+ HCRYPTPROV hprov = 0;
+ int ret = 0;
+
+ if (!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ return -EINVAL;
+ }
+ if (!CryptGenRandom(hprov, size, buf)) {
+ ret = -EIO;
+ }
+ CryptReleaseContext(hprov, 0);
+
+ return ret;
+}
--
1.8.3.1
next reply other threads:[~2015-08-06 8:24 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-06 8:23 Thomas Huth [this message]
2015-08-06 11:26 ` [Qemu-devel] [Qemu-ppc] [RFC PATCH] ppc/spapr_hcall: Implement H_RANDOM hypercall Laurent Vivier
2015-08-06 12:05 ` Thomas Huth
2015-08-06 12:35 ` Laurent Vivier
2015-08-06 12:43 ` Thomas Huth
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1438849438-18552-1-git-send-email-thuth@redhat.com \
--to=thuth@redhat.com \
--cc=agraf@suse.de \
--cc=david@gibson.dropbear.id.au \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).