DHKekGenerator.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Kdf
  7. {
  8. /**
  9. * RFC 2631 Diffie-hellman KEK derivation function.
  10. */
  11. public class DHKekGenerator
  12. : IDerivationFunction
  13. {
  14. private readonly IDigest digest;
  15. private DerObjectIdentifier algorithm;
  16. private int keySize;
  17. private byte[] z;
  18. private byte[] partyAInfo;
  19. public DHKekGenerator(IDigest digest)
  20. {
  21. this.digest = digest;
  22. }
  23. public virtual void Init(IDerivationParameters param)
  24. {
  25. DHKdfParameters parameters = (DHKdfParameters)param;
  26. this.algorithm = parameters.Algorithm;
  27. this.keySize = parameters.KeySize;
  28. this.z = parameters.GetZ(); // TODO Clone?
  29. this.partyAInfo = parameters.GetExtraInfo(); // TODO Clone?
  30. }
  31. public virtual IDigest Digest
  32. {
  33. get { return digest; }
  34. }
  35. public virtual int GenerateBytes(byte[] outBytes, int outOff, int len)
  36. {
  37. if ((outBytes.Length - len) < outOff)
  38. {
  39. throw new DataLengthException("output buffer too small");
  40. }
  41. long oBytes = len;
  42. int outLen = digest.GetDigestSize();
  43. //
  44. // this is at odds with the standard implementation, the
  45. // maximum value should be hBits * (2^32 - 1) where hBits
  46. // is the digest output size in bits. We can't have an
  47. // array with a long index at the moment...
  48. //
  49. if (oBytes > ((2L << 32) - 1))
  50. {
  51. throw new ArgumentException("Output length too large");
  52. }
  53. int cThreshold = (int)((oBytes + outLen - 1) / outLen);
  54. byte[] dig = new byte[digest.GetDigestSize()];
  55. uint counter = 1;
  56. for (int i = 0; i < cThreshold; i++)
  57. {
  58. digest.BlockUpdate(z, 0, z.Length);
  59. // KeySpecificInfo
  60. DerSequence keyInfo = new DerSequence(
  61. algorithm,
  62. new DerOctetString(Pack.UInt32_To_BE(counter)));
  63. // OtherInfo
  64. Asn1EncodableVector v1 = new Asn1EncodableVector(keyInfo);
  65. if (partyAInfo != null)
  66. {
  67. v1.Add(new DerTaggedObject(true, 0, new DerOctetString(partyAInfo)));
  68. }
  69. v1.Add(new DerTaggedObject(true, 2, new DerOctetString(Pack.UInt32_To_BE((uint)keySize))));
  70. byte[] other = new DerSequence(v1).GetDerEncoded();
  71. digest.BlockUpdate(other, 0, other.Length);
  72. digest.DoFinal(dig, 0);
  73. if (len > outLen)
  74. {
  75. Array.Copy(dig, 0, outBytes, outOff, outLen);
  76. outOff += outLen;
  77. len -= outLen;
  78. }
  79. else
  80. {
  81. Array.Copy(dig, 0, outBytes, outOff, len);
  82. }
  83. counter++;
  84. }
  85. digest.Reset();
  86. return (int)oBytes;
  87. }
  88. }
  89. }
  90. #pragma warning restore
  91. #endif