#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) #pragma warning disable using System; using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security; namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Paddings { /// A padder that adds Trailing-Bit-Compliment padding to a block. ///

/// This padding pads the block out compliment of the last bit /// of the plain text. ///

///
public class TbcPadding : IBlockCipherPadding { /// Return the name of the algorithm the cipher implements. /// the name of the algorithm the cipher implements. /// public string PaddingName { get { return "TBC"; } } /// Initialise the padder. /// - a SecureRandom if available. /// public virtual void Init(SecureRandom random) { // nothing to do. } /// add the pad bytes to the passed in block, returning the number of bytes added. /// /// This assumes that the last block of plain text is always passed to it inside . /// i.e. if is zero, indicating the padding will fill the entire block,the value of /// should be the same as the last block of plain text. /// public virtual int AddPadding(byte[] input, int inOff) { int count = input.Length - inOff; byte lastByte = inOff > 0 ? input[inOff - 1] : input[input.Length - 1]; byte padValue = (byte)((lastByte & 1) - 1); while (inOff < input.Length) { input[inOff++] = padValue; } return count; } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER /// add the pad bytes to the passed in block, returning the number of bytes added. /// /// This assumes that the last block of plain text is always passed to it inside . /// i.e. if is zero, indicating the padding will fill the entire block,the value of /// should be the same as the last block of plain text. /// public virtual int AddPadding(Span block, int position) { byte lastByte = position > 0 ? block[position - 1] : block[block.Length - 1]; byte padValue = (byte)((lastByte & 1) - 1); var padding = block[position..]; padding.Fill(padValue); return padding.Length; } #endif public virtual int PadCount(byte[] input) { int i = input.Length; int code = input[--i], count = 1, countingMask = -1; while (--i >= 0) { int next = input[i]; int matchMask = ((next ^ code) - 1) >> 31; countingMask &= matchMask; count -= countingMask; } return count; } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER public virtual int PadCount(ReadOnlySpan block) { int i = block.Length; int code = block[--i], count = 1, countingMask = -1; while (--i >= 0) { int next = block[i]; int matchMask = ((next ^ code) - 1) >> 31; countingMask &= matchMask; count -= countingMask; } return count; } #endif } } #pragma warning restore #endif