diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2019-08-13 21:32:44 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2019-09-08 16:05:34 +0000 |
commit | 5cea83a8a2fc3384bb07a7265c8d907171cb1ea4 (patch) | |
tree | 035272822295d3e6099b9afcf90e9730fce7c573 | |
parent | 72a04b132c346a61e0a46f39df977e56306fc84c (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.cpp | 19 |
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: |