diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-01-29 17:35:58 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-01-29 17:35:58 +0700 |
commit | 60c2d34deac485cb50c2350735b4efff50c88a62 (patch) | |
tree | c1b9cbe64d347b8572f2d41010bab158647da20a | |
parent | Refactor X509CertificatePair (diff) | |
download | BouncyCastle.NET-ed25519-60c2d34deac485cb50c2350735b4efff50c88a62.tar.xz |
Improve seed generation
7 files changed, 43 insertions, 3 deletions
diff --git a/crypto/src/crypto/prng/BasicEntropySourceProvider.cs b/crypto/src/crypto/prng/BasicEntropySourceProvider.cs index 5de1e4e5e..7a3e2b2b4 100644 --- a/crypto/src/crypto/prng/BasicEntropySourceProvider.cs +++ b/crypto/src/crypto/prng/BasicEntropySourceProvider.cs @@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Prng #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER int IEntropySource.GetEntropy(Span<byte> output) { - int length = (mEntropySize + 7) / 8; + int length = System.Math.Min(output.Length, (mEntropySize + 7) / 8); mSecureRandom.NextBytes(output[..length]); return length; } diff --git a/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs b/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs index 9a2f6de2c..d20b5b22b 100644 --- a/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs +++ b/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs @@ -59,7 +59,7 @@ namespace Org.BouncyCastle.Crypto.Prng #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER int IEntropySource.GetEntropy(Span<byte> output) { - int length = (mEntropySize + 7) / 8; + int length = System.Math.Min(output.Length, (mEntropySize + 7) / 8); mRng.GetBytes(output[..length]); return length; } diff --git a/crypto/src/crypto/prng/EntropyUtilities.cs b/crypto/src/crypto/prng/EntropyUtilities.cs index 58c8703f4..156b46622 100644 --- a/crypto/src/crypto/prng/EntropyUtilities.cs +++ b/crypto/src/crypto/prng/EntropyUtilities.cs @@ -16,6 +16,10 @@ namespace Org.BouncyCastle.Crypto.Prng public static byte[] GenerateSeed(IEntropySource entropySource, int numBytes) { byte[] bytes = new byte[numBytes]; + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + GenerateSeed(entropySource, bytes); +#else int count = 0; while (count < numBytes) { @@ -24,7 +28,20 @@ namespace Org.BouncyCastle.Crypto.Prng Array.Copy(entropy, 0, bytes, count, toCopy); count += toCopy; } +#endif + return bytes; } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void GenerateSeed(IEntropySource entropySource, Span<byte> seed) + { + while (!seed.IsEmpty) + { + int len = entropySource.GetEntropy(seed); + seed = seed[len..]; + } + } +#endif } } diff --git a/crypto/src/crypto/prng/SP800SecureRandom.cs b/crypto/src/crypto/prng/SP800SecureRandom.cs index a18576d03..4fbbc927f 100644 --- a/crypto/src/crypto/prng/SP800SecureRandom.cs +++ b/crypto/src/crypto/prng/SP800SecureRandom.cs @@ -113,6 +113,13 @@ namespace Org.BouncyCastle.Crypto.Prng return EntropyUtilities.GenerateSeed(mEntropySource, numBytes); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override void GenerateSeed(Span<byte> seed) + { + EntropyUtilities.GenerateSeed(mEntropySource, seed); + } +#endif + /// <summary>Force a reseed of the DRBG.</summary> /// <param name="additionalInput">optional additional input</param> public virtual void Reseed(byte[] additionalInput) diff --git a/crypto/src/crypto/prng/X931SecureRandom.cs b/crypto/src/crypto/prng/X931SecureRandom.cs index d40134851..6c0114cb2 100644 --- a/crypto/src/crypto/prng/X931SecureRandom.cs +++ b/crypto/src/crypto/prng/X931SecureRandom.cs @@ -96,5 +96,12 @@ namespace Org.BouncyCastle.Crypto.Prng { return EntropyUtilities.GenerateSeed(mDrbg.EntropySource, numBytes); } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override void GenerateSeed(Span<byte> seed) + { + EntropyUtilities.GenerateSeed(mDrbg.EntropySource, seed); + } +#endif } } diff --git a/crypto/test/src/crypto/prng/test/TestEntropySourceProvider.cs b/crypto/test/src/crypto/prng/test/TestEntropySourceProvider.cs index ae80b3dbe..1c0d24dba 100644 --- a/crypto/test/src/crypto/prng/test/TestEntropySourceProvider.cs +++ b/crypto/test/src/crypto/prng/test/TestEntropySourceProvider.cs @@ -53,7 +53,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Test #if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER int IEntropySource.GetEntropy(Span<byte> output) { - int length = bitsRequired / 8; + int length = System.Math.Min(output.Length, bitsRequired / 8); data.AsSpan(index, length).CopyTo(output); index += length; return length; diff --git a/crypto/test/src/util/test/FixedSecureRandom.cs b/crypto/test/src/util/test/FixedSecureRandom.cs index a7f3c1f3b..a23438794 100644 --- a/crypto/test/src/util/test/FixedSecureRandom.cs +++ b/crypto/test/src/util/test/FixedSecureRandom.cs @@ -213,6 +213,15 @@ namespace Org.BouncyCastle.Utilities.Test return GetNextBytes(this, numBytes); } + // NOTE: .NET Core 3.1 has Span<T>, but is tested against our .NET Standard 2.0 assembly. +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override void GenerateSeed(Span<byte> seed) + { + NextBytes(seed); + } +#endif + public override void NextBytes(byte[] buf) { NextBytes(buf, 0, buf.Length); |