summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2019-08-13 21:32:44 -0700
committerThiago Macieira <thiago.macieira@intel.com>2019-09-08 16:05:34 +0000
commit5cea83a8a2fc3384bb07a7265c8d907171cb1ea4 (patch)
tree035272822295d3e6099b9afcf90e9730fce7c573
parent72a04b132c346a61e0a46f39df977e56306fc84c (diff)
QRandom: retry the use of RDRAND instruction as recommended by manuals
The Intel whitepaper[1] recommends retrying RDRAND some 10 times even after it fails, since the hardware has a fairness algorithm and reseeds itself quite quickly. [1] https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide Change-Id: I907a43cd9a714da288a2fffd15baafd88242d8b6 Reviewed-by: André Hartmann <aha_1980@gmx.de>
-rw-r--r--src/corelib/global/qrandom.cpp19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index bf01b7ae2a..fa26d54afa 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -103,17 +103,22 @@ static QT_FUNCTION_TARGET(RDRND) qsizetype qt_random_cpu(void *buffer, qsizetype
{
unsigned *ptr = reinterpret_cast<unsigned *>(buffer);
unsigned *end = ptr + count;
+ int retries = 10;
while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) {
- if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)) == 0)
+ if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)))
+ ptr += sizeof(qregisteruint)/sizeof(*ptr);
+ else if (--retries == 0)
goto out;
- ptr += sizeof(qregisteruint)/sizeof(*ptr);
}
- if (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
- if (_rdrand32_step(ptr))
- goto out;
- ++ptr;
+ while (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
+ bool ok = _rdrand32_step(ptr);
+ if (!ok && --retries)
+ continue;
+ if (ok)
+ ++ptr;
+ break;
}
out: