VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Core/RandomNumberGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Core/RandomNumberGenerator.cpp')
-rw-r--r--src/Core/RandomNumberGenerator.cpp60
1 files changed, 39 insertions, 21 deletions
diff --git a/src/Core/RandomNumberGenerator.cpp b/src/Core/RandomNumberGenerator.cpp
index ab3aad6..ae0f824 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;
}
}