summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/crypto/CipherKeyGenerator.cs4
-rw-r--r--crypto/src/crypto/encodings/OaepEncoding.cs2
-rw-r--r--crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs70
-rw-r--r--crypto/src/crypto/prng/DigestRandomGenerator.cs12
-rw-r--r--crypto/src/crypto/prng/EntropyUtilities.cs30
-rw-r--r--crypto/src/crypto/prng/SP800SecureRandom.cs4
-rw-r--r--crypto/src/crypto/prng/X931Rng.cs2
-rw-r--r--crypto/src/crypto/prng/X931SecureRandom.cs4
-rw-r--r--crypto/src/security/SecureRandom.cs21
9 files changed, 122 insertions, 27 deletions
diff --git a/crypto/src/crypto/CipherKeyGenerator.cs b/crypto/src/crypto/CipherKeyGenerator.cs

index 5d00d34dd..d8d9b29b5 100644 --- a/crypto/src/crypto/CipherKeyGenerator.cs +++ b/crypto/src/crypto/CipherKeyGenerator.cs
@@ -75,9 +75,9 @@ namespace Org.BouncyCastle.Crypto return engineGenerateKey(); } - protected virtual byte[] engineGenerateKey() + protected virtual byte[] engineGenerateKey() { - return random.GenerateSeed(strength); + return SecureRandom.GetNextBytes(random, strength); } } } diff --git a/crypto/src/crypto/encodings/OaepEncoding.cs b/crypto/src/crypto/encodings/OaepEncoding.cs
index a4d2f0e36..95814ef25 100644 --- a/crypto/src/crypto/encodings/OaepEncoding.cs +++ b/crypto/src/crypto/encodings/OaepEncoding.cs
@@ -161,7 +161,7 @@ namespace Org.BouncyCastle.Crypto.Encodings // // generate the seed. // - byte[] seed = random.GenerateSeed(defHash.Length); + byte[] seed = SecureRandom.GetNextBytes(random, defHash.Length); // // mask the message block. diff --git a/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs b/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs new file mode 100644
index 000000000..68579aaf4 --- /dev/null +++ b/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs
@@ -0,0 +1,70 @@ +#if !(NETCF_1_0 || PORTABLE) +using System; +using System.Security.Cryptography; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public class CryptoApiEntropySourceProvider + : IEntropySourceProvider + { + private readonly RandomNumberGenerator mRng; + private readonly bool mPredictionResistant; + + public CryptoApiEntropySourceProvider() + : this(new RNGCryptoServiceProvider(), true) + { + } + + public CryptoApiEntropySourceProvider(RandomNumberGenerator rng, bool isPredictionResistant) + { + if (rng == null) + throw new ArgumentNullException("rng"); + + mRng = rng; + mPredictionResistant = isPredictionResistant; + } + + public IEntropySource Get(int bitsRequired) + { + return new CryptoApiEntropySource(mRng, mPredictionResistant, bitsRequired); + } + + private class CryptoApiEntropySource + : IEntropySource + { + private readonly RandomNumberGenerator mRng; + private readonly bool mPredictionResistant; + private readonly int mEntropySize; + + internal CryptoApiEntropySource(RandomNumberGenerator rng, bool predictionResistant, int entropySize) + { + this.mRng = rng; + this.mPredictionResistant = predictionResistant; + this.mEntropySize = entropySize; + } + + #region IEntropySource Members + + bool IEntropySource.IsPredictionResistant + { + get { return mPredictionResistant; } + } + + byte[] IEntropySource.GetEntropy() + { + byte[] result = new byte[(mEntropySize + 7) / 8]; + mRng.GetBytes(result); + return result; + } + + int IEntropySource.EntropySize + { + get { return mEntropySize; } + } + + #endregion + } + } +} + +#endif diff --git a/crypto/src/crypto/prng/DigestRandomGenerator.cs b/crypto/src/crypto/prng/DigestRandomGenerator.cs
index cbd2ef060..f5a29952a 100644 --- a/crypto/src/crypto/prng/DigestRandomGenerator.cs +++ b/crypto/src/crypto/prng/DigestRandomGenerator.cs
@@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Crypto.Prng { @@ -108,15 +109,12 @@ namespace Org.BouncyCastle.Crypto.Prng private void DigestAddCounter(long seedVal) { - ulong seed = (ulong)seedVal; - for (int i = 0; i != 8; i++) - { - digest.Update((byte)seed); - seed >>= 8; - } + byte[] bytes = new byte[8]; + Pack.UInt64_To_LE((ulong)seedVal, bytes); + digest.BlockUpdate(bytes, 0, bytes.Length); } - private void DigestUpdate(byte[] inSeed) + private void DigestUpdate(byte[] inSeed) { digest.BlockUpdate(inSeed, 0, inSeed.Length); } diff --git a/crypto/src/crypto/prng/EntropyUtilities.cs b/crypto/src/crypto/prng/EntropyUtilities.cs new file mode 100644
index 000000000..58c8703f4 --- /dev/null +++ b/crypto/src/crypto/prng/EntropyUtilities.cs
@@ -0,0 +1,30 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public abstract class EntropyUtilities + { + /** + * Generate numBytes worth of entropy from the passed in entropy source. + * + * @param entropySource the entropy source to request the data from. + * @param numBytes the number of bytes of entropy requested. + * @return a byte array populated with the random data. + */ + public static byte[] GenerateSeed(IEntropySource entropySource, int numBytes) + { + byte[] bytes = new byte[numBytes]; + int count = 0; + while (count < numBytes) + { + byte[] entropy = entropySource.GetEntropy(); + int toCopy = System.Math.Min(bytes.Length, numBytes - count); + Array.Copy(entropy, 0, bytes, count, toCopy); + count += toCopy; + } + return bytes; + } + } +} diff --git a/crypto/src/crypto/prng/SP800SecureRandom.cs b/crypto/src/crypto/prng/SP800SecureRandom.cs
index 996ba0846..5c5bda399 100644 --- a/crypto/src/crypto/prng/SP800SecureRandom.cs +++ b/crypto/src/crypto/prng/SP800SecureRandom.cs
@@ -74,9 +74,7 @@ namespace Org.BouncyCastle.Crypto.Prng public override byte[] GenerateSeed(int numBytes) { - byte[] bytes = new byte[numBytes]; - NextBytes(bytes); - return bytes; + return EntropyUtilities.GenerateSeed(mEntropySource, numBytes); } } } diff --git a/crypto/src/crypto/prng/X931Rng.cs b/crypto/src/crypto/prng/X931Rng.cs
index d09cc6618..987379d4b 100644 --- a/crypto/src/crypto/prng/X931Rng.cs +++ b/crypto/src/crypto/prng/X931Rng.cs
@@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Crypto.Prng private const int BLOCK128_MAX_BITS_REQUEST = 1 << (19 - 1); private readonly IBlockCipher mEngine; - private readonly IEntropySource mEntropySource; + internal readonly IEntropySource mEntropySource; private readonly byte[] mDT; private readonly byte[] mI; diff --git a/crypto/src/crypto/prng/X931SecureRandom.cs b/crypto/src/crypto/prng/X931SecureRandom.cs
index a87bf1567..bce8d2cf1 100644 --- a/crypto/src/crypto/prng/X931SecureRandom.cs +++ b/crypto/src/crypto/prng/X931SecureRandom.cs
@@ -64,9 +64,7 @@ namespace Org.BouncyCastle.Crypto.Prng public override byte[] GenerateSeed(int numBytes) { - byte[] bytes = new byte[numBytes]; - NextBytes(bytes); - return bytes; + return EntropyUtilities.GenerateSeed(mDrbg.mEntropySource, numBytes); } } } diff --git a/crypto/src/security/SecureRandom.cs b/crypto/src/security/SecureRandom.cs
index 8683b4729..cb831acc2 100644 --- a/crypto/src/security/SecureRandom.cs +++ b/crypto/src/security/SecureRandom.cs
@@ -68,11 +68,18 @@ namespace Org.BouncyCastle.Security if (autoSeed) { prng.AddSeedMaterial(NextCounterValue()); - prng.AddSeedMaterial(GetSeed(digest.GetDigestSize())); + prng.AddSeedMaterial(GetNextBytes(Master, digest.GetDigestSize())); } return prng; } + public static byte[] GetNextBytes(SecureRandom secureRandom, int length) + { + byte[] result = new byte[length]; + secureRandom.NextBytes(result); + return result; + } + /// <summary> /// Create and auto-seed an instance based on the given algorithm. /// </summary> @@ -104,12 +111,10 @@ namespace Org.BouncyCastle.Security throw new ArgumentException("Unrecognised PRNG algorithm: " + algorithm, "algorithm"); } + [Obsolete("Call GenerateSeed() on a SecureRandom instance instead")] public static byte[] GetSeed(int length) { -#if NETCF_1_0 || PORTABLE - lock (master) -#endif - return Master.GenerateSeed(length); + return GetNextBytes(Master, length); } protected readonly IRandomGenerator generator; @@ -145,11 +150,7 @@ namespace Org.BouncyCastle.Security public virtual byte[] GenerateSeed(int length) { - SetSeed(DateTime.Now.Ticks); - - byte[] rv = new byte[length]; - NextBytes(rv); - return rv; + return GetNextBytes(Master, length); } public virtual void SetSeed(byte[] seed)