BcSsl3Hmac.cs 3.3 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.Crypto;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
  7. {
  8. /// <summary>HMAC implementation based on original internet draft for HMAC (RFC 2104).</summary>
  9. /// <remarks>
  10. /// The difference is that padding is concatenated versus XORed with the key, e.g:
  11. /// <code>H(K + opad, H(K + ipad, text))</code>
  12. /// </remarks>
  13. internal class BcSsl3Hmac
  14. : TlsHmac
  15. {
  16. private const byte IPAD_BYTE = (byte)0x36;
  17. private const byte OPAD_BYTE = (byte)0x5C;
  18. private static readonly byte[] IPAD = GenPad(IPAD_BYTE, 48);
  19. private static readonly byte[] OPAD = GenPad(OPAD_BYTE, 48);
  20. private readonly IDigest m_digest;
  21. private readonly int m_padLength;
  22. private byte[] m_secret;
  23. /// <summary>Base constructor for one of the standard digest algorithms for which the byteLength is known.
  24. /// </summary>
  25. /// <remarks>
  26. /// Behaviour is undefined for digests other than MD5 or SHA1.
  27. /// </remarks>
  28. /// <param name="digest">the digest.</param>
  29. internal BcSsl3Hmac(IDigest digest)
  30. {
  31. this.m_digest = digest;
  32. if (digest.GetDigestSize() == 20)
  33. {
  34. this.m_padLength = 40;
  35. }
  36. else
  37. {
  38. this.m_padLength = 48;
  39. }
  40. }
  41. public virtual void SetKey(byte[] key, int keyOff, int keyLen)
  42. {
  43. this.m_secret = TlsUtilities.CopyOfRangeExact(key, keyOff, keyOff + keyLen);
  44. Reset();
  45. }
  46. public virtual void Update(byte[] input, int inOff, int len)
  47. {
  48. m_digest.BlockUpdate(input, inOff, len);
  49. }
  50. public virtual byte[] CalculateMac()
  51. {
  52. byte[] result = new byte[m_digest.GetDigestSize()];
  53. DoFinal(result, 0);
  54. return result;
  55. }
  56. public virtual void CalculateMac(byte[] output, int outOff)
  57. {
  58. DoFinal(output, outOff);
  59. }
  60. public virtual int InternalBlockSize
  61. {
  62. get { return m_digest.GetByteLength(); }
  63. }
  64. public virtual int MacLength
  65. {
  66. get { return m_digest.GetDigestSize(); }
  67. }
  68. /**
  69. * Reset the mac generator.
  70. */
  71. public virtual void Reset()
  72. {
  73. m_digest.Reset();
  74. m_digest.BlockUpdate(m_secret, 0, m_secret.Length);
  75. m_digest.BlockUpdate(IPAD, 0, m_padLength);
  76. }
  77. private void DoFinal(byte[] output, int outOff)
  78. {
  79. byte[] tmp = new byte[m_digest.GetDigestSize()];
  80. m_digest.DoFinal(tmp, 0);
  81. m_digest.BlockUpdate(m_secret, 0, m_secret.Length);
  82. m_digest.BlockUpdate(OPAD, 0, m_padLength);
  83. m_digest.BlockUpdate(tmp, 0, tmp.Length);
  84. m_digest.DoFinal(output, outOff);
  85. Reset();
  86. }
  87. private static byte[] GenPad(byte b, int count)
  88. {
  89. byte[] padding = new byte[count];
  90. Arrays.Fill(padding, b);
  91. return padding;
  92. }
  93. }
  94. }
  95. #pragma warning restore
  96. #endif