diff options
Diffstat (limited to 'src/Core/RandomNumberGenerator.cpp')
-rw-r--r-- | src/Core/RandomNumberGenerator.cpp | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/src/Core/RandomNumberGenerator.cpp b/src/Core/RandomNumberGenerator.cpp index 38a228ee..3fb6062a 100644 --- a/src/Core/RandomNumberGenerator.cpp +++ b/src/Core/RandomNumberGenerator.cpp @@ -14,6 +14,11 @@ #include <sys/types.h> #include <errno.h> #include <fcntl.h> + +#ifndef ERESTART +#define ERESTART EINTR +#endif + #endif #include "RandomNumberGenerator.h" @@ -49,22 +54,20 @@ namespace VeraCrypt { int rndCount = read (random, buffer, buffer.Size()); throw_sys_sub_if ((rndCount == -1) && errno != EAGAIN && errno != ERESTART && errno != EINTR, L"/dev/random"); - if (rndCount == -1 && (!DevRandomSucceeded || (DevRandomBytesCount < 32))) - { - // wait 250ms before querying /dev/random again - ::usleep (250 * 1000); + if (rndCount != -1) { + // We count returned bytes until 32-bytes threshold reached + if (DevRandomBytesCount < 32) + DevRandomBytesCount += rndCount; + break; } - else - { - if (rndCount != -1) - { - // We count returned bytes untill 32-bytes treshold reached - if (DevRandomBytesCount < 32) - DevRandomBytesCount += rndCount; - DevRandomSucceeded = true; - } + else if (DevRandomBytesCount >= 32) { + // allow /dev/random to fail gracefully since we have enough bytes break; } + else { + // wait 250ms before querying /dev/random again + ::usleep (250 * 1000); + } } AddToPool (buffer); @@ -182,18 +185,26 @@ namespace VeraCrypt void RandomNumberGenerator::HashMixPool () { BytesAddedSincePoolHashMix = 0; - - for (size_t poolPos = 0; poolPos < Pool.Size(); ) + size_t digestSize = PoolHash->GetDigestSize(); + size_t poolSize = Pool.Size(); + // pool size must be multiple of digest size + // this is always the case with default pool size value (320 bytes) + if (poolSize % digestSize) + throw AssertionFailed (SRC_POS); + + for (size_t poolPos = 0; poolPos < poolSize; poolPos += digestSize) { // Compute the message digest of the entire pool using the selected hash function - SecureBuffer digest (PoolHash->GetDigestSize()); + SecureBuffer digest (digestSize); + PoolHash->Init(); PoolHash->ProcessData (Pool); PoolHash->GetDigest (digest); - // Add the message digest to the pool - for (size_t digestPos = 0; digestPos < digest.Size() && poolPos < Pool.Size(); ++digestPos) + /* XOR the resultant message digest to the pool at the poolIndex position. */ + /* this matches the documentation: https://veracrypt.fr/en/Random%20Number%20Generator.html */ + for (size_t digestIndex = 0; digestIndex < digestSize; digestIndex++) { - Pool[poolPos++] += digest[digestPos]; + Pool [poolPos + digestIndex] ^= digest [digestIndex]; } } } @@ -240,14 +251,17 @@ namespace VeraCrypt EnrichedByUser = false; Running = false; - DevRandomSucceeded = false; DevRandomBytesCount = 0; } void RandomNumberGenerator::Test () { shared_ptr <Hash> origPoolHash = PoolHash; - PoolHash.reset (new Ripemd160()); + #ifndef WOLFCRYPT_BACKEND + PoolHash.reset (new Blake2s()); + #else + PoolHash.reset (new Sha256()); + #endif Pool.Zero(); Buffer buffer (1); @@ -257,15 +271,23 @@ namespace VeraCrypt AddToPool (buffer); } - if (Crc32::ProcessBuffer (Pool) != 0x2de46d17) - throw TestFailed (SRC_POS); + #ifndef WOLFCRYPT_BACKEND + if (Crc32::ProcessBuffer (Pool) != 0x9c743238) + #else + if (Crc32::ProcessBuffer (Pool) != 0xac95ac1a) + #endif + throw TestFailed (SRC_POS); buffer.Allocate (PoolSize); buffer.CopyFrom (PeekPool()); AddToPool (buffer); - if (Crc32::ProcessBuffer (Pool) != 0xcb88e019) - throw TestFailed (SRC_POS); + #ifndef WOLFCRYPT_BACKEND + if (Crc32::ProcessBuffer (Pool) != 0xd2d09c8d) + #else + if (Crc32::ProcessBuffer (Pool) != 0xb79f3c12) + #endif + throw TestFailed (SRC_POS); PoolHash = origPoolHash; } @@ -279,6 +301,5 @@ namespace VeraCrypt bool RandomNumberGenerator::Running = false; size_t RandomNumberGenerator::WriteOffset; struct rand_data *RandomNumberGenerator::JitterRngCtx = NULL; - bool RandomNumberGenerator::DevRandomSucceeded = false; int RandomNumberGenerator::DevRandomBytesCount = 0; } |