SP800SecureRandomBuilder.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng.Drbg;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng
  7. {
  8. /**
  9. * Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG).
  10. */
  11. public class SP800SecureRandomBuilder
  12. {
  13. private readonly SecureRandom mRandom;
  14. private readonly IEntropySourceProvider mEntropySourceProvider;
  15. private byte[] mPersonalizationString = null;
  16. private int mSecurityStrength = 256;
  17. private int mEntropyBitsRequired = 256;
  18. /**
  19. * Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with
  20. * predictionResistant set to false.
  21. * <p>
  22. * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if
  23. * the default SecureRandom does for its generateSeed() call.
  24. * </p>
  25. */
  26. public SP800SecureRandomBuilder()
  27. : this(new SecureRandom(), false)
  28. {
  29. }
  30. /**
  31. * Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value
  32. * for prediction resistance.
  33. * <p>
  34. * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if
  35. * the passed in SecureRandom does for its generateSeed() call.
  36. * </p>
  37. * @param entropySource
  38. * @param predictionResistant
  39. */
  40. public SP800SecureRandomBuilder(SecureRandom entropySource, bool predictionResistant)
  41. {
  42. this.mRandom = entropySource;
  43. this.mEntropySourceProvider = new BasicEntropySourceProvider(entropySource, predictionResistant);
  44. }
  45. /**
  46. * Create a builder which makes creates the SecureRandom objects from a specified entropy source provider.
  47. * <p>
  48. * <b>Note:</b> If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored.
  49. * </p>
  50. * @param entropySourceProvider a provider of EntropySource objects.
  51. */
  52. public SP800SecureRandomBuilder(IEntropySourceProvider entropySourceProvider)
  53. {
  54. this.mRandom = null;
  55. this.mEntropySourceProvider = entropySourceProvider;
  56. }
  57. /**
  58. * Set the personalization string for DRBG SecureRandoms created by this builder
  59. * @param personalizationString the personalisation string for the underlying DRBG.
  60. * @return the current builder.
  61. */
  62. public SP800SecureRandomBuilder SetPersonalizationString(byte[] personalizationString)
  63. {
  64. this.mPersonalizationString = personalizationString;
  65. return this;
  66. }
  67. /**
  68. * Set the security strength required for DRBGs used in building SecureRandom objects.
  69. *
  70. * @param securityStrength the security strength (in bits)
  71. * @return the current builder.
  72. */
  73. public SP800SecureRandomBuilder SetSecurityStrength(int securityStrength)
  74. {
  75. this.mSecurityStrength = securityStrength;
  76. return this;
  77. }
  78. /**
  79. * Set the amount of entropy bits required for seeding and reseeding DRBGs used in building SecureRandom objects.
  80. *
  81. * @param entropyBitsRequired the number of bits of entropy to be requested from the entropy source on each seed/reseed.
  82. * @return the current builder.
  83. */
  84. public SP800SecureRandomBuilder SetEntropyBitsRequired(int entropyBitsRequired)
  85. {
  86. this.mEntropyBitsRequired = entropyBitsRequired;
  87. return this;
  88. }
  89. /**
  90. * Build a SecureRandom based on a SP 800-90A Hash DRBG.
  91. *
  92. * @param digest digest algorithm to use in the DRBG underneath the SecureRandom.
  93. * @param nonce nonce value to use in DRBG construction.
  94. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes.
  95. * @return a SecureRandom supported by a Hash DRBG.
  96. */
  97. public SP800SecureRandom BuildHash(IDigest digest, byte[] nonce, bool predictionResistant)
  98. {
  99. return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired),
  100. new HashDrbgProvider(digest, nonce, mPersonalizationString, mSecurityStrength), predictionResistant);
  101. }
  102. /**
  103. * Build a SecureRandom based on a SP 800-90A CTR DRBG.
  104. *
  105. * @param cipher the block cipher to base the DRBG on.
  106. * @param keySizeInBits key size in bits to be used with the block cipher.
  107. * @param nonce nonce value to use in DRBG construction.
  108. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes.
  109. * @return a SecureRandom supported by a CTR DRBG.
  110. */
  111. public SP800SecureRandom BuildCtr(IBlockCipher cipher, int keySizeInBits, byte[] nonce, bool predictionResistant)
  112. {
  113. return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired),
  114. new CtrDrbgProvider(cipher, keySizeInBits, nonce, mPersonalizationString, mSecurityStrength), predictionResistant);
  115. }
  116. /**
  117. * Build a SecureRandom based on a SP 800-90A HMAC DRBG.
  118. *
  119. * @param hMac HMAC algorithm to use in the DRBG underneath the SecureRandom.
  120. * @param nonce nonce value to use in DRBG construction.
  121. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes.
  122. * @return a SecureRandom supported by a HMAC DRBG.
  123. */
  124. public SP800SecureRandom BuildHMac(IMac hMac, byte[] nonce, bool predictionResistant)
  125. {
  126. return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired),
  127. new HMacDrbgProvider(hMac, nonce, mPersonalizationString, mSecurityStrength), predictionResistant);
  128. }
  129. private class HashDrbgProvider
  130. : IDrbgProvider
  131. {
  132. private readonly IDigest mDigest;
  133. private readonly byte[] mNonce;
  134. private readonly byte[] mPersonalizationString;
  135. private readonly int mSecurityStrength;
  136. public HashDrbgProvider(IDigest digest, byte[] nonce, byte[] personalizationString, int securityStrength)
  137. {
  138. this.mDigest = digest;
  139. this.mNonce = nonce;
  140. this.mPersonalizationString = personalizationString;
  141. this.mSecurityStrength = securityStrength;
  142. }
  143. public ISP80090Drbg Get(IEntropySource entropySource)
  144. {
  145. return new HashSP800Drbg(mDigest, mSecurityStrength, entropySource, mPersonalizationString, mNonce);
  146. }
  147. }
  148. private class HMacDrbgProvider
  149. : IDrbgProvider
  150. {
  151. private readonly IMac mHMac;
  152. private readonly byte[] mNonce;
  153. private readonly byte[] mPersonalizationString;
  154. private readonly int mSecurityStrength;
  155. public HMacDrbgProvider(IMac hMac, byte[] nonce, byte[] personalizationString, int securityStrength)
  156. {
  157. this.mHMac = hMac;
  158. this.mNonce = nonce;
  159. this.mPersonalizationString = personalizationString;
  160. this.mSecurityStrength = securityStrength;
  161. }
  162. public ISP80090Drbg Get(IEntropySource entropySource)
  163. {
  164. return new HMacSP800Drbg(mHMac, mSecurityStrength, entropySource, mPersonalizationString, mNonce);
  165. }
  166. }
  167. private class CtrDrbgProvider
  168. : IDrbgProvider
  169. {
  170. private readonly IBlockCipher mBlockCipher;
  171. private readonly int mKeySizeInBits;
  172. private readonly byte[] mNonce;
  173. private readonly byte[] mPersonalizationString;
  174. private readonly int mSecurityStrength;
  175. public CtrDrbgProvider(IBlockCipher blockCipher, int keySizeInBits, byte[] nonce, byte[] personalizationString, int securityStrength)
  176. {
  177. this.mBlockCipher = blockCipher;
  178. this.mKeySizeInBits = keySizeInBits;
  179. this.mNonce = nonce;
  180. this.mPersonalizationString = personalizationString;
  181. this.mSecurityStrength = securityStrength;
  182. }
  183. public ISP80090Drbg Get(IEntropySource entropySource)
  184. {
  185. return new CtrSP800Drbg(mBlockCipher, mKeySizeInBits, mSecurityStrength, entropySource, mPersonalizationString, mNonce);
  186. }
  187. }
  188. }
  189. }
  190. #pragma warning restore
  191. #endif