DSTU7564Mac.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  7. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs
  8. {
  9. /// <summary>
  10. /// Implementation of DSTU7564 mac mode
  11. /// </summary>
  12. public class Dstu7564Mac
  13. : IMac
  14. {
  15. private Dstu7564Digest engine;
  16. private int macSize;
  17. private ulong inputLength;
  18. byte[] paddedKey;
  19. byte[] invertedKey;
  20. public string AlgorithmName
  21. {
  22. get { return "DSTU7564Mac"; }
  23. }
  24. public Dstu7564Mac(int macSizeBits)
  25. {
  26. engine = new Dstu7564Digest(macSizeBits);
  27. macSize = macSizeBits / 8;
  28. }
  29. public void Init(ICipherParameters parameters)
  30. {
  31. if (parameters is KeyParameter)
  32. {
  33. byte[] key = ((KeyParameter)parameters).GetKey();
  34. invertedKey = new byte[key.Length];
  35. paddedKey = PadKey(key);
  36. for (int byteIndex = 0; byteIndex < invertedKey.Length; byteIndex++)
  37. {
  38. invertedKey[byteIndex] = (byte)(key[byteIndex] ^ (byte)0xFF);
  39. }
  40. }
  41. else
  42. {
  43. throw new ArgumentException("Bad parameter passed");
  44. }
  45. engine.BlockUpdate(paddedKey, 0, paddedKey.Length);
  46. }
  47. public int GetMacSize()
  48. {
  49. return macSize;
  50. }
  51. public void BlockUpdate(byte[] input, int inOff, int len)
  52. {
  53. Check.DataLength(input, inOff, len, "Input buffer too short");
  54. if (paddedKey == null)
  55. throw new InvalidOperationException(AlgorithmName + " not initialised");
  56. engine.BlockUpdate(input, inOff, len);
  57. inputLength += (ulong)len;
  58. }
  59. public void Update(byte input)
  60. {
  61. engine.Update(input);
  62. inputLength++;
  63. }
  64. public int DoFinal(byte[] output, int outOff)
  65. {
  66. Check.OutputLength(output, outOff, macSize, "Output buffer too short");
  67. if (paddedKey == null)
  68. throw new InvalidOperationException(AlgorithmName + " not initialised");
  69. Pad();
  70. engine.BlockUpdate(invertedKey, 0, invertedKey.Length);
  71. inputLength = 0;
  72. return engine.DoFinal(output, outOff);
  73. }
  74. public void Reset()
  75. {
  76. inputLength = 0;
  77. engine.Reset();
  78. if (paddedKey != null)
  79. {
  80. engine.BlockUpdate(paddedKey, 0, paddedKey.Length);
  81. }
  82. }
  83. private void Pad()
  84. {
  85. int extra = engine.GetByteLength() - (int)(inputLength % (ulong)engine.GetByteLength());
  86. if (extra < 13) // terminator byte + 96 bits of length
  87. {
  88. extra += engine.GetByteLength();
  89. }
  90. byte[] padded = new byte[extra];
  91. padded[0] = (byte)0x80; // Defined in standard;
  92. // Defined in standard;
  93. Pack.UInt64_To_LE(inputLength * 8, padded, padded.Length - 12);
  94. engine.BlockUpdate(padded, 0, padded.Length);
  95. }
  96. private byte[] PadKey(byte[] input)
  97. {
  98. int paddedLen = ((input.Length + engine.GetByteLength() - 1) / engine.GetByteLength()) * engine.GetByteLength();
  99. int extra = engine.GetByteLength() - (int)(input.Length % engine.GetByteLength());
  100. if (extra < 13) // terminator byte + 96 bits of length
  101. {
  102. paddedLen += engine.GetByteLength();
  103. }
  104. byte[] padded = new byte[paddedLen];
  105. Array.Copy(input, 0, padded, 0, input.Length);
  106. padded[input.Length] = (byte)0x80; // Defined in standard;
  107. Pack.UInt32_To_LE((uint)(input.Length * 8), padded, padded.Length - 12); // Defined in standard;
  108. return padded;
  109. }
  110. }
  111. }
  112. #pragma warning restore
  113. #endif