diff options
Diffstat (limited to 'src/Core/RandomNumberGenerator.cpp')
-rw-r--r-- | src/Core/RandomNumberGenerator.cpp | 60 |
1 files changed, 39 insertions, 21 deletions
diff --git a/src/Core/RandomNumberGenerator.cpp b/src/Core/RandomNumberGenerator.cpp index ab3aad6b..ae0f8248 100644 --- a/src/Core/RandomNumberGenerator.cpp +++ b/src/Core/RandomNumberGenerator.cpp @@ -65,45 +65,63 @@ namespace VeraCrypt } } - void RandomNumberGenerator::GetData (const BufferPtr &buffer, bool fast) + void RandomNumberGenerator::GetData (const BufferPtr &buffer, bool fast, bool allowAnyLength) { if (!Running) throw NotInitialized (SRC_POS); - if (buffer.Size() > PoolSize) + if (!allowAnyLength && (buffer.Size() > PoolSize)) throw ParameterIncorrect (SRC_POS); ScopeLock lock (AccessMutex); + size_t bufferLen = buffer.Size(), loopLen; + byte* pbBuffer = buffer.Get(); // Poll system for data AddSystemDataToPool (fast); HashMixPool(); - // Transfer bytes from pool to output buffer - for (size_t i = 0; i < buffer.Size(); ++i) + while (bufferLen > 0) { - buffer[i] += Pool[ReadOffset++]; + if (bufferLen > PoolSize) + { + loopLen = PoolSize; + bufferLen -= PoolSize; + } + else + { + loopLen = bufferLen; + bufferLen = 0; + } - if (ReadOffset >= PoolSize) - ReadOffset = 0; - } + // Transfer bytes from pool to output buffer + for (size_t i = 0; i < loopLen; ++i) + { + pbBuffer[i] += Pool[ReadOffset++]; - // Invert and mix the pool - for (size_t i = 0; i < Pool.Size(); ++i) - { - Pool[i] = ~Pool[i]; - } + if (ReadOffset >= PoolSize) + ReadOffset = 0; + } - AddSystemDataToPool (true); - HashMixPool(); + // Invert and mix the pool + for (size_t i = 0; i < Pool.Size(); ++i) + { + Pool[i] = ~Pool[i]; + } - // XOR the current pool content into the output buffer to prevent pool state leaks - for (size_t i = 0; i < buffer.Size(); ++i) - { - buffer[i] ^= Pool[ReadOffset++]; + AddSystemDataToPool (true); + HashMixPool(); + + // XOR the current pool content into the output buffer to prevent pool state leaks + for (size_t i = 0; i < loopLen; ++i) + { + pbBuffer[i] ^= Pool[ReadOffset++]; - if (ReadOffset >= PoolSize) - ReadOffset = 0; + if (ReadOffset >= PoolSize) + ReadOffset = 0; + } + + pbBuffer += loopLen; } } |