Einzelnen Beitrag anzeigen

Kas Ob.

Registriert seit: 3. Sep 2023
365 Beiträge
 
#13

AW: Kleines Weihnachtsgeschenk von der DEC

  Alt 2. Jan 2025, 15:14
Well, here my thought on how this can be, and sorry again it is here.

@TurboMagic , you are the maintainer so it is up to you for naming and length limiting, the limit i mentioned in earlier posts, for me the whole padding scheme is critical, well when it is critical, see the point of using padding is to protect the data integrity, and the code below does that, only it is relaxed for its usage (a little)

also from https://crypto.stackexchange.com/que...o7816-and-x923
Zitat:
If used in an unauthenticated scheme, the bytes should be checked for correctness, since some attacker advantage could be achieved through their manipulation. Verification is done with bitwise OR against those bytes, which then must either equal 0x00 for ANSI or the length byte for PKCS#7 padding.
Both only support up to 255 bytes of padding.
So my proposed implementation is about both usage, you can strict the checking by applying the BlockSize for a value above 0, also combining the usage with MinLength, makes these useful, for the limit padding lengths (PKCS#7,PKCS#5) and none limited lengths like ISO-7816 (the one known as 1zero)

Delphi-Quellcode:
{*****************************************************************************
  The DEC team (see file NOTICE.txt) licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License. A copy of this licence is found in the root directory
  of this project in the file LICENCE.txt or alternatively at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
*****************************************************************************}

unit DECCipherPaddings;
{$INCLUDE DECOptions.inc}

interface

uses
  {$IFDEF FPC}
  SysUtils,
  {$ELSE}
  System.SysUtils,
  {$ENDIF}
  DECRandom,
  DECTypes;

type
  /// <summary>
  /// Base class for implementing block padding algorithms.
  /// </summary>
  /// <remarks>
  /// Padding algorithms are used to fill data to a specific block size when the
  /// data length is not an integer multiple of the block size.
  /// This abstract class defines the basic interfaces for adding, validating,
  /// and removing padding.
  /// </remarks>
  TDECPadding = class abstract
  protected
    class procedure DoPadding(var Data : TBytes;
                              Start : Integer); virtual; abstract;
  public
    /// <summary>
    /// Adds padding to the specified data to align it with the given block size.
    /// </summary>
    /// <param name="Data">
    /// The data to be padded.
    /// </param>
    /// <param name="BlockSize">
    /// The block size to align the data with.
    /// </param>
    /// <returns>
    /// The padded data.
    /// </returns>
    /// <remarks>
    /// The specific method of padding depends on the implementation of the subclass.
    /// </remarks>
    class function AddPadding(const Data : TBytes;
                              BlockSize : Integer;
                              MinLength : Integer = 0): TBytes; overload; virtual; abstract;

    // <summary>
    /// Adds PKCS#7 padding to a string.
    /// </summary>
    /// <param name="data">
    /// The string to which padding should be added.
    /// </param>
    /// <param name="BlockSize">
    /// The block size in byte to align the data with.
    /// </param>
    /// <returns>
    /// A new byte string with PKCS#7 padding applied.
    /// </returns>
    /// <remarks>
    /// PKCS#7 padding, as defined in RFC 5652 (which updates RFC 2315), adds
    /// bytes to the end of the data so that the total length is a multiple of
    /// the block size. Each padding byte contains the number of padding bytes
    /// added. For example, if 5 bytes of padding are needed, each of the 5
    /// padding bytes will have the value $5.
    /// <para>
    /// Call this method before starting encryption.
    // </para>
    /// </remarks>
    class function AddPadding(const Data : string;
                              BlockSize : Integer;
                              MinLength : Integer = 0): string; overload; virtual; abstract;
    // <summary>
    /// Adds PKCS#7 padding to a raw byte string.
    /// </summary>
    /// <param name="data">
    /// The raw byte string to which padding should be added.
    /// </param>
    /// <param name="BlockSize">
    /// The block size in byte to align the data with.
    /// </param>
    /// <returns>
    /// A new byte raw byte string with PKCS#7 padding applied.
    /// </returns>
    /// <remarks>
    /// PKCS#7 padding, as defined in RFC 5652 (which updates RFC 2315), adds
    /// bytes to the end of the data so that the total length is a multiple of
    /// the block size. Each padding byte contains the number of padding bytes
    /// added. For example, if 5 bytes of padding are needed, each of the 5
    /// padding bytes will have the value $5.
    /// <para>
    /// Call this method before starting encryption.
    /// </para>
    /// </remarks>
    class function AddPadding(const Data : RawByteString;
                              BlockSize : Integer;
                              MinLength : Integer = 0): RawByteString; overload; virtual; abstract;
    /// <summary>
    /// Checks if the specified data contains valid padding.
    /// </summary>
    /// <param name="Data">
    /// The data to be checked.
    /// </param>
    /// <param name="BlockSize">
    /// The expected block size.
    /// </param>
    /// <returns>
    /// True if the padding is valid; otherwise, False.
    /// </returns>
    /// <remarks>
    /// This method is used to ensure the integrity and consistency of the padding.
    /// </remarks>
    class function HasValidPadding(const Data : TBytes;
                                   BlockSize : Integer = 0): Boolean; virtual; abstract;
    /// <summary>
    /// Removes padding from the specified data.
    /// </summary>
    /// <param name="Data">
    /// The data from which padding will be removed.
    /// </param>
    /// <param name="BlockSize">
    /// The block size in bytes used for padding.
    /// </param>
    /// <returns>
    /// The original data without padding.
    /// </returns>
    /// <remarks>
    /// This method assumes that the padding has already been validated.
    /// </remarks>
    class function RemovePadding(const Data : TBytes;
                                 BlockSize : Integer = 0): TBytes; overload; virtual; abstract;
    // <summary>
    /// Removes PKCS#7 padding from a raw byte string.
    /// </summary>
    /// <param name="data">
    /// The padded byte raw byte string.
    /// </param>
    /// <param name="BlockSize">
    /// The block size in bytes used for padding.
    /// </param>
    /// <returns>
    /// A new raw byte string with the padding removed. Raises an exception
    /// if the padding is invalid.
    /// </returns>
    /// <exception cref="EDECCipherException">
    /// Raised if the padding is invalid or missing.
    /// </exception>
    /// <remarks>
    /// This function checks for valid PKCS#7 padding and raises an
    /// `EDECCipherException` exception if the padding is incorrect. This
    /// includes cases where the final bytes do not match the pad count or if
    /// the pad count is greater than the block size.
    /// <para>
    /// Call this method after decryption.
    /// </para>
    /// </remarks>
    class function RemovePadding(const Data : RawByteString;
                                 BlockSize : Integer = 0): RawByteString; overload; virtual; abstract;
    // <summary>
    /// Removes PKCS#7 padding from a string.
    /// </summary>
    /// <param name="data">
    /// The padded byte raw byte string.
    /// </param>
    /// <param name="BlockSize">
    /// The block size in bytes used for padding.
    /// </param>
    /// <returns>
    /// A new raw byte string with the padding removed. Raises an exception
    /// if the padding is invalid.
    /// </returns>
    /// <exception cref="EDECCipherException">
    /// Raised if the padding is invalid or missing.
    /// </exception>
    /// <remarks>
    /// This function checks for valid PKCS#7 padding and raises an
    /// `EDECCipherException` exception if the padding is incorrect. This
    /// includes cases where the final bytes do not match the pad count or if
    /// the pad count is greater than the block size.
    /// <para>
    /// Call this method after decryption.
    /// </para>
    /// </remarks>
    class function RemovePadding(const Data : string;
                                 BlockSize : Integer = 0): string; overload; virtual; abstract;
  end;

  TDECPaddingCommon = class(TDECPadding)
  protected
    class function CalculatePaddingLength(DataLength : Integer ;
                                    BlockSize: Integer;
                                    MinLength: Integer = 0): Integer;
  public
    class function AddPadding(const Data: string;
                              BlockSize: Integer;
                              MinLength : Integer = 0): string; override;
    class function AddPadding(const Data : RawByteString;
                              BlockSize : Integer;
                              MinLength : Integer = 0): RawByteString; override;
    class function RemovePadding(const Data : string;
                                 BlockSize : Integer = 0): string; override;
    class function RemovePadding(const Data : RawByteString;
                                 BlockSize : Integer = 0): RawByteString; override;
  end;


  /// <summary>
  /// Implementation of the PKCS7 padding algorithm.
  /// </summary>
  /// <remarks>
  /// PKCS7 padding is a standard algorithm used in symmetric cryptosystems like AES.
  /// It appends the number of padding bytes as the value of the padding itself.
  /// </remarks>
  TDECPKCS7Padding = class(TDECPaddingCommon)
  protected
    class procedure DoPadding(var Data : TBytes;
                              Start : Integer); reintroduce; virtual;
  public
    /// <summary>
    /// Adds PKCS7 padding to the specified data.
    /// </summary>
    /// <param name="Data">
    /// The data to be padded.
    /// </param>
    /// <param name="BlockSize">
    /// The block size in byte to align the data with.
    /// </param>
    /// <returns>
    /// The padded data following the PKCS7 algorithm.
    /// </returns>
    class function AddPadding(const Data: TBytes; BlockSize: Integer; MinLength:
        Integer = 0): TBytes; override;
    /// <summary>
    /// Checks if the specified data contains valid padding.
    /// </summary>
    /// <param name="Data">
    /// The data to be checked.
    /// </param>
    /// <param name="BlockSize">
    /// The expected block size.
    /// </param>
    /// <returns>
    /// True if the padding is valid; otherwise, False.
    /// </returns>
    /// <remarks>
    /// This method is used to ensure the integrity and consistency of the padding.
    /// </remarks>
    class function HasValidPadding(const Data : TBytes;
                                   BlockSize : Integer = 0): Boolean; override;
    /// <summary>
    /// Removes PKCS7 padding from the specified data.
    /// </summary>
    /// <param name="Data">
    /// The data from which padding will be removed.
    /// </param>
    /// <param name="BlockSize">
    /// The block size used for padding.
    /// </param>
    /// <exception cref="EDECCipherException">
    /// Raised if the padding is invalid or missing.
    /// </exception>
    /// <returns>
    /// The original data without padding.
    /// </returns>
    class function RemovePadding(const Data : TBytes;
                                 BlockSize : Integer = 0): TBytes; override;
  end;

  TDECPKCS5Padding = class(TDECPaddingCommon)
  protected
    class procedure DoPadding(var Data : TBytes;
                              Start : Integer); reintroduce; virtual;
  public
    class function AddPadding(const Data: TBytes; BlockSize: Integer; MinLength:
        Integer = 0): TBytes; override;
    class function HasValidPadding(const Data : TBytes;
                                   BlockSize : Integer = 0): Boolean; override;
    class function RemovePadding(const Data : TBytes;
                                 BlockSize : Integer = 0): TBytes; override;
  end;

// https://www.ibm.com/docs/en/linux-on-systems?topic=processes-ansi-x923-cipher-block-chaining
// https://crypto.stackexchange.com/questions/61689/what-is-ansi-x-923-padding-standard
// Doesn't need specific fill for padding (like random, 0, or soecific value) but limited to block size of 8
  TDECANSIX923Padding = class(TDECPaddingCommon)
  protected
    class procedure DoPadding(var Data : TBytes;
                              Start : Integer); reintroduce; virtual;
  public
    class function AddPadding(const Data: TBytes; BlockSize: Integer; MinLength:
        Integer = 0): TBytes; override;
    class function HasValidPadding(const Data : TBytes;
                                   BlockSize : Integer = 0): Boolean; override;
    class function RemovePadding(const Data : TBytes;
                                 BlockSize : Integer = 0): TBytes; override;
  end;

  // both are limited to 8 bytes in their original references so both should not be used with AES or any modern standard
  // but many modern uses and implementation remove this limitiation
  // for Ansi X9.23 random fill used here, but in many implmentation it is zero, while ISO 10126 is random fill
  TDECISO10126Padding = class(TDECPaddingCommon)
  protected
    class procedure DoPadding(var Data : TBytes;
                              Start : Integer); reintroduce; virtual;
  public
    class function AddPadding(const Data: TBytes; BlockSize: Integer; MinLength:
        Integer = 0): TBytes; override;
    class function HasValidPadding(const Data : TBytes;
                                   BlockSize : Integer = 0): Boolean; override;
    class function RemovePadding(const Data : TBytes;
                                 BlockSize : Integer = 0): TBytes; override;
  end;


  TDECISO7816Padding = class(TDECPaddingCommon)
  protected
    class procedure DoPadding(var Data : TBytes; Start : Integer); reintroduce; virtual;
  public
    class function AddPadding(const Data: TBytes; BlockSize: Integer; MinLength:
        Integer = 0): TBytes; override;
    class function HasValidPadding(const Data : TBytes;
                                   BlockSize : Integer = 0): Boolean; override;
    class function RemovePadding(const Data : TBytes;
                                 BlockSize : Integer = 0): TBytes; override;
  end;

  TDECOneZeroesPadding = TDECISO7816Padding;

  // W3C padding mainly used in XML encryption
  // https://www.w3.org/TR/xmlenc-core1/#sec-Padding
  // It require arbitrary fill (can be random), so we can use our ISO 10126
  TDECW3CPadding = TDECISO10126Padding;


// additional resources
// https://www.cryptosys.net/pki/manpki/pki_paddingschemes.html
// https://crypto.stackexchange.com/questions/31372/what-are-the-relative-merits-of-padding-algorithms-pkcs7-iso7816-and-x923
implementation

uses
  DECUtil;

{ TPaddingCommon }

class function TDECPaddingCommon.CalculatePaddingLength(DataLength, BlockSize, MinLength: Integer): Integer;
begin
  if (MinLength < 0) or (DataLength < 0) or (BlockSize < 0) or (MinLength or BlockSize = 0) then
  begin
    Result := -1;
  end
  else if MinLength <= DataLength then
  begin
    Result := DataLength + BlockSize - (DataLength mod BlockSize);
  end
  else
  begin
    Result := MinLength;
    if BlockSize > 0 then
      Result := Result + BlockSize - ((MinLength - 1) mod BlockSize) - 1;
  end;
end;

class function TDECPaddingCommon.AddPadding(const Data: RawByteString; BlockSize, MinLength: Integer): RawByteString;
var
  Buf: TBytes;
begin
  Buf := AddPadding(RawStringToBytes(Data), BlockSize);
  Result := BytesToRawString(Buf);
  ProtectBytes(Buf);
end;

class function TDECPaddingCommon.AddPadding(const Data: string; BlockSize, MinLength: Integer): string;
var
  Buf: TBytes;
begin
  Buf := AddPadding(StringToBytes(Data), BlockSize);
  Result := BytesToString(Buf);
  ProtectBytes(Buf);
end;

class function TDECPaddingCommon.RemovePadding(const Data: RawByteString; BlockSize: Integer = 0): RawByteString;
var
  Buf: TBytes;
begin
  Buf := RemovePadding(RawStringToBytes(Data), BlockSize);
  Result := BytesToRawString(Buf);
  ProtectBytes(Buf);
end;

class function TDECPaddingCommon.RemovePadding(const Data: string; BlockSize: Integer = 0): string;
var
  Buf: TBytes;
begin
  Buf := RemovePadding(StringToBytes(Data), BlockSize);
  Result := BytesToString(Buf);
  ProtectBytes(Buf);
end;


{ TPKCS7Padding }

class procedure TDECPKCS7Padding.DoPadding(var Data: TBytes; Start: Integer);
var
  I: Integer;
  PadByte: Byte;
begin
  PadByte := Length(Data) - Start;

  if PadByte < 1 then
    raise EDECCipherException.Create('Invalid PKCS#7 Padding operation');

  for I := Start to High(Data) do
    Data[I] := PadByte;
end;

class function TDECPKCS7Padding.AddPadding(const Data: TBytes; BlockSize: Integer; MinLength: Integer = 0): TBytes;
var
  ResLength: Integer;
begin
  ResLength := CalculatePaddingLength(Length(Data), BlockSize, MinLength);

  if (ResLength < 0) or (ResLength - Length(Data) > 255) then
    raise EDECCipherException.Create('Invalid PKCS#7 Padding operation');

  SetLength(Result, ResLength);

  if Length(Data) > 0 then
    Move(Data[0], Result[0], Length(Data));

  DoPadding(Result, Length(Data));
end;

class function TDECPKCS7Padding.HasValidPadding(const Data: TBytes; BlockSize: integer = 0): boolean;
var
  PadLength: Integer;
  I: Integer;
begin
  Result := False;
  if (Length(Data) = 0) or ((BlockSize > 0) and (Length(Data) mod BlockSize <> 0)) then
    exit;

  PadLength := Data[High(Data)];
  for I := Length(Data) - PadLength to High(Data) do
    if Data[I] <> PadLength then
      exit;

  Result := True;
end;

class function TDECPKCS7Padding.RemovePadding(const Data: TBytes; BlockSize: integer = 0): TBytes;
var
  PadLength: Integer;
begin
  if not HasValidPadding(Data, BlockSize) then
    raise EDECCipherException.Create('Invalid PKCS#7 padding');
  PadLength := Data[High(Data)];
  SetLength(Result, Length(Data) - PadLength);
  if length(Result) > 0 then
    Move(Data[0], Result[0], Length(Result));
end;


{ TDECPKCS5Padding }

class procedure TDECPKCS5Padding.DoPadding(var Data: TBytes; Start: Integer);
var
  I: Integer;
  PadByte: Byte;
begin
  PadByte := Length(Data) - Start;

  // limiting PadByte to less 8 is the correct form , but its usage is really outdated, by removing this
  // but by removing the limit we almost have the PKCS7, which should be used instead
  if (PadByte < 1) {or (PadByte>8)} then
    raise EDECCipherException.Create('Invalid PKCS#5 Padding operation');

  for I := Start to High(Data) do
    Data[I] := PadByte;
end;

class function TDECPKCS5Padding.AddPadding(const Data: TBytes; BlockSize, MinLength: Integer): TBytes;
var
  ResLength: Integer;
begin
  ResLength := CalculatePaddingLength(Length(Data), BlockSize, MinLength);

  if (ResLength < 0) or (ResLength - Length(Data) > 255) then
    raise EDECCipherException.Create('Invalid PKCS#5 Padding operation');

  SetLength(Result, ResLength);

  if Length(Data) > 0 then
    Move(Data[0], Result[0], Length(Data));

  DoPadding(Result, Length(Data));
end;

class function TDECPKCS5Padding.HasValidPadding(const Data: TBytes; BlockSize: Integer): Boolean;
var
  PadLength: Integer;
  I: Integer;
begin
  Result := False;
  if (Length(Data) = 0) or ((BlockSize > 0) and (Length(Data) mod BlockSize <> 0)) then
    exit;

  PadLength := Data[High(Data)];
  if PadLength > 8 then // PKCS5 is outdated and limited to 8 bytes
    Exit;

  for I := Length(Data) - PadLength to High(Data) do
    if Data[I] <> PadLength then
      exit;

  Result := True;
end;

class function TDECPKCS5Padding.RemovePadding(const Data: TBytes; BlockSize: Integer): TBytes;
var
  PadLength: Integer;
begin
  if not HasValidPadding(Data, BlockSize) then
    raise EDECCipherException.Create('Invalid PKCS#5 padding');
  PadLength := Data[High(Data)];
  SetLength(Result, Length(Data) - PadLength);
  if length(Result) > 0 then
    Move(Data[0], Result[0], Length(Result));
end;


{ TANSIX923Padding }

class procedure TDECANSIX923Padding.DoPadding(var Data: TBytes; Start: Integer);
var
  PadByte: Byte;
begin
  PadByte := Length(Data) - Start;

  if PadByte < 1 then
    raise EDECCipherException.Create('Invalid ANSI X9.23 Padding operation');

  //RandomBuffer(Data[Start], PadByte); // comment for zero fill

  Data[High(Data)] := PadByte;
end;

class function TDECANSIX923Padding.AddPadding(const Data: TBytes; BlockSize, MinLength: Integer): TBytes;
var
  ResLength: Integer;
begin
  {if (BlockSize <> 8) and (MinLength mod 8 <> 0)and ((Length(Data)-MinLength) >= 8) then  // for limiting the length to one block of 8 bytes
    raise EDECCipherException.Create('Invalid ANSI X9.23 Padding operation'); }

  ResLength := CalculatePaddingLength(Length(Data), BlockSize, MinLength);

  if (ResLength < 0) or (ResLength - Length(Data) > 255) then
    raise EDECCipherException.Create('Invalid ANSI X9.23 Padding operation');

  SetLength(Result, ResLength);

  if Length(Data) > 0 then
    Move(Data[0], Result[0], Length(Data));

  DoPadding(Result, Length(Data));
end;

class function TDECANSIX923Padding.HasValidPadding(const Data: TBytes; BlockSize: Integer): Boolean;
var
  PadLength: Integer;
begin
  Result := False;
  {if (Length(Data) = 0) or ((BlockSize <> 8)and (BlockSize<>0) and (Length(Data) mod BlockSize <> 0)) then  // for limiting the length to one block of 8 bytes
    exit; }

  if (Length(Data) = 0) or ((BlockSize > 0) and (Length(Data) mod BlockSize <> 0)) then
    exit;

  PadLength := Data[High(Data)];

  {if PadLength > 8 then            // for limiting the length to one block of 8 bytes
    Exit;}

  if PadLength > Length(Data) then
    Exit;

  Result := True;
end;

class function TDECANSIX923Padding.RemovePadding(const Data: TBytes; BlockSize: Integer): TBytes;
var
  PadLength: Integer;
begin
  if not HasValidPadding(Data, BlockSize) then
    raise EDECCipherException.Create('Invalid ANSI X9.23 padding');

  PadLength := Data[High(Data)];
  SetLength(Result, Length(Data) - PadLength);

  if length(Result) > 0 then
    Move(Data[0], Result[0], Length(Result));
end;


{ TDECISO10126Padding }

class procedure TDECISO10126Padding.DoPadding(var Data: TBytes; Start: Integer);
var
  PadByte: Byte;
begin
  PadByte := Length(Data) - Start;

  if PadByte < 1 then
    raise EDECCipherException.Create('Invalid ISO 10126 Padding operation');

  RandomBuffer(Data[Start], PadByte);

  Data[High(Data)] := PadByte;
end;

class function TDECISO10126Padding.AddPadding(const Data: TBytes; BlockSize, MinLength: Integer): TBytes;
var
  ResLength: Integer;
begin
  ResLength := CalculatePaddingLength(Length(Data), BlockSize, MinLength);

  if (ResLength < 0) or (ResLength - Length(Data) > 255) then
    raise EDECCipherException.Create('Invalid ISO 10126 Padding operation');

  SetLength(Result, ResLength);

  if Length(Data) > 0 then
    Move(Data[0], Result[0], Length(Data));

  DoPadding(Result, Length(Data));
end;

class function TDECISO10126Padding.HasValidPadding(const Data: TBytes; BlockSize: Integer): Boolean;
var
  PadLength: Integer;
begin
  Result := False;
  if (Length(Data) = 0) or ((BlockSize > 0) and (Length(Data) mod BlockSize <> 0)) then
    exit;

  PadLength := Data[High(Data)];

  if PadLength > Length(Data) then
    Exit;

  Result := True;
end;

class function TDECISO10126Padding.RemovePadding(const Data: TBytes; BlockSize: Integer): TBytes;
var
  PadLength: Integer;
begin
  if not HasValidPadding(Data, BlockSize) then
    raise EDECCipherException.Create('Invalid ISO 10126 padding');

  PadLength := Data[High(Data)];
  SetLength(Result, Length(Data) - PadLength);

  if length(Result) > 0 then
    Move(Data[0], Result[0], Length(Result));
end;

{ TDECISO7816Padding }

class procedure TDECISO7816Padding.DoPadding(var Data: TBytes; Start: Integer);
begin
  Data[Start] := $80; // first bit is one followed by zeros;
end;

class function TDECISO7816Padding.AddPadding(const Data: TBytes; BlockSize, MinLength: Integer): TBytes;
var
  ResLength: Integer;
begin
  ResLength := CalculatePaddingLength(Length(Data), BlockSize, MinLength);

  if (ResLength < 0) then
    raise EDECCipherException.Create('Invalid ISO 7816 Padding operation');

  SetLength(Result, ResLength);

  if Length(Data) > 0 then
    Move(Data[0], Result[0], Length(Data));

  DoPadding(Result, Length(Data));
end;

class function TDECISO7816Padding.HasValidPadding(const Data: TBytes; BlockSize: Integer): Boolean;
var
  I: Integer;
begin
  Result := False;
  if (Length(Data) = 0) or ((BlockSize > 0) and (Length(Data) mod BlockSize <> 0)) then
    exit;

  I := High(Data);

  while I > 0 do
    if Data[I] <> 00 then
      Break
    else
      Dec(I);

  if Data[I] <> $80 then
    Exit;

  Result := True;
end;

class function TDECISO7816Padding.RemovePadding(const Data: TBytes; BlockSize: Integer): TBytes;
var
  I: Integer;
begin
  if (Length(Data) = 0) or ((BlockSize > 0) and (Length(Data) mod BlockSize <> 0)) then
    raise EDECCipherException.Create('Invalid ISO 7816 padding');

  I := High(Data);

  while I > 0 do
    if Data[I] <> 00 then
      Break
    else
      Dec(I);

  if (Data[I] <> $80) then
    raise EDECCipherException.Create('Invalid ISO 7816 padding');

  SetLength(Result, I);

  if length(Result) > 0 then
    Move(Data[0], Result[0], Length(Result));
end;

end.
Simple Project to use with that
Delphi-Quellcode:
program DECPadding;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  DECCipherPaddings,
  DECFormat,
  DECUtil;

type
  TLocalPadding = type of TDECPadding;

procedure TestPadding(PaddingClass: TLocalPadding; const Data: TBytes; BlockSize: Integer; MinLength: Integer = 0);
var
  Padded, UnPadded: TBytes;
begin
  Padded := PaddingClass.AddPadding(Data, BlockSize, MinLength);

  Writeln('Data: '#9 + IntToStr(Length(Data)) + #9' _ ' + StringOf(TFormat_HEX.Encode(Data)));
  Write('Padded:'#9 + IntToStr(Length(Padded)) + #9' _ ' + StringOf(TFormat_HEX.Encode(Padded)));

  //if not PaddingClass.HasValidPadding(Padded,16) then // some values should fail for TPKCS7Padding ....
  if not PaddingClass.HasValidPadding(Padded) then
  begin
    Writeln(' _ Couldn''t validate !!!!');
    Exit;
  end;

  //UnPadded := PaddingClass.RemovePadding(Padded, 7); // should raise exception for TPKCS7Padding ..
  //UnPadded := PaddingClass.RemovePadding(Padded, 16); // should raise exception for TPKCS7Padding ..
  UnPadded := PaddingClass.RemovePadding(Padded);
  if not IsEqual(Data, UnPadded) then
    Writeln(' _ Wrong Padding !!!!')
  else
    Writeln(' _ OK');
end;

procedure TestMultiPadding(PaddingClass: TLocalPadding);
var
  Data: TBytes;
  I, J: Integer;
begin
  Writeln(#13#10 + PaddingClass.ClassName);
  for I := 0 to 35 do
  begin
    SetLength(Data, I);
    for J := Low(Data) to High(Data) do
      Data[J] := J + 55;
    TestPadding(PaddingClass, Data, 8);
  end;
  for I := 0 to 67 do
  begin
    SetLength(Data, I);
    for J := Low(Data) to High(Data) do
      Data[J] := 255 - J; //J + 55;
    TestPadding(PaddingClass, Data, 8, 64);
  end;

  Data := BytesOf('Test!');
  TestPadding(PaddingClass, Data, 16);
  TestPadding(PaddingClass, Data, 0, 23);

  Data := BytesOf('Longer Test !_1234567890');
  TestPadding(PaddingClass, Data, 16, 48);
  TestPadding(PaddingClass, Data, 0, 128);
end;

procedure TestPKCS7Padding;
begin
  TestPadding(TDECANSIX923Padding, BytesOf('Test!'), 16, 48);
  TestPadding(TDECISO7816Padding, BytesOf('Test!'), 0, 512);
  TestMultiPadding(TDECPKCS7Padding);
  TestMultiPadding(TDECPKCS5Padding);
  TestMultiPadding(TDECANSIX923Padding);
  TestMultiPadding(TDECISO10126Padding);
  TestMultiPadding(TDECISO7816Padding);
  //TestMultiPadding(TDECW3CPadding);
end;

begin
  try
    TestPKCS7Padding;
  except
    on E: Exception do
      Writeln(#13#10'Exception: ' + E.Message);
  end;

  Writeln('Done!');
  Readln;
end.
Some parts of the output
Code:
Data:  5        _ 5465737421
Padded: 48       _ 54657374210000000000000000000000000000000000000000000000000000000000000000000000000000000000002B _ OK
Data:  5        _ 5465737421
Padded: 512      _ 54657374218000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000......
...
TDECPKCS7Padding
Data:  0        _
Padded: 8        _ 0808080808080808 _ OK
Data:  1        _ 37
Padded: 8        _ 3707070707070707 _ OK
Data:  2        _ 3738
Padded: 8        _ 3738060606060606 _ OK
Data:  3        _ 373839
Padded: 8        _ 3738390505050505 _ OK
Data:  4        _ 3738393A
Padded: 8        _ 3738393A04040404 _ OK
Data:  5        _ 3738393A3B
Padded: 8        _ 3738393A3B030303 _ OK
Data:  6        _ 3738393A3B3C
Padded: 8        _ 3738393A3B3C0202 _ OK
Data:  7        _ 3738393A3B3C3D
Padded: 8        _ 3738393A3B3C3D01 _ OK
Data:  8        _ 3738393A3B3C3D3E
Padded: 16       _ 3738393A3B3C3D3E0808080808080808 _ OK
Data:  9        _ 3738393A3B3C3D3E3F
Padded: 16       _ 3738393A3B3C3D3E3F07070707070707 _ OK
Data:  10       _ 3738393A3B3C3D3E3F40
Padded: 16       _ 3738393A3B3C3D3E3F40060606060606 _ OK
Data:  11       _ 3738393A3B3C3D3E3F4041
Padded: 16       _ 3738393A3B3C3D3E3F40410505050505 _ OK
Data:  12       _ 3738393A3B3C3D3E3F404142
Padded: 16       _ 3738393A3B3C3D3E3F40414204040404 _ OK
Data:  13       _ 3738393A3B3C3D3E3F40414243
Padded: 16       _ 3738393A3B3C3D3E3F40414243030303 _ OK
Data:  14       _ 3738393A3B3C3D3E3F4041424344
Padded: 16       _ 3738393A3B3C3D3E3F40414243440202 _ OK
Data:  15       _ 3738393A3B3C3D3E3F404142434445
Padded: 16       _ 3738393A3B3C3D3E3F40414243444501 _ OK
Data:  16       _ 3738393A3B3C3D3E3F40414243444546
Padded: 24       _ 3738393A3B3C3D3E3F404142434445460808080808080808 _ OK
Data:  17       _ 3738393A3B3C3D3E3F4041424344454647
Padded: 24       _ 3738393A3B3C3D3E3F404142434445464707070707070707 _ OK
Data:  18       _ 3738393A3B3C3D3E3F404142434445464748
Padded: 24       _ 3738393A3B3C3D3E3F404142434445464748060606060606 _ OK
Data:  19       _ 3738393A3B3C3D3E3F40414243444546474849
Padded: 24       _ 3738393A3B3C3D3E3F404142434445464748490505050505 _ OK
Data:  20       _ 3738393A3B3C3D3E3F404142434445464748494A
Padded: 24       _ 3738393A3B3C3D3E3F404142434445464748494A04040404 _ OK
Data:  21       _ 3738393A3B3C3D3E3F404142434445464748494A4B
Padded: 24       _ 3738393A3B3C3D3E3F404142434445464748494A4B030303 _ OK
Data:  22       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C
Padded: 24       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C0202 _ OK
Data:  23       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D
Padded: 24       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D01 _ OK
Data:  24       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E
Padded: 32       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E0808080808080808 _ OK
Data:  25       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
Padded: 32       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F07070707070707 _ OK
Data:  26       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50
Padded: 32       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50060606060606 _ OK
Data:  27       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F5051
Padded: 32       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50510505050505 _ OK
Data:  28       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152
Padded: 32       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515204040404 _ OK
Data:  29       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253
Padded: 32       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253030303 _ OK
Data:  30       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F5051525354
Padded: 32       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253540202 _ OK
Data:  31       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455
Padded: 32       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545501 _ OK
Data:  32       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556
Padded: 40       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455560808080808080808 _ OK
Data:  33       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F5051525354555657
Padded: 40       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565707070707070707 _ OK
Data:  34       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758
Padded: 40       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758060606060606 _ OK
Data:  35       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556575859
Padded: 40       _ 3738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758590505050505 _ OK
Data:  0        _
Padded: 64       _ 40404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040 _ OK
Data:  1        _ FF
Padded: 64       _ FF3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F _ OK
Data:  2        _ FFFE
Padded: 64       _ FFFE3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E _ OK
Data:  3        _ FFFEFD
Padded: 64       _ FFFEFD3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D _ OK
Data:  4        _ FFFEFDFC
Padded: 64       _ FFFEFDFC3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C _ OK
Data:  5        _ FFFEFDFCFB
Padded: 64       _ FFFEFDFCFB3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B _ OK
Data:  6        _ FFFEFDFCFBFA
Padded: 64       _ FFFEFDFCFBFA3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A _ OK
Data:  7        _ FFFEFDFCFBFAF9
Padded: 64       _ FFFEFDFCFBFAF9393939393939393939393939393939393939393939393939393939393939393939393939393939393939393939393939393939393939393939 _ OK
Data:  8        _ FFFEFDFCFBFAF9F8
Padded: 64       _ FFFEFDFCFBFAF9F83838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838 _ OK
Data:  9        _ FFFEFDFCFBFAF9F8F7
Padded: 64       _ FFFEFDFCFBFAF9F8F737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737 _ OK
Data:  10       _ FFFEFDFCFBFAF9F8F7F6
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636 _ OK
Data:  11       _ FFFEFDFCFBFAF9F8F7F6F5
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F53535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535353535 _ OK
Data:  12       _ FFFEFDFCFBFAF9F8F7F6F5F4
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434 _ OK
Data:  13       _ FFFEFDFCFBFAF9F8F7F6F5F4F3
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 _ OK
Data:  14       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F23232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232 _ OK
Data:  15       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131 _ OK
Data:  16       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030 _ OK
Data:  17       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EF
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F _ OK
Data:  18       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEE
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEE2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E _ OK
Data:  19       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEED
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEED2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D _ OK
Data:  20       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDEC
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDEC2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C _ OK
Data:  21       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEB
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEB2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B _ OK
Data:  22       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEA
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEA2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A _ OK
Data:  23       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE92929292929292929292929292929292929292929292929292929292929292929292929292929292929 _ OK
Data:  24       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E828282828282828282828282828282828282828282828282828282828282828282828282828282828 _ OK
Data:  25       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7272727272727272727272727272727272727272727272727272727272727272727272727272727 _ OK
Data:  26       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E62626262626262626262626262626262626262626262626262626262626262626262626262626 _ OK
Data:  27       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E525252525252525252525252525252525252525252525252525252525252525252525252525 _ OK
Data:  28       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4242424242424242424242424242424242424242424242424242424242424242424242424 _ OK
Data:  29       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E32323232323232323232323232323232323232323232323232323232323232323232323 _ OK
Data:  30       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E222222222222222222222222222222222222222222222222222222222222222222222 _ OK
Data:  31       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1212121212121212121212121212121212121212121212121212121212121212121 _ OK
Data:  32       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E02020202020202020202020202020202020202020202020202020202020202020 _ OK
Data:  33       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DF
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DF1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F _ OK
Data:  34       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDE
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDE1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E _ OK
Data:  35       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDD
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDD1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D _ OK
Data:  36       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDC
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDC1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C _ OK
Data:  37       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDB
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDB1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B _ OK
Data:  38       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDA
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDA1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A _ OK
Data:  39       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD919191919191919191919191919191919191919191919191919 _ OK
Data:  40       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8181818181818181818181818181818181818181818181818 _ OK
Data:  41       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D71717171717171717171717171717171717171717171717 _ OK
Data:  42       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D616161616161616161616161616161616161616161616 _ OK
Data:  43       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5151515151515151515151515151515151515151515 _ OK
Data:  44       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D41414141414141414141414141414141414141414 _ OK
Data:  45       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D313131313131313131313131313131313131313 _ OK
Data:  46       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2121212121212121212121212121212121212 _ OK
Data:  47       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D11111111111111111111111111111111111 _ OK
Data:  48       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D010101010101010101010101010101010 _ OK
Data:  49       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CF
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F _ OK
Data:  50       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCE
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCE0E0E0E0E0E0E0E0E0E0E0E0E0E0E _ OK
Data:  51       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECD
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECD0D0D0D0D0D0D0D0D0D0D0D0D0D _ OK
Data:  52       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCC
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCC0C0C0C0C0C0C0C0C0C0C0C0C _ OK
Data:  53       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCB
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCB0B0B0B0B0B0B0B0B0B0B0B _ OK
Data:  54       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCA
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCA0A0A0A0A0A0A0A0A0A0A _ OK
Data:  55       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9090909090909090909 _ OK
Data:  56       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C80808080808080808 _ OK
Data:  57       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C707070707070707 _ OK
Data:  58       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6060606060606 _ OK
Data:  59       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C50505050505 _ OK
Data:  60       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C404040404 _ OK
Data:  61       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3030303 _ OK
Data:  62       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C20202 _ OK
Data:  63       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1
Padded: 64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C101 _ OK
Data:  64       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0
Padded: 72       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C00808080808080808 _ OK
Data:  65       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BF
Padded: 72       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BF07070707070707 _ OK
Data:  66       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBE
Padded: 72       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBE060606060606 _ OK
Data:  67       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBD
Padded: 72       _ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBD0505050505 _ OK

TDECANSIX923Padding
Data:  0        _
Padded: 8        _ 0000000000000008 _ OK
Data:  1        _ 37
Padded: 8        _ 3700000000000007 _ OK
Data:  2        _ 3738
Padded: 8        _ 3738000000000006 _ OK
Data:  3        _ 373839
Padded: 8        _ 3738390000000005 _ OK
Data:  4        _ 3738393A
Padded: 8        _ 3738393A00000004 _ OK
Data:  5        _ 3738393A3B
Padded: 8        _ 3738393A3B000003 _ OK
Data:  6        _ 3738393A3B3C
Padded: 8        _ 3738393A3B3C0002 _ OK
Data:  7        _ 3738393A3B3C3D
Padded: 8        _ 3738393A3B3C3D01 _ OK
Data:  8        _ 3738393A3B3C3D3E
Padded: 16       _ 3738393A3B3C3D3E0000000000000008 _ OK
Data:  9        _ 3738393A3B3C3D3E3F
Padded: 16       _ 3738393A3B3C3D3E3F00000000000007 _ OK
Data:  10       _ 3738393A3B3C3D3E3F40
Padded: 16       _ 3738393A3B3C3D3E3F40000000000006 _ OK
Data:  11       _ 3738393A3B3C3D3E3F4041
Padded: 16       _ 3738393A3B3C3D3E3F40410000000005 _ OK

TDECISO10126Padding
Data:  0        _
Padded: 8        _ 4284CDE2A1FCA908 _ OK
Data:  1        _ 37
Padded: 8        _ 37F28EE75CE38507 _ OK
Data:  2        _ 3738
Padded: 8        _ 3738266443C00406 _ OK
Data:  3        _ 373839
Padded: 8        _ 3738392DF1BDEE05 _ OK
Data:  4        _ 3738393A
Padded: 8        _ 3738393A51EA4C04 _ OK
Data:  5        _ 3738393A3B
Padded: 8        _ 3738393A3BE17703 _ OK
Data:  6        _ 3738393A3B3C
Padded: 8        _ 3738393A3B3C9D02 _ OK
Data:  7        _ 3738393A3B3C3D
Padded: 8        _ 3738393A3B3C3D01 _ OK
Data:  8        _ 3738393A3B3C3D3E
Padded: 16       _ 3738393A3B3C3D3E7322A43A816EFE08 _ OK
Data:  9        _ 3738393A3B3C3D3E3F
Padded: 16       _ 3738393A3B3C3D3E3F0DD18B7CFC4707 _ OK
Data:  10       _ 3738393A3B3C3D3E3F40
Padded: 16       _ 3738393A3B3C3D3E3F402A8368130E06 _ OK
Data:  11       _ 3738393A3B3C3D3E3F4041
Padded: 16       _ 3738393A3B3C3D3E3F40414185976A05 _ OK

TDECISO7816Padding
Data:  0        _
Padded: 8        _ 8000000000000000 _ OK
Data:  1        _ 37
Padded: 8        _ 3780000000000000 _ OK
Data:  2        _ 3738
Padded: 8        _ 3738800000000000 _ OK
Data:  3        _ 373839
Padded: 8        _ 3738398000000000 _ OK
Data:  4        _ 3738393A
Padded: 8        _ 3738393A80000000 _ OK
Data:  5        _ 3738393A3B
Padded: 8        _ 3738393A3B800000 _ OK
Data:  6        _ 3738393A3B3C
Padded: 8        _ 3738393A3B3C8000 _ OK
Data:  7        _ 3738393A3B3C3D
Padded: 8        _ 3738393A3B3C3D80 _ OK
Data:  8        _ 3738393A3B3C3D3E
Padded: 16       _ 3738393A3B3C3D3E8000000000000000 _ OK
Data:  9        _ 3738393A3B3C3D3E3F
Padded: 16       _ 3738393A3B3C3D3E3F80000000000000 _ OK
Data:  10       _ 3738393A3B3C3D3E3F40
Padded: 16       _ 3738393A3B3C3D3E3F40800000000000 _ OK
Data:  11       _ 3738393A3B3C3D3E3F4041
Padded: 16       _ 3738393A3B3C3D3E3F40418000000000 _ OK
Data:  12       _ 3738393A3B3C3D3E3F404142
Padded: 16       _ 3738393A3B3C3D3E3F40414280000000 _ OK
Data:  13       _ 3738393A3B3C3D3E3F40414243
Padded: 16       _ 3738393A3B3C3D3E3F40414243800000 _ OK
Data:  14       _ 3738393A3B3C3D3E3F4041424344
Padded: 16       _ 3738393A3B3C3D3E3F40414243448000 _ OK
Data:  15       _ 3738393A3B3C3D3E3F404142434445
Padded: 16       _ 3738393A3B3C3D3E3F40414243444580 _ OK
Data:  16       _ 3738393A3B3C3D3E3F40414243444546
Padded: 24       _ 3738393A3B3C3D3E3F404142434445468000000000000000 _ OK
Notes : i added TPaddingCommon as middle layer and i am not fan of it, yet i don't want to break your own abstraction or roles, so it is up to you to keep it or expand it into the inherited or move it to the base.

Sorry again for running your code and your help, that help need to be rewritten in case you used the suggested schemes/code.

Happy and peaceful new year to everyone !
Kas
  Mit Zitat antworten Zitat