From 32e72d111747bcfee8ba0ecfb30045b6cd42685f Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Mon, 8 Dec 2014 23:41:29 +0100 Subject: Implement function RandgetBytesFull that enables generating random bytes of any length. --- src/Common/Random.c | 68 ++++++++++++++++++++++++++++++++++++----------------- src/Common/Random.h | 8 +++++++ 2 files changed, 55 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); diff --git a/src/Common/Random.h b/src/Common/Random.h index ffb443ad..1a3a51d8 100644 --- a/src/Common/Random.h +++ b/src/Common/Random.h @@ -44,8 +44,16 @@ void RandaddBuf ( void *buf , int len ); BOOL FastPoll ( void ); BOOL SlowPoll ( void ); 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 ); +/* 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); + #ifdef _WIN32 extern BOOL volatile bFastPollEnabled; -- cgit v1.2.3