2
0
Эх сурвалжийг харах

add Clear() method to some data sensitive classes.

Ugochukwu Mmaduekwe 6 жил өмнө
parent
commit
2bdd1da73d

+ 4 - 0
CryptoLib.Tests/src/Crypto/Argon2Tests.pas

@@ -109,6 +109,8 @@ begin
     ((LArgon2Generator.GenerateDerivedMacParameters(AOutputLength)
     as IKeyParameter).GetKey(), False);
 
+  LArgon2Generator.Clear();
+
   CheckEquals(APasswordRef, LActual, Format('Expected %s but got %s.',
     [APasswordRef, LActual]));
 
@@ -140,6 +142,8 @@ begin
     ((LArgon2Generator.GenerateDerivedMacParameters(AOutputLength)
     as IKeyParameter).GetKey(), False);
 
+  LArgon2Generator.Clear();
+
   CheckEquals(APasswordRef, LActual, Format('Expected %s but got %s.',
     [APasswordRef, LActual]));
 

+ 28 - 1
CryptoLib.Tests/src/Crypto/Pkcs5Tests.pas

@@ -114,6 +114,8 @@ begin
     Fail('PBKDF2 HMAC-SHA1 with iteration count "5", 64 bits key generation test failed');
   end;
 
+  generator.Clear();
+
   PasswordString :=
     'All n-entities must communicate with other n-entities via n-1 entiteeheehees';
   PasswordBytes := TConverters.ConvertStringToBytes(PasswordString,
@@ -128,6 +130,8 @@ begin
     Fail('PBKDF2 HMAC-SHA1 with iteration count "500", 192 bits key generation test failed');
   end;
 
+  generator.Clear();
+
   generator.Init(PasswordBytes, SaltBytes, 60000);
 
   if (not TArrayUtils.AreEqual((generator.GenerateDerivedMacParameters(192)
@@ -137,6 +141,8 @@ begin
     Fail('PBKDF2 HMAC-SHA1 with iteration count "60000", 192 bits key generation test failed');
   end;
 
+  generator.Clear();
+
   // https://github.com/ircmaxell/PHP-PasswordLib/blob/master/test/Data/Vectors/pbkdf2-draft-josefsson-sha1.test-vectors
 
   generator := TPkcs5S2ParametersGenerator.Create
@@ -166,6 +172,8 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
+
   // 2
 
   iteration_count := 2;
@@ -183,6 +191,8 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
+
 
   // 3
 
@@ -201,6 +211,8 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
+
   // 4
   // commented out because iteration_count is very large
   // iteration_count := 16777216;
@@ -217,6 +229,8 @@ begin
   // ('PBKDF2 HMAC-SHA1 with iteration count "%u", %u bits key generation test failed',
   // [iteration_count, dkLen]));
   // end;
+  //
+  // generator.Clear();
 
 
   // 5
@@ -243,6 +257,8 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
+
 
   // 6
 
@@ -269,6 +285,8 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
+
 end;
 
 procedure TTestPkcs5.TestPkcs5_WITH_SHA256;
@@ -309,6 +327,8 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
+
   // 2
 
   iteration_count := 2;
@@ -327,6 +347,7 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
 
   // 3
 
@@ -346,6 +367,8 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
+
   // 4
   // commented out because iteration_count is very large
   // iteration_count := 16777216;
@@ -363,7 +386,8 @@ begin
   // ('PBKDF2 HMAC-SHA256 with iteration count "%u", %u bits key generation test failed',
   // [iteration_count, dkLen]));
   // end;
-
+  //
+  // generator.Clear();
 
   // 5
 
@@ -391,6 +415,7 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
 
   // 6
 
@@ -417,6 +442,8 @@ begin
       [iteration_count, dkLen]));
   end;
 
+  generator.Clear();
+
 end;
 
 initialization

+ 19 - 32
CryptoLib/src/Crypto/Generators/ClpArgon2ParametersGenerator.pas

@@ -32,6 +32,7 @@ uses
   ClpIKeyParameter,
   ClpParametersWithIV,
   ClpParameterUtilities,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -52,23 +53,14 @@ type
   var
     FPassword: TCryptoLibByteArray;
     FPBKDF_Argon2: IPBKDF_Argon2;
-    FArgon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder;
-
-    /// <returns>
-    /// the password byte array.
-    /// </returns>
-    function GetPassword: TCryptoLibByteArray; inline;
-
-    /// <returns>
-    /// the Argon2 Parameter Builder Instance
-    /// </returns>
-    function GetArgon2ParametersBuilder
-      : HlpIHashInfo.IArgon2ParametersBuilder; inline;
+    FArgon2Parameters: IArgon2Parameters;
 
     function GenerateDerivedKey(dkLen: Int32): TCryptoLibByteArray; inline;
 
   public
 
+    procedure Clear();
+
     /// <summary>
     /// construct an Argon2 Parameters generator.
     /// </summary>
@@ -77,6 +69,8 @@ type
     /// </param>
     constructor Create();
 
+    destructor Destroy; override;
+
     procedure Init(argon2Type: TArgon2Type; argon2Version: TArgon2Version;
       const password, salt, secret, additional: TCryptoLibByteArray;
       iterations, memory, parallelism: Int32;
@@ -132,37 +126,28 @@ type
     function GenerateDerivedMacParameters(keySize: Int32)
       : ICipherParameters; overload;
 
-    /// <value>
-    /// the password byte array.
-    /// </value>
-    property password: TCryptoLibByteArray read GetPassword;
-
-    /// <returns>
-    /// the Argon2 Parameter Builder Instance
-    /// </returns>
-    property Argon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder
-      read GetArgon2ParametersBuilder;
-
   end;
 
 implementation
 
 { TArgon2ParametersGenerator }
 
-function TArgon2ParametersGenerator.GetPassword: TCryptoLibByteArray;
+procedure TArgon2ParametersGenerator.Clear();
 begin
-  result := System.Copy(FPassword);
+  TArrayUtils.ZeroFill(FPassword);
+  FArgon2Parameters.Clear();
+  FPBKDF_Argon2.Clear();
 end;
 
-function TArgon2ParametersGenerator.GetArgon2ParametersBuilder
-  : HlpIHashInfo.IArgon2ParametersBuilder;
+constructor TArgon2ParametersGenerator.Create();
 begin
-  result := FArgon2ParametersBuilder;
+  Inherited Create();
 end;
 
-constructor TArgon2ParametersGenerator.Create();
+destructor TArgon2ParametersGenerator.Destroy();
 begin
-  Inherited Create();
+  Clear();
+  inherited Destroy;
 end;
 
 function TArgon2ParametersGenerator.GenerateDerivedKey(dkLen: Int32)
@@ -217,7 +202,7 @@ procedure TArgon2ParametersGenerator.Init(argon2Type: TArgon2Type;
 var
   LArgon2ParametersBuilder: IArgon2ParametersBuilder;
 begin
-  FPassword := password;
+  FPassword := System.Copy(password);
 
   case argon2Type of
     TArgon2Type.a2tARGON2_d:
@@ -262,8 +247,10 @@ begin
     end;
   end;
 
+  FArgon2Parameters := LArgon2ParametersBuilder.Build();
+  LArgon2ParametersBuilder.Clear();
   FPBKDF_Argon2 := TKDF.TPBKDF_Argon2.CreatePBKDF_Argon2(FPassword,
-    LArgon2ParametersBuilder.Build());
+    FArgon2Parameters);
 end;
 
 end.

+ 14 - 0
CryptoLib/src/Crypto/Generators/ClpPkcs5S2ParametersGenerator.pas

@@ -58,6 +58,7 @@ type
 
   public
 
+    procedure Clear();
     /// <summary>
     /// construct a Pkcs5 Scheme 2 Parameters generator.
     /// </summary>
@@ -66,6 +67,8 @@ type
     /// </param>
     constructor Create(const digest: IDigest);
 
+    destructor Destroy; override;
+
     procedure Init(const password, salt: TCryptoLibByteArray;
       iterationCount: Int32); override;
 
@@ -129,12 +132,23 @@ implementation
 
 { TPkcs5S2ParametersGenerator }
 
+procedure TPkcs5S2ParametersGenerator.Clear();
+begin
+  FPBKDF2_HMAC.Clear();
+end;
+
 constructor TPkcs5S2ParametersGenerator.Create(const digest: IDigest);
 begin
   Inherited Create();
   Fdigest := digest;
 end;
 
+destructor TPkcs5S2ParametersGenerator.Destroy;
+begin
+  Clear();
+  inherited Destroy;
+end;
+
 function TPkcs5S2ParametersGenerator.GenerateDerivedKey(dkLen: Int32)
   : TCryptoLibByteArray;
 begin

+ 15 - 0
CryptoLib/src/Crypto/Macs/ClpHMac.pas

@@ -57,6 +57,10 @@ type
   public
     constructor Create(const digest: IDigest);
 
+    destructor Destroy(); override;
+
+    procedure Clear();
+
     function GetUnderlyingDigest: IDigest; inline;
     function GetMacSize: Int32; inline;
 
@@ -91,6 +95,11 @@ begin
   FHMAC.TransformBytes(input, inOff, len);
 end;
 
+procedure THMac.Clear();
+begin
+  FHMAC.Clear();
+end;
+
 constructor THMac.Create(const digest: IDigest);
 begin
   Inherited Create();
@@ -98,6 +107,12 @@ begin
   FHMAC := THashFactory.THMac.CreateHMAC(FDigest.GetUnderlyingIHash);
 end;
 
+destructor THMac.Destroy;
+begin
+  Clear();
+  inherited Destroy;
+end;
+
 function THMac.DoFinal(const output: TCryptoLibByteArray; outOff: Int32): Int32;
 var
   buf: TCryptoLibByteArray;

+ 2 - 21
CryptoLib/src/Interfaces/ClpIArgon2ParametersGenerator.pas

@@ -39,32 +39,13 @@ type
 
     ['{0AC3D3A8-9422-405F-B0EE-6B7AE0F64F74}']
 
+    procedure Clear();
+
     procedure Init(argon2Type: TArgon2Type; argon2Version: TArgon2Version;
       const password, salt, secret, additional: TCryptoLibByteArray;
       iterations, memory, parallelism: Int32;
       memoryCostType: TArgon2MemoryCostType);
 
-    /// <returns>
-    /// the password byte array.
-    /// </returns>
-    function GetPassword: TCryptoLibByteArray;
-
-    /// <value>
-    /// the password byte array.
-    /// </value>
-    property password: TCryptoLibByteArray read GetPassword;
-
-    /// <returns>
-    /// the Argon2 Parameter Builder Instance
-    /// </returns>
-    function GetArgon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder;
-
-    /// <returns>
-    /// the Argon2 Parameter Builder Instance
-    /// </returns>
-    property Argon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder
-      read GetArgon2ParametersBuilder;
-
     /// <summary>
     /// Generate derived parameters for a key of length keySize.
     /// </summary>

+ 2 - 0
CryptoLib/src/Interfaces/ClpIMac.pas

@@ -35,6 +35,8 @@ type
   IMac = interface(IInterface)
     ['{3273EF2F-AE51-4878-B55C-5F801DB85A74}']
 
+    procedure Clear();
+
     /// <summary>
     /// returns the name of the algorithm the MAC implements.
     /// </summary>

+ 2 - 0
CryptoLib/src/Interfaces/ClpIPkcs5S2ParametersGenerator.pas

@@ -30,6 +30,8 @@ type
 
     ['{AD345DB8-2341-4C56-B401-23444C2A81BA}']
 
+    procedure Clear();
+
     function GetDigest: IDigest;
 
     /// <value>

+ 19 - 10
CryptoLib/src/Utils/ClpArrayUtils.pas

@@ -257,31 +257,40 @@ end;
 class procedure TArrayUtils.Fill(const buf: TCryptoLibByteArray;
   from, &to: Int32; filler: Byte);
 begin
-  System.FillChar(buf[from], (&to - from) * System.SizeOf(Byte), filler);
+  if buf <> Nil then
+  begin
+    System.FillChar(buf[from], (&to - from) * System.SizeOf(Byte), filler);
+  end;
 end;
 
 class procedure TArrayUtils.Fill(const buf: TCryptoLibInt32Array;
   from, &to: Int32; filler: Int32);
 begin
-  while from < &to do
+  if buf <> Nil then
   begin
-    buf[from] := filler;
-    System.Inc(from);
+    while from < &to do
+    begin
+      buf[from] := filler;
+      System.Inc(from);
+    end;
   end;
 end;
 
 class procedure TArrayUtils.Fill(const buf: TCryptoLibUInt32Array;
   from, &to: Int32; filler: UInt32);
 begin
+  if buf <> Nil then
+  begin
 {$IFDEF FPC}
-  System.FillDWord(buf[from], (&to - from), filler);
+    System.FillDWord(buf[from], (&to - from), filler);
 {$ELSE}
-  while from < &to do
-  begin
-    buf[from] := filler;
-    System.Inc(from);
-  end;
+    while from < &to do
+    begin
+      buf[from] := filler;
+      System.Inc(from);
+    end;
 {$ENDIF}
+  end;
 end;
 
 class procedure TArrayUtils.ZeroFill(const buf: TCryptoLibByteArray);