VMPCMac.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  5. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs
  6. {
  7. public class VmpcMac
  8. : IMac
  9. {
  10. private byte g;
  11. private byte n = 0;
  12. private byte[] P = null;
  13. private byte s = 0;
  14. private byte[] T;
  15. private byte[] workingIV;
  16. private byte[] workingKey;
  17. private byte x1, x2, x3, x4;
  18. public virtual int DoFinal(byte[] output, int outOff)
  19. {
  20. // Execute the Post-Processing Phase
  21. for (int r = 1; r < 25; r++)
  22. {
  23. s = P[(s + P[n & 0xff]) & 0xff];
  24. x4 = P[(x4 + x3 + r) & 0xff];
  25. x3 = P[(x3 + x2 + r) & 0xff];
  26. x2 = P[(x2 + x1 + r) & 0xff];
  27. x1 = P[(x1 + s + r) & 0xff];
  28. T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1);
  29. T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2);
  30. T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3);
  31. T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4);
  32. g = (byte) ((g + 4) & 0x1f);
  33. byte temp = P[n & 0xff];
  34. P[n & 0xff] = P[s & 0xff];
  35. P[s & 0xff] = temp;
  36. n = (byte) ((n + 1) & 0xff);
  37. }
  38. // Input T to the IV-phase of the VMPC KSA
  39. for (int m = 0; m < 768; m++)
  40. {
  41. s = P[(s + P[m & 0xff] + T[m & 0x1f]) & 0xff];
  42. byte temp = P[m & 0xff];
  43. P[m & 0xff] = P[s & 0xff];
  44. P[s & 0xff] = temp;
  45. }
  46. // Store 20 new outputs of the VMPC Stream Cipher input table M
  47. byte[] M = new byte[20];
  48. for (int i = 0; i < 20; i++)
  49. {
  50. s = P[(s + P[i & 0xff]) & 0xff];
  51. M[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff];
  52. byte temp = P[i & 0xff];
  53. P[i & 0xff] = P[s & 0xff];
  54. P[s & 0xff] = temp;
  55. }
  56. Array.Copy(M, 0, output, outOff, M.Length);
  57. Reset();
  58. return M.Length;
  59. }
  60. public virtual string AlgorithmName
  61. {
  62. get { return "VMPC-MAC"; }
  63. }
  64. public virtual int GetMacSize()
  65. {
  66. return 20;
  67. }
  68. public virtual void Init(ICipherParameters parameters)
  69. {
  70. if (!(parameters is ParametersWithIV))
  71. throw new ArgumentException("VMPC-MAC Init parameters must include an IV", "parameters");
  72. ParametersWithIV ivParams = (ParametersWithIV) parameters;
  73. KeyParameter key = (KeyParameter) ivParams.Parameters;
  74. if (!(ivParams.Parameters is KeyParameter))
  75. throw new ArgumentException("VMPC-MAC Init parameters must include a key", "parameters");
  76. this.workingIV = ivParams.GetIV();
  77. if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768)
  78. throw new ArgumentException("VMPC-MAC requires 1 to 768 bytes of IV", "parameters");
  79. this.workingKey = key.GetKey();
  80. Reset();
  81. }
  82. private void initKey(byte[] keyBytes, byte[] ivBytes)
  83. {
  84. s = 0;
  85. P = new byte[256];
  86. for (int i = 0; i < 256; i++)
  87. {
  88. P[i] = (byte) i;
  89. }
  90. for (int m = 0; m < 768; m++)
  91. {
  92. s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff];
  93. byte temp = P[m & 0xff];
  94. P[m & 0xff] = P[s & 0xff];
  95. P[s & 0xff] = temp;
  96. }
  97. for (int m = 0; m < 768; m++)
  98. {
  99. s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff];
  100. byte temp = P[m & 0xff];
  101. P[m & 0xff] = P[s & 0xff];
  102. P[s & 0xff] = temp;
  103. }
  104. n = 0;
  105. }
  106. public virtual void Reset()
  107. {
  108. initKey(this.workingKey, this.workingIV);
  109. g = x1 = x2 = x3 = x4 = n = 0;
  110. T = new byte[32];
  111. for (int i = 0; i < 32; i++)
  112. {
  113. T[i] = 0;
  114. }
  115. }
  116. public virtual void Update(byte input)
  117. {
  118. s = P[(s + P[n & 0xff]) & 0xff];
  119. byte c = (byte) (input ^ P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]);
  120. x4 = P[(x4 + x3) & 0xff];
  121. x3 = P[(x3 + x2) & 0xff];
  122. x2 = P[(x2 + x1) & 0xff];
  123. x1 = P[(x1 + s + c) & 0xff];
  124. T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1);
  125. T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2);
  126. T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3);
  127. T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4);
  128. g = (byte) ((g + 4) & 0x1f);
  129. byte temp = P[n & 0xff];
  130. P[n & 0xff] = P[s & 0xff];
  131. P[s & 0xff] = temp;
  132. n = (byte) ((n + 1) & 0xff);
  133. }
  134. public virtual void BlockUpdate(byte[] input, int inOff, int len)
  135. {
  136. if ((inOff + len) > input.Length)
  137. throw new DataLengthException("input buffer too short");
  138. for (int i = 0; i < len; i++)
  139. {
  140. Update(input[inOff + i]);
  141. }
  142. }
  143. }
  144. }
  145. #pragma warning restore
  146. #endif