@@ -218,9 +218,11 @@ TFixedBytePadding = class abstract(TPaddingBase)
218218 // / The length of the block in bytes.
219219 // / </param>
220220 // / <returns>
221- // / Length of the padding in bytes.
221+ // / Length of the padding in bytes. Can not be zero. When the DataSize
222+ // / is a multiply of the BlockSize the method returns the sum of DataSize and
223+ // / BlockSize.
222224 // / </returns>
223- class function GetPadLength (DataSize, BlockSize: Integer): Integer; virtual ; abstract ;
225+ class function GetPadLength (DataSize, BlockSize: Integer): Integer; virtual ;
224226
225227 // / <summary>
226228 // / Retrieves the padding character used to fill up the last block(s).
@@ -396,21 +398,6 @@ TFixedBytePadding = class abstract(TPaddingBase)
396398 // / </remarks>
397399 TPKCS7Padding = class (TFixedBytePadding)
398400 strict protected
399- // / <summary>
400- // / Calculated the length of the padding.
401- // / </summary>
402- // / <param name="DataSize">
403- // / The length of the data.
404- // / </param>
405- // / <param name="BlockSize">
406- // / The length of the block.
407- // / </param>
408- // / <returns>
409- // / Length of the padding. Can not be zero. When the DataSize is a multiply
410- // / of the BlockSize the method returns the BlockSize.
411- // / </returns>
412- class function GetPadLength (DataSize, BlockSize: Integer): Integer; override;
413-
414401 // / <summary>
415402 // / Check if block size is supported by the concerete padding algorithm.
416403 // / </summary>
@@ -439,8 +426,8 @@ TPKCS7Padding = class(TFixedBytePadding)
439426 end ;
440427
441428 // / <summary>
442- // / PKCS#5 is a subset of the PKCS#7 padding algorithm. Better use PKCS#7
443- // / where possible.
429+ // / PKCS#5 is a subset of the PKCS#7 padding algorithm for block size of
430+ // / 8 bytes. Better use PKCS#7 where possible.
444431 // / </summary>
445432 TPKCS5Padding = class (TPKCS7Padding)
446433 strict protected
@@ -451,7 +438,7 @@ TPKCS5Padding = class(TPKCS7Padding)
451438 // / The length of the block size for PKCS#5 must be 8.
452439 // / </param>
453440 // / <returns>
454- // / True, if block size is in expected range of 1..255 , otherwise false.
441+ // / True, if block size is 8 , otherwise false.
455442 // / </returns>
456443 class function IsBlockSizeValid (BlockSize: Integer): Boolean; override;
457444 end ;
@@ -468,21 +455,6 @@ TPKCS5Padding = class(TPKCS7Padding)
468455 // / </remarks>
469456 TANSI_X9_23_Padding = class (TFixedBytePadding)
470457 strict protected
471- // / <summary>
472- // / Calculates the length of the pad.
473- // / </summary>
474- // / <param name="DataSize">
475- // / The length of the data in byte.
476- // / </param>
477- // / <param name="BlockSize">
478- // / The length of the block in byte.
479- // / </param>
480- // / <returns>
481- // / Length of the padding. Can be zero when the DataSize is a multiply of
482- // / the BlockSize.
483- // / </returns>
484- class function GetPadLength (DataSize, BlockSize: Integer): Integer; override;
485-
486458 // / <summary>
487459 // / Check if block size is supported by the concerete padding algorithm.
488460 // / </summary>
@@ -560,19 +532,15 @@ TISO10126Padding = class(TANSI_X9_23_Padding)
560532 TISO7816Padding = class (TFixedBytePadding)
561533 strict protected
562534 // / <summary>
563- // / Calculates the length of the padding.
535+ // / Check if block size is supported by the concerete padding algorithm .
564536 // / </summary>
565- // / <param name="DataSize">
566- // / The length of the data in bytes.
567- // / </param>
568537 // / <param name="BlockSize">
569- // / The length of the block in bytes .
538+ // / The length of the block size must be 1 or higher .
570539 // / </param>
571540 // / <returns>
572- // / Length of the padding in bytes. Can not be zero when the DataSize is a
573- // / multiply of the BlockSize.
541+ // / True, if block size is > 0, otherwise false.
574542 // / </returns>
575- class function GetPadLength (DataSize, BlockSize: Integer): Integer ; override;
543+ class function IsBlockSizeValid ( BlockSize: Integer): Boolean ; override;
576544 public
577545 // / <summary>
578546 // / Adds padding to the specified data, depending on the padding byte
@@ -676,6 +644,11 @@ class function TFixedBytePadding.AddPadding(const Data : RawByteString;
676644 ProtectBytes(Buf);
677645end ;
678646
647+ class function TFixedBytePadding.GetPadLength (DataSize, BlockSize: Integer): Integer;
648+ begin
649+ Result := BlockSize - (DataSize mod BlockSize);
650+ end ;
651+
679652class function TFixedBytePadding.HasValidPadding (const Data : TBytes;
680653 BlockSize : Integer): Boolean;
681654var
@@ -688,6 +661,9 @@ class function TFixedBytePadding.HasValidPadding(const Data : TBytes;
688661 if not IsBlockSizeValid(BlockSize) then
689662 exit(false);
690663
664+ if Length(Data) mod BlockSize <> 0 then
665+ exit(false);
666+
691667 PadLength := Data[High(Data)];
692668 if (PadLength <= 0 ) or (PadLength > BlockSize) then
693669 exit(false);
@@ -735,12 +711,6 @@ class function TFixedBytePadding.RemovePadding(const Data : string;
735711
736712{ TPKCS7Padding }
737713
738- class function TPKCS7Padding.GetPadLength (DataSize,
739- BlockSize: integer): integer;
740- begin
741- Result := BlockSize - (DataSize mod BlockSize);
742- end ;
743-
744714class function TPKCS7Padding.IsBlockSizeValid (BlockSize: Integer): Boolean;
745715begin
746716 Result := (BlockSize > 0 ) and (BlockSize < 256 );
@@ -775,28 +745,26 @@ class function TANSI_X9_23_Padding.GetPaddingByte(PaddingLength : Integer;
775745 Result := 0 ;
776746end ;
777747
778- class function TANSI_X9_23_Padding.GetPadLength (DataSize,
779- BlockSize : Integer): Integer;
780- begin
781- Result := DataSize mod BlockSize;
782- end ;
783-
784748class function TANSI_X9_23_Padding.HasValidPadding (const Data : TBytes;
785749 BlockSize : Integer): Boolean;
786750var
787751 PadLength : Integer;
788752begin
753+ if Length(Data) = 0 then
754+ exit(false);
755+
789756 if not IsBlockSizeValid(BlockSize) then
790757 exit(false);
791758
792- PadLength := Data[High(Data)];
793- if (PadLength <= 0 ) or (PadLength > BlockSize) then
759+ if Length(Data) mod BlockSize <> 0 then
794760 exit(false);
795761
796- // check only last padding byte according to standard
797- if (Data[High(Data)] <> GetPaddingByte (PadLength, true) ) then
762+ PadLength := Data[High(Data)];
763+ if (PadLength <= 0 ) or (PadLength > BlockSize ) then
798764 exit(false);
799765
766+ // Padding bytes cannot be tested as the content is not defined and does
767+ // not necessarily have to be zero!
800768 Result := true;
801769end ;
802770
@@ -813,10 +781,9 @@ class function TISO10126Padding.GetPaddingByte(PaddingLength : Integer;
813781
814782{ TISO7816Padding }
815783
816- class function TISO7816Padding.GetPadLength (DataSize,
817- BlockSize: Integer): Integer;
784+ class function TISO7816Padding.IsBlockSizeValid (BlockSize: Integer): Boolean;
818785begin
819- Result := DataSize mod BlockSize ;
786+ Result := BlockSize > 0 ;
820787end ;
821788
822789class function TISO7816Padding.AddPadding (const Data: TBytes;
@@ -846,14 +813,17 @@ class function TISO7816Padding.HasValidPadding(const Data : TBytes;
846813var
847814 I: Integer;
848815begin
816+ if Length(Data) = 0 then
817+ exit(false);
818+
849819 if not IsBlockSizeValid(BlockSize) then
850820 exit(false);
851821
852- if ( Length(Data) = 0 ) or ((BlockSize > 0 ) and (Length(Data) mod BlockSize <> 0 )) then
822+ if Length(Data) mod BlockSize <> 0 then
853823 exit(false);
854824
855825 I := High(Data);
856- while (I > 0 ) and (Data[I] <> 0 ) do
826+ while (I > 0 ) and (Data[I] = 0 ) do
857827 dec(I);
858828
859829 if Data[I] <> $80 then
@@ -871,7 +841,7 @@ class function TISO7816Padding.RemovePadding(const Data : TBytes;
871841 raise EDECCipherException.CreateResFmt(@sInvalidPadding, [ClassName]);
872842
873843 I := High(Data);
874- while (I > 0 ) and (Data[I] <> 0 ) do
844+ while (I > 0 ) and (Data[I] = 0 ) do
875845 dec(I);
876846 if Data[I] <> $80 then
877847 raise EDECCipherException.CreateResFmt(@sInvalidPadding, [ClassName]);
0 commit comments