ISO7816d4Padding.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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 the padding according to the scheme referenced in
  10. * ISO 7814-4 - scheme 2 from ISO 9797-1. The first byte is 0x80, rest is 0x00
  11. */
  12. public class ISO7816d4Padding
  13. : IBlockCipherPadding
  14. {
  15. /**
  16. * Initialise the padder.
  17. *
  18. * @param random - a SecureRandom if available.
  19. */
  20. public void Init(
  21. SecureRandom random)
  22. {
  23. // nothing to do.
  24. }
  25. /**
  26. * Return the name of the algorithm the padder implements.
  27. *
  28. * @return the name of the algorithm the padder implements.
  29. */
  30. public string PaddingName
  31. {
  32. get { return "ISO7816-4"; }
  33. }
  34. public int AddPadding(byte[] input, int inOff)
  35. {
  36. int count = input.Length - inOff;
  37. input[inOff]= 0x80;
  38. while (++inOff < input.Length)
  39. {
  40. input[inOff] = 0x00;
  41. }
  42. return count;
  43. }
  44. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  45. public int AddPadding(Span<byte> block, int position)
  46. {
  47. int count = block.Length - position;
  48. block[position++] = 0x80;
  49. block[position..].Fill(0x00);
  50. return count;
  51. }
  52. #endif
  53. public int PadCount(byte[] input)
  54. {
  55. int position = -1, still00Mask = -1;
  56. int i = input.Length;
  57. while (--i >= 0)
  58. {
  59. int next = input[i];
  60. int match00Mask = ((next ^ 0x00) - 1) >> 31;
  61. int match80Mask = ((next ^ 0x80) - 1) >> 31;
  62. position ^= (i ^ position) & still00Mask & match80Mask;
  63. still00Mask &= match00Mask;
  64. }
  65. if (position < 0)
  66. throw new InvalidCipherTextException("pad block corrupted");
  67. return input.Length - position;
  68. }
  69. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  70. public int PadCount(ReadOnlySpan<byte> block)
  71. {
  72. int position = -1, still00Mask = -1;
  73. int i = block.Length;
  74. while (--i >= 0)
  75. {
  76. int next = block[i];
  77. int match00Mask = ((next ^ 0x00) - 1) >> 31;
  78. int match80Mask = ((next ^ 0x80) - 1) >> 31;
  79. position ^= (i ^ position) & still00Mask & match80Mask;
  80. still00Mask &= match00Mask;
  81. }
  82. if (position < 0)
  83. throw new InvalidCipherTextException("pad block corrupted");
  84. return block.Length - position;
  85. }
  86. #endif
  87. }
  88. }
  89. #pragma warning restore
  90. #endif