Ejemplo n.º 1
0
/* 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 ( void* hwndDlg, unsigned char *buf , int len, BOOL forceSlowPoll , BOOL allowAnyLength)
{
	int i, looplen;
	BOOL ret = TRUE;

	if (!bRandDidInit || HashFunction == 0)
		TC_THROW_FATAL_EXCEPTION;

	EnterCriticalSection (&critRandProt);

	if (bDidSlowPoll == FALSE || forceSlowPoll)
	{
		if (!SlowPoll ())
		{
			handleError ((HWND) hwndDlg, ERR_CAPI_INIT_FAILED, SRC_POS);
			ret = FALSE;
		}
		else
			bDidSlowPoll = TRUE;
	}

	if (!FastPoll ())
	{
		handleError ((HWND) hwndDlg, ERR_CAPI_INIT_FAILED, SRC_POS);
		ret = FALSE;
	}

	/* There's never more than RNG_POOL_SIZE worth of randomess */
	if ( (!allowAnyLength) && (len > RNG_POOL_SIZE))
	{
		Error ("ERR_NOT_ENOUGH_RANDOM_DATA", (HWND) hwndDlg);	
		len = RNG_POOL_SIZE;
		LeaveCriticalSection (&critRandProt);
		return FALSE;
	}

	while (len > 0)
	{
		if (len > RNG_POOL_SIZE)
		{
			looplen = RNG_POOL_SIZE;
			len -= RNG_POOL_SIZE;
		}
		else
		{
			looplen = len;
			len = 0;
		}

		// 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;
		}

		/* Invert the pool */
		for (i = 0; i < RNG_POOL_SIZE / 4; i++)
		{
			((unsigned __int32 *) pRandPool)[i] = ~((unsigned __int32 *) pRandPool)[i];
		}

		// 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);

	if (!ret)
		TC_THROW_FATAL_EXCEPTION;

	return ret;
}
Ejemplo n.º 2
0
/* 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;
	BOOL ret = TRUE;

	if (!bRandDidInit || HashFunction == 0)
		TC_THROW_FATAL_EXCEPTION;

	EnterCriticalSection (&critRandProt);

	if (bDidSlowPoll == FALSE || forceSlowPoll)
	{
		if (!SlowPoll ())
			ret = FALSE;
		else
			bDidSlowPoll = TRUE;
	}

	if (!FastPoll ())
		ret = FALSE;

	/* There's never more than RNG_POOL_SIZE worth of randomess */
	if (len > RNG_POOL_SIZE)
	{
		Error ("ERR_NOT_ENOUGH_RANDOM_DATA");	
		len = RNG_POOL_SIZE;
		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++)
	{
		buf[i] = pRandPool[randPoolReadIndex++];
		if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
	}

	/* Invert the pool */
	for (i = 0; i < RNG_POOL_SIZE / 4; i++)
	{
		((unsigned __int32 *) pRandPool)[i] = ~((unsigned __int32 *) pRandPool)[i];
	}

	// 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 < len; i++)
	{
		buf[i] ^= pRandPool[randPoolReadIndex++];
		if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
	}

	LeaveCriticalSection (&critRandProt);

	if (!ret)
		TC_THROW_FATAL_EXCEPTION;

	return ret;
}