TEAEngine.cs 5.3 KB

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