BasicEntropySourceProvider.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
  5. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng
  6. {
  7. /**
  8. * An EntropySourceProvider where entropy generation is based on a SecureRandom output using SecureRandom.generateSeed().
  9. */
  10. public class BasicEntropySourceProvider
  11. : IEntropySourceProvider
  12. {
  13. private readonly SecureRandom mSecureRandom;
  14. private readonly bool mPredictionResistant;
  15. /**
  16. * Create a entropy source provider based on the passed in SecureRandom.
  17. *
  18. * @param secureRandom the SecureRandom to base EntropySource construction on.
  19. * @param isPredictionResistant boolean indicating if the SecureRandom is based on prediction resistant entropy or not (true if it is).
  20. */
  21. public BasicEntropySourceProvider(SecureRandom secureRandom, bool isPredictionResistant)
  22. {
  23. if (secureRandom == null)
  24. throw new ArgumentNullException(nameof(secureRandom));
  25. mSecureRandom = secureRandom;
  26. mPredictionResistant = isPredictionResistant;
  27. }
  28. /**
  29. * Return an entropy source that will create bitsRequired bits of entropy on
  30. * each invocation of getEntropy().
  31. *
  32. * @param bitsRequired size (in bits) of entropy to be created by the provided source.
  33. * @return an EntropySource that generates bitsRequired bits of entropy on each call to its getEntropy() method.
  34. */
  35. public IEntropySource Get(int bitsRequired)
  36. {
  37. return new BasicEntropySource(mSecureRandom, mPredictionResistant, bitsRequired);
  38. }
  39. private class BasicEntropySource
  40. : IEntropySource
  41. {
  42. private readonly SecureRandom mSecureRandom;
  43. private readonly bool mPredictionResistant;
  44. private readonly int mEntropySize;
  45. internal BasicEntropySource(SecureRandom secureRandom, bool predictionResistant, int entropySize)
  46. {
  47. if (secureRandom == null)
  48. throw new ArgumentNullException(nameof(secureRandom));
  49. this.mSecureRandom = secureRandom;
  50. this.mPredictionResistant = predictionResistant;
  51. this.mEntropySize = entropySize;
  52. }
  53. bool IEntropySource.IsPredictionResistant
  54. {
  55. get { return mPredictionResistant; }
  56. }
  57. byte[] IEntropySource.GetEntropy()
  58. {
  59. // TODO[FIPS] Not all SecureRandom implementations are considered valid entropy sources
  60. return SecureRandom.GetNextBytes(mSecureRandom, (mEntropySize + 7) / 8);
  61. }
  62. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  63. int IEntropySource.GetEntropy(Span<byte> output)
  64. {
  65. int length = (mEntropySize + 7) / 8;
  66. mSecureRandom.NextBytes(output[..length]);
  67. return length;
  68. }
  69. #endif
  70. int IEntropySource.EntropySize
  71. {
  72. get { return mEntropySize; }
  73. }
  74. }
  75. }
  76. }
  77. #pragma warning restore
  78. #endif