BaseKdfBytesGenerator.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  7. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
  8. {
  9. /**
  10. * Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033
  11. * <br/>
  12. * This implementation is based on ISO 18033/P1363a.
  13. */
  14. public class BaseKdfBytesGenerator
  15. : IDerivationFunction
  16. {
  17. private int counterStart;
  18. private IDigest digest;
  19. private byte[] shared;
  20. private byte[] iv;
  21. /**
  22. * Construct a KDF Parameters generator.
  23. *
  24. * @param counterStart value of counter.
  25. * @param digest the digest to be used as the source of derived keys.
  26. */
  27. public BaseKdfBytesGenerator(int counterStart, IDigest digest)
  28. {
  29. this.counterStart = counterStart;
  30. this.digest = digest;
  31. }
  32. public virtual void Init(IDerivationParameters parameters)
  33. {
  34. if (parameters is KdfParameters)
  35. {
  36. KdfParameters p = (KdfParameters)parameters;
  37. shared = p.GetSharedSecret();
  38. iv = p.GetIV();
  39. }
  40. else if (parameters is Iso18033KdfParameters)
  41. {
  42. Iso18033KdfParameters p = (Iso18033KdfParameters)parameters;
  43. shared = p.GetSeed();
  44. iv = null;
  45. }
  46. else
  47. {
  48. throw new ArgumentException("KDF parameters required for KDF Generator");
  49. }
  50. }
  51. /**
  52. * return the underlying digest.
  53. */
  54. public virtual IDigest Digest
  55. {
  56. get { return digest; }
  57. }
  58. /**
  59. * fill len bytes of the output buffer with bytes generated from
  60. * the derivation function.
  61. *
  62. * @throws ArgumentException if the size of the request will cause an overflow.
  63. * @throws DataLengthException if the out buffer is too small.
  64. */
  65. public virtual int GenerateBytes(byte[] output, int outOff, int length)
  66. {
  67. if ((output.Length - length) < outOff)
  68. throw new DataLengthException("output buffer too small");
  69. long oBytes = length;
  70. int outLen = digest.GetDigestSize();
  71. //
  72. // this is at odds with the standard implementation, the
  73. // maximum value should be hBits * (2^32 - 1) where hBits
  74. // is the digest output size in bits. We can't have an
  75. // array with a long index at the moment...
  76. //
  77. if (oBytes > ((2L << 32) - 1))
  78. throw new ArgumentException("Output length too large");
  79. int cThreshold = (int)((oBytes + outLen - 1) / outLen);
  80. byte[] dig = new byte[digest.GetDigestSize()];
  81. byte[] C = new byte[4];
  82. Pack.UInt32_To_BE((uint)counterStart, C, 0);
  83. uint counterBase = (uint)(counterStart & ~0xFF);
  84. for (int i = 0; i < cThreshold; i++)
  85. {
  86. digest.BlockUpdate(shared, 0, shared.Length);
  87. digest.BlockUpdate(C, 0, 4);
  88. if (iv != null)
  89. {
  90. digest.BlockUpdate(iv, 0, iv.Length);
  91. }
  92. digest.DoFinal(dig, 0);
  93. if (length > outLen)
  94. {
  95. Array.Copy(dig, 0, output, outOff, outLen);
  96. outOff += outLen;
  97. length -= outLen;
  98. }
  99. else
  100. {
  101. Array.Copy(dig, 0, output, outOff, length);
  102. }
  103. if (++C[3] == 0)
  104. {
  105. counterBase += 0x100;
  106. Pack.UInt32_To_BE(counterBase, C, 0);
  107. }
  108. }
  109. digest.Reset();
  110. return (int)oBytes;
  111. }
  112. }
  113. }
  114. #pragma warning restore
  115. #endif