Browse Source

Merge pull request #8 from tondrej/master

Consider using RtlGenRandom
Ugochukwu Mmaduekwe 6 years ago
parent
commit
398fce9fa8

+ 1 - 1
CryptoLib/src/Math/EC/Multiplier/ClpValidityPrecompInfo.pas

@@ -17,7 +17,7 @@
 
 unit ClpValidityPrecompInfo;
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I ..\..\..\Include\CryptoLib.inc}
 
 interface
 

+ 57 - 15
CryptoLib/src/Utils/Randoms/ClpOSRandom.pas

@@ -240,6 +240,21 @@ type
       : Int32; static;
     class property IsCngBCryptGenRandomSupportedOnOS: Boolean
       read GetIsCngBCryptGenRandomSupportedOnOS;
+
+  type
+    TRtlGenRandom = function(RandomBuffer: PVOID; RandomBufferLength: ULONG): Boolean; stdcall;
+
+  class var
+    FIsRtlGenRandomSupportedOnOS: Boolean;
+    FRtlGenRandom: TRtlGenRandom;
+
+    class function GetIsRtlGenRandomSupportedOnOS(): Boolean;
+      static; inline;
+
+    class function IsRtlGenRandomAvailable(): Boolean; static;
+
+    class property IsRtlGenRandomSupportedOnOS: Boolean
+      read GetIsRtlGenRandomSupportedOnOS;
 {$ENDIF}
 
     // ================================================================//
@@ -336,6 +351,7 @@ implementation
 class procedure TOSRandom.Boot;
 begin
 {$IFDEF CRYPTOLIB_MSWINDOWS}
+  FIsRtlGenRandomSupportedOnOS := IsRtlGenRandomAvailable();
   FIsCngBCryptGenRandomSupportedOnOS := IsCngBCryptGenRandomAvailable();
 {$ENDIF}
 {$IFDEF CRYPTOLIB_HAS_GETRANDOM}
@@ -355,22 +371,39 @@ begin
   result := FIsCngBCryptGenRandomSupportedOnOS;
 end;
 
-class function TOSRandom.IsCngBCryptGenRandomAvailable(): Boolean;
-const
-  BCRYPT = 'bcrypt.dll';
+class function TOSRandom.GetIsRtlGenRandomSupportedOnOS(): Boolean;
+begin
+  result := FIsRtlGenRandomSupportedOnOS;
+end;
+
+function GetProcedureAddress(ModuleHandle: THandle; const AProcedureName: String;
+  var AFunctionFound: Boolean): Pointer;
+begin
+  result := GetProcAddress(ModuleHandle, PChar(AProcedureName));
+  if result = Nil then
+  begin
+    AFunctionFound := False;
+  end;
+end;
+
+class function TOSRandom.IsRtlGenRandomAvailable(): Boolean;
 var
   ModuleHandle: THandle;
-
-  function GetProcedureAddress(const AProcedureName: String;
-    var AFunctionFound: Boolean): Pointer;
+begin
+  result := False;
+  ModuleHandle := SafeLoadLibrary(ADVAPI32, SEM_FAILCRITICALERRORS);
+  if ModuleHandle <> 0 then
   begin
-    result := GetProcAddress(ModuleHandle, PChar(AProcedureName));
-    if result = Nil then
-    begin
-      AFunctionFound := False;
-    end;
+    result := True;
+    FRtlGenRandom := GetProcedureAddress(ModuleHandle, 'SystemFunction036', result);
   end;
+end;
 
+class function TOSRandom.IsCngBCryptGenRandomAvailable(): Boolean;
+const
+  BCRYPT = 'bcrypt.dll';
+var
+  ModuleHandle: THandle;
 begin
   result := False;
   ModuleHandle := SafeLoadLibrary(PChar(BCRYPT), SEM_FAILCRITICALERRORS);
@@ -378,10 +411,10 @@ begin
   begin
     result := True;
     FBCryptOpenAlgorithmProvider :=
-      GetProcedureAddress('BCryptOpenAlgorithmProvider', result);
+      GetProcedureAddress(ModuleHandle, 'BCryptOpenAlgorithmProvider', result);
     FBCryptCloseAlgorithmProvider :=
-      GetProcedureAddress('BCryptCloseAlgorithmProvider', result);
-    FBCryptGenRandom := GetProcedureAddress('BCryptGenRandom', result);
+      GetProcedureAddress(ModuleHandle, 'BCryptCloseAlgorithmProvider', result);
+    FBCryptGenRandom := GetProcedureAddress(ModuleHandle, 'BCryptGenRandom', result);
   end;
 end;
 
@@ -402,7 +435,16 @@ const
   BCRYPT_RNG_ALGORITHM: WideString = 'RNG';
 
 begin
-  if IsCngBCryptGenRandomSupportedOnOS then
+  if IsRtlGenRandomSupportedOnOS then
+  begin
+    // Windows XP / Server 2003 and Above
+    if not FRtlGenRandom(data, ULONG(len)) then
+    begin
+      result := HResultFromWin32(GetLastError);
+      Exit;
+    end;
+  end
+  else if IsCngBCryptGenRandomSupportedOnOS then
   begin
     // Windows Vista and Above
     if (not BCRYPT_SUCCESS(FBCryptOpenAlgorithmProvider(@hProv,