TbcPadding.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
  5. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Paddings
  6. {
  7. /// <summary> A padder that adds Trailing-Bit-Compliment padding to a block.
  8. /// <p>
  9. /// This padding pads the block out compliment of the last bit
  10. /// of the plain text.
  11. /// </p>
  12. /// </summary>
  13. public class TbcPadding
  14. : IBlockCipherPadding
  15. {
  16. /// <summary> Return the name of the algorithm the cipher implements.</summary>
  17. /// <returns> the name of the algorithm the cipher implements.
  18. /// </returns>
  19. public string PaddingName
  20. {
  21. get { return "TBC"; }
  22. }
  23. /// <summary> Initialise the padder.</summary>
  24. /// <param name="random">- a SecureRandom if available.
  25. /// </param>
  26. public virtual void Init(SecureRandom random)
  27. {
  28. // nothing to do.
  29. }
  30. /// <summary> add the pad bytes to the passed in block, returning the number of bytes added.</summary>
  31. /// <remarks>
  32. /// This assumes that the last block of plain text is always passed to it inside <paramref name="input"/>.
  33. /// i.e. if <paramref name="inOff"/> is zero, indicating the padding will fill the entire block,the value of
  34. /// <paramref name="input"/> should be the same as the last block of plain text.
  35. /// </remarks>
  36. public virtual int AddPadding(byte[] input, int inOff)
  37. {
  38. int count = input.Length - inOff;
  39. byte lastByte = inOff > 0 ? input[inOff - 1] : input[input.Length - 1];
  40. byte padValue = (byte)((lastByte & 1) - 1);
  41. while (inOff < input.Length)
  42. {
  43. input[inOff++] = padValue;
  44. }
  45. return count;
  46. }
  47. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  48. /// <summary> add the pad bytes to the passed in block, returning the number of bytes added.</summary>
  49. /// <remarks>
  50. /// This assumes that the last block of plain text is always passed to it inside <paramref name="block"/>.
  51. /// i.e. if <paramref name="position"/> is zero, indicating the padding will fill the entire block,the value of
  52. /// <paramref name="block"/> should be the same as the last block of plain text.
  53. /// </remarks>
  54. public virtual int AddPadding(Span<byte> block, int position)
  55. {
  56. byte lastByte = position > 0 ? block[position - 1] : block[block.Length - 1];
  57. byte padValue = (byte)((lastByte & 1) - 1);
  58. var padding = block[position..];
  59. padding.Fill(padValue);
  60. return padding.Length;
  61. }
  62. #endif
  63. public virtual int PadCount(byte[] input)
  64. {
  65. int i = input.Length;
  66. int code = input[--i], count = 1, countingMask = -1;
  67. while (--i >= 0)
  68. {
  69. int next = input[i];
  70. int matchMask = ((next ^ code) - 1) >> 31;
  71. countingMask &= matchMask;
  72. count -= countingMask;
  73. }
  74. return count;
  75. }
  76. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  77. public virtual int PadCount(ReadOnlySpan<byte> block)
  78. {
  79. int i = block.Length;
  80. int code = block[--i], count = 1, countingMask = -1;
  81. while (--i >= 0)
  82. {
  83. int next = block[i];
  84. int matchMask = ((next ^ code) - 1) >> 31;
  85. countingMask &= matchMask;
  86. count -= countingMask;
  87. }
  88. return count;
  89. }
  90. #endif
  91. }
  92. }
  93. #pragma warning restore
  94. #endif