SicBlockCipher.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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.Math;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  7. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes
  8. {
  9. /**
  10. * Implements the Segmented Integer Counter (SIC) mode on top of a simple
  11. * block cipher.
  12. */
  13. public class SicBlockCipher
  14. : IBlockCipherMode
  15. {
  16. private readonly IBlockCipher cipher;
  17. private readonly int blockSize;
  18. private readonly byte[] counter;
  19. private readonly byte[] counterOut;
  20. private byte[] IV;
  21. /**
  22. * Basic constructor.
  23. *
  24. * @param c the block cipher to be used.
  25. */
  26. public SicBlockCipher(IBlockCipher cipher)
  27. {
  28. this.cipher = cipher;
  29. this.blockSize = cipher.GetBlockSize();
  30. this.counter = new byte[blockSize];
  31. this.counterOut = new byte[blockSize];
  32. this.IV = new byte[blockSize];
  33. }
  34. /**
  35. * return the underlying block cipher that we are wrapping.
  36. *
  37. * @return the underlying block cipher that we are wrapping.
  38. */
  39. public IBlockCipher UnderlyingCipher => cipher;
  40. public virtual void Init(
  41. bool forEncryption, //ignored by this CTR mode
  42. ICipherParameters parameters)
  43. {
  44. ParametersWithIV ivParam = parameters as ParametersWithIV;
  45. if (ivParam == null)
  46. throw new ArgumentException("CTR/SIC mode requires ParametersWithIV", "parameters");
  47. this.IV = Arrays.Clone(ivParam.GetIV());
  48. if (blockSize < IV.Length)
  49. throw new ArgumentException("CTR/SIC mode requires IV no greater than: " + blockSize + " bytes.");
  50. int maxCounterSize = System.Math.Min(8, blockSize / 2);
  51. if (blockSize - IV.Length > maxCounterSize)
  52. throw new ArgumentException("CTR/SIC mode requires IV of at least: " + (blockSize - maxCounterSize) + " bytes.");
  53. // if null it's an IV changed only.
  54. if (ivParam.Parameters != null)
  55. {
  56. cipher.Init(true, ivParam.Parameters);
  57. }
  58. Reset();
  59. }
  60. public virtual string AlgorithmName
  61. {
  62. get { return cipher.AlgorithmName + "/SIC"; }
  63. }
  64. public virtual bool IsPartialBlockOkay
  65. {
  66. get { return true; }
  67. }
  68. public virtual int GetBlockSize()
  69. {
  70. return cipher.GetBlockSize();
  71. }
  72. public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
  73. {
  74. cipher.ProcessBlock(counter, 0, counterOut, 0);
  75. //
  76. // XOR the counterOut with the plaintext producing the cipher text
  77. //
  78. for (int i = 0; i < counterOut.Length; i++)
  79. {
  80. output[outOff + i] = (byte)(counterOut[i] ^ input[inOff + i]);
  81. }
  82. // Increment the counter
  83. int j = counter.Length;
  84. while (--j >= 0 && ++counter[j] == 0)
  85. {
  86. }
  87. return counter.Length;
  88. }
  89. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  90. public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
  91. {
  92. cipher.ProcessBlock(counter, 0, counterOut, 0);
  93. //
  94. // XOR the counterOut with the plaintext producing the cipher text
  95. //
  96. for (int i = 0; i < counterOut.Length; i++)
  97. {
  98. output[i] = (byte)(counterOut[i] ^ input[i]);
  99. }
  100. // Increment the counter
  101. int j = counter.Length;
  102. while (--j >= 0 && ++counter[j] == 0)
  103. {
  104. }
  105. return counter.Length;
  106. }
  107. #endif
  108. public virtual void Reset()
  109. {
  110. Arrays.Fill(counter, (byte)0);
  111. Array.Copy(IV, 0, counter, 0, IV.Length);
  112. }
  113. }
  114. }
  115. #pragma warning restore
  116. #endif