* [Qemu-devel] [PATCH v6 01/25] configure: Link test before auto-enabling crypto libraries
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 02/25] crypto: Merge crypto-obj-y into libqemuutil.a Richard Henderson
` (24 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
At least ubuntu 18.04 does not package static gnutls libraries.
At least Fedora 30 does not ship static nettle and gcrypt libraries.
Tested-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v5: Include nettle, gcrypt.
---
configure | 72 +++++++++++++++++++++++++++++++++----------------------
1 file changed, 44 insertions(+), 28 deletions(-)
diff --git a/configure b/configure
index 63f312bd1f..c4f27ed453 100755
--- a/configure
+++ b/configure
@@ -2784,17 +2784,24 @@ fi
# GNUTLS probe
if test "$gnutls" != "no"; then
+ pass="no"
if $pkg_config --exists "gnutls >= 3.1.18"; then
gnutls_cflags=$($pkg_config --cflags gnutls)
gnutls_libs=$($pkg_config --libs gnutls)
- libs_softmmu="$gnutls_libs $libs_softmmu"
- libs_tools="$gnutls_libs $libs_tools"
- QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
- gnutls="yes"
- elif test "$gnutls" = "yes"; then
+ # Packaging for the static libraries is not always correct.
+ # At least ubuntu 18.04 ships only shared libraries.
+ write_c_skeleton
+ if compile_prog "" "$gnutls_libs" ; then
+ libs_softmmu="$gnutls_libs $libs_softmmu"
+ libs_tools="$gnutls_libs $libs_tools"
+ QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
+ pass="yes"
+ fi
+ fi
+ if test "$pass" = "no" && test "$gnutls" = "yes"; then
feature_not_found "gnutls" "Install gnutls devel >= 3.1.18"
else
- gnutls="no"
+ gnutls="$pass"
fi
fi
@@ -2849,43 +2856,54 @@ has_libgcrypt() {
if test "$nettle" != "no"; then
+ pass="no"
if $pkg_config --exists "nettle >= 2.7.1"; then
nettle_cflags=$($pkg_config --cflags nettle)
nettle_libs=$($pkg_config --libs nettle)
nettle_version=$($pkg_config --modversion nettle)
- libs_softmmu="$nettle_libs $libs_softmmu"
- libs_tools="$nettle_libs $libs_tools"
- QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
- nettle="yes"
-
- if test -z "$gcrypt"; then
- gcrypt="no"
+ # Link test to make sure the given libraries work (e.g for static).
+ write_c_skeleton
+ if compile_prog "" "$nettle_libs" ; then
+ libs_softmmu="$nettle_libs $libs_softmmu"
+ libs_tools="$nettle_libs $libs_tools"
+ QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
+ if test -z "$gcrypt"; then
+ gcrypt="no"
+ fi
+ pass="yes"
fi
+ fi
+ if test "$pass" = "no" && test "$nettle" = "yes"; then
+ feature_not_found "nettle" "Install nettle devel >= 2.7.1"
else
- if test "$nettle" = "yes"; then
- feature_not_found "nettle" "Install nettle devel >= 2.7.1"
- else
- nettle="no"
- fi
+ nettle="$pass"
fi
fi
if test "$gcrypt" != "no"; then
+ pass="no"
if has_libgcrypt; then
gcrypt_cflags=$(libgcrypt-config --cflags)
gcrypt_libs=$(libgcrypt-config --libs)
- # Debian has remove -lgpg-error from libgcrypt-config
+ # Debian has removed -lgpg-error from libgcrypt-config
# as it "spreads unnecessary dependencies" which in
# turn breaks static builds...
if test "$static" = "yes"
then
gcrypt_libs="$gcrypt_libs -lgpg-error"
fi
- libs_softmmu="$gcrypt_libs $libs_softmmu"
- libs_tools="$gcrypt_libs $libs_tools"
- QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
- gcrypt="yes"
+ # Link test to make sure the given libraries work (e.g for static).
+ write_c_skeleton
+ if compile_prog "" "$gcrypt_libs" ; then
+ libs_softmmu="$gcrypt_libs $libs_softmmu"
+ libs_tools="$gcrypt_libs $libs_tools"
+ QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
+ pass="yes"
+ fi
+ fi
+ if test "$pass" = "yes"; then
+ gcrypt="yes"
cat > $TMPC << EOF
#include <gcrypt.h>
int main(void) {
@@ -2898,12 +2916,10 @@ EOF
if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
gcrypt_hmac=yes
fi
+ elif test "$gcrypt" = "yes"; then
+ feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0"
else
- if test "$gcrypt" = "yes"; then
- feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0"
- else
- gcrypt="no"
- fi
+ gcrypt="no"
fi
fi
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 02/25] crypto: Merge crypto-obj-y into libqemuutil.a
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 01/25] configure: Link test before auto-enabling crypto libraries Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 03/25] crypto: Reverse code blocks in random-platform.c Richard Henderson
` (23 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
We will shortly need this in the user-only binaries, so drop the split
into system and tools binaries. Remove crypto-obj-y and crypto-aes-obj-y,
moving the objects into util-obj-y.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v6: Remove a stray crypto-aes-obj-$(COND) -- (lvivier)
Remove crypto-obj-y entirely -- (berrange)
---
Makefile | 14 +++-----
Makefile.objs | 8 +----
Makefile.target | 4 ---
configure | 9 ++---
crypto/Makefile.objs | 77 ++++++++++++++++++++----------------------
tests/Makefile.include | 3 +-
6 files changed, 47 insertions(+), 68 deletions(-)
diff --git a/Makefile b/Makefile
index 4a8ae0ef95..acf13f5eaa 100644
--- a/Makefile
+++ b/Makefile
@@ -409,8 +409,6 @@ dummy := $(call unnest-vars,, \
qga-vss-dll-obj-y \
block-obj-y \
block-obj-m \
- crypto-obj-y \
- crypto-aes-obj-y \
qom-obj-y \
io-obj-y \
common-obj-y \
@@ -446,7 +444,6 @@ SOFTMMU_SUBDIR_RULES=$(filter %-softmmu,$(SUBDIR_RULES))
$(SOFTMMU_SUBDIR_RULES): $(authz-obj-y)
$(SOFTMMU_SUBDIR_RULES): $(block-obj-y)
-$(SOFTMMU_SUBDIR_RULES): $(crypto-obj-y)
$(SOFTMMU_SUBDIR_RULES): $(io-obj-y)
$(SOFTMMU_SUBDIR_RULES): config-all-devices.mak
$(SOFTMMU_SUBDIR_RULES): $(edk2-decompressed)
@@ -482,8 +479,7 @@ subdir-capstone: .git-submodule-status
subdir-slirp: .git-submodule-status
$(call quiet-command,$(MAKE) -C $(SRC_PATH)/slirp BUILD_DIR="$(BUILD_DIR)/slirp" CC="$(CC)" AR="$(AR)" LD="$(LD)" RANLIB="$(RANLIB)" CFLAGS="$(QEMU_CFLAGS) $(CFLAGS)" LDFLAGS="$(LDFLAGS)")
-$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) \
- $(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
+$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) $(qom-obj-y)
ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
# Only keep -O and -g cflags
@@ -511,9 +507,9 @@ COMMON_LDADDS = libqemuutil.a
qemu-img.o: qemu-img-cmds.h
-qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
-qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
-qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
@@ -524,7 +520,7 @@ qemu-edid$(EXESUF): qemu-edid.o hw/display/edid-generate.o $(COMMON_LDADDS)
fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/9p-marshal.o fsdev/9p-iov-marshal.o $(COMMON_LDADDS)
fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
-scsi/qemu-pr-helper$(EXESUF): scsi/qemu-pr-helper.o scsi/utils.o $(authz-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+scsi/qemu-pr-helper$(EXESUF): scsi/qemu-pr-helper.o scsi/utils.o $(authz-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
ifdef CONFIG_MPATH
scsi/qemu-pr-helper$(EXESUF): LIBS += -ludev -lmultipath -lmpathpersist
endif
diff --git a/Makefile.objs b/Makefile.objs
index cf065de5ed..4875b6f2e5 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -1,7 +1,7 @@
#######################################################################
# Common libraries for tools and emulators
stub-obj-y = stubs/ util/ crypto/
-util-obj-y = util/ qobject/ qapi/
+util-obj-y = util/ crypto/ qobject/ qapi/
chardev-obj-y = chardev/
@@ -21,12 +21,6 @@ block-obj-$(CONFIG_REPLICATION) += replication.o
block-obj-m = block/
-#######################################################################
-# crypto-obj-y is code used by both qemu system emulation and qemu-img
-
-crypto-obj-y = crypto/
-crypto-aes-obj-y = crypto/
-
#######################################################################
# qom-obj-y is code used by both qemu system emulation and qemu-img
diff --git a/Makefile.target b/Makefile.target
index ae02495951..ce02924ffb 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -179,8 +179,6 @@ dummy := $(call unnest-vars,.., \
block-obj-y \
block-obj-m \
chardev-obj-y \
- crypto-obj-y \
- crypto-aes-obj-y \
qom-obj-y \
io-obj-y \
common-obj-y \
@@ -189,8 +187,6 @@ all-obj-y += $(common-obj-y)
all-obj-y += $(qom-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(authz-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
-all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
-all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
ifdef CONFIG_SOFTMMU
diff --git a/configure b/configure
index c4f27ed453..68b34a93eb 100755
--- a/configure
+++ b/configure
@@ -2792,8 +2792,7 @@ if test "$gnutls" != "no"; then
# At least ubuntu 18.04 ships only shared libraries.
write_c_skeleton
if compile_prog "" "$gnutls_libs" ; then
- libs_softmmu="$gnutls_libs $libs_softmmu"
- libs_tools="$gnutls_libs $libs_tools"
+ LIBS="$gnutls_libs $LIBS"
QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
pass="yes"
fi
@@ -2864,8 +2863,7 @@ if test "$nettle" != "no"; then
# Link test to make sure the given libraries work (e.g for static).
write_c_skeleton
if compile_prog "" "$nettle_libs" ; then
- libs_softmmu="$nettle_libs $libs_softmmu"
- libs_tools="$nettle_libs $libs_tools"
+ LIBS="$nettle_libs $LIBS"
QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
if test -z "$gcrypt"; then
gcrypt="no"
@@ -2896,8 +2894,7 @@ if test "$gcrypt" != "no"; then
# Link test to make sure the given libraries work (e.g for static).
write_c_skeleton
if compile_prog "" "$gcrypt_libs" ; then
- libs_softmmu="$gcrypt_libs $libs_softmmu"
- libs_tools="$gcrypt_libs $libs_tools"
+ LIBS="$gcrypt_libs $LIBS"
QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
pass="yes"
fi
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 256c9aca1f..8fafffb048 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -1,41 +1,38 @@
-crypto-obj-y = init.o
-crypto-obj-y += hash.o
-crypto-obj-$(CONFIG_NETTLE) += hash-nettle.o
-crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += hash-gcrypt.o
-crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT),n,y)) += hash-glib.o
-crypto-obj-y += hmac.o
-crypto-obj-$(CONFIG_NETTLE) += hmac-nettle.o
-crypto-obj-$(CONFIG_GCRYPT_HMAC) += hmac-gcrypt.o
-crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT_HMAC),n,y)) += hmac-glib.o
-crypto-obj-y += aes.o
-crypto-obj-y += desrfb.o
-crypto-obj-y += cipher.o
-crypto-obj-$(CONFIG_AF_ALG) += afalg.o
-crypto-obj-$(CONFIG_AF_ALG) += cipher-afalg.o
-crypto-obj-$(CONFIG_AF_ALG) += hash-afalg.o
-crypto-obj-y += tlscreds.o
-crypto-obj-y += tlscredsanon.o
-crypto-obj-y += tlscredspsk.o
-crypto-obj-y += tlscredsx509.o
-crypto-obj-y += tlssession.o
-crypto-obj-y += secret.o
-crypto-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
-crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) += random-gnutls.o
-crypto-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) += random-platform.o
-crypto-obj-y += pbkdf.o
-crypto-obj-$(CONFIG_NETTLE) += pbkdf-nettle.o
-crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += pbkdf-gcrypt.o
-crypto-obj-y += ivgen.o
-crypto-obj-y += ivgen-essiv.o
-crypto-obj-y += ivgen-plain.o
-crypto-obj-y += ivgen-plain64.o
-crypto-obj-y += afsplit.o
-crypto-obj-y += xts.o
-crypto-obj-y += block.o
-crypto-obj-y += block-qcow.o
-crypto-obj-y += block-luks.o
-
-# Let the userspace emulators avoid linking gnutls/etc
-crypto-aes-obj-y = aes.o
-
+util-obj-y = init.o
+util-obj-y += hash.o
+util-obj-$(CONFIG_NETTLE) += hash-nettle.o
+util-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += hash-gcrypt.o
+util-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT),n,y)) += hash-glib.o
+util-obj-y += hmac.o
+util-obj-$(CONFIG_NETTLE) += hmac-nettle.o
+util-obj-$(CONFIG_GCRYPT_HMAC) += hmac-gcrypt.o
+util-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT_HMAC),n,y)) += hmac-glib.o
+util-obj-y += aes.o
+util-obj-y += desrfb.o
+util-obj-y += cipher.o
+util-obj-$(CONFIG_AF_ALG) += afalg.o
+util-obj-$(CONFIG_AF_ALG) += cipher-afalg.o
+util-obj-$(CONFIG_AF_ALG) += hash-afalg.o
+util-obj-y += tlscreds.o
+util-obj-y += tlscredsanon.o
+util-obj-y += tlscredspsk.o
+util-obj-y += tlscredsx509.o
+util-obj-y += tlssession.o
+util-obj-y += secret.o
+util-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
+util-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) += random-gnutls.o
+util-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) += random-platform.o
+util-obj-y += pbkdf.o
+util-obj-$(CONFIG_NETTLE) += pbkdf-nettle.o
+util-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += pbkdf-gcrypt.o
+util-obj-y += ivgen.o
+util-obj-y += ivgen-essiv.o
+util-obj-y += ivgen-plain.o
+util-obj-y += ivgen-plain64.o
+util-obj-y += afsplit.o
+util-obj-y += xts.o
+util-obj-y += block.o
+util-obj-y += block-qcow.o
+util-obj-y += block-luks.o
+util-obj-y += aes.o
stub-obj-y += pbkdf-stub.o
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 60de085ee1..96bf071992 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -496,8 +496,7 @@ test-qapi-obj-y = tests/test-qapi-types.o \
tests/test-qapi-visit-sub-sub-module.o \
tests/test-qapi-introspect.o \
$(test-qom-obj-y)
-benchmark-crypto-obj-y = $(authz-obj-y) $(crypto-obj-y) $(test-qom-obj-y)
-test-crypto-obj-y = $(authz-obj-y) $(crypto-obj-y) $(test-qom-obj-y)
+test-crypto-obj-y = $(authz-obj-y) $(test-qom-obj-y)
test-io-obj-y = $(io-obj-y) $(test-crypto-obj-y)
test-authz-obj-y = $(test-qom-obj-y) $(authz-obj-y)
test-block-obj-y = $(block-obj-y) $(test-io-obj-y) tests/iothread.o
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 03/25] crypto: Reverse code blocks in random-platform.c
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 01/25] configure: Link test before auto-enabling crypto libraries Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 02/25] crypto: Merge crypto-obj-y into libqemuutil.a Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 04/25] crypto: Do not fail for EINTR during qcrypto_random_bytes Richard Henderson
` (22 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
Use #ifdef _WIN32 instead of #ifndef _WIN32.
This will make other tests easier to sequence.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
crypto/random-platform.c | 35 +++++++++++++++++------------------
1 file changed, 17 insertions(+), 18 deletions(-)
diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index 7541b4cae7..f995fc0ef1 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -32,7 +32,14 @@ static int fd; /* a file handle to either /dev/urandom or /dev/random */
int qcrypto_random_init(Error **errp)
{
-#ifndef _WIN32
+#ifdef _WIN32
+ if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
+ error_setg_win32(errp, GetLastError(),
+ "Unable to create cryptographic provider");
+ return -1;
+ }
+#else
/* TBD perhaps also add support for BSD getentropy / Linux
* getrandom syscalls directly */
fd = open("/dev/urandom", O_RDONLY);
@@ -44,15 +51,7 @@ int qcrypto_random_init(Error **errp)
error_setg(errp, "No /dev/urandom or /dev/random found");
return -1;
}
-#else
- if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
- error_setg_win32(errp, GetLastError(),
- "Unable to create cryptographic provider");
- return -1;
- }
#endif
-
return 0;
}
@@ -60,7 +59,15 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
size_t buflen G_GNUC_UNUSED,
Error **errp)
{
-#ifndef _WIN32
+#ifdef _WIN32
+ if (!CryptGenRandom(hCryptProv, buflen, buf)) {
+ error_setg_win32(errp, GetLastError(),
+ "Unable to read random bytes");
+ return -1;
+ }
+
+ return 0;
+#else
int ret = -1;
int got;
@@ -82,13 +89,5 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
ret = 0;
cleanup:
return ret;
-#else
- if (!CryptGenRandom(hCryptProv, buflen, buf)) {
- error_setg_win32(errp, GetLastError(),
- "Unable to read random bytes");
- return -1;
- }
-
- return 0;
#endif
}
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 04/25] crypto: Do not fail for EINTR during qcrypto_random_bytes
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (2 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 03/25] crypto: Reverse code blocks in random-platform.c Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 05/25] crypto: Use O_CLOEXEC in qcrypto_random_init Richard Henderson
` (21 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
We can always get EINTR for read; /dev/urandom is no exception.
Rearrange the order of tests for likelihood; allow degenerate buflen==0
case to perform a no-op zero-length read. This means that the normal
success path is a straight line with a single test for success.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v3: Rearrage the read loop again.
---
crypto/random-platform.c | 36 +++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)
diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index f995fc0ef1..260b64564d 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -65,29 +65,23 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
"Unable to read random bytes");
return -1;
}
-
- return 0;
#else
- int ret = -1;
- int got;
-
- while (buflen > 0) {
- got = read(fd, buf, buflen);
- if (got < 0) {
- error_setg_errno(errp, errno,
- "Unable to read random bytes");
- goto cleanup;
- } else if (!got) {
- error_setg(errp,
- "Unexpected EOF reading random bytes");
- goto cleanup;
+ while (1) {
+ ssize_t got = read(fd, buf, buflen);
+ if (likely(got == buflen)) {
+ return 0;
+ }
+ if (got > 0) {
+ buflen -= got;
+ buf += got;
+ } else if (got == 0) {
+ error_setg(errp, "Unexpected EOF reading random bytes");
+ return -1;
+ } else if (errno != EINTR) {
+ error_setg_errno(errp, errno, "Unable to read random bytes");
+ return -1;
}
- buflen -= got;
- buf += got;
}
-
- ret = 0;
- cleanup:
- return ret;
#endif
+ return 0;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 05/25] crypto: Use O_CLOEXEC in qcrypto_random_init
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (3 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 04/25] crypto: Do not fail for EINTR during qcrypto_random_bytes Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 06/25] crypto: Use getrandom for qcrypto_random_bytes Richard Henderson
` (20 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
Avoids leaking the /dev/urandom fd into any child processes.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
crypto/random-platform.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index 260b64564d..6df40744c7 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -42,9 +42,9 @@ int qcrypto_random_init(Error **errp)
#else
/* TBD perhaps also add support for BSD getentropy / Linux
* getrandom syscalls directly */
- fd = open("/dev/urandom", O_RDONLY);
+ fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
if (fd == -1 && errno == ENOENT) {
- fd = open("/dev/random", O_RDONLY);
+ fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
}
if (fd < 0) {
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 06/25] crypto: Use getrandom for qcrypto_random_bytes
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (4 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 05/25] crypto: Use O_CLOEXEC in qcrypto_random_init Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 07/25] crypto: Change the qcrypto_random_bytes buffer type to void* Richard Henderson
` (19 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
Prefer it to direct use of /dev/urandom.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v3: If getrandom is not present, fall back on /dev/(u)random.
---
crypto/random-platform.c | 37 ++++++++++++++++++++++++++++++++-----
configure | 18 +++++++++++++++++-
2 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index 6df40744c7..cb3ca1bc09 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -27,7 +27,11 @@
#include <wincrypt.h>
static HCRYPTPROV hCryptProv;
#else
-static int fd; /* a file handle to either /dev/urandom or /dev/random */
+# ifdef CONFIG_GETRANDOM
+# include <sys/random.h>
+# endif
+/* This is -1 for getrandom(), or a file handle for /dev/{u,}random. */
+static int fd;
#endif
int qcrypto_random_init(Error **errp)
@@ -40,15 +44,20 @@ int qcrypto_random_init(Error **errp)
return -1;
}
#else
- /* TBD perhaps also add support for BSD getentropy / Linux
- * getrandom syscalls directly */
+# ifdef CONFIG_GETRANDOM
+ if (getrandom(NULL, 0, 0) == 0) {
+ /* Use getrandom() */
+ fd = -1;
+ return 0;
+ }
+ /* Fall through to /dev/urandom case. */
+# endif
fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
if (fd == -1 && errno == ENOENT) {
fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
}
-
if (fd < 0) {
- error_setg(errp, "No /dev/urandom or /dev/random found");
+ error_setg_errno(errp, errno, "No /dev/urandom or /dev/random");
return -1;
}
#endif
@@ -66,6 +75,24 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
return -1;
}
#else
+# ifdef CONFIG_GETRANDOM
+ if (likely(fd < 0)) {
+ while (1) {
+ ssize_t got = getrandom(buf, buflen, 0);
+ if (likely(got == buflen)) {
+ return 0;
+ }
+ if (got >= 0) {
+ buflen -= got;
+ buf += got;
+ } else if (errno != EINTR) {
+ error_setg_errno(errp, errno, "getrandom");
+ return -1;
+ }
+ }
+ }
+ /* Fall through to /dev/urandom case. */
+# endif
while (1) {
ssize_t got = read(fd, buf, buflen);
if (likely(got == buflen)) {
diff --git a/configure b/configure
index 68b34a93eb..346f89ea6c 100755
--- a/configure
+++ b/configure
@@ -5815,6 +5815,20 @@ if compile_prog "" "" ; then
have_utmpx=yes
fi
+##########################################
+# check for getrandom()
+
+have_getrandom=no
+cat > $TMPC << EOF
+#include <sys/random.h>
+int main(void) {
+ return getrandom(0, 0, GRND_NONBLOCK);
+}
+EOF
+if compile_prog "" "" ; then
+ have_getrandom=yes
+fi
+
##########################################
# checks for sanitizers
@@ -7202,7 +7216,9 @@ fi
if test "$have_utmpx" = "yes" ; then
echo "HAVE_UTMPX=y" >> $config_host_mak
fi
-
+if test "$have_getrandom" = "yes" ; then
+ echo "CONFIG_GETRANDOM=y" >> $config_host_mak
+fi
if test "$ivshmem" = "yes" ; then
echo "CONFIG_IVSHMEM=y" >> $config_host_mak
fi
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 07/25] crypto: Change the qcrypto_random_bytes buffer type to void*
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (5 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 06/25] crypto: Use getrandom for qcrypto_random_bytes Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 08/25] ui/vnc: Split out authentication_failed Richard Henderson
` (18 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
Using uint8_t* merely requires useless casts for use with
other types to be filled with randomness.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/crypto/random.h | 2 +-
crypto/random-gcrypt.c | 2 +-
crypto/random-gnutls.c | 2 +-
crypto/random-platform.c | 4 ++--
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/crypto/random.h b/include/crypto/random.h
index 8764ca0562..fde592904e 100644
--- a/include/crypto/random.h
+++ b/include/crypto/random.h
@@ -34,7 +34,7 @@
*
* Returns 0 on success, -1 on error
*/
-int qcrypto_random_bytes(uint8_t *buf,
+int qcrypto_random_bytes(void *buf,
size_t buflen,
Error **errp);
diff --git a/crypto/random-gcrypt.c b/crypto/random-gcrypt.c
index 9f1c9ee60e..7aea4ac81f 100644
--- a/crypto/random-gcrypt.c
+++ b/crypto/random-gcrypt.c
@@ -24,7 +24,7 @@
#include <gcrypt.h>
-int qcrypto_random_bytes(uint8_t *buf,
+int qcrypto_random_bytes(void *buf,
size_t buflen,
Error **errp G_GNUC_UNUSED)
{
diff --git a/crypto/random-gnutls.c b/crypto/random-gnutls.c
index 445fd6a30b..ed6c9ca12f 100644
--- a/crypto/random-gnutls.c
+++ b/crypto/random-gnutls.c
@@ -26,7 +26,7 @@
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
-int qcrypto_random_bytes(uint8_t *buf,
+int qcrypto_random_bytes(void *buf,
size_t buflen,
Error **errp)
{
diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index cb3ca1bc09..66624106fe 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -64,8 +64,8 @@ int qcrypto_random_init(Error **errp)
return 0;
}
-int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
- size_t buflen G_GNUC_UNUSED,
+int qcrypto_random_bytes(void *buf,
+ size_t buflen,
Error **errp)
{
#ifdef _WIN32
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 08/25] ui/vnc: Split out authentication_failed
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (6 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 07/25] crypto: Change the qcrypto_random_bytes buffer type to void* Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 09/25] ui/vnc: Use gcrypto_random_bytes for start_auth_vnc Richard Henderson
` (17 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
There were 3 copies of this code, one of which used the wrong
data size for the failure indicator.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
ui/vnc.c | 37 +++++++++++++++----------------------
1 file changed, 15 insertions(+), 22 deletions(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index 1871422e1d..785edf3af1 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2535,6 +2535,18 @@ void start_client_init(VncState *vs)
vnc_read_when(vs, protocol_client_init, 1);
}
+static void authentication_failed(VncState *vs)
+{
+ vnc_write_u32(vs, 1); /* Reject auth */
+ if (vs->minor >= 8) {
+ static const char err[] = "Authentication failed";
+ vnc_write_u32(vs, sizeof(err));
+ vnc_write(vs, err, sizeof(err));
+ }
+ vnc_flush(vs);
+ vnc_client_error(vs);
+}
+
static void make_challenge(VncState *vs)
{
int i;
@@ -2609,14 +2621,7 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
return 0;
reject:
- vnc_write_u32(vs, 1); /* Reject auth */
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_flush(vs);
- vnc_client_error(vs);
+ authentication_failed(vs);
qcrypto_cipher_free(cipher);
return 0;
}
@@ -2638,13 +2643,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
* must pick the one we sent. Verify this */
if (data[0] != vs->auth) { /* Reject auth */
trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
- vnc_write_u32(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
+ authentication_failed(vs);
} else { /* Accept requested auth */
trace_vnc_auth_start(vs, vs->auth);
switch (vs->auth) {
@@ -2673,13 +2672,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
default: /* Should not be possible, but just in case */
trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
- vnc_write_u8(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
+ authentication_failed(vs);
}
}
return 0;
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 09/25] ui/vnc: Use gcrypto_random_bytes for start_auth_vnc
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (7 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 08/25] ui/vnc: Split out authentication_failed Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 10/25] util: Add qemu_guest_getrandom and associated routines Richard Henderson
` (16 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
Use a better interface for random numbers than rand().
Fail gracefully if for some reason we cannot use the crypto system.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v2: Use qcrypto_random_bytes, not qemu_getrandom, as there is
no need for deterministic results for this interface.
v3: Fail gracefully in the event qcrypto_random_bytes fails.
---
ui/vnc.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index 785edf3af1..d83f4a6ff9 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -43,6 +43,7 @@
#include "crypto/hash.h"
#include "crypto/tlscredsanon.h"
#include "crypto/tlscredsx509.h"
+#include "crypto/random.h"
#include "qom/object_interfaces.h"
#include "qemu/cutils.h"
#include "io/dns-resolver.h"
@@ -2547,16 +2548,6 @@ static void authentication_failed(VncState *vs)
vnc_client_error(vs);
}
-static void make_challenge(VncState *vs)
-{
- int i;
-
- srand(time(NULL)+getpid()+getpid()*987654+rand());
-
- for (i = 0 ; i < sizeof(vs->challenge) ; i++)
- vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
-}
-
static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
{
unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
@@ -2628,7 +2619,16 @@ reject:
void start_auth_vnc(VncState *vs)
{
- make_challenge(vs);
+ Error *err = NULL;
+
+ if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), &err)) {
+ trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes",
+ error_get_pretty(err));
+ error_free(err);
+ authentication_failed(vs);
+ return;
+ }
+
/* Send client a 'random' challenge */
vnc_write(vs, vs->challenge, sizeof(vs->challenge));
vnc_flush(vs);
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 10/25] util: Add qemu_guest_getrandom and associated routines
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (8 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 09/25] ui/vnc: Use gcrypto_random_bytes for start_auth_vnc Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 11/25] cpus: Initialize pseudo-random seeds for all guest cpus Richard Henderson
` (15 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
This routine is intended to produce high-quality random numbers to the
guest. Normally, such numbers are crypto quality from the host, but a
command-line option can force the use of a fully deterministic sequence
for use while debugging.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qemu/guest-random.h | 68 +++++++++++++++++++++++++++
util/guest-random.c | 93 +++++++++++++++++++++++++++++++++++++
util/Makefile.objs | 1 +
3 files changed, 162 insertions(+)
create mode 100644 include/qemu/guest-random.h
create mode 100644 util/guest-random.c
diff --git a/include/qemu/guest-random.h b/include/qemu/guest-random.h
new file mode 100644
index 0000000000..09ff9c2236
--- /dev/null
+++ b/include/qemu/guest-random.h
@@ -0,0 +1,68 @@
+/*
+ * QEMU guest-visible random functions
+ *
+ * Copyright 2019 Linaro, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#ifndef QEMU_GUEST_RANDOM_H
+#define QEMU_GUEST_RANDOM_H
+
+/**
+ * qemu_guest_random_seed_main(const char *optarg, Error **errp)
+ * @optarg: a non-NULL pointer to a C string
+ * @errp: an error indicator
+ *
+ * The @optarg value is that which accompanies the -seed argument.
+ * This forces qemu_guest_getrandom into deterministic mode.
+ *
+ * Returns 0 on success, < 0 on failure while setting *errp.
+ */
+int qemu_guest_random_seed_main(const char *optarg, Error **errp);
+
+/**
+ * qemu_guest_random_seed_thread_part1(void)
+ *
+ * If qemu_getrandom is in deterministic mode, returns an
+ * independent seed for the new thread. Otherwise returns 0.
+ */
+uint64_t qemu_guest_random_seed_thread_part1(void);
+
+/**
+ * qemu_guest_random_seed_thread_part2(uint64_t seed)
+ * @seed: a value for the new thread.
+ *
+ * If qemu_guest_getrandom is in deterministic mode, this stores an
+ * independent seed for the new thread. Otherwise a no-op.
+ */
+void qemu_guest_random_seed_thread_part2(uint64_t seed);
+
+/**
+ * qemu_guest_getrandom(void *buf, size_t len, Error **errp)
+ * @buf: a buffer of bytes to be written
+ * @len: the number of bytes in @buf
+ * @errp: an error indicator
+ *
+ * Fills len bytes in buf with random data. This should only be used
+ * for data presented to the guest. Host-side crypto services should
+ * use qcrypto_random_bytes.
+ *
+ * Returns 0 on success, < 0 on failure while setting *errp.
+ */
+int qemu_guest_getrandom(void *buf, size_t len, Error **errp);
+
+/**
+ * qemu_guest_getrandom_nofail(void *buf, size_t len)
+ * @buf: a buffer of bytes to be written
+ * @len: the number of bytes in @buf
+ *
+ * Like qemu_guest_getrandom, but will assert for failure.
+ * Use this when there is no reasonable recovery.
+ */
+void qemu_guest_getrandom_nofail(void *buf, size_t len);
+
+#endif /* QEMU_GUEST_RANDOM_H */
diff --git a/util/guest-random.c b/util/guest-random.c
new file mode 100644
index 0000000000..e8124a3cad
--- /dev/null
+++ b/util/guest-random.c
@@ -0,0 +1,93 @@
+/*
+ * QEMU guest-visible random functions
+ *
+ * Copyright 2019 Linaro, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
+#include "crypto/random.h"
+
+
+static __thread GRand *thread_rand;
+static bool deterministic;
+
+
+static int glib_random_bytes(void *buf, size_t len)
+{
+ GRand *rand = thread_rand;
+ size_t i;
+ uint32_t x;
+
+ if (unlikely(rand == NULL)) {
+ /* Thread not initialized for a cpu, or main w/o -seed. */
+ thread_rand = rand = g_rand_new();
+ }
+
+ for (i = 0; i + 4 <= len; i += 4) {
+ x = g_rand_int(rand);
+ __builtin_memcpy(buf + i, &x, 4);
+ }
+ if (i < len) {
+ x = g_rand_int(rand);
+ __builtin_memcpy(buf + i, &x, i - len);
+ }
+ return 0;
+}
+
+int qemu_guest_getrandom(void *buf, size_t len, Error **errp)
+{
+ if (unlikely(deterministic)) {
+ /* Deterministic implementation using Glib's Mersenne Twister. */
+ return glib_random_bytes(buf, len);
+ } else {
+ /* Non-deterministic implementation using crypto routines. */
+ return qcrypto_random_bytes(buf, len, errp);
+ }
+}
+
+void qemu_guest_getrandom_nofail(void *buf, size_t len)
+{
+ qemu_guest_getrandom(buf, len, &error_fatal);
+}
+
+uint64_t qemu_guest_random_seed_thread_part1(void)
+{
+ if (deterministic) {
+ uint64_t ret;
+ glib_random_bytes(&ret, sizeof(ret));
+ return ret;
+ }
+ return 0;
+}
+
+void qemu_guest_random_seed_thread_part2(uint64_t seed)
+{
+ g_assert(thread_rand == NULL);
+ if (deterministic) {
+ thread_rand =
+ g_rand_new_with_seed_array((const guint32 *)&seed,
+ sizeof(seed) / sizeof(guint32));
+ }
+}
+
+int qemu_guest_random_seed_main(const char *optarg, Error **errp)
+{
+ unsigned long long seed;
+ if (parse_uint_full(optarg, &seed, 0)) {
+ error_setg(errp, "Invalid seed number: %s", optarg);
+ return -1;
+ } else {
+ deterministic = true;
+ qemu_guest_random_seed_thread_part2(seed);
+ return 0;
+ }
+}
diff --git a/util/Makefile.objs b/util/Makefile.objs
index 9206878dec..c27a923dbe 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -54,5 +54,6 @@ util-obj-y += iova-tree.o
util-obj-$(CONFIG_INOTIFY1) += filemonitor-inotify.o
util-obj-$(CONFIG_LINUX) += vfio-helpers.o
util-obj-$(CONFIG_OPENGL) += drm.o
+util-obj-y += guest-random.o
stub-obj-y += filemonitor-stub.o
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 11/25] cpus: Initialize pseudo-random seeds for all guest cpus
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (9 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 10/25] util: Add qemu_guest_getrandom and associated routines Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 12/25] linux-user: " Richard Henderson
` (14 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
When the -seed option is given, call qemu_guest_random_seed_main,
putting the subsystem into deterministic mode. Pass derived seeds
to each cpu created; which is a no-op unless the subsystem is in
deterministic mode.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qom/cpu.h | 1 +
cpus.c | 9 +++++++++
vl.c | 4 ++++
qemu-options.hx | 10 ++++++++++
4 files changed, 24 insertions(+)
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 08abcbd3fe..9793ec39bc 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -369,6 +369,7 @@ struct CPUState {
int singlestep_enabled;
int64_t icount_budget;
int64_t icount_extra;
+ uint64_t random_seed;
sigjmp_buf jmp_env;
QemuMutex work_mutex;
diff --git a/cpus.c b/cpus.c
index e58e7ab0f6..ffc57119ca 100644
--- a/cpus.c
+++ b/cpus.c
@@ -50,6 +50,7 @@
#include "qemu/option.h"
#include "qemu/bitmap.h"
#include "qemu/seqlock.h"
+#include "qemu/guest-random.h"
#include "tcg.h"
#include "hw/nmi.h"
#include "sysemu/replay.h"
@@ -1276,6 +1277,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
@@ -1319,6 +1321,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
qemu_mutex_unlock_iothread();
@@ -1478,6 +1481,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
cpu->created = true;
cpu->can_do_io = 1;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
/* wait for initial kick-off after machine start */
while (first_cpu->stopped) {
@@ -1592,6 +1596,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
hax_init_vcpu(cpu);
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
@@ -1631,6 +1636,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
@@ -1671,6 +1677,7 @@ static void *qemu_whpx_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
@@ -1724,6 +1731,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
cpu->can_do_io = 1;
current_cpu = cpu;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
/* process any pending work */
cpu->exit_request = 1;
@@ -2071,6 +2079,7 @@ void qemu_init_vcpu(CPUState *cpu)
cpu->nr_cores = smp_cores;
cpu->nr_threads = smp_threads;
cpu->stopped = true;
+ cpu->random_seed = qemu_guest_random_seed_thread_part1();
if (!cpu->as) {
/* If the target cpu hasn't set up any address spaces itself,
diff --git a/vl.c b/vl.c
index b6709514c1..e1d75a047f 100644
--- a/vl.c
+++ b/vl.c
@@ -128,6 +128,7 @@ int main(int argc, char **argv)
#include "qapi/qapi-commands-ui.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/iothread.h"
+#include "qemu/guest-random.h"
#define MAX_VIRTIO_CONSOLES 1
@@ -3347,6 +3348,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_DFILTER:
qemu_set_dfilter_ranges(optarg, &error_fatal);
break;
+ case QEMU_OPTION_seed:
+ qemu_guest_random_seed_main(optarg, &error_fatal);
+ break;
case QEMU_OPTION_s:
add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
break;
diff --git a/qemu-options.hx b/qemu-options.hx
index 51802cbb26..0191ef8b1e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3601,6 +3601,16 @@ the 0x200 sized block starting at 0xffffffc000080000 and another 0x1000 sized
block starting at 0xffffffc00005f000.
ETEXI
+DEF("seed", HAS_ARG, QEMU_OPTION_seed, \
+ "-seed number seed the pseudo-random number generator\n",
+ QEMU_ARCH_ALL)
+STEXI
+@item -seed @var{number}
+@findex -seed
+Force the guest to use a deterministic pseudo-random number generator, seeded
+with @var{number}. This does not affect crypto routines within the host.
+ETEXI
+
DEF("L", HAS_ARG, QEMU_OPTION_L, \
"-L path set the directory for the BIOS, VGA BIOS and keymaps\n",
QEMU_ARCH_ALL)
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 12/25] linux-user: Initialize pseudo-random seeds for all guest cpus
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (10 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 11/25] cpus: Initialize pseudo-random seeds for all guest cpus Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 13/25] linux-user: Call qcrypto_init if not using -seed Richard Henderson
` (13 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
When the -seed option is given, call qemu_guest_random_seed_main,
putting the subsystem into deterministic mode. Pass derived seeds
to each cpu created during clone; which is a no-op unless the
subsystem is in deterministic mode.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v5: Retain srand() until last user goes away.
---
linux-user/main.c | 30 +++++++++++++++++++-----------
linux-user/syscall.c | 3 +++
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index 3d2230320b..7e704845c0 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -34,6 +34,7 @@
#include "tcg.h"
#include "qemu/timer.h"
#include "qemu/envlist.h"
+#include "qemu/guest-random.h"
#include "elf.h"
#include "trace/control.h"
#include "target_elf.h"
@@ -48,6 +49,7 @@ static int gdbstub_port;
static envlist_t *envlist;
static const char *cpu_model;
static const char *cpu_type;
+static const char *seed_optarg;
unsigned long mmap_min_addr;
unsigned long guest_base;
int have_guest_base;
@@ -290,15 +292,9 @@ static void handle_arg_pagesize(const char *arg)
}
}
-static void handle_arg_randseed(const char *arg)
+static void handle_arg_seed(const char *arg)
{
- unsigned long long seed;
-
- if (parse_uint_full(arg, &seed, 0) != 0 || seed > UINT_MAX) {
- fprintf(stderr, "Invalid seed number: %s\n", arg);
- exit(EXIT_FAILURE);
- }
- srand(seed);
+ seed_optarg = arg;
}
static void handle_arg_gdb(const char *arg)
@@ -433,7 +429,7 @@ static const struct qemu_argument arg_table[] = {
"", "run in singlestep mode"},
{"strace", "QEMU_STRACE", false, handle_arg_strace,
"", "log system calls"},
- {"seed", "QEMU_RAND_SEED", true, handle_arg_randseed,
+ {"seed", "QEMU_RAND_SEED", true, handle_arg_seed,
"", "Seed for pseudo-random number generator"},
{"trace", "QEMU_TRACE", true, handle_arg_trace,
"", "[[enable=]<pattern>][,events=<file>][,file=<file>]"},
@@ -689,8 +685,20 @@ int main(int argc, char **argv, char **envp)
do_strace = 1;
}
- if (getenv("QEMU_RAND_SEED")) {
- handle_arg_randseed(getenv("QEMU_RAND_SEED"));
+ if (seed_optarg == NULL) {
+ seed_optarg = getenv("QEMU_RAND_SEED");
+ }
+ if (seed_optarg != NULL) {
+ unsigned long long seed;
+
+ /* This will go away with the last user of rand(). */
+ if (parse_uint_full(seed_optarg, &seed, 0) != 0) {
+ fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
+ exit(EXIT_FAILURE);
+ }
+ srand(seed);
+
+ qemu_guest_random_seed_main(seed_optarg, &error_fatal);
}
target_environ = envlist_to_environ(envlist, NULL);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f5ff6f5dc8..96f20886ce 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -107,6 +107,7 @@
#include "uname.h"
#include "qemu.h"
+#include "qemu/guest-random.h"
#include "fd-trans.h"
#ifndef CLONE_IO
@@ -5482,6 +5483,7 @@ static void *clone_func(void *arg)
put_user_u32(info->tid, info->child_tidptr);
if (info->parent_tidptr)
put_user_u32(info->tid, info->parent_tidptr);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
/* Enable signals. */
sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
/* Signal to the parent that we're ready. */
@@ -5568,6 +5570,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
initializing, so temporarily block all signals. */
sigfillset(&sigmask);
sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
+ cpu->random_seed = qemu_guest_random_seed_thread_part1();
/* If this is our first additional thread, we need to ensure we
* generate code for parallel execution and flush old translations.
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 13/25] linux-user: Call qcrypto_init if not using -seed
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (11 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 12/25] linux-user: " Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 14/25] linux-user: Use qemu_guest_getrandom_nofail for AT_RANDOM Richard Henderson
` (12 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/main.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index 7e704845c0..e455bff1b7 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -39,6 +39,7 @@
#include "trace/control.h"
#include "target_elf.h"
#include "cpu_loop-common.h"
+#include "crypto/init.h"
char *exec_path;
@@ -688,17 +689,27 @@ int main(int argc, char **argv, char **envp)
if (seed_optarg == NULL) {
seed_optarg = getenv("QEMU_RAND_SEED");
}
- if (seed_optarg != NULL) {
- unsigned long long seed;
+ {
+ Error *err = NULL;
+ if (seed_optarg != NULL) {
+ unsigned long long seed;
- /* This will go away with the last user of rand(). */
- if (parse_uint_full(seed_optarg, &seed, 0) != 0) {
- fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
- exit(EXIT_FAILURE);
+ /* This will go away with the last user of rand(). */
+ if (parse_uint_full(seed_optarg, &seed, 0) != 0) {
+ fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
+ exit(EXIT_FAILURE);
+ }
+ srand(seed);
+
+ qemu_guest_random_seed_main(seed_optarg, &err);
+ } else {
+ /* ??? Assumes qcrypto is only used by qemu_guest_getrandom. */
+ qcrypto_init(&err);
+ }
+ if (err) {
+ error_reportf_err(err, "cannot initialize crypto: ");
+ exit(1);
}
- srand(seed);
-
- qemu_guest_random_seed_main(seed_optarg, &error_fatal);
}
target_environ = envlist_to_environ(envlist, NULL);
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 14/25] linux-user: Use qemu_guest_getrandom_nofail for AT_RANDOM
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (12 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 13/25] linux-user: Call qcrypto_init if not using -seed Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 15/25] linux-user/aarch64: Use qemu_guest_getrandom for PAUTH keys Richard Henderson
` (11 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
Use a better interface for random numbers than rand * 16.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ef42e02d82..1e06b908b7 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -7,6 +7,7 @@
#include "qemu.h"
#include "disas/disas.h"
#include "qemu/path.h"
+#include "qemu/guest-random.h"
#ifdef _ARCH_PPC64
#undef ARCH_DLINFO
@@ -1883,12 +1884,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
}
/*
- * Generate 16 random bytes for userspace PRNG seeding (not
- * cryptically secure but it's not the aim of QEMU).
+ * Generate 16 random bytes for userspace PRNG seeding.
*/
- for (i = 0; i < 16; i++) {
- k_rand_bytes[i] = rand();
- }
+ qemu_guest_getrandom_nofail(k_rand_bytes, sizeof(k_rand_bytes));
if (STACK_GROWS_DOWN) {
sp -= 16;
u_rand_bytes = sp;
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 15/25] linux-user/aarch64: Use qemu_guest_getrandom for PAUTH keys
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (13 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 14/25] linux-user: Use qemu_guest_getrandom_nofail for AT_RANDOM Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 16/25] linux-user: Remove srand call Richard Henderson
` (10 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
Use a better interface for random numbers than rand() * 3.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/target_syscall.h | 2 --
linux-user/aarch64/cpu_loop.c | 29 ++++++---------------------
linux-user/syscall.c | 31 ++++++++++++++++++++++++-----
3 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
index b595e5da82..995e475c73 100644
--- a/linux-user/aarch64/target_syscall.h
+++ b/linux-user/aarch64/target_syscall.h
@@ -29,6 +29,4 @@ struct target_pt_regs {
# define TARGET_PR_PAC_APDBKEY (1 << 3)
# define TARGET_PR_PAC_APGAKEY (1 << 4)
-void arm_init_pauth_key(ARMPACKey *key);
-
#endif /* AARCH64_TARGET_SYSCALL_H */
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index d75fd9d3e2..cedad39ca0 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "qemu/guest-random.h"
#define get_user_code_u32(x, gaddr, env) \
({ abi_long __r = get_user_u32((x), (gaddr)); \
@@ -147,24 +148,6 @@ void cpu_loop(CPUARMState *env)
}
}
-static uint64_t arm_rand64(void)
-{
- int shift = 64 - clz64(RAND_MAX);
- int i, n = 64 / shift + (64 % shift != 0);
- uint64_t ret = 0;
-
- for (i = 0; i < n; i++) {
- ret = (ret << shift) | rand();
- }
- return ret;
-}
-
-void arm_init_pauth_key(ARMPACKey *key)
-{
- key->lo = arm_rand64();
- key->hi = arm_rand64();
-}
-
void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
{
ARMCPU *cpu = arm_env_get_cpu(env);
@@ -192,11 +175,11 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
#endif
if (cpu_isar_feature(aa64_pauth, cpu)) {
- arm_init_pauth_key(&env->apia_key);
- arm_init_pauth_key(&env->apib_key);
- arm_init_pauth_key(&env->apda_key);
- arm_init_pauth_key(&env->apdb_key);
- arm_init_pauth_key(&env->apga_key);
+ qemu_guest_getrandom_nofail(&env->apia_key, sizeof(ARMPACKey));
+ qemu_guest_getrandom_nofail(&env->apib_key, sizeof(ARMPACKey));
+ qemu_guest_getrandom_nofail(&env->apda_key, sizeof(ARMPACKey));
+ qemu_guest_getrandom_nofail(&env->apdb_key, sizeof(ARMPACKey));
+ qemu_guest_getrandom_nofail(&env->apga_key, sizeof(ARMPACKey));
}
ts->stack_base = info->start_stack;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 96f20886ce..8c17b14d51 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -108,6 +108,7 @@
#include "qemu.h"
#include "qemu/guest-random.h"
+#include "qapi/error.h"
#include "fd-trans.h"
#ifndef CLONE_IO
@@ -9765,25 +9766,45 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
int all = (TARGET_PR_PAC_APIAKEY | TARGET_PR_PAC_APIBKEY |
TARGET_PR_PAC_APDAKEY | TARGET_PR_PAC_APDBKEY |
TARGET_PR_PAC_APGAKEY);
+ int ret = 0;
+ Error *err = NULL;
+
if (arg2 == 0) {
arg2 = all;
} else if (arg2 & ~all) {
return -TARGET_EINVAL;
}
if (arg2 & TARGET_PR_PAC_APIAKEY) {
- arm_init_pauth_key(&env->apia_key);
+ ret |= qemu_guest_getrandom(&env->apia_key,
+ sizeof(ARMPACKey), &err);
}
if (arg2 & TARGET_PR_PAC_APIBKEY) {
- arm_init_pauth_key(&env->apib_key);
+ ret |= qemu_guest_getrandom(&env->apib_key,
+ sizeof(ARMPACKey), &err);
}
if (arg2 & TARGET_PR_PAC_APDAKEY) {
- arm_init_pauth_key(&env->apda_key);
+ ret |= qemu_guest_getrandom(&env->apda_key,
+ sizeof(ARMPACKey), &err);
}
if (arg2 & TARGET_PR_PAC_APDBKEY) {
- arm_init_pauth_key(&env->apdb_key);
+ ret |= qemu_guest_getrandom(&env->apdb_key,
+ sizeof(ARMPACKey), &err);
}
if (arg2 & TARGET_PR_PAC_APGAKEY) {
- arm_init_pauth_key(&env->apga_key);
+ ret |= qemu_guest_getrandom(&env->apga_key,
+ sizeof(ARMPACKey), &err);
+ }
+ if (ret != 0) {
+ /*
+ * Some unknown failure in the crypto. The best
+ * we can do is log it and fail the syscall.
+ * The real syscall cannot fail this way.
+ */
+ qemu_log_mask(LOG_UNIMP,
+ "PR_PAC_RESET_KEYS: Crypto failure: %s",
+ error_get_pretty(err));
+ error_free(err);
+ return -TARGET_EIO;
}
return 0;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 16/25] linux-user: Remove srand call
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (14 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 15/25] linux-user/aarch64: Use qemu_guest_getrandom for PAUTH keys Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 17/25] aspeed/scu: Use qemu_guest_getrandom_nofail Richard Henderson
` (9 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
We no longer use rand() within linux-user.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/main.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index e455bff1b7..5d1c6a115b 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -623,8 +623,6 @@ int main(int argc, char **argv, char **envp)
cpu_model = NULL;
- srand(time(NULL));
-
qemu_add_opts(&qemu_trace_opts);
optind = parse_args(argc, argv);
@@ -692,15 +690,6 @@ int main(int argc, char **argv, char **envp)
{
Error *err = NULL;
if (seed_optarg != NULL) {
- unsigned long long seed;
-
- /* This will go away with the last user of rand(). */
- if (parse_uint_full(seed_optarg, &seed, 0) != 0) {
- fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
- exit(EXIT_FAILURE);
- }
- srand(seed);
-
qemu_guest_random_seed_main(seed_optarg, &err);
} else {
/* ??? Assumes qcrypto is only used by qemu_guest_getrandom. */
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 17/25] aspeed/scu: Use qemu_guest_getrandom_nofail
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (15 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 16/25] linux-user: Remove srand call Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 18/25] hw/misc/nrf51_rng: " Richard Henderson
` (8 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Andrew Jeffery, qemu-arm
The random number is intended for use by the guest. As such, we should
honor the -seed argument for reproducibility. Use the *_nofail routine
instead of rolling our own error handling locally.
Cc: qemu-arm@nongnu.org
Cc: Andrew Jeffery <andrew@aj.id.au>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
hw/misc/aspeed_scu.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index c8217740ef..ab1e18ed4b 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -16,7 +16,7 @@
#include "qapi/visitor.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
-#include "crypto/random.h"
+#include "qemu/guest-random.h"
#include "trace.h"
#define TO_REG(offset) ((offset) >> 2)
@@ -157,14 +157,8 @@ static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
static uint32_t aspeed_scu_get_random(void)
{
- Error *err = NULL;
uint32_t num;
-
- if (qcrypto_random_bytes((uint8_t *)&num, sizeof(num), &err)) {
- error_report_err(err);
- exit(1);
- }
-
+ qemu_guest_getrandom_nofail(&num, sizeof(num));
return num;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 18/25] hw/misc/nrf51_rng: Use qemu_guest_getrandom_nofail
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (16 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 17/25] aspeed/scu: Use qemu_guest_getrandom_nofail Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 19/25] hw/misc/bcm2835_rng: " Richard Henderson
` (7 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-arm
The random number is intended for use by the guest. As such, we should
honor the -seed argument for reproducibility. Use the *_nofail routine
instead of error_abort directly.
Cc: qemu-arm@nongnu.org
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
hw/misc/nrf51_rng.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/misc/nrf51_rng.c b/hw/misc/nrf51_rng.c
index d188f044f4..3400e90a9b 100644
--- a/hw/misc/nrf51_rng.c
+++ b/hw/misc/nrf51_rng.c
@@ -14,7 +14,7 @@
#include "qapi/error.h"
#include "hw/arm/nrf51.h"
#include "hw/misc/nrf51_rng.h"
-#include "crypto/random.h"
+#include "qemu/guest-random.h"
static void update_irq(NRF51RNGState *s)
{
@@ -145,7 +145,7 @@ static void nrf51_rng_timer_expire(void *opaque)
{
NRF51RNGState *s = NRF51_RNG(opaque);
- qcrypto_random_bytes(&s->value, 1, &error_abort);
+ qemu_guest_getrandom_nofail(&s->value, 1);
s->event_valrdy = 1;
qemu_set_irq(s->eep_valrdy, 1);
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 19/25] hw/misc/bcm2835_rng: Use qemu_guest_getrandom_nofail
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (17 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 18/25] hw/misc/nrf51_rng: " Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 20/25] hw/misc/exynos4210_rng: Use qemu_guest_getrandom Richard Henderson
` (6 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-arm, Andrew Baumann
The random number is intended for use by the guest. As such, we should
honor the -seed argument for reproducibility. Use the *_nofail routine
instead of rolling our own error handling locally.
Cc: qemu-arm@nongnu.org
Cc: Andrew Baumann <Andrew.Baumann@microsoft.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
hw/misc/bcm2835_rng.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/hw/misc/bcm2835_rng.c b/hw/misc/bcm2835_rng.c
index 4d62143b24..fe59c868f5 100644
--- a/hw/misc/bcm2835_rng.c
+++ b/hw/misc/bcm2835_rng.c
@@ -9,30 +9,26 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
-#include "qapi/error.h"
-#include "crypto/random.h"
+#include "qemu/guest-random.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);
- }
+ /*
+ * 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.
+ */
+ qemu_guest_getrandom_nofail(&res, sizeof(res));
return res;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 20/25] hw/misc/exynos4210_rng: Use qemu_guest_getrandom
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (18 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 19/25] hw/misc/bcm2835_rng: " Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 21/25] target/arm: Put all PAC keys into a structure Richard Henderson
` (5 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Igor Mitsyanko, qemu-arm
The random number is intended for use by the guest. As such, we should
honor the -seed argument for reproducibility.
Cc: qemu-arm@nongnu.org
Cc: Igor Mitsyanko <i.mitsyanko@gmail.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
hw/misc/exynos4210_rng.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/hw/misc/exynos4210_rng.c b/hw/misc/exynos4210_rng.c
index 4ecbebd2d7..0e70ffb404 100644
--- a/hw/misc/exynos4210_rng.c
+++ b/hw/misc/exynos4210_rng.c
@@ -18,10 +18,10 @@
*/
#include "qemu/osdep.h"
-#include "crypto/random.h"
#include "hw/sysbus.h"
#include "qapi/error.h"
#include "qemu/log.h"
+#include "qemu/guest-random.h"
#define DEBUG_EXYNOS_RNG 0
@@ -109,7 +109,6 @@ static void exynos4210_rng_set_seed(Exynos4210RngState *s, unsigned int i,
static void exynos4210_rng_run_engine(Exynos4210RngState *s)
{
Error *err = NULL;
- int ret;
/* Seed set? */
if ((s->reg_status & EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE) == 0) {
@@ -127,13 +126,11 @@ static void exynos4210_rng_run_engine(Exynos4210RngState *s)
}
/* Get randoms */
- ret = qcrypto_random_bytes((uint8_t *)s->randr_value,
- sizeof(s->randr_value), &err);
- if (!ret) {
+ if (qemu_guest_getrandom(s->randr_value, sizeof(s->randr_value), &err)) {
+ error_report_err(err);
+ } else {
/* Notify that PRNG is ready */
s->reg_status |= EXYNOS4210_RNG_STATUS_PRNG_DONE;
- } else {
- error_report_err(err);
}
out:
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 21/25] target/arm: Put all PAC keys into a structure
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (19 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 20/25] hw/misc/exynos4210_rng: Use qemu_guest_getrandom Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 22/25] target/arm: Implement ARMv8.5-RNG Richard Henderson
` (4 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
This allows us to use a single syscall to initialize them all.
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 12 +++++++-----
linux-user/aarch64/cpu_loop.c | 6 +-----
linux-user/syscall.c | 10 +++++-----
target/arm/helper.c | 20 ++++++++++----------
target/arm/pauth_helper.c | 18 +++++++++---------
5 files changed, 32 insertions(+), 34 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 733b840a71..892f9a4ad2 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -636,11 +636,13 @@ typedef struct CPUARMState {
} iwmmxt;
#ifdef TARGET_AARCH64
- ARMPACKey apia_key;
- ARMPACKey apib_key;
- ARMPACKey apda_key;
- ARMPACKey apdb_key;
- ARMPACKey apga_key;
+ struct {
+ ARMPACKey apia;
+ ARMPACKey apib;
+ ARMPACKey apda;
+ ARMPACKey apdb;
+ ARMPACKey apga;
+ } keys;
#endif
#if defined(CONFIG_USER_ONLY)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index cedad39ca0..2f2f63e3e8 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -175,11 +175,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
#endif
if (cpu_isar_feature(aa64_pauth, cpu)) {
- qemu_guest_getrandom_nofail(&env->apia_key, sizeof(ARMPACKey));
- qemu_guest_getrandom_nofail(&env->apib_key, sizeof(ARMPACKey));
- qemu_guest_getrandom_nofail(&env->apda_key, sizeof(ARMPACKey));
- qemu_guest_getrandom_nofail(&env->apdb_key, sizeof(ARMPACKey));
- qemu_guest_getrandom_nofail(&env->apga_key, sizeof(ARMPACKey));
+ qemu_guest_getrandom_nofail(&env->keys, sizeof(env->keys));
}
ts->stack_base = info->start_stack;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8c17b14d51..394b956b4a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9775,23 +9775,23 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
return -TARGET_EINVAL;
}
if (arg2 & TARGET_PR_PAC_APIAKEY) {
- ret |= qemu_guest_getrandom(&env->apia_key,
+ ret |= qemu_guest_getrandom(&env->keys.apia,
sizeof(ARMPACKey), &err);
}
if (arg2 & TARGET_PR_PAC_APIBKEY) {
- ret |= qemu_guest_getrandom(&env->apib_key,
+ ret |= qemu_guest_getrandom(&env->keys.apib,
sizeof(ARMPACKey), &err);
}
if (arg2 & TARGET_PR_PAC_APDAKEY) {
- ret |= qemu_guest_getrandom(&env->apda_key,
+ ret |= qemu_guest_getrandom(&env->keys.apda,
sizeof(ARMPACKey), &err);
}
if (arg2 & TARGET_PR_PAC_APDBKEY) {
- ret |= qemu_guest_getrandom(&env->apdb_key,
+ ret |= qemu_guest_getrandom(&env->keys.apdb,
sizeof(ARMPACKey), &err);
}
if (arg2 & TARGET_PR_PAC_APGAKEY) {
- ret |= qemu_guest_getrandom(&env->apga_key,
+ ret |= qemu_guest_getrandom(&env->keys.apga,
sizeof(ARMPACKey), &err);
}
if (ret != 0) {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 1e6eb0d0f3..7e88b2cadd 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5707,43 +5707,43 @@ static const ARMCPRegInfo pauth_reginfo[] = {
{ .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apda_key.lo) },
+ .fieldoffset = offsetof(CPUARMState, keys.apda.lo) },
{ .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apda_key.hi) },
+ .fieldoffset = offsetof(CPUARMState, keys.apda.hi) },
{ .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apdb_key.lo) },
+ .fieldoffset = offsetof(CPUARMState, keys.apdb.lo) },
{ .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apdb_key.hi) },
+ .fieldoffset = offsetof(CPUARMState, keys.apdb.hi) },
{ .name = "APGAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apga_key.lo) },
+ .fieldoffset = offsetof(CPUARMState, keys.apga.lo) },
{ .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apga_key.hi) },
+ .fieldoffset = offsetof(CPUARMState, keys.apga.hi) },
{ .name = "APIAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apia_key.lo) },
+ .fieldoffset = offsetof(CPUARMState, keys.apia.lo) },
{ .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apia_key.hi) },
+ .fieldoffset = offsetof(CPUARMState, keys.apia.hi) },
{ .name = "APIBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apib_key.lo) },
+ .fieldoffset = offsetof(CPUARMState, keys.apib.lo) },
{ .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
.access = PL1_RW, .accessfn = access_pauth,
- .fieldoffset = offsetof(CPUARMState, apib_key.hi) },
+ .fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
REGINFO_SENTINEL
};
#endif
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
index d750f96edf..7f30ae7395 100644
--- a/target/arm/pauth_helper.c
+++ b/target/arm/pauth_helper.c
@@ -403,7 +403,7 @@ uint64_t HELPER(pacia)(CPUARMState *env, uint64_t x, uint64_t y)
return x;
}
pauth_check_trap(env, el, GETPC());
- return pauth_addpac(env, x, y, &env->apia_key, false);
+ return pauth_addpac(env, x, y, &env->keys.apia, false);
}
uint64_t HELPER(pacib)(CPUARMState *env, uint64_t x, uint64_t y)
@@ -413,7 +413,7 @@ uint64_t HELPER(pacib)(CPUARMState *env, uint64_t x, uint64_t y)
return x;
}
pauth_check_trap(env, el, GETPC());
- return pauth_addpac(env, x, y, &env->apib_key, false);
+ return pauth_addpac(env, x, y, &env->keys.apib, false);
}
uint64_t HELPER(pacda)(CPUARMState *env, uint64_t x, uint64_t y)
@@ -423,7 +423,7 @@ uint64_t HELPER(pacda)(CPUARMState *env, uint64_t x, uint64_t y)
return x;
}
pauth_check_trap(env, el, GETPC());
- return pauth_addpac(env, x, y, &env->apda_key, true);
+ return pauth_addpac(env, x, y, &env->keys.apda, true);
}
uint64_t HELPER(pacdb)(CPUARMState *env, uint64_t x, uint64_t y)
@@ -433,7 +433,7 @@ uint64_t HELPER(pacdb)(CPUARMState *env, uint64_t x, uint64_t y)
return x;
}
pauth_check_trap(env, el, GETPC());
- return pauth_addpac(env, x, y, &env->apdb_key, true);
+ return pauth_addpac(env, x, y, &env->keys.apdb, true);
}
uint64_t HELPER(pacga)(CPUARMState *env, uint64_t x, uint64_t y)
@@ -441,7 +441,7 @@ uint64_t HELPER(pacga)(CPUARMState *env, uint64_t x, uint64_t y)
uint64_t pac;
pauth_check_trap(env, arm_current_el(env), GETPC());
- pac = pauth_computepac(x, y, env->apga_key);
+ pac = pauth_computepac(x, y, env->keys.apga);
return pac & 0xffffffff00000000ull;
}
@@ -453,7 +453,7 @@ uint64_t HELPER(autia)(CPUARMState *env, uint64_t x, uint64_t y)
return x;
}
pauth_check_trap(env, el, GETPC());
- return pauth_auth(env, x, y, &env->apia_key, false, 0);
+ return pauth_auth(env, x, y, &env->keys.apia, false, 0);
}
uint64_t HELPER(autib)(CPUARMState *env, uint64_t x, uint64_t y)
@@ -463,7 +463,7 @@ uint64_t HELPER(autib)(CPUARMState *env, uint64_t x, uint64_t y)
return x;
}
pauth_check_trap(env, el, GETPC());
- return pauth_auth(env, x, y, &env->apib_key, false, 1);
+ return pauth_auth(env, x, y, &env->keys.apib, false, 1);
}
uint64_t HELPER(autda)(CPUARMState *env, uint64_t x, uint64_t y)
@@ -473,7 +473,7 @@ uint64_t HELPER(autda)(CPUARMState *env, uint64_t x, uint64_t y)
return x;
}
pauth_check_trap(env, el, GETPC());
- return pauth_auth(env, x, y, &env->apda_key, true, 0);
+ return pauth_auth(env, x, y, &env->keys.apda, true, 0);
}
uint64_t HELPER(autdb)(CPUARMState *env, uint64_t x, uint64_t y)
@@ -483,7 +483,7 @@ uint64_t HELPER(autdb)(CPUARMState *env, uint64_t x, uint64_t y)
return x;
}
pauth_check_trap(env, el, GETPC());
- return pauth_auth(env, x, y, &env->apdb_key, true, 1);
+ return pauth_auth(env, x, y, &env->keys.apdb, true, 1);
}
uint64_t HELPER(xpaci)(CPUARMState *env, uint64_t a)
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 22/25] target/arm: Implement ARMv8.5-RNG
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (20 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 21/25] target/arm: Put all PAC keys into a structure Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 23/25] target/ppc: Use qemu_guest_getrandom for DARN Richard Henderson
` (3 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v3: Log errors with -d unimp, for lack of a better flag.
v6: Add ARM_CP_IO for -icount.
---
target/arm/cpu.h | 5 +++++
target/arm/cpu64.c | 1 +
target/arm/helper.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 50 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 892f9a4ad2..c34207611b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3521,6 +3521,11 @@ static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
}
+static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
+}
+
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 228906f267..835f73cceb 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -310,6 +310,7 @@ static void aarch64_max_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
+ t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
cpu->isar.id_aa64isar0 = t;
t = cpu->isar.id_aa64isar1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7e88b2cadd..1e90f4d722 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -22,6 +22,8 @@
#include "fpu/softfloat.h"
#include "qemu/range.h"
#include "qapi/qapi-commands-target.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
@@ -5746,6 +5748,45 @@ static const ARMCPRegInfo pauth_reginfo[] = {
.fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
REGINFO_SENTINEL
};
+
+static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ Error *err = NULL;
+ uint64_t ret;
+
+ /* Success sets NZCV = 0000. */
+ env->NF = env->CF = env->VF = 0, env->ZF = 1;
+
+ if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
+ /*
+ * ??? Failed, for unknown reasons in the crypto subsystem.
+ * The best we can do is log the reason and return the
+ * timed-out indication to the guest. There is no reason
+ * we know to expect this failure to be transitory, so the
+ * guest may well hang retrying the operation.
+ */
+ qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
+ ri->name, error_get_pretty(err));
+ error_free(err);
+
+ env->ZF = 0; /* NZCF = 0100 */
+ return 0;
+ }
+ return ret;
+}
+
+/* We do not support re-seeding, so the two registers operate the same. */
+static const ARMCPRegInfo rndr_reginfo[] = {
+ { .name = "RNDR", .state = ARM_CP_STATE_AA64,
+ .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
+ .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 0,
+ .access = PL0_R, .readfn = rndr_readfn },
+ { .name = "RNDRRS", .state = ARM_CP_STATE_AA64,
+ .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
+ .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
+ .access = PL0_R, .readfn = rndr_readfn },
+ REGINFO_SENTINEL
+};
#endif
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -6690,6 +6731,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
if (cpu_isar_feature(aa64_pauth, cpu)) {
define_arm_cp_regs(cpu, pauth_reginfo);
}
+ if (cpu_isar_feature(aa64_rndr, cpu)) {
+ define_arm_cp_regs(cpu, rndr_reginfo);
+ }
#endif
/*
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 23/25] target/ppc: Use qemu_guest_getrandom for DARN
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (21 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 22/25] target/arm: Implement ARMv8.5-RNG Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 24/25] target/ppc: Use gen_io_start/end around DARN Richard Henderson
` (2 subsequent siblings)
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel
We now have an interface for guest visible random numbers.
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v5: Do not loop for darn64; use sizeof.
---
target/ppc/int_helper.c | 39 +++++++++++++++++++++++++++------------
1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index f6a088ac08..9af779ad38 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -23,6 +23,8 @@
#include "exec/helper-proto.h"
#include "crypto/aes.h"
#include "fpu/softfloat.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
#include "helper_regs.h"
/*****************************************************************************/
@@ -158,25 +160,38 @@ uint32_t helper_cmpeqb(target_ulong ra, target_ulong rb)
#undef hasvalue
/*
- * Return invalid random number.
- *
- * FIXME: Add rng backend or other mechanism to get cryptographically suitable
- * random number
+ * Return a random number.
*/
-target_ulong helper_darn32(void)
+uint64_t helper_darn32(void)
{
- return -1;
+ Error *err = NULL;
+ uint32_t ret;
+
+ if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
+ qemu_log_mask(LOG_UNIMP, "darn: Crypto failure: %s",
+ error_get_pretty(err));
+ error_free(err);
+ return -1;
+ }
+
+ return ret;
}
-target_ulong helper_darn64(void)
+uint64_t helper_darn64(void)
{
- return -1;
+ Error *err = NULL;
+ uint64_t ret;
+
+ if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
+ qemu_log_mask(LOG_UNIMP, "darn: Crypto failure: %s",
+ error_get_pretty(err));
+ error_free(err);
+ return -1;
+ }
+
+ return ret;
}
-#endif
-
-#if defined(TARGET_PPC64)
-
uint64_t helper_bpermd(uint64_t rs, uint64_t rb)
{
int i;
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 24/25] target/ppc: Use gen_io_start/end around DARN
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (22 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 23/25] target/ppc: Use qemu_guest_getrandom for DARN Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-13 1:38 ` David Gibson
` (2 more replies)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 25/25] target/i386: Implement CPUID_EXT_RDRAND Richard Henderson
2019-05-14 15:15 ` [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Markus Armbruster
25 siblings, 3 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel; +Cc: David Gibson
Generating a random number counts as I/O, as it cannot be
replayed and produce the same results.
Cc: David Gibson <david@gibson.dropbear.id.au>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/ppc/translate.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 8d08625c33..76628df6dd 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -1847,13 +1847,22 @@ static void gen_darn(DisasContext *ctx)
{
int l = L(ctx->opcode);
- if (l == 0) {
- gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
- } else if (l <= 2) {
- /* Return 64-bit random for both CRN and RRN */
- gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
- } else {
+ if (l > 2) {
tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1);
+ } else {
+ if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+ gen_io_start();
+ }
+ if (l == 0) {
+ gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
+ } else {
+ /* Return 64-bit random for both CRN and RRN */
+ gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
+ }
+ if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+ gen_io_end();
+ gen_stop_exception(ctx);
+ }
}
}
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 24/25] target/ppc: Use gen_io_start/end around DARN
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 24/25] target/ppc: Use gen_io_start/end around DARN Richard Henderson
@ 2019-05-13 1:38 ` David Gibson
2019-05-13 12:48 ` Laurent Vivier
2019-05-16 1:48 ` David Gibson
2 siblings, 0 replies; 36+ messages in thread
From: David Gibson @ 2019-05-13 1:38 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1862 bytes --]
On Fri, May 10, 2019 at 10:30:48AM -0700, Richard Henderson wrote:
> Generating a random number counts as I/O, as it cannot be
> replayed and produce the same results.
>
> Cc: David Gibson <david@gibson.dropbear.id.au>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> target/ppc/translate.c | 21 +++++++++++++++------
> 1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 8d08625c33..76628df6dd 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -1847,13 +1847,22 @@ static void gen_darn(DisasContext *ctx)
> {
> int l = L(ctx->opcode);
>
> - if (l == 0) {
> - gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
> - } else if (l <= 2) {
> - /* Return 64-bit random for both CRN and RRN */
> - gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
> - } else {
> + if (l > 2) {
> tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1);
> + } else {
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_start();
> + }
> + if (l == 0) {
> + gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
> + } else {
> + /* Return 64-bit random for both CRN and RRN */
> + gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
> + }
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_end();
> + gen_stop_exception(ctx);
> + }
> }
> }
> #endif
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 24/25] target/ppc: Use gen_io_start/end around DARN
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 24/25] target/ppc: Use gen_io_start/end around DARN Richard Henderson
2019-05-13 1:38 ` David Gibson
@ 2019-05-13 12:48 ` Laurent Vivier
2019-05-16 1:48 ` David Gibson
2 siblings, 0 replies; 36+ messages in thread
From: Laurent Vivier @ 2019-05-13 12:48 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: David Gibson
On 10/05/2019 19:30, Richard Henderson wrote:
> Generating a random number counts as I/O, as it cannot be
> replayed and produce the same results.
>
> Cc: David Gibson <david@gibson.dropbear.id.au>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/ppc/translate.c | 21 +++++++++++++++------
> 1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 8d08625c33..76628df6dd 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -1847,13 +1847,22 @@ static void gen_darn(DisasContext *ctx)
> {
> int l = L(ctx->opcode);
>
> - if (l == 0) {
> - gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
> - } else if (l <= 2) {
> - /* Return 64-bit random for both CRN and RRN */
> - gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
> - } else {
> + if (l > 2) {
> tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1);
> + } else {
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_start();
> + }
> + if (l == 0) {
> + gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
> + } else {
> + /* Return 64-bit random for both CRN and RRN */
> + gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
> + }
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_end();
> + gen_stop_exception(ctx);
> + }
> }
> }
> #endif
>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 24/25] target/ppc: Use gen_io_start/end around DARN
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 24/25] target/ppc: Use gen_io_start/end around DARN Richard Henderson
2019-05-13 1:38 ` David Gibson
2019-05-13 12:48 ` Laurent Vivier
@ 2019-05-16 1:48 ` David Gibson
2 siblings, 0 replies; 36+ messages in thread
From: David Gibson @ 2019-05-16 1:48 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1862 bytes --]
On Fri, May 10, 2019 at 10:30:48AM -0700, Richard Henderson wrote:
> Generating a random number counts as I/O, as it cannot be
> replayed and produce the same results.
>
> Cc: David Gibson <david@gibson.dropbear.id.au>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> target/ppc/translate.c | 21 +++++++++++++++------
> 1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 8d08625c33..76628df6dd 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -1847,13 +1847,22 @@ static void gen_darn(DisasContext *ctx)
> {
> int l = L(ctx->opcode);
>
> - if (l == 0) {
> - gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
> - } else if (l <= 2) {
> - /* Return 64-bit random for both CRN and RRN */
> - gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
> - } else {
> + if (l > 2) {
> tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1);
> + } else {
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_start();
> + }
> + if (l == 0) {
> + gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
> + } else {
> + /* Return 64-bit random for both CRN and RRN */
> + gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
> + }
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_end();
> + gen_stop_exception(ctx);
> + }
> }
> }
> #endif
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v6 25/25] target/i386: Implement CPUID_EXT_RDRAND
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (23 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 24/25] target/ppc: Use gen_io_start/end around DARN Richard Henderson
@ 2019-05-10 17:30 ` Richard Henderson
2019-05-14 15:15 ` [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Markus Armbruster
25 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-10 17:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini
We now have an interface for guest visible random numbers.
Cc: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v6: Add gen_io_start/end for -icount.
---
target/i386/helper.h | 2 ++
target/i386/cpu.c | 5 ++--
target/i386/int_helper.c | 21 ++++++++++++++
target/i386/translate.c | 62 ++++++++++++++++++++++++++++++----------
4 files changed, 73 insertions(+), 17 deletions(-)
diff --git a/target/i386/helper.h b/target/i386/helper.h
index 6fb8fb9b74..8f9e1905c3 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -226,3 +226,5 @@ DEF_HELPER_3(rcrl, tl, env, tl, tl)
DEF_HELPER_3(rclq, tl, env, tl, tl)
DEF_HELPER_3(rcrq, tl, env, tl, tl)
#endif
+
+DEF_HELPER_1(rdrand, tl, env)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 722c5514d4..1386814957 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -730,13 +730,14 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \
- CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
+ CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \
+ CPUID_EXT_RDRAND)
/* missing:
CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
- CPUID_EXT_F16C, CPUID_EXT_RDRAND */
+ CPUID_EXT_F16C */
#ifdef TARGET_X86_64
#define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
diff --git a/target/i386/int_helper.c b/target/i386/int_helper.c
index 4dc5c65991..334469ca8c 100644
--- a/target/i386/int_helper.c
+++ b/target/i386/int_helper.c
@@ -22,6 +22,8 @@
#include "exec/exec-all.h"
#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
//#define DEBUG_MULDIV
@@ -470,3 +472,22 @@ void helper_cr4_testbit(CPUX86State *env, uint32_t bit)
raise_exception_ra(env, EXCP06_ILLOP, GETPC());
}
}
+
+target_ulong HELPER(rdrand)(CPUX86State *env)
+{
+ Error *err = NULL;
+ target_ulong ret;
+
+ if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
+ qemu_log_mask(LOG_UNIMP, "rdrand: Crypto failure: %s",
+ error_get_pretty(err));
+ error_free(err);
+ /* Failure clears CF and all other flags, and returns 0. */
+ env->cc_src = 0;
+ return 0;
+ }
+
+ /* Success sets CF and clears all others. */
+ env->cc_src = CC_C;
+ return ret;
+}
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 77d6b73e42..03150a86e2 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -5332,31 +5332,63 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x1c7: /* cmpxchg8b */
modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3;
- if ((mod == 3) || ((modrm & 0x38) != 0x8))
- goto illegal_op;
-#ifdef TARGET_X86_64
- if (dflag == MO_64) {
- if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
+ switch ((modrm >> 3) & 7) {
+ case 1: /* CMPXCHG8, CMPXCHG16 */
+ if (mod == 3) {
goto illegal_op;
- gen_lea_modrm(env, s, modrm);
- if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) & CF_PARALLEL)) {
- gen_helper_cmpxchg16b(cpu_env, s->A0);
- } else {
- gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
}
- } else
+#ifdef TARGET_X86_64
+ if (dflag == MO_64) {
+ if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
+ goto illegal_op;
+ }
+ gen_lea_modrm(env, s, modrm);
+ if ((s->prefix & PREFIX_LOCK) &&
+ (tb_cflags(s->base.tb) & CF_PARALLEL)) {
+ gen_helper_cmpxchg16b(cpu_env, s->A0);
+ } else {
+ gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
+ }
+ set_cc_op(s, CC_OP_EFLAGS);
+ break;
+ }
#endif
- {
- if (!(s->cpuid_features & CPUID_CX8))
+ if (!(s->cpuid_features & CPUID_CX8)) {
goto illegal_op;
+ }
gen_lea_modrm(env, s, modrm);
- if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) & CF_PARALLEL)) {
+ if ((s->prefix & PREFIX_LOCK) &&
+ (tb_cflags(s->base.tb) & CF_PARALLEL)) {
gen_helper_cmpxchg8b(cpu_env, s->A0);
} else {
gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0);
}
+ set_cc_op(s, CC_OP_EFLAGS);
+ break;
+
+ case 7: /* RDSEED */
+ case 6: /* RDRAND */
+ if (mod != 3 ||
+ (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) ||
+ !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
+ goto illegal_op;
+ }
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+ gen_io_start();
+ }
+ gen_helper_rdrand(s->T0, cpu_env);
+ rm = (modrm & 7) | REX_B(s);
+ gen_op_mov_reg_v(s, dflag, rm, s->T0);
+ set_cc_op(s, CC_OP_EFLAGS);
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+ gen_io_end();
+ gen_jmp(s, s->pc - s->cs_base);
+ }
+ break;
+
+ default:
+ goto illegal_op;
}
- set_cc_op(s, CC_OP_EFLAGS);
break;
/**************************/
--
2.17.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc
2019-05-10 17:30 [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Richard Henderson
` (24 preceding siblings ...)
2019-05-10 17:30 ` [Qemu-devel] [PATCH v6 25/25] target/i386: Implement CPUID_EXT_RDRAND Richard Henderson
@ 2019-05-14 15:15 ` Markus Armbruster
2019-05-14 15:23 ` Daniel P. Berrangé
25 siblings, 1 reply; 36+ messages in thread
From: Markus Armbruster @ 2019-05-14 15:15 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
"make check-unit" fails for me:
TEST check-unit: tests/test-crypto-tlscredsx509
Unexpected error in object_new_with_propv() at /work/armbru/qemu/qom/object.c:674:
invalid object type: tls-creds-x509
and
TEST check-unit: tests/test-io-channel-tls
Unexpected error in object_new_with_propv() at /work/armbru/qemu/qom/object.c:674:
invalid object type: tls-creds-x509
I haven't looked further.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc
2019-05-14 15:15 ` [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc Markus Armbruster
@ 2019-05-14 15:23 ` Daniel P. Berrangé
2019-05-14 16:14 ` Richard Henderson
0 siblings, 1 reply; 36+ messages in thread
From: Daniel P. Berrangé @ 2019-05-14 15:23 UTC (permalink / raw)
To: Markus Armbruster; +Cc: Richard Henderson, qemu-devel
On Tue, May 14, 2019 at 05:15:31PM +0200, Markus Armbruster wrote:
> "make check-unit" fails for me:
>
> TEST check-unit: tests/test-crypto-tlscredsx509
> Unexpected error in object_new_with_propv() at /work/armbru/qemu/qom/object.c:674:
> invalid object type: tls-creds-x509
>
> and
>
> TEST check-unit: tests/test-io-channel-tls
> Unexpected error in object_new_with_propv() at /work/armbru/qemu/qom/object.c:674:
> invalid object type: tls-creds-x509
>
> I haven't looked further.
I have a nasty feeling it is caused by
Subject: [PATCH v6 02/25] crypto: Merge crypto-obj-y into libqemuutil.a
The QOM objects are not directly used by most of the code. We rely on
the constructor registering the QOM object and then we request an
instance of it via the type name. So there's no direct function calls
from any code into the crypto object impls.
When we put the crypto objects into libqemuutil.a the linker is not
intelligent enough to see the constructor and so thinks all these
QOM object impls are unused and discards them when linking the final
binary.
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc
2019-05-14 15:23 ` Daniel P. Berrangé
@ 2019-05-14 16:14 ` Richard Henderson
2019-05-14 16:50 ` Daniel P. Berrangé
0 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2019-05-14 16:14 UTC (permalink / raw)
To: Daniel P. Berrangé, Markus Armbruster; +Cc: qemu-devel
On 5/14/19 8:23 AM, Daniel P. Berrangé wrote:
> On Tue, May 14, 2019 at 05:15:31PM +0200, Markus Armbruster wrote:
>> "make check-unit" fails for me:
>>
>> TEST check-unit: tests/test-crypto-tlscredsx509
>> Unexpected error in object_new_with_propv() at /work/armbru/qemu/qom/object.c:674:
>> invalid object type: tls-creds-x509
>>
>> and
>>
>> TEST check-unit: tests/test-io-channel-tls
>> Unexpected error in object_new_with_propv() at /work/armbru/qemu/qom/object.c:674:
>> invalid object type: tls-creds-x509
>>
>> I haven't looked further.
>
> I have a nasty feeling it is caused by
>
> Subject: [PATCH v6 02/25] crypto: Merge crypto-obj-y into libqemuutil.a
>
> The QOM objects are not directly used by most of the code. We rely on
> the constructor registering the QOM object and then we request an
> instance of it via the type name. So there's no direct function calls
> from any code into the crypto object impls.
>
> When we put the crypto objects into libqemuutil.a the linker is not
> intelligent enough to see the constructor and so thinks all these
> QOM object impls are unused and discards them when linking the final
> binary.
Yes, that would do it. We would need something in the test that forces the
objects into the link. Without having yet looked at the test cases, any ideas?
r~
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc
2019-05-14 16:14 ` Richard Henderson
@ 2019-05-14 16:50 ` Daniel P. Berrangé
2019-05-14 17:46 ` Richard Henderson
0 siblings, 1 reply; 36+ messages in thread
From: Daniel P. Berrangé @ 2019-05-14 16:50 UTC (permalink / raw)
To: Richard Henderson; +Cc: Markus Armbruster, qemu-devel
On Tue, May 14, 2019 at 09:14:57AM -0700, Richard Henderson wrote:
> On 5/14/19 8:23 AM, Daniel P. Berrangé wrote:
> > On Tue, May 14, 2019 at 05:15:31PM +0200, Markus Armbruster wrote:
> >> "make check-unit" fails for me:
> >>
> >> TEST check-unit: tests/test-crypto-tlscredsx509
> >> Unexpected error in object_new_with_propv() at /work/armbru/qemu/qom/object.c:674:
> >> invalid object type: tls-creds-x509
> >>
> >> and
> >>
> >> TEST check-unit: tests/test-io-channel-tls
> >> Unexpected error in object_new_with_propv() at /work/armbru/qemu/qom/object.c:674:
> >> invalid object type: tls-creds-x509
> >>
> >> I haven't looked further.
> >
> > I have a nasty feeling it is caused by
> >
> > Subject: [PATCH v6 02/25] crypto: Merge crypto-obj-y into libqemuutil.a
> >
> > The QOM objects are not directly used by most of the code. We rely on
> > the constructor registering the QOM object and then we request an
> > instance of it via the type name. So there's no direct function calls
> > from any code into the crypto object impls.
> >
> > When we put the crypto objects into libqemuutil.a the linker is not
> > intelligent enough to see the constructor and so thinks all these
> > QOM object impls are unused and discards them when linking the final
> > binary.
>
> Yes, that would do it. We would need something in the test that forces the
> objects into the link. Without having yet looked at the test cases, any ideas?
I don't think this is only the test suite. I think it will affect all the
binaries we build
The only way you can force it is to use -Wl,--whole-archive arg to tell ld
to include everything from libqemuutil.la, but that will break the way
the stubs work, as we want make of the stubs to be discarded.
The only other option is to not build $(crypto-obj-y) into libqemuutil.la,
but list that variable explicitly everywhere that we list libqemuutil.la
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc
2019-05-14 16:50 ` Daniel P. Berrangé
@ 2019-05-14 17:46 ` Richard Henderson
2019-05-14 21:43 ` Eric Blake
0 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2019-05-14 17:46 UTC (permalink / raw)
To: Daniel P. Berrangé; +Cc: Markus Armbruster, qemu-devel
On 5/14/19 9:50 AM, Daniel P. Berrangé wrote:
> On Tue, May 14, 2019 at 09:14:57AM -0700, Richard Henderson wrote:
>> Yes, that would do it. We would need something in the test that forces the
>> objects into the link. Without having yet looked at the test cases, any ideas?
>
> I don't think this is only the test suite. I think it will affect all the
> binaries we build
You're right, it does.
$ nm aarch64-softmmu/qemu-system-aarch64 \
| grep qcrypto_tls_creds_x509_register_types
comes up empty.
It didn't occur to me that there was nothing in the object files for the
reference. I'll have to drop the crypto-obj-y patch and come up with a
different solution.
r~
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc
2019-05-14 17:46 ` Richard Henderson
@ 2019-05-14 21:43 ` Eric Blake
2019-05-14 23:22 ` Richard Henderson
0 siblings, 1 reply; 36+ messages in thread
From: Eric Blake @ 2019-05-14 21:43 UTC (permalink / raw)
To: Richard Henderson, Daniel P. Berrangé; +Cc: Markus Armbruster, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1464 bytes --]
On 5/14/19 12:46 PM, Richard Henderson wrote:
> On 5/14/19 9:50 AM, Daniel P. Berrangé wrote:
>> On Tue, May 14, 2019 at 09:14:57AM -0700, Richard Henderson wrote:
>>> Yes, that would do it. We would need something in the test that forces the
>>> objects into the link. Without having yet looked at the test cases, any ideas?
>>
>> I don't think this is only the test suite. I think it will affect all the
>> binaries we build
>
> You're right, it does.
>
> $ nm aarch64-softmmu/qemu-system-aarch64 \
> | grep qcrypto_tls_creds_x509_register_types
>
> comes up empty.
>
> It didn't occur to me that there was nothing in the object files for the
> reference. I'll have to drop the crypto-obj-y patch and come up with a
> different solution.
Isn't there a gcc annotation for marking a simple as mandatorily
included during link?
/me goes looking...
__attribute__((externally_visible)) sounds promising (it nullifies the
effects of -fwhole-program, so that a function remains visible even if
the linker would have otherwise suppressed it)
__attribute__((used)) also sounds useful (the function must be emitted
even if it does not appear to be referenced, which may be enough for the
linker to infer that it is used)
There may be other tricks, although I didn't go searching very hard.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization: qemu.org | libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v6 00/25] Add qemu_getrandom and ARMv8.5-RNG etc
2019-05-14 21:43 ` Eric Blake
@ 2019-05-14 23:22 ` Richard Henderson
0 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2019-05-14 23:22 UTC (permalink / raw)
To: Eric Blake, Daniel P. Berrangé; +Cc: Markus Armbruster, qemu-devel
On 5/14/19 2:43 PM, Eric Blake wrote:
>> It didn't occur to me that there was nothing in the object files for the
>> reference. I'll have to drop the crypto-obj-y patch and come up with a
>> different solution.
>
> Isn't there a gcc annotation for marking a simple as mandatorily
> included during link?
No.
There's stuff you can mark a single function within an object file that you can
use to avoid the function being elided...
> __attribute__((externally_visible)) sounds promising (it nullifies the
> effects of -fwhole-program, so that a function remains visible even if
> the linker would have otherwise suppressed it)
>
> __attribute__((used)) also sounds useful (the function must be emitted
> even if it does not appear to be referenced, which may be enough for the
> linker to infer that it is used)
... and you found those. But those do not affect the linker's behaviour with
.a files at all.
You can force a symbol reference from the ld command-line: -u sym, which can
cause the .o containing sym to be included from the .a file. But that doesn't
work if there's no global symbol in the .o to reference.
You can force all .o from a .a file to be included, with --whole-archive. That
is useful when you're using .a files a shorthand for lots and lots of .o files.
But in our case that would break the use of stubs.
Anyway, see v7 now.
r~
^ permalink raw reply [flat|nested] 36+ messages in thread