diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2014-12-08 23:41:29 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2014-12-11 18:31:30 +0100 |
commit | 32e72d111747bcfee8ba0ecfb30045b6cd42685f (patch) | |
tree | b21c674e1dbecd055d8904ce554c549d918140e3 /src/Common/Random.c | |
parent | fd0e434087ee51d8bc7be6ea1287685d91dc4b1e (diff) | |
download | VeraCrypt-32e72d111747bcfee8ba0ecfb30045b6cd42685f.tar.gz VeraCrypt-32e72d111747bcfee8ba0ecfb30045b6cd42685f.zip |
Implement function RandgetBytesFull that enables generating random bytes of any length.
Diffstat (limited to 'src/Common/Random.c')
-rw-r--r-- | src/Common/Random.c | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/src/Common/Random.c b/src/Common/Random.c index 76ff6b61..f7379685 100644 --- a/src/Common/Random.c +++ b/src/Common/Random.c @@ -339,7 +339,16 @@ BOOL RandpeekBytes (unsigned char *buf, int len) /* Get len random bytes from the pool (max. RNG_POOL_SIZE bytes per a single call) */
BOOL RandgetBytes (unsigned char *buf, int len, BOOL forceSlowPoll)
{
- int i;
+ return RandgetBytesFull (buf, len, forceSlowPoll, FALSE);
+}
+
+/* Get len random bytes from the pool.
+ * If allowAnyLength is FALSE, then len must be less or equal to RNG_POOL_SIZE
+ * If allowAnyLength is TRUE, then len can have any positive value
+ */
+BOOL RandgetBytesFull ( unsigned char *buf , int len, BOOL forceSlowPoll , BOOL allowAnyLength)
+{
+ int i, looplen;
BOOL ret = TRUE;
if (!bRandDidInit || HashFunction == 0)
@@ -359,7 +368,7 @@ BOOL RandgetBytes (unsigned char *buf, int len, BOOL forceSlowPoll) ret = FALSE;
/* There's never more than RNG_POOL_SIZE worth of randomess */
- if (len > RNG_POOL_SIZE)
+ if ( (!allowAnyLength) && (len > RNG_POOL_SIZE))
{
Error ("ERR_NOT_ENOUGH_RANDOM_DATA");
len = RNG_POOL_SIZE;
@@ -367,29 +376,46 @@ BOOL RandgetBytes (unsigned char *buf, int len, BOOL forceSlowPoll) return FALSE;
}
- // Requested number of bytes is copied from pool to output buffer,
- // pool is rehashed, and output buffer is XORed with new data from pool
- for (i = 0; i < len; i++)
+ while (len > 0)
{
- buf[i] = pRandPool[randPoolReadIndex++];
- if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
- }
+ if (len > RNG_POOL_SIZE)
+ {
+ looplen = RNG_POOL_SIZE;
+ len -= RNG_POOL_SIZE;
+ }
+ else
+ {
+ looplen = len;
+ len = 0;
+ }
- /* Invert the pool */
- for (i = 0; i < RNG_POOL_SIZE / 4; i++)
- {
- ((unsigned __int32 *) pRandPool)[i] = ~((unsigned __int32 *) pRandPool)[i];
- }
+ // this loop number of bytes is copied from pool to output buffer,
+ // pool is rehashed, and output buffer is XORed with new data from pool
+ for (i = 0; i < looplen; i++)
+ {
+ buf[i] = pRandPool[randPoolReadIndex++];
+ if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
+ }
- // Mix the pool
- if (!FastPoll ())
- ret = FALSE;
+ /* Invert the pool */
+ for (i = 0; i < RNG_POOL_SIZE / 4; i++)
+ {
+ ((unsigned __int32 *) pRandPool)[i] = ~((unsigned __int32 *) pRandPool)[i];
+ }
- // XOR the current pool content into the output buffer to prevent pool state leaks
- for (i = 0; i < len; i++)
- {
- buf[i] ^= pRandPool[randPoolReadIndex++];
- if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
+ // Mix the pool
+ if (!FastPoll ())
+ ret = FALSE;
+
+ // XOR the current pool content into the output buffer to prevent pool state leaks
+ for (i = 0; i < looplen; i++)
+ {
+ buf[i] ^= pRandPool[randPoolReadIndex++];
+ if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
+ }
+
+ // increment the pointer for the next loop
+ buf += looplen;
}
LeaveCriticalSection (&critRandProt);
|