VMPCEngine.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  5. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
  6. {
  7. public class VmpcEngine
  8. : IStreamCipher
  9. {
  10. /*
  11. * variables to hold the state of the VMPC engine during encryption and
  12. * decryption
  13. */
  14. protected byte n = 0;
  15. protected byte[] P = null;
  16. protected byte s = 0;
  17. protected byte[] workingIV;
  18. protected byte[] workingKey;
  19. public virtual string AlgorithmName
  20. {
  21. get { return "VMPC"; }
  22. }
  23. /**
  24. * initialise a VMPC cipher.
  25. *
  26. * @param forEncryption
  27. * whether or not we are for encryption.
  28. * @param params
  29. * the parameters required to set up the cipher.
  30. * @exception ArgumentException
  31. * if the params argument is inappropriate.
  32. */
  33. public virtual void Init(
  34. bool forEncryption,
  35. ICipherParameters parameters)
  36. {
  37. if (!(parameters is ParametersWithIV))
  38. throw new ArgumentException("VMPC Init parameters must include an IV");
  39. ParametersWithIV ivParams = (ParametersWithIV) parameters;
  40. if (!(ivParams.Parameters is KeyParameter))
  41. throw new ArgumentException("VMPC Init parameters must include a key");
  42. KeyParameter key = (KeyParameter)ivParams.Parameters;
  43. this.workingIV = ivParams.GetIV();
  44. if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768)
  45. throw new ArgumentException("VMPC requires 1 to 768 bytes of IV");
  46. this.workingKey = key.GetKey();
  47. InitKey(this.workingKey, this.workingIV);
  48. }
  49. protected virtual void InitKey(
  50. byte[] keyBytes,
  51. byte[] ivBytes)
  52. {
  53. s = 0;
  54. P = new byte[256];
  55. for (int i = 0; i < 256; i++)
  56. {
  57. P[i] = (byte) i;
  58. }
  59. for (int m = 0; m < 768; m++)
  60. {
  61. s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff];
  62. byte temp = P[m & 0xff];
  63. P[m & 0xff] = P[s & 0xff];
  64. P[s & 0xff] = temp;
  65. }
  66. for (int m = 0; m < 768; m++)
  67. {
  68. s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff];
  69. byte temp = P[m & 0xff];
  70. P[m & 0xff] = P[s & 0xff];
  71. P[s & 0xff] = temp;
  72. }
  73. n = 0;
  74. }
  75. public virtual void ProcessBytes(
  76. byte[] input,
  77. int inOff,
  78. int len,
  79. byte[] output,
  80. int outOff)
  81. {
  82. Check.DataLength(input, inOff, len, "input buffer too short");
  83. Check.OutputLength(output, outOff, len, "output buffer too short");
  84. for (int i = 0; i < len; i++)
  85. {
  86. byte pn = P[n];
  87. s = P[(s + pn) & 0xff];
  88. byte ps = P[s];
  89. byte z = P[(P[ps] + 1) & 0xff];
  90. // encryption
  91. P[n] = ps;
  92. P[s] = pn;
  93. n = (byte)(n + 1);
  94. // xor
  95. output[i + outOff] = (byte)(input[i + inOff] ^ z);
  96. }
  97. }
  98. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  99. public virtual void ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
  100. {
  101. Check.OutputLength(output, input.Length, "output buffer too short");
  102. for (int i = 0; i < input.Length; i++)
  103. {
  104. byte pn = P[n];
  105. s = P[(s + pn) & 0xff];
  106. byte ps = P[s];
  107. byte z = P[(P[ps] + 1) & 0xff];
  108. // encryption
  109. P[n] = ps;
  110. P[s] = pn;
  111. n = (byte)(n + 1);
  112. // xor
  113. output[i] = (byte)(input[i] ^ z);
  114. }
  115. }
  116. #endif
  117. public virtual void Reset()
  118. {
  119. InitKey(this.workingKey, this.workingIV);
  120. }
  121. public virtual byte ReturnByte(
  122. byte input)
  123. {
  124. s = P[(s + P[n & 0xff]) & 0xff];
  125. byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff];
  126. // encryption
  127. byte temp = P[n & 0xff];
  128. P[n & 0xff] = P[s & 0xff];
  129. P[s & 0xff] = temp;
  130. n = (byte) ((n + 1) & 0xff);
  131. // xor
  132. return (byte) (input ^ z);
  133. }
  134. }
  135. }
  136. #pragma warning restore
  137. #endif