HMac.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs
  9. {
  10. /**
  11. * HMAC implementation based on RFC2104
  12. *
  13. * H(K XOR opad, H(K XOR ipad, text))
  14. */
  15. [BestHTTP.PlatformSupport.IL2CPP.Il2CppSetOption(BestHTTP.PlatformSupport.IL2CPP.Option.NullChecks, false)]
  16. [BestHTTP.PlatformSupport.IL2CPP.Il2CppSetOption(BestHTTP.PlatformSupport.IL2CPP.Option.ArrayBoundsChecks, false)]
  17. [BestHTTP.PlatformSupport.IL2CPP.Il2CppSetOption(BestHTTP.PlatformSupport.IL2CPP.Option.DivideByZeroChecks, false)]
  18. [BestHTTP.PlatformSupport.IL2CPP.Il2CppEagerStaticClassConstructionAttribute]
  19. public sealed class HMac
  20. : IMac
  21. {
  22. private const byte IPAD = (byte)0x36;
  23. private const byte OPAD = (byte)0x5C;
  24. private readonly IDigest digest;
  25. private readonly int digestSize;
  26. private readonly int blockLength;
  27. private IMemoable ipadState;
  28. private IMemoable opadState;
  29. private readonly byte[] inputPad;
  30. private readonly byte[] outputBuf;
  31. public HMac(IDigest digest)
  32. {
  33. this.digest = digest;
  34. this.digestSize = digest.GetDigestSize();
  35. this.blockLength = digest.GetByteLength();
  36. this.inputPad = new byte[blockLength];
  37. this.outputBuf = new byte[blockLength + digestSize];
  38. }
  39. public /*virtual */string AlgorithmName
  40. {
  41. get { return digest.AlgorithmName + "/HMAC"; }
  42. }
  43. public /*virtual */IDigest GetUnderlyingDigest()
  44. {
  45. return digest;
  46. }
  47. public /*virtual */void Init(ICipherParameters parameters)
  48. {
  49. digest.Reset();
  50. byte[] key = ((KeyParameter)parameters).GetKey();
  51. int keyLength = key.Length;
  52. if (keyLength > blockLength)
  53. {
  54. digest.BlockUpdate(key, 0, keyLength);
  55. digest.DoFinal(inputPad, 0);
  56. keyLength = digestSize;
  57. }
  58. else
  59. {
  60. Array.Copy(key, 0, inputPad, 0, keyLength);
  61. }
  62. Array.Clear(inputPad, keyLength, blockLength - keyLength);
  63. Array.Copy(inputPad, 0, outputBuf, 0, blockLength);
  64. XorPad(inputPad, blockLength, IPAD);
  65. XorPad(outputBuf, blockLength, OPAD);
  66. if (digest is IMemoable)
  67. {
  68. opadState = ((IMemoable)digest).Copy();
  69. ((IDigest)opadState).BlockUpdate(outputBuf, 0, blockLength);
  70. }
  71. digest.BlockUpdate(inputPad, 0, inputPad.Length);
  72. if (digest is IMemoable)
  73. {
  74. ipadState = ((IMemoable)digest).Copy();
  75. }
  76. }
  77. public /*virtual */int GetMacSize()
  78. {
  79. return digestSize;
  80. }
  81. public /*virtual */void Update(byte input)
  82. {
  83. digest.Update(input);
  84. }
  85. public /*virtual */void BlockUpdate(byte[] input, int inOff, int len)
  86. {
  87. digest.BlockUpdate(input, inOff, len);
  88. }
  89. public /*virtual */int DoFinal(byte[] output, int outOff)
  90. {
  91. digest.DoFinal(outputBuf, blockLength);
  92. if (opadState != null)
  93. {
  94. ((IMemoable)digest).Reset(opadState);
  95. digest.BlockUpdate(outputBuf, blockLength, digest.GetDigestSize());
  96. }
  97. else
  98. {
  99. digest.BlockUpdate(outputBuf, 0, outputBuf.Length);
  100. }
  101. int len = digest.DoFinal(output, outOff);
  102. Array.Clear(outputBuf, blockLength, digestSize);
  103. if (ipadState != null)
  104. {
  105. ((IMemoable)digest).Reset(ipadState);
  106. }
  107. else
  108. {
  109. digest.BlockUpdate(inputPad, 0, inputPad.Length);
  110. }
  111. return len;
  112. }
  113. /**
  114. * Reset the mac generator.
  115. */
  116. public /*virtual */void Reset()
  117. {
  118. // Reset underlying digest
  119. digest.Reset();
  120. // Initialise the digest
  121. digest.BlockUpdate(inputPad, 0, inputPad.Length);
  122. }
  123. private static void XorPad(byte[] pad, int len, byte n)
  124. {
  125. for (int i = 0; i < len; ++i)
  126. {
  127. pad[i] ^= n;
  128. }
  129. }
  130. }
  131. }
  132. #pragma warning restore
  133. #endif