XTEAEngine.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  7. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
  8. {
  9. /**
  10. * An XTEA engine.
  11. */
  12. public class XteaEngine
  13. : IBlockCipher
  14. {
  15. private const int
  16. rounds = 32,
  17. block_size = 8,
  18. // key_size = 16,
  19. delta = unchecked((int) 0x9E3779B9);
  20. /*
  21. * the expanded key array of 4 subkeys
  22. */
  23. private uint[] _S = new uint[4],
  24. _sum0 = new uint[32],
  25. _sum1 = new uint[32];
  26. private bool _initialised, _forEncryption;
  27. /**
  28. * Create an instance of the TEA encryption algorithm
  29. * and set some defaults
  30. */
  31. public XteaEngine()
  32. {
  33. _initialised = false;
  34. }
  35. public virtual string AlgorithmName
  36. {
  37. get { return "XTEA"; }
  38. }
  39. public virtual int GetBlockSize()
  40. {
  41. return block_size;
  42. }
  43. /**
  44. * initialise
  45. *
  46. * @param forEncryption whether or not we are for encryption.
  47. * @param params the parameters required to set up the cipher.
  48. * @exception ArgumentException if the params argument is
  49. * inappropriate.
  50. */
  51. public virtual void Init(
  52. bool forEncryption,
  53. ICipherParameters parameters)
  54. {
  55. if (!(parameters is KeyParameter))
  56. {
  57. throw new ArgumentException("invalid parameter passed to TEA init - "
  58. + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
  59. }
  60. _forEncryption = forEncryption;
  61. _initialised = true;
  62. KeyParameter p = (KeyParameter) parameters;
  63. setKey(p.GetKey());
  64. }
  65. public virtual int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
  66. {
  67. if (!_initialised)
  68. throw new InvalidOperationException(AlgorithmName + " not initialised");
  69. Check.DataLength(inBytes, inOff, block_size, "input buffer too short");
  70. Check.OutputLength(outBytes, outOff, block_size, "output buffer too short");
  71. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  72. return _forEncryption
  73. ? EncryptBlock(inBytes.AsSpan(inOff), outBytes.AsSpan(outOff))
  74. : DecryptBlock(inBytes.AsSpan(inOff), outBytes.AsSpan(outOff));
  75. #else
  76. return _forEncryption
  77. ? EncryptBlock(inBytes, inOff, outBytes, outOff)
  78. : DecryptBlock(inBytes, inOff, outBytes, outOff);
  79. #endif
  80. }
  81. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  82. public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
  83. {
  84. if (!_initialised)
  85. throw new InvalidOperationException(AlgorithmName + " not initialised");
  86. Check.DataLength(input, block_size, "input buffer too short");
  87. Check.OutputLength(output, block_size, "output buffer too short");
  88. return _forEncryption
  89. ? EncryptBlock(input, output)
  90. : DecryptBlock(input, output);
  91. }
  92. #endif
  93. /**
  94. * Re-key the cipher.
  95. *
  96. * @param key the key to be used
  97. */
  98. private void setKey(
  99. byte[] key)
  100. {
  101. int i, j;
  102. for (i = j = 0; i < 4; i++,j+=4)
  103. {
  104. _S[i] = Pack.BE_To_UInt32(key, j);
  105. }
  106. for (i = j = 0; i < rounds; i++)
  107. {
  108. _sum0[i] = ((uint)j + _S[j & 3]);
  109. j += delta;
  110. _sum1[i] = ((uint)j + _S[j >> 11 & 3]);
  111. }
  112. }
  113. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  114. private int EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
  115. {
  116. // Pack bytes into integers
  117. uint v0 = Pack.BE_To_UInt32(input);
  118. uint v1 = Pack.BE_To_UInt32(input[4..]);
  119. for (int i = 0; i < rounds; i++)
  120. {
  121. v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i];
  122. v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i];
  123. }
  124. Pack.UInt32_To_BE(v0, output);
  125. Pack.UInt32_To_BE(v1, output[4..]);
  126. return block_size;
  127. }
  128. private int DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
  129. {
  130. // Pack bytes into integers
  131. uint v0 = Pack.BE_To_UInt32(input);
  132. uint v1 = Pack.BE_To_UInt32(input[4..]);
  133. for (int i = rounds - 1; i >= 0; i--)
  134. {
  135. v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i];
  136. v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i];
  137. }
  138. Pack.UInt32_To_BE(v0, output);
  139. Pack.UInt32_To_BE(v1, output[4..]);
  140. return block_size;
  141. }
  142. #else
  143. private int EncryptBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
  144. {
  145. uint v0 = Pack.BE_To_UInt32(inBytes, inOff);
  146. uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4);
  147. for (int i = 0; i < rounds; i++)
  148. {
  149. v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i];
  150. v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i];
  151. }
  152. Pack.UInt32_To_BE(v0, outBytes, outOff);
  153. Pack.UInt32_To_BE(v1, outBytes, outOff + 4);
  154. return block_size;
  155. }
  156. private int DecryptBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
  157. {
  158. // Pack bytes into integers
  159. uint v0 = Pack.BE_To_UInt32(inBytes, inOff);
  160. uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4);
  161. for (int i = rounds-1; i >= 0; i--)
  162. {
  163. v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i];
  164. v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i];
  165. }
  166. Pack.UInt32_To_BE(v0, outBytes, outOff);
  167. Pack.UInt32_To_BE(v1, outBytes, outOff + 4);
  168. return block_size;
  169. }
  170. #endif
  171. }
  172. }
  173. #pragma warning restore
  174. #endif