summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-01-29 17:35:58 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-01-29 17:35:58 +0700
commit60c2d34deac485cb50c2350735b4efff50c88a62 (patch)
treec1b9cbe64d347b8572f2d41010bab158647da20a
parentRefactor X509CertificatePair (diff)
downloadBouncyCastle.NET-ed25519-60c2d34deac485cb50c2350735b4efff50c88a62.tar.xz
Improve seed generation
-rw-r--r--crypto/src/crypto/prng/BasicEntropySourceProvider.cs2
-rw-r--r--crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs2
-rw-r--r--crypto/src/crypto/prng/EntropyUtilities.cs17
-rw-r--r--crypto/src/crypto/prng/SP800SecureRandom.cs7
-rw-r--r--crypto/src/crypto/prng/X931SecureRandom.cs7
-rw-r--r--crypto/test/src/crypto/prng/test/TestEntropySourceProvider.cs2
-rw-r--r--crypto/test/src/util/test/FixedSecureRandom.cs9
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);