Browse Source

added more AES block and padding modes support

- added AES OFB, CFB, CTR and SIC block modes
- added the following padding support
ISO10126PADDING, ISO10126D2PADDING,
      ISO10126_2PADDING, ISO7816_4PADDING, ISO9797_1PADDING, TBCPADDING, X923PADDING.
- some refactoring.
Ugochukwu Mmaduekwe 7 years ago
parent
commit
fdf8d8fa86
58 changed files with 3525 additions and 533 deletions
  1. 22 2
      CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr
  2. 96 57
      CryptoLib.Samples/src/UsageExamples.pas
  3. 22 2
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
  4. 5 1
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
  5. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
  6. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
  7. 223 0
      CryptoLib.Tests/src/Crypto/AESSICTests.pas
  8. 88 7
      CryptoLib.Tests/src/Crypto/AESTests.pas
  9. 23 25
      CryptoLib.Tests/src/Crypto/DigestRandomNumberTests.pas
  10. 8 8
      CryptoLib.Tests/src/Crypto/IESCipherTests.pas
  11. 2 2
      CryptoLib/src/Asn1/ClpDerIA5String.pas
  12. 11 7
      CryptoLib/src/Asn1/ClpDerObjectIdentifier.pas
  13. 2 2
      CryptoLib/src/Asn1/ClpDerStringBase.pas
  14. 2 2
      CryptoLib/src/Asn1/ClpDerVisibleString.pas
  15. 76 2
      CryptoLib/src/Asn1/Nist/ClpNistObjectIdentifiers.pas
  16. 9 9
      CryptoLib/src/Crypto/Engines/ClpIESEngine.pas
  17. 1 1
      CryptoLib/src/Crypto/Engines/ClpPascalCoinIESEngine.pas
  18. 7 8
      CryptoLib/src/Crypto/Generators/ClpBaseKdfBytesGenerator.pas
  19. 152 0
      CryptoLib/src/Crypto/Generators/ClpCipherKeyGenerator.pas
  20. 3 3
      CryptoLib/src/Crypto/Generators/ClpKdf2BytesGenerator.pas
  21. 6 8
      CryptoLib/src/Crypto/Generators/ClpPascalCoinECIESKdfBytesGenerator.pas
  22. 367 0
      CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas
  23. 282 0
      CryptoLib/src/Crypto/Modes/ClpOfbBlockCipher.pas
  24. 290 0
      CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas
  25. 151 0
      CryptoLib/src/Crypto/Paddings/ClpISO10126d2Padding.pas
  26. 150 0
      CryptoLib/src/Crypto/Paddings/ClpISO7816d4Padding.pas
  27. 1 1
      CryptoLib/src/Crypto/Paddings/ClpPkcs7Padding.pas
  28. 163 0
      CryptoLib/src/Crypto/Paddings/ClpTTBCPadding.pas
  29. 150 0
      CryptoLib/src/Crypto/Paddings/ClpX923Padding.pas
  30. 4 0
      CryptoLib/src/Crypto/Paddings/ClpZeroBytePadding.pas
  31. 5 5
      CryptoLib/src/Crypto/Prng/ClpDigestRandomGenerator.pas
  32. 4 4
      CryptoLib/src/Crypto/Signers/ClpDsaDigestSigner.pas
  33. 5 5
      CryptoLib/src/Crypto/Signers/ClpECSchnorrSigner.pas
  34. 44 0
      CryptoLib/src/Interfaces/ClpICfbBlockCipher.pas
  35. 57 0
      CryptoLib/src/Interfaces/ClpICipherKeyGenerator.pas
  36. 3 3
      CryptoLib/src/Interfaces/ClpIDerivationFunction.pas
  37. 36 0
      CryptoLib/src/Interfaces/ClpIDigest.pas
  38. 36 0
      CryptoLib/src/Interfaces/ClpIDigestMAC.pas
  39. 3 3
      CryptoLib/src/Interfaces/ClpIIESEngine.pas
  40. 36 0
      CryptoLib/src/Interfaces/ClpIISO10126d2Padding.pas
  41. 36 0
      CryptoLib/src/Interfaces/ClpIISO7816d4Padding.pas
  42. 44 0
      CryptoLib/src/Interfaces/ClpIOfbBlockCipher.pas
  43. 36 0
      CryptoLib/src/Interfaces/ClpIPBKDF2_DigestMAC.pas
  44. 3 3
      CryptoLib/src/Interfaces/ClpIPascalCoinECIESKdfBytesGenerator.pas
  45. 44 0
      CryptoLib/src/Interfaces/ClpISicBlockCipher.pas
  46. 65 0
      CryptoLib/src/Interfaces/ClpIStreamCipher.pas
  47. 36 0
      CryptoLib/src/Interfaces/ClpITBCPadding.pas
  48. 36 0
      CryptoLib/src/Interfaces/ClpIX923Padding.pas
  49. 230 145
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
  50. 19 14
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
  51. 124 7
      CryptoLib/src/Security/ClpCipherUtilities.pas
  52. 81 46
      CryptoLib/src/Security/ClpDigestUtilities.pas
  53. 44 5
      CryptoLib/src/Security/ClpGeneratorUtilities.pas
  54. 33 8
      CryptoLib/src/Security/ClpParameterUtilities.pas
  55. 3 3
      CryptoLib/src/Security/ClpSecureRandom.pas
  56. 96 96
      CryptoLib/src/Security/ClpSignerUtilities.pas
  57. 45 36
      CryptoLib/src/Utils/ClpStringUtils.pas
  58. 3 3
      README.md

+ 22 - 2
CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr

@@ -220,7 +220,6 @@ uses
   ClpBase64 in '..\..\CryptoLib\src\Utils\Encoders\ClpBase64.pas',
   ClpBase64 in '..\..\CryptoLib\src\Utils\Encoders\ClpBase64.pas',
   ClpHex in '..\..\CryptoLib\src\Utils\Encoders\ClpHex.pas',
   ClpHex in '..\..\CryptoLib\src\Utils\Encoders\ClpHex.pas',
   ClpStreamHelper in '..\..\CryptoLib\src\Utils\Helpers\ClpStreamHelper.pas',
   ClpStreamHelper in '..\..\CryptoLib\src\Utils\Helpers\ClpStreamHelper.pas',
-  ClpStringHelper in '..\..\CryptoLib\src\Utils\Helpers\ClpStringHelper.pas',
   ClpBaseInputStream in '..\..\CryptoLib\src\Utils\IO\ClpBaseInputStream.pas',
   ClpBaseInputStream in '..\..\CryptoLib\src\Utils\IO\ClpBaseInputStream.pas',
   ClpFilterStream in '..\..\CryptoLib\src\Utils\IO\ClpFilterStream.pas',
   ClpFilterStream in '..\..\CryptoLib\src\Utils\IO\ClpFilterStream.pas',
   ClpStreams in '..\..\CryptoLib\src\Utils\IO\ClpStreams.pas',
   ClpStreams in '..\..\CryptoLib\src\Utils\IO\ClpStreams.pas',
@@ -344,7 +343,27 @@ uses
   ClpPascalCoinIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpPascalCoinIESEngine.pas',
   ClpPascalCoinIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpPascalCoinIESEngine.pas',
   ClpIPascalCoinIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinIESEngine.pas',
   ClpIPascalCoinIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinIESEngine.pas',
   ClpPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
   ClpPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
-  ClpIPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas';
+  ClpIPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas',
+  ClpISO10126d2Padding in '..\..\CryptoLib\src\Crypto\Paddings\ClpISO10126d2Padding.pas',
+  ClpIISO10126d2Padding in '..\..\CryptoLib\src\Interfaces\ClpIISO10126d2Padding.pas',
+  ClpISO7816d4Padding in '..\..\CryptoLib\src\Crypto\Paddings\ClpISO7816d4Padding.pas',
+  ClpIISO7816d4Padding in '..\..\CryptoLib\src\Interfaces\ClpIISO7816d4Padding.pas',
+  ClpTTBCPadding in '..\..\CryptoLib\src\Crypto\Paddings\ClpTTBCPadding.pas',
+  ClpITBCPadding in '..\..\CryptoLib\src\Interfaces\ClpITBCPadding.pas',
+  ClpX923Padding in '..\..\CryptoLib\src\Crypto\Paddings\ClpX923Padding.pas',
+  ClpIX923Padding in '..\..\CryptoLib\src\Interfaces\ClpIX923Padding.pas',
+  ClpCfbBlockCipher in '..\..\CryptoLib\src\Crypto\Modes\ClpCfbBlockCipher.pas',
+  ClpICfbBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpICfbBlockCipher.pas',
+  ClpOfbBlockCipher in '..\..\CryptoLib\src\Crypto\Modes\ClpOfbBlockCipher.pas',
+  ClpIOfbBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpIOfbBlockCipher.pas',
+  ClpSicBlockCipher in '..\..\CryptoLib\src\Crypto\Modes\ClpSicBlockCipher.pas',
+  ClpISicBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpISicBlockCipher.pas',
+  ClpIDigest in '..\..\CryptoLib\src\Interfaces\ClpIDigest.pas',
+  ClpIDigestMAC in '..\..\CryptoLib\src\Interfaces\ClpIDigestMAC.pas',
+  ClpIPBKDF2_DigestMAC in '..\..\CryptoLib\src\Interfaces\ClpIPBKDF2_DigestMAC.pas',
+  ClpStringUtils in '..\..\CryptoLib\src\Utils\ClpStringUtils.pas',
+  ClpCipherKeyGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpCipherKeyGenerator.pas',
+  ClpICipherKeyGenerator in '..\..\CryptoLib\src\Interfaces\ClpICipherKeyGenerator.pas';
 
 
 begin
 begin
   try
   try
@@ -356,6 +375,7 @@ begin
     TUsageExamples.RecreatePublicKeyFromXAndYCoordByteArray;
     TUsageExamples.RecreatePublicKeyFromXAndYCoordByteArray;
     TUsageExamples.BinaryCompatiblePascalCoinAES256EncryptDecryptDemo('Pascal Rules', 'Pascal');
     TUsageExamples.BinaryCompatiblePascalCoinAES256EncryptDecryptDemo('Pascal Rules', 'Pascal');
     TUsageExamples.BinaryCompatiblePascalCoinECIESEncryptDecryptDemo('Kowalski');
     TUsageExamples.BinaryCompatiblePascalCoinECIESEncryptDecryptDemo('Kowalski');
+   // TUsageExamples.BinaryCompatiblePascalCoinECIESDecryptExistingPayloadDemo('', '', '');
     Readln;
     Readln;
   except
   except
     on E: Exception do
     on E: Exception do

+ 96 - 57
CryptoLib.Samples/src/UsageExamples.pas

@@ -27,9 +27,9 @@ interface
 
 
 uses
 uses
   SysUtils,
   SysUtils,
-  HlpIHash,
-  HlpIHashInfo,
-  HlpHashFactory,
+  ClpIDigest,
+  ClpIDigestMAC,
+  ClpDigestUtilities,
   ClpBigInteger,
   ClpBigInteger,
   ClpSecureRandom,
   ClpSecureRandom,
   ClpISecureRandom,
   ClpISecureRandom,
@@ -80,6 +80,7 @@ uses
   ClpGeneratorUtilities,
   ClpGeneratorUtilities,
   ClpIAsymmetricCipherKeyPairGenerator,
   ClpIAsymmetricCipherKeyPairGenerator,
   ClpArrayUtils,
   ClpArrayUtils,
+  ClpHex,
   ClpSecNamedCurves;
   ClpSecNamedCurves;
 
 
 type
 type
@@ -148,6 +149,10 @@ type
       (const inputmessage, password: string); static;
       (const inputmessage, password: string); static;
     class procedure BinaryCompatiblePascalCoinECIESEncryptDecryptDemo
     class procedure BinaryCompatiblePascalCoinECIESEncryptDecryptDemo
       (const input: string); static;
       (const input: string); static;
+
+    class procedure BinaryCompatiblePascalCoinECIESDecryptExistingPayloadDemo
+      (const PrivateKeyInHex, EncryptedMessageInHex,
+      ACurveName: string); static;
   end;
   end;
 
 
 implementation
 implementation
@@ -182,33 +187,32 @@ class function TUsageExamples.EVP_GetKeyIV(PasswordBytes, SaltBytes: TBytes;
   out KeyBytes, IVBytes: TBytes): Boolean;
   out KeyBytes, IVBytes: TBytes): Boolean;
 var
 var
   LKey, LIV: integer;
   LKey, LIV: integer;
-  LHash: IHash;
+  LDigest: IDigest;
 begin
 begin
   LKey := 32; // AES256 CBC Key Length
   LKey := 32; // AES256 CBC Key Length
   LIV := 16; // AES256 CBC IV Length
   LIV := 16; // AES256 CBC IV Length
   System.SetLength(KeyBytes, LKey);
   System.SetLength(KeyBytes, LKey);
   System.SetLength(IVBytes, LKey);
   System.SetLength(IVBytes, LKey);
   // Max size to start then reduce it at the end
   // Max size to start then reduce it at the end
-  LHash := THashFactory.TCrypto.CreateSHA2_256; // SHA2_256
-  LHash.Initialize();
-  System.Assert(LHash.HashSize >= LKey);
-  System.Assert(LHash.HashSize >= LIV);
+  LDigest := TDigestUtilities.GetDigest('SHA-256'); // SHA2_256
+  System.Assert(LDigest.HashSize >= LKey);
+  System.Assert(LDigest.HashSize >= LIV);
   // Derive Key First
   // Derive Key First
-  LHash.TransformBytes(PasswordBytes);
+  LDigest.TransformBytes(PasswordBytes);
   if SaltBytes <> Nil then
   if SaltBytes <> Nil then
   begin
   begin
-    LHash.TransformBytes(SaltBytes);
+    LDigest.TransformBytes(SaltBytes);
   end;
   end;
-  KeyBytes := System.Copy(LHash.TransformFinal.GetBytes);
+  KeyBytes := System.Copy(LDigest.TransformFinal.GetBytes);
   // Derive IV Next
   // Derive IV Next
-  LHash.Initialize();
-  LHash.TransformBytes(KeyBytes);
-  LHash.TransformBytes(PasswordBytes);
+  LDigest.Initialize();
+  LDigest.TransformBytes(KeyBytes);
+  LDigest.TransformBytes(PasswordBytes);
   if SaltBytes <> Nil then
   if SaltBytes <> Nil then
   begin
   begin
-    LHash.TransformBytes(SaltBytes);
+    LDigest.TransformBytes(SaltBytes);
   end;
   end;
-  IVBytes := System.Copy(LHash.TransformFinal.GetBytes);
+  IVBytes := System.Copy(LDigest.TransformFinal.GetBytes);
 
 
   System.SetLength(IVBytes, LIV);
   System.SetLength(IVBytes, LIV);
   Result := True;
   Result := True;
@@ -343,6 +347,77 @@ begin
 
 
 end;
 end;
 
 
+class procedure TUsageExamples.
+  BinaryCompatiblePascalCoinECIESDecryptExistingPayloadDemo
+  (const PrivateKeyInHex, EncryptedMessageInHex, ACurveName: string);
+
+const
+  MethodName = 'BinaryCompatiblePascalCoinECIESDecryptExistingPayloadDemo';
+var
+  PrivateKeyBytes, PayloadToDecodeBytes, DecryptedCipherText: TBytes;
+  Lcurve: IX9ECParameters;
+  domain: IECDomainParameters;
+  RegeneratedPublicKey: IECPublicKeyParameters;
+  RegeneratedPrivateKey: IECPrivateKeyParameters;
+  KeyPair: IAsymmetricCipherKeyPair;
+  PrivD: TBigInteger;
+begin
+
+  // Create From Existing Parameter Method
+  System.Assert(PrivateKeyInHex <> '', 'PrivateKeyInHex Cannot be Empty');
+  System.Assert(EncryptedMessageInHex <> '',
+    'EncryptedMessageInHex Cannot be Empty');
+  System.Assert(ACurveName <> '', 'ACurveName Cannot be Empty');
+
+  PrivateKeyBytes := THex.Decode(PrivateKeyInHex);
+  System.Assert(PrivateKeyBytes <> Nil, 'PrivateKeyBytes Cannot be Nil');
+
+  PayloadToDecodeBytes := THex.Decode(EncryptedMessageInHex);
+  System.Assert(PayloadToDecodeBytes <> Nil,
+    'PayloadToDecodeBytes Cannot be Nil');
+
+  Lcurve := TSecNamedCurves.GetByName(ACurveName);
+  System.Assert(Lcurve <> Nil, 'Lcurve Cannot be Nil');
+
+  // Set Up Asymmetric Key Pair from known private key ByteArray
+
+  domain := TECDomainParameters.Create(Lcurve.Curve, Lcurve.G, Lcurve.N,
+    Lcurve.H, Lcurve.GetSeed);
+
+  PrivD := TBigInteger.Create(1, PrivateKeyBytes);
+  RegeneratedPrivateKey := TECPrivateKeyParameters.Create('ECDSA',
+    PrivD, domain);
+
+  RegeneratedPublicKey := TECKeyPairGenerator.GetCorrespondingPublicKey
+    (RegeneratedPrivateKey);
+
+  KeyPair := TAsymmetricCipherKeyPair.Create(RegeneratedPublicKey,
+    RegeneratedPrivateKey);
+
+  // Do Signing and Verifying to Assert Proper Recreation Of Public and Private Key
+  DoSigningAndVerifying(KeyPair.Public as IECPublicKeyParameters,
+    KeyPair.Private as IECPrivateKeyParameters, MethodName, 'PascalECDSA');
+
+  // Do Decryption Of Payload
+
+  if TUsageExamples.ECIESPascalCoinDecrypt(RegeneratedPrivateKey,
+    PayloadToDecodeBytes, DecryptedCipherText) then
+  begin
+
+    Writeln('ECIES PascalCoin Existing Payload Compatability Decrypt Was Successful '
+      + sLineBreak);
+
+    Writeln('Payload Message Is "' + TEncoding.UTF8.GetString
+      (DecryptedCipherText) + '"');
+    Exit;
+
+  end;
+
+  Writeln('ECIES PascalCoin Existing Payload Compatability Decrypt Failed ' +
+    sLineBreak);
+
+end;
+
 class procedure TUsageExamples.BinaryCompatiblePascalCoinECIESEncryptDecryptDemo
 class procedure TUsageExamples.BinaryCompatiblePascalCoinECIESEncryptDecryptDemo
   (const input: string);
   (const input: string);
 var
 var
@@ -516,7 +591,7 @@ var
   blockCipher: ICbcBlockCipher;
   blockCipher: ICbcBlockCipher;
   ECDHBasicAgreementInstance: IECDHBasicAgreement;
   ECDHBasicAgreementInstance: IECDHBasicAgreement;
   KDFInstance: IPascalCoinECIESKdfBytesGenerator;
   KDFInstance: IPascalCoinECIESKdfBytesGenerator;
-  HMACInstance: IHMAC;
+  DigestMACInstance: IDigestMAC;
 
 
 begin
 begin
   // Set up IES Cipher Engine For Compatibility With PascalCoin
   // Set up IES Cipher Engine For Compatibility With PascalCoin
@@ -524,10 +599,10 @@ begin
   ECDHBasicAgreementInstance := TECDHBasicAgreement.Create();
   ECDHBasicAgreementInstance := TECDHBasicAgreement.Create();
 
 
   KDFInstance := TPascalCoinECIESKdfBytesGenerator.Create
   KDFInstance := TPascalCoinECIESKdfBytesGenerator.Create
-    (THashFactory.TCrypto.CreateSHA2_512 as IHash);
+    (TDigestUtilities.GetDigest('SHA-512'));
 
 
-  HMACInstance := THashFactory.THMAC.CreateHMAC
-    (THashFactory.TCrypto.CreateMD5 as IHash);
+  DigestMACInstance := TDigestUtilities.GetDigestMAC
+    (TDigestUtilities.GetDigest('MD5'));
 
 
   // Set Up Block Cipher
   // Set Up Block Cipher
   AesEngine := TAesEngine.Create(); // AES Engine
   AesEngine := TAesEngine.Create(); // AES Engine
@@ -538,53 +613,17 @@ begin
     TZeroBytePadding.Create() as IZeroBytePadding); // ZeroBytePadding
     TZeroBytePadding.Create() as IZeroBytePadding); // ZeroBytePadding
 
 
   Result := TPascalCoinIESEngine.Create(ECDHBasicAgreementInstance, KDFInstance,
   Result := TPascalCoinIESEngine.Create(ECDHBasicAgreementInstance, KDFInstance,
-    HMACInstance, cipher);
+    DigestMACInstance, cipher);
 end;
 end;
 
 
 class function TUsageExamples.GetECKeyPair: IAsymmetricCipherKeyPair;
 class function TUsageExamples.GetECKeyPair: IAsymmetricCipherKeyPair;
-const
-  AccountPrivateKeyHex =
-    'Enter Your Decrypted Private Key Here in Hexadecimal!!!';
-  CurveName = 'secp256k1';
 var
 var
   Lcurve: IX9ECParameters;
   Lcurve: IX9ECParameters;
   domain: IECDomainParameters;
   domain: IECDomainParameters;
-  // PrivateKeyBytes: TBytes;
-  // RegeneratedPublicKey: IECPublicKeyParameters;
-  // RegeneratedPrivateKey: IECPrivateKeyParameters;
-  // PrivD: TBigInteger;
   KeyPairGeneratorInstance: IAsymmetricCipherKeyPairGenerator;
   KeyPairGeneratorInstance: IAsymmetricCipherKeyPairGenerator;
 const
 const
   MethodName = 'GetECKeyPair';
   MethodName = 'GetECKeyPair';
 begin
 begin
-  // Create From Existing Parameter Method
-  // System.Assert(AccountPrivateKeyHex <> '', 'Private Key Cannot be Empty');
-  // System.Assert(CurveName <> '', 'CurveName Cannot be Empty');
-  //
-  // PrivateKeyBytes := THex.Decode(AccountPrivateKeyHex);
-  // Lcurve := TSecNamedCurves.GetByName(CurveName);
-  // System.Assert(Lcurve <> Nil, 'Curve Cannot be Nil');
-  //
-  // // Set Up Asymmetric Key Pair from known private key ByteArray
-  //
-  // domain := TECDomainParameters.Create(Lcurve.Curve, Lcurve.G, Lcurve.N,
-  // Lcurve.H, Lcurve.GetSeed);
-  //
-  // PrivD := TBigInteger.Create(1, PrivateKeyBytes);
-  // RegeneratedPrivateKey := TECPrivateKeyParameters.Create('ECDSA',
-  // PrivD, domain);
-  //
-  // RegeneratedPublicKey := TECKeyPairGenerator.GetCorrespondingPublicKey
-  // (RegeneratedPrivateKey);
-  //
-  // Result := TAsymmetricCipherKeyPair.Create
-  // (RegeneratedPublicKey as IAsymmetricKeyParameter,
-  // RegeneratedPrivateKey as IAsymmetricKeyParameter);
-  //
-  // // Do Signing and Verifying to Assert Proper Recreation Of Public and Private Key
-  // DoSigningAndVerifying(RegeneratedPublicKey, RegeneratedPrivateKey, MethodName,
-  // 'PascalECDSA');
-
   // Full Generation Method
   // Full Generation Method
 
 
   Lcurve := TSecNamedCurves.GetByName(CurveName);
   Lcurve := TSecNamedCurves.GetByName(CurveName);

+ 22 - 2
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -233,7 +233,6 @@ uses
   ClpBase64 in '..\..\CryptoLib\src\Utils\Encoders\ClpBase64.pas',
   ClpBase64 in '..\..\CryptoLib\src\Utils\Encoders\ClpBase64.pas',
   ClpHex in '..\..\CryptoLib\src\Utils\Encoders\ClpHex.pas',
   ClpHex in '..\..\CryptoLib\src\Utils\Encoders\ClpHex.pas',
   ClpStreamHelper in '..\..\CryptoLib\src\Utils\Helpers\ClpStreamHelper.pas',
   ClpStreamHelper in '..\..\CryptoLib\src\Utils\Helpers\ClpStreamHelper.pas',
-  ClpStringHelper in '..\..\CryptoLib\src\Utils\Helpers\ClpStringHelper.pas',
   ClpBaseInputStream in '..\..\CryptoLib\src\Utils\IO\ClpBaseInputStream.pas',
   ClpBaseInputStream in '..\..\CryptoLib\src\Utils\IO\ClpBaseInputStream.pas',
   ClpFilterStream in '..\..\CryptoLib\src\Utils\IO\ClpFilterStream.pas',
   ClpFilterStream in '..\..\CryptoLib\src\Utils\IO\ClpFilterStream.pas',
   ClpStreams in '..\..\CryptoLib\src\Utils\IO\ClpStreams.pas',
   ClpStreams in '..\..\CryptoLib\src\Utils\IO\ClpStreams.pas',
@@ -378,7 +377,28 @@ uses
   ClpIPascalCoinIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinIESEngine.pas',
   ClpIPascalCoinIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinIESEngine.pas',
   IESCipherTests in '..\src\Crypto\IESCipherTests.pas',
   IESCipherTests in '..\src\Crypto\IESCipherTests.pas',
   ClpPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
   ClpPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
-  ClpIPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas';
+  ClpIPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas',
+  ClpISO10126d2Padding in '..\..\CryptoLib\src\Crypto\Paddings\ClpISO10126d2Padding.pas',
+  ClpIISO10126d2Padding in '..\..\CryptoLib\src\Interfaces\ClpIISO10126d2Padding.pas',
+  ClpISO7816d4Padding in '..\..\CryptoLib\src\Crypto\Paddings\ClpISO7816d4Padding.pas',
+  ClpIISO7816d4Padding in '..\..\CryptoLib\src\Interfaces\ClpIISO7816d4Padding.pas',
+  ClpTTBCPadding in '..\..\CryptoLib\src\Crypto\Paddings\ClpTTBCPadding.pas',
+  ClpITBCPadding in '..\..\CryptoLib\src\Interfaces\ClpITBCPadding.pas',
+  ClpX923Padding in '..\..\CryptoLib\src\Crypto\Paddings\ClpX923Padding.pas',
+  ClpIX923Padding in '..\..\CryptoLib\src\Interfaces\ClpIX923Padding.pas',
+  ClpCfbBlockCipher in '..\..\CryptoLib\src\Crypto\Modes\ClpCfbBlockCipher.pas',
+  ClpICfbBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpICfbBlockCipher.pas',
+  ClpOfbBlockCipher in '..\..\CryptoLib\src\Crypto\Modes\ClpOfbBlockCipher.pas',
+  ClpIOfbBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpIOfbBlockCipher.pas',
+  ClpSicBlockCipher in '..\..\CryptoLib\src\Crypto\Modes\ClpSicBlockCipher.pas',
+  ClpISicBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpISicBlockCipher.pas',
+  ClpIDigest in '..\..\CryptoLib\src\Interfaces\ClpIDigest.pas',
+  ClpIDigestMAC in '..\..\CryptoLib\src\Interfaces\ClpIDigestMAC.pas',
+  ClpIPBKDF2_DigestMAC in '..\..\CryptoLib\src\Interfaces\ClpIPBKDF2_DigestMAC.pas',
+  ClpStringUtils in '..\..\CryptoLib\src\Utils\ClpStringUtils.pas',
+  ClpCipherKeyGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpCipherKeyGenerator.pas',
+  ClpICipherKeyGenerator in '..\..\CryptoLib\src\Interfaces\ClpICipherKeyGenerator.pas',
+  AESSICTests in '..\src\Crypto\AESSICTests.pas';
 
 
 begin
 begin
 
 

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

@@ -35,7 +35,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item4>
       </Item4>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="23">
+    <Units Count="24">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -129,6 +129,10 @@
         <Filename Value="..\src\Crypto\IESCipherTests.pas"/>
         <Filename Value="..\src\Crypto\IESCipherTests.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit22>
       </Unit22>
+      <Unit23>
+        <Filename Value="..\src\Crypto\AESSICTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit23>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

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

@@ -26,6 +26,7 @@ uses
   BlockCipherVectorTests,
   BlockCipherVectorTests,
   AESTestVectors,
   AESTestVectors,
   IESCipherTests,
   IESCipherTests,
+  AESSICTests,
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom;
   ClpIFixedSecureRandom;
 
 

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

@@ -24,6 +24,7 @@ uses
   BlockCipherVectorTests,
   BlockCipherVectorTests,
   AESTestVectors,
   AESTestVectors,
   IESCipherTests,
   IESCipherTests,
+  AESSICTests,
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom;
   ClpIFixedSecureRandom;
 
 

+ 223 - 0
CryptoLib.Tests/src/Crypto/AESSICTests.pas

@@ -0,0 +1,223 @@
+{ *********************************************************************************** }
+{ *                              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 AESSICTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+{$HINTS OFF}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpKeyParameter,
+  ClpIKeyParameter,
+  ClpParametersWithIV,
+  ClpIParametersWithIV,
+  ClpIBufferedCipher,
+  ClpICipherKeyGenerator,
+  ClpICipherParameters,
+  ClpGeneratorUtilities,
+  ClpParameterUtilities,
+  ClpCipherUtilities,
+  ClpHex,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  /// <summary>
+  /// Test vectors based on NIST Special Publication 800-38A, <br />
+  /// "Recommendation for Block Cipher Modes of Operation"
+  /// </summary>
+  TTestAESSIC = class(TCryptoLibTestCase)
+  private
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+
+    procedure TestAESSIC;
+
+  end;
+
+implementation
+
+{ TTestAESSIC }
+
+procedure TTestAESSIC.SetUp;
+begin
+  inherited;
+end;
+
+procedure TTestAESSIC.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestAESSIC.TestAESSIC;
+var
+  keys, plain: TCryptoLibMatrixByteArray;
+  cipher: TCryptoLibGenericArray<TCryptoLibMatrixByteArray>;
+  c: IBufferedCipher;
+  i, j: Int32;
+  skey, sk: IKeyParameter;
+  enc, crypt: TBytes;
+begin
+  keys := TCryptoLibMatrixByteArray.Create
+    (THex.Decode('2b7e151628aed2a6abf7158809cf4f3c'),
+    THex.Decode('8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'),
+    THex.Decode
+    ('603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4'));
+
+  plain := TCryptoLibMatrixByteArray.Create
+    (THex.Decode('6bc1bee22e409f96e93d7e117393172a'),
+    THex.Decode('ae2d8a571e03ac9c9eb76fac45af8e51'),
+    THex.Decode('30c81c46a35ce411e5fbc1191a0a52ef'),
+    THex.Decode('f69f2445df4f9b17ad2b417be66c3710'));
+
+  cipher := TCryptoLibGenericArray<TCryptoLibMatrixByteArray>.Create
+    (TCryptoLibMatrixByteArray.Create
+    (THex.Decode('874d6191b620e3261bef6864990db6ce'),
+    THex.Decode('9806f66b7970fdff8617187bb9fffdff'),
+    THex.Decode('5ae4df3edbd5d35e5b4f09020db03eab'),
+    THex.Decode('1e031dda2fbe03d1792170a0f3009cee')),
+    TCryptoLibMatrixByteArray.Create
+    (THex.Decode('1abc932417521ca24f2b0459fe7e6e0b'),
+    THex.Decode('090339ec0aa6faefd5ccc2c6f4ce8e94'),
+    THex.Decode('1e36b26bd1ebc670d1bd1d665620abf7'),
+    THex.Decode('4f78a7f6d29809585a97daec58c6b050')),
+    TCryptoLibMatrixByteArray.Create
+    (THex.Decode('601ec313775789a5b7a7f504bbf3d228'),
+    THex.Decode('f443e3ca4d62b59aca84e990cacaf5c5'),
+    THex.Decode('2b0930daa23de94ce87017ba2d84988d'),
+    THex.Decode('dfc9c58db67aada613c2dd08457941a6')));
+
+  c := TCipherUtilities.GetCipher('AES/SIC/NoPadding');
+
+  //
+  // NIST vectors
+  //
+
+  i := 0;
+  while i <> System.Length(keys) do
+  begin
+    skey := TParameterUtilities.CreateKeyParameter('AES', keys[i]);
+    c.Init(true, TParametersWithIV.Create(skey,
+      THex.Decode('F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF')) as IParametersWithIV);
+
+    j := 0;
+    while j <> System.Length(plain) do
+    begin
+      enc := c.ProcessBytes(plain[j]);
+      if (not TArrayUtils.AreEqual(enc, cipher[i, j])) then
+      begin
+        Fail('AESSIC encrypt failed: key ' + IntToStr(i) + ' block ' +
+          IntToStr(j));
+      end;
+      System.Inc(j);
+    end;
+
+    c.Init(false, TParametersWithIV.Create(skey,
+      THex.Decode('F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF')) as IParametersWithIV);
+
+    j := 0;
+    while j <> System.Length(plain) do
+    begin
+      enc := c.ProcessBytes(cipher[i, j]);
+      if (not TArrayUtils.AreEqual(enc, plain[j])) then
+      begin
+        Fail('AESSIC decrypt failed: key ' + IntToStr(i) + ' block ' +
+          IntToStr(j));
+      end;
+      System.Inc(j);
+    end;
+    System.Inc(i);
+  end;
+
+  //
+  // check CTR also recognised.
+  //
+
+  c := TCipherUtilities.GetCipher('AES/CTR/NoPadding');
+
+  sk := TParameterUtilities.CreateKeyParameter('AES',
+    THex.Decode('2B7E151628AED2A6ABF7158809CF4F3C'));
+
+  c.Init(true, TParametersWithIV.Create(sk,
+    THex.Decode('F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001')) as IParametersWithIV);
+
+  crypt := c.DoFinal(THex.Decode('00000000000000000000000000000000'));
+
+  if (not TArrayUtils.AreEqual(crypt,
+    THex.Decode('D23513162B02D0F72A43A2FE4A5F97AB'))) then
+  begin
+    Fail('AESSIC failed test 2');
+  end;
+
+  //
+  // check partial block processing
+  //
+  c := TCipherUtilities.GetCipher('AES/CTR/NoPadding');
+
+  sk := TParameterUtilities.CreateKeyParameter('AES',
+    THex.Decode('2B7E151628AED2A6ABF7158809CF4F3C'));
+
+  c.Init(true, TParametersWithIV.Create(sk,
+    THex.Decode('F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001')) as IParametersWithIV);
+
+  crypt := c.DoFinal(THex.Decode('12345678'));
+
+  c.Init(false, TParametersWithIV.Create(sk,
+    THex.Decode('F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001')) as IParametersWithIV);
+
+  crypt := c.DoFinal(crypt);
+
+  if (not TArrayUtils.AreEqual(crypt, THex.Decode('12345678'))) then
+  begin
+    Fail('AESSIC failed partial test');
+  end;
+
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestAESSIC);
+{$ELSE}
+  RegisterTest(TTestAESSIC.Suite);
+{$ENDIF FPC}
+
+end.

+ 88 - 7
CryptoLib.Tests/src/Crypto/AESTests.pas

@@ -40,8 +40,12 @@ uses
   ClpParametersWithIV,
   ClpParametersWithIV,
   ClpIParametersWithIV,
   ClpIParametersWithIV,
   ClpIBufferedCipher,
   ClpIBufferedCipher,
+  ClpICipherKeyGenerator,
+  ClpICipherParameters,
+  ClpGeneratorUtilities,
   ClpParameterUtilities,
   ClpParameterUtilities,
   ClpCipherUtilities,
   ClpCipherUtilities,
+  ClpNistObjectIdentifiers,
   // ClpCbcBlockCipher,
   // ClpCbcBlockCipher,
   // ClpICbcBlockCipher,
   // ClpICbcBlockCipher,
   // ClpPaddedBufferedBlockCipher,
   // ClpPaddedBufferedBlockCipher,
@@ -49,7 +53,8 @@ uses
   // ClpZeroBytePadding,
   // ClpZeroBytePadding,
   // ClpIZeroBytePadding,
   // ClpIZeroBytePadding,
   ClpHex,
   ClpHex,
-  ClpArrayUtils;
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
 
 
 type
 type
 
 
@@ -62,6 +67,8 @@ type
   TTestAES = class(TCryptoLibTestCase)
   TTestAES = class(TCryptoLibTestCase)
   private
   private
 
 
+    procedure dooidTest(oids, names: TCryptoLibStringArray; groupSize: Int32);
+
     procedure doAESTestWithIV(const cipher: IBufferedCipher;
     procedure doAESTestWithIV(const cipher: IBufferedCipher;
       const param: IParametersWithIV; const input, output: String);
       const param: IParametersWithIV; const input, output: String);
 
 
@@ -70,6 +77,7 @@ type
     procedure TearDown; override;
     procedure TearDown; override;
   published
   published
 
 
+    procedure TestOids;
     procedure TestAES256_CBC_PKCS7PADDING;
     procedure TestAES256_CBC_PKCS7PADDING;
 
 
   end;
   end;
@@ -131,6 +139,53 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TTestAES.dooidTest(oids, names: TCryptoLibStringArray;
+  groupSize: Int32);
+var
+  data, result, IV: TBytes;
+  i: Int32;
+  c1, c2: IBufferedCipher;
+  kg: ICipherKeyGenerator;
+  k: IKeyParameter;
+  cp: ICipherParameters;
+begin
+  data := TBytes.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+  i := 0;
+  while i <> System.Length(oids) do
+  begin
+    c1 := TCipherUtilities.GetCipher(oids[i]);
+    c2 := TCipherUtilities.GetCipher(names[i]);
+    kg := TGeneratorUtilities.GetKeyGenerator(oids[i]);
+
+    k := TParameterUtilities.CreateKeyParameter(oids[i], kg.GenerateKey());
+
+    cp := k;
+
+    if System.Pos('/ECB/', names[i]) = 0 then
+    begin
+      System.SetLength(IV, 16);
+      cp := TParametersWithIV.Create(cp, IV);
+    end;
+
+    c1.Init(True, cp);
+    c2.Init(false, cp);
+
+    result := c2.DoFinal(c1.DoFinal(data));
+
+    if (not TArrayUtils.AreEqual(data, result)) then
+    begin
+      Fail('failed OID test');
+    end;
+
+    if (System.Length(k.GetKey()) <> (16 + ((i div groupSize) * 8))) then
+    begin
+      Fail('failed key length test');
+    end;
+    System.Inc(i);
+  end;
+
+end;
+
 procedure TTestAES.SetUp;
 procedure TTestAES.SetUp;
 begin
 begin
   inherited;
   inherited;
@@ -149,7 +204,7 @@ var
   keyBytes, IVBytes: TBytes;
   keyBytes, IVBytes: TBytes;
   cipher: IBufferedCipher;
   cipher: IBufferedCipher;
   input, output: string;
   input, output: string;
-  I: Int32;
+  i: Int32;
   // engine: IAesEngine;
   // engine: IAesEngine;
   // blockCipher: ICbcBlockCipher;
   // blockCipher: ICbcBlockCipher;
 begin
 begin
@@ -162,13 +217,13 @@ begin
   // // Default scheme is PKCS5/PKCS7
   // // Default scheme is PKCS5/PKCS7
   cipher := TCipherUtilities.GetCipher('AES/CBC/PKCS7PADDING');
   cipher := TCipherUtilities.GetCipher('AES/CBC/PKCS7PADDING');
 
 
-  for I := System.Low(TAESTestVectors.FOfficialVectorKeys__AES256_CBC)
+  for i := System.Low(TAESTestVectors.FOfficialVectorKeys__AES256_CBC)
     to System.Low(TAESTestVectors.FOfficialVectorKeys__AES256_CBC) do
     to System.Low(TAESTestVectors.FOfficialVectorKeys__AES256_CBC) do
   begin
   begin
-    keyBytes := THex.Decode(TAESTestVectors.FOfficialVectorKeys__AES256_CBC[I]);
-    IVBytes := THex.Decode(TAESTestVectors.FOfficialVectorIVs_AES256_CBC[I]);
-    input := TAESTestVectors.FOfficialVectorInputs_AES256_CBC[I];
-    output := TAESTestVectors.FOfficialVectorOutputs_AES256_CBC[I];
+    keyBytes := THex.Decode(TAESTestVectors.FOfficialVectorKeys__AES256_CBC[i]);
+    IVBytes := THex.Decode(TAESTestVectors.FOfficialVectorIVs_AES256_CBC[i]);
+    input := TAESTestVectors.FOfficialVectorInputs_AES256_CBC[i];
+    output := TAESTestVectors.FOfficialVectorOutputs_AES256_CBC[i];
 
 
     KeyParametersWithIV := TParametersWithIV.Create
     KeyParametersWithIV := TParametersWithIV.Create
       (TParameterUtilities.CreateKeyParameter('AES', keyBytes), IVBytes);
       (TParameterUtilities.CreateKeyParameter('AES', keyBytes), IVBytes);
@@ -178,6 +233,32 @@ begin
 
 
 end;
 end;
 
 
+procedure TTestAES.TestOids;
+var
+  oids, names: TCryptoLibStringArray;
+begin
+  oids := TCryptoLibStringArray.Create(TNistObjectIdentifiers.IdAes128Ecb.Id,
+    TNistObjectIdentifiers.IdAes128Cbc.Id,
+    TNistObjectIdentifiers.IdAes128Ofb.Id,
+    TNistObjectIdentifiers.IdAes128Cfb.Id,
+    TNistObjectIdentifiers.IdAes192Ecb.Id,
+    TNistObjectIdentifiers.IdAes192Cbc.Id,
+    TNistObjectIdentifiers.IdAes192Ofb.Id,
+    TNistObjectIdentifiers.IdAes192Cfb.Id,
+    TNistObjectIdentifiers.IdAes256Ecb.Id,
+    TNistObjectIdentifiers.IdAes256Cbc.Id,
+    TNistObjectIdentifiers.IdAes256Ofb.Id,
+    TNistObjectIdentifiers.IdAes256Cfb.Id);
+
+  names := TCryptoLibStringArray.Create('AES/ECB/PKCS7Padding',
+    'AES/CBC/PKCS7Padding', 'AES/OFB/NoPadding', 'AES/CFB/NoPadding',
+    'AES/ECB/PKCS7Padding', 'AES/CBC/PKCS7Padding', 'AES/OFB/NoPadding',
+    'AES/CFB/NoPadding', 'AES/ECB/PKCS7Padding', 'AES/CBC/PKCS7Padding',
+    'AES/OFB/NoPadding', 'AES/CFB/NoPadding');
+
+  dooidTest(oids, names, 4);
+end;
+
 initialization
 initialization
 
 
 // Register any test cases with the test runner
 // Register any test cases with the test runner

+ 23 - 25
CryptoLib.Tests/src/Crypto/DigestRandomNumberTests.pas

@@ -33,12 +33,12 @@ uses
 {$ELSE}
 {$ELSE}
   TestFramework,
   TestFramework,
 {$ENDIF FPC}
 {$ENDIF FPC}
-  HlpIHash,
-  HlpHashFactory,
-  ClpHex,
-  ClpArrayUtils,
+  ClpIDigest,
   ClpDigestRandomGenerator,
   ClpDigestRandomGenerator,
   ClpIDigestRandomGenerator,
   ClpIDigestRandomGenerator,
+  ClpDigestUtilities,
+  ClpHex,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 type
 type
@@ -57,12 +57,12 @@ type
       FnoCycle0SHA256, Fexpected100SHA1, Fexpected100SHA256, FexpectedTestSHA1,
       FnoCycle0SHA256, Fexpected100SHA1, Fexpected100SHA256, FexpectedTestSHA1,
       FexpectedTestSHA256, Fsha1Xors, Fsha256Xors: TBytes;
       FexpectedTestSHA256, Fsha1Xors, Fsha256Xors: TBytes;
 
 
-    procedure doExpectedTest(digest: IHash; seed: Int32;
+    procedure doExpectedTest(digest: IDigest; seed: Int32;
       expected: TBytes); overload;
       expected: TBytes); overload;
-    procedure doExpectedTest(digest: IHash; seed, expected: TBytes); overload;
-    procedure doExpectedTest(digest: IHash; seed: Int32;
+    procedure doExpectedTest(digest: IDigest; seed, expected: TBytes); overload;
+    procedure doExpectedTest(digest: IDigest; seed: Int32;
       expected, noCycle: TBytes); overload;
       expected, noCycle: TBytes); overload;
-    procedure doCountTest(digest: IHash; seed, expectedXors: TBytes);
+    procedure doCountTest(digest: IDigest; seed, expectedXors: TBytes);
 
 
   protected
   protected
     procedure SetUp; override;
     procedure SetUp; override;
@@ -76,7 +76,7 @@ implementation
 
 
 { TTestDigestRandomNumber }
 { TTestDigestRandomNumber }
 
 
-procedure TTestDigestRandomNumber.doCountTest(digest: IHash;
+procedure TTestDigestRandomNumber.doCountTest(digest: IDigest;
   seed, expectedXors: TBytes);
   seed, expectedXors: TBytes);
 var
 var
   rGen: IDigestRandomGenerator;
   rGen: IDigestRandomGenerator;
@@ -84,7 +84,6 @@ var
   averages: TCryptoLibInt32Array;
   averages: TCryptoLibInt32Array;
   i, j: Int32;
   i, j: Int32;
 begin
 begin
-  digest.Initialize;
   rGen := TDigestRandomGenerator.Create(digest);
   rGen := TDigestRandomGenerator.Create(digest);
   System.SetLength(output, digest.HashSize);
   System.SetLength(output, digest.HashSize);
   System.SetLength(averages, digest.HashSize);
   System.SetLength(averages, digest.HashSize);
@@ -135,20 +134,19 @@ begin
 
 
 end;
 end;
 
 
-procedure TTestDigestRandomNumber.doExpectedTest(digest: IHash; seed: Int32;
+procedure TTestDigestRandomNumber.doExpectedTest(digest: IDigest; seed: Int32;
   expected: TBytes);
   expected: TBytes);
 begin
 begin
   doExpectedTest(digest, seed, expected, Nil);
   doExpectedTest(digest, seed, expected, Nil);
 end;
 end;
 
 
-procedure TTestDigestRandomNumber.doExpectedTest(digest: IHash; seed: Int32;
+procedure TTestDigestRandomNumber.doExpectedTest(digest: IDigest; seed: Int32;
   expected, noCycle: TBytes);
   expected, noCycle: TBytes);
 var
 var
   rGen: IDigestRandomGenerator;
   rGen: IDigestRandomGenerator;
   output: TBytes;
   output: TBytes;
   i: Int32;
   i: Int32;
 begin
 begin
-  digest.Initialize;
   rGen := TDigestRandomGenerator.Create(digest);
   rGen := TDigestRandomGenerator.Create(digest);
   System.SetLength(output, digest.HashSize);
   System.SetLength(output, digest.HashSize);
 
 
@@ -176,14 +174,13 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TTestDigestRandomNumber.doExpectedTest(digest: IHash;
+procedure TTestDigestRandomNumber.doExpectedTest(digest: IDigest;
   seed, expected: TBytes);
   seed, expected: TBytes);
 var
 var
   rGen: IDigestRandomGenerator;
   rGen: IDigestRandomGenerator;
   output: TBytes;
   output: TBytes;
   i: Int32;
   i: Int32;
 begin
 begin
-  digest.Initialize;
   rGen := TDigestRandomGenerator.Create(digest);
   rGen := TDigestRandomGenerator.Create(digest);
   System.SetLength(output, digest.HashSize);
   System.SetLength(output, digest.HashSize);
 
 
@@ -238,26 +235,27 @@ end;
 
 
 procedure TTestDigestRandomNumber.TestDigestRandomNumber;
 procedure TTestDigestRandomNumber.TestDigestRandomNumber;
 begin
 begin
-  doExpectedTest(THashFactory.TCrypto.CreateSHA1(), 0, Fexpected0SHA1,
+  doExpectedTest(TDigestUtilities.GetDigest('SHA-1'), 0, Fexpected0SHA1,
     FnoCycle0SHA1);
     FnoCycle0SHA1);
-  doExpectedTest(THashFactory.TCrypto.CreateSHA2_256(), 0, Fexpected0SHA256,
+  doExpectedTest(TDigestUtilities.GetDigest('SHA-256'), 0, Fexpected0SHA256,
     FnoCycle0SHA256);
     FnoCycle0SHA256);
 
 
-  doExpectedTest(THashFactory.TCrypto.CreateSHA1(), 100, Fexpected100SHA1);
-  doExpectedTest(THashFactory.TCrypto.CreateSHA2_256(), 100,
+  doExpectedTest(TDigestUtilities.GetDigest('SHA-1'), 100, Fexpected100SHA1);
+  doExpectedTest(TDigestUtilities.GetDigest('SHA-256'), 100,
     Fexpected100SHA256);
     Fexpected100SHA256);
 
 
-  doExpectedTest(THashFactory.TCrypto.CreateSHA1(), FZERO_SEED, Fexpected0SHA1);
-  doExpectedTest(THashFactory.TCrypto.CreateSHA2_256(), FZERO_SEED,
+  doExpectedTest(TDigestUtilities.GetDigest('SHA-1'), FZERO_SEED,
+    Fexpected0SHA1);
+  doExpectedTest(TDigestUtilities.GetDigest('SHA-256'), FZERO_SEED,
     Fexpected0SHA256);
     Fexpected0SHA256);
 
 
-  doExpectedTest(THashFactory.TCrypto.CreateSHA1(), FTEST_SEED,
+  doExpectedTest(TDigestUtilities.GetDigest('SHA-1'), FTEST_SEED,
     FexpectedTestSHA1);
     FexpectedTestSHA1);
-  doExpectedTest(THashFactory.TCrypto.CreateSHA2_256(), FTEST_SEED,
+  doExpectedTest(TDigestUtilities.GetDigest('SHA-256'), FTEST_SEED,
     FexpectedTestSHA256);
     FexpectedTestSHA256);
 
 
-  doCountTest(THashFactory.TCrypto.CreateSHA1(), FTEST_SEED, Fsha1Xors);
-  doCountTest(THashFactory.TCrypto.CreateSHA2_256(), FTEST_SEED, Fsha256Xors);
+  doCountTest(TDigestUtilities.GetDigest('SHA-1'), FTEST_SEED, Fsha1Xors);
+  doCountTest(TDigestUtilities.GetDigest('SHA-256'), FTEST_SEED, Fsha256Xors);
 end;
 end;
 
 
 initialization
 initialization

+ 8 - 8
CryptoLib.Tests/src/Crypto/IESCipherTests.pas

@@ -32,9 +32,8 @@ uses
 {$ELSE}
 {$ELSE}
   TestFramework,
   TestFramework,
 {$ENDIF FPC}
 {$ENDIF FPC}
-  HlpIHash,
-  HlpIHashInfo,
-  HlpHashFactory,
+  ClpIDigest,
+  ClpIDigestMAC,
   ClpAesEngine,
   ClpAesEngine,
   ClpIAesEngine,
   ClpIAesEngine,
   ClpIAsymmetricCipherKeyPairGenerator,
   ClpIAsymmetricCipherKeyPairGenerator,
@@ -75,6 +74,7 @@ uses
   ClpIIESCipher,
   ClpIIESCipher,
   ClpIESCipher,
   ClpIESCipher,
   ClpHex,
   ClpHex,
+  ClpDigestUtilities,
   ClpArrayUtils;
   ClpArrayUtils;
 
 
 type
 type
@@ -145,7 +145,7 @@ var
   blockCipher: ICbcBlockCipher;
   blockCipher: ICbcBlockCipher;
   ECDHBasicAgreementInstance: IECDHBasicAgreement;
   ECDHBasicAgreementInstance: IECDHBasicAgreement;
   KDFInstance: IKdf2BytesGenerator;
   KDFInstance: IKdf2BytesGenerator;
-  HMACInstance: IHMAC;
+  DigestMACInstance: IDigestMAC;
 
 
 begin
 begin
   // // Set up IES Cipher Engine
   // // Set up IES Cipher Engine
@@ -153,10 +153,10 @@ begin
   ECDHBasicAgreementInstance := TECDHBasicAgreement.Create();
   ECDHBasicAgreementInstance := TECDHBasicAgreement.Create();
 
 
   KDFInstance := TKdf2BytesGenerator.Create
   KDFInstance := TKdf2BytesGenerator.Create
-    (THashFactory.TCrypto.CreateSHA2_256 as IHash);
+    (TDigestUtilities.GetDigest('SHA-256'));
 
 
-  HMACInstance := THashFactory.THMAC.CreateHMAC
-    (THashFactory.TCrypto.CreateSHA2_256 as IHash);
+  DigestMACInstance := TDigestUtilities.GetDigestMAC
+    (TDigestUtilities.GetDigest('SHA-256'));
 
 
   // Method 1: Set Up Block Cipher
   // Method 1: Set Up Block Cipher
   // Cipher := TCipherUtilities.GetCipher('AES/CBC/PKCS7PADDING') as IBufferedBlockCipher;
   // Cipher := TCipherUtilities.GetCipher('AES/CBC/PKCS7PADDING') as IBufferedBlockCipher;
@@ -173,7 +173,7 @@ begin
   // TZeroBytePadding.Create() as IZeroBytePadding); // ZeroBytePadding
   // TZeroBytePadding.Create() as IZeroBytePadding); // ZeroBytePadding
 
 
   result := TIESEngine.Create(ECDHBasicAgreementInstance, KDFInstance,
   result := TIESEngine.Create(ECDHBasicAgreementInstance, KDFInstance,
-    HMACInstance, Cipher);
+    DigestMACInstance, Cipher);
 end;
 end;
 
 
 function TTestIESCipher.GetECKeyPair: IAsymmetricCipherKeyPair;
 function TTestIESCipher.GetECKeyPair: IAsymmetricCipherKeyPair;

+ 2 - 2
CryptoLib/src/Asn1/ClpDerIA5String.pas

@@ -27,7 +27,7 @@ uses
   ClpAsn1Tags,
   ClpAsn1Tags,
   ClpAsn1OctetString,
   ClpAsn1OctetString,
   ClpAsn1Object,
   ClpAsn1Object,
-  ClpStringHelper,
+  ClpStringUtils,
   ClpIProxiedInterface,
   ClpIProxiedInterface,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIAsn1TaggedObject,
@@ -174,7 +174,7 @@ end;
 
 
 function TDerIA5String.Asn1GetHashCode: Int32;
 function TDerIA5String.Asn1GetHashCode: Int32;
 begin
 begin
-  result := Str.GetHashCode;
+  result := TStringUtils.GetStringHashCode(FStr);
 end;
 end;
 
 
 constructor TDerIA5String.Create(Str: TCryptoLibByteArray);
 constructor TDerIA5String.Create(Str: TCryptoLibByteArray);

+ 11 - 7
CryptoLib/src/Asn1/ClpDerObjectIdentifier.pas

@@ -28,7 +28,7 @@ uses
   SyncObjs,
   SyncObjs,
   ClpBits,
   ClpBits,
   ClpArrayUtils,
   ClpArrayUtils,
-  ClpStringHelper,
+  ClpStringUtils,
   ClpStreamHelper,
   ClpStreamHelper,
   ClpBigInteger,
   ClpBigInteger,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
@@ -158,7 +158,7 @@ end;
 
 
 function TDerObjectIdentifier.Asn1GetHashCode: Int32;
 function TDerObjectIdentifier.Asn1GetHashCode: Int32;
 begin
 begin
-  result := Fidentifier.GetHashCode();
+  result := TStringUtils.GetStringHashCode(Fidentifier);
 end;
 end;
 
 
 function TDerObjectIdentifier.Branch(const branchID: String)
 function TDerObjectIdentifier.Branch(const branchID: String)
@@ -172,8 +172,10 @@ constructor TDerObjectIdentifier.Create(const oid: IDerObjectIdentifier;
 begin
 begin
   Inherited Create();
   Inherited Create();
   if (not(IsValidBranchID(branchID, 1))) then
   if (not(IsValidBranchID(branchID, 1))) then
+  begin
     raise EArgumentCryptoLibException.CreateResFmt(@SInvalidBranchId,
     raise EArgumentCryptoLibException.CreateResFmt(@SInvalidBranchId,
       [branchID]);
       [branchID]);
+  end;
 
 
   Fidentifier := oid.ID + '.' + branchID;
   Fidentifier := oid.ID + '.' + branchID;
 end;
 end;
@@ -182,9 +184,13 @@ constructor TDerObjectIdentifier.Create(const identifier: String);
 begin
 begin
   Inherited Create();
   Inherited Create();
   if (identifier = '') then
   if (identifier = '') then
+  begin
     raise EArgumentNilCryptoLibException.CreateRes(@SIdentifierNil);
     raise EArgumentNilCryptoLibException.CreateRes(@SIdentifierNil);
+  end;
   if (not(IsValidIdentifier(identifier))) then
   if (not(IsValidIdentifier(identifier))) then
+  begin
     raise EFormatCryptoLibException.CreateResFmt(@SInvalidOID, [identifier]);
     raise EFormatCryptoLibException.CreateResFmt(@SInvalidOID, [identifier]);
+  end;
 
 
   Fidentifier := identifier;
   Fidentifier := identifier;
 end;
 end;
@@ -247,7 +253,6 @@ begin
     end
     end
     else
     else
     begin
     begin
-
       WriteField(bOut, TBigInteger.Create(token));
       WriteField(bOut, TBigInteger.Create(token));
     end;
     end;
   end;
   end;
@@ -261,12 +266,12 @@ end;
 class function TDerObjectIdentifier.FromOctetString(enc: TCryptoLibByteArray)
 class function TDerObjectIdentifier.FromOctetString(enc: TCryptoLibByteArray)
   : IDerObjectIdentifier;
   : IDerObjectIdentifier;
 var
 var
-  hashCode, first: Int32;
+  HashCode, first: Int32;
   entry: IDerObjectIdentifier;
   entry: IDerObjectIdentifier;
 begin
 begin
 
 
-  hashCode := TArrayUtils.GetArrayHashCode(enc);
-  first := hashCode and 1023;
+  HashCode := TArrayUtils.GetArrayHashCode(enc);
+  first := HashCode and 1023;
 
 
   FLock.Acquire;
   FLock.Acquire;
   try
   try
@@ -440,7 +445,6 @@ var
   i, b: Int32;
   i, b: Int32;
 begin
 begin
   value := 0;
   value := 0;
-  // bigValue := null;
   bigValue := Default (TBigInteger);
   bigValue := Default (TBigInteger);
   first := true;
   first := true;
   objId := TStringList.Create();
   objId := TStringList.Create();

+ 2 - 2
CryptoLib/src/Asn1/ClpDerStringBase.pas

@@ -24,7 +24,7 @@ interface
 uses
 uses
   ClpIAsn1String,
   ClpIAsn1String,
   ClpAsn1Object,
   ClpAsn1Object,
-  ClpStringHelper,
+  ClpStringUtils,
   ClpIDerStringBase;
   ClpIDerStringBase;
 
 
 type
 type
@@ -44,7 +44,7 @@ implementation
 
 
 function TDerStringBase.Asn1GetHashCode: Int32;
 function TDerStringBase.Asn1GetHashCode: Int32;
 begin
 begin
-  Result := GetString().GetHashCode;
+  Result := TStringUtils.GetStringHashCode(GetString());
 end;
 end;
 
 
 constructor TDerStringBase.Create;
 constructor TDerStringBase.Create;

+ 2 - 2
CryptoLib/src/Asn1/ClpDerVisibleString.pas

@@ -27,7 +27,7 @@ uses
   ClpAsn1Tags,
   ClpAsn1Tags,
   ClpAsn1Object,
   ClpAsn1Object,
   ClpIAsn1OctetString,
   ClpIAsn1OctetString,
-  ClpStringHelper,
+  ClpStringUtils,
   ClpIProxiedInterface,
   ClpIProxiedInterface,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIAsn1TaggedObject,
@@ -133,7 +133,7 @@ end;
 
 
 function TDerVisibleString.Asn1GetHashCode: Int32;
 function TDerVisibleString.Asn1GetHashCode: Int32;
 begin
 begin
-  result := Str.GetHashCode;
+  result := TStringUtils.GetStringHashCode(FStr);
 end;
 end;
 
 
 constructor TDerVisibleString.Create(Str: TCryptoLibByteArray);
 constructor TDerVisibleString.Create(Str: TCryptoLibByteArray);

+ 76 - 2
CryptoLib/src/Asn1/Nist/ClpNistObjectIdentifiers.pas

@@ -34,8 +34,10 @@ type
 
 
       FNistAlgorithm, FHashAlgs, FAES, FIdSha256, FIdSha384, FIdSha512,
       FNistAlgorithm, FHashAlgs, FAES, FIdSha256, FIdSha384, FIdSha512,
       FIdSha224, FIdSha512_224, FIdSha512_256, FIdSha3_224, FIdSha3_256,
       FIdSha224, FIdSha512_224, FIdSha512_256, FIdSha3_224, FIdSha3_256,
-      FIdSha3_384, FIdSha3_512, FIdAes128Cbc, FIdAes192Cbc,
-      FIdAes256Cbc: IDerObjectIdentifier;
+      FIdSha3_384, FIdSha3_512, FIdAES128Ecb, FIdAes128Cbc, FIdAes128Ofb,
+      FIdAes128Cfb, FidAes192Ecb, FIdAes192Cbc, FIdAes192Ofb, FIdAes192Cfb,
+      FIdAes256Ecb, FIdAes256Cbc, FIdAes256Ofb, FIdAes256Cfb
+      : IDerObjectIdentifier;
 
 
     class function GetNistAlgorithm: IDerObjectIdentifier; static; inline;
     class function GetNistAlgorithm: IDerObjectIdentifier; static; inline;
     class function GetHashAlgs: IDerObjectIdentifier; static; inline;
     class function GetHashAlgs: IDerObjectIdentifier; static; inline;
@@ -50,9 +52,18 @@ type
     class function GetIdSha512: IDerObjectIdentifier; static; inline;
     class function GetIdSha512: IDerObjectIdentifier; static; inline;
     class function GetIdSha512_224: IDerObjectIdentifier; static; inline;
     class function GetIdSha512_224: IDerObjectIdentifier; static; inline;
     class function GetIdSha512_256: IDerObjectIdentifier; static; inline;
     class function GetIdSha512_256: IDerObjectIdentifier; static; inline;
+    class function GetIdAes128Ecb: IDerObjectIdentifier; static; inline;
     class function GetIdAes128Cbc: IDerObjectIdentifier; static; inline;
     class function GetIdAes128Cbc: IDerObjectIdentifier; static; inline;
+    class function GetIdAes128Ofb: IDerObjectIdentifier; static; inline;
+    class function GetIdAes128Cfb: IDerObjectIdentifier; static; inline;
+    class function GetIdAes192Ecb: IDerObjectIdentifier; static; inline;
     class function GetIdAes192Cbc: IDerObjectIdentifier; static; inline;
     class function GetIdAes192Cbc: IDerObjectIdentifier; static; inline;
+    class function GetIdAes192Ofb: IDerObjectIdentifier; static; inline;
+    class function GetIdAes192Cfb: IDerObjectIdentifier; static; inline;
+    class function GetIdAes256Ecb: IDerObjectIdentifier; static; inline;
     class function GetIdAes256Cbc: IDerObjectIdentifier; static; inline;
     class function GetIdAes256Cbc: IDerObjectIdentifier; static; inline;
+    class function GetIdAes256Ofb: IDerObjectIdentifier; static; inline;
+    class function GetIdAes256Cfb: IDerObjectIdentifier; static; inline;
 
 
     class constructor NistObjectIdentifiers();
     class constructor NistObjectIdentifiers();
 
 
@@ -78,9 +89,18 @@ type
     class property IdSha3_256: IDerObjectIdentifier read GetIdSha3_256;
     class property IdSha3_256: IDerObjectIdentifier read GetIdSha3_256;
     class property IdSha3_384: IDerObjectIdentifier read GetIdSha3_384;
     class property IdSha3_384: IDerObjectIdentifier read GetIdSha3_384;
     class property IdSha3_512: IDerObjectIdentifier read GetIdSha3_512;
     class property IdSha3_512: IDerObjectIdentifier read GetIdSha3_512;
+    class property IdAes128Ecb: IDerObjectIdentifier read GetIdAes128Ecb;
     class property IdAes128Cbc: IDerObjectIdentifier read GetIdAes128Cbc;
     class property IdAes128Cbc: IDerObjectIdentifier read GetIdAes128Cbc;
+    class property IdAes128Ofb: IDerObjectIdentifier read GetIdAes128Ofb;
+    class property IdAes128Cfb: IDerObjectIdentifier read GetIdAes128Cfb;
+    class property IdAes192Ecb: IDerObjectIdentifier read GetIdAes192Ecb;
     class property IdAes192Cbc: IDerObjectIdentifier read GetIdAes192Cbc;
     class property IdAes192Cbc: IDerObjectIdentifier read GetIdAes192Cbc;
+    class property IdAes192Ofb: IDerObjectIdentifier read GetIdAes192Ofb;
+    class property IdAes192Cfb: IDerObjectIdentifier read GetIdAes192Cfb;
+    class property IdAes256Ecb: IDerObjectIdentifier read GetIdAes256Ecb;
     class property IdAes256Cbc: IDerObjectIdentifier read GetIdAes256Cbc;
     class property IdAes256Cbc: IDerObjectIdentifier read GetIdAes256Cbc;
+    class property IdAes256Ofb: IDerObjectIdentifier read GetIdAes256Ofb;
+    class property IdAes256Cfb: IDerObjectIdentifier read GetIdAes256Cfb;
 
 
     class procedure Boot(); static;
     class procedure Boot(); static;
 
 
@@ -106,9 +126,18 @@ begin
   FIdSha3_256 := HashAlgs.Branch('8');
   FIdSha3_256 := HashAlgs.Branch('8');
   FIdSha3_384 := HashAlgs.Branch('9');
   FIdSha3_384 := HashAlgs.Branch('9');
   FIdSha3_512 := HashAlgs.Branch('10');
   FIdSha3_512 := HashAlgs.Branch('10');
+  FIdAES128Ecb := TDerObjectIdentifier.Create(AES.id + '.1');
   FIdAes128Cbc := TDerObjectIdentifier.Create(AES.id + '.2');
   FIdAes128Cbc := TDerObjectIdentifier.Create(AES.id + '.2');
+  FIdAes128Ofb := TDerObjectIdentifier.Create(AES.id + '.3');
+  FIdAes128Cfb := TDerObjectIdentifier.Create(AES.id + '.4');
+  FidAes192Ecb := TDerObjectIdentifier.Create(AES.id + '.21');
   FIdAes192Cbc := TDerObjectIdentifier.Create(AES.id + '.22');
   FIdAes192Cbc := TDerObjectIdentifier.Create(AES.id + '.22');
+  FIdAes192Ofb := TDerObjectIdentifier.Create(AES.id + '.23');
+  FIdAes192Cfb := TDerObjectIdentifier.Create(AES.id + '.24');
+  FIdAes256Ecb := TDerObjectIdentifier.Create(AES.id + '.41');
   FIdAes256Cbc := TDerObjectIdentifier.Create(AES.id + '.42');
   FIdAes256Cbc := TDerObjectIdentifier.Create(AES.id + '.42');
+  FIdAes256Ofb := TDerObjectIdentifier.Create(AES.id + '.43');
+  FIdAes256Cfb := TDerObjectIdentifier.Create(AES.id + '.44');
 end;
 end;
 
 
 class function TNistObjectIdentifiers.GetAES: IDerObjectIdentifier;
 class function TNistObjectIdentifiers.GetAES: IDerObjectIdentifier;
@@ -126,16 +155,61 @@ begin
   result := FIdAes128Cbc;
   result := FIdAes128Cbc;
 end;
 end;
 
 
+class function TNistObjectIdentifiers.GetIdAes128Cfb: IDerObjectIdentifier;
+begin
+  result := FIdAes128Cfb;
+end;
+
+class function TNistObjectIdentifiers.GetIdAes128Ecb: IDerObjectIdentifier;
+begin
+  result := FIdAES128Ecb;
+end;
+
+class function TNistObjectIdentifiers.GetIdAes128Ofb: IDerObjectIdentifier;
+begin
+  result := FIdAes128Ofb;
+end;
+
 class function TNistObjectIdentifiers.GetIdAes192Cbc: IDerObjectIdentifier;
 class function TNistObjectIdentifiers.GetIdAes192Cbc: IDerObjectIdentifier;
 begin
 begin
   result := FIdAes192Cbc;
   result := FIdAes192Cbc;
 end;
 end;
 
 
+class function TNistObjectIdentifiers.GetIdAes192Cfb: IDerObjectIdentifier;
+begin
+  result := FIdAes192Cfb;
+end;
+
+class function TNistObjectIdentifiers.GetIdAes192Ecb: IDerObjectIdentifier;
+begin
+  result := FidAes192Ecb;
+end;
+
+class function TNistObjectIdentifiers.GetIdAes192Ofb: IDerObjectIdentifier;
+begin
+  result := FIdAes192Ofb;
+end;
+
 class function TNistObjectIdentifiers.GetIdAes256Cbc: IDerObjectIdentifier;
 class function TNistObjectIdentifiers.GetIdAes256Cbc: IDerObjectIdentifier;
 begin
 begin
   result := FIdAes256Cbc;
   result := FIdAes256Cbc;
 end;
 end;
 
 
+class function TNistObjectIdentifiers.GetIdAes256Cfb: IDerObjectIdentifier;
+begin
+  result := FIdAes256Cfb;
+end;
+
+class function TNistObjectIdentifiers.GetIdAes256Ecb: IDerObjectIdentifier;
+begin
+  result := FIdAes256Ecb;
+end;
+
+class function TNistObjectIdentifiers.GetIdAes256Ofb: IDerObjectIdentifier;
+begin
+  result := FIdAes256Ofb;
+end;
+
 class function TNistObjectIdentifiers.GetIdSha224: IDerObjectIdentifier;
 class function TNistObjectIdentifiers.GetIdSha224: IDerObjectIdentifier;
 begin
 begin
   result := FIdSha224;
   result := FIdSha224;

+ 9 - 9
CryptoLib/src/Crypto/Engines/ClpIESEngine.pas

@@ -24,7 +24,7 @@ interface
 uses
 uses
   Classes,
   Classes,
   SysUtils,
   SysUtils,
-  HlpIHashInfo,
+  ClpIDigestMAC,
   ClpIIESEngine,
   ClpIIESEngine,
   ClpIBasicAgreement,
   ClpIBasicAgreement,
   ClpIDerivationFunction,
   ClpIDerivationFunction,
@@ -76,7 +76,7 @@ type
   var
   var
     Fagree: IBasicAgreement;
     Fagree: IBasicAgreement;
     Fkdf: IDerivationFunction;
     Fkdf: IDerivationFunction;
-    Fmac: IHMAC;
+    Fmac: IDigestMAC;
     Fcipher: IBufferedBlockCipher;
     Fcipher: IBufferedBlockCipher;
     FmacBuf, FV, FIV: TCryptoLibByteArray;
     FmacBuf, FV, FIV: TCryptoLibByteArray;
     FforEncryption: Boolean;
     FforEncryption: Boolean;
@@ -86,7 +86,7 @@ type
     FkeyParser: IKeyParser;
     FkeyParser: IKeyParser;
 
 
     function GetCipher: IBufferedBlockCipher; inline;
     function GetCipher: IBufferedBlockCipher; inline;
-    function GetMac: IHMAC; inline;
+    function GetMac: IDigestMAC; inline;
     function EncryptBlock(&in: TCryptoLibByteArray; inOff, inLen: Int32)
     function EncryptBlock(&in: TCryptoLibByteArray; inOff, inLen: Int32)
       : TCryptoLibByteArray; virtual;
       : TCryptoLibByteArray; virtual;
 
 
@@ -109,7 +109,7 @@ type
     /// the message authentication code generator for the message
     /// the message authentication code generator for the message
     /// </param>
     /// </param>
     constructor Create(const agree: IBasicAgreement;
     constructor Create(const agree: IBasicAgreement;
-      const kdf: IDerivationFunction; const mac: IHMAC); overload;
+      const kdf: IDerivationFunction; const mac: IDigestMAC); overload;
 
 
     /// <summary>
     /// <summary>
     /// Set up for use in conjunction with a block cipher to handle the <br />
     /// Set up for use in conjunction with a block cipher to handle the <br />
@@ -129,7 +129,7 @@ type
     /// the cipher to used for encrypting the message
     /// the cipher to used for encrypting the message
     /// </param>
     /// </param>
     constructor Create(const agree: IBasicAgreement;
     constructor Create(const agree: IBasicAgreement;
-      const kdf: IDerivationFunction; const mac: IHMAC;
+      const kdf: IDerivationFunction; const mac: IDigestMAC;
       const cipher: IBufferedBlockCipher); overload;
       const cipher: IBufferedBlockCipher); overload;
 
 
     /// <summary>
     /// <summary>
@@ -189,7 +189,7 @@ type
       : TCryptoLibByteArray; virtual;
       : TCryptoLibByteArray; virtual;
 
 
     property cipher: IBufferedBlockCipher read GetCipher;
     property cipher: IBufferedBlockCipher read GetCipher;
-    property mac: IHMAC read GetMac;
+    property mac: IDigestMAC read GetMac;
 
 
   end;
   end;
 
 
@@ -207,7 +207,7 @@ begin
 end;
 end;
 
 
 constructor TIESEngine.Create(const agree: IBasicAgreement;
 constructor TIESEngine.Create(const agree: IBasicAgreement;
-  const kdf: IDerivationFunction; const mac: IHMAC);
+  const kdf: IDerivationFunction; const mac: IDigestMAC);
 begin
 begin
   Inherited Create();
   Inherited Create();
   Fagree := agree;
   Fagree := agree;
@@ -218,7 +218,7 @@ begin
 end;
 end;
 
 
 constructor TIESEngine.Create(const agree: IBasicAgreement;
 constructor TIESEngine.Create(const agree: IBasicAgreement;
-  const kdf: IDerivationFunction; const mac: IHMAC;
+  const kdf: IDerivationFunction; const mac: IDigestMAC;
   const cipher: IBufferedBlockCipher);
   const cipher: IBufferedBlockCipher);
 begin
 begin
   Inherited Create();
   Inherited Create();
@@ -486,7 +486,7 @@ begin
   Result := Fcipher;
   Result := Fcipher;
 end;
 end;
 
 
-function TIESEngine.GetMac: IHMAC;
+function TIESEngine.GetMac: IDigestMAC;
 begin
 begin
   Result := Fmac;
   Result := Fmac;
 end;
 end;

+ 1 - 1
CryptoLib/src/Crypto/Engines/ClpPascalCoinIESEngine.pas

@@ -24,7 +24,7 @@ interface
 uses
 uses
   SysUtils,
   SysUtils,
   Classes,
   Classes,
-  HlpIHashInfo,
+  ClpIDigestMAC,
   ClpIPascalCoinIESEngine,
   ClpIPascalCoinIESEngine,
   ClpIBufferedBlockCipher,
   ClpIBufferedBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,

+ 7 - 8
CryptoLib/src/Crypto/Generators/ClpBaseKdfBytesGenerator.pas

@@ -23,7 +23,7 @@ interface
 
 
 uses
 uses
   SysUtils,
   SysUtils,
-  HlpIHash,
+  ClpIDigest,
   ClpIKdfParameters,
   ClpIKdfParameters,
   ClpIIso18033KdfParameters,
   ClpIIso18033KdfParameters,
   ClpIDerivationFunction,
   ClpIDerivationFunction,
@@ -53,10 +53,10 @@ type
 
 
   strict protected
   strict protected
   var
   var
-    Fdigest: IHash;
+    Fdigest: IDigest;
     FcounterStart: Int32;
     FcounterStart: Int32;
     Fshared, Fiv: TCryptoLibByteArray;
     Fshared, Fiv: TCryptoLibByteArray;
-    function GetDigest(): IHash; virtual;
+    function GetDigest(): IDigest; virtual;
 
 
   public
   public
 
 
@@ -69,14 +69,14 @@ type
     /// <param name="digest">
     /// <param name="digest">
     /// the digest to be used as the source of derived keys.
     /// the digest to be used as the source of derived keys.
     /// </param>
     /// </param>
-    constructor Create(counterStart: Int32; const digest: IHash);
+    constructor Create(counterStart: Int32; const digest: IDigest);
 
 
     procedure Init(const parameters: IDerivationParameters); virtual;
     procedure Init(const parameters: IDerivationParameters); virtual;
 
 
     /// <summary>
     /// <summary>
     /// return the underlying digest.
     /// return the underlying digest.
     /// </summary>
     /// </summary>
-    property digest: IHash read GetDigest;
+    property digest: IDigest read GetDigest;
 
 
     /// <summary>
     /// <summary>
     /// fill len bytes of the output buffer with bytes generated from the
     /// fill len bytes of the output buffer with bytes generated from the
@@ -98,7 +98,7 @@ implementation
 { TBaseKdfBytesGenerator }
 { TBaseKdfBytesGenerator }
 
 
 constructor TBaseKdfBytesGenerator.Create(counterStart: Int32;
 constructor TBaseKdfBytesGenerator.Create(counterStart: Int32;
-  const digest: IHash);
+  const digest: IDigest);
 begin
 begin
   Inherited Create();
   Inherited Create();
   FcounterStart := counterStart;
   FcounterStart := counterStart;
@@ -184,7 +184,7 @@ begin
   result := Int32(oBytes);
   result := Int32(oBytes);
 end;
 end;
 
 
-function TBaseKdfBytesGenerator.GetDigest: IHash;
+function TBaseKdfBytesGenerator.GetDigest: IDigest;
 begin
 begin
   result := Fdigest;
   result := Fdigest;
 end;
 end;
@@ -212,7 +212,6 @@ begin
     raise EArgumentCryptoLibException.CreateRes(@SKDFParameterNotFound);
     raise EArgumentCryptoLibException.CreateRes(@SKDFParameterNotFound);
   end;
   end;
 
 
-  Fdigest.Initialize();
 end;
 end;
 
 
 end.
 end.

+ 152 - 0
CryptoLib/src/Crypto/Generators/ClpCipherKeyGenerator.pas

@@ -0,0 +1,152 @@
+{ *********************************************************************************** }
+{ *                              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 ClpCipherKeyGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpICipherKeyGenerator,
+  ClpKeyGenerationParameters,
+  ClpIKeyGenerationParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidStrengthValue =
+    'Strength must be a Positive Value, "defaultStrength"';
+  SParametersNil = 'Parameters Cannot be Nil';
+  SGeneratorNotInitialized = 'Generator has not been Initialised';
+
+type
+
+  /// <summary>
+  /// The base class for symmetric, or secret, cipher key generators.
+  /// </summary>
+  TCipherKeyGenerator = class(TInterfacedObject, ICipherKeyGenerator)
+
+  strict private
+    Funinitialised: Boolean;
+    FdefaultStrength: Int32;
+
+    function GetdefaultStrength: Int32; inline;
+
+  strict protected
+    Frandom: ISecureRandom;
+    Fstrength: Int32;
+
+    procedure EngineInit(const parameters: IKeyGenerationParameters); virtual;
+    function EngineGenerateKey: TCryptoLibByteArray; virtual;
+
+  public
+
+    constructor Create(); overload;
+    constructor Create(defaultStrength: Int32); overload;
+
+    /// <summary>
+    /// initialise the key generator.
+    /// </summary>
+    /// <param name="parameters">
+    /// the parameters to be used for key generation
+    /// </param>
+    procedure Init(const parameters: IKeyGenerationParameters);
+
+    /// <summary>
+    /// Generate a secret key.
+    /// </summary>
+    /// <returns>
+    /// a byte array containing the key value.
+    /// </returns>
+    function GenerateKey: TCryptoLibByteArray;
+
+    property defaultStrength: Int32 read GetdefaultStrength;
+  end;
+
+implementation
+
+{ TCipherKeyGenerator }
+
+constructor TCipherKeyGenerator.Create;
+begin
+  Inherited Create();
+  Funinitialised := true;
+end;
+
+constructor TCipherKeyGenerator.Create(defaultStrength: Int32);
+begin
+  Inherited Create();
+  Funinitialised := true;
+  if (defaultStrength < 1) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidStrengthValue);
+  end;
+
+  FdefaultStrength := defaultStrength;
+end;
+
+function TCipherKeyGenerator.EngineGenerateKey: TCryptoLibByteArray;
+begin
+  result := TSecureRandom.GetNextBytes(Frandom, Fstrength);
+end;
+
+procedure TCipherKeyGenerator.EngineInit(const parameters
+  : IKeyGenerationParameters);
+begin
+  Frandom := parameters.Random;
+  Fstrength := (parameters.Strength + 7) div 8;
+end;
+
+function TCipherKeyGenerator.GenerateKey: TCryptoLibByteArray;
+begin
+  if (Funinitialised) then
+  begin
+    if (FdefaultStrength < 1) then
+    begin
+      raise EInvalidOperationCryptoLibException.CreateRes
+        (@SGeneratorNotInitialized);
+    end;
+
+    Funinitialised := false;
+
+    EngineInit(TKeyGenerationParameters.Create(TSecureRandom.Create()
+      as ISecureRandom, FdefaultStrength) as IKeyGenerationParameters);
+  end;
+
+  result := EngineGenerateKey();
+end;
+
+function TCipherKeyGenerator.GetdefaultStrength: Int32;
+begin
+  result := FdefaultStrength;
+end;
+
+procedure TCipherKeyGenerator.Init(const parameters: IKeyGenerationParameters);
+begin
+  if (parameters = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SParametersNil);
+  end;
+
+  Funinitialised := false;
+
+  EngineInit(parameters);
+end;
+
+end.

+ 3 - 3
CryptoLib/src/Crypto/Generators/ClpKdf2BytesGenerator.pas

@@ -22,7 +22,7 @@ unit ClpKdf2BytesGenerator;
 interface
 interface
 
 
 uses
 uses
-  HlpIHash,
+  ClpIDigest,
   ClpBaseKdfBytesGenerator,
   ClpBaseKdfBytesGenerator,
   ClpIKdf2BytesGenerator;
   ClpIKdf2BytesGenerator;
 
 
@@ -48,7 +48,7 @@ type
     /// <param name="digest">
     /// <param name="digest">
     /// the digest to be used as the source of derived keys.
     /// the digest to be used as the source of derived keys.
     /// </param>
     /// </param>
-    constructor Create(const digest: IHash);
+    constructor Create(const digest: IDigest);
 
 
   end;
   end;
 
 
@@ -56,7 +56,7 @@ implementation
 
 
 { TKdf2BytesGenerator }
 { TKdf2BytesGenerator }
 
 
-constructor TKdf2BytesGenerator.Create(const digest: IHash);
+constructor TKdf2BytesGenerator.Create(const digest: IDigest);
 begin
 begin
   Inherited Create(1, digest);
   Inherited Create(1, digest);
 end;
 end;

+ 6 - 8
CryptoLib/src/Crypto/Generators/ClpPascalCoinECIESKdfBytesGenerator.pas

@@ -23,7 +23,7 @@ interface
 
 
 uses
 uses
   SysUtils,
   SysUtils,
-  HlpIHash,
+  ClpIDigest,
   ClpBaseKdfBytesGenerator,
   ClpBaseKdfBytesGenerator,
   ClpIDerivationParameters,
   ClpIDerivationParameters,
   ClpIKdfParameters,
   ClpIKdfParameters,
@@ -48,7 +48,7 @@ type
     IPascalCoinECIESKdfBytesGenerator)
     IPascalCoinECIESKdfBytesGenerator)
 
 
   strict protected
   strict protected
-    function GetDigest(): IHash; override;
+    function GetDigest(): IDigest; override;
 
 
   public
   public
 
 
@@ -58,14 +58,14 @@ type
     /// <param name="digest">
     /// <param name="digest">
     /// the digest to be used as the source of derived keys.
     /// the digest to be used as the source of derived keys.
     /// </param>
     /// </param>
-    constructor Create(const digest: IHash);
+    constructor Create(const digest: IDigest);
 
 
     procedure Init(const parameters: IDerivationParameters); override;
     procedure Init(const parameters: IDerivationParameters); override;
 
 
     /// <summary>
     /// <summary>
     /// return the underlying digest.
     /// return the underlying digest.
     /// </summary>
     /// </summary>
-    property digest: IHash read GetDigest;
+    property digest: IDigest read GetDigest;
 
 
     /// <summary>
     /// <summary>
     /// fill len bytes of the output buffer with bytes generated from the
     /// fill len bytes of the output buffer with bytes generated from the
@@ -86,7 +86,7 @@ implementation
 
 
 { TPascalCoinECIESKdfBytesGenerator }
 { TPascalCoinECIESKdfBytesGenerator }
 
 
-constructor TPascalCoinECIESKdfBytesGenerator.Create(const digest: IHash);
+constructor TPascalCoinECIESKdfBytesGenerator.Create(const digest: IDigest);
 begin
 begin
   Inherited Create(0, digest);
   Inherited Create(0, digest);
 end;
 end;
@@ -124,7 +124,7 @@ begin
 
 
 end;
 end;
 
 
-function TPascalCoinECIESKdfBytesGenerator.GetDigest: IHash;
+function TPascalCoinECIESKdfBytesGenerator.GetDigest: IDigest;
 begin
 begin
   result := Fdigest;
   result := Fdigest;
 end;
 end;
@@ -146,8 +146,6 @@ begin
   begin
   begin
     raise EArgumentCryptoLibException.CreateRes(@SKDFParameterNotFound);
     raise EArgumentCryptoLibException.CreateRes(@SKDFParameterNotFound);
   end;
   end;
-
-  Fdigest.Initialize();
 end;
 end;
 
 
 end.
 end.

+ 367 - 0
CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas

@@ -0,0 +1,367 @@
+{ *********************************************************************************** }
+{ *                              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 ClpCfbBlockCipher;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpIBlockCipher,
+  ClpICfbBlockCipher,
+  ClpICipherParameters,
+  ClpIParametersWithIV,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInputBufferTooShort = 'Input Buffer too Short';
+  SOutputBufferTooShort = 'Output Buffer too Short';
+
+type
+
+  /// <summary>
+  /// implements a Cipher-FeedBack (CFB) mode on top of a simple cipher.
+  /// </summary>
+  TCfbBlockCipher = class sealed(TInterfacedObject, ICfbBlockCipher,
+    IBlockCipher)
+
+  strict private
+
+  var
+    FIV, FcfbV, FcfbOutV: TCryptoLibByteArray;
+    FblockSize: Int32;
+    Fcipher: IBlockCipher;
+    Fencrypting: Boolean;
+
+    /// <summary>
+    /// return the algorithm name and mode.
+    /// </summary>
+    /// <returns>
+    /// return the name of the underlying algorithm followed by "/CFB"
+    /// </returns>
+    function GetAlgorithmName: String; inline;
+
+    function GetIsPartialBlockOkay: Boolean; inline;
+
+    /// <summary>
+    /// Do the appropriate processing for CFB mode encryption.
+    /// </summary>
+    /// <param name="input">
+    /// the array containing the data to be encrypted.
+    /// </param>
+    /// <param name="inOff">
+    /// offset into the in array the data starts at.
+    /// </param>
+    /// <param name="outBytes">
+    /// the array the encrypted data will be copied into.
+    /// </param>
+    /// <param name="outOff">
+    /// the offset into the out array the output will start at.
+    /// </param>
+    /// <returns>
+    /// the number of bytes processed and produced.
+    /// </returns>
+    /// <exception cref="EDataLengthCryptoLibException">
+    /// if there isn't enough data in input, or space in output.
+    /// </exception>
+    /// <exception cref="EInvalidOperationCryptoLibException">
+    /// if the cipher isn't initialised.
+    /// </exception>
+    function EncryptBlock(input: TCryptoLibByteArray; inOff: Int32;
+      outBytes: TCryptoLibByteArray; outOff: Int32): Int32;
+
+    /// <summary>
+    /// Do the appropriate chaining step for CBC mode decryption.
+    /// </summary>
+    /// <param name="input">
+    /// the array containing the data to be decrypted.
+    /// </param>
+    /// <param name="inOff">
+    /// offset into the in array the data starts at.
+    /// </param>
+    /// <param name="outBytes">
+    /// the array the decrypted data will be copied into.
+    /// </param>
+    /// <param name="outOff">
+    /// the offset into the out array the output will start at.
+    /// </param>
+    /// <returns>
+    /// the number of bytes processed and produced.
+    /// </returns>
+    /// <exception cref="EDataLengthCryptoLibException">
+    /// if there isn't enough data in input, or space in output.
+    /// </exception>
+    /// <exception cref="EInvalidOperationCryptoLibException">
+    /// if the cipher isn't initialised.
+    /// </exception>
+    function DecryptBlock(input: TCryptoLibByteArray; inOff: Int32;
+      outBytes: TCryptoLibByteArray; outOff: Int32): Int32;
+
+  public
+
+    /// <summary>
+    /// Basic constructor.
+    /// </summary>
+    /// <param name="cipher">
+    /// the block cipher to be used as the basis of the feedback mode.
+    /// </param>
+    /// <param name="bitBlockSize">
+    /// the block size in bits (note: a multiple of 8)
+    /// </param>
+    constructor Create(const cipher: IBlockCipher; bitBlockSize: Int32);
+
+    /// <summary>
+    /// return the underlying block cipher that we are wrapping.
+    /// </summary>
+    /// <returns>
+    /// return the underlying block cipher that we are wrapping.
+    /// </returns>
+    function GetUnderlyingCipher(): IBlockCipher;
+
+    /// <summary>
+    /// Initialise the cipher and, possibly, the initialisation vector (IV). <br />
+    /// If an IV isn't passed as part of the parameter, the IV will be all
+    /// zeros.
+    /// An IV which is too short is handled in FIPS compliant fashion.
+    /// </summary>
+    /// <param name="forEncryption">
+    /// forEncryption if true the cipher is initialised for encryption, if
+    /// false for decryption.
+    /// </param>
+    /// <param name="parameters">
+    /// the key and other data required by the cipher.
+    /// </param>
+    procedure Init(forEncryption: Boolean; const parameters: ICipherParameters);
+
+    /// <summary>
+    /// return the block size we are operating at.
+    /// </summary>
+    /// <returns>
+    /// the block size we are operating at (in bytes).
+    /// </returns>
+    function GetBlockSize(): Int32; inline;
+
+    /// <summary>
+    /// Process one block of input from the input array and write it to the
+    /// output array.
+    /// </summary>
+    /// <param name="input">
+    /// the array containing the input data.
+    /// </param>
+    /// <param name="inOff">
+    /// offset into the input array the data starts at.
+    /// </param>
+    /// <param name="output">
+    /// the array the output data will be copied into.
+    /// </param>
+    /// <param name="outOff">
+    /// the offset into the output array the data starts at.
+    /// </param>
+    /// <returns>
+    /// the number of bytes processed and produced.
+    /// </returns>
+    /// <exception cref="EDataLengthCryptoLibException">
+    /// if there isn't enough data in input, or space in output.
+    /// </exception>
+    /// <exception cref="EInvalidOperationCryptoLibException">
+    /// if the cipher isn't initialised.
+    /// </exception>
+    function ProcessBlock(input: TCryptoLibByteArray; inOff: Int32;
+      output: TCryptoLibByteArray; outOff: Int32): Int32;
+
+    /// <summary>
+    /// reset the chaining vector back to the IV and reset the underlying
+    /// cipher.
+    /// </summary>
+    procedure Reset(); inline;
+
+    /// <summary>
+    /// return the algorithm name and mode.
+    /// </summary>
+    /// <value>
+    /// return the name of the underlying algorithm followed by "/CFB"
+    /// </value>
+    property AlgorithmName: String read GetAlgorithmName;
+
+    property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
+
+  end;
+
+implementation
+
+{ TCfbBlockCipher }
+
+constructor TCfbBlockCipher.Create(const cipher: IBlockCipher;
+  bitBlockSize: Int32);
+begin
+  inherited Create();
+  Fcipher := cipher;
+  FblockSize := bitBlockSize div 8;
+
+  System.SetLength(FIV, Fcipher.GetBlockSize);
+  System.SetLength(FcfbV, Fcipher.GetBlockSize);
+  System.SetLength(FcfbOutV, Fcipher.GetBlockSize);
+end;
+
+function TCfbBlockCipher.DecryptBlock(input: TCryptoLibByteArray; inOff: Int32;
+  outBytes: TCryptoLibByteArray; outOff: Int32): Int32;
+var
+  I: Int32;
+begin
+  if ((inOff + FblockSize) > System.length(input)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
+  end;
+
+  if ((outOff + FblockSize) > System.length(outBytes)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
+  end;
+
+  Fcipher.ProcessBlock(FcfbV, 0, FcfbOutV, 0);
+
+  //
+  // change over the input block.
+  //
+  System.Move(FcfbV[FblockSize], FcfbV[0], (System.length(FcfbV) - FblockSize) *
+    System.SizeOf(Byte));
+
+  System.Move(input[inOff], FcfbV[(System.length(FcfbV) - FblockSize)],
+    FblockSize * System.SizeOf(Byte));
+
+  // XOR the FcfbV with the ciphertext producing the plaintext
+
+  for I := 0 to System.Pred(FblockSize) do
+  begin
+    outBytes[outOff + I] := Byte(FcfbOutV[I] xor input[inOff + I]);
+  end;
+
+  result := FblockSize;
+end;
+
+function TCfbBlockCipher.EncryptBlock(input: TCryptoLibByteArray; inOff: Int32;
+  outBytes: TCryptoLibByteArray; outOff: Int32): Int32;
+var
+  I: Int32;
+begin
+  if ((inOff + FblockSize) > System.length(input)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
+  end;
+
+  if ((outOff + FblockSize) > System.length(outBytes)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
+  end;
+
+  Fcipher.ProcessBlock(FcfbV, 0, FcfbOutV, 0);
+
+  // XOR the FcfbV with the plaintext producing the ciphertext
+
+  for I := 0 to System.Pred(FblockSize) do
+  begin
+    outBytes[outOff + I] := Byte(FcfbOutV[I] xor input[inOff + I]);
+  end;
+
+  //
+  // change over the input block.
+  //
+  System.Move(FcfbV[FblockSize], FcfbV[0], (System.length(FcfbV) - FblockSize) *
+    System.SizeOf(Byte));
+
+  System.Move(outBytes[outOff], FcfbV[(System.length(FcfbV) - FblockSize)],
+    FblockSize * System.SizeOf(Byte));
+
+  result := FblockSize;
+end;
+
+procedure TCfbBlockCipher.Reset;
+begin
+  System.Move(FIV[0], FcfbV[0], System.length(FIV));
+
+  Fcipher.Reset();
+end;
+
+function TCfbBlockCipher.GetAlgorithmName: String;
+begin
+  result := Fcipher.AlgorithmName + '/CFB' + IntToStr(FblockSize * 8);
+end;
+
+function TCfbBlockCipher.GetBlockSize: Int32;
+begin
+  result := FblockSize;
+end;
+
+function TCfbBlockCipher.GetIsPartialBlockOkay: Boolean;
+begin
+  result := true;
+end;
+
+function TCfbBlockCipher.GetUnderlyingCipher: IBlockCipher;
+begin
+  result := Fcipher;
+end;
+
+procedure TCfbBlockCipher.Init(forEncryption: Boolean;
+  const parameters: ICipherParameters);
+var
+  ivParam: IParametersWithIV;
+  iv: TCryptoLibByteArray;
+  Lparameters: ICipherParameters;
+  diff: Int32;
+begin
+  Fencrypting := forEncryption;
+  Lparameters := parameters;
+
+  if Supports(Lparameters, IParametersWithIV, ivParam) then
+  begin
+    iv := ivParam.GetIV();
+
+    diff := System.length(FIV) - System.length(iv);
+
+    System.Move(iv[0], FIV[diff], System.length(iv) * System.SizeOf(Byte));
+    System.FillChar(FIV[0], diff, Byte(0));
+
+    Lparameters := ivParam.parameters;
+  end;
+
+  Reset();
+
+  // if it's Nil, key is to be reused.
+  if (Lparameters <> Nil) then
+  begin
+    Fcipher.Init(true, Lparameters);
+  end;
+
+end;
+
+function TCfbBlockCipher.ProcessBlock(input: TCryptoLibByteArray; inOff: Int32;
+  output: TCryptoLibByteArray; outOff: Int32): Int32;
+begin
+  if Fencrypting then
+  begin
+    result := EncryptBlock(input, inOff, output, outOff);
+  end
+  else
+  begin
+    result := DecryptBlock(input, inOff, output, outOff);
+  end;
+end;
+
+end.

+ 282 - 0
CryptoLib/src/Crypto/Modes/ClpOfbBlockCipher.pas

@@ -0,0 +1,282 @@
+{ *********************************************************************************** }
+{ *                              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 ClpOfbBlockCipher;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpIBlockCipher,
+  ClpIOfbBlockCipher,
+  ClpICipherParameters,
+  ClpIParametersWithIV,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInputBufferTooShort = 'Input Buffer too Short';
+  SOutputBufferTooShort = 'Output Buffer too Short';
+
+type
+
+  /// <summary>
+  /// implements a Output-FeedBack (OFB) mode on top of a simple cipher.
+  /// </summary>
+  TOfbBlockCipher = class sealed(TInterfacedObject, IOfbBlockCipher,
+    IBlockCipher)
+
+  strict private
+
+  var
+    FIV, FofbV, FofbOutV: TCryptoLibByteArray;
+    FblockSize: Int32;
+    Fcipher: IBlockCipher;
+    Fencrypting: Boolean;
+
+    /// <summary>
+    /// return the algorithm name and mode.
+    /// </summary>
+    /// <returns>
+    /// return the name of the underlying algorithm followed by "/OFB"
+    /// </returns>
+    function GetAlgorithmName: String; inline;
+
+    function GetIsPartialBlockOkay: Boolean; inline;
+
+  public
+
+    /// <summary>
+    /// Basic constructor.
+    /// </summary>
+    /// <param name="cipher">
+    /// the block cipher to be used as the basis of the feedback mode.
+    /// </param>
+    /// <param name="blockSize">
+    /// the block size in bits (note: a multiple of 8)
+    /// </param>
+    constructor Create(const cipher: IBlockCipher; blockSize: Int32);
+
+    /// <summary>
+    /// return the underlying block cipher that we are wrapping.
+    /// </summary>
+    /// <returns>
+    /// return the underlying block cipher that we are wrapping.
+    /// </returns>
+    function GetUnderlyingCipher(): IBlockCipher;
+
+    /// <summary>
+    /// Initialise the cipher and, possibly, the initialisation vector (IV). <br />
+    /// If an IV isn't passed as part of the parameter, the IV will be all
+    /// zeros.
+    /// An IV which is too short is handled in FIPS compliant fashion.
+    /// </summary>
+    /// <param name="forEncryption">
+    /// forEncryption if true the cipher is initialised for encryption, if
+    /// false for decryption.
+    /// ignored by this OFB mode though
+    /// </param>
+    /// <param name="parameters">
+    /// the key and other data required by the cipher.
+    /// </param>
+    procedure Init(forEncryption: Boolean; const parameters: ICipherParameters);
+
+    /// <summary>
+    /// return the block size we are operating at.
+    /// </summary>
+    /// <returns>
+    /// the block size we are operating at (in bytes).
+    /// </returns>
+    function GetBlockSize(): Int32; inline;
+
+    /// <summary>
+    /// Process one block of input from the input array and write it to the
+    /// output array.
+    /// </summary>
+    /// <param name="input">
+    /// the array containing the input data.
+    /// </param>
+    /// <param name="inOff">
+    /// offset into the input array the data starts at.
+    /// </param>
+    /// <param name="output">
+    /// the array the output data will be copied into.
+    /// </param>
+    /// <param name="outOff">
+    /// the offset into the output array the data starts at.
+    /// </param>
+    /// <returns>
+    /// the number of bytes processed and produced.
+    /// </returns>
+    /// <exception cref="EDataLengthCryptoLibException">
+    /// if there isn't enough data in input, or space in output.
+    /// </exception>
+    /// <exception cref="EInvalidOperationCryptoLibException">
+    /// if the cipher isn't initialised.
+    /// </exception>
+    function ProcessBlock(input: TCryptoLibByteArray; inOff: Int32;
+      output: TCryptoLibByteArray; outOff: Int32): Int32;
+
+    /// <summary>
+    /// reset the chaining vector back to the IV and reset the underlying
+    /// cipher.
+    /// </summary>
+    procedure Reset(); inline;
+
+    /// <summary>
+    /// return the algorithm name and mode.
+    /// </summary>
+    /// <value>
+    /// return the name of the underlying algorithm followed by "/OFB"
+    /// </value>
+    property AlgorithmName: String read GetAlgorithmName;
+
+    property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
+
+  end;
+
+implementation
+
+{ TOfbBlockCipher }
+
+constructor TOfbBlockCipher.Create(const cipher: IBlockCipher;
+  blockSize: Int32);
+begin
+  inherited Create();
+  Fcipher := cipher;
+  FblockSize := blockSize div 8;
+
+  System.SetLength(FIV, Fcipher.GetBlockSize);
+  System.SetLength(FofbV, Fcipher.GetBlockSize);
+  System.SetLength(FofbOutV, Fcipher.GetBlockSize);
+end;
+
+procedure TOfbBlockCipher.Reset;
+begin
+  System.Move(FIV[0], FofbV[0], System.length(FIV));
+
+  Fcipher.Reset();
+
+end;
+
+function TOfbBlockCipher.GetAlgorithmName: String;
+begin
+  result := Fcipher.AlgorithmName + '/OFB' + IntToStr(FblockSize * 8);
+end;
+
+function TOfbBlockCipher.GetBlockSize: Int32;
+begin
+  result := FblockSize;
+end;
+
+function TOfbBlockCipher.GetIsPartialBlockOkay: Boolean;
+begin
+  result := true;
+end;
+
+function TOfbBlockCipher.GetUnderlyingCipher: IBlockCipher;
+begin
+  result := Fcipher;
+end;
+
+procedure TOfbBlockCipher.Init(forEncryption: Boolean;
+  // forEncryption ignored by this OFB mode
+  const parameters: ICipherParameters);
+var
+  ivParam: IParametersWithIV;
+  iv: TCryptoLibByteArray;
+  Lparameters: ICipherParameters;
+  I: Int32;
+begin
+  Fencrypting := forEncryption;
+  Lparameters := parameters;
+
+  if Supports(Lparameters, IParametersWithIV, ivParam) then
+  begin
+    iv := ivParam.GetIV();
+
+    if (System.length(iv) < System.length(FIV)) then
+    begin
+      // prepend the supplied IV with zeros (per FIPS PUB 81)
+      System.Move(iv[0], FIV[System.length(FIV) - System.length(iv)],
+        System.length(iv) * System.SizeOf(Byte));
+
+      for I := 0 to System.Pred(System.length(FIV) - System.length(iv)) do
+      begin
+        FIV[I] := 0;
+      end;
+
+    end
+    else
+    begin
+      System.Move(iv[0], FIV[0], System.length(FIV) * System.SizeOf(Byte));
+    end;
+
+    Lparameters := ivParam.parameters;
+  end;
+
+  Reset();
+
+  // if it's Nil, key is to be reused.
+  if (Lparameters <> Nil) then
+  begin
+    Fcipher.Init(true, Lparameters);
+  end;
+
+end;
+
+function TOfbBlockCipher.ProcessBlock(input: TCryptoLibByteArray; inOff: Int32;
+  output: TCryptoLibByteArray; outOff: Int32): Int32;
+var
+  I: Int32;
+begin
+  if ((inOff + FblockSize) > System.length(input)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
+  end;
+
+  if ((outOff + FblockSize) > System.length(output)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
+  end;
+
+  Fcipher.ProcessBlock(FofbV, 0, FofbOutV, 0);
+
+  //
+  // XOR the ofbV with the plaintext producing the cipher text (and
+  // the next input block).
+  //
+
+  for I := 0 to System.Pred(FblockSize) do
+  begin
+    output[outOff + I] := Byte(FofbOutV[I] xor input[inOff + I]);
+  end;
+
+  //
+  // change over the input block.
+  //
+  System.Move(FofbV[FblockSize], FofbV[0], (System.length(FofbV) - FblockSize) *
+    System.SizeOf(Byte));
+
+  System.Move(FofbOutV[0], FofbV[(System.length(FofbV) - FblockSize)],
+    FblockSize * System.SizeOf(Byte));
+
+  result := FblockSize;
+end;
+
+end.

+ 290 - 0
CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas

@@ -0,0 +1,290 @@
+{ *********************************************************************************** }
+{ *                              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 ClpSicBlockCipher;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  Math,
+  ClpIBlockCipher,
+  ClpISicBlockCipher,
+  ClpICipherParameters,
+  ClpIParametersWithIV,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInputBufferTooShort = 'Input Buffer too Short';
+  SOutputBufferTooShort = 'Output Buffer too Short';
+{$IFNDEF _FIXINSIGHT_}
+  SInvalidParameterArgument = 'CTR/SIC Mode Requires ParametersWithIV';
+  SInvalidTooLargeIVLength =
+    'CTR/SIC mode requires IV no greater than: %u bytes';
+  SInvalidTooSmallIVLength = 'CTR/SIC mode requires IV of at least: %u bytes';
+{$ENDIF}
+
+type
+
+  /// <summary>
+  /// Implements the Segmented Integer Counter (SIC) mode on top of a simple block cipher.
+  /// </summary>
+  TSicBlockCipher = class sealed(TInterfacedObject, ISicBlockCipher,
+    IBlockCipher)
+
+  strict private
+
+  var
+    FIV, Fcounter, FcounterOut: TCryptoLibByteArray;
+    FblockSize: Int32;
+    Fcipher: IBlockCipher;
+
+    /// <summary>
+    /// return the algorithm name and mode.
+    /// </summary>
+    /// <returns>
+    /// return the name of the underlying algorithm followed by "/SIC"
+    /// </returns>
+    function GetAlgorithmName: String; inline;
+
+    function GetIsPartialBlockOkay: Boolean; inline;
+
+  public
+
+    /// <summary>
+    /// Basic constructor.
+    /// </summary>
+    /// <param name="cipher">
+    /// the block cipher to be used.
+    /// </param>
+    constructor Create(const cipher: IBlockCipher);
+
+    /// <summary>
+    /// return the underlying block cipher that we are wrapping.
+    /// </summary>
+    /// <returns>
+    /// return the underlying block cipher that we are wrapping.
+    /// </returns>
+    function GetUnderlyingCipher(): IBlockCipher;
+
+    /// <summary>
+    /// Initialise the cipher and, possibly, the initialisation vector (IV). <br />
+    /// If an IV isn't passed as part of the parameter, the IV will be all
+    /// zeros.
+    /// An IV which is required in this mode.
+    /// </summary>
+    /// <param name="forEncryption">
+    /// forEncryption if true the cipher is initialised for encryption, if
+    /// false for decryption.
+    /// ignored by this CTR mode though
+    /// </param>
+    /// <param name="parameters">
+    /// the key and other data required by the cipher.
+    /// </param>
+    procedure Init(forEncryption: Boolean; const parameters: ICipherParameters);
+
+    /// <summary>
+    /// return the block size we are operating at.
+    /// </summary>
+    /// <returns>
+    /// the block size we are operating at (in bytes).
+    /// </returns>
+    function GetBlockSize(): Int32; inline;
+
+    /// <summary>
+    /// Process one block of input from the input array and write it to the
+    /// output array.
+    /// </summary>
+    /// <param name="input">
+    /// the array containing the input data.
+    /// </param>
+    /// <param name="inOff">
+    /// offset into the input array the data starts at.
+    /// </param>
+    /// <param name="output">
+    /// the array the output data will be copied into.
+    /// </param>
+    /// <param name="outOff">
+    /// the offset into the output array the data starts at.
+    /// </param>
+    /// <returns>
+    /// the number of bytes processed and produced.
+    /// </returns>
+    /// <exception cref="EDataLengthCryptoLibException">
+    /// if there isn't enough data in input, or space in output.
+    /// </exception>
+    /// <exception cref="EInvalidOperationCryptoLibException">
+    /// if the cipher isn't initialised.
+    /// </exception>
+    function ProcessBlock(input: TCryptoLibByteArray; inOff: Int32;
+      output: TCryptoLibByteArray; outOff: Int32): Int32;
+
+    /// <summary>
+    /// reset the chaining vector back to the IV and reset the underlying
+    /// cipher.
+    /// </summary>
+    procedure Reset(); inline;
+
+    /// <summary>
+    /// return the algorithm name and mode.
+    /// </summary>
+    /// <value>
+    /// return the name of the underlying algorithm followed by "/SIC"
+    /// </value>
+    property AlgorithmName: String read GetAlgorithmName;
+
+    property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
+
+  end;
+
+implementation
+
+{ TSicBlockCipher }
+
+constructor TSicBlockCipher.Create(const cipher: IBlockCipher);
+begin
+  inherited Create();
+  Fcipher := cipher;
+  FblockSize := Fcipher.GetBlockSize;
+
+  System.SetLength(Fcounter, FblockSize);
+  System.SetLength(FcounterOut, FblockSize);
+  System.SetLength(FIV, FblockSize);
+end;
+
+procedure TSicBlockCipher.Reset;
+begin
+  System.FillChar(Fcounter[0], System.Length(Fcounter) *
+    System.SizeOf(Byte), Byte(0));
+  System.Move(FIV[0], Fcounter[0], System.Length(FIV) *
+    System.SizeOf(Byte));
+
+  Fcipher.Reset();
+
+end;
+
+function TSicBlockCipher.GetAlgorithmName: String;
+begin
+  result := Fcipher.AlgorithmName + '/SIC';
+end;
+
+function TSicBlockCipher.GetBlockSize: Int32;
+begin
+  result := Fcipher.GetBlockSize();
+end;
+
+function TSicBlockCipher.GetIsPartialBlockOkay: Boolean;
+begin
+  result := true;
+end;
+
+function TSicBlockCipher.GetUnderlyingCipher: IBlockCipher;
+begin
+  result := Fcipher;
+end;
+
+{$IFNDEF _FIXINSIGHT_}
+
+procedure TSicBlockCipher.Init(forEncryption: Boolean;
+  // forEncryption ignored by this CTR mode
+  const parameters: ICipherParameters);
+var
+  ivParam: IParametersWithIV;
+  Lparameters: ICipherParameters;
+  maxCounterSize: Int32;
+begin
+  Lparameters := parameters;
+
+  if Supports(Lparameters, IParametersWithIV, ivParam) then
+  begin
+    FIV := ivParam.GetIV();
+
+    if (FblockSize < System.Length(FIV)) then
+    begin
+      raise EArgumentCryptoLibException.CreateResFmt(@SInvalidTooLargeIVLength,
+        [FblockSize]);
+    end;
+
+    maxCounterSize := Min(8, FblockSize div 2);
+
+    if ((FblockSize - System.Length(FIV)) > maxCounterSize) then
+    begin
+      raise EArgumentCryptoLibException.CreateResFmt(@SInvalidTooSmallIVLength,
+        [FblockSize - maxCounterSize]);
+    end;
+
+    Lparameters := ivParam.parameters;
+  end
+  else
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidParameterArgument);
+  end;
+
+  // if it's Nil, key is to be reused.
+  if (Lparameters <> Nil) then
+  begin
+    Fcipher.Init(true, Lparameters);
+  end;
+
+  Reset();
+
+end;
+{$ENDIF}
+
+function TSicBlockCipher.ProcessBlock(input: TCryptoLibByteArray; inOff: Int32;
+  output: TCryptoLibByteArray; outOff: Int32): Int32;
+var
+  I, J: Int32;
+begin
+
+  if ((inOff + FblockSize) > System.Length(input)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
+  end;
+
+  if ((outOff + FblockSize) > System.Length(output)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
+  end;
+
+  Fcipher.ProcessBlock(Fcounter, 0, FcounterOut, 0);
+
+  //
+  // XOR the counterOut with the plaintext producing the cipher text
+  //
+  for I := 0 to System.Pred(System.Length(FcounterOut)) do
+  begin
+
+    output[outOff + I] := Byte(FcounterOut[I] xor input[inOff + I]);
+  end;
+
+  // Increment the counter
+  J := System.Length(Fcounter);
+  System.Dec(J);
+  System.Inc(Fcounter[J]);
+  while ((J >= 0) and (Fcounter[J] = 0)) do
+  begin
+    System.Dec(J);
+    System.Inc(Fcounter[J]);
+  end;
+
+  result := System.Length(Fcounter);
+end;
+
+end.

+ 151 - 0
CryptoLib/src/Crypto/Paddings/ClpISO10126d2Padding.pas

@@ -0,0 +1,151 @@
+{ *********************************************************************************** }
+{ *                              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 ClpISO10126d2Padding;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding,
+  ClpIISO10126d2Padding,
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SCorruptedPadBlock = 'Pad Block Corrupted';
+
+type
+
+  /// <summary>
+  /// A padder that adds ISO10126-2 padding to a block.
+  /// </summary>
+  TISO10126d2Padding = class sealed(TInterfacedObject, IISO10126d2Padding,
+    IBlockCipherPadding)
+
+  strict private
+
+  var
+    FRandom: ISecureRandom;
+    /// <returns>
+    /// return the name of the algorithm the cipher implements.
+    /// </returns>
+    function GetPaddingName: String; inline;
+
+  public
+    /// <summary>
+    /// Initialise the padder.
+    /// </summary>
+    /// <param name="random">
+    /// a SecureRandom if available.
+    /// </param>
+    procedure Init(const random: ISecureRandom);
+
+    /// <summary>
+    /// Return the name of the algorithm the cipher implements.
+    /// </summary>
+    property PaddingName: String read GetPaddingName;
+
+    /// <summary>
+    /// add the pad bytes to the passed in block, returning the number of
+    /// bytes added.
+    /// </summary>
+    /// <param name="input">
+    /// input block to pad
+    /// </param>
+    /// <param name="inOff">
+    /// offset to start the padding from in the block
+    /// </param>
+    /// <returns>
+    /// returns number of bytes added
+    /// </returns>
+    function AddPadding(input: TCryptoLibByteArray; inOff: Int32): Int32;
+
+    /// <summary>
+    /// return the number of pad bytes present in the block.
+    /// </summary>
+    /// <param name="input">
+    /// block to count pad bytes in
+    /// </param>
+    /// <returns>
+    /// the number of pad bytes present in the block.
+    /// </returns>
+    /// <exception cref="EInvalidCipherTextCryptoLibException">
+    /// if the padding is badly formed or invalid.
+    /// </exception>
+    function PadCount(input: TCryptoLibByteArray): Int32;
+
+  end;
+
+implementation
+
+{ TISO10126d2Padding }
+
+function TISO10126d2Padding.AddPadding(input: TCryptoLibByteArray;
+  inOff: Int32): Int32;
+var
+  code: Byte;
+begin
+  code := Byte(System.Length(input) - inOff);
+
+  while (inOff < (System.Length(input) - 1)) do
+  begin
+    input[inOff] := Byte(FRandom.NextInt32);
+    System.Inc(inOff);
+  end;
+
+  input[inOff] := code;
+
+  result := code;
+end;
+
+function TISO10126d2Padding.GetPaddingName: String;
+begin
+  result := 'ISO10126-2';
+end;
+
+procedure TISO10126d2Padding.Init(const random: ISecureRandom);
+begin
+  if random <> Nil then
+  begin
+    FRandom := random;
+  end
+  else
+  begin
+    FRandom := TSecureRandom.Create();
+  end;
+end;
+
+function TISO10126d2Padding.PadCount(input: TCryptoLibByteArray): Int32;
+var
+  count: Int32;
+begin
+
+  count := input[System.Length(input) - 1] and $FF;
+
+  if (count > System.Length(input)) then
+  begin
+    raise EInvalidCipherTextCryptoLibException.CreateRes(@SCorruptedPadBlock);
+  end;
+
+  result := count;
+
+end;
+
+end.

+ 150 - 0
CryptoLib/src/Crypto/Paddings/ClpISO7816d4Padding.pas

@@ -0,0 +1,150 @@
+{ *********************************************************************************** }
+{ *                              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 ClpISO7816d4Padding;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding,
+  ClpIISO7816d4Padding,
+  ClpISecureRandom,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SCorruptedPadBlock = 'Pad Block Corrupted';
+
+type
+
+  /// <summary>
+  /// A padder that adds the padding according to the scheme referenced in
+  /// ISO 7814-4 - scheme 2 from ISO 9797-1. The first byte is $80, rest is $00
+  /// </summary>
+  TISO7816d4Padding = class sealed(TInterfacedObject, IISO7816d4Padding,
+    IBlockCipherPadding)
+
+  strict private
+    /// <returns>
+    /// return the name of the algorithm the cipher implements.
+    /// </returns>
+    function GetPaddingName: String; inline;
+
+  public
+    /// <summary>
+    /// Initialise the padder.
+    /// </summary>
+    /// <param name="random">
+    /// a SecureRandom if available.
+    /// </param>
+    procedure Init(const random: ISecureRandom);
+
+    /// <summary>
+    /// Return the name of the algorithm the cipher implements.
+    /// </summary>
+    property PaddingName: String read GetPaddingName;
+
+    /// <summary>
+    /// add the pad bytes to the passed in block, returning the number of
+    /// bytes added.
+    /// </summary>
+    /// <param name="input">
+    /// input block to pad
+    /// </param>
+    /// <param name="inOff">
+    /// offset to start the padding from in the block
+    /// </param>
+    /// <returns>
+    /// returns number of bytes added
+    /// </returns>
+    function AddPadding(input: TCryptoLibByteArray; inOff: Int32): Int32;
+
+    /// <summary>
+    /// return the number of pad bytes present in the block.
+    /// </summary>
+    /// <param name="input">
+    /// block to count pad bytes in
+    /// </param>
+    /// <returns>
+    /// the number of pad bytes present in the block.
+    /// </returns>
+    /// <exception cref="EInvalidCipherTextCryptoLibException">
+    /// if the padding is badly formed or invalid.
+    /// </exception>
+    function PadCount(input: TCryptoLibByteArray): Int32;
+
+  end;
+
+implementation
+
+{ TISO7816d4Padding }
+
+function TISO7816d4Padding.AddPadding(input: TCryptoLibByteArray;
+  inOff: Int32): Int32;
+var
+  added: Int32;
+begin
+  added := (System.Length(input) - inOff);
+
+  input[inOff] := Byte($80);
+  System.Inc(inOff);
+
+  while (inOff < System.Length(input)) do
+  begin
+    input[inOff] := Byte(0);
+    System.Inc(inOff);
+  end;
+
+  result := added;
+end;
+
+function TISO7816d4Padding.GetPaddingName: String;
+begin
+  result := 'ISO7816-4';
+end;
+
+{$IFNDEF _FIXINSIGHT_}
+
+procedure TISO7816d4Padding.Init(const random: ISecureRandom);
+begin
+  // nothing to do.
+end;
+{$ENDIF}
+
+function TISO7816d4Padding.PadCount(input: TCryptoLibByteArray): Int32;
+var
+  count: Int32;
+begin
+
+  count := System.Length(input) - 1;
+
+  while ((count > 0) and (input[count] = 0)) do
+  begin
+    System.Dec(count);
+  end;
+
+  if (input[count] <> Byte($80)) then
+  begin
+    raise EInvalidCipherTextCryptoLibException.CreateRes(@SCorruptedPadBlock);
+  end;
+
+  result := System.Length(input) - count;
+
+end;
+
+end.

+ 1 - 1
CryptoLib/src/Crypto/Paddings/ClpPkcs7Padding.pas

@@ -143,7 +143,7 @@ begin
   //
   //
   // result := count;
   // result := count;
 
 
-  count := input[System.Length(input) - 1];
+  count := input[System.Length(input) - 1] and $FF;
   countAsByte := Byte(count);
   countAsByte := Byte(count);
 
 
   // constant time version
   // constant time version

+ 163 - 0
CryptoLib/src/Crypto/Paddings/ClpTTBCPadding.pas

@@ -0,0 +1,163 @@
+{ *********************************************************************************** }
+{ *                              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 ClpTTBCPadding;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding,
+  ClpITBCPadding,
+  ClpISecureRandom,
+  ClpCryptoLibTypes;
+
+type
+
+  /// <summary> A padder that adds Trailing-Bit-Compliment padding to a block.
+  /// <p>
+  /// This padding pads the block out compliment of the last bit
+  /// of the plain text.
+  /// </p>
+  /// </summary>
+  TTBCPadding = class sealed(TInterfacedObject, ITBCPadding,
+    IBlockCipherPadding)
+
+  strict private
+    /// <returns>
+    /// return the name of the algorithm the cipher implements.
+    /// </returns>
+    function GetPaddingName: String; inline;
+
+  public
+    /// <summary>
+    /// Initialise the padder.
+    /// </summary>
+    /// <param name="random">
+    /// a SecureRandom if available.
+    /// </param>
+    procedure Init(const random: ISecureRandom);
+
+    /// <summary>
+    /// Return the name of the algorithm the cipher implements.
+    /// </summary>
+    property PaddingName: String read GetPaddingName;
+
+    /// <summary> add the pad bytes to the passed in block, returning the
+    /// number of bytes added.
+    /// <p>
+    /// Note: this assumes that the last block of plain text is always
+    /// passed to it inside in. i.e. if inOff is zero, indicating the
+    /// entire block is to be overwritten with padding the value of in
+    /// should be the same as the last block of plain text.
+    /// </p>
+    /// </summary>
+    function AddPadding(input: TCryptoLibByteArray; inOff: Int32): Int32;
+
+    /// <summary>
+    /// return the number of pad bytes present in the block.
+    /// </summary>
+    /// <param name="input">
+    /// block to count pad bytes in
+    /// </param>
+    /// <returns>
+    /// the number of pad bytes present in the block.
+    /// </returns>
+    function PadCount(input: TCryptoLibByteArray): Int32;
+
+  end;
+
+implementation
+
+{ TTBCPadding }
+
+function TTBCPadding.AddPadding(input: TCryptoLibByteArray;
+  inOff: Int32): Int32;
+var
+  count: Int32;
+  code: Byte;
+begin
+  count := System.Length(input) - inOff;
+
+  if (inOff > 0) then
+  begin
+    if (input[inOff - 1] and $01) = 0 then
+    begin
+      code := Byte($FF)
+    end
+    else
+    begin
+      code := Byte($00)
+    end;
+
+  end
+  else
+  begin
+
+    if (input[System.Length(input) - 1] and $01) = 0 then
+    begin
+      code := Byte($FF)
+    end
+    else
+    begin
+      code := Byte($00)
+    end;
+
+  end;
+
+  while (inOff < System.Length(input)) do
+  begin
+    input[inOff] := code;
+    System.Inc(inOff);
+  end;
+
+  result := count;
+end;
+
+function TTBCPadding.GetPaddingName: String;
+begin
+  result := 'TBC';
+end;
+
+{$IFNDEF _FIXINSIGHT_}
+
+procedure TTBCPadding.Init(const random: ISecureRandom);
+begin
+  // nothing to do.
+end;
+{$ENDIF}
+
+function TTBCPadding.PadCount(input: TCryptoLibByteArray): Int32;
+var
+  code: Byte;
+  index: Int32;
+begin
+
+  code := input[System.Length(input) - 1];
+
+  index := System.Length(input) - 1;
+  while ((index > 0) and (input[index - 1] = code)) do
+  begin
+    System.Dec(index);
+  end;
+
+  result := System.Length(input) - index;
+
+end;
+
+end.

+ 150 - 0
CryptoLib/src/Crypto/Paddings/ClpX923Padding.pas

@@ -0,0 +1,150 @@
+{ *********************************************************************************** }
+{ *                              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 ClpX923Padding;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding,
+  ClpIX923Padding,
+  ClpISecureRandom,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SCorruptedPadBlock = 'Pad Block Corrupted';
+
+type
+
+  /// <summary>
+  /// A padder that adds X9.23 padding to a block - if a SecureRandom is
+  /// passed in random padding is assumed, otherwise padding with zeros is
+  /// used.
+  /// </summary>
+  TX923Padding = class sealed(TInterfacedObject, IX923Padding,
+    IBlockCipherPadding)
+
+  strict private
+  var
+    FRandom: ISecureRandom;
+
+    /// <returns>
+    /// return the name of the algorithm the cipher implements.
+    /// </returns>
+    function GetPaddingName: String; inline;
+
+  public
+    /// <summary>
+    /// Initialise the padder.
+    /// </summary>
+    /// <param name="random">
+    /// a SecureRandom if available.
+    /// </param>
+    procedure Init(const random: ISecureRandom);
+
+    /// <summary>
+    /// Return the name of the algorithm the cipher implements.
+    /// </summary>
+    property PaddingName: String read GetPaddingName;
+
+    /// <summary>
+    /// add the pad bytes to the passed in block, returning the number of
+    /// bytes added.
+    /// </summary>
+    /// <param name="input">
+    /// input block to pad
+    /// </param>
+    /// <param name="inOff">
+    /// offset to start the padding from in the block
+    /// </param>
+    /// <returns>
+    /// returns number of bytes added
+    /// </returns>
+    function AddPadding(input: TCryptoLibByteArray; inOff: Int32): Int32;
+
+    /// <summary>
+    /// return the number of pad bytes present in the block.
+    /// </summary>
+    /// <param name="input">
+    /// block to count pad bytes in
+    /// </param>
+    /// <returns>
+    /// the number of pad bytes present in the block.
+    /// </returns>
+    /// <exception cref="EInvalidCipherTextCryptoLibException">
+    /// if the padding is badly formed or invalid.
+    /// </exception>
+    function PadCount(input: TCryptoLibByteArray): Int32;
+
+  end;
+
+implementation
+
+{ TX923Padding }
+
+function TX923Padding.AddPadding(input: TCryptoLibByteArray;
+  inOff: Int32): Int32;
+var
+  code: Byte;
+begin
+  code := Byte(System.Length(input) - inOff);
+
+  while (inOff < (System.Length(input) - 1)) do
+  begin
+    if (FRandom = Nil) then
+    begin
+      input[inOff] := 0;
+    end
+    else
+    begin
+      input[inOff] := Byte(FRandom.NextInt32);
+    end;
+    System.Inc(inOff);
+  end;
+
+  result := code;
+end;
+
+function TX923Padding.GetPaddingName: String;
+begin
+  result := 'X9.23';
+end;
+
+procedure TX923Padding.Init(const random: ISecureRandom);
+begin
+  FRandom := random;
+end;
+
+function TX923Padding.PadCount(input: TCryptoLibByteArray): Int32;
+var
+  count: Int32;
+begin
+
+  count := input[System.Length(input) - 1] and $FF;
+
+  if (count > System.Length(input)) then
+  begin
+    raise EInvalidCipherTextCryptoLibException.CreateRes(@SCorruptedPadBlock);
+  end;
+
+  result := count;
+
+end;
+
+end.

+ 4 - 0
CryptoLib/src/Crypto/Paddings/ClpZeroBytePadding.pas

@@ -28,6 +28,10 @@ uses
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 type
 type
+
+  /// <summary>
+  /// A padder that adds Null byte padding to a block.
+  /// </summary>
   TZeroBytePadding = class sealed(TInterfacedObject, IZeroBytePadding,
   TZeroBytePadding = class sealed(TInterfacedObject, IZeroBytePadding,
     IBlockCipherPadding)
     IBlockCipherPadding)
 
 

+ 5 - 5
CryptoLib/src/Crypto/Prng/ClpDigestRandomGenerator.pas

@@ -22,8 +22,8 @@ unit ClpDigestRandomGenerator;
 interface
 interface
 
 
 uses
 uses
-  HlpIHash,
   SyncObjs,
   SyncObjs,
+  ClpIDigest,
   ClpConverters,
   ClpConverters,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
   ClpIDigestRandomGenerator,
   ClpIDigestRandomGenerator,
@@ -46,7 +46,7 @@ type
 
 
   var
   var
     FstateCounter, FseedCounter: Int64;
     FstateCounter, FseedCounter: Int64;
-    Fdigest: IHash;
+    Fdigest: IDigest;
     Fstate, Fseed: TCryptoLibByteArray;
     Fstate, Fseed: TCryptoLibByteArray;
 
 
     procedure CycleSeed(); inline;
     procedure CycleSeed(); inline;
@@ -64,7 +64,7 @@ type
 
 
   public
   public
 
 
-    constructor Create(const digest: IHash);
+    constructor Create(const digest: IDigest);
     procedure AddSeedMaterial(inSeed: TCryptoLibByteArray); overload; inline;
     procedure AddSeedMaterial(inSeed: TCryptoLibByteArray); overload; inline;
     procedure AddSeedMaterial(rSeed: Int64); overload; inline;
     procedure AddSeedMaterial(rSeed: Int64); overload; inline;
     procedure NextBytes(bytes: TCryptoLibByteArray); overload; inline;
     procedure NextBytes(bytes: TCryptoLibByteArray); overload; inline;
@@ -97,7 +97,7 @@ var
 begin
 begin
   digest := Fdigest.TransformFinal().GetBytes;
   digest := Fdigest.TransformFinal().GetBytes;
   System.Move(digest[0], value[0], System.Length(digest) * System.SizeOf(Byte));
   System.Move(digest[0], value[0], System.Length(digest) * System.SizeOf(Byte));
-  // value := Fdigest.TransformFinal().GetBytes;
+  // value := Fdigest.TransformFinal().GetBytes; // Review
 end;
 end;
 
 
 procedure TDigestRandomGenerator.AddSeedMaterial(rSeed: Int64);
 procedure TDigestRandomGenerator.AddSeedMaterial(rSeed: Int64);
@@ -124,7 +124,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-constructor TDigestRandomGenerator.Create(const digest: IHash);
+constructor TDigestRandomGenerator.Create(const digest: IDigest);
 begin
 begin
   Inherited Create();
   Inherited Create();
   Fdigest := digest;
   Fdigest := digest;

+ 4 - 4
CryptoLib/src/Crypto/Signers/ClpDsaDigestSigner.pas

@@ -24,9 +24,9 @@ interface
 uses
 uses
 
 
   SysUtils,
   SysUtils,
-  HlpIHash,
   ClpIDsa,
   ClpIDsa,
   ClpIAsn1Sequence,
   ClpIAsn1Sequence,
+  ClpIDigest,
   ClpIDerInteger,
   ClpIDerInteger,
   ClpDerSequence,
   ClpDerSequence,
   ClpDerInteger,
   ClpDerInteger,
@@ -52,7 +52,7 @@ type
 
 
   strict private
   strict private
   var
   var
-    Fdigest: IHash;
+    Fdigest: IDigest;
     FdsaSigner: IDsa;
     FdsaSigner: IDsa;
     FforSigning: Boolean;
     FforSigning: Boolean;
 
 
@@ -62,7 +62,7 @@ type
       : TCryptoLibGenericArray<TBigInteger>; inline;
       : TCryptoLibGenericArray<TBigInteger>; inline;
 
 
   public
   public
-    constructor Create(const signer: IDsa; const digest: IHash);
+    constructor Create(const signer: IDsa; const digest: IDigest);
 
 
     function GetAlgorithmName: String; virtual;
     function GetAlgorithmName: String; virtual;
     property AlgorithmName: String read GetAlgorithmName;
     property AlgorithmName: String read GetAlgorithmName;
@@ -110,7 +110,7 @@ begin
   Fdigest.TransformBytes(input, inOff, length);
   Fdigest.TransformBytes(input, inOff, length);
 end;
 end;
 
 
-constructor TDsaDigestSigner.Create(const signer: IDsa; const digest: IHash);
+constructor TDsaDigestSigner.Create(const signer: IDsa; const digest: IDigest);
 begin
 begin
   Inherited Create();
   Inherited Create();
   FdsaSigner := signer;
   FdsaSigner := signer;

+ 5 - 5
CryptoLib/src/Crypto/Signers/ClpECSchnorrSigner.pas

@@ -24,7 +24,7 @@ interface
 uses
 uses
   SysUtils,
   SysUtils,
   Classes,
   Classes,
-  HlpIHash,
+  ClpIDigest,
   ClpISigner,
   ClpISigner,
   ClpSecureRandom,
   ClpSecureRandom,
   ClpISecureRandom,
   ClpISecureRandom,
@@ -61,7 +61,7 @@ type
       FRandom: ISecureRandom;
       FRandom: ISecureRandom;
 
 
   var
   var
-    FDigest: IHash;
+    FDigest: IDigest;
     FVariant: String;
     FVariant: String;
     FforSigning: Boolean;
     FforSigning: Boolean;
     Fkey: IECKeyParameters;
     Fkey: IECKeyParameters;
@@ -180,12 +180,12 @@ type
     // 4. Signature is valid if the serialization of R's x coordinate equals r.
     // 4. Signature is valid if the serialization of R's x coordinate equals r.
 
 
     /// <param name="digest">
     /// <param name="digest">
-    /// initialized "IHash" instance.
+    /// initialized "IDigest" instance.
     /// </param>
     /// </param>
     /// <param name="schnorr_variant">
     /// <param name="schnorr_variant">
     /// one of "BSI","ISO","ISOx","LIBSECP"
     /// one of "BSI","ISO","ISOx","LIBSECP"
     /// </param>
     /// </param>
-    constructor Create(const digest: IHash; const schnorr_variant: String);
+    constructor Create(const digest: IDigest; const schnorr_variant: String);
     destructor Destroy(); override;
     destructor Destroy(); override;
 
 
     function GetAlgorithmName: String;
     function GetAlgorithmName: String;
@@ -260,7 +260,7 @@ begin
   FBuffer.Write(input[inOff], length);
   FBuffer.Write(input[inOff], length);
 end;
 end;
 
 
-constructor TECSchnorrSigner.Create(const digest: IHash;
+constructor TECSchnorrSigner.Create(const digest: IDigest;
   const schnorr_variant: String);
   const schnorr_variant: String);
 begin
 begin
   inherited Create();
   inherited Create();

+ 44 - 0
CryptoLib/src/Interfaces/ClpICfbBlockCipher.pas

@@ -0,0 +1,44 @@
+{ *********************************************************************************** }
+{ *                              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 ClpICfbBlockCipher;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipher;
+
+type
+  ICfbBlockCipher = interface(IBlockCipher)
+
+    ['{A58FD8F1-EECF-402F-9007-4E884FF7D325}']
+
+    /// <summary>
+    /// return the underlying block cipher that we are wrapping.
+    /// </summary>
+    /// <returns>
+    /// return the underlying block cipher that we are wrapping.
+    /// </returns>
+    function GetUnderlyingCipher(): IBlockCipher;
+
+  end;
+
+implementation
+
+end.

+ 57 - 0
CryptoLib/src/Interfaces/ClpICipherKeyGenerator.pas

@@ -0,0 +1,57 @@
+{ *********************************************************************************** }
+{ *                              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 ClpICipherKeyGenerator;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIKeyGenerationParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  ICipherKeyGenerator = interface(IInterface)
+    ['{084FE16F-7AEA-42C0-92BB-6CEC7923DE6F}']
+
+    /// <summary>
+    /// initialise the key generator.
+    /// </summary>
+    /// <param name="parameters">
+    /// the parameters to be used for key generation
+    /// </param>
+    procedure Init(const parameters: IKeyGenerationParameters);
+
+    /// <summary>
+    /// Generate a secret key.
+    /// </summary>
+    /// <returns>
+    /// a byte array containing the key value.
+    /// </returns>
+    function GenerateKey: TCryptoLibByteArray;
+
+    function GetdefaultStrength: Int32;
+
+    property defaultStrength: Int32 read GetdefaultStrength;
+
+  end;
+
+implementation
+
+end.

+ 3 - 3
CryptoLib/src/Interfaces/ClpIDerivationFunction.pas

@@ -22,7 +22,7 @@ unit ClpIDerivationFunction;
 interface
 interface
 
 
 uses
 uses
-  HlpIHash,
+  ClpIDigest,
   ClpIDerivationParameters,
   ClpIDerivationParameters,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
@@ -36,12 +36,12 @@ type
 
 
     procedure Init(const parameters: IDerivationParameters);
     procedure Init(const parameters: IDerivationParameters);
 
 
-    function GetDigest(): IHash;
+    function GetDigest(): IDigest;
 
 
     /// <value>
     /// <value>
     /// return the message digest used as the basis for the function
     /// return the message digest used as the basis for the function
     /// </value>
     /// </value>
-    property Digest: IHash read GetDigest;
+    property Digest: IDigest read GetDigest;
 
 
     /// <exception cref="EDataLengthCryptoLibException" />
     /// <exception cref="EDataLengthCryptoLibException" />
     /// <exception cref="EArgumentCryptoLibException" />
     /// <exception cref="EArgumentCryptoLibException" />

+ 36 - 0
CryptoLib/src/Interfaces/ClpIDigest.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 ClpIDigest;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  HlpIHash;
+
+type
+
+  IDigest = interface(IHash)
+    ['{4AF1A541-DABE-4F89-8E9E-26DB61097330}']
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
CryptoLib/src/Interfaces/ClpIDigestMAC.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 ClpIDigestMAC;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  HlpIHashInfo;
+
+type
+
+  IDigestMAC = interface(IHMAC)
+    ['{D6FC6D29-6624-4264-B527-BF13E3C6D452}']
+
+  end;
+
+implementation
+
+end.

+ 3 - 3
CryptoLib/src/Interfaces/ClpIIESEngine.pas

@@ -22,7 +22,7 @@ unit ClpIIESEngine;
 interface
 interface
 
 
 uses
 uses
-  HlpIHashInfo,
+  ClpIDigestMAC,
   ClpIBufferedBlockCipher,
   ClpIBufferedBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpIAsymmetricKeyParameter,
   ClpIAsymmetricKeyParameter,
@@ -36,7 +36,7 @@ type
     ['{9FA0E287-9988-467D-9E00-3BECEE4A78C6}']
     ['{9FA0E287-9988-467D-9E00-3BECEE4A78C6}']
 
 
     function GetCipher: IBufferedBlockCipher;
     function GetCipher: IBufferedBlockCipher;
-    function GetMac: IHMAC;
+    function GetMac: IDigestMAC;
 
 
     /// <summary>
     /// <summary>
     /// Initialise the encryptor/decryptor.
     /// Initialise the encryptor/decryptor.
@@ -95,7 +95,7 @@ type
       : TCryptoLibByteArray;
       : TCryptoLibByteArray;
 
 
     property cipher: IBufferedBlockCipher read GetCipher;
     property cipher: IBufferedBlockCipher read GetCipher;
-    property mac: IHMAC read GetMac;
+    property mac: IDigestMAC read GetMac;
   end;
   end;
 
 
 implementation
 implementation

+ 36 - 0
CryptoLib/src/Interfaces/ClpIISO10126d2Padding.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 ClpIISO10126d2Padding;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding;
+
+type
+  IISO10126d2Padding = interface(IBlockCipherPadding)
+
+    ['{42C927E4-57D2-4179-BEB0-250B7E2F7166}']
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
CryptoLib/src/Interfaces/ClpIISO7816d4Padding.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 ClpIISO7816d4Padding;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding;
+
+type
+  IISO7816d4Padding = interface(IBlockCipherPadding)
+
+    ['{0550BE74-BEDB-4723-9D31-F9E145C8C7AE}']
+
+  end;
+
+implementation
+
+end.

+ 44 - 0
CryptoLib/src/Interfaces/ClpIOfbBlockCipher.pas

@@ -0,0 +1,44 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIOfbBlockCipher;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipher;
+
+type
+  IOfbBlockCipher = interface(IBlockCipher)
+
+    ['{17D4977F-C9D8-466D-8E46-7E23A03471FC}']
+
+    /// <summary>
+    /// return the underlying block cipher that we are wrapping.
+    /// </summary>
+    /// <returns>
+    /// return the underlying block cipher that we are wrapping.
+    /// </returns>
+    function GetUnderlyingCipher(): IBlockCipher;
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
CryptoLib/src/Interfaces/ClpIPBKDF2_DigestMAC.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 ClpIPBKDF2_DigestMAC;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  HlpIHashInfo;
+
+type
+
+  IPBKDF2_DigestMAC = interface(IPBKDF2_HMAC)
+  ['{808DBBC9-4F6E-40D9-AE7F-001798637CE4}']
+
+  end;
+
+implementation
+
+end.

+ 3 - 3
CryptoLib/src/Interfaces/ClpIPascalCoinECIESKdfBytesGenerator.pas

@@ -22,7 +22,7 @@ unit ClpIPascalCoinECIESKdfBytesGenerator;
 interface
 interface
 
 
 uses
 uses
-  HlpIHash,
+  ClpIDigest,
   ClpIDerivationParameters,
   ClpIDerivationParameters,
   ClpIBaseKdfBytesGenerator,
   ClpIBaseKdfBytesGenerator,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
@@ -32,14 +32,14 @@ type
   IPascalCoinECIESKdfBytesGenerator = interface(IBaseKdfBytesGenerator)
   IPascalCoinECIESKdfBytesGenerator = interface(IBaseKdfBytesGenerator)
     ['{F6C7D34B-BA6A-45DB-B2A2-088F36557396}']
     ['{F6C7D34B-BA6A-45DB-B2A2-088F36557396}']
 
 
-    function GetDigest(): IHash;
+    function GetDigest(): IDigest;
 
 
     procedure Init(const parameters: IDerivationParameters);
     procedure Init(const parameters: IDerivationParameters);
 
 
     /// <summary>
     /// <summary>
     /// return the underlying digest.
     /// return the underlying digest.
     /// </summary>
     /// </summary>
-    property digest: IHash read GetDigest;
+    property digest: IDigest read GetDigest;
 
 
     /// <summary>
     /// <summary>
     /// fill len bytes of the output buffer with bytes generated from the
     /// fill len bytes of the output buffer with bytes generated from the

+ 44 - 0
CryptoLib/src/Interfaces/ClpISicBlockCipher.pas

@@ -0,0 +1,44 @@
+{ *********************************************************************************** }
+{ *                              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 ClpISicBlockCipher;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipher;
+
+type
+  ISicBlockCipher = interface(IBlockCipher)
+
+   ['{85CC4B84-8E49-40E1-B2F9-6C271C1FB5E7}']
+
+    /// <summary>
+    /// return the underlying block cipher that we are wrapping.
+    /// </summary>
+    /// <returns>
+    /// return the underlying block cipher that we are wrapping.
+    /// </returns>
+    function GetUnderlyingCipher(): IBlockCipher;
+
+  end;
+
+implementation
+
+end.

+ 65 - 0
CryptoLib/src/Interfaces/ClpIStreamCipher.pas

@@ -0,0 +1,65 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIStreamCipher;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpICipherParameters,
+  ClpCryptoLibTypes;
+
+type
+  /// <remarks>the interface stream ciphers conform to.</remarks>
+  IStreamCipher = interface(IInterface)
+   ['{A4366B7A-2BC4-4D92-AEF2-512B621CA746}']
+
+    /// <summary>The name of the algorithm this cipher implements.</summary>
+    function GetAlgorithmName: String;
+    property AlgorithmName: String read GetAlgorithmName;
+
+    /// <summary>Initialise the cipher.</summary>
+    /// <param name="forEncryption">Initialise for encryption if true, for decryption if false.</param>
+    /// <param name="parameters">The key or other data required by the cipher.</param>
+    procedure Init(forEncryption: Boolean; const parameters: ICipherParameters);
+
+    /// <summary>Indicates whether this cipher can handle partial blocks.</summary>
+    function GetIsPartialBlockOkay: Boolean;
+    property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
+
+    /// <summary>Process a block.</summary>
+    /// <param name="inBuf">The input buffer.</param>
+    /// <param name="inOff">The offset into <paramref>inBuf</paramref> that the input block begins.</param>
+    /// <param name="outBuf">The output buffer.</param>
+    /// <param name="outOff">The offset into <paramref>outBuf</paramref> to write the output block.</param>
+    /// <exception cref="DataLengthException">If input block is wrong size, or outBuf too small.</exception>
+    /// <returns>The number of bytes processed and produced.</returns>
+    function ProcessBlock(inBuf: TCryptoLibByteArray; inOff: Int32;
+      outBuf: TCryptoLibByteArray; outOff: Int32): Int32;
+
+    /// <summary>
+    /// Reset the cipher to the same state as it was after the last init (if there was one).
+    /// </summary>
+    procedure Reset();
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
CryptoLib/src/Interfaces/ClpITBCPadding.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 ClpITBCPadding;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding;
+
+type
+  ITBCPadding = interface(IBlockCipherPadding)
+
+    ['{D279C067-7DB6-406C-82CC-607DECD79F60}']
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
CryptoLib/src/Interfaces/ClpIX923Padding.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 ClpIX923Padding;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding;
+
+type
+  IX923Padding = interface(IBlockCipherPadding)
+
+    ['{8815D63C-936C-497F-9B00-29F6F9E178A7}']
+
+  end;
+
+implementation
+
+end.

+ 230 - 145
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk

@@ -19,13 +19,13 @@
         </Optimizations>
         </Optimizations>
       </CodeGeneration>
       </CodeGeneration>
     </CompilerOptions>
     </CompilerOptions>
-    <Description Value="CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying ECDSA and ECShnorr Signatures using various curves and hashes."/>
+    <Description Value="CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying ECDSA and ECShnorr Signatures using various curves and hashes, AES Encryption and Decryption (With various modes and paddings) and ECIES ."/>
     <License Value="MIT License                          
     <License Value="MIT License                          
 
 
  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="1" Minor="8"/>
-    <Files Count="339">
+    <Version Major="1" Minor="9"/>
+    <Files Count="360">
       <Item1>
       <Item1>
         <Filename Value="..\..\Asn1\ClpAsn1Encodable.pas"/>
         <Filename Value="..\..\Asn1\ClpAsn1Encodable.pas"/>
         <UnitName Value="ClpAsn1Encodable"/>
         <UnitName Value="ClpAsn1Encodable"/>
@@ -1099,289 +1099,374 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
         <UnitName Value="ClpStreamHelper"/>
         <UnitName Value="ClpStreamHelper"/>
       </Item268>
       </Item268>
       <Item269>
       <Item269>
-        <Filename Value="..\..\Utils\Helpers\ClpStringHelper.pas"/>
-        <UnitName Value="ClpStringHelper"/>
-      </Item269>
-      <Item270>
         <Filename Value="..\..\Utils\IO\ClpBaseInputStream.pas"/>
         <Filename Value="..\..\Utils\IO\ClpBaseInputStream.pas"/>
         <UnitName Value="ClpBaseInputStream"/>
         <UnitName Value="ClpBaseInputStream"/>
-      </Item270>
-      <Item271>
+      </Item269>
+      <Item270>
         <Filename Value="..\..\Utils\IO\ClpFilterStream.pas"/>
         <Filename Value="..\..\Utils\IO\ClpFilterStream.pas"/>
         <UnitName Value="ClpFilterStream"/>
         <UnitName Value="ClpFilterStream"/>
-      </Item271>
-      <Item272>
+      </Item270>
+      <Item271>
         <Filename Value="..\..\Utils\IO\ClpStreams.pas"/>
         <Filename Value="..\..\Utils\IO\ClpStreams.pas"/>
         <UnitName Value="ClpStreams"/>
         <UnitName Value="ClpStreams"/>
-      </Item272>
-      <Item273>
+      </Item271>
+      <Item272>
         <Filename Value="..\..\Utils\Randoms\ClpOSRandom.pas"/>
         <Filename Value="..\..\Utils\Randoms\ClpOSRandom.pas"/>
         <UnitName Value="ClpOSRandom"/>
         <UnitName Value="ClpOSRandom"/>
-      </Item273>
-      <Item274>
+      </Item272>
+      <Item273>
         <Filename Value="..\..\Utils\Randoms\ClpPcgRandomMinimal.pas"/>
         <Filename Value="..\..\Utils\Randoms\ClpPcgRandomMinimal.pas"/>
         <UnitName Value="ClpPcgRandomMinimal"/>
         <UnitName Value="ClpPcgRandomMinimal"/>
-      </Item274>
-      <Item275>
+      </Item273>
+      <Item274>
         <Filename Value="..\..\Utils\Rng\ClpOSRandomNumberGenerator.pas"/>
         <Filename Value="..\..\Utils\Rng\ClpOSRandomNumberGenerator.pas"/>
         <UnitName Value="ClpOSRandomNumberGenerator"/>
         <UnitName Value="ClpOSRandomNumberGenerator"/>
-      </Item275>
-      <Item276>
+      </Item274>
+      <Item275>
         <Filename Value="..\..\Utils\Rng\ClpPCGRandomNumberGenerator.pas"/>
         <Filename Value="..\..\Utils\Rng\ClpPCGRandomNumberGenerator.pas"/>
         <UnitName Value="ClpPCGRandomNumberGenerator"/>
         <UnitName Value="ClpPCGRandomNumberGenerator"/>
-      </Item276>
-      <Item277>
+      </Item275>
+      <Item276>
         <Filename Value="..\..\Utils\Rng\ClpRandomNumberGenerator.pas"/>
         <Filename Value="..\..\Utils\Rng\ClpRandomNumberGenerator.pas"/>
         <UnitName Value="ClpRandomNumberGenerator"/>
         <UnitName Value="ClpRandomNumberGenerator"/>
-      </Item277>
-      <Item278>
+      </Item276>
+      <Item277>
         <Filename Value="..\..\Utils\ClpSetWeakRef.pas"/>
         <Filename Value="..\..\Utils\ClpSetWeakRef.pas"/>
         <UnitName Value="ClpSetWeakRef"/>
         <UnitName Value="ClpSetWeakRef"/>
-      </Item278>
-      <Item279>
+      </Item277>
+      <Item278>
         <Filename Value="..\..\Asn1\ClpDefiniteLengthInputStream.pas"/>
         <Filename Value="..\..\Asn1\ClpDefiniteLengthInputStream.pas"/>
         <UnitName Value="ClpDefiniteLengthInputStream"/>
         <UnitName Value="ClpDefiniteLengthInputStream"/>
-      </Item279>
-      <Item280>
+      </Item278>
+      <Item279>
         <Filename Value="..\..\Crypto\Signers\ClpECSchnorrSigner.pas"/>
         <Filename Value="..\..\Crypto\Signers\ClpECSchnorrSigner.pas"/>
         <UnitName Value="ClpECSchnorrSigner"/>
         <UnitName Value="ClpECSchnorrSigner"/>
-      </Item280>
-      <Item281>
+      </Item279>
+      <Item280>
         <Filename Value="..\..\Interfaces\ClpIECSchnorrSigner.pas"/>
         <Filename Value="..\..\Interfaces\ClpIECSchnorrSigner.pas"/>
         <UnitName Value="ClpIECSchnorrSigner"/>
         <UnitName Value="ClpIECSchnorrSigner"/>
-      </Item281>
-      <Item282>
+      </Item280>
+      <Item281>
         <Filename Value="..\..\Security\ClpParameterUtilities.pas"/>
         <Filename Value="..\..\Security\ClpParameterUtilities.pas"/>
         <UnitName Value="ClpParameterUtilities"/>
         <UnitName Value="ClpParameterUtilities"/>
-      </Item282>
-      <Item283>
+      </Item281>
+      <Item282>
         <Filename Value="..\..\Security\ClpGeneratorUtilities.pas"/>
         <Filename Value="..\..\Security\ClpGeneratorUtilities.pas"/>
         <UnitName Value="ClpGeneratorUtilities"/>
         <UnitName Value="ClpGeneratorUtilities"/>
-      </Item283>
-      <Item284>
+      </Item282>
+      <Item283>
         <Filename Value="..\..\Security\ClpCipherUtilities.pas"/>
         <Filename Value="..\..\Security\ClpCipherUtilities.pas"/>
         <UnitName Value="ClpCipherUtilities"/>
         <UnitName Value="ClpCipherUtilities"/>
-      </Item284>
-      <Item285>
+      </Item283>
+      <Item284>
         <Filename Value="..\..\Interfaces\ClpIAesEngine.pas"/>
         <Filename Value="..\..\Interfaces\ClpIAesEngine.pas"/>
         <UnitName Value="ClpIAesEngine"/>
         <UnitName Value="ClpIAesEngine"/>
-      </Item285>
-      <Item286>
+      </Item284>
+      <Item285>
         <Filename Value="..\..\Interfaces\ClpIPkcs7Padding.pas"/>
         <Filename Value="..\..\Interfaces\ClpIPkcs7Padding.pas"/>
         <UnitName Value="ClpIPkcs7Padding"/>
         <UnitName Value="ClpIPkcs7Padding"/>
-      </Item286>
-      <Item287>
+      </Item285>
+      <Item286>
         <Filename Value="..\..\Interfaces\ClpIParametersWithIV.pas"/>
         <Filename Value="..\..\Interfaces\ClpIParametersWithIV.pas"/>
         <UnitName Value="ClpIParametersWithIV"/>
         <UnitName Value="ClpIParametersWithIV"/>
-      </Item287>
-      <Item288>
+      </Item286>
+      <Item287>
         <Filename Value="..\..\Interfaces\ClpIPaddedBufferedBlockCipher.pas"/>
         <Filename Value="..\..\Interfaces\ClpIPaddedBufferedBlockCipher.pas"/>
         <UnitName Value="ClpIPaddedBufferedBlockCipher"/>
         <UnitName Value="ClpIPaddedBufferedBlockCipher"/>
-      </Item288>
-      <Item289>
+      </Item287>
+      <Item288>
         <Filename Value="..\..\Interfaces\ClpIKeyParameter.pas"/>
         <Filename Value="..\..\Interfaces\ClpIKeyParameter.pas"/>
         <UnitName Value="ClpIKeyParameter"/>
         <UnitName Value="ClpIKeyParameter"/>
-      </Item289>
-      <Item290>
+      </Item288>
+      <Item289>
         <Filename Value="..\..\Interfaces\ClpICbcBlockCipher.pas"/>
         <Filename Value="..\..\Interfaces\ClpICbcBlockCipher.pas"/>
         <UnitName Value="ClpICbcBlockCipher"/>
         <UnitName Value="ClpICbcBlockCipher"/>
-      </Item290>
-      <Item291>
+      </Item289>
+      <Item290>
         <Filename Value="..\..\Interfaces\ClpIBufferedCipherBase.pas"/>
         <Filename Value="..\..\Interfaces\ClpIBufferedCipherBase.pas"/>
         <UnitName Value="ClpIBufferedCipherBase"/>
         <UnitName Value="ClpIBufferedCipherBase"/>
-      </Item291>
-      <Item292>
+      </Item290>
+      <Item291>
         <Filename Value="..\..\Interfaces\ClpIBufferedCipher.pas"/>
         <Filename Value="..\..\Interfaces\ClpIBufferedCipher.pas"/>
         <UnitName Value="ClpIBufferedCipher"/>
         <UnitName Value="ClpIBufferedCipher"/>
-      </Item292>
-      <Item293>
+      </Item291>
+      <Item292>
         <Filename Value="..\..\Interfaces\ClpIBufferedBlockCipher.pas"/>
         <Filename Value="..\..\Interfaces\ClpIBufferedBlockCipher.pas"/>
         <UnitName Value="ClpIBufferedBlockCipher"/>
         <UnitName Value="ClpIBufferedBlockCipher"/>
-      </Item293>
-      <Item294>
+      </Item292>
+      <Item293>
         <Filename Value="..\..\Interfaces\ClpIBlockCipherPadding.pas"/>
         <Filename Value="..\..\Interfaces\ClpIBlockCipherPadding.pas"/>
         <UnitName Value="ClpIBlockCipherPadding"/>
         <UnitName Value="ClpIBlockCipherPadding"/>
-      </Item294>
-      <Item295>
+      </Item293>
+      <Item294>
         <Filename Value="..\..\Interfaces\ClpIBlockCipher.pas"/>
         <Filename Value="..\..\Interfaces\ClpIBlockCipher.pas"/>
         <UnitName Value="ClpIBlockCipher"/>
         <UnitName Value="ClpIBlockCipher"/>
-      </Item295>
-      <Item296>
+      </Item294>
+      <Item295>
         <Filename Value="..\..\Crypto\Modes\ClpCbcBlockCipher.pas"/>
         <Filename Value="..\..\Crypto\Modes\ClpCbcBlockCipher.pas"/>
         <UnitName Value="ClpCbcBlockCipher"/>
         <UnitName Value="ClpCbcBlockCipher"/>
-      </Item296>
-      <Item297>
+      </Item295>
+      <Item296>
         <Filename Value="..\..\Crypto\Paddings\ClpPaddedBufferedBlockCipher.pas"/>
         <Filename Value="..\..\Crypto\Paddings\ClpPaddedBufferedBlockCipher.pas"/>
         <UnitName Value="ClpPaddedBufferedBlockCipher"/>
         <UnitName Value="ClpPaddedBufferedBlockCipher"/>
-      </Item297>
-      <Item298>
+      </Item296>
+      <Item297>
         <Filename Value="..\..\Crypto\Paddings\ClpPkcs7Padding.pas"/>
         <Filename Value="..\..\Crypto\Paddings\ClpPkcs7Padding.pas"/>
         <UnitName Value="ClpPkcs7Padding"/>
         <UnitName Value="ClpPkcs7Padding"/>
-      </Item298>
-      <Item299>
+      </Item297>
+      <Item298>
         <Filename Value="..\..\Crypto\Parameters\ClpParametersWithIV.pas"/>
         <Filename Value="..\..\Crypto\Parameters\ClpParametersWithIV.pas"/>
         <UnitName Value="ClpParametersWithIV"/>
         <UnitName Value="ClpParametersWithIV"/>
-      </Item299>
-      <Item300>
+      </Item298>
+      <Item299>
         <Filename Value="..\..\Crypto\Parameters\ClpKeyParameter.pas"/>
         <Filename Value="..\..\Crypto\Parameters\ClpKeyParameter.pas"/>
         <UnitName Value="ClpKeyParameter"/>
         <UnitName Value="ClpKeyParameter"/>
-      </Item300>
-      <Item301>
+      </Item299>
+      <Item300>
         <Filename Value="..\..\Crypto\ClpBufferedBlockCipher.pas"/>
         <Filename Value="..\..\Crypto\ClpBufferedBlockCipher.pas"/>
         <UnitName Value="ClpBufferedBlockCipher"/>
         <UnitName Value="ClpBufferedBlockCipher"/>
-      </Item301>
-      <Item302>
+      </Item300>
+      <Item301>
         <Filename Value="..\..\Crypto\ClpBufferedCipherBase.pas"/>
         <Filename Value="..\..\Crypto\ClpBufferedCipherBase.pas"/>
         <UnitName Value="ClpBufferedCipherBase"/>
         <UnitName Value="ClpBufferedCipherBase"/>
-      </Item302>
-      <Item303>
+      </Item301>
+      <Item302>
         <Filename Value="..\..\Utils\ClpCheck.pas"/>
         <Filename Value="..\..\Utils\ClpCheck.pas"/>
         <UnitName Value="ClpCheck"/>
         <UnitName Value="ClpCheck"/>
-      </Item303>
-      <Item304>
+      </Item302>
+      <Item303>
         <Filename Value="..\..\Crypto\Engines\ClpAesEngine.pas"/>
         <Filename Value="..\..\Crypto\Engines\ClpAesEngine.pas"/>
         <UnitName Value="ClpAesEngine"/>
         <UnitName Value="ClpAesEngine"/>
-      </Item304>
-      <Item305>
+      </Item303>
+      <Item304>
         <Filename Value="..\..\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas"/>
         <Filename Value="..\..\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas"/>
         <UnitName Value="ClpPascalCoinECIESKdfBytesGenerator"/>
         <UnitName Value="ClpPascalCoinECIESKdfBytesGenerator"/>
-      </Item305>
-      <Item306>
+      </Item304>
+      <Item305>
         <Filename Value="..\..\Crypto\Engines\ClpPascalCoinIESEngine.pas"/>
         <Filename Value="..\..\Crypto\Engines\ClpPascalCoinIESEngine.pas"/>
         <UnitName Value="ClpPascalCoinIESEngine"/>
         <UnitName Value="ClpPascalCoinIESEngine"/>
-      </Item306>
-      <Item307>
+      </Item305>
+      <Item306>
         <Filename Value="..\..\Crypto\Generators\ClpBaseKdfBytesGenerator.pas"/>
         <Filename Value="..\..\Crypto\Generators\ClpBaseKdfBytesGenerator.pas"/>
         <UnitName Value="ClpBaseKdfBytesGenerator"/>
         <UnitName Value="ClpBaseKdfBytesGenerator"/>
-      </Item307>
-      <Item308>
+      </Item306>
+      <Item307>
         <Filename Value="..\..\Crypto\Engines\ClpIESEngine.pas"/>
         <Filename Value="..\..\Crypto\Engines\ClpIESEngine.pas"/>
         <UnitName Value="ClpIESEngine"/>
         <UnitName Value="ClpIESEngine"/>
-      </Item308>
-      <Item309>
+      </Item307>
+      <Item308>
         <Filename Value="..\..\Crypto\Parsers\ClpECIESPublicKeyParser.pas"/>
         <Filename Value="..\..\Crypto\Parsers\ClpECIESPublicKeyParser.pas"/>
         <UnitName Value="ClpECIESPublicKeyParser"/>
         <UnitName Value="ClpECIESPublicKeyParser"/>
-      </Item309>
-      <Item310>
+      </Item308>
+      <Item309>
         <Filename Value="..\..\Crypto\ClpIESCipher.pas"/>
         <Filename Value="..\..\Crypto\ClpIESCipher.pas"/>
         <UnitName Value="ClpIESCipher"/>
         <UnitName Value="ClpIESCipher"/>
-      </Item310>
-      <Item311>
+      </Item309>
+      <Item310>
         <Filename Value="..\..\Crypto\Agreement\ClpECDHBasicAgreement.pas"/>
         <Filename Value="..\..\Crypto\Agreement\ClpECDHBasicAgreement.pas"/>
         <UnitName Value="ClpECDHBasicAgreement"/>
         <UnitName Value="ClpECDHBasicAgreement"/>
-      </Item311>
-      <Item312>
+      </Item310>
+      <Item311>
         <Filename Value="..\..\Crypto\ClpEphemeralKeyPair.pas"/>
         <Filename Value="..\..\Crypto\ClpEphemeralKeyPair.pas"/>
         <UnitName Value="ClpEphemeralKeyPair"/>
         <UnitName Value="ClpEphemeralKeyPair"/>
-      </Item312>
-      <Item313>
+      </Item311>
+      <Item312>
         <Filename Value="..\..\Crypto\ClpKeyEncoder.pas"/>
         <Filename Value="..\..\Crypto\ClpKeyEncoder.pas"/>
         <UnitName Value="ClpKeyEncoder"/>
         <UnitName Value="ClpKeyEncoder"/>
-      </Item313>
-      <Item314>
+      </Item312>
+      <Item313>
         <Filename Value="..\..\Crypto\Paddings\ClpZeroBytePadding.pas"/>
         <Filename Value="..\..\Crypto\Paddings\ClpZeroBytePadding.pas"/>
         <UnitName Value="ClpZeroBytePadding"/>
         <UnitName Value="ClpZeroBytePadding"/>
-      </Item314>
-      <Item315>
+      </Item313>
+      <Item314>
         <Filename Value="..\..\Crypto\Parameters\ClpIesWithCipherParameters.pas"/>
         <Filename Value="..\..\Crypto\Parameters\ClpIesWithCipherParameters.pas"/>
         <UnitName Value="ClpIESWithCipherParameters"/>
         <UnitName Value="ClpIESWithCipherParameters"/>
-      </Item315>
-      <Item316>
+      </Item314>
+      <Item315>
         <Filename Value="..\..\Crypto\Parameters\ClpIesParameters.pas"/>
         <Filename Value="..\..\Crypto\Parameters\ClpIesParameters.pas"/>
         <UnitName Value="ClpIESParameters"/>
         <UnitName Value="ClpIESParameters"/>
-      </Item316>
-      <Item317>
+      </Item315>
+      <Item316>
         <Filename Value="..\..\Crypto\Generators\ClpEphemeralKeyPairGenerator.pas"/>
         <Filename Value="..\..\Crypto\Generators\ClpEphemeralKeyPairGenerator.pas"/>
         <UnitName Value="ClpEphemeralKeyPairGenerator"/>
         <UnitName Value="ClpEphemeralKeyPairGenerator"/>
-      </Item317>
-      <Item318>
+      </Item316>
+      <Item317>
         <Filename Value="..\..\Crypto\Generators\ClpKdf2BytesGenerator.pas"/>
         <Filename Value="..\..\Crypto\Generators\ClpKdf2BytesGenerator.pas"/>
         <UnitName Value="ClpKdf2BytesGenerator"/>
         <UnitName Value="ClpKdf2BytesGenerator"/>
-      </Item318>
-      <Item319>
+      </Item317>
+      <Item318>
         <Filename Value="..\..\Crypto\Parameters\ClpIso18033KdfParameters.pas"/>
         <Filename Value="..\..\Crypto\Parameters\ClpIso18033KdfParameters.pas"/>
         <UnitName Value="ClpIso18033KdfParameters"/>
         <UnitName Value="ClpIso18033KdfParameters"/>
-      </Item319>
-      <Item320>
+      </Item318>
+      <Item319>
         <Filename Value="..\..\Crypto\Parameters\ClpKdfParameters.pas"/>
         <Filename Value="..\..\Crypto\Parameters\ClpKdfParameters.pas"/>
         <UnitName Value="ClpKdfParameters"/>
         <UnitName Value="ClpKdfParameters"/>
-      </Item320>
-      <Item321>
+      </Item319>
+      <Item320>
         <Filename Value="..\..\Interfaces\ClpIIesWithCipherParameters.pas"/>
         <Filename Value="..\..\Interfaces\ClpIIesWithCipherParameters.pas"/>
         <UnitName Value="ClpIIESWithCipherParameters"/>
         <UnitName Value="ClpIIESWithCipherParameters"/>
-      </Item321>
-      <Item322>
+      </Item320>
+      <Item321>
         <Filename Value="..\..\Interfaces\ClpIIesParameters.pas"/>
         <Filename Value="..\..\Interfaces\ClpIIesParameters.pas"/>
         <UnitName Value="ClpIIESParameters"/>
         <UnitName Value="ClpIIESParameters"/>
-      </Item322>
-      <Item323>
+      </Item321>
+      <Item322>
         <Filename Value="..\..\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas"/>
         <Filename Value="..\..\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas"/>
         <UnitName Value="ClpIPascalCoinECIESKdfBytesGenerator"/>
         <UnitName Value="ClpIPascalCoinECIESKdfBytesGenerator"/>
-      </Item323>
-      <Item324>
+      </Item322>
+      <Item323>
         <Filename Value="..\..\Interfaces\ClpIPascalCoinIESEngine.pas"/>
         <Filename Value="..\..\Interfaces\ClpIPascalCoinIESEngine.pas"/>
         <UnitName Value="ClpIPascalCoinIESEngine"/>
         <UnitName Value="ClpIPascalCoinIESEngine"/>
-      </Item324>
-      <Item325>
+      </Item323>
+      <Item324>
         <Filename Value="..\..\Interfaces\ClpIIESEngine.pas"/>
         <Filename Value="..\..\Interfaces\ClpIIESEngine.pas"/>
         <UnitName Value="ClpIIESEngine"/>
         <UnitName Value="ClpIIESEngine"/>
-      </Item325>
-      <Item326>
+      </Item324>
+      <Item325>
         <Filename Value="..\..\Interfaces\ClpIIESCipher.pas"/>
         <Filename Value="..\..\Interfaces\ClpIIESCipher.pas"/>
         <UnitName Value="ClpIIESCipher"/>
         <UnitName Value="ClpIIESCipher"/>
-      </Item326>
-      <Item327>
+      </Item325>
+      <Item326>
         <Filename Value="..\..\Interfaces\ClpIZeroBytePadding.pas"/>
         <Filename Value="..\..\Interfaces\ClpIZeroBytePadding.pas"/>
         <UnitName Value="ClpIZeroBytePadding"/>
         <UnitName Value="ClpIZeroBytePadding"/>
-      </Item327>
-      <Item328>
+      </Item326>
+      <Item327>
         <Filename Value="..\..\Interfaces\ClpIECIESPublicKeyParser.pas"/>
         <Filename Value="..\..\Interfaces\ClpIECIESPublicKeyParser.pas"/>
         <UnitName Value="ClpIECIESPublicKeyParser"/>
         <UnitName Value="ClpIECIESPublicKeyParser"/>
-      </Item328>
-      <Item329>
+      </Item327>
+      <Item328>
         <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPairGenerator.pas"/>
         <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPairGenerator.pas"/>
         <UnitName Value="ClpIEphemeralKeyPairGenerator"/>
         <UnitName Value="ClpIEphemeralKeyPairGenerator"/>
-      </Item329>
-      <Item330>
+      </Item328>
+      <Item329>
         <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPair.pas"/>
         <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPair.pas"/>
         <UnitName Value="ClpIEphemeralKeyPair"/>
         <UnitName Value="ClpIEphemeralKeyPair"/>
-      </Item330>
-      <Item331>
+      </Item329>
+      <Item330>
         <Filename Value="..\..\Interfaces\ClpIKeyParser.pas"/>
         <Filename Value="..\..\Interfaces\ClpIKeyParser.pas"/>
         <UnitName Value="ClpIKeyParser"/>
         <UnitName Value="ClpIKeyParser"/>
-      </Item331>
-      <Item332>
+      </Item330>
+      <Item331>
         <Filename Value="..\..\Interfaces\ClpIKdf2BytesGenerator.pas"/>
         <Filename Value="..\..\Interfaces\ClpIKdf2BytesGenerator.pas"/>
         <UnitName Value="ClpIKdf2BytesGenerator"/>
         <UnitName Value="ClpIKdf2BytesGenerator"/>
-      </Item332>
-      <Item333>
+      </Item331>
+      <Item332>
         <Filename Value="..\..\Interfaces\ClpIBaseKdfBytesGenerator.pas"/>
         <Filename Value="..\..\Interfaces\ClpIBaseKdfBytesGenerator.pas"/>
         <UnitName Value="ClpIBaseKdfBytesGenerator"/>
         <UnitName Value="ClpIBaseKdfBytesGenerator"/>
-      </Item333>
-      <Item334>
+      </Item332>
+      <Item333>
         <Filename Value="..\..\Interfaces\ClpIIso18033KdfParameters.pas"/>
         <Filename Value="..\..\Interfaces\ClpIIso18033KdfParameters.pas"/>
         <UnitName Value="ClpIIso18033KdfParameters"/>
         <UnitName Value="ClpIIso18033KdfParameters"/>
-      </Item334>
-      <Item335>
+      </Item333>
+      <Item334>
         <Filename Value="..\..\Interfaces\ClpIKdfParameters.pas"/>
         <Filename Value="..\..\Interfaces\ClpIKdfParameters.pas"/>
         <UnitName Value="ClpIKdfParameters"/>
         <UnitName Value="ClpIKdfParameters"/>
-      </Item335>
-      <Item336>
+      </Item334>
+      <Item335>
         <Filename Value="..\..\Interfaces\ClpIDerivationFunction.pas"/>
         <Filename Value="..\..\Interfaces\ClpIDerivationFunction.pas"/>
         <UnitName Value="ClpIDerivationFunction"/>
         <UnitName Value="ClpIDerivationFunction"/>
-      </Item336>
-      <Item337>
+      </Item335>
+      <Item336>
         <Filename Value="..\..\Interfaces\ClpIDerivationParameters.pas"/>
         <Filename Value="..\..\Interfaces\ClpIDerivationParameters.pas"/>
         <UnitName Value="ClpIDerivationParameters"/>
         <UnitName Value="ClpIDerivationParameters"/>
-      </Item337>
-      <Item338>
+      </Item336>
+      <Item337>
         <Filename Value="..\..\Interfaces\ClpIECDHBasicAgreement.pas"/>
         <Filename Value="..\..\Interfaces\ClpIECDHBasicAgreement.pas"/>
         <UnitName Value="ClpIECDHBasicAgreement"/>
         <UnitName Value="ClpIECDHBasicAgreement"/>
-      </Item338>
-      <Item339>
+      </Item337>
+      <Item338>
         <Filename Value="..\..\Interfaces\ClpIBasicAgreement.pas"/>
         <Filename Value="..\..\Interfaces\ClpIBasicAgreement.pas"/>
         <UnitName Value="ClpIBasicAgreement"/>
         <UnitName Value="ClpIBasicAgreement"/>
+      </Item338>
+      <Item339>
+        <Filename Value="..\..\Crypto\Modes\ClpSicBlockCipher.pas"/>
+        <UnitName Value="ClpSicBlockCipher"/>
       </Item339>
       </Item339>
+      <Item340>
+        <Filename Value="..\..\Crypto\Modes\ClpCfbBlockCipher.pas"/>
+        <UnitName Value="ClpCfbBlockCipher"/>
+      </Item340>
+      <Item341>
+        <Filename Value="..\..\Crypto\Generators\ClpCipherKeyGenerator.pas"/>
+        <UnitName Value="ClpCipherKeyGenerator"/>
+      </Item341>
+      <Item342>
+        <Filename Value="..\..\Utils\ClpStringUtils.pas"/>
+        <UnitName Value="ClpStringUtils"/>
+      </Item342>
+      <Item343>
+        <Filename Value="..\..\Interfaces\ClpICipherKeyGenerator.pas"/>
+        <UnitName Value="ClpICipherKeyGenerator"/>
+      </Item343>
+      <Item344>
+        <Filename Value="..\..\Interfaces\ClpIPBKDF2_DigestMAC.pas"/>
+        <UnitName Value="ClpIPBKDF2_DigestMAC"/>
+      </Item344>
+      <Item345>
+        <Filename Value="..\..\Interfaces\ClpIDigestMAC.pas"/>
+        <UnitName Value="ClpIDigestMAC"/>
+      </Item345>
+      <Item346>
+        <Filename Value="..\..\Interfaces\ClpIDigest.pas"/>
+        <UnitName Value="ClpIDigest"/>
+      </Item346>
+      <Item347>
+        <Filename Value="..\..\Interfaces\ClpISicBlockCipher.pas"/>
+        <UnitName Value="ClpISicBlockCipher"/>
+      </Item347>
+      <Item348>
+        <Filename Value="..\..\Interfaces\ClpIStreamCipher.pas"/>
+        <UnitName Value="ClpIStreamCipher"/>
+      </Item348>
+      <Item349>
+        <Filename Value="..\..\Crypto\Modes\ClpOfbBlockCipher.pas"/>
+        <UnitName Value="ClpOfbBlockCipher"/>
+      </Item349>
+      <Item350>
+        <Filename Value="..\..\Interfaces\ClpIOfbBlockCipher.pas"/>
+        <UnitName Value="ClpIOfbBlockCipher"/>
+      </Item350>
+      <Item351>
+        <Filename Value="..\..\Interfaces\ClpICfbBlockCipher.pas"/>
+        <UnitName Value="ClpICfbBlockCipher"/>
+      </Item351>
+      <Item352>
+        <Filename Value="..\..\Crypto\Paddings\ClpX923Padding.pas"/>
+        <UnitName Value="ClpX923Padding"/>
+      </Item352>
+      <Item353>
+        <Filename Value="..\..\Interfaces\ClpIX923Padding.pas"/>
+        <UnitName Value="ClpIX923Padding"/>
+      </Item353>
+      <Item354>
+        <Filename Value="..\..\Crypto\Paddings\ClpTTBCPadding.pas"/>
+        <UnitName Value="ClpTTBCPadding"/>
+      </Item354>
+      <Item355>
+        <Filename Value="..\..\Crypto\Paddings\ClpISO7816d4Padding.pas"/>
+        <UnitName Value="ClpISO7816d4Padding"/>
+      </Item355>
+      <Item356>
+        <Filename Value="..\..\Interfaces\ClpITBCPadding.pas"/>
+        <UnitName Value="ClpITBCPadding"/>
+      </Item356>
+      <Item357>
+        <Filename Value="..\..\Interfaces\ClpIISO7816d4Padding.pas"/>
+        <UnitName Value="ClpIISO7816d4Padding"/>
+      </Item357>
+      <Item358>
+        <Filename Value="..\..\Crypto\Paddings\ClpISO10126d2Padding.pas"/>
+        <UnitName Value="ClpISO10126d2Padding"/>
+      </Item358>
+      <Item359>
+        <Filename Value="..\..\Interfaces\ClpIISO10126d2Padding.pas"/>
+        <UnitName Value="ClpIISO10126d2Padding"/>
+      </Item359>
+      <Item360>
+        <Filename Value="CryptoLib4PascalPackage.pas"/>
+        <AddToUsesPkgSection Value="False"/>
+        <UnitName Value="CryptoLib4PascalPackage"/>
+      </Item360>
     </Files>
     </Files>
     <RequiredPkgs Count="3">
     <RequiredPkgs Count="3">
       <Item1>
       <Item1>

+ 19 - 14
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas

@@ -90,19 +90,18 @@ uses
   ClpNat, ClpDigestUtilities, ClpRandom, ClpSecureRandom, ClpSignerUtilities, 
   ClpNat, ClpDigestUtilities, ClpRandom, ClpSecureRandom, ClpSignerUtilities, 
   ClpArrayUtils, ClpBigIntegers, ClpBitConverter, ClpBits, ClpConverters, 
   ClpArrayUtils, ClpBigIntegers, ClpBitConverter, ClpBits, ClpConverters, 
   ClpCryptoLibTypes, ClpStreamSorter, ClpTimes, ClpCollectionUtilities, 
   ClpCryptoLibTypes, ClpStreamSorter, ClpTimes, ClpCollectionUtilities, 
-  ClpBase64, ClpHex, ClpStreamHelper, ClpStringHelper, ClpBaseInputStream, 
-  ClpFilterStream, ClpStreams, ClpOSRandom, ClpPcgRandomMinimal, 
-  ClpOSRandomNumberGenerator, ClpPCGRandomNumberGenerator, 
-  ClpRandomNumberGenerator, ClpSetWeakRef, ClpDefiniteLengthInputStream, 
-  ClpECSchnorrSigner, ClpIECSchnorrSigner, ClpParameterUtilities, 
-  ClpGeneratorUtilities, ClpCipherUtilities, ClpIAesEngine, ClpIPkcs7Padding, 
-  ClpIParametersWithIV, ClpIPaddedBufferedBlockCipher, ClpIKeyParameter, 
-  ClpICbcBlockCipher, ClpIBufferedCipherBase, ClpIBufferedCipher, 
-  ClpIBufferedBlockCipher, ClpIBlockCipherPadding, ClpIBlockCipher, 
-  ClpCbcBlockCipher, ClpPaddedBufferedBlockCipher, ClpPkcs7Padding, 
-  ClpParametersWithIV, ClpKeyParameter, ClpBufferedBlockCipher, 
-  ClpBufferedCipherBase, ClpCheck, ClpAesEngine, 
-  ClpPascalCoinECIESKdfBytesGenerator, ClpPascalCoinIESEngine, 
+  ClpBase64, ClpHex, ClpStreamHelper, ClpBaseInputStream, ClpFilterStream, 
+  ClpStreams, ClpOSRandom, ClpPcgRandomMinimal, ClpOSRandomNumberGenerator, 
+  ClpPCGRandomNumberGenerator, ClpRandomNumberGenerator, ClpSetWeakRef, 
+  ClpDefiniteLengthInputStream, ClpECSchnorrSigner, ClpIECSchnorrSigner, 
+  ClpParameterUtilities, ClpGeneratorUtilities, ClpCipherUtilities, 
+  ClpIAesEngine, ClpIPkcs7Padding, ClpIParametersWithIV, 
+  ClpIPaddedBufferedBlockCipher, ClpIKeyParameter, ClpICbcBlockCipher, 
+  ClpIBufferedCipherBase, ClpIBufferedCipher, ClpIBufferedBlockCipher, 
+  ClpIBlockCipherPadding, ClpIBlockCipher, ClpCbcBlockCipher, 
+  ClpPaddedBufferedBlockCipher, ClpPkcs7Padding, ClpParametersWithIV, 
+  ClpKeyParameter, ClpBufferedBlockCipher, ClpBufferedCipherBase, ClpCheck, 
+  ClpAesEngine, ClpPascalCoinECIESKdfBytesGenerator, ClpPascalCoinIESEngine, 
   ClpBaseKdfBytesGenerator, ClpIESEngine, ClpECIESPublicKeyParser, 
   ClpBaseKdfBytesGenerator, ClpIESEngine, ClpECIESPublicKeyParser, 
   ClpIESCipher, ClpECDHBasicAgreement, ClpEphemeralKeyPair, ClpKeyEncoder, 
   ClpIESCipher, ClpECDHBasicAgreement, ClpEphemeralKeyPair, ClpKeyEncoder, 
   ClpZeroBytePadding, ClpIesWithCipherParameters, ClpIesParameters, 
   ClpZeroBytePadding, ClpIesWithCipherParameters, ClpIesParameters, 
@@ -114,7 +113,13 @@ uses
   ClpIEphemeralKeyPair, ClpIKeyParser, ClpIKdf2BytesGenerator, 
   ClpIEphemeralKeyPair, ClpIKeyParser, ClpIKdf2BytesGenerator, 
   ClpIBaseKdfBytesGenerator, ClpIIso18033KdfParameters, ClpIKdfParameters, 
   ClpIBaseKdfBytesGenerator, ClpIIso18033KdfParameters, ClpIKdfParameters, 
   ClpIDerivationFunction, ClpIDerivationParameters, ClpIECDHBasicAgreement, 
   ClpIDerivationFunction, ClpIDerivationParameters, ClpIECDHBasicAgreement, 
-  ClpIBasicAgreement;
+  ClpIBasicAgreement, ClpSicBlockCipher, ClpCfbBlockCipher, 
+  ClpCipherKeyGenerator, ClpStringUtils, ClpICipherKeyGenerator, 
+  ClpIPBKDF2_DigestMAC, ClpIDigestMAC, ClpIDigest, ClpISicBlockCipher, 
+  ClpIStreamCipher, ClpOfbBlockCipher, ClpIOfbBlockCipher, ClpICfbBlockCipher, 
+  ClpX923Padding, ClpIX923Padding, ClpTTBCPadding, ClpISO7816d4Padding, 
+  ClpITBCPadding, ClpIISO7816d4Padding, ClpISO10126d2Padding, 
+  ClpIISO10126d2Padding;
 
 
 implementation
 implementation
 
 

+ 124 - 7
CryptoLib/src/Security/ClpCipherUtilities.pas

@@ -26,13 +26,27 @@ uses
   TypInfo,
   TypInfo,
   Generics.Collections,
   Generics.Collections,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
-  ClpStringHelper,
+  ClpStringUtils,
   ClpPkcs7Padding,
   ClpPkcs7Padding,
   ClpIPkcs7Padding,
   ClpIPkcs7Padding,
+  ClpISO10126d2Padding,
+  ClpIISO10126d2Padding,
+  ClpISO7816d4Padding,
+  ClpIISO7816d4Padding,
+  ClpX923Padding,
+  ClpIX923Padding,
   ClpZeroBytePadding,
   ClpZeroBytePadding,
   ClpIZeroBytePadding,
   ClpIZeroBytePadding,
+  ClpTTBCPadding,
+  ClpITBCPadding,
   ClpCbcBlockCipher,
   ClpCbcBlockCipher,
   ClpICbcBlockCipher,
   ClpICbcBlockCipher,
+  ClpCfbBlockCipher,
+  ClpICfbBlockCipher,
+  ClpOfbBlockCipher,
+  ClpIOfbBlockCipher,
+  ClpSicBlockCipher,
+  ClpISicBlockCipher,
   ClpBufferedBlockCipher,
   ClpBufferedBlockCipher,
   ClpIBufferedBlockCipher,
   ClpIBufferedBlockCipher,
   ClpPaddedBufferedBlockCipher,
   ClpPaddedBufferedBlockCipher,
@@ -49,6 +63,8 @@ resourcestring
   SMechanismNil = 'Mechanism Cannot be Nil';
   SMechanismNil = 'Mechanism Cannot be Nil';
   SAlgorithmNil = 'Algorithm Cannot be Nil';
   SAlgorithmNil = 'Algorithm Cannot be Nil';
   SUnRecognizedCipher = '"Cipher " %s Not Recognised.';
   SUnRecognizedCipher = '"Cipher " %s Not Recognised.';
+  SSICModeWarning =
+    'Warning: SIC-Mode Can Become a TwoTime-Pad if the Blocksize of the Cipher is Too Small. Use a Cipher With a Block Size of at Least 128 bits (e.g. AES)';
 
 
 type
 type
 
 
@@ -62,8 +78,10 @@ type
   type
   type
 {$SCOPEDENUMS ON}
 {$SCOPEDENUMS ON}
     TCipherAlgorithm = (AES);
     TCipherAlgorithm = (AES);
-    TCipherMode = (NONE, CBC);
-    TCipherPadding = (NOPADDING, PKCS5, PKCS5PADDING, PKCS7, PKCS7PADDING,
+    TCipherMode = (NONE, CBC, CFB, CTR, ECB, OFB, SIC);
+    TCipherPadding = (NOPADDING, ISO10126PADDING, ISO10126D2PADDING,
+      ISO10126_2PADDING, ISO7816_4PADDING, ISO9797_1PADDING, PKCS5,
+      PKCS5PADDING, PKCS7, PKCS7PADDING, TBCPADDING, X923PADDING,
       ZEROBYTEPADDING);
       ZEROBYTEPADDING);
 {$SCOPEDENUMS OFF}
 {$SCOPEDENUMS OFF}
 
 
@@ -109,6 +127,17 @@ begin
 
 
   // TODO Flesh out the list of aliases
   // TODO Flesh out the list of aliases
 
 
+  Falgorithms.Add(TNistObjectIdentifiers.IdAes128Ecb.Id,
+    'AES/ECB/PKCS7PADDING');
+  Falgorithms.Add(TNistObjectIdentifiers.IdAes192Ecb.Id,
+    'AES/ECB/PKCS7PADDING');
+  Falgorithms.Add(TNistObjectIdentifiers.IdAes256Ecb.Id,
+    'AES/ECB/PKCS7PADDING');
+  Falgorithms.Add('AES//PKCS7', 'AES/ECB/PKCS7PADDING');
+  Falgorithms.Add('AES//PKCS7PADDING', 'AES/ECB/PKCS7PADDING');
+  Falgorithms.Add('AES//PKCS5', 'AES/ECB/PKCS7PADDING');
+  Falgorithms.Add('AES//PKCS5PADDING', 'AES/ECB/PKCS7PADDING');
+
   Falgorithms.Add(TNistObjectIdentifiers.IdAes128Cbc.Id,
   Falgorithms.Add(TNistObjectIdentifiers.IdAes128Cbc.Id,
     'AES/CBC/PKCS7PADDING');
     'AES/CBC/PKCS7PADDING');
   Falgorithms.Add(TNistObjectIdentifiers.IdAes192Cbc.Id,
   Falgorithms.Add(TNistObjectIdentifiers.IdAes192Cbc.Id,
@@ -116,6 +145,14 @@ begin
   Falgorithms.Add(TNistObjectIdentifiers.IdAes256Cbc.Id,
   Falgorithms.Add(TNistObjectIdentifiers.IdAes256Cbc.Id,
     'AES/CBC/PKCS7PADDING');
     'AES/CBC/PKCS7PADDING');
 
 
+  Falgorithms.Add(TNistObjectIdentifiers.IdAes128Ofb.Id, 'AES/OFB/NOPADDING');
+  Falgorithms.Add(TNistObjectIdentifiers.IdAes192Ofb.Id, 'AES/OFB/NOPADDING');
+  Falgorithms.Add(TNistObjectIdentifiers.IdAes256Ofb.Id, 'AES/OFB/NOPADDING');
+
+  Falgorithms.Add(TNistObjectIdentifiers.IdAes128Cfb.Id, 'AES/CFB/NOPADDING');
+  Falgorithms.Add(TNistObjectIdentifiers.IdAes192Cfb.Id, 'AES/CFB/NOPADDING');
+  Falgorithms.Add(TNistObjectIdentifiers.IdAes256Cfb.Id, 'AES/CFB/NOPADDING');
+
 end;
 end;
 
 
 class constructor TCipherUtilities.CreateCipherUtilities;
 class constructor TCipherUtilities.CreateCipherUtilities;
@@ -159,7 +196,7 @@ end;
 class function TCipherUtilities.GetCipher(algorithm: String): IBufferedCipher;
 class function TCipherUtilities.GetCipher(algorithm: String): IBufferedCipher;
 var
 var
   aliased, algorithmName, temp, paddingName, mode, modeName: string;
   aliased, algorithmName, temp, paddingName, mode, modeName: string;
-  di, LowPoint: Int32;
+  di, LowPoint, bits, HighPoint: Int32;
   padded: Boolean;
   padded: Boolean;
   parts: TCryptoLibStringArray;
   parts: TCryptoLibStringArray;
   cipherAlgorithm: TCipherAlgorithm;
   cipherAlgorithm: TCipherAlgorithm;
@@ -179,7 +216,7 @@ begin
     algorithm := aliased;
     algorithm := aliased;
   end;
   end;
 
 
-  parts := algorithm.SplitString('/');
+  parts := TStringUtils.SplitString(algorithm, '/');
 
 
   blockCipher := Nil;
   blockCipher := Nil;
 
 
@@ -228,15 +265,39 @@ begin
         begin
         begin
           padded := false;
           padded := false;
         end;
         end;
+
+      TCipherPadding.ISO10126PADDING, TCipherPadding.ISO10126D2PADDING,
+        TCipherPadding.ISO10126_2PADDING:
+        begin
+          padding := TISO10126d2Padding.Create() as IISO10126d2Padding;
+        end;
+
+      TCipherPadding.ISO7816_4PADDING, TCipherPadding.ISO9797_1PADDING:
+        begin
+          padding := TISO7816d4Padding.Create() as IISO7816d4Padding;
+        end;
+
       TCipherPadding.PKCS5, TCipherPadding.PKCS5PADDING, TCipherPadding.PKCS7,
       TCipherPadding.PKCS5, TCipherPadding.PKCS5PADDING, TCipherPadding.PKCS7,
         TCipherPadding.PKCS7PADDING:
         TCipherPadding.PKCS7PADDING:
         begin
         begin
           padding := TPkcs7Padding.Create() as IPkcs7Padding;
           padding := TPkcs7Padding.Create() as IPkcs7Padding;
         end;
         end;
+
+      TCipherPadding.TBCPADDING:
+        begin
+          padding := TTBCPadding.Create() as ITBCPadding;
+        end;
+
+      TCipherPadding.X923PADDING:
+        begin
+          padding := TX923Padding.Create() as IX923Padding;
+        end;
+
       TCipherPadding.ZEROBYTEPADDING:
       TCipherPadding.ZEROBYTEPADDING:
         begin
         begin
           padding := TZeroBytePadding.Create() as IZeroBytePadding;
           padding := TZeroBytePadding.Create() as IZeroBytePadding;
-        end;
+        end
+
     else
     else
       begin
       begin
         raise ESecurityUtilityCryptoLibException.CreateResFmt
         raise ESecurityUtilityCryptoLibException.CreateResFmt
@@ -280,14 +341,70 @@ begin
     end;
     end;
 
 
     case cipherMode of
     case cipherMode of
-      TCipherMode.NONE:
+      TCipherMode.ECB, TCipherMode.NONE:
         begin
         begin
           // do nothing
           // do nothing
         end;
         end;
+
       TCipherMode.CBC:
       TCipherMode.CBC:
         begin
         begin
           blockCipher := TCbcBlockCipher.Create(blockCipher) as ICbcBlockCipher;
           blockCipher := TCbcBlockCipher.Create(blockCipher) as ICbcBlockCipher;
+        end;
+
+      TCipherMode.CFB:
+        begin
+          if (di < 0) then
+          begin
+            bits := 8 * blockCipher.GetBlockSize();
+          end
+          else
+          begin
+{$IFDEF DELPHIXE3_UP}
+            HighPoint := System.High(mode);
+{$ELSE}
+            HighPoint := System.Length(mode);
+{$ENDIF DELPHIXE3_UP}
+            bits := StrToInt(System.Copy(mode, di, HighPoint - di));
+          end;
+
+          blockCipher := TCfbBlockCipher.Create(blockCipher, bits)
+            as ICfbBlockCipher;
+        end;
+
+      TCipherMode.CTR:
+        begin
+          blockCipher := TSicBlockCipher.Create(blockCipher) as ISicBlockCipher;
+        end;
+
+      TCipherMode.OFB:
+        begin
+          if (di < 0) then
+          begin
+            bits := 8 * blockCipher.GetBlockSize();
+          end
+          else
+          begin
+{$IFDEF DELPHIXE3_UP}
+            HighPoint := System.High(mode);
+{$ELSE}
+            HighPoint := System.Length(mode);
+{$ENDIF DELPHIXE3_UP}
+            bits := StrToInt(System.Copy(mode, di, HighPoint - di));
+          end;
+
+          blockCipher := TOfbBlockCipher.Create(blockCipher, bits)
+            as IOfbBlockCipher;
+        end;
+
+      TCipherMode.SIC:
+        begin
+          if (blockCipher.GetBlockSize() < 16) then
+          begin
+            raise EArgumentCryptoLibException.CreateRes(@SSICModeWarning);
+          end;
+          blockCipher := TSicBlockCipher.Create(blockCipher) as ISicBlockCipher;
         end
         end
+
     else
     else
       begin
       begin
         raise ESecurityUtilityCryptoLibException.CreateResFmt
         raise ESecurityUtilityCryptoLibException.CreateResFmt

+ 81 - 46
CryptoLib/src/Security/ClpDigestUtilities.pas

@@ -24,9 +24,11 @@ interface
 uses
 uses
   SysUtils,
   SysUtils,
   TypInfo,
   TypInfo,
-  HlpIHash,
   Generics.Collections,
   Generics.Collections,
   HlpHashFactory,
   HlpHashFactory,
+  ClpIDigest,
+  ClpIDigestMAC,
+  ClpIPBKDF2_DigestMAC,
   ClpPkcsObjectIdentifiers,
   ClpPkcsObjectIdentifiers,
   ClpOiwObjectIdentifiers,
   ClpOiwObjectIdentifiers,
   ClpNistObjectIdentifiers,
   ClpNistObjectIdentifiers,
@@ -50,7 +52,7 @@ type
 
 
   type
   type
 {$SCOPEDENUMS ON}
 {$SCOPEDENUMS ON}
-    TDigestAlgorithm = (GOST3411, MD2, MD4, MD5, RIPEMD128, RIPEMD160,
+    TDigestAlgorithm = (NULL, GOST3411, MD2, MD4, MD5, RIPEMD128, RIPEMD160,
       RIPEMD256, RIPEMD320, SHA_1, SHA_224, SHA_256, SHA_384, SHA_512,
       RIPEMD256, RIPEMD320, SHA_1, SHA_224, SHA_256, SHA_384, SHA_512,
       SHA_512_224, SHA_512_256, SHA3_224, SHA3_256, SHA3_384, SHA3_512,
       SHA_512_224, SHA_512_256, SHA3_224, SHA3_256, SHA3_384, SHA3_512,
       TIGER_5_192, WHIRLPOOL);
       TIGER_5_192, WHIRLPOOL);
@@ -66,9 +68,16 @@ type
     /// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
     /// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
     class function GetObjectIdentifier(mechanism: String)
     class function GetObjectIdentifier(mechanism: String)
       : IDerObjectIdentifier; static;
       : IDerObjectIdentifier; static;
-    class function GetDigest(const id: IDerObjectIdentifier): IHash; overload;
+    class function GetDigest(const id: IDerObjectIdentifier): IDigest; overload;
       static; inline;
       static; inline;
-    class function GetDigest(const algorithm: String): IHash; overload; static;
+    class function GetDigest(const algorithm: String): IDigest;
+      overload; static;
+
+    class function GetDigestMAC(const digest: IDigest): IDigestMAC; static;
+
+    class function GetPBKDF2_DigestMAC(const digest: IDigest;
+      a_password, a_salt: TCryptoLibByteArray; a_iterations: UInt32)
+      : IPBKDF2_DigestMAC; static;
 
 
     class function GetAlgorithmName(const oid: IDerObjectIdentifier): String;
     class function GetAlgorithmName(const oid: IDerObjectIdentifier): String;
       static; inline;
       static; inline;
@@ -76,11 +85,6 @@ type
     class function CalculateDigest(const algorithm: String;
     class function CalculateDigest(const algorithm: String;
       input: TCryptoLibByteArray): TCryptoLibByteArray; static; inline;
       input: TCryptoLibByteArray): TCryptoLibByteArray; static; inline;
 
 
-    class function DoFinal(const digest: IHash): TCryptoLibByteArray; overload;
-      static; inline;
-    class function DoFinal(const digest: IHash; input: TCryptoLibByteArray)
-      : TCryptoLibByteArray; overload; static; inline;
-
     class procedure Boot(); static;
     class procedure Boot(); static;
   end;
   end;
 
 
@@ -89,12 +93,12 @@ implementation
 { TDigestUtilities }
 { TDigestUtilities }
 
 
 class function TDigestUtilities.GetDigest
 class function TDigestUtilities.GetDigest
-  (const id: IDerObjectIdentifier): IHash;
+  (const id: IDerObjectIdentifier): IDigest;
 begin
 begin
   result := GetDigest(id.id);
   result := GetDigest(id.id);
 end;
 end;
 
 
-class function TDigestUtilities.GetDigest(const algorithm: String): IHash;
+class function TDigestUtilities.GetDigest(const algorithm: String): IDigest;
 var
 var
   upper, mechanism, temp: String;
   upper, mechanism, temp: String;
   digestAlgorithm: TDigestAlgorithm;
   digestAlgorithm: TDigestAlgorithm;
@@ -120,131 +124,161 @@ begin
     (GetEnumValue(TypeInfo(TDigestAlgorithm), temp));
     (GetEnumValue(TypeInfo(TDigestAlgorithm), temp));
 
 
   case digestAlgorithm of
   case digestAlgorithm of
+
+    TDigestAlgorithm.NULL:
+      begin
+        result := IDigest(THashFactory.TNullDigestFactory.CreateNullDigest());
+        result.Initialize;
+        Exit;
+      end;
+
     TDigestAlgorithm.GOST3411:
     TDigestAlgorithm.GOST3411:
       begin
       begin
-        result := THashFactory.TCrypto.CreateGost();
+        result := IDigest(THashFactory.TCrypto.CreateGost());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.MD2:
     TDigestAlgorithm.MD2:
       begin
       begin
-        result := THashFactory.TCrypto.CreateMD2();
+        result := IDigest(THashFactory.TCrypto.CreateMD2());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.MD4:
     TDigestAlgorithm.MD4:
       begin
       begin
-        result := THashFactory.TCrypto.CreateMD4();
+        result := IDigest(THashFactory.TCrypto.CreateMD4());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.MD5:
     TDigestAlgorithm.MD5:
       begin
       begin
-        result := THashFactory.TCrypto.CreateMD5();
+        result := IDigest(THashFactory.TCrypto.CreateMD5());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.RIPEMD128:
     TDigestAlgorithm.RIPEMD128:
       begin
       begin
-        result := THashFactory.TCrypto.CreateRIPEMD128();
+        result := IDigest(THashFactory.TCrypto.CreateRIPEMD128());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.RIPEMD160:
     TDigestAlgorithm.RIPEMD160:
       begin
       begin
-        result := THashFactory.TCrypto.CreateRIPEMD160();
+        result := IDigest(THashFactory.TCrypto.CreateRIPEMD160());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.RIPEMD256:
     TDigestAlgorithm.RIPEMD256:
       begin
       begin
-        result := THashFactory.TCrypto.CreateRIPEMD256();
+        result := IDigest(THashFactory.TCrypto.CreateRIPEMD256());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.RIPEMD320:
     TDigestAlgorithm.RIPEMD320:
       begin
       begin
-        result := THashFactory.TCrypto.CreateRIPEMD320();
+        result := IDigest(THashFactory.TCrypto.CreateRIPEMD320());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_1:
     TDigestAlgorithm.SHA_1:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA1();
+        result := IDigest(THashFactory.TCrypto.CreateSHA1());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_224:
     TDigestAlgorithm.SHA_224:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA2_224();
+        result := IDigest(THashFactory.TCrypto.CreateSHA2_224());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_256:
     TDigestAlgorithm.SHA_256:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA2_256();
+        result := IDigest(THashFactory.TCrypto.CreateSHA2_256());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_384:
     TDigestAlgorithm.SHA_384:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA2_384();
+        result := IDigest(THashFactory.TCrypto.CreateSHA2_384());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_512:
     TDigestAlgorithm.SHA_512:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA2_512();
+
+        result := IDigest(THashFactory.TCrypto.CreateSHA2_512());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_512_224:
     TDigestAlgorithm.SHA_512_224:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA2_512_224();
+        result := IDigest(THashFactory.TCrypto.CreateSHA2_512_224());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_512_256:
     TDigestAlgorithm.SHA_512_256:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA2_512_256();
+        result := IDigest(THashFactory.TCrypto.CreateSHA2_512_256());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA3_224:
     TDigestAlgorithm.SHA3_224:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA3_224();
+        result := IDigest(THashFactory.TCrypto.CreateSHA3_224());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA3_256:
     TDigestAlgorithm.SHA3_256:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA3_256();
+        result := IDigest(THashFactory.TCrypto.CreateSHA3_256());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA3_384:
     TDigestAlgorithm.SHA3_384:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA3_384();
+        result := IDigest(THashFactory.TCrypto.CreateSHA3_384());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA3_512:
     TDigestAlgorithm.SHA3_512:
       begin
       begin
-        result := THashFactory.TCrypto.CreateSHA3_512();
+        result := IDigest(THashFactory.TCrypto.CreateSHA3_512());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.TIGER_5_192:
     TDigestAlgorithm.TIGER_5_192:
       begin
       begin
-        result := THashFactory.TCrypto.CreateTiger_5_192();
+        result := IDigest(THashFactory.TCrypto.CreateTiger_5_192());
+        result.Initialize;
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.WHIRLPOOL:
     TDigestAlgorithm.WHIRLPOOL:
       begin
       begin
-        result := THashFactory.TCrypto.CreateWhirlPool();
+        result := IDigest(THashFactory.TCrypto.CreateWhirlPool());
+        result.Initialize;
         Exit;
         Exit;
-      end;
+      end
 
 
   else
   else
     begin
     begin
@@ -256,10 +290,17 @@ begin
 
 
 end;
 end;
 
 
-class function TDigestUtilities.DoFinal(const digest: IHash)
-  : TCryptoLibByteArray;
+class function TDigestUtilities.GetDigestMAC(const digest: IDigest): IDigestMAC;
 begin
 begin
-  result := digest.TransformFinal().GetBytes();
+  result := IDigestMAC(THashFactory.THMAC.CreateHMAC(digest));
+end;
+
+class function TDigestUtilities.GetPBKDF2_DigestMAC(const digest: IDigest;
+  a_password, a_salt: TCryptoLibByteArray; a_iterations: UInt32)
+  : IPBKDF2_DigestMAC;
+begin
+  result := IPBKDF2_DigestMAC(TKDF.TPBKDF2_HMAC.CreatePBKDF2_HMAC(digest,
+    a_password, a_salt, a_iterations));
 end;
 end;
 
 
 class procedure TDigestUtilities.Boot;
 class procedure TDigestUtilities.Boot;
@@ -267,6 +308,8 @@ begin
   Falgorithms := TDictionary<string, string>.Create();
   Falgorithms := TDictionary<string, string>.Create();
   Foids := TDictionary<string, IDerObjectIdentifier>.Create();
   Foids := TDictionary<string, IDerObjectIdentifier>.Create();
 
 
+  Falgorithms.Add('NULL', 'NULL'); // Null Digest
+
   TPkcsObjectIdentifiers.Boot;
   TPkcsObjectIdentifiers.Boot;
 
 
   Falgorithms.Add(TPkcsObjectIdentifiers.MD2.id, 'MD2');
   Falgorithms.Add(TPkcsObjectIdentifiers.MD2.id, 'MD2');
@@ -336,12 +379,11 @@ end;
 class function TDigestUtilities.CalculateDigest(const algorithm: String;
 class function TDigestUtilities.CalculateDigest(const algorithm: String;
   input: TCryptoLibByteArray): TCryptoLibByteArray;
   input: TCryptoLibByteArray): TCryptoLibByteArray;
 var
 var
-  digest: IHash;
+  digest: IDigest;
 begin
 begin
   digest := GetDigest(algorithm);
   digest := GetDigest(algorithm);
-  digest.Initialize();
   digest.TransformBytes(input, 0, System.Length(input));
   digest.TransformBytes(input, 0, System.Length(input));
-  result := DoFinal(digest);
+  result := digest.TransformFinal().GetBytes();
 end;
 end;
 
 
 class constructor TDigestUtilities.CreateDigestUtilities;
 class constructor TDigestUtilities.CreateDigestUtilities;
@@ -355,13 +397,6 @@ begin
   Foids.Free;
   Foids.Free;
 end;
 end;
 
 
-class function TDigestUtilities.DoFinal(const digest: IHash;
-  input: TCryptoLibByteArray): TCryptoLibByteArray;
-begin
-  digest.TransformBytes(input, 0, System.Length(input));
-  result := DoFinal(digest);
-end;
-
 class function TDigestUtilities.GetAlgorithmName
 class function TDigestUtilities.GetAlgorithmName
   (const oid: IDerObjectIdentifier): String;
   (const oid: IDerObjectIdentifier): String;
 begin
 begin

+ 44 - 5
CryptoLib/src/Security/ClpGeneratorUtilities.pas

@@ -26,10 +26,12 @@ uses
   Generics.Collections,
   Generics.Collections,
   ClpECKeyPairGenerator,
   ClpECKeyPairGenerator,
   ClpIECKeyPairGenerator,
   ClpIECKeyPairGenerator,
+  ClpCipherKeyGenerator,
+  ClpICipherKeyGenerator,
   ClpIDerObjectIdentifier,
   ClpIDerObjectIdentifier,
   ClpIAsymmetricCipherKeyPairGenerator,
   ClpIAsymmetricCipherKeyPairGenerator,
   ClpNistObjectIdentifiers,
   ClpNistObjectIdentifiers,
-  ClpStringHelper,
+  ClpStringUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 resourcestring
 resourcestring
@@ -81,6 +83,9 @@ type
     class function GetKeyPairGenerator(const algorithm: String)
     class function GetKeyPairGenerator(const algorithm: String)
       : IAsymmetricCipherKeyPairGenerator; overload; static;
       : IAsymmetricCipherKeyPairGenerator; overload; static;
 
 
+    class function GetKeyGenerator(const algorithm: String)
+      : ICipherKeyGenerator; static;
+
     class function GetDefaultKeySize(const oid: IDerObjectIdentifier): Int32;
     class function GetDefaultKeySize(const oid: IDerObjectIdentifier): Int32;
       overload; static; inline;
       overload; static; inline;
 
 
@@ -146,18 +151,28 @@ begin
   //
   //
 
 
   AddKgAlgorithm('AES128', ['2.16.840.1.101.3.4.2',
   AddKgAlgorithm('AES128', ['2.16.840.1.101.3.4.2',
-    TNistObjectIdentifiers.IdAes128Cbc.ID]);
+    TNistObjectIdentifiers.IdAes128Cbc.ID,
+    TNistObjectIdentifiers.IdAes128Cfb.ID,
+    TNistObjectIdentifiers.IdAes128Ecb.ID,
+    TNistObjectIdentifiers.IdAes128Ofb.ID]);
 
 
   AddKgAlgorithm('AES192', ['2.16.840.1.101.3.4.22',
   AddKgAlgorithm('AES192', ['2.16.840.1.101.3.4.22',
-    TNistObjectIdentifiers.IdAes192Cbc.ID]);
+    TNistObjectIdentifiers.IdAes192Cbc.ID,
+    TNistObjectIdentifiers.IdAes192Cfb.ID,
+    TNistObjectIdentifiers.IdAes192Ecb.ID,
+    TNistObjectIdentifiers.IdAes192Ofb.ID]);
 
 
   AddKgAlgorithm('AES256', ['2.16.840.1.101.3.4.42',
   AddKgAlgorithm('AES256', ['2.16.840.1.101.3.4.42',
-    TNistObjectIdentifiers.IdAes256Cbc.ID]);
+    TNistObjectIdentifiers.IdAes256Cbc.ID,
+    TNistObjectIdentifiers.IdAes256Cfb.ID,
+    TNistObjectIdentifiers.IdAes256Ecb.ID,
+    TNistObjectIdentifiers.IdAes256Ofb.ID]);
 
 
   //
   //
   // key pair generators.
   // key pair generators.
   //
   //
 
 
+  AddKpgAlgorithm('ECDH', ['ECIES']);
   AddKpgAlgorithm('ECDSA', []);
   AddKpgAlgorithm('ECDSA', []);
 
 
   AddDefaultKeySizeEntries(128, ['AES128']);
   AddDefaultKeySizeEntries(128, ['AES128']);
@@ -232,6 +247,30 @@ begin
   result := GetDefaultKeySize(oid.ID);
   result := GetDefaultKeySize(oid.ID);
 end;
 end;
 
 
+class function TGeneratorUtilities.GetKeyGenerator(const algorithm: String)
+  : ICipherKeyGenerator;
+var
+  canonicalName: string;
+  defaultKeySize: Int32;
+begin
+
+  canonicalName := GetCanonicalKeyGeneratorAlgorithm(algorithm);
+  if (canonicalName = '') then
+  begin
+    raise ESecurityUtilityCryptoLibException.CreateResFmt
+      (@SKeyGeneratorAlgorithmNotRecognised, [algorithm]);
+  end;
+
+  defaultKeySize := FindDefaultKeySize(canonicalName);
+  if (defaultKeySize = -1) then
+  begin
+    raise ESecurityUtilityCryptoLibException.CreateResFmt
+      (@SKeyGeneratorAlgorithmNotSupported, [algorithm, canonicalName]);
+  end;
+
+  result := TCipherKeyGenerator.Create(defaultKeySize);
+end;
+
 class function TGeneratorUtilities.GetKeyPairGenerator(const algorithm: String)
 class function TGeneratorUtilities.GetKeyPairGenerator(const algorithm: String)
   : IAsymmetricCipherKeyPairGenerator;
   : IAsymmetricCipherKeyPairGenerator;
 var
 var
@@ -246,7 +285,7 @@ begin
   end;
   end;
 
 
   // "EC", "ECDH", "ECDHC", "ECDSA", "ECGOST3410", "ECMQV"
   // "EC", "ECDH", "ECDHC", "ECDSA", "ECGOST3410", "ECMQV"
-  if canonicalName.BeginsWith('EC', False) then
+  if TStringUtils.BeginsWith(canonicalName, 'EC', True) then
   begin
   begin
     result := TECKeyPairGenerator.Create(canonicalName) as IECKeyPairGenerator;
     result := TECKeyPairGenerator.Create(canonicalName) as IECKeyPairGenerator;
     Exit;
     Exit;

+ 33 - 8
CryptoLib/src/Security/ClpParameterUtilities.pas

@@ -39,13 +39,17 @@ type
   TParameterUtilities = class sealed(TObject)
   TParameterUtilities = class sealed(TObject)
 
 
   strict private
   strict private
-    class var
+  class var
 
 
-      Falgorithms: TDictionary<String, String>;
+    Falgorithms: TDictionary<String, String>;
+    FbasicIVSizes: TDictionary<String, Int32>;
 
 
     class procedure AddAlgorithm(const canonicalName: String;
     class procedure AddAlgorithm(const canonicalName: String;
       aliases: array of String); static;
       aliases: array of String); static;
 
 
+    class procedure AddBasicIVSizeEntries(size: Int32;
+      algorithms: array of String); static;
+
     class constructor CreateParameterUtilities();
     class constructor CreateParameterUtilities();
     class destructor DestroyParameterUtilities();
     class destructor DestroyParameterUtilities();
 
 
@@ -87,22 +91,42 @@ begin
 
 
 end;
 end;
 
 
+class procedure TParameterUtilities.AddBasicIVSizeEntries(size: Int32;
+  algorithms: array of String);
+var
+  algorithm: string;
+begin
+  for algorithm in algorithms do
+  begin
+    FbasicIVSizes.Add(algorithm, size);
+  end;
+end;
+
 class procedure TParameterUtilities.Boot;
 class procedure TParameterUtilities.Boot;
 begin
 begin
   Falgorithms := TDictionary<String, String>.Create();
   Falgorithms := TDictionary<String, String>.Create();
+  FbasicIVSizes := TDictionary<string, Integer>.Create();
 
 
   TNistObjectIdentifiers.Boot;
   TNistObjectIdentifiers.Boot;
 
 
   AddAlgorithm('AES', []);
   AddAlgorithm('AES', []);
-
   AddAlgorithm('AES128', ['2.16.840.1.101.3.4.2',
   AddAlgorithm('AES128', ['2.16.840.1.101.3.4.2',
-    TNistObjectIdentifiers.IdAes128Cbc.ID]);
-
+    TNistObjectIdentifiers.IdAes128Cbc.ID,
+    TNistObjectIdentifiers.IdAes128Cfb.ID,
+    TNistObjectIdentifiers.IdAes128Ecb.ID,
+    TNistObjectIdentifiers.IdAes128Ofb.ID]);
   AddAlgorithm('AES192', ['2.16.840.1.101.3.4.22',
   AddAlgorithm('AES192', ['2.16.840.1.101.3.4.22',
-    TNistObjectIdentifiers.IdAes192Cbc.ID]);
-
+    TNistObjectIdentifiers.IdAes192Cbc.ID,
+    TNistObjectIdentifiers.IdAes192Cfb.ID,
+    TNistObjectIdentifiers.IdAes192Ecb.ID,
+    TNistObjectIdentifiers.IdAes192Ofb.ID]);
   AddAlgorithm('AES256', ['2.16.840.1.101.3.4.42',
   AddAlgorithm('AES256', ['2.16.840.1.101.3.4.42',
-    TNistObjectIdentifiers.IdAes256Cbc.ID]);
+    TNistObjectIdentifiers.IdAes256Cbc.ID,
+    TNistObjectIdentifiers.IdAes256Cfb.ID,
+    TNistObjectIdentifiers.IdAes256Ecb.ID,
+    TNistObjectIdentifiers.IdAes256Ofb.ID]);
+
+  AddBasicIVSizeEntries(16, ['AES', 'AES128', 'AES192', 'AES256']);
 
 
 end;
 end;
 
 
@@ -161,6 +185,7 @@ end;
 class destructor TParameterUtilities.DestroyParameterUtilities;
 class destructor TParameterUtilities.DestroyParameterUtilities;
 begin
 begin
   Falgorithms.Free;
   Falgorithms.Free;
+  FbasicIVSizes.Free;
 end;
 end;
 
 
 end.
 end.

+ 3 - 3
CryptoLib/src/Security/ClpSecureRandom.pas

@@ -26,12 +26,12 @@ uses
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   SyncObjs,
   SyncObjs,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
-  HlpIHash,
   SysUtils,
   SysUtils,
   StrUtils,
   StrUtils,
   ClpBits,
   ClpBits,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
   ClpTimes,
   ClpTimes,
+  ClpIDigest,
   ClpIRandomGenerator,
   ClpIRandomGenerator,
   ClpRandom,
   ClpRandom,
   ClpDigestUtilities,
   ClpDigestUtilities,
@@ -286,7 +286,7 @@ end;
 class function TSecureRandom.CreatePrng(const digestName: String;
 class function TSecureRandom.CreatePrng(const digestName: String;
   autoSeed: Boolean): IDigestRandomGenerator;
   autoSeed: Boolean): IDigestRandomGenerator;
 var
 var
-  digest: IHash;
+  digest: IDigest;
   prng: IDigestRandomGenerator;
   prng: IDigestRandomGenerator;
 begin
 begin
   digest := TDigestUtilities.GetDigest(digestName);
   digest := TDigestUtilities.GetDigest(digestName);
@@ -295,7 +295,7 @@ begin
     Result := Nil;
     Result := Nil;
     Exit;
     Exit;
   end;
   end;
-  digest.Initialize(); // initialize digest state
+
   prng := TDigestRandomGenerator.Create(digest);
   prng := TDigestRandomGenerator.Create(digest);
   if (autoSeed) then
   if (autoSeed) then
   begin
   begin

+ 96 - 96
CryptoLib/src/Security/ClpSignerUtilities.pas

@@ -25,8 +25,8 @@ uses
   SysUtils,
   SysUtils,
   Generics.Collections,
   Generics.Collections,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
-  HlpHashFactory,
-  HlpIHash,
+  ClpIDigest,
+  ClpDigestUtilities,
   ClpDsaDigestSigner,
   ClpDsaDigestSigner,
   ClpECSchnorrSigner,
   ClpECSchnorrSigner,
   ClpX9ObjectIdentifiers,
   ClpX9ObjectIdentifiers,
@@ -389,7 +389,7 @@ end;
 class function TSignerUtilities.GetSigner(algorithm: String): ISigner;
 class function TSignerUtilities.GetSigner(algorithm: String): ISigner;
 var
 var
   mechanism: string;
   mechanism: string;
-  HashInstance: IHash;
+  DigestInstance: IDigest;
 begin
 begin
   if (algorithm = '') then
   if (algorithm = '') then
   begin
   begin
@@ -405,59 +405,59 @@ begin
 
 
   if (mechanism = 'NONEwithECDSA') then
   if (mechanism = 'NONEwithECDSA') then
   begin
   begin
-    HashInstance := THashFactory.TNullDigestFactory.CreateNullDigest();
-    HashInstance.Initialize;
+    DigestInstance := TDigestUtilities.GetDigest('NULL');
+
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      HashInstance));
+      DigestInstance));
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-1withECDSA') then
   if (mechanism = 'SHA-1withECDSA') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA1();
-    HashInstance.Initialize;
+    DigestInstance := TDigestUtilities.GetDigest('SHA-1');
+
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      HashInstance));
+      DigestInstance));
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-224withECDSA') then
   if (mechanism = 'SHA-224withECDSA') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_224();
-    HashInstance.Initialize;
+    DigestInstance := TDigestUtilities.GetDigest('SHA-224');
+
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      HashInstance));
+      DigestInstance));
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-256withECDSA') then
   if (mechanism = 'SHA-256withECDSA') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_256();
-    HashInstance.Initialize;
+    DigestInstance := TDigestUtilities.GetDigest('SHA-256');
+
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      HashInstance));
+      DigestInstance));
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-384withECDSA') then
   if (mechanism = 'SHA-384withECDSA') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_384();
-    HashInstance.Initialize;
+    DigestInstance := TDigestUtilities.GetDigest('SHA-384');
+
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      HashInstance));
+      DigestInstance));
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-512withECDSA') then
   if (mechanism = 'SHA-512withECDSA') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_512();
-    HashInstance.Initialize;
+    DigestInstance := TDigestUtilities.GetDigest('SHA-512');
+
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      HashInstance));
+      DigestInstance));
     Exit;
     Exit;
   end;
   end;
 
 
   if (mechanism = 'RIPEMD160withECDSA') then
   if (mechanism = 'RIPEMD160withECDSA') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateRIPEMD160();
-    HashInstance.Initialize;
+    DigestInstance := TDigestUtilities.GetDigest('RIPEMD-160');
+
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      HashInstance));
+      DigestInstance));
     Exit;
     Exit;
   end;
   end;
 
 
@@ -466,45 +466,45 @@ begin
 
 
   if (mechanism = 'SHA-1withECSCHNORRBSI') then
   if (mechanism = 'SHA-1withECSCHNORRBSI') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA1();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-1');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'BSI');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-224withECSCHNORRBSI') then
   if (mechanism = 'SHA-224withECSCHNORRBSI') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_224();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-224');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'BSI');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-256withECSCHNORRBSI') then
   if (mechanism = 'SHA-256withECSCHNORRBSI') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_256();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-256');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'BSI');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-384withECSCHNORRBSI') then
   if (mechanism = 'SHA-384withECSCHNORRBSI') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_384();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-384');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'BSI');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-512withECSCHNORRBSI') then
   if (mechanism = 'SHA-512withECSCHNORRBSI') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_512();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-512');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'BSI');
     Exit;
     Exit;
   end;
   end;
 
 
   if (mechanism = 'RIPEMD160withECSCHNORRBSI') then
   if (mechanism = 'RIPEMD160withECSCHNORRBSI') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateRIPEMD160();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    DigestInstance := TDigestUtilities.GetDigest('RIPEMD-160');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'BSI');
     Exit;
     Exit;
   end;
   end;
 
 
@@ -512,45 +512,45 @@ begin
 
 
   if (mechanism = 'SHA-1withECSCHNORRISO') then
   if (mechanism = 'SHA-1withECSCHNORRISO') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA1();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-1');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISO');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-224withECSCHNORRISO') then
   if (mechanism = 'SHA-224withECSCHNORRISO') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_224();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-224');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISO');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-256withECSCHNORRISO') then
   if (mechanism = 'SHA-256withECSCHNORRISO') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_256();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-256');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISO');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-384withECSCHNORRISO') then
   if (mechanism = 'SHA-384withECSCHNORRISO') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_384();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-384');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISO');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-512withECSCHNORRISO') then
   if (mechanism = 'SHA-512withECSCHNORRISO') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_512();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-512');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISO');
     Exit;
     Exit;
   end;
   end;
 
 
   if (mechanism = 'RIPEMD160withECSCHNORRISO') then
   if (mechanism = 'RIPEMD160withECSCHNORRISO') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateRIPEMD160();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    DigestInstance := TDigestUtilities.GetDigest('RIPEMD-160');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISO');
     Exit;
     Exit;
   end;
   end;
 
 
@@ -558,45 +558,45 @@ begin
 
 
   if (CompareText(mechanism, 'SHA-1withECSCHNORRISOx') = 0) then
   if (CompareText(mechanism, 'SHA-1withECSCHNORRISOx') = 0) then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA1();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-1');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISOx');
     Exit;
     Exit;
   end;
   end;
   if (CompareText(mechanism, 'SHA-224withECSCHNORRISOx') = 0) then
   if (CompareText(mechanism, 'SHA-224withECSCHNORRISOx') = 0) then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_224();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-224');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISOx');
     Exit;
     Exit;
   end;
   end;
   if (CompareText(mechanism, 'SHA-256withECSCHNORRISOx') = 0) then
   if (CompareText(mechanism, 'SHA-256withECSCHNORRISOx') = 0) then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_256();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-256');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISOx');
     Exit;
     Exit;
   end;
   end;
   if (CompareText(mechanism, 'SHA-384withECSCHNORRISOx') = 0) then
   if (CompareText(mechanism, 'SHA-384withECSCHNORRISOx') = 0) then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_384();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-384');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISOx');
     Exit;
     Exit;
   end;
   end;
   if (CompareText(mechanism, 'SHA-512withECSCHNORRISOx') = 0) then
   if (CompareText(mechanism, 'SHA-512withECSCHNORRISOx') = 0) then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_512();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-512');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISOx');
     Exit;
     Exit;
   end;
   end;
 
 
   if (CompareText(mechanism, 'RIPEMD160withECSCHNORRISOx') = 0) then
   if (CompareText(mechanism, 'RIPEMD160withECSCHNORRISOx') = 0) then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateRIPEMD160();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    DigestInstance := TDigestUtilities.GetDigest('RIPEMD-160');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'ISOx');
     Exit;
     Exit;
   end;
   end;
 
 
@@ -604,45 +604,45 @@ begin
 
 
   if (mechanism = 'SHA-1withECSCHNORRLIBSECP') then
   if (mechanism = 'SHA-1withECSCHNORRLIBSECP') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA1();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-1');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'LIBSECP');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-224withECSCHNORRLIBSECP') then
   if (mechanism = 'SHA-224withECSCHNORRLIBSECP') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_224();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-224');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'LIBSECP');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-256withECSCHNORRLIBSECP') then
   if (mechanism = 'SHA-256withECSCHNORRLIBSECP') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_256();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-256');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'LIBSECP');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-384withECSCHNORRLIBSECP') then
   if (mechanism = 'SHA-384withECSCHNORRLIBSECP') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_384();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-384');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'LIBSECP');
     Exit;
     Exit;
   end;
   end;
   if (mechanism = 'SHA-512withECSCHNORRLIBSECP') then
   if (mechanism = 'SHA-512withECSCHNORRLIBSECP') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateSHA2_512();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    DigestInstance := TDigestUtilities.GetDigest('SHA-512');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'LIBSECP');
     Exit;
     Exit;
   end;
   end;
 
 
   if (mechanism = 'RIPEMD160withECSCHNORRLIBSECP') then
   if (mechanism = 'RIPEMD160withECSCHNORRLIBSECP') then
   begin
   begin
-    HashInstance := THashFactory.TCrypto.CreateRIPEMD160();
-    HashInstance.Initialize;
-    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    DigestInstance := TDigestUtilities.GetDigest('RIPEMD-160');
+
+    Result := TECSchnorrSigner.Create(DigestInstance, 'LIBSECP');
     Exit;
     Exit;
   end;
   end;
 
 

+ 45 - 36
CryptoLib/src/Utils/Helpers/ClpStringHelper.pas → CryptoLib/src/Utils/ClpStringUtils.pas

@@ -15,9 +15,9 @@
 
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
 
-unit ClpStringHelper;
+unit ClpStringUtils;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I ..\Include\CryptoLib.inc}
 
 
 interface
 interface
 
 
@@ -28,57 +28,62 @@ uses
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 type
 type
-  TStringHelper = record helper for
-    String public
-    function GetHashCode: Int32;
-    function SplitString(Delimiter: Char): TCryptoLibStringArray;
-    function BeginsWith(const Value: string; IgnoreCase: Boolean): Boolean;
+  TStringUtils = class sealed(TObject)
+  public
+    class function GetStringHashCode(const Input: string): Int32; static;
+    class function SplitString(const Input: string; Delimiter: Char)
+      : TCryptoLibStringArray; static;
+    class function BeginsWith(const Input, SubString: string;
+      IgnoreCase: Boolean; Offset: Int32 = 1): Boolean; static;
 
 
   end;
   end;
 
 
 implementation
 implementation
 
 
-{ TStringHelper }
+{ TStringUtils }
 
 
-function TStringHelper.GetHashCode: Int32;
+class function TStringUtils.GetStringHashCode(const Input: string): Int32;
 var
 var
-  temp: string;
-  I, Top: UInt32;
+  LowPoint, HighPoint: Int32;
   LResult: UInt32;
   LResult: UInt32;
 begin
 begin
-  temp := Self;
-
   LResult := 0;
   LResult := 0;
 {$IFDEF DELPHIXE3_UP}
 {$IFDEF DELPHIXE3_UP}
-  I := System.Low(temp);
-  Top := System.High(temp);
+  LowPoint := System.Low(Input);
+  HighPoint := System.High(Input);
 {$ELSE}
 {$ELSE}
-  I := 1;
-  Top := System.Length(temp);
+  LowPoint := 1;
+  HighPoint := System.Length(Input);
 {$ENDIF DELPHIXE3_UP}
 {$ENDIF DELPHIXE3_UP}
-  while I <= Top do
+  while LowPoint <= HighPoint do
   begin
   begin
     LResult := TBits.RotateLeft32(LResult, 5);
     LResult := TBits.RotateLeft32(LResult, 5);
-    LResult := LResult xor UInt32(temp[I]);
-    System.Inc(I);
+    LResult := LResult xor UInt32(Input[LowPoint]);
+    System.Inc(LowPoint);
   end;
   end;
   Result := Int32(LResult);
   Result := Int32(LResult);
 end;
 end;
 
 
-function TStringHelper.SplitString(Delimiter: Char): TCryptoLibStringArray;
+class function TStringUtils.SplitString(const Input: string; Delimiter: Char)
+  : TCryptoLibStringArray;
 var
 var
-  PosStart, PosDel, SplitPoints, I, Len: Int32;
-  S: string;
+  PosStart, PosDel, SplitPoints, I, LowPoint, HighPoint, Len: Int32;
 begin
 begin
   Result := Nil;
   Result := Nil;
-  S := Self;
-  if S <> '' then
+  if Input <> '' then
   begin
   begin
     { Determine the length of the resulting array }
     { Determine the length of the resulting array }
+{$IFDEF DELPHIXE3_UP}
+    LowPoint := System.Low(Input);
+    HighPoint := System.High(Input);
+{$ELSE}
+    LowPoint := 1;
+    HighPoint := System.Length(Input);
+{$ENDIF DELPHIXE3_UP}
     SplitPoints := 0;
     SplitPoints := 0;
-    for I := 1 to System.Length(S) do
+    for I := LowPoint to HighPoint do
     begin
     begin
-      if (Delimiter = S[I]) then
+      if (Delimiter = Input[I]) then
         System.Inc(SplitPoints);
         System.Inc(SplitPoints);
     end;
     end;
 
 
@@ -89,34 +94,38 @@ begin
     I := 0;
     I := 0;
     Len := System.Length(Delimiter);
     Len := System.Length(Delimiter);
     PosStart := 1;
     PosStart := 1;
-    PosDel := System.Pos(Delimiter, S);
+    PosDel := System.Pos(Delimiter, Input);
     while PosDel > 0 do
     while PosDel > 0 do
     begin
     begin
-      Result[I] := System.Copy(S, PosStart, PosDel - PosStart);
+      Result[I] := System.Copy(Input, PosStart, PosDel - PosStart);
       PosStart := PosDel + Len;
       PosStart := PosDel + Len;
-      PosDel := PosEx(Delimiter, S, PosStart);
+      PosDel := PosEx(Delimiter, Input, PosStart);
       System.Inc(I);
       System.Inc(I);
     end;
     end;
-    Result[I] := System.Copy(S, PosStart, System.Length(S));
+    Result[I] := System.Copy(Input, PosStart, System.Length(Input));
   end;
   end;
 end;
 end;
 
 
-function TStringHelper.BeginsWith(const Value: string;
-  IgnoreCase: Boolean): Boolean;
+class function TStringUtils.BeginsWith(const Input, SubString: string;
+  IgnoreCase: Boolean; Offset: Int32): Boolean;
 var
 var
   L: Integer;
   L: Integer;
+  PtrInput, PtrSubString: PChar;
 begin
 begin
-  L := System.Length(Value);
+  L := System.Length(SubString);
   Result := L > 0;
   Result := L > 0;
+  PtrInput := PChar(Input);
+  System.Inc(PtrInput, Offset - 1);
+  PtrSubString := PChar(SubString);
   if Result then
   if Result then
   begin
   begin
     if IgnoreCase then
     if IgnoreCase then
     begin
     begin
-      Result := StrLiComp(PChar(Value), PChar(Self), L) = 0
+      Result := StrLiComp(PtrSubString, PtrInput, L) = 0
     end
     end
     else
     else
     begin
     begin
-      Result := StrLComp(PChar(Value), PChar(Self), L) = 0
+      Result := StrLComp(PtrSubString, PtrInput, L) = 0
     end;
     end;
   end;
   end;
 end;
 end;

+ 3 - 3
README.md

@@ -1,5 +1,5 @@
 # CryptoLib4Pascal
 # CryptoLib4Pascal
-CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying ECDSA and ECShnorr Signatures using various curves and hashes.
+CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying ECDSA and ECShnorr Signatures using various curves and hashes, AES Encryption and Decryption (With various modes and paddings) and ECIES.
 
 
 **Supported Algorithms:**
 **Supported Algorithms:**
 
 
@@ -36,7 +36,7 @@ CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that
  
  
     FreePascal 3.0.0 and Above.
     FreePascal 3.0.0 and Above.
     
     
-    Delphi 2010 and Above.
+    Delphi XE3 and Above. (might work in earlier versions though.)
 
 
 **Installing the Library.**
 **Installing the Library.**
 
 
@@ -61,7 +61,7 @@ To Run Unit Tests,
 
 
     Simply compile and run "CryptoLib.Tests" project in "FreePascal.Tests" Folder.
     Simply compile and run "CryptoLib.Tests" project in "FreePascal.Tests" Folder.
 
 
-**For Delphi 2010 and above**
+**For Delphi**
 
 
    **Method One (Using DUnit Test Runner)**
    **Method One (Using DUnit Test Runner)**