Browse Source

add Blowfish block cipher support

Ugochukwu Mmaduekwe 7 years ago
parent
commit
24836ca696
27 changed files with 873 additions and 40 deletions
  1. 3 1
      CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr
  2. 4 1
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
  3. 5 1
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
  4. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
  5. 5 1
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi
  6. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
  7. 20 0
      CryptoLib.Tests/src/Crypto/BlockCipherVectorTests.pas
  8. 80 0
      CryptoLib.Tests/src/Crypto/BlowfishTestVectors.pas
  9. 3 3
      CryptoLib.Tests/src/Crypto/PaddingTests.pas
  10. 78 3
      CryptoLib/src/Asn1/Misc/ClpMiscObjectIdentifiers.pas
  11. 2 1
      CryptoLib/src/Crypto/ClpBufferedBlockCipher.pas
  12. 7 7
      CryptoLib/src/Crypto/Engines/ClpAesEngine.pas
  13. 2 2
      CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas
  14. 555 0
      CryptoLib/src/Crypto/Engines/ClpBlowfishEngine.pas
  15. 2 2
      CryptoLib/src/Crypto/Modes/ClpCbcBlockCipher.pas
  16. 2 1
      CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas
  17. 2 2
      CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas
  18. 36 0
      CryptoLib/src/Interfaces/ClpIBlowfishEngine.pas
  19. 3 4
      CryptoLib/src/Math/ClpBigInteger.pas
  20. 2 1
      CryptoLib/src/Math/Raw/ClpNat.pas
  21. 2 1
      CryptoLib/src/Math/Raw/ClpNat192.pas
  22. 2 1
      CryptoLib/src/Math/Raw/ClpNat256.pas
  23. 9 1
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
  24. 1 1
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
  25. 9 1
      CryptoLib/src/Security/ClpCipherUtilities.pas
  26. 4 2
      CryptoLib/src/Security/ClpGeneratorUtilities.pas
  27. 33 3
      CryptoLib/src/Utils/ClpArrayUtils.pas

+ 3 - 1
CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr

@@ -460,7 +460,9 @@ uses
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpISchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpISchnorrEncoding.pas',
   ClpISchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpISchnorrEncoding.pas',
   ClpIPlainSchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainSchnorrEncoding.pas',
   ClpIPlainSchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainSchnorrEncoding.pas',
-  ClpPlainSchnorrEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainSchnorrEncoding.pas';
+  ClpPlainSchnorrEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainSchnorrEncoding.pas',
+  ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
+  ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.pas';
 
 
 begin
 begin
   try
   try

+ 4 - 1
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -518,7 +518,10 @@ uses
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpISchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpISchnorrEncoding.pas',
   ClpISchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpISchnorrEncoding.pas',
   ClpIPlainSchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainSchnorrEncoding.pas',
   ClpIPlainSchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainSchnorrEncoding.pas',
-  ClpPlainSchnorrEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainSchnorrEncoding.pas';
+  ClpPlainSchnorrEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainSchnorrEncoding.pas',
+  ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
+  ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.pas',
+  BlowfishTestVectors in '..\src\Crypto\BlowfishTestVectors.pas';
 
 
 begin
 begin
 
 

+ 5 - 1
CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi

@@ -36,7 +36,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item4>
       </Item4>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="47">
+    <Units Count="48">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -226,6 +226,10 @@
         <Filename Value="..\src\Asn1\TagTests.pas"/>
         <Filename Value="..\src\Asn1\TagTests.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit46>
       </Unit46>
+      <Unit47>
+        <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit47>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

+ 1 - 0
CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr

@@ -32,6 +32,7 @@ uses
   BlockCipherVectorTests,
   BlockCipherVectorTests,
   BlockCipherMonteCarloTests,
   BlockCipherMonteCarloTests,
   AESTestVectors,
   AESTestVectors,
+  BlowfishTestVectors,
   AESSICTests,
   AESSICTests,
   IESCipherTests,
   IESCipherTests,
   MD5HMacTests,
   MD5HMacTests,

+ 5 - 1
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi

@@ -37,7 +37,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item2>
       </Item2>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="47">
+    <Units Count="48">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLibConsole.lpr"/>
         <Filename Value="CryptoLibConsole.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -226,6 +226,10 @@
         <Filename Value="..\src\Asn1\TagTests.pas"/>
         <Filename Value="..\src\Asn1\TagTests.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit46>
       </Unit46>
+      <Unit47>
+        <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit47>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

+ 1 - 0
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr

@@ -30,6 +30,7 @@ uses
   BlockCipherVectorTests,
   BlockCipherVectorTests,
   BlockCipherMonteCarloTests,
   BlockCipherMonteCarloTests,
   AESTestVectors,
   AESTestVectors,
+  BlowfishTestVectors,
   AESSICTests,
   AESSICTests,
   IESCipherTests,
   IESCipherTests,
   MD5HMacTests,
   MD5HMacTests,

+ 20 - 0
CryptoLib.Tests/src/Crypto/BlockCipherVectorTests.pas

@@ -32,12 +32,15 @@ uses
   TestFramework,
   TestFramework,
 {$ENDIF FPC}
 {$ENDIF FPC}
   AESTestVectors,
   AESTestVectors,
+  BlowfishTestVectors,
   ClpIBlockCipher,
   ClpIBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpAesEngine,
   ClpAesEngine,
   ClpIAesEngine,
   ClpIAesEngine,
   ClpAesLightEngine,
   ClpAesLightEngine,
   ClpIAesLightEngine,
   ClpIAesLightEngine,
+  ClpBlowfishEngine,
+  ClpIBlowfishEngine,
   ClpKeyParameter,
   ClpKeyParameter,
   ClpIKeyParameter,
   ClpIKeyParameter,
   ClpParametersWithIV,
   ClpParametersWithIV,
@@ -74,6 +77,7 @@ type
 
 
     procedure TestBlockCipherAESEngine;
     procedure TestBlockCipherAESEngine;
     procedure TestBlockCipherAESLightEngine;
     procedure TestBlockCipherAESLightEngine;
+    procedure TestBlockCipherBlowfishEngine;
     procedure TestBadParameters;
     procedure TestBadParameters;
 
 
   end;
   end;
@@ -229,6 +233,22 @@ begin
 
 
 end;
 end;
 
 
+procedure TTestBlockCipherVector.TestBlockCipherBlowfishEngine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TBlowfishTestVectors.FBlockCipherVectorKeys)
+    to System.High(TBlowfishTestVectors.FBlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TBlowfishEngine.Create() as IBlowfishEngine,
+      TKeyParameter.Create
+      (THex.Decode(TBlowfishTestVectors.FBlockCipherVectorKeys[I]))
+      as IKeyParameter, TBlowfishTestVectors.FBlockCipherVectorInputs[I],
+      TBlowfishTestVectors.FBlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
 initialization
 initialization
 
 
 // Register any test cases with the test runner
 // Register any test cases with the test runner

+ 80 - 0
CryptoLib.Tests/src/Crypto/BlowfishTestVectors.pas

@@ -0,0 +1,80 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit BlowfishTestVectors;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  ClpCryptoLibTypes;
+
+type
+  /// <remarks>Blowfish tester - vectors from http://www.counterpane.com/vectors.txt</remarks>
+  TBlowfishTestVectors = class sealed(TObject)
+
+  public
+    class var
+
+      FBlockCipherVectorKeys, FBlockCipherVectorInputs,
+      FBlockCipherVectorOutputs: TCryptoLibStringArray;
+
+    class constructor BlowfishTestVectors();
+
+  end;
+
+implementation
+
+{ TBlowfishTestVectors }
+
+class constructor TBlowfishTestVectors.BlowfishTestVectors;
+begin
+
+  /// <remarks>Blowfish tester - vectors from http://www.counterpane.com/vectors.txt</remarks>
+  FBlockCipherVectorKeys := TCryptoLibStringArray.Create
+
+    (
+
+    '0000000000000000', 'FFFFFFFFFFFFFFFF',
+
+    '3000000000000000',
+
+    '1111111111111111', '0123456789ABCDEF', 'FEDCBA9876543210',
+    '7CA110454A1A6E57', '0131D9619DC1376E');
+
+  FBlockCipherVectorInputs := TCryptoLibStringArray.Create('0000000000000000',
+    'FFFFFFFFFFFFFFFF',
+
+    '1000000000000001',
+
+    '1111111111111111', '1111111111111111', '0123456789ABCDEF',
+    '01A1D6D039776742', '5CD54CA83DEF57DA');
+
+  FBlockCipherVectorOutputs := TCryptoLibStringArray.Create('4EF997456198DD78',
+    '51866FD5B85ECB8A',
+
+    '7D856F9A613063F2',
+
+    '2466DD878B963C9D', '61F9C3802281B096', '0ACEAB0FC6A0A28D',
+    '59C68245EB05282B', 'B1B8CC0B250F09A0');
+
+end;
+
+end.

+ 3 - 3
CryptoLib.Tests/src/Crypto/PaddingTests.pas

@@ -250,7 +250,7 @@ begin
 
 
   if (ffVector <> Nil) then
   if (ffVector <> Nil) then
   begin
   begin
-    padding.addPadding(data, 3);
+    padding.AddPadding(data, 3);
 
 
     if (not TArrayUtils.AreEqual(data, ffVector)) then
     if (not TArrayUtils.AreEqual(data, ffVector)) then
     begin
     begin
@@ -263,8 +263,8 @@ begin
   //
   //
   if (ZeroVector <> Nil) then
   if (ZeroVector <> Nil) then
   begin
   begin
-    System.FillChar(data[0], 8 * System.SizeOf(Byte), Byte(0));
-    padding.addPadding(data, 4);
+    TArrayUtils.Fill(data, 0, 8, Byte(0));
+    padding.AddPadding(data, 4);
 
 
     if (not TArrayUtils.AreEqual(data, ZeroVector)) then
     if (not TArrayUtils.AreEqual(data, ZeroVector)) then
     begin
     begin

+ 78 - 3
CryptoLib/src/Asn1/Misc/ClpMiscObjectIdentifiers.pas

@@ -33,9 +33,23 @@ type
   class var
   class var
 
 
     FIsBooted: Boolean;
     FIsBooted: Boolean;
-    Fblake2, Fid_blake2b160, Fid_blake2b256, Fid_blake2b384, Fid_blake2b512,
-      Fid_blake2s128, Fid_blake2s160, Fid_blake2s224, Fid_blake2s256
-      : IDerObjectIdentifier;
+    Fcryptlib, Fcryptlib_algorithm, Fcryptlib_algorithm_blowfish_ECB,
+      Fcryptlib_algorithm_blowfish_CBC, Fcryptlib_algorithm_blowfish_CFB,
+      Fcryptlib_algorithm_blowfish_OFB, Fblake2, Fid_blake2b160, Fid_blake2b256,
+      Fid_blake2b384, Fid_blake2b512, Fid_blake2s128, Fid_blake2s160,
+      Fid_blake2s224, Fid_blake2s256: IDerObjectIdentifier;
+
+    class function Getcryptlib: IDerObjectIdentifier; static; inline;
+
+    class function Getcryptlib_algorithm: IDerObjectIdentifier; static; inline;
+    class function Getcryptlib_algorithm_blowfish_ECB: IDerObjectIdentifier;
+      static; inline;
+    class function Getcryptlib_algorithm_blowfish_CBC: IDerObjectIdentifier;
+      static; inline;
+    class function Getcryptlib_algorithm_blowfish_CFB: IDerObjectIdentifier;
+      static; inline;
+    class function Getcryptlib_algorithm_blowfish_OFB: IDerObjectIdentifier;
+      static; inline;
 
 
     class function Getblake2: IDerObjectIdentifier; static; inline;
     class function Getblake2: IDerObjectIdentifier; static; inline;
 
 
@@ -53,6 +67,19 @@ type
 
 
   public
   public
 
 
+    class property cryptlib: IDerObjectIdentifier read Getcryptlib;
+
+    class property cryptlib_algorithm: IDerObjectIdentifier
+      read Getcryptlib_algorithm;
+    class property cryptlib_algorithm_blowfish_ECB: IDerObjectIdentifier
+      read Getcryptlib_algorithm_blowfish_ECB;
+    class property cryptlib_algorithm_blowfish_CBC: IDerObjectIdentifier
+      read Getcryptlib_algorithm_blowfish_CBC;
+    class property cryptlib_algorithm_blowfish_CFB: IDerObjectIdentifier
+      read Getcryptlib_algorithm_blowfish_CFB;
+    class property cryptlib_algorithm_blowfish_OFB: IDerObjectIdentifier
+      read Getcryptlib_algorithm_blowfish_OFB;
+
     class property blake2: IDerObjectIdentifier read Getblake2;
     class property blake2: IDerObjectIdentifier read Getblake2;
 
 
     class property id_blake2b160: IDerObjectIdentifier read Getid_blake2b160;
     class property id_blake2b160: IDerObjectIdentifier read Getid_blake2b160;
@@ -78,6 +105,41 @@ begin
   result := Fblake2;
   result := Fblake2;
 end;
 end;
 
 
+class function TMiscObjectIdentifiers.Getcryptlib: IDerObjectIdentifier;
+begin
+  result := Fcryptlib;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm_blowfish_CBC
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm_blowfish_CBC;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm_blowfish_CFB
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm_blowfish_CFB;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm_blowfish_ECB
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm_blowfish_ECB;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm_blowfish_OFB
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm_blowfish_OFB;
+end;
+
 class function TMiscObjectIdentifiers.Getid_blake2b160: IDerObjectIdentifier;
 class function TMiscObjectIdentifiers.Getid_blake2b160: IDerObjectIdentifier;
 begin
 begin
   result := Fid_blake2b160;
   result := Fid_blake2b160;
@@ -123,6 +185,19 @@ begin
 
 
   if not FIsBooted then
   if not FIsBooted then
   begin
   begin
+
+    //
+    // Peter Gutmann's Cryptlib
+    //
+
+    Fcryptlib := TDerObjectIdentifier.Create('1.3.6.1.4.1.3029');
+
+    Fcryptlib_algorithm := cryptlib.Branch('1');
+    Fcryptlib_algorithm_blowfish_ECB := cryptlib_algorithm.Branch('1.1');
+    Fcryptlib_algorithm_blowfish_CBC := cryptlib_algorithm.Branch('1.2');
+    Fcryptlib_algorithm_blowfish_CFB := cryptlib_algorithm.Branch('1.3');
+    Fcryptlib_algorithm_blowfish_OFB := cryptlib_algorithm.Branch('1.4');
+
     //
     //
     // Blake2b and Blake2s
     // Blake2b and Blake2s
     //
     //

+ 2 - 1
CryptoLib/src/Crypto/ClpBufferedBlockCipher.pas

@@ -29,6 +29,7 @@ uses
   ClpIBufferedBlockCipher,
   ClpIBufferedBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpIParametersWithRandom,
   ClpIParametersWithRandom,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 resourcestring
 resourcestring
@@ -539,7 +540,7 @@ end;
 
 
 procedure TBufferedBlockCipher.Reset;
 procedure TBufferedBlockCipher.Reset;
 begin
 begin
-  System.FillChar(Fbuf[0], System.length(Fbuf), Byte(0));
+  TArrayUtils.Fill(Fbuf, 0, System.length(Fbuf), Byte(0));
   FbufOff := 0;
   FbufOff := 0;
 
 
   Fcipher.Reset();
   Fcipher.Reset();

+ 7 - 7
CryptoLib/src/Crypto/Engines/ClpAesEngine.pas

@@ -33,7 +33,7 @@ uses
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 resourcestring
 resourcestring
-  AESEngineNotInitialised = 'AES Engine not Initialised';
+  SAESEngineNotInitialised = 'AES Engine not Initialised';
   SInputBuffertooShort = 'Input Buffer too Short';
   SInputBuffertooShort = 'Input Buffer too Short';
   SOutputBuffertooShort = 'Output Buffer too Short';
   SOutputBuffertooShort = 'Output Buffer too Short';
   SInvalidParameterAESInit = 'Invalid Parameter Passed to AES Init - "%s"';
   SInvalidParameterAESInit = 'Invalid Parameter Passed to AES Init - "%s"';
@@ -217,7 +217,7 @@ type
     FC0, FC1, FC2, FC3: UInt32;
     FC0, FC1, FC2, FC3: UInt32;
     FforEncryption: Boolean;
     FforEncryption: Boolean;
 
 
-    Fstate: TCryptoLibByteArray;
+    Fstate: array [0 .. 255] of Byte;
 
 
     function GetAlgorithmName: String; virtual;
     function GetAlgorithmName: String; virtual;
     function GetIsPartialBlockOkay: Boolean; virtual;
     function GetIsPartialBlockOkay: Boolean; virtual;
@@ -727,15 +727,15 @@ begin
   FWorkingKey := GenerateWorkingKey(forEncryption, keyParameter.GetKey());
   FWorkingKey := GenerateWorkingKey(forEncryption, keyParameter.GetKey());
 
 
   FforEncryption := forEncryption;
   FforEncryption := forEncryption;
+
   if forEncryption then
   if forEncryption then
   begin
   begin
-    System.SetLength(Fstate, System.SizeOf(S));
-    System.Move(S[System.Low(S)], Fstate[0], System.SizeOf(S));
+    System.Move(S[System.Low(S)], Fstate[System.Low(Fstate)], System.SizeOf(S));
   end
   end
   else
   else
   begin
   begin
-    System.SetLength(Fstate, System.SizeOf(Si));
-    System.Move(Si[System.Low(Si)], Fstate[0], System.SizeOf(Si));
+    System.Move(Si[System.Low(Si)], Fstate[System.Low(Fstate)],
+      System.SizeOf(Si));
   end;
   end;
 
 
 end;
 end;
@@ -762,7 +762,7 @@ begin
   if (FWorkingKey = Nil) then
   if (FWorkingKey = Nil) then
   begin
   begin
     raise EInvalidOperationCryptoLibException.CreateRes
     raise EInvalidOperationCryptoLibException.CreateRes
-      (@AESEngineNotInitialised);
+      (@SAESEngineNotInitialised);
   end;
   end;
 
 
   TCheck.DataLength(input, inOff, 16, SInputBuffertooShort);
   TCheck.DataLength(input, inOff, 16, SInputBuffertooShort);

+ 2 - 2
CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas

@@ -33,7 +33,7 @@ uses
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 resourcestring
 resourcestring
-  AESEngineNotInitialised = 'AES Engine not Initialised';
+  SAESEngineNotInitialised = 'AES Engine not Initialised';
   SInputBuffertooShort = 'Input Buffer too Short';
   SInputBuffertooShort = 'Input Buffer too Short';
   SOutputBuffertooShort = 'Output Buffer too Short';
   SOutputBuffertooShort = 'Output Buffer too Short';
   SInvalidParameterAESInit = 'Invalid Parameter Passed to AES Init - "%s"';
   SInvalidParameterAESInit = 'Invalid Parameter Passed to AES Init - "%s"';
@@ -679,7 +679,7 @@ begin
   if (FWorkingKey = Nil) then
   if (FWorkingKey = Nil) then
   begin
   begin
     raise EInvalidOperationCryptoLibException.CreateRes
     raise EInvalidOperationCryptoLibException.CreateRes
-      (@AESEngineNotInitialised);
+      (@SAESEngineNotInitialised);
   end;
   end;
 
 
   TCheck.DataLength(input, inOff, 16, SInputBuffertooShort);
   TCheck.DataLength(input, inOff, 16, SInputBuffertooShort);

+ 555 - 0
CryptoLib/src/Crypto/Engines/ClpBlowfishEngine.pas

@@ -0,0 +1,555 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBlowfishEngine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpIBlockCipher,
+  ClpIKeyParameter,
+  ClpICipherParameters,
+  ClpIBlowfishEngine,
+  ClpCheck,
+  ClpConverters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SBlowfishEngineNotInitialised = 'Blowfish Engine not Initialised';
+  SInvalidParameterBlowfishInit =
+    'Invalid Parameter Passed to Blowfish Init - "%s"';
+  SInputBuffertooShort = 'Input Buffer too Short';
+  SOutputBuffertooShort = 'Output Buffer too Short';
+  SInvalidKeyLength =
+    'Key Length must be between 32 - 448 bits and divisible by 8.';
+
+type
+
+  /// <summary>
+  /// A class that provides Blowfish key encryption operations, <br />such as
+  /// encoding data and generating keys. <br />All the algorithms herein are
+  /// from Applied Cryptography <br />and implement a simplified cryptography
+  /// interface. <br />
+  /// </summary>
+  TBlowfishEngine = class sealed(TInterfacedObject, IBlowfishEngine,
+    IBlockCipher)
+
+  strict private
+  const
+    ROUNDS = Int32(16);
+    BLOCK_SIZE = Int32(8); // bytes = 64 bits
+    SBOX_SK = Int32(256);
+    P_SZ = Int32(ROUNDS + 2);
+
+    KP: array [0 .. 17] of UInt32 = ($243F6A88, $85A308D3, $13198A2E, $03707344,
+      $A4093822, $299F31D0, $082EFA98, $EC4E6C89, $452821E6, $38D01377,
+      $BE5466CF, $34E90C6C, $C0AC29B7, $C97C50DD, $3F84D5B5, $B5470917,
+      $9216D5D9, $8979FB1B);
+
+    KS0: array [0 .. 255] of UInt32 = ($D1310BA6, $98DFB5AC, $2FFD72DB,
+      $D01ADFB7, $B8E1AFED, $6A267E96, $BA7C9045, $F12C7F99, $24A19947,
+      $B3916CF7, $0801F2E2, $858EFC16, $636920D8, $71574E69, $A458FEA3,
+      $F4933D7E, $0D95748F, $728EB658, $718BCD58, $82154AEE, $7B54A41D,
+      $C25A59B5, $9C30D539, $2AF26013, $C5D1B023, $286085F0, $CA417918,
+      $B8DB38EF, $8E79DCB0, $603A180E, $6C9E0E8B, $B01E8A3E, $D71577C1,
+      $BD314B27, $78AF2FDA, $55605C60, $E65525F3, $AA55AB94, $57489862,
+      $63E81440, $55CA396A, $2AAB10B6, $B4CC5C34, $1141E8CE, $A15486AF,
+      $7C72E993, $B3EE1411, $636FBC2A, $2BA9C55D, $741831F6, $CE5C3E16,
+      $9B87931E, $AFD6BA33, $6C24CF5C, $7A325381, $28958677, $3B8F4898,
+      $6B4BB9AF, $C4BFE81B, $66282193, $61D809CC, $FB21A991, $487CAC60,
+      $5DEC8032, $EF845D5D, $E98575B1, $DC262302, $EB651B88, $23893E81,
+      $D396ACC5, $0F6D6FF3, $83F44239, $2E0B4482, $A4842004, $69C8F04A,
+      $9E1F9B5E, $21C66842, $F6E96C9A, $670C9C61, $ABD388F0, $6A51A0D2,
+      $D8542F68, $960FA728, $AB5133A3, $6EEF0B6C, $137A3BE4, $BA3BF050,
+      $7EFB2A98, $A1F1651D, $39AF0176, $66CA593E, $82430E88, $8CEE8619,
+      $456F9FB4, $7D84A5C3, $3B8B5EBE, $E06F75D8, $85C12073, $401A449F,
+      $56C16AA6, $4ED3AA62, $363F7706, $1BFEDF72, $429B023D, $37D0D724,
+      $D00A1248, $DB0FEAD3, $49F1C09B, $075372C9, $80991B7B, $25D479D8,
+      $F6E8DEF7, $E3FE501A, $B6794C3B, $976CE0BD, $04C006BA, $C1A94FB6,
+      $409F60C4, $5E5C9EC2, $196A2463, $68FB6FAF, $3E6C53B5, $1339B2EB,
+      $3B52EC6F, $6DFC511F, $9B30952C, $CC814544, $AF5EBD09, $BEE3D004,
+      $DE334AFD, $660F2807, $192E4BB3, $C0CBA857, $45C8740F, $D20B5F39,
+      $B9D3FBDB, $5579C0BD, $1A60320A, $D6A100C6, $402C7279, $679F25FE,
+      $FB1FA3CC, $8EA5E9F8, $DB3222F8, $3C7516DF, $FD616B15, $2F501EC8,
+      $AD0552AB, $323DB5FA, $FD238760, $53317B48, $3E00DF82, $9E5C57BB,
+      $CA6F8CA0, $1A87562E, $DF1769DB, $D542A8F6, $287EFFC3, $AC6732C6,
+      $8C4F5573, $695B27B0, $BBCA58C8, $E1FFA35D, $B8F011A0, $10FA3D98,
+      $FD2183B8, $4AFCB56C, $2DD1D35B, $9A53E479, $B6F84565, $D28E49BC,
+      $4BFB9790, $E1DDF2DA, $A4CB7E33, $62FB1341, $CEE4C6E8, $EF20CADA,
+      $36774C01, $D07E9EFE, $2BF11FB4, $95DBDA4D, $AE909198, $EAAD8E71,
+      $6B93D5A0, $D08ED1D0, $AFC725E0, $8E3C5B2F, $8E7594B7, $8FF6E2FB,
+      $F2122B64, $8888B812, $900DF01C, $4FAD5EA0, $688FC31C, $D1CFF191,
+      $B3A8C1AD, $2F2F2218, $BE0E1777, $EA752DFE, $8B021FA1, $E5A0CC0F,
+      $B56F74E8, $18ACF3D6, $CE89E299, $B4A84FE0, $FD13E0B7, $7CC43B81,
+      $D2ADA8D9, $165FA266, $80957705, $93CC7314, $211A1477, $E6AD2065,
+      $77B5FA86, $C75442F5, $FB9D35CF, $EBCDAF0C, $7B3E89A0, $D6411BD3,
+      $AE1E7E49, $00250E2D, $2071B35E, $226800BB, $57B8E0AF, $2464369B,
+      $F009B91E, $5563911D, $59DFA6AA, $78C14389, $D95A537F, $207D5BA2,
+      $02E5B9C5, $83260376, $6295CFA9, $11C81968, $4E734A41, $B3472DCA,
+      $7B14A94A, $1B510052, $9A532915, $D60F573F, $BC9BC6E4, $2B60A476,
+      $81E67400, $08BA6FB5, $571BE91F, $F296EC6B, $2A0DD915, $B6636521,
+      $E7B9F9B6, $FF34052E, $C5855664, $53B02D5D, $A99F8FA1, $08BA4799,
+      $6E85076A);
+
+    KS1: array [0 .. 255] of UInt32 = ($4B7A70E9, $B5B32944, $DB75092E,
+      $C4192623, $AD6EA6B0, $49A7DF7D, $9CEE60B8, $8FEDB266, $ECAA8C71,
+      $699A17FF, $5664526C, $C2B19EE1, $193602A5, $75094C29, $A0591340,
+      $E4183A3E, $3F54989A, $5B429D65, $6B8FE4D6, $99F73FD6, $A1D29C07,
+      $EFE830F5, $4D2D38E6, $F0255DC1, $4CDD2086, $8470EB26, $6382E9C6,
+      $021ECC5E, $09686B3F, $3EBAEFC9, $3C971814, $6B6A70A1, $687F3584,
+      $52A0E286, $B79C5305, $AA500737, $3E07841C, $7FDEAE5C, $8E7D44EC,
+      $5716F2B8, $B03ADA37, $F0500C0D, $F01C1F04, $0200B3FF, $AE0CF51A,
+      $3CB574B2, $25837A58, $DC0921BD, $D19113F9, $7CA92FF6, $94324773,
+      $22F54701, $3AE5E581, $37C2DADC, $C8B57634, $9AF3DDA7, $A9446146,
+      $0FD0030E, $ECC8C73E, $A4751E41, $E238CD99, $3BEA0E2F, $3280BBA1,
+      $183EB331, $4E548B38, $4F6DB908, $6F420D03, $F60A04BF, $2CB81290,
+      $24977C79, $5679B072, $BCAF89AF, $DE9A771F, $D9930810, $B38BAE12,
+      $DCCF3F2E, $5512721F, $2E6B7124, $501ADDE6, $9F84CD87, $7A584718,
+      $7408DA17, $BC9F9ABC, $E94B7D8C, $EC7AEC3A, $DB851DFA, $63094366,
+      $C464C3D2, $EF1C1847, $3215D908, $DD433B37, $24C2BA16, $12A14D43,
+      $2A65C451, $50940002, $133AE4DD, $71DFF89E, $10314E55, $81AC77D6,
+      $5F11199B, $043556F1, $D7A3C76B, $3C11183B, $5924A509, $F28FE6ED,
+      $97F1FBFA, $9EBABF2C, $1E153C6E, $86E34570, $EAE96FB1, $860E5E0A,
+      $5A3E2AB3, $771FE71C, $4E3D06FA, $2965DCB9, $99E71D0F, $803E89D6,
+      $5266C825, $2E4CC978, $9C10B36A, $C6150EBA, $94E2EA78, $A5FC3C53,
+      $1E0A2DF4, $F2F74EA7, $361D2B3D, $1939260F, $19C27960, $5223A708,
+      $F71312B6, $EBADFE6E, $EAC31F66, $E3BC4595, $A67BC883, $B17F37D1,
+      $018CFF28, $C332DDEF, $BE6C5AA5, $65582185, $68AB9802, $EECEA50F,
+      $DB2F953B, $2AEF7DAD, $5B6E2F84, $1521B628, $29076170, $ECDD4775,
+      $619F1510, $13CCA830, $EB61BD96, $0334FE1E, $AA0363CF, $B5735C90,
+      $4C70A239, $D59E9E0B, $CBAADE14, $EECC86BC, $60622CA7, $9CAB5CAB,
+      $B2F3846E, $648B1EAF, $19BDF0CA, $A02369B9, $655ABB50, $40685A32,
+      $3C2AB4B3, $319EE9D5, $C021B8F7, $9B540B19, $875FA099, $95F7997E,
+      $623D7DA8, $F837889A, $97E32D77, $11ED935F, $16681281, $0E358829,
+      $C7E61FD6, $96DEDFA1, $7858BA99, $57F584A5, $1B227263, $9B83C3FF,
+      $1AC24696, $CDB30AEB, $532E3054, $8FD948E4, $6DBC3128, $58EBF2EF,
+      $34C6FFEA, $FE28ED61, $EE7C3C73, $5D4A14D9, $E864B7E3, $42105D14,
+      $203E13E0, $45EEE2B6, $A3AAABEA, $DB6C4F15, $FACB4FD0, $C742F442,
+      $EF6ABBB5, $654F3B1D, $41CD2105, $D81E799E, $86854DC7, $E44B476A,
+      $3D816250, $CF62A1F2, $5B8D2646, $FC8883A0, $C1C7B6A3, $7F1524C3,
+      $69CB7492, $47848A0B, $5692B285, $095BBF00, $AD19489D, $1462B174,
+      $23820E00, $58428D2A, $0C55F5EA, $1DADF43E, $233F7061, $3372F092,
+      $8D937E41, $D65FECF1, $6C223BDB, $7CDE3759, $CBEE7460, $4085F2A7,
+      $CE77326E, $A6078084, $19F8509E, $E8EFD855, $61D99735, $A969A7AA,
+      $C50C06C2, $5A04ABFC, $800BCADC, $9E447A2E, $C3453484, $FDD56705,
+      $0E1E9EC9, $DB73DBD3, $105588CD, $675FDA79, $E3674340, $C5C43465,
+      $713E38D8, $3D28F89E, $F16DFF20, $153E21E7, $8FB03D4A, $E6E39F2B,
+      $DB83ADF7);
+
+    KS2: array [0 .. 255] of UInt32 = ($E93D5A68, $948140F7, $F64C261C,
+      $94692934, $411520F7, $7602D4F7, $BCF46B2E, $D4A20068, $D4082471,
+      $3320F46A, $43B7D4B7, $500061AF, $1E39F62E, $97244546, $14214F74,
+      $BF8B8840, $4D95FC1D, $96B591AF, $70F4DDD3, $66A02F45, $BFBC09EC,
+      $03BD9785, $7FAC6DD0, $31CB8504, $96EB27B3, $55FD3941, $DA2547E6,
+      $ABCA0A9A, $28507825, $530429F4, $0A2C86DA, $E9B66DFB, $68DC1462,
+      $D7486900, $680EC0A4, $27A18DEE, $4F3FFEA2, $E887AD8C, $B58CE006,
+      $7AF4D6B6, $AACE1E7C, $D3375FEC, $CE78A399, $406B2A42, $20FE9E35,
+      $D9F385B9, $EE39D7AB, $3B124E8B, $1DC9FAF7, $4B6D1856, $26A36631,
+      $EAE397B2, $3A6EFA74, $DD5B4332, $6841E7F7, $CA7820FB, $FB0AF54E,
+      $D8FEB397, $454056AC, $BA489527, $55533A3A, $20838D87, $FE6BA9B7,
+      $D096954B, $55A867BC, $A1159A58, $CCA92963, $99E1DB33, $A62A4A56,
+      $3F3125F9, $5EF47E1C, $9029317C, $FDF8E802, $04272F70, $80BB155C,
+      $05282CE3, $95C11548, $E4C66D22, $48C1133F, $C70F86DC, $07F9C9EE,
+      $41041F0F, $404779A4, $5D886E17, $325F51EB, $D59BC0D1, $F2BCC18F,
+      $41113564, $257B7834, $602A9C60, $DFF8E8A3, $1F636C1B, $0E12B4C2,
+      $02E1329E, $AF664FD1, $CAD18115, $6B2395E0, $333E92E1, $3B240B62,
+      $EEBEB922, $85B2A20E, $E6BA0D99, $DE720C8C, $2DA2F728, $D0127845,
+      $95B794FD, $647D0862, $E7CCF5F0, $5449A36F, $877D48FA, $C39DFD27,
+      $F33E8D1E, $0A476341, $992EFF74, $3A6F6EAB, $F4F8FD37, $A812DC60,
+      $A1EBDDF8, $991BE14C, $DB6E6B0D, $C67B5510, $6D672C37, $2765D43B,
+      $DCD0E804, $F1290DC7, $CC00FFA3, $B5390F92, $690FED0B, $667B9FFB,
+      $CEDB7D9C, $A091CF0B, $D9155EA3, $BB132F88, $515BAD24, $7B9479BF,
+      $763BD6EB, $37392EB3, $CC115979, $8026E297, $F42E312D, $6842ADA7,
+      $C66A2B3B, $12754CCC, $782EF11C, $6A124237, $B79251E7, $06A1BBE6,
+      $4BFB6350, $1A6B1018, $11CAEDFA, $3D25BDD8, $E2E1C3C9, $44421659,
+      $0A121386, $D90CEC6E, $D5ABEA2A, $64AF674E, $DA86A85F, $BEBFE988,
+      $64E4C3FE, $9DBC8057, $F0F7C086, $60787BF8, $6003604D, $D1FD8346,
+      $F6381FB0, $7745AE04, $D736FCCC, $83426B33, $F01EAB71, $B0804187,
+      $3C005E5F, $77A057BE, $BDE8AE24, $55464299, $BF582E61, $4E58F48F,
+      $F2DDFDA2, $F474EF38, $8789BDC2, $5366F9C3, $C8B38E74, $B475F255,
+      $46FCD9B9, $7AEB2661, $8B1DDF84, $846A0E79, $915F95E2, $466E598E,
+      $20B45770, $8CD55591, $C902DE4C, $B90BACE1, $BB8205D0, $11A86248,
+      $7574A99E, $B77F19B6, $E0A9DC09, $662D09A1, $C4324633, $E85A1F02,
+      $09F0BE8C, $4A99A025, $1D6EFE10, $1AB93D1D, $0BA5A4DF, $A186F20F,
+      $2868F169, $DCB7DA83, $573906FE, $A1E2CE9B, $4FCD7F52, $50115E01,
+      $A70683FA, $A002B5C4, $0DE6D027, $9AF88C27, $773F8641, $C3604C06,
+      $61A806B5, $F0177A28, $C0F586E0, $006058AA, $30DC7D62, $11E69ED7,
+      $2338EA63, $53C2DD94, $C2C21634, $BBCBEE56, $90BCB6DE, $EBFC7DA1,
+      $CE591D76, $6F05E409, $4B7C0188, $39720A3D, $7C927C24, $86E3725F,
+      $724D9DB9, $1AC15BB4, $D39EB8FC, $ED545578, $08FCA5B5, $D83D7CD3,
+      $4DAD0FC4, $1E50EF5E, $B161E6F8, $A28514D9, $6C51133C, $6FD5C7E7,
+      $56E14EC4, $362ABFCE, $DDC6C837, $D79A3234, $92638212, $670EFA8E,
+      $406000E0);
+
+    KS3: array [0 .. 255] of UInt32 = ($3A39CE37, $D3FAF5CF, $ABC27737,
+      $5AC52D1B, $5CB0679E, $4FA33742, $D3822740, $99BC9BBE, $D5118E9D,
+      $BF0F7315, $D62D1C7E, $C700C47B, $B78C1B6B, $21A19045, $B26EB1BE,
+      $6A366EB4, $5748AB2F, $BC946E79, $C6A376D2, $6549C2C8, $530FF8EE,
+      $468DDE7D, $D5730A1D, $4CD04DC6, $2939BBDB, $A9BA4650, $AC9526E8,
+      $BE5EE304, $A1FAD5F0, $6A2D519A, $63EF8CE2, $9A86EE22, $C089C2B8,
+      $43242EF6, $A51E03AA, $9CF2D0A4, $83C061BA, $9BE96A4D, $8FE51550,
+      $BA645BD6, $2826A2F9, $A73A3AE1, $4BA99586, $EF5562E9, $C72FEFD3,
+      $F752F7DA, $3F046F69, $77FA0A59, $80E4A915, $87B08601, $9B09E6AD,
+      $3B3EE593, $E990FD5A, $9E34D797, $2CF0B7D9, $022B8B51, $96D5AC3A,
+      $017DA67D, $D1CF3ED6, $7C7D2D28, $1F9F25CF, $ADF2B89B, $5AD6B472,
+      $5A88F54C, $E029AC71, $E019A5E6, $47B0ACFD, $ED93FA9B, $E8D3C48D,
+      $283B57CC, $F8D56629, $79132E28, $785F0191, $ED756055, $F7960E44,
+      $E3D35E8C, $15056DD4, $88F46DBA, $03A16125, $0564F0BD, $C3EB9E15,
+      $3C9057A2, $97271AEC, $A93A072A, $1B3F6D9B, $1E6321F5, $F59C66FB,
+      $26DCF319, $7533D928, $B155FDF5, $03563482, $8ABA3CBB, $28517711,
+      $C20AD9F8, $ABCC5167, $CCAD925F, $4DE81751, $3830DC8E, $379D5862,
+      $9320F991, $EA7A90C2, $FB3E7BCE, $5121CE64, $774FBE32, $A8B6E37E,
+      $C3293D46, $48DE5369, $6413E680, $A2AE0810, $DD6DB224, $69852DFD,
+      $09072166, $B39A460A, $6445C0DD, $586CDECF, $1C20C8AE, $5BBEF7DD,
+      $1B588D40, $CCD2017F, $6BB4E3BB, $DDA26A7E, $3A59FF45, $3E350A44,
+      $BCB4CDD5, $72EACEA8, $FA6484BB, $8D6612AE, $BF3C6F47, $D29BE463,
+      $542F5D9E, $AEC2771B, $F64E6370, $740E0D8D, $E75B1357, $F8721671,
+      $AF537D5D, $4040CB08, $4EB4E2CC, $34D2466A, $0115AF84, $E1B00428,
+      $95983A1D, $06B89FB4, $CE6EA048, $6F3F3B82, $3520AB82, $011A1D4B,
+      $277227F8, $611560B1, $E7933FDC, $BB3A792B, $344525BD, $A08839E1,
+      $51CE794B, $2F32C9B7, $A01FBAC9, $E01CC87E, $BCC7D1F6, $CF0111C3,
+      $A1E8AAC7, $1A908749, $D44FBD9A, $D0DADECB, $D50ADA38, $0339C32A,
+      $C6913667, $8DF9317C, $E0B12B4F, $F79E59B7, $43F5BB3A, $F2D519FF,
+      $27D9459C, $BF97222C, $15E6FC2A, $0F91FC71, $9B941525, $FAE59361,
+      $CEB69CEB, $C2A86459, $12BAA8D1, $B6C1075E, $E3056A0C, $10D25065,
+      $CB03A442, $E0EC6E0E, $1698DB3B, $4C98A0BE, $3278E964, $9F1F9532,
+      $E0D392DF, $D3A0342B, $8971F21E, $1B0A7441, $4BA3348C, $C5BE7120,
+      $C37632D8, $DF359F8D, $9B992F2E, $E60B6F47, $0FE3F11D, $E54CDA54,
+      $1EDAD891, $CE6279CF, $CD3E7E6F, $1618B166, $FD2C1D05, $848FD2C5,
+      $F6FB2299, $F523F357, $A6327623, $93A83531, $56CCCD02, $ACF08162,
+      $5A75EBB5, $6E163697, $88D273CC, $DE966292, $81B949D0, $4C50901B,
+      $71C65614, $E6C6C7BD, $327A140A, $45E1D006, $C3F27B9A, $C9AA53FD,
+      $62A80F00, $BB25BFE2, $35BDD2F6, $71126905, $B2040222, $B6CBCF7C,
+      $CD769C2B, $53113EC0, $1640E3D3, $38ABBD60, $2547ADF0, $BA38209C,
+      $F746CE76, $77AFA1C5, $20756060, $85CBFE4E, $8AE88DD8, $7AAAF9B0,
+      $4CF9AA7E, $1948C25C, $02FB8A8C, $01C36AE4, $D6EBE1F9, $90D4F869,
+      $A65CDEA0, $3F09252D, $C208E69F, $B74E6132, $CE77E25B, $578FDFE3,
+      $3AC372E6);
+
+  var
+    FS0, FS1, FS2, FS3: array [0 .. (SBOX_SK - 1)] of UInt32; // the s-boxes
+    FP: array [0 .. (P_SZ - 1)] of UInt32; // the p-array
+
+    FforEncryption: Boolean;
+
+    FWorkingKey: TCryptoLibByteArray;
+
+    function F(x: UInt32): UInt32; inline;
+    procedure SetKey(const key: TCryptoLibByteArray);
+
+    /// <summary>
+    /// apply the encryption cycle to each value pair in the table.
+    /// </summary>
+    procedure ProcessTable(xl, xr: UInt32; var table: array of UInt32);
+
+    /// <summary>
+    /// Encrypt the given input starting at the given offset and place <br />
+    /// the result in the provided buffer starting at the given offset. <br />
+    /// The input will be an exact multiple of our blocksize.
+    /// </summary>
+    procedure EncryptBlock(const src: TCryptoLibByteArray; srcIndex: Int32;
+      const dst: TCryptoLibByteArray; dstIndex: Int32);
+
+    /// <summary>
+    /// Decrypt the given input starting at the given offset and place <br />
+    /// the result in the provided buffer starting at the given offset. <br />
+    /// The input will be an exact multiple of our blocksize.
+    /// </summary>
+    procedure DecryptBlock(const src: TCryptoLibByteArray; srcIndex: Int32;
+      const dst: TCryptoLibByteArray; dstIndex: Int32);
+
+    function GetAlgorithmName: String; virtual;
+    function GetIsPartialBlockOkay: Boolean; virtual;
+    function GetBlockSize(): Int32; virtual;
+
+  public
+
+    /// <summary>
+    /// initialise a Blowfish cipher.
+    /// </summary>
+    /// <param name="forEncryption">
+    /// whether or not we are for encryption.
+    /// </param>
+    /// <param name="parameters">
+    /// the parameters required to set up the cipher.
+    /// </param>
+    /// <exception cref="EArgumentCryptoLibException">
+    /// if the parameters argument is inappropriate.
+    /// </exception>
+    procedure Init(forEncryption: Boolean;
+      const parameters: ICipherParameters); virtual;
+
+    function ProcessBlock(const input: TCryptoLibByteArray; inOff: Int32;
+      const output: TCryptoLibByteArray; outOff: Int32): Int32; virtual;
+
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+    property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
+
+  end;
+
+implementation
+
+{ TBlowfishEngine }
+
+function TBlowfishEngine.F(x: UInt32): UInt32;
+begin
+  result := (((FS0[x shr 24] + FS1[(x shr 16) and $FF]) xor FS2[(x shr 8) and
+    $FF]) + FS3[x and $FF]);
+end;
+
+procedure TBlowfishEngine.SetKey(const key: TCryptoLibByteArray);
+var
+  keyLength, keyIndex, i, j: Int32;
+  data: UInt32;
+begin
+  keyLength := System.Length(key);
+  if ((keyLength < 4) or (keyLength > 56) or (((keyLength * 8) and 7) <> 0))
+  then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidKeyLength);
+  end;
+
+  (*
+    * - comments are from _Applied Crypto_, Schneier, p338
+    * please be careful comparing the two, AC numbers the
+    * arrays from 1, the enclosed code from 0.
+    *
+    * (1)
+    * Initialise the S-boxes and the P-array, with a fixed string
+    * This string contains the hexadecimal digits of pi (3.141...)
+  *)
+  System.Move(KS0[System.Low(KS0)], FS0[System.Low(FS0)],
+    SBOX_SK * System.SizeOf(UInt32));
+  System.Move(KS1[System.Low(KS1)], FS1[System.Low(FS1)],
+    SBOX_SK * System.SizeOf(UInt32));
+  System.Move(KS2[System.Low(KS2)], FS2[System.Low(FS2)],
+    SBOX_SK * System.SizeOf(UInt32));
+  System.Move(KS3[System.Low(KS3)], FS3[System.Low(FS3)],
+    SBOX_SK * System.SizeOf(UInt32));
+
+  System.Move(KP[System.Low(KP)], FP[System.Low(FP)],
+    P_SZ * System.SizeOf(UInt32));
+
+  (*
+    * (2)
+    * Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the
+    * second 32-bits of the key, and so on for all bits of the key
+    * (up to P[17]).  Repeatedly cycle through the key bits until the
+    * entire P-array has been XOR-ed with the key bits
+  *)
+  keyIndex := 0;
+
+  i := 0;
+  while i < P_SZ do
+  begin
+    // Get the 32 bits of the key, in 4 * 8 bit chunks
+    data := $0000000;
+    j := 0;
+    while j < 4 do
+    begin
+      // create a 32 bit block
+      data := (data shl 8) or UInt32(key[keyIndex]);
+      System.Inc(keyIndex);
+
+      // wrap when we get to the end of the key
+      if (keyIndex >= keyLength) then
+      begin
+        keyIndex := 0;
+      end;
+      System.Inc(j);
+    end;
+    // XOR the newly created 32 bit chunk onto the P-array
+    FP[i] := FP[i] xor data;
+
+    System.Inc(i);
+  end;
+
+  (*
+    * (3)
+    * Encrypt the all-zero string with the Blowfish algorithm, using
+    * the subkeys described in (1) and (2)
+    *
+    * (4)
+    * Replace P1 and P2 with the output of step (3)
+    *
+    * (5)
+    * Encrypt the output of step(3) using the Blowfish algorithm,
+    * with the modified subkeys.
+    *
+    * (6)
+    * Replace P3 and P4 with the output of step (5)
+    *
+    * (7)
+    * Continue the process, replacing all elements of the P-array
+    * and then all four S-boxes in order, with the output of the
+    * continuously changing Blowfish algorithm
+  *)
+
+  ProcessTable(0, 0, FP);
+  ProcessTable(FP[P_SZ - 2], FP[P_SZ - 1], FS0);
+  ProcessTable(FS0[SBOX_SK - 2], FS0[SBOX_SK - 1], FS1);
+  ProcessTable(FS1[SBOX_SK - 2], FS1[SBOX_SK - 1], FS2);
+  ProcessTable(FS2[SBOX_SK - 2], FS2[SBOX_SK - 1], FS3);
+end;
+
+procedure TBlowfishEngine.EncryptBlock(const src: TCryptoLibByteArray;
+  srcIndex: Int32; const dst: TCryptoLibByteArray; dstIndex: Int32);
+var
+  xl, xr: UInt32;
+  i: Int32;
+begin
+  xl := TConverters.ReadBytesAsUInt32BE(PByte(src), srcIndex);
+  xr := TConverters.ReadBytesAsUInt32BE(PByte(src), srcIndex + 4);
+
+  xl := xl xor FP[0];
+
+  i := 1;
+  while i < ROUNDS do
+
+  begin
+    xr := xr xor (F(xl) xor FP[i]);
+    xl := xl xor (F(xr) xor FP[i + 1]);
+    System.Inc(i, 2);
+  end;
+
+  xr := xr xor FP[ROUNDS + 1];
+
+  TConverters.ReadUInt32AsBytesBE(xr, dst, dstIndex);
+  TConverters.ReadUInt32AsBytesBE(xl, dst, dstIndex + 4);
+end;
+
+procedure TBlowfishEngine.DecryptBlock(const src: TCryptoLibByteArray;
+  srcIndex: Int32; const dst: TCryptoLibByteArray; dstIndex: Int32);
+var
+  xl, xr: UInt32;
+  i: Int32;
+begin
+  xl := TConverters.ReadBytesAsUInt32BE(PByte(src), srcIndex);
+  xr := TConverters.ReadBytesAsUInt32BE(PByte(src), srcIndex + 4);
+
+  xl := xl xor FP[ROUNDS + 1];
+
+  i := ROUNDS;
+  while i > 0 do
+
+  begin
+    xr := xr xor (F(xl) xor FP[i]);
+    xl := xl xor (F(xr) xor FP[i - 1]);
+    System.Dec(i, 2);
+  end;
+
+  xr := xr xor FP[0];
+
+  TConverters.ReadUInt32AsBytesBE(xr, dst, dstIndex);
+  TConverters.ReadUInt32AsBytesBE(xl, dst, dstIndex + 4);
+end;
+
+function TBlowfishEngine.GetAlgorithmName: String;
+begin
+  result := 'Blowfish';
+end;
+
+function TBlowfishEngine.GetBlockSize: Int32;
+begin
+  result := BLOCK_SIZE;
+end;
+
+function TBlowfishEngine.GetIsPartialBlockOkay: Boolean;
+begin
+  result := false;
+end;
+
+procedure TBlowfishEngine.Init(forEncryption: Boolean;
+  const parameters: ICipherParameters);
+var
+  keyParameter: IKeyParameter;
+begin
+  if not Supports(parameters, IKeyParameter, keyParameter) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SInvalidParameterBlowfishInit, [(parameters as TObject).ToString]);
+  end;
+  FforEncryption := forEncryption;
+  FWorkingKey := keyParameter.GetKey();
+  SetKey(FWorkingKey);
+end;
+
+function TBlowfishEngine.ProcessBlock(const input: TCryptoLibByteArray;
+  inOff: Int32; const output: TCryptoLibByteArray; outOff: Int32): Int32;
+begin
+
+  if (FWorkingKey = Nil) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SBlowfishEngineNotInitialised);
+  end;
+
+  TCheck.DataLength(input, inOff, BLOCK_SIZE, SInputBuffertooShort);
+  TCheck.OutputLength(output, outOff, BLOCK_SIZE, SOutputBuffertooShort);
+
+  if (FforEncryption) then
+  begin
+    EncryptBlock(input, inOff, output, outOff);
+  end
+  else
+  begin
+    DecryptBlock(input, inOff, output, outOff);
+  end;
+
+  result := BLOCK_SIZE;
+end;
+
+procedure TBlowfishEngine.ProcessTable(xl, xr: UInt32;
+  var table: array of UInt32);
+var
+  size, s, i: Int32;
+begin
+  size := System.Length(table);
+  s := 0;
+  while s < size do
+  begin
+    xl := xl xor FP[0];
+    i := 1;
+    while i < ROUNDS do
+    begin
+      xr := xr xor (F(xl) xor FP[i]);
+      xl := xl xor (F(xr) xor FP[i + 1]);
+      System.Inc(i, 2);
+    end;
+
+    xr := xr xor FP[ROUNDS + 1];
+
+    table[s] := xr;
+    table[s + 1] := xl;
+
+    xr := xl; // end of cycle swap
+    xl := table[s];
+    System.Inc(s, 2);
+  end;
+end;
+
+procedure TBlowfishEngine.Reset;
+begin
+  // nothing to do.
+end;
+
+end.

+ 2 - 2
CryptoLib/src/Crypto/Modes/ClpCbcBlockCipher.pas

@@ -27,6 +27,7 @@ uses
   ClpICbcBlockCipher,
   ClpICbcBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpIParametersWithIV,
   ClpIParametersWithIV,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 resourcestring
 resourcestring
@@ -283,8 +284,7 @@ end;
 procedure TCbcBlockCipher.Reset;
 procedure TCbcBlockCipher.Reset;
 begin
 begin
   System.Move(FIV[0], FcbcV[0], System.length(FIV));
   System.Move(FIV[0], FcbcV[0], System.length(FIV));
-  System.FillChar(FcbcNextV[0], System.length(FcbcNextV) *
-    System.SizeOf(Byte), Byte(0));
+  TArrayUtils.Fill(FcbcNextV, 0, System.length(FcbcNextV), Byte(0));
 
 
   Fcipher.Reset();
   Fcipher.Reset();
 end;
 end;

+ 2 - 1
CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas

@@ -27,6 +27,7 @@ uses
   ClpICfbBlockCipher,
   ClpICfbBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpIParametersWithIV,
   ClpIParametersWithIV,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 resourcestring
 resourcestring
@@ -343,7 +344,7 @@ begin
     diff := System.length(FIV) - System.length(iv);
     diff := System.length(FIV) - System.length(iv);
 
 
     System.Move(iv[0], FIV[diff], System.length(iv) * System.SizeOf(Byte));
     System.Move(iv[0], FIV[diff], System.length(iv) * System.SizeOf(Byte));
-    System.FillChar(FIV[0], diff, Byte(0));
+    TArrayUtils.Fill(FIV, 0, diff, Byte(0));
 
 
     Lparameters := ivParam.parameters;
     Lparameters := ivParam.parameters;
   end;
   end;

+ 2 - 2
CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas

@@ -28,6 +28,7 @@ uses
   ClpISicBlockCipher,
   ClpISicBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpIParametersWithIV,
   ClpIParametersWithIV,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 resourcestring
 resourcestring
@@ -170,8 +171,7 @@ end;
 
 
 procedure TSicBlockCipher.Reset;
 procedure TSicBlockCipher.Reset;
 begin
 begin
-  System.FillChar(Fcounter[0], System.Length(Fcounter) *
-    System.SizeOf(Byte), Byte(0));
+  TArrayUtils.Fill(Fcounter, 0, System.Length(Fcounter), Byte(0));
   System.Move(FIV[0], Fcounter[0], System.Length(FIV) * System.SizeOf(Byte));
   System.Move(FIV[0], Fcounter[0], System.Length(FIV) * System.SizeOf(Byte));
 
 
   Fcipher.Reset();
   Fcipher.Reset();

+ 36 - 0
CryptoLib/src/Interfaces/ClpIBlowfishEngine.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIBlowfishEngine;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipher;
+
+type
+
+  IBlowfishEngine = interface(IBlockCipher)
+    ['{005CFC45-DEB3-4AC1-896D-1370AF09F3C5}']
+
+  end;
+
+implementation
+
+end.

+ 3 - 4
CryptoLib/src/Math/ClpBigInteger.pas

@@ -30,6 +30,7 @@ uses
   ClpNumberStyles,
   ClpNumberStyles,
   ClpISecureRandom,
   ClpISecureRandom,
   ClpIRandom,
   ClpIRandom,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 resourcestring
 resourcestring
@@ -3828,8 +3829,7 @@ begin
 
 
   if (xyCmp = 0) then
   if (xyCmp = 0) then
   begin
   begin
-    System.FillChar(x[xStart], (System.length(x) - xStart) *
-      System.SizeOf(Int32), Int32(0));
+    TArrayUtils.Fill(x, xStart, System.length(x), Int32(0));
   end;
   end;
 
 
   Result := x;
   Result := x;
@@ -4844,8 +4844,7 @@ begin
   if (xyCmp = 0) then
   if (xyCmp = 0) then
   begin
   begin
     AddMagnitudes(Count, One.Fmagnitude);
     AddMagnitudes(Count, One.Fmagnitude);
-    System.FillChar(x[xStart], (System.length(x) - xStart) *
-      System.SizeOf(Int32), Int32(0));
+    TArrayUtils.Fill(x, xStart, System.length(x), Int32(0));
   end;
   end;
 
 
   Result := Count;
   Result := Count;

+ 2 - 1
CryptoLib/src/Math/Raw/ClpNat.pas

@@ -25,6 +25,7 @@ uses
   ClpConverters,
   ClpConverters,
   ClpBits,
   ClpBits,
   ClpBigInteger,
   ClpBigInteger,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 type
 type
@@ -2039,7 +2040,7 @@ end;
 
 
 class procedure TNat.Zero(len: Int32; const z: TCryptoLibUInt32Array);
 class procedure TNat.Zero(len: Int32; const z: TCryptoLibUInt32Array);
 begin
 begin
-  System.FillChar(z[0], len * System.SizeOf(UInt32), UInt32(0));
+    TArrayUtils.Fill(z, 0, len, UInt32(0));
 end;
 end;
 
 
 end.
 end.

+ 2 - 1
CryptoLib/src/Math/Raw/ClpNat192.pas

@@ -26,6 +26,7 @@ uses
   ClpNat,
   ClpNat,
   ClpBigInteger,
   ClpBigInteger,
   ClpConverters,
   ClpConverters,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 type
 type
@@ -1420,7 +1421,7 @@ end;
 
 
 class procedure TNat192.Zero(const z: TCryptoLibUInt32Array);
 class procedure TNat192.Zero(const z: TCryptoLibUInt32Array);
 begin
 begin
-  System.FillChar(z[0], 6 * System.SizeOf(UInt32), UInt32(0));
+  TArrayUtils.Fill(z, 0, 6, UInt32(0));
 end;
 end;
 
 
 end.
 end.

+ 2 - 1
CryptoLib/src/Math/Raw/ClpNat256.pas

@@ -26,6 +26,7 @@ uses
   ClpConverters,
   ClpConverters,
   ClpBits,
   ClpBits,
   ClpBigInteger,
   ClpBigInteger,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 type
 type
@@ -1774,7 +1775,7 @@ end;
 
 
 class procedure TNat256.Zero(const z: TCryptoLibUInt32Array);
 class procedure TNat256.Zero(const z: TCryptoLibUInt32Array);
 begin
 begin
-  System.FillChar(z[0], 8 * System.SizeOf(UInt32), UInt32(0));
+  TArrayUtils.Fill(z, 0, 8, UInt32(0));
 end;
 end;
 
 
 end.
 end.

+ 9 - 1
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk

@@ -25,7 +25,7 @@
  Acknowledgements: 
  Acknowledgements: 
 Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
 Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
     <Version Major="2" Minor="7"/>
     <Version Major="2" Minor="7"/>
-    <Files Count="458">
+    <Files Count="460">
       <Item1>
       <Item1>
         <Filename Value="..\..\Asn1\ClpAsn1Encodable.pas"/>
         <Filename Value="..\..\Asn1\ClpAsn1Encodable.pas"/>
         <UnitName Value="ClpAsn1Encodable"/>
         <UnitName Value="ClpAsn1Encodable"/>
@@ -1860,6 +1860,14 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
         <Filename Value="..\..\Interfaces\ClpISchnorrExt.pas"/>
         <Filename Value="..\..\Interfaces\ClpISchnorrExt.pas"/>
         <UnitName Value="ClpISchnorrExt"/>
         <UnitName Value="ClpISchnorrExt"/>
       </Item458>
       </Item458>
+      <Item459>
+        <Filename Value="..\..\Crypto\Engines\ClpBlowfishEngine.pas"/>
+        <UnitName Value="ClpBlowfishEngine"/>
+      </Item459>
+      <Item460>
+        <Filename Value="..\..\Interfaces\ClpIBlowfishEngine.pas"/>
+        <UnitName Value="ClpIBlowfishEngine"/>
+      </Item460>
     </Files>
     </Files>
     <RequiredPkgs Count="3">
     <RequiredPkgs Count="3">
       <Item1>
       <Item1>

+ 1 - 1
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas

@@ -150,7 +150,7 @@ uses
   ClpIDsaExt, ClpIDsaEncoding, ClpISchnorrDigestSigner, 
   ClpIDsaExt, ClpIDsaEncoding, ClpISchnorrDigestSigner, 
   ClpIECSchnorrSipaSigner, ClpECSchnorrSipaSigner, ClpSchnorrDigestSigner, 
   ClpIECSchnorrSipaSigner, ClpECSchnorrSipaSigner, ClpSchnorrDigestSigner, 
   ClpPlainSchnorrEncoding, ClpIPlainSchnorrEncoding, ClpISchnorrEncoding, 
   ClpPlainSchnorrEncoding, ClpIPlainSchnorrEncoding, ClpISchnorrEncoding, 
-  ClpISchnorr, ClpISchnorrExt;
+  ClpISchnorr, ClpISchnorrExt, ClpBlowfishEngine, ClpIBlowfishEngine;
 
 
 implementation
 implementation
 
 

+ 9 - 1
CryptoLib/src/Security/ClpCipherUtilities.pas

@@ -57,6 +57,8 @@ uses
   ClpIBlockCipher,
   ClpIBlockCipher,
   ClpAesEngine,
   ClpAesEngine,
   ClpIAesEngine,
   ClpIAesEngine,
+  ClpBlowfishEngine,
+  ClpIBlowfishEngine,
   ClpIBlockCipherPadding;
   ClpIBlockCipherPadding;
 
 
 resourcestring
 resourcestring
@@ -77,7 +79,7 @@ type
 
 
   type
   type
 {$SCOPEDENUMS ON}
 {$SCOPEDENUMS ON}
-    TCipherAlgorithm = (AES);
+    TCipherAlgorithm = (AES, BLOWFISH);
     TCipherMode = (NONE, CBC, CFB, CTR, ECB, OFB, SIC);
     TCipherMode = (NONE, CBC, CFB, CTR, ECB, OFB, SIC);
     TCipherPadding = (NOPADDING, ISO10126PADDING, ISO10126D2PADDING,
     TCipherPadding = (NOPADDING, ISO10126PADDING, ISO10126D2PADDING,
       ISO10126_2PADDING, ISO7816_4PADDING, ISO9797_1PADDING, PKCS5,
       ISO10126_2PADDING, ISO7816_4PADDING, ISO9797_1PADDING, PKCS5,
@@ -153,6 +155,8 @@ begin
   Falgorithms.Add(TNistObjectIdentifiers.IdAes192Cfb.Id, 'AES/CFB/NOPADDING');
   Falgorithms.Add(TNistObjectIdentifiers.IdAes192Cfb.Id, 'AES/CFB/NOPADDING');
   Falgorithms.Add(TNistObjectIdentifiers.IdAes256Cfb.Id, 'AES/CFB/NOPADDING');
   Falgorithms.Add(TNistObjectIdentifiers.IdAes256Cfb.Id, 'AES/CFB/NOPADDING');
 
 
+  Falgorithms.Add('1.3.6.1.4.1.3029.1.2', 'BLOWFISH/CBC');
+
 end;
 end;
 
 
 class constructor TCipherUtilities.CreateCipherUtilities;
 class constructor TCipherUtilities.CreateCipherUtilities;
@@ -238,6 +242,10 @@ begin
     TCipherAlgorithm.AES:
     TCipherAlgorithm.AES:
       begin
       begin
         blockCipher := TAesEngine.Create() as IAesEngine;
         blockCipher := TAesEngine.Create() as IAesEngine;
+      end;
+    TCipherAlgorithm.BLOWFISH:
+      begin
+        blockCipher := TBlowfishEngine.Create() as IBlowfishEngine;
       end
       end
   else
   else
     begin
     begin

+ 4 - 2
CryptoLib/src/Security/ClpGeneratorUtilities.pas

@@ -194,6 +194,8 @@ begin
     TNistObjectIdentifiers.IdAes256Ecb.ID,
     TNistObjectIdentifiers.IdAes256Ecb.ID,
     TNistObjectIdentifiers.IdAes256Ofb.ID]);
     TNistObjectIdentifiers.IdAes256Ofb.ID]);
 
 
+  AddKgAlgorithm('BLOWFISH', ['1.3.6.1.4.1.3029.1.2']);
+
   //
   //
   // HMac key generators
   // HMac key generators
   //
   //
@@ -241,8 +243,8 @@ begin
   AddKpgAlgorithm('ECDH', ['ECIES']);
   AddKpgAlgorithm('ECDH', ['ECIES']);
   AddKpgAlgorithm('ECDSA', []);
   AddKpgAlgorithm('ECDSA', []);
 
 
-  AddDefaultKeySizeEntries(128, ['AES128', 'HMACMD2', 'HMACMD4', 'HMACMD5',
-    'HMACRIPEMD128']);
+  AddDefaultKeySizeEntries(128, ['AES128', 'BLOWFISH', 'HMACMD2', 'HMACMD4',
+    'HMACMD5', 'HMACRIPEMD128']);
   AddDefaultKeySizeEntries(160, ['HMACRIPEMD160', 'HMACSHA1']);
   AddDefaultKeySizeEntries(160, ['HMACRIPEMD160', 'HMACSHA1']);
   AddDefaultKeySizeEntries(192, ['AES', 'AES192', 'HMACTIGER']);
   AddDefaultKeySizeEntries(192, ['AES', 'AES192', 'HMACTIGER']);
   AddDefaultKeySizeEntries(224, ['HMACSHA3-224', 'HMACSHA224',
   AddDefaultKeySizeEntries(224, ['HMACSHA3-224', 'HMACSHA224',

+ 33 - 3
CryptoLib/src/Utils/ClpArrayUtils.pas

@@ -84,7 +84,13 @@ type
       : Boolean; static;
       : Boolean; static;
 
 
     class procedure Fill(const buf: TCryptoLibByteArray; from, &to: Int32;
     class procedure Fill(const buf: TCryptoLibByteArray; from, &to: Int32;
-      B: Byte); static;
+      filler: Byte); overload; static;
+
+    class procedure Fill(const buf: TCryptoLibInt32Array; from, &to: Int32;
+      filler: Int32); overload; static;
+
+    class procedure Fill(const buf: TCryptoLibUInt32Array; from, &to: Int32;
+      filler: UInt32); overload; static;
 
 
   end;
   end;
 
 
@@ -244,9 +250,33 @@ begin
 end;
 end;
 
 
 class procedure TArrayUtils.Fill(const buf: TCryptoLibByteArray;
 class procedure TArrayUtils.Fill(const buf: TCryptoLibByteArray;
-  from, &to: Int32; B: Byte);
+  from, &to: Int32; filler: Byte);
+begin
+  System.FillChar(buf[from], (&to - from) * System.SizeOf(Byte), filler);
+end;
+
+class procedure TArrayUtils.Fill(const buf: TCryptoLibInt32Array;
+  from, &to: Int32; filler: Int32);
+begin
+  while from < &to do
+  begin
+    buf[from] := filler;
+    System.Inc(from);
+  end;
+end;
+
+class procedure TArrayUtils.Fill(const buf: TCryptoLibUInt32Array;
+  from, &to: Int32; filler: UInt32);
 begin
 begin
-  System.FillChar(buf[from], (&to - from) * System.SizeOf(Byte), B);
+{$IFDEF FPC}
+  System.FillDWord(buf[from], (&to - from), filler);
+{$ELSE}
+  while from < &to do
+  begin
+    buf[from] := filler;
+    System.Inc(from);
+  end;
+{$ENDIF}
 end;
 end;
 
 
 class function TArrayUtils.GetArrayHashCode(const data
 class function TArrayUtils.GetArrayHashCode(const data