Pkcs7Padding.cs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
  6. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Paddings
  7. {
  8. /**
  9. * A padder that adds Pkcs7/Pkcs5 padding to a block.
  10. */
  11. public class Pkcs7Padding
  12. : IBlockCipherPadding
  13. {
  14. /**
  15. * Initialise the padder.
  16. *
  17. * @param random - a SecureRandom if available.
  18. */
  19. public void Init(
  20. SecureRandom random)
  21. {
  22. // nothing to do.
  23. }
  24. /**
  25. * Return the name of the algorithm the cipher implements.
  26. *
  27. * @return the name of the algorithm the cipher implements.
  28. */
  29. public string PaddingName
  30. {
  31. get { return "PKCS7"; }
  32. }
  33. public int AddPadding(byte[] input, int inOff)
  34. {
  35. int count = input.Length - inOff;
  36. byte padValue = (byte)count;
  37. while (inOff < input.Length)
  38. {
  39. input[inOff++] = padValue;
  40. }
  41. return count;
  42. }
  43. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  44. public int AddPadding(Span<byte> block, int position)
  45. {
  46. int count = block.Length - position;
  47. byte padValue = (byte)count;
  48. block[position..].Fill(padValue);
  49. return count;
  50. }
  51. #endif
  52. public int PadCount(byte[] input)
  53. {
  54. byte padValue = input[input.Length - 1];
  55. int count = padValue;
  56. int position = input.Length - count;
  57. int failed = (position | (count - 1)) >> 31;
  58. for (int i = 0; i < input.Length; ++i)
  59. {
  60. failed |= (input[i] ^ padValue) & ~((i - position) >> 31);
  61. }
  62. if (failed != 0)
  63. throw new InvalidCipherTextException("pad block corrupted");
  64. return count;
  65. }
  66. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  67. public int PadCount(ReadOnlySpan<byte> block)
  68. {
  69. byte padValue = block[block.Length - 1];
  70. int count = padValue;
  71. int position = block.Length - count;
  72. int failed = (position | (count - 1)) >> 31;
  73. for (int i = 0; i < block.Length; ++i)
  74. {
  75. failed |= (block[i] ^ padValue) & ~((i - position) >> 31);
  76. }
  77. if (failed != 0)
  78. throw new InvalidCipherTextException("pad block corrupted");
  79. return count;
  80. }
  81. #endif
  82. }
  83. }
  84. #pragma warning restore
  85. #endif