diff --git a/crypto/src/crypto/prng/SP800SecureRandom.cs b/crypto/src/crypto/prng/SP800SecureRandom.cs
index 30c838c1b..2e1484125 100644
--- a/crypto/src/crypto/prng/SP800SecureRandom.cs
+++ b/crypto/src/crypto/prng/SP800SecureRandom.cs
@@ -49,6 +49,11 @@ namespace Org.BouncyCastle.Crypto.Prng
public override void NextBytes(byte[] bytes)
{
+ NextBytes(bytes, 0, bytes.Length);
+ }
+
+ public override void NextBytes(byte[] buf, int off, int len)
+ {
lock (this)
{
if (mDrbg == null)
@@ -57,21 +62,14 @@ namespace Org.BouncyCastle.Crypto.Prng
}
// check if a reseed is required...
- if (mDrbg.Generate(bytes, null, mPredictionResistant) < 0)
+ if (mDrbg.Generate(buf, off, len, null, mPredictionResistant) < 0)
{
mDrbg.Reseed(null);
- mDrbg.Generate(bytes, null, mPredictionResistant);
+ mDrbg.Generate(buf, off, len, null, mPredictionResistant);
}
}
}
- public override void NextBytes(byte[] buf, int off, int len)
- {
- byte[] bytes = new byte[len];
- NextBytes(bytes);
- Array.Copy(bytes, 0, buf, off, len);
- }
-
public override byte[] GenerateSeed(int numBytes)
{
return EntropyUtilities.GenerateSeed(mEntropySource, numBytes);
diff --git a/crypto/src/crypto/prng/X931Rng.cs b/crypto/src/crypto/prng/X931Rng.cs
index 2bd8e0c6b..53c982c25 100644
--- a/crypto/src/crypto/prng/X931Rng.cs
+++ b/crypto/src/crypto/prng/X931Rng.cs
@@ -46,14 +46,14 @@ namespace Org.BouncyCastle.Crypto.Prng
*
* @return number of bits generated, -1 if a reseed required.
*/
- internal int Generate(byte[] output, bool predictionResistant)
+ internal int Generate(byte[] output, int outputOff, int outputLen, bool predictionResistant)
{
if (mR.Length == 8) // 64 bit block size
{
if (mReseedCounter > BLOCK64_RESEED_MAX)
return -1;
- if (IsTooLarge(output, BLOCK64_MAX_BITS_REQUEST / 8))
+ if (outputLen > BLOCK64_MAX_BITS_REQUEST / 8)
throw new ArgumentException("Number of bits per request limited to " + BLOCK64_MAX_BITS_REQUEST, "output");
}
else
@@ -61,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Prng
if (mReseedCounter > BLOCK128_RESEED_MAX)
return -1;
- if (IsTooLarge(output, BLOCK128_MAX_BITS_REQUEST / 8))
+ if (outputLen > BLOCK128_MAX_BITS_REQUEST / 8)
throw new ArgumentException("Number of bits per request limited to " + BLOCK128_MAX_BITS_REQUEST, "output");
}
@@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Prng
throw new InvalidOperationException("Insufficient entropy returned");
}
- int m = output.Length / mR.Length;
+ int m = outputLen / mR.Length;
for (int i = 0; i < m; i++)
{
@@ -80,12 +80,12 @@ namespace Org.BouncyCastle.Crypto.Prng
Process(mR, mI, mV);
Process(mV, mR, mI);
- Array.Copy(mR, 0, output, i * mR.Length, mR.Length);
+ Array.Copy(mR, 0, output, outputOff + i * mR.Length, mR.Length);
Increment(mDT);
}
- int bytesToCopy = (output.Length - m * mR.Length);
+ int bytesToCopy = (outputLen - m * mR.Length);
if (bytesToCopy > 0)
{
@@ -93,14 +93,14 @@ namespace Org.BouncyCastle.Crypto.Prng
Process(mR, mI, mV);
Process(mV, mR, mI);
- Array.Copy(mR, 0, output, m * mR.Length, bytesToCopy);
+ Array.Copy(mR, 0, output, outputOff + m * mR.Length, bytesToCopy);
Increment(mDT);
}
mReseedCounter++;
- return output.Length;
+ return outputLen * 8;
}
/**
@@ -137,10 +137,5 @@ namespace Org.BouncyCastle.Crypto.Prng
break;
}
}
-
- private static bool IsTooLarge(byte[] bytes, int maxBytes)
- {
- return bytes != null && bytes.Length > maxBytes;
- }
}
}
diff --git a/crypto/src/crypto/prng/X931SecureRandom.cs b/crypto/src/crypto/prng/X931SecureRandom.cs
index d2e4849c5..1402e5c31 100644
--- a/crypto/src/crypto/prng/X931SecureRandom.cs
+++ b/crypto/src/crypto/prng/X931SecureRandom.cs
@@ -44,24 +44,22 @@ namespace Org.BouncyCastle.Crypto.Prng
public override void NextBytes(byte[] bytes)
{
+ NextBytes(bytes, 0, bytes.Length);
+ }
+
+ public override void NextBytes(byte[] buf, int off, int len)
+ {
lock (this)
{
// check if a reseed is required...
- if (mDrbg.Generate(bytes, mPredictionResistant) < 0)
+ if (mDrbg.Generate(buf, off, len, mPredictionResistant) < 0)
{
mDrbg.Reseed();
- mDrbg.Generate(bytes, mPredictionResistant);
+ mDrbg.Generate(buf, off, len, mPredictionResistant);
}
}
}
- public override void NextBytes(byte[] buf, int off, int len)
- {
- byte[] bytes = new byte[len];
- NextBytes(bytes);
- Array.Copy(bytes, 0, buf, off, len);
- }
-
public override byte[] GenerateSeed(int numBytes)
{
return EntropyUtilities.GenerateSeed(mDrbg.EntropySource, numBytes);
diff --git a/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs b/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs
index 5715a915e..a7b1326c3 100644
--- a/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs
+++ b/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs
@@ -331,14 +331,15 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
*
* @return number of bits generated, -1 if a reseed required.
*/
- public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
+ public int Generate(byte[] output, int outputOff, int outputLen, byte[] additionalInput,
+ bool predictionResistant)
{
if (mIsTdea)
{
if (mReseedCounter > TDEA_RESEED_MAX)
return -1;
- if (DrbgUtilities.IsTooLarge(output, TDEA_MAX_BITS_REQUEST / 8))
+ if (outputLen > TDEA_MAX_BITS_REQUEST / 8)
throw new ArgumentException("Number of bits per request limited to " + TDEA_MAX_BITS_REQUEST, "output");
}
else
@@ -346,7 +347,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
if (mReseedCounter > AES_RESEED_MAX)
return -1;
- if (DrbgUtilities.IsTooLarge(output, AES_MAX_BITS_REQUEST / 8))
+ if (outputLen > AES_MAX_BITS_REQUEST / 8)
throw new ArgumentException("Number of bits per request limited to " + AES_MAX_BITS_REQUEST, "output");
}
@@ -370,11 +371,9 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
mEngine.Init(true, new KeyParameter(ExpandKey(mKey)));
- for (int i = 0; i <= output.Length / tmp.Length; i++)
+ for (int i = 0, limit = outputLen / tmp.Length; i <= limit; i++)
{
- int bytesToCopy = ((output.Length - i * tmp.Length) > tmp.Length)
- ? tmp.Length
- : (output.Length - i * mV.Length);
+ int bytesToCopy = System.Math.Min(tmp.Length, outputLen - i * tmp.Length);
if (bytesToCopy != 0)
{
@@ -382,7 +381,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
mEngine.ProcessBlock(mV, 0, tmp, 0);
- Array.Copy(tmp, 0, output, i * tmp.Length, bytesToCopy);
+ Array.Copy(tmp, 0, output, outputOff + i * tmp.Length, bytesToCopy);
}
}
@@ -390,7 +389,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
mReseedCounter++;
- return output.Length * 8;
+ return outputLen * 8;
}
/**
diff --git a/crypto/src/crypto/prng/drbg/DrbgUtilities.cs b/crypto/src/crypto/prng/drbg/DrbgUtilities.cs
index b1f2f29be..58baaf5d9 100644
--- a/crypto/src/crypto/prng/drbg/DrbgUtilities.cs
+++ b/crypto/src/crypto/prng/drbg/DrbgUtilities.cs
@@ -95,10 +95,5 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
return temp;
}
-
- internal static bool IsTooLarge(byte[] bytes, int maxBytes)
- {
- return bytes != null && bytes.Length > maxBytes;
- }
}
}
diff --git a/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs b/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs
index 78331705e..0ec0e8b71 100644
--- a/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs
+++ b/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs
@@ -104,9 +104,10 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
*
* @return number of bits generated, -1 if a reseed required.
*/
- public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
+ public int Generate(byte[] output, int outputOff, int outputLen, byte[] additionalInput,
+ bool predictionResistant)
{
- int numberOfBits = output.Length * 8;
+ int numberOfBits = outputLen * 8;
if (numberOfBits > MAX_BITS_REQUEST)
throw new ArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST, "output");
@@ -129,9 +130,9 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
}
// 3.
- byte[] rv = new byte[output.Length];
+ byte[] rv = new byte[outputLen];
- int m = output.Length / mV.Length;
+ int m = outputLen / mV.Length;
mHMac.Init(new KeyParameter(mK));
@@ -155,7 +156,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
mReseedCounter++;
- Array.Copy(rv, 0, output, 0, output.Length);
+ Array.Copy(rv, 0, output, outputOff, outputLen);
return numberOfBits;
}
diff --git a/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs b/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs
index 506517aae..accc65ec3 100644
--- a/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs
+++ b/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs
@@ -101,7 +101,8 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
*
* @return number of bits generated, -1 if a reseed required.
*/
- public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
+ public int Generate(byte[] output, int outputOff, int outputLen, byte[] additionalInput,
+ bool predictionResistant)
{
// 1. If reseed_counter > reseed_interval, then return an indication that a
// reseed is required.
@@ -116,7 +117,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
// 6. reseed_counter = reseed_counter + 1.
// 7. Return SUCCESS, returned_bits, and the new values of V, C, and
// reseed_counter for the new_working_state.
- int numberOfBits = output.Length * 8;
+ int numberOfBits = outputLen * 8;
if (numberOfBits > MAX_BITS_REQUEST)
throw new ArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST, "output");
@@ -166,7 +167,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
mReseedCounter++;
- Array.Copy(rv, 0, output, 0, output.Length);
+ Array.Copy(rv, 0, output, outputOff, outputLen);
return numberOfBits;
}
diff --git a/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs b/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs
index 0e398209e..78cbcd92f 100644
--- a/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs
+++ b/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs
@@ -23,7 +23,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg
*
* @return number of bits generated, -1 if a reseed required.
*/
- int Generate(byte[] output, byte[] additionalInput, bool predictionResistant);
+ int Generate(byte[] output, int outputOff, int outputLen, byte[] additionalInput, bool predictionResistant);
/**
* Reseed the DRBG.
|